[PATCH 28/57][Arm][GAS] Add support for MVE instructions: vqdmlah, vqrdmlah, vqdmlash...
[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 */
a8465a06
AV
6954 OP_RNSDQ_RNSC_MQ_RR, /* Vector S, D or Q reg, or MVE vector reg , or Neon
6955 scalar, or ARM register. */
5287ad62 6956 OP_RNDQ_RNSC, /* Neon D or Q reg, or Neon scalar. */
42b16635
AV
6957 OP_RNDQ_RNSC_RR, /* Neon D or Q reg, Neon scalar, or ARM register. */
6958 OP_RNDQMQ_RNSC_RR, /* Neon D or Q reg, Neon scalar, MVE vector or ARM
6959 register. */
5d281bf0 6960 OP_RNDQMQ_RNSC, /* Neon D, Q or MVE vector reg, or Neon scalar. */
5287ad62
JB
6961 OP_RND_RNSC, /* Neon D reg, or Neon scalar. */
6962 OP_VMOV, /* Neon VMOV operands. */
4316f0d2 6963 OP_RNDQ_Ibig, /* Neon D or Q reg, or big immediate for logic and VMVN. */
f601a00c
AV
6964 /* Neon D, Q or MVE vector register, or big immediate for logic and VMVN. */
6965 OP_RNDQMQ_Ibig,
5287ad62 6966 OP_RNDQ_I63b, /* Neon D or Q reg, or immediate for shift. */
2d447fca 6967 OP_RIWR_I32z, /* iWMMXt wR register, or immediate 0 .. 32 for iWMMXt2. */
32c36c3c 6968 OP_VLDR, /* VLDR operand. */
5287ad62
JB
6969
6970 OP_I0, /* immediate zero */
c19d1205
ZW
6971 OP_I7, /* immediate value 0 .. 7 */
6972 OP_I15, /* 0 .. 15 */
6973 OP_I16, /* 1 .. 16 */
5287ad62 6974 OP_I16z, /* 0 .. 16 */
c19d1205
ZW
6975 OP_I31, /* 0 .. 31 */
6976 OP_I31w, /* 0 .. 31, optional trailing ! */
6977 OP_I32, /* 1 .. 32 */
5287ad62
JB
6978 OP_I32z, /* 0 .. 32 */
6979 OP_I63, /* 0 .. 63 */
c19d1205 6980 OP_I63s, /* -64 .. 63 */
5287ad62
JB
6981 OP_I64, /* 1 .. 64 */
6982 OP_I64z, /* 0 .. 64 */
c19d1205 6983 OP_I255, /* 0 .. 255 */
c19d1205
ZW
6984
6985 OP_I4b, /* immediate, prefix optional, 1 .. 4 */
6986 OP_I7b, /* 0 .. 7 */
6987 OP_I15b, /* 0 .. 15 */
6988 OP_I31b, /* 0 .. 31 */
6989
6990 OP_SH, /* shifter operand */
4962c51a 6991 OP_SHG, /* shifter operand with possible group relocation */
c19d1205 6992 OP_ADDR, /* Memory address expression (any mode) */
35c228db 6993 OP_ADDRMVE, /* Memory address expression for MVE's VSTR/VLDR. */
4962c51a
MS
6994 OP_ADDRGLDR, /* Mem addr expr (any mode) with possible LDR group reloc */
6995 OP_ADDRGLDRS, /* Mem addr expr (any mode) with possible LDRS group reloc */
6996 OP_ADDRGLDC, /* Mem addr expr (any mode) with possible LDC group reloc */
c19d1205
ZW
6997 OP_EXP, /* arbitrary expression */
6998 OP_EXPi, /* same, with optional immediate prefix */
6999 OP_EXPr, /* same, with optional relocation suffix */
e2b0ab59 7000 OP_EXPs, /* same, with optional non-first operand relocation suffix */
b6895b4f 7001 OP_HALF, /* 0 .. 65535 or low/high reloc. */
c28eeff2
SN
7002 OP_IROT1, /* VCADD rotate immediate: 90, 270. */
7003 OP_IROT2, /* VCMLA rotate immediate: 0, 90, 180, 270. */
c19d1205
ZW
7004
7005 OP_CPSF, /* CPS flags */
7006 OP_ENDI, /* Endianness specifier */
d2cd1205
JB
7007 OP_wPSR, /* CPSR/SPSR/APSR mask for msr (writing). */
7008 OP_rPSR, /* CPSR/SPSR/APSR mask for msr (reading). */
c19d1205 7009 OP_COND, /* conditional code */
92e90b6e 7010 OP_TB, /* Table branch. */
c19d1205 7011
037e8744
JB
7012 OP_APSR_RR, /* ARM register or "APSR_nzcv". */
7013
c19d1205 7014 OP_RRnpc_I0, /* ARM register or literal 0 */
33eaf5de 7015 OP_RR_EXr, /* ARM register or expression with opt. reloc stuff. */
c19d1205
ZW
7016 OP_RR_EXi, /* ARM register or expression with imm prefix */
7017 OP_RF_IF, /* FPA register or immediate */
7018 OP_RIWR_RIWC, /* iWMMXt R or C reg */
41adaa5c 7019 OP_RIWC_RIWG, /* iWMMXt wC or wCG reg */
c19d1205
ZW
7020
7021 /* Optional operands. */
7022 OP_oI7b, /* immediate, prefix optional, 0 .. 7 */
7023 OP_oI31b, /* 0 .. 31 */
5287ad62 7024 OP_oI32b, /* 1 .. 32 */
5f1af56b 7025 OP_oI32z, /* 0 .. 32 */
c19d1205
ZW
7026 OP_oIffffb, /* 0 .. 65535 */
7027 OP_oI255c, /* curly-brace enclosed, 0 .. 255 */
7028
7029 OP_oRR, /* ARM register */
60f993ce 7030 OP_oLR, /* ARM LR register */
c19d1205 7031 OP_oRRnpc, /* ARM register, not the PC */
5be8be5d 7032 OP_oRRnpcsp, /* ARM register, neither the PC nor the SP (a.k.a. BadReg) */
b6702015 7033 OP_oRRw, /* ARM register, not r15, optional trailing ! */
5287ad62
JB
7034 OP_oRND, /* Optional Neon double precision register */
7035 OP_oRNQ, /* Optional Neon quad precision register */
5ee91343 7036 OP_oRNDQMQ, /* Optional Neon double, quad or MVE vector register. */
5287ad62 7037 OP_oRNDQ, /* Optional Neon double or quad precision register */
037e8744 7038 OP_oRNSDQ, /* Optional single, double or quad precision vector register */
5ee91343
AV
7039 OP_oRNSDQMQ, /* Optional single, double or quad register or MVE vector
7040 register. */
c19d1205
ZW
7041 OP_oSHll, /* LSL immediate */
7042 OP_oSHar, /* ASR immediate */
7043 OP_oSHllar, /* LSL or ASR immediate */
7044 OP_oROR, /* ROR 0/8/16/24 */
52e7f43d 7045 OP_oBARRIER_I15, /* Option argument for a barrier instruction. */
c19d1205 7046
1b883319
AV
7047 OP_oRMQRZ, /* optional MVE vector or ARM register including ZR. */
7048
5be8be5d
DG
7049 /* Some pre-defined mixed (ARM/THUMB) operands. */
7050 OP_RR_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RR, OP_RRnpcsp),
7051 OP_RRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RRnpc, OP_RRnpcsp),
7052 OP_oRRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_oRRnpc, OP_oRRnpcsp),
7053
c19d1205
ZW
7054 OP_FIRST_OPTIONAL = OP_oI7b
7055};
a737bd4d 7056
c19d1205
ZW
7057/* Generic instruction operand parser. This does no encoding and no
7058 semantic validation; it merely squirrels values away in the inst
7059 structure. Returns SUCCESS or FAIL depending on whether the
7060 specified grammar matched. */
7061static int
5be8be5d 7062parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
c19d1205 7063{
5be8be5d 7064 unsigned const int *upat = pattern;
c19d1205
ZW
7065 char *backtrack_pos = 0;
7066 const char *backtrack_error = 0;
99aad254 7067 int i, val = 0, backtrack_index = 0;
5287ad62 7068 enum arm_reg_type rtype;
4962c51a 7069 parse_operand_result result;
5be8be5d 7070 unsigned int op_parse_code;
efd6b359 7071 bfd_boolean partial_match;
c19d1205 7072
e07e6e58
NC
7073#define po_char_or_fail(chr) \
7074 do \
7075 { \
7076 if (skip_past_char (&str, chr) == FAIL) \
477330fc 7077 goto bad_args; \
e07e6e58
NC
7078 } \
7079 while (0)
c19d1205 7080
e07e6e58
NC
7081#define po_reg_or_fail(regtype) \
7082 do \
dcbf9037 7083 { \
e07e6e58 7084 val = arm_typed_reg_parse (& str, regtype, & rtype, \
477330fc 7085 & inst.operands[i].vectype); \
e07e6e58 7086 if (val == FAIL) \
477330fc
RM
7087 { \
7088 first_error (_(reg_expected_msgs[regtype])); \
7089 goto failure; \
7090 } \
e07e6e58
NC
7091 inst.operands[i].reg = val; \
7092 inst.operands[i].isreg = 1; \
7093 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
7094 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
7095 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc
RM
7096 || rtype == REG_TYPE_VFD \
7097 || rtype == REG_TYPE_NQ); \
1b883319 7098 inst.operands[i].iszr = (rtype == REG_TYPE_ZR); \
dcbf9037 7099 } \
e07e6e58
NC
7100 while (0)
7101
7102#define po_reg_or_goto(regtype, label) \
7103 do \
7104 { \
7105 val = arm_typed_reg_parse (& str, regtype, & rtype, \
7106 & inst.operands[i].vectype); \
7107 if (val == FAIL) \
7108 goto label; \
dcbf9037 7109 \
e07e6e58
NC
7110 inst.operands[i].reg = val; \
7111 inst.operands[i].isreg = 1; \
7112 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
7113 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
7114 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc 7115 || rtype == REG_TYPE_VFD \
e07e6e58 7116 || rtype == REG_TYPE_NQ); \
1b883319 7117 inst.operands[i].iszr = (rtype == REG_TYPE_ZR); \
e07e6e58
NC
7118 } \
7119 while (0)
7120
7121#define po_imm_or_fail(min, max, popt) \
7122 do \
7123 { \
7124 if (parse_immediate (&str, &val, min, max, popt) == FAIL) \
7125 goto failure; \
7126 inst.operands[i].imm = val; \
7127 } \
7128 while (0)
7129
57785aa2 7130#define po_scalar_or_goto(elsz, label, reg_type) \
e07e6e58
NC
7131 do \
7132 { \
57785aa2
AV
7133 val = parse_scalar (& str, elsz, & inst.operands[i].vectype, \
7134 reg_type); \
e07e6e58
NC
7135 if (val == FAIL) \
7136 goto label; \
7137 inst.operands[i].reg = val; \
7138 inst.operands[i].isscalar = 1; \
7139 } \
7140 while (0)
7141
7142#define po_misc_or_fail(expr) \
7143 do \
7144 { \
7145 if (expr) \
7146 goto failure; \
7147 } \
7148 while (0)
7149
7150#define po_misc_or_fail_no_backtrack(expr) \
7151 do \
7152 { \
7153 result = expr; \
7154 if (result == PARSE_OPERAND_FAIL_NO_BACKTRACK) \
7155 backtrack_pos = 0; \
7156 if (result != PARSE_OPERAND_SUCCESS) \
7157 goto failure; \
7158 } \
7159 while (0)
4962c51a 7160
52e7f43d
RE
7161#define po_barrier_or_imm(str) \
7162 do \
7163 { \
7164 val = parse_barrier (&str); \
ccb84d65
JB
7165 if (val == FAIL && ! ISALPHA (*str)) \
7166 goto immediate; \
7167 if (val == FAIL \
7168 /* ISB can only take SY as an option. */ \
7169 || ((inst.instruction & 0xf0) == 0x60 \
7170 && val != 0xf)) \
52e7f43d 7171 { \
ccb84d65
JB
7172 inst.error = _("invalid barrier type"); \
7173 backtrack_pos = 0; \
7174 goto failure; \
52e7f43d
RE
7175 } \
7176 } \
7177 while (0)
7178
c19d1205
ZW
7179 skip_whitespace (str);
7180
7181 for (i = 0; upat[i] != OP_stop; i++)
7182 {
5be8be5d
DG
7183 op_parse_code = upat[i];
7184 if (op_parse_code >= 1<<16)
7185 op_parse_code = thumb ? (op_parse_code >> 16)
7186 : (op_parse_code & ((1<<16)-1));
7187
7188 if (op_parse_code >= OP_FIRST_OPTIONAL)
c19d1205
ZW
7189 {
7190 /* Remember where we are in case we need to backtrack. */
c19d1205
ZW
7191 backtrack_pos = str;
7192 backtrack_error = inst.error;
7193 backtrack_index = i;
7194 }
7195
b6702015 7196 if (i > 0 && (i > 1 || inst.operands[0].present))
c19d1205
ZW
7197 po_char_or_fail (',');
7198
5be8be5d 7199 switch (op_parse_code)
c19d1205
ZW
7200 {
7201 /* Registers */
7202 case OP_oRRnpc:
5be8be5d 7203 case OP_oRRnpcsp:
c19d1205 7204 case OP_RRnpc:
5be8be5d 7205 case OP_RRnpcsp:
c19d1205 7206 case OP_oRR:
a302e574
AV
7207 case OP_RRe:
7208 case OP_RRo:
60f993ce
AV
7209 case OP_LR:
7210 case OP_oLR:
c19d1205
ZW
7211 case OP_RR: po_reg_or_fail (REG_TYPE_RN); break;
7212 case OP_RCP: po_reg_or_fail (REG_TYPE_CP); break;
7213 case OP_RCN: po_reg_or_fail (REG_TYPE_CN); break;
7214 case OP_RF: po_reg_or_fail (REG_TYPE_FN); break;
7215 case OP_RVS: po_reg_or_fail (REG_TYPE_VFS); break;
7216 case OP_RVD: po_reg_or_fail (REG_TYPE_VFD); break;
477330fc 7217 case OP_oRND:
5ee91343
AV
7218 case OP_RNDMQR:
7219 po_reg_or_goto (REG_TYPE_RN, try_rndmq);
7220 break;
7221 try_rndmq:
7222 case OP_RNDMQ:
7223 po_reg_or_goto (REG_TYPE_MQ, try_rnd);
7224 break;
7225 try_rnd:
5287ad62 7226 case OP_RND: po_reg_or_fail (REG_TYPE_VFD); break;
cd2cf30b
PB
7227 case OP_RVC:
7228 po_reg_or_goto (REG_TYPE_VFC, coproc_reg);
7229 break;
7230 /* Also accept generic coprocessor regs for unknown registers. */
7231 coproc_reg:
7232 po_reg_or_fail (REG_TYPE_CN);
7233 break;
c19d1205
ZW
7234 case OP_RMF: po_reg_or_fail (REG_TYPE_MVF); break;
7235 case OP_RMD: po_reg_or_fail (REG_TYPE_MVD); break;
7236 case OP_RMFX: po_reg_or_fail (REG_TYPE_MVFX); break;
7237 case OP_RMDX: po_reg_or_fail (REG_TYPE_MVDX); break;
7238 case OP_RMAX: po_reg_or_fail (REG_TYPE_MVAX); break;
7239 case OP_RMDS: po_reg_or_fail (REG_TYPE_DSPSC); break;
7240 case OP_RIWR: po_reg_or_fail (REG_TYPE_MMXWR); break;
7241 case OP_RIWC: po_reg_or_fail (REG_TYPE_MMXWC); break;
7242 case OP_RIWG: po_reg_or_fail (REG_TYPE_MMXWCG); break;
7243 case OP_RXA: po_reg_or_fail (REG_TYPE_XSCALE); break;
477330fc 7244 case OP_oRNQ:
5ee91343
AV
7245 case OP_RNQMQ:
7246 po_reg_or_goto (REG_TYPE_MQ, try_nq);
7247 break;
7248 try_nq:
5287ad62 7249 case OP_RNQ: po_reg_or_fail (REG_TYPE_NQ); break;
dec41383 7250 case OP_RNSD: po_reg_or_fail (REG_TYPE_NSD); break;
7df54120
AV
7251 case OP_RNDQMQR:
7252 po_reg_or_goto (REG_TYPE_RN, try_rndqmq);
7253 break;
7254 try_rndqmq:
5ee91343
AV
7255 case OP_oRNDQMQ:
7256 case OP_RNDQMQ:
7257 po_reg_or_goto (REG_TYPE_MQ, try_rndq);
7258 break;
7259 try_rndq:
477330fc 7260 case OP_oRNDQ:
5287ad62 7261 case OP_RNDQ: po_reg_or_fail (REG_TYPE_NDQ); break;
dd9634d9
AV
7262 case OP_RVSDMQ:
7263 po_reg_or_goto (REG_TYPE_MQ, try_rvsd);
7264 break;
7265 try_rvsd:
477330fc 7266 case OP_RVSD: po_reg_or_fail (REG_TYPE_VFSD); break;
1b883319
AV
7267 case OP_RVSD_COND:
7268 po_reg_or_goto (REG_TYPE_VFSD, try_cond);
7269 break;
477330fc
RM
7270 case OP_oRNSDQ:
7271 case OP_RNSDQ: po_reg_or_fail (REG_TYPE_NSDQ); break;
5ee91343
AV
7272 case OP_RNSDQMQR:
7273 po_reg_or_goto (REG_TYPE_RN, try_mq);
7274 break;
7275 try_mq:
7276 case OP_oRNSDQMQ:
7277 case OP_RNSDQMQ:
7278 po_reg_or_goto (REG_TYPE_MQ, try_nsdq2);
7279 break;
7280 try_nsdq2:
7281 po_reg_or_fail (REG_TYPE_NSDQ);
7282 inst.error = 0;
7283 break;
a302e574
AV
7284 case OP_RMQ:
7285 po_reg_or_fail (REG_TYPE_MQ);
7286 break;
477330fc
RM
7287 /* Neon scalar. Using an element size of 8 means that some invalid
7288 scalars are accepted here, so deal with those in later code. */
57785aa2 7289 case OP_RNSC: po_scalar_or_goto (8, failure, REG_TYPE_VFD); break;
477330fc
RM
7290
7291 case OP_RNDQ_I0:
7292 {
7293 po_reg_or_goto (REG_TYPE_NDQ, try_imm0);
7294 break;
7295 try_imm0:
7296 po_imm_or_fail (0, 0, TRUE);
7297 }
7298 break;
7299
7300 case OP_RVSD_I0:
7301 po_reg_or_goto (REG_TYPE_VFSD, try_imm0);
7302 break;
7303
1b883319
AV
7304 case OP_RSVDMQ_FI0:
7305 po_reg_or_goto (REG_TYPE_MQ, try_rsvd_fi0);
7306 break;
7307 try_rsvd_fi0:
aacf0b33
KT
7308 case OP_RSVD_FI0:
7309 {
7310 po_reg_or_goto (REG_TYPE_VFSD, try_ifimm0);
7311 break;
7312 try_ifimm0:
7313 if (parse_ifimm_zero (&str))
7314 inst.operands[i].imm = 0;
7315 else
7316 {
7317 inst.error
7318 = _("only floating point zero is allowed as immediate value");
7319 goto failure;
7320 }
7321 }
7322 break;
7323
477330fc
RM
7324 case OP_RR_RNSC:
7325 {
57785aa2 7326 po_scalar_or_goto (8, try_rr, REG_TYPE_VFD);
477330fc
RM
7327 break;
7328 try_rr:
7329 po_reg_or_fail (REG_TYPE_RN);
7330 }
7331 break;
7332
a8465a06
AV
7333 case OP_RNSDQ_RNSC_MQ_RR:
7334 po_reg_or_goto (REG_TYPE_RN, try_rnsdq_rnsc_mq);
7335 break;
7336 try_rnsdq_rnsc_mq:
886e1c73
AV
7337 case OP_RNSDQ_RNSC_MQ:
7338 po_reg_or_goto (REG_TYPE_MQ, try_rnsdq_rnsc);
7339 break;
7340 try_rnsdq_rnsc:
477330fc
RM
7341 case OP_RNSDQ_RNSC:
7342 {
57785aa2
AV
7343 po_scalar_or_goto (8, try_nsdq, REG_TYPE_VFD);
7344 inst.error = 0;
477330fc
RM
7345 break;
7346 try_nsdq:
7347 po_reg_or_fail (REG_TYPE_NSDQ);
57785aa2 7348 inst.error = 0;
477330fc
RM
7349 }
7350 break;
7351
dec41383
JW
7352 case OP_RNSD_RNSC:
7353 {
57785aa2 7354 po_scalar_or_goto (8, try_s_scalar, REG_TYPE_VFD);
dec41383
JW
7355 break;
7356 try_s_scalar:
57785aa2 7357 po_scalar_or_goto (4, try_nsd, REG_TYPE_VFS);
dec41383
JW
7358 break;
7359 try_nsd:
7360 po_reg_or_fail (REG_TYPE_NSD);
7361 }
7362 break;
7363
42b16635
AV
7364 case OP_RNDQMQ_RNSC_RR:
7365 po_reg_or_goto (REG_TYPE_MQ, try_rndq_rnsc_rr);
7366 break;
7367 try_rndq_rnsc_rr:
7368 case OP_RNDQ_RNSC_RR:
7369 po_reg_or_goto (REG_TYPE_RN, try_rndq_rnsc);
7370 break;
5d281bf0
AV
7371 case OP_RNDQMQ_RNSC:
7372 po_reg_or_goto (REG_TYPE_MQ, try_rndq_rnsc);
7373 break;
7374 try_rndq_rnsc:
477330fc
RM
7375 case OP_RNDQ_RNSC:
7376 {
57785aa2 7377 po_scalar_or_goto (8, try_ndq, REG_TYPE_VFD);
477330fc
RM
7378 break;
7379 try_ndq:
7380 po_reg_or_fail (REG_TYPE_NDQ);
7381 }
7382 break;
7383
7384 case OP_RND_RNSC:
7385 {
57785aa2 7386 po_scalar_or_goto (8, try_vfd, REG_TYPE_VFD);
477330fc
RM
7387 break;
7388 try_vfd:
7389 po_reg_or_fail (REG_TYPE_VFD);
7390 }
7391 break;
7392
7393 case OP_VMOV:
7394 /* WARNING: parse_neon_mov can move the operand counter, i. If we're
7395 not careful then bad things might happen. */
7396 po_misc_or_fail (parse_neon_mov (&str, &i) == FAIL);
7397 break;
7398
f601a00c
AV
7399 case OP_RNDQMQ_Ibig:
7400 po_reg_or_goto (REG_TYPE_MQ, try_rndq_ibig);
7401 break;
7402 try_rndq_ibig:
477330fc
RM
7403 case OP_RNDQ_Ibig:
7404 {
7405 po_reg_or_goto (REG_TYPE_NDQ, try_immbig);
7406 break;
7407 try_immbig:
7408 /* There's a possibility of getting a 64-bit immediate here, so
7409 we need special handling. */
8335d6aa
JW
7410 if (parse_big_immediate (&str, i, NULL, /*allow_symbol_p=*/FALSE)
7411 == FAIL)
477330fc
RM
7412 {
7413 inst.error = _("immediate value is out of range");
7414 goto failure;
7415 }
7416 }
7417 break;
7418
7419 case OP_RNDQ_I63b:
7420 {
7421 po_reg_or_goto (REG_TYPE_NDQ, try_shimm);
7422 break;
7423 try_shimm:
7424 po_imm_or_fail (0, 63, TRUE);
7425 }
7426 break;
c19d1205
ZW
7427
7428 case OP_RRnpcb:
7429 po_char_or_fail ('[');
7430 po_reg_or_fail (REG_TYPE_RN);
7431 po_char_or_fail (']');
7432 break;
a737bd4d 7433
55881a11 7434 case OP_RRnpctw:
c19d1205 7435 case OP_RRw:
b6702015 7436 case OP_oRRw:
c19d1205
ZW
7437 po_reg_or_fail (REG_TYPE_RN);
7438 if (skip_past_char (&str, '!') == SUCCESS)
7439 inst.operands[i].writeback = 1;
7440 break;
7441
7442 /* Immediates */
7443 case OP_I7: po_imm_or_fail ( 0, 7, FALSE); break;
7444 case OP_I15: po_imm_or_fail ( 0, 15, FALSE); break;
7445 case OP_I16: po_imm_or_fail ( 1, 16, FALSE); break;
477330fc 7446 case OP_I16z: po_imm_or_fail ( 0, 16, FALSE); break;
c19d1205
ZW
7447 case OP_I31: po_imm_or_fail ( 0, 31, FALSE); break;
7448 case OP_I32: po_imm_or_fail ( 1, 32, FALSE); break;
477330fc 7449 case OP_I32z: po_imm_or_fail ( 0, 32, FALSE); break;
c19d1205 7450 case OP_I63s: po_imm_or_fail (-64, 63, FALSE); break;
477330fc
RM
7451 case OP_I63: po_imm_or_fail ( 0, 63, FALSE); break;
7452 case OP_I64: po_imm_or_fail ( 1, 64, FALSE); break;
7453 case OP_I64z: po_imm_or_fail ( 0, 64, FALSE); break;
c19d1205 7454 case OP_I255: po_imm_or_fail ( 0, 255, FALSE); break;
c19d1205
ZW
7455
7456 case OP_I4b: po_imm_or_fail ( 1, 4, TRUE); break;
7457 case OP_oI7b:
7458 case OP_I7b: po_imm_or_fail ( 0, 7, TRUE); break;
7459 case OP_I15b: po_imm_or_fail ( 0, 15, TRUE); break;
7460 case OP_oI31b:
7461 case OP_I31b: po_imm_or_fail ( 0, 31, TRUE); break;
477330fc
RM
7462 case OP_oI32b: po_imm_or_fail ( 1, 32, TRUE); break;
7463 case OP_oI32z: po_imm_or_fail ( 0, 32, TRUE); break;
c19d1205
ZW
7464 case OP_oIffffb: po_imm_or_fail ( 0, 0xffff, TRUE); break;
7465
7466 /* Immediate variants */
7467 case OP_oI255c:
7468 po_char_or_fail ('{');
7469 po_imm_or_fail (0, 255, TRUE);
7470 po_char_or_fail ('}');
7471 break;
7472
7473 case OP_I31w:
7474 /* The expression parser chokes on a trailing !, so we have
7475 to find it first and zap it. */
7476 {
7477 char *s = str;
7478 while (*s && *s != ',')
7479 s++;
7480 if (s[-1] == '!')
7481 {
7482 s[-1] = '\0';
7483 inst.operands[i].writeback = 1;
7484 }
7485 po_imm_or_fail (0, 31, TRUE);
7486 if (str == s - 1)
7487 str = s;
7488 }
7489 break;
7490
7491 /* Expressions */
7492 case OP_EXPi: EXPi:
e2b0ab59 7493 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7494 GE_OPT_PREFIX));
7495 break;
7496
7497 case OP_EXP:
e2b0ab59 7498 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7499 GE_NO_PREFIX));
7500 break;
7501
7502 case OP_EXPr: EXPr:
e2b0ab59 7503 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205 7504 GE_NO_PREFIX));
e2b0ab59 7505 if (inst.relocs[0].exp.X_op == O_symbol)
a737bd4d 7506 {
c19d1205
ZW
7507 val = parse_reloc (&str);
7508 if (val == -1)
7509 {
7510 inst.error = _("unrecognized relocation suffix");
7511 goto failure;
7512 }
7513 else if (val != BFD_RELOC_UNUSED)
7514 {
7515 inst.operands[i].imm = val;
7516 inst.operands[i].hasreloc = 1;
7517 }
a737bd4d 7518 }
c19d1205 7519 break;
a737bd4d 7520
e2b0ab59
AV
7521 case OP_EXPs:
7522 po_misc_or_fail (my_get_expression (&inst.relocs[i].exp, &str,
7523 GE_NO_PREFIX));
7524 if (inst.relocs[i].exp.X_op == O_symbol)
7525 {
7526 inst.operands[i].hasreloc = 1;
7527 }
7528 else if (inst.relocs[i].exp.X_op == O_constant)
7529 {
7530 inst.operands[i].imm = inst.relocs[i].exp.X_add_number;
7531 inst.operands[i].hasreloc = 0;
7532 }
7533 break;
7534
b6895b4f
PB
7535 /* Operand for MOVW or MOVT. */
7536 case OP_HALF:
7537 po_misc_or_fail (parse_half (&str));
7538 break;
7539
e07e6e58 7540 /* Register or expression. */
c19d1205
ZW
7541 case OP_RR_EXr: po_reg_or_goto (REG_TYPE_RN, EXPr); break;
7542 case OP_RR_EXi: po_reg_or_goto (REG_TYPE_RN, EXPi); break;
a737bd4d 7543
e07e6e58 7544 /* Register or immediate. */
c19d1205
ZW
7545 case OP_RRnpc_I0: po_reg_or_goto (REG_TYPE_RN, I0); break;
7546 I0: po_imm_or_fail (0, 0, FALSE); break;
a737bd4d 7547
c19d1205
ZW
7548 case OP_RF_IF: po_reg_or_goto (REG_TYPE_FN, IF); break;
7549 IF:
7550 if (!is_immediate_prefix (*str))
7551 goto bad_args;
7552 str++;
7553 val = parse_fpa_immediate (&str);
7554 if (val == FAIL)
7555 goto failure;
7556 /* FPA immediates are encoded as registers 8-15.
7557 parse_fpa_immediate has already applied the offset. */
7558 inst.operands[i].reg = val;
7559 inst.operands[i].isreg = 1;
7560 break;
09d92015 7561
2d447fca
JM
7562 case OP_RIWR_I32z: po_reg_or_goto (REG_TYPE_MMXWR, I32z); break;
7563 I32z: po_imm_or_fail (0, 32, FALSE); break;
7564
e07e6e58 7565 /* Two kinds of register. */
c19d1205
ZW
7566 case OP_RIWR_RIWC:
7567 {
7568 struct reg_entry *rege = arm_reg_parse_multi (&str);
97f87066
JM
7569 if (!rege
7570 || (rege->type != REG_TYPE_MMXWR
7571 && rege->type != REG_TYPE_MMXWC
7572 && rege->type != REG_TYPE_MMXWCG))
c19d1205
ZW
7573 {
7574 inst.error = _("iWMMXt data or control register expected");
7575 goto failure;
7576 }
7577 inst.operands[i].reg = rege->number;
7578 inst.operands[i].isreg = (rege->type == REG_TYPE_MMXWR);
7579 }
7580 break;
09d92015 7581
41adaa5c
JM
7582 case OP_RIWC_RIWG:
7583 {
7584 struct reg_entry *rege = arm_reg_parse_multi (&str);
7585 if (!rege
7586 || (rege->type != REG_TYPE_MMXWC
7587 && rege->type != REG_TYPE_MMXWCG))
7588 {
7589 inst.error = _("iWMMXt control register expected");
7590 goto failure;
7591 }
7592 inst.operands[i].reg = rege->number;
7593 inst.operands[i].isreg = 1;
7594 }
7595 break;
7596
c19d1205
ZW
7597 /* Misc */
7598 case OP_CPSF: val = parse_cps_flags (&str); break;
7599 case OP_ENDI: val = parse_endian_specifier (&str); break;
7600 case OP_oROR: val = parse_ror (&str); break;
1b883319 7601 try_cond:
c19d1205 7602 case OP_COND: val = parse_cond (&str); break;
52e7f43d
RE
7603 case OP_oBARRIER_I15:
7604 po_barrier_or_imm (str); break;
7605 immediate:
7606 if (parse_immediate (&str, &val, 0, 15, TRUE) == FAIL)
477330fc 7607 goto failure;
52e7f43d 7608 break;
c19d1205 7609
fa94de6b 7610 case OP_wPSR:
d2cd1205 7611 case OP_rPSR:
90ec0d68
MGD
7612 po_reg_or_goto (REG_TYPE_RNB, try_psr);
7613 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_virt))
7614 {
7615 inst.error = _("Banked registers are not available with this "
7616 "architecture.");
7617 goto failure;
7618 }
7619 break;
d2cd1205
JB
7620 try_psr:
7621 val = parse_psr (&str, op_parse_code == OP_wPSR);
7622 break;
037e8744 7623
32c36c3c
AV
7624 case OP_VLDR:
7625 po_reg_or_goto (REG_TYPE_VFSD, try_sysreg);
7626 break;
7627 try_sysreg:
7628 val = parse_sys_vldr_vstr (&str);
7629 break;
7630
477330fc
RM
7631 case OP_APSR_RR:
7632 po_reg_or_goto (REG_TYPE_RN, try_apsr);
7633 break;
7634 try_apsr:
7635 /* Parse "APSR_nvzc" operand (for FMSTAT-equivalent MRS
7636 instruction). */
7637 if (strncasecmp (str, "APSR_", 5) == 0)
7638 {
7639 unsigned found = 0;
7640 str += 5;
7641 while (found < 15)
7642 switch (*str++)
7643 {
7644 case 'c': found = (found & 1) ? 16 : found | 1; break;
7645 case 'n': found = (found & 2) ? 16 : found | 2; break;
7646 case 'z': found = (found & 4) ? 16 : found | 4; break;
7647 case 'v': found = (found & 8) ? 16 : found | 8; break;
7648 default: found = 16;
7649 }
7650 if (found != 15)
7651 goto failure;
7652 inst.operands[i].isvec = 1;
f7c21dc7
NC
7653 /* APSR_nzcv is encoded in instructions as if it were the REG_PC. */
7654 inst.operands[i].reg = REG_PC;
477330fc
RM
7655 }
7656 else
7657 goto failure;
7658 break;
037e8744 7659
92e90b6e
PB
7660 case OP_TB:
7661 po_misc_or_fail (parse_tb (&str));
7662 break;
7663
e07e6e58 7664 /* Register lists. */
c19d1205 7665 case OP_REGLST:
4b5a202f 7666 val = parse_reg_list (&str, REGLIST_RN);
c19d1205
ZW
7667 if (*str == '^')
7668 {
5e0d7f77 7669 inst.operands[i].writeback = 1;
c19d1205
ZW
7670 str++;
7671 }
7672 break;
09d92015 7673
4b5a202f
AV
7674 case OP_CLRMLST:
7675 val = parse_reg_list (&str, REGLIST_CLRM);
7676 break;
7677
c19d1205 7678 case OP_VRSLST:
efd6b359
AV
7679 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_S,
7680 &partial_match);
c19d1205 7681 break;
09d92015 7682
c19d1205 7683 case OP_VRDLST:
efd6b359
AV
7684 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_D,
7685 &partial_match);
c19d1205 7686 break;
a737bd4d 7687
477330fc
RM
7688 case OP_VRSDLST:
7689 /* Allow Q registers too. */
7690 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359 7691 REGLIST_NEON_D, &partial_match);
477330fc
RM
7692 if (val == FAIL)
7693 {
7694 inst.error = NULL;
7695 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359
AV
7696 REGLIST_VFP_S, &partial_match);
7697 inst.operands[i].issingle = 1;
7698 }
7699 break;
7700
7701 case OP_VRSDVLST:
7702 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
7703 REGLIST_VFP_D_VPR, &partial_match);
7704 if (val == FAIL && !partial_match)
7705 {
7706 inst.error = NULL;
7707 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
7708 REGLIST_VFP_S_VPR, &partial_match);
477330fc
RM
7709 inst.operands[i].issingle = 1;
7710 }
7711 break;
7712
7713 case OP_NRDLST:
7714 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359 7715 REGLIST_NEON_D, &partial_match);
477330fc 7716 break;
5287ad62 7717
35c228db
AV
7718 case OP_MSTRLST4:
7719 case OP_MSTRLST2:
7720 val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
7721 1, &inst.operands[i].vectype);
7722 if (val != (((op_parse_code == OP_MSTRLST2) ? 3 : 7) << 5 | 0xe))
7723 goto failure;
7724 break;
5287ad62 7725 case OP_NSTRLST:
477330fc 7726 val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
35c228db 7727 0, &inst.operands[i].vectype);
477330fc 7728 break;
5287ad62 7729
c19d1205 7730 /* Addressing modes */
35c228db
AV
7731 case OP_ADDRMVE:
7732 po_misc_or_fail (parse_address_group_reloc (&str, i, GROUP_MVE));
7733 break;
7734
c19d1205
ZW
7735 case OP_ADDR:
7736 po_misc_or_fail (parse_address (&str, i));
7737 break;
09d92015 7738
4962c51a
MS
7739 case OP_ADDRGLDR:
7740 po_misc_or_fail_no_backtrack (
477330fc 7741 parse_address_group_reloc (&str, i, GROUP_LDR));
4962c51a
MS
7742 break;
7743
7744 case OP_ADDRGLDRS:
7745 po_misc_or_fail_no_backtrack (
477330fc 7746 parse_address_group_reloc (&str, i, GROUP_LDRS));
4962c51a
MS
7747 break;
7748
7749 case OP_ADDRGLDC:
7750 po_misc_or_fail_no_backtrack (
477330fc 7751 parse_address_group_reloc (&str, i, GROUP_LDC));
4962c51a
MS
7752 break;
7753
c19d1205
ZW
7754 case OP_SH:
7755 po_misc_or_fail (parse_shifter_operand (&str, i));
7756 break;
09d92015 7757
4962c51a
MS
7758 case OP_SHG:
7759 po_misc_or_fail_no_backtrack (
477330fc 7760 parse_shifter_operand_group_reloc (&str, i));
4962c51a
MS
7761 break;
7762
c19d1205
ZW
7763 case OP_oSHll:
7764 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_IMMEDIATE));
7765 break;
09d92015 7766
c19d1205
ZW
7767 case OP_oSHar:
7768 po_misc_or_fail (parse_shift (&str, i, SHIFT_ASR_IMMEDIATE));
7769 break;
09d92015 7770
c19d1205
ZW
7771 case OP_oSHllar:
7772 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_OR_ASR_IMMEDIATE));
7773 break;
09d92015 7774
1b883319
AV
7775 case OP_RMQRZ:
7776 case OP_oRMQRZ:
7777 po_reg_or_goto (REG_TYPE_MQ, try_rr_zr);
7778 break;
7779 try_rr_zr:
7780 po_reg_or_goto (REG_TYPE_RN, ZR);
7781 break;
7782 ZR:
7783 po_reg_or_fail (REG_TYPE_ZR);
7784 break;
7785
c19d1205 7786 default:
5be8be5d 7787 as_fatal (_("unhandled operand code %d"), op_parse_code);
c19d1205 7788 }
09d92015 7789
c19d1205
ZW
7790 /* Various value-based sanity checks and shared operations. We
7791 do not signal immediate failures for the register constraints;
7792 this allows a syntax error to take precedence. */
5be8be5d 7793 switch (op_parse_code)
c19d1205
ZW
7794 {
7795 case OP_oRRnpc:
7796 case OP_RRnpc:
7797 case OP_RRnpcb:
7798 case OP_RRw:
b6702015 7799 case OP_oRRw:
c19d1205
ZW
7800 case OP_RRnpc_I0:
7801 if (inst.operands[i].isreg && inst.operands[i].reg == REG_PC)
7802 inst.error = BAD_PC;
7803 break;
09d92015 7804
5be8be5d
DG
7805 case OP_oRRnpcsp:
7806 case OP_RRnpcsp:
7807 if (inst.operands[i].isreg)
7808 {
7809 if (inst.operands[i].reg == REG_PC)
7810 inst.error = BAD_PC;
5c8ed6a4
JW
7811 else if (inst.operands[i].reg == REG_SP
7812 /* The restriction on Rd/Rt/Rt2 on Thumb mode has been
7813 relaxed since ARMv8-A. */
7814 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
7815 {
7816 gas_assert (thumb);
7817 inst.error = BAD_SP;
7818 }
5be8be5d
DG
7819 }
7820 break;
7821
55881a11 7822 case OP_RRnpctw:
fa94de6b
RM
7823 if (inst.operands[i].isreg
7824 && inst.operands[i].reg == REG_PC
55881a11
MGD
7825 && (inst.operands[i].writeback || thumb))
7826 inst.error = BAD_PC;
7827 break;
7828
1b883319 7829 case OP_RVSD_COND:
32c36c3c
AV
7830 case OP_VLDR:
7831 if (inst.operands[i].isreg)
7832 break;
7833 /* fall through. */
1b883319 7834
c19d1205
ZW
7835 case OP_CPSF:
7836 case OP_ENDI:
7837 case OP_oROR:
d2cd1205
JB
7838 case OP_wPSR:
7839 case OP_rPSR:
c19d1205 7840 case OP_COND:
52e7f43d 7841 case OP_oBARRIER_I15:
c19d1205 7842 case OP_REGLST:
4b5a202f 7843 case OP_CLRMLST:
c19d1205
ZW
7844 case OP_VRSLST:
7845 case OP_VRDLST:
477330fc 7846 case OP_VRSDLST:
efd6b359 7847 case OP_VRSDVLST:
477330fc
RM
7848 case OP_NRDLST:
7849 case OP_NSTRLST:
35c228db
AV
7850 case OP_MSTRLST2:
7851 case OP_MSTRLST4:
c19d1205
ZW
7852 if (val == FAIL)
7853 goto failure;
7854 inst.operands[i].imm = val;
7855 break;
a737bd4d 7856
60f993ce
AV
7857 case OP_LR:
7858 case OP_oLR:
7859 if (inst.operands[i].reg != REG_LR)
7860 inst.error = _("operand must be LR register");
7861 break;
7862
1b883319
AV
7863 case OP_RMQRZ:
7864 case OP_oRMQRZ:
7865 if (!inst.operands[i].iszr && inst.operands[i].reg == REG_PC)
7866 inst.error = BAD_PC;
7867 break;
7868
a302e574
AV
7869 case OP_RRe:
7870 if (inst.operands[i].isreg
7871 && (inst.operands[i].reg & 0x00000001) != 0)
7872 inst.error = BAD_ODD;
7873 break;
7874
7875 case OP_RRo:
7876 if (inst.operands[i].isreg)
7877 {
7878 if ((inst.operands[i].reg & 0x00000001) != 1)
7879 inst.error = BAD_EVEN;
7880 else if (inst.operands[i].reg == REG_SP)
7881 as_tsktsk (MVE_BAD_SP);
7882 else if (inst.operands[i].reg == REG_PC)
7883 inst.error = BAD_PC;
7884 }
7885 break;
7886
c19d1205
ZW
7887 default:
7888 break;
7889 }
09d92015 7890
c19d1205
ZW
7891 /* If we get here, this operand was successfully parsed. */
7892 inst.operands[i].present = 1;
7893 continue;
09d92015 7894
c19d1205 7895 bad_args:
09d92015 7896 inst.error = BAD_ARGS;
c19d1205
ZW
7897
7898 failure:
7899 if (!backtrack_pos)
d252fdde
PB
7900 {
7901 /* The parse routine should already have set inst.error, but set a
5f4273c7 7902 default here just in case. */
d252fdde 7903 if (!inst.error)
5ee91343 7904 inst.error = BAD_SYNTAX;
d252fdde
PB
7905 return FAIL;
7906 }
c19d1205
ZW
7907
7908 /* Do not backtrack over a trailing optional argument that
7909 absorbed some text. We will only fail again, with the
7910 'garbage following instruction' error message, which is
7911 probably less helpful than the current one. */
7912 if (backtrack_index == i && backtrack_pos != str
7913 && upat[i+1] == OP_stop)
d252fdde
PB
7914 {
7915 if (!inst.error)
5ee91343 7916 inst.error = BAD_SYNTAX;
d252fdde
PB
7917 return FAIL;
7918 }
c19d1205
ZW
7919
7920 /* Try again, skipping the optional argument at backtrack_pos. */
7921 str = backtrack_pos;
7922 inst.error = backtrack_error;
7923 inst.operands[backtrack_index].present = 0;
7924 i = backtrack_index;
7925 backtrack_pos = 0;
09d92015 7926 }
09d92015 7927
c19d1205
ZW
7928 /* Check that we have parsed all the arguments. */
7929 if (*str != '\0' && !inst.error)
7930 inst.error = _("garbage following instruction");
09d92015 7931
c19d1205 7932 return inst.error ? FAIL : SUCCESS;
09d92015
MM
7933}
7934
c19d1205
ZW
7935#undef po_char_or_fail
7936#undef po_reg_or_fail
7937#undef po_reg_or_goto
7938#undef po_imm_or_fail
5287ad62 7939#undef po_scalar_or_fail
52e7f43d 7940#undef po_barrier_or_imm
e07e6e58 7941
c19d1205 7942/* Shorthand macro for instruction encoding functions issuing errors. */
e07e6e58
NC
7943#define constraint(expr, err) \
7944 do \
c19d1205 7945 { \
e07e6e58
NC
7946 if (expr) \
7947 { \
7948 inst.error = err; \
7949 return; \
7950 } \
c19d1205 7951 } \
e07e6e58 7952 while (0)
c19d1205 7953
fdfde340
JM
7954/* Reject "bad registers" for Thumb-2 instructions. Many Thumb-2
7955 instructions are unpredictable if these registers are used. This
5c8ed6a4
JW
7956 is the BadReg predicate in ARM's Thumb-2 documentation.
7957
7958 Before ARMv8-A, REG_PC and REG_SP were not allowed in quite a few
7959 places, while the restriction on REG_SP was relaxed since ARMv8-A. */
7960#define reject_bad_reg(reg) \
7961 do \
7962 if (reg == REG_PC) \
7963 { \
7964 inst.error = BAD_PC; \
7965 return; \
7966 } \
7967 else if (reg == REG_SP \
7968 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)) \
7969 { \
7970 inst.error = BAD_SP; \
7971 return; \
7972 } \
fdfde340
JM
7973 while (0)
7974
94206790
MM
7975/* If REG is R13 (the stack pointer), warn that its use is
7976 deprecated. */
7977#define warn_deprecated_sp(reg) \
7978 do \
7979 if (warn_on_deprecated && reg == REG_SP) \
5c3696f8 7980 as_tsktsk (_("use of r13 is deprecated")); \
94206790
MM
7981 while (0)
7982
c19d1205
ZW
7983/* Functions for operand encoding. ARM, then Thumb. */
7984
d840c081 7985#define rotate_left(v, n) (v << (n & 31) | v >> ((32 - n) & 31))
c19d1205 7986
9db2f6b4
RL
7987/* If the current inst is scalar ARMv8.2 fp16 instruction, do special encoding.
7988
7989 The only binary encoding difference is the Coprocessor number. Coprocessor
7990 9 is used for half-precision calculations or conversions. The format of the
2b0f3761 7991 instruction is the same as the equivalent Coprocessor 10 instruction that
9db2f6b4
RL
7992 exists for Single-Precision operation. */
7993
7994static void
7995do_scalar_fp16_v82_encode (void)
7996{
5ee91343 7997 if (inst.cond < COND_ALWAYS)
9db2f6b4
RL
7998 as_warn (_("ARMv8.2 scalar fp16 instruction cannot be conditional,"
7999 " the behaviour is UNPREDICTABLE"));
8000 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
8001 _(BAD_FP16));
8002
8003 inst.instruction = (inst.instruction & 0xfffff0ff) | 0x900;
8004 mark_feature_used (&arm_ext_fp16);
8005}
8006
c19d1205
ZW
8007/* If VAL can be encoded in the immediate field of an ARM instruction,
8008 return the encoded form. Otherwise, return FAIL. */
8009
8010static unsigned int
8011encode_arm_immediate (unsigned int val)
09d92015 8012{
c19d1205
ZW
8013 unsigned int a, i;
8014
4f1d6205
L
8015 if (val <= 0xff)
8016 return val;
8017
8018 for (i = 2; i < 32; i += 2)
c19d1205
ZW
8019 if ((a = rotate_left (val, i)) <= 0xff)
8020 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
8021
8022 return FAIL;
09d92015
MM
8023}
8024
c19d1205
ZW
8025/* If VAL can be encoded in the immediate field of a Thumb32 instruction,
8026 return the encoded form. Otherwise, return FAIL. */
8027static unsigned int
8028encode_thumb32_immediate (unsigned int val)
09d92015 8029{
c19d1205 8030 unsigned int a, i;
09d92015 8031
9c3c69f2 8032 if (val <= 0xff)
c19d1205 8033 return val;
a737bd4d 8034
9c3c69f2 8035 for (i = 1; i <= 24; i++)
09d92015 8036 {
9c3c69f2
PB
8037 a = val >> i;
8038 if ((val & ~(0xff << i)) == 0)
8039 return ((val >> i) & 0x7f) | ((32 - i) << 7);
09d92015 8040 }
a737bd4d 8041
c19d1205
ZW
8042 a = val & 0xff;
8043 if (val == ((a << 16) | a))
8044 return 0x100 | a;
8045 if (val == ((a << 24) | (a << 16) | (a << 8) | a))
8046 return 0x300 | a;
09d92015 8047
c19d1205
ZW
8048 a = val & 0xff00;
8049 if (val == ((a << 16) | a))
8050 return 0x200 | (a >> 8);
a737bd4d 8051
c19d1205 8052 return FAIL;
09d92015 8053}
5287ad62 8054/* Encode a VFP SP or DP register number into inst.instruction. */
09d92015
MM
8055
8056static void
5287ad62
JB
8057encode_arm_vfp_reg (int reg, enum vfp_reg_pos pos)
8058{
8059 if ((pos == VFP_REG_Dd || pos == VFP_REG_Dn || pos == VFP_REG_Dm)
8060 && reg > 15)
8061 {
b1cc4aeb 8062 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
477330fc
RM
8063 {
8064 if (thumb_mode)
8065 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
8066 fpu_vfp_ext_d32);
8067 else
8068 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
8069 fpu_vfp_ext_d32);
8070 }
5287ad62 8071 else
477330fc
RM
8072 {
8073 first_error (_("D register out of range for selected VFP version"));
8074 return;
8075 }
5287ad62
JB
8076 }
8077
c19d1205 8078 switch (pos)
09d92015 8079 {
c19d1205
ZW
8080 case VFP_REG_Sd:
8081 inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
8082 break;
8083
8084 case VFP_REG_Sn:
8085 inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
8086 break;
8087
8088 case VFP_REG_Sm:
8089 inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
8090 break;
8091
5287ad62
JB
8092 case VFP_REG_Dd:
8093 inst.instruction |= ((reg & 15) << 12) | ((reg >> 4) << 22);
8094 break;
5f4273c7 8095
5287ad62
JB
8096 case VFP_REG_Dn:
8097 inst.instruction |= ((reg & 15) << 16) | ((reg >> 4) << 7);
8098 break;
5f4273c7 8099
5287ad62
JB
8100 case VFP_REG_Dm:
8101 inst.instruction |= (reg & 15) | ((reg >> 4) << 5);
8102 break;
8103
c19d1205
ZW
8104 default:
8105 abort ();
09d92015 8106 }
09d92015
MM
8107}
8108
c19d1205 8109/* Encode a <shift> in an ARM-format instruction. The immediate,
55cf6793 8110 if any, is handled by md_apply_fix. */
09d92015 8111static void
c19d1205 8112encode_arm_shift (int i)
09d92015 8113{
008a97ef
RL
8114 /* register-shifted register. */
8115 if (inst.operands[i].immisreg)
8116 {
bf355b69
MR
8117 int op_index;
8118 for (op_index = 0; op_index <= i; ++op_index)
008a97ef 8119 {
5689c942
RL
8120 /* Check the operand only when it's presented. In pre-UAL syntax,
8121 if the destination register is the same as the first operand, two
8122 register form of the instruction can be used. */
bf355b69
MR
8123 if (inst.operands[op_index].present && inst.operands[op_index].isreg
8124 && inst.operands[op_index].reg == REG_PC)
008a97ef
RL
8125 as_warn (UNPRED_REG ("r15"));
8126 }
8127
8128 if (inst.operands[i].imm == REG_PC)
8129 as_warn (UNPRED_REG ("r15"));
8130 }
8131
c19d1205
ZW
8132 if (inst.operands[i].shift_kind == SHIFT_RRX)
8133 inst.instruction |= SHIFT_ROR << 5;
8134 else
09d92015 8135 {
c19d1205
ZW
8136 inst.instruction |= inst.operands[i].shift_kind << 5;
8137 if (inst.operands[i].immisreg)
8138 {
8139 inst.instruction |= SHIFT_BY_REG;
8140 inst.instruction |= inst.operands[i].imm << 8;
8141 }
8142 else
e2b0ab59 8143 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
09d92015 8144 }
c19d1205 8145}
09d92015 8146
c19d1205
ZW
8147static void
8148encode_arm_shifter_operand (int i)
8149{
8150 if (inst.operands[i].isreg)
09d92015 8151 {
c19d1205
ZW
8152 inst.instruction |= inst.operands[i].reg;
8153 encode_arm_shift (i);
09d92015 8154 }
c19d1205 8155 else
a415b1cd
JB
8156 {
8157 inst.instruction |= INST_IMMEDIATE;
e2b0ab59 8158 if (inst.relocs[0].type != BFD_RELOC_ARM_IMMEDIATE)
a415b1cd
JB
8159 inst.instruction |= inst.operands[i].imm;
8160 }
09d92015
MM
8161}
8162
c19d1205 8163/* Subroutine of encode_arm_addr_mode_2 and encode_arm_addr_mode_3. */
09d92015 8164static void
c19d1205 8165encode_arm_addr_mode_common (int i, bfd_boolean is_t)
09d92015 8166{
2b2f5df9
NC
8167 /* PR 14260:
8168 Generate an error if the operand is not a register. */
8169 constraint (!inst.operands[i].isreg,
8170 _("Instruction does not support =N addresses"));
8171
c19d1205 8172 inst.instruction |= inst.operands[i].reg << 16;
a737bd4d 8173
c19d1205 8174 if (inst.operands[i].preind)
09d92015 8175 {
c19d1205
ZW
8176 if (is_t)
8177 {
8178 inst.error = _("instruction does not accept preindexed addressing");
8179 return;
8180 }
8181 inst.instruction |= PRE_INDEX;
8182 if (inst.operands[i].writeback)
8183 inst.instruction |= WRITE_BACK;
09d92015 8184
c19d1205
ZW
8185 }
8186 else if (inst.operands[i].postind)
8187 {
9c2799c2 8188 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
8189 if (is_t)
8190 inst.instruction |= WRITE_BACK;
8191 }
8192 else /* unindexed - only for coprocessor */
09d92015 8193 {
c19d1205 8194 inst.error = _("instruction does not accept unindexed addressing");
09d92015
MM
8195 return;
8196 }
8197
c19d1205
ZW
8198 if (((inst.instruction & WRITE_BACK) || !(inst.instruction & PRE_INDEX))
8199 && (((inst.instruction & 0x000f0000) >> 16)
8200 == ((inst.instruction & 0x0000f000) >> 12)))
8201 as_warn ((inst.instruction & LOAD_BIT)
8202 ? _("destination register same as write-back base")
8203 : _("source register same as write-back base"));
09d92015
MM
8204}
8205
c19d1205
ZW
8206/* inst.operands[i] was set up by parse_address. Encode it into an
8207 ARM-format mode 2 load or store instruction. If is_t is true,
8208 reject forms that cannot be used with a T instruction (i.e. not
8209 post-indexed). */
a737bd4d 8210static void
c19d1205 8211encode_arm_addr_mode_2 (int i, bfd_boolean is_t)
09d92015 8212{
5be8be5d
DG
8213 const bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
8214
c19d1205 8215 encode_arm_addr_mode_common (i, is_t);
a737bd4d 8216
c19d1205 8217 if (inst.operands[i].immisreg)
09d92015 8218 {
5be8be5d
DG
8219 constraint ((inst.operands[i].imm == REG_PC
8220 || (is_pc && inst.operands[i].writeback)),
8221 BAD_PC_ADDRESSING);
c19d1205
ZW
8222 inst.instruction |= INST_IMMEDIATE; /* yes, this is backwards */
8223 inst.instruction |= inst.operands[i].imm;
8224 if (!inst.operands[i].negative)
8225 inst.instruction |= INDEX_UP;
8226 if (inst.operands[i].shifted)
8227 {
8228 if (inst.operands[i].shift_kind == SHIFT_RRX)
8229 inst.instruction |= SHIFT_ROR << 5;
8230 else
8231 {
8232 inst.instruction |= inst.operands[i].shift_kind << 5;
e2b0ab59 8233 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
c19d1205
ZW
8234 }
8235 }
09d92015 8236 }
e2b0ab59 8237 else /* immediate offset in inst.relocs[0] */
09d92015 8238 {
e2b0ab59 8239 if (is_pc && !inst.relocs[0].pc_rel)
5be8be5d
DG
8240 {
8241 const bfd_boolean is_load = ((inst.instruction & LOAD_BIT) != 0);
23a10334
JZ
8242
8243 /* If is_t is TRUE, it's called from do_ldstt. ldrt/strt
8244 cannot use PC in addressing.
8245 PC cannot be used in writeback addressing, either. */
8246 constraint ((is_t || inst.operands[i].writeback),
5be8be5d 8247 BAD_PC_ADDRESSING);
23a10334 8248
dc5ec521 8249 /* Use of PC in str is deprecated for ARMv7. */
23a10334
JZ
8250 if (warn_on_deprecated
8251 && !is_load
8252 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7))
5c3696f8 8253 as_tsktsk (_("use of PC in this instruction is deprecated"));
5be8be5d
DG
8254 }
8255
e2b0ab59 8256 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
8257 {
8258 /* Prefer + for zero encoded value. */
8259 if (!inst.operands[i].negative)
8260 inst.instruction |= INDEX_UP;
e2b0ab59 8261 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM;
26d97720 8262 }
09d92015 8263 }
09d92015
MM
8264}
8265
c19d1205
ZW
8266/* inst.operands[i] was set up by parse_address. Encode it into an
8267 ARM-format mode 3 load or store instruction. Reject forms that
8268 cannot be used with such instructions. If is_t is true, reject
8269 forms that cannot be used with a T instruction (i.e. not
8270 post-indexed). */
8271static void
8272encode_arm_addr_mode_3 (int i, bfd_boolean is_t)
09d92015 8273{
c19d1205 8274 if (inst.operands[i].immisreg && inst.operands[i].shifted)
09d92015 8275 {
c19d1205
ZW
8276 inst.error = _("instruction does not accept scaled register index");
8277 return;
09d92015 8278 }
a737bd4d 8279
c19d1205 8280 encode_arm_addr_mode_common (i, is_t);
a737bd4d 8281
c19d1205
ZW
8282 if (inst.operands[i].immisreg)
8283 {
5be8be5d 8284 constraint ((inst.operands[i].imm == REG_PC
eb9f3f00 8285 || (is_t && inst.operands[i].reg == REG_PC)),
5be8be5d 8286 BAD_PC_ADDRESSING);
eb9f3f00
JB
8287 constraint (inst.operands[i].reg == REG_PC && inst.operands[i].writeback,
8288 BAD_PC_WRITEBACK);
c19d1205
ZW
8289 inst.instruction |= inst.operands[i].imm;
8290 if (!inst.operands[i].negative)
8291 inst.instruction |= INDEX_UP;
8292 }
e2b0ab59 8293 else /* immediate offset in inst.relocs[0] */
c19d1205 8294 {
e2b0ab59 8295 constraint ((inst.operands[i].reg == REG_PC && !inst.relocs[0].pc_rel
5be8be5d
DG
8296 && inst.operands[i].writeback),
8297 BAD_PC_WRITEBACK);
c19d1205 8298 inst.instruction |= HWOFFSET_IMM;
e2b0ab59 8299 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
8300 {
8301 /* Prefer + for zero encoded value. */
8302 if (!inst.operands[i].negative)
8303 inst.instruction |= INDEX_UP;
8304
e2b0ab59 8305 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM8;
26d97720 8306 }
c19d1205 8307 }
a737bd4d
NC
8308}
8309
8335d6aa
JW
8310/* Write immediate bits [7:0] to the following locations:
8311
8312 |28/24|23 19|18 16|15 4|3 0|
8313 | 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|
8314
8315 This function is used by VMOV/VMVN/VORR/VBIC. */
8316
8317static void
8318neon_write_immbits (unsigned immbits)
8319{
8320 inst.instruction |= immbits & 0xf;
8321 inst.instruction |= ((immbits >> 4) & 0x7) << 16;
8322 inst.instruction |= ((immbits >> 7) & 0x1) << (thumb_mode ? 28 : 24);
8323}
8324
8325/* Invert low-order SIZE bits of XHI:XLO. */
8326
8327static void
8328neon_invert_size (unsigned *xlo, unsigned *xhi, int size)
8329{
8330 unsigned immlo = xlo ? *xlo : 0;
8331 unsigned immhi = xhi ? *xhi : 0;
8332
8333 switch (size)
8334 {
8335 case 8:
8336 immlo = (~immlo) & 0xff;
8337 break;
8338
8339 case 16:
8340 immlo = (~immlo) & 0xffff;
8341 break;
8342
8343 case 64:
8344 immhi = (~immhi) & 0xffffffff;
8345 /* fall through. */
8346
8347 case 32:
8348 immlo = (~immlo) & 0xffffffff;
8349 break;
8350
8351 default:
8352 abort ();
8353 }
8354
8355 if (xlo)
8356 *xlo = immlo;
8357
8358 if (xhi)
8359 *xhi = immhi;
8360}
8361
8362/* True if IMM has form 0bAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD for bits
8363 A, B, C, D. */
09d92015 8364
c19d1205 8365static int
8335d6aa 8366neon_bits_same_in_bytes (unsigned imm)
09d92015 8367{
8335d6aa
JW
8368 return ((imm & 0x000000ff) == 0 || (imm & 0x000000ff) == 0x000000ff)
8369 && ((imm & 0x0000ff00) == 0 || (imm & 0x0000ff00) == 0x0000ff00)
8370 && ((imm & 0x00ff0000) == 0 || (imm & 0x00ff0000) == 0x00ff0000)
8371 && ((imm & 0xff000000) == 0 || (imm & 0xff000000) == 0xff000000);
8372}
a737bd4d 8373
8335d6aa 8374/* For immediate of above form, return 0bABCD. */
09d92015 8375
8335d6aa
JW
8376static unsigned
8377neon_squash_bits (unsigned imm)
8378{
8379 return (imm & 0x01) | ((imm & 0x0100) >> 7) | ((imm & 0x010000) >> 14)
8380 | ((imm & 0x01000000) >> 21);
8381}
8382
8383/* Compress quarter-float representation to 0b...000 abcdefgh. */
8384
8385static unsigned
8386neon_qfloat_bits (unsigned imm)
8387{
8388 return ((imm >> 19) & 0x7f) | ((imm >> 24) & 0x80);
8389}
8390
8391/* Returns CMODE. IMMBITS [7:0] is set to bits suitable for inserting into
8392 the instruction. *OP is passed as the initial value of the op field, and
8393 may be set to a different value depending on the constant (i.e.
8394 "MOV I64, 0bAAAAAAAABBBB..." which uses OP = 1 despite being MOV not
8395 MVN). If the immediate looks like a repeated pattern then also
8396 try smaller element sizes. */
8397
8398static int
8399neon_cmode_for_move_imm (unsigned immlo, unsigned immhi, int float_p,
8400 unsigned *immbits, int *op, int size,
8401 enum neon_el_type type)
8402{
8403 /* Only permit float immediates (including 0.0/-0.0) if the operand type is
8404 float. */
8405 if (type == NT_float && !float_p)
8406 return FAIL;
8407
8408 if (type == NT_float && is_quarter_float (immlo) && immhi == 0)
09d92015 8409 {
8335d6aa
JW
8410 if (size != 32 || *op == 1)
8411 return FAIL;
8412 *immbits = neon_qfloat_bits (immlo);
8413 return 0xf;
8414 }
8415
8416 if (size == 64)
8417 {
8418 if (neon_bits_same_in_bytes (immhi)
8419 && neon_bits_same_in_bytes (immlo))
c19d1205 8420 {
8335d6aa
JW
8421 if (*op == 1)
8422 return FAIL;
8423 *immbits = (neon_squash_bits (immhi) << 4)
8424 | neon_squash_bits (immlo);
8425 *op = 1;
8426 return 0xe;
c19d1205 8427 }
a737bd4d 8428
8335d6aa
JW
8429 if (immhi != immlo)
8430 return FAIL;
8431 }
a737bd4d 8432
8335d6aa 8433 if (size >= 32)
09d92015 8434 {
8335d6aa 8435 if (immlo == (immlo & 0x000000ff))
c19d1205 8436 {
8335d6aa
JW
8437 *immbits = immlo;
8438 return 0x0;
c19d1205 8439 }
8335d6aa 8440 else if (immlo == (immlo & 0x0000ff00))
c19d1205 8441 {
8335d6aa
JW
8442 *immbits = immlo >> 8;
8443 return 0x2;
c19d1205 8444 }
8335d6aa
JW
8445 else if (immlo == (immlo & 0x00ff0000))
8446 {
8447 *immbits = immlo >> 16;
8448 return 0x4;
8449 }
8450 else if (immlo == (immlo & 0xff000000))
8451 {
8452 *immbits = immlo >> 24;
8453 return 0x6;
8454 }
8455 else if (immlo == ((immlo & 0x0000ff00) | 0x000000ff))
8456 {
8457 *immbits = (immlo >> 8) & 0xff;
8458 return 0xc;
8459 }
8460 else if (immlo == ((immlo & 0x00ff0000) | 0x0000ffff))
8461 {
8462 *immbits = (immlo >> 16) & 0xff;
8463 return 0xd;
8464 }
8465
8466 if ((immlo & 0xffff) != (immlo >> 16))
8467 return FAIL;
8468 immlo &= 0xffff;
09d92015 8469 }
a737bd4d 8470
8335d6aa 8471 if (size >= 16)
4962c51a 8472 {
8335d6aa
JW
8473 if (immlo == (immlo & 0x000000ff))
8474 {
8475 *immbits = immlo;
8476 return 0x8;
8477 }
8478 else if (immlo == (immlo & 0x0000ff00))
8479 {
8480 *immbits = immlo >> 8;
8481 return 0xa;
8482 }
8483
8484 if ((immlo & 0xff) != (immlo >> 8))
8485 return FAIL;
8486 immlo &= 0xff;
4962c51a
MS
8487 }
8488
8335d6aa
JW
8489 if (immlo == (immlo & 0x000000ff))
8490 {
8491 /* Don't allow MVN with 8-bit immediate. */
8492 if (*op == 1)
8493 return FAIL;
8494 *immbits = immlo;
8495 return 0xe;
8496 }
26d97720 8497
8335d6aa 8498 return FAIL;
c19d1205 8499}
a737bd4d 8500
5fc177c8 8501#if defined BFD_HOST_64_BIT
ba592044
AM
8502/* Returns TRUE if double precision value V may be cast
8503 to single precision without loss of accuracy. */
8504
8505static bfd_boolean
5fc177c8 8506is_double_a_single (bfd_int64_t v)
ba592044 8507{
5fc177c8 8508 int exp = (int)((v >> 52) & 0x7FF);
8fe3f3d6 8509 bfd_int64_t mantissa = (v & (bfd_int64_t)0xFFFFFFFFFFFFFULL);
ba592044
AM
8510
8511 return (exp == 0 || exp == 0x7FF
8512 || (exp >= 1023 - 126 && exp <= 1023 + 127))
8513 && (mantissa & 0x1FFFFFFFl) == 0;
8514}
8515
3739860c 8516/* Returns a double precision value casted to single precision
ba592044
AM
8517 (ignoring the least significant bits in exponent and mantissa). */
8518
8519static int
5fc177c8 8520double_to_single (bfd_int64_t v)
ba592044
AM
8521{
8522 int sign = (int) ((v >> 63) & 1l);
5fc177c8 8523 int exp = (int) ((v >> 52) & 0x7FF);
8fe3f3d6 8524 bfd_int64_t mantissa = (v & (bfd_int64_t)0xFFFFFFFFFFFFFULL);
ba592044
AM
8525
8526 if (exp == 0x7FF)
8527 exp = 0xFF;
8528 else
8529 {
8530 exp = exp - 1023 + 127;
8531 if (exp >= 0xFF)
8532 {
8533 /* Infinity. */
8534 exp = 0x7F;
8535 mantissa = 0;
8536 }
8537 else if (exp < 0)
8538 {
8539 /* No denormalized numbers. */
8540 exp = 0;
8541 mantissa = 0;
8542 }
8543 }
8544 mantissa >>= 29;
8545 return (sign << 31) | (exp << 23) | mantissa;
8546}
5fc177c8 8547#endif /* BFD_HOST_64_BIT */
ba592044 8548
8335d6aa
JW
8549enum lit_type
8550{
8551 CONST_THUMB,
8552 CONST_ARM,
8553 CONST_VEC
8554};
8555
ba592044
AM
8556static void do_vfp_nsyn_opcode (const char *);
8557
e2b0ab59 8558/* inst.relocs[0].exp describes an "=expr" load pseudo-operation.
c19d1205
ZW
8559 Determine whether it can be performed with a move instruction; if
8560 it can, convert inst.instruction to that move instruction and
c921be7d
NC
8561 return TRUE; if it can't, convert inst.instruction to a literal-pool
8562 load and return FALSE. If this is not a valid thing to do in the
8563 current context, set inst.error and return TRUE.
a737bd4d 8564
c19d1205
ZW
8565 inst.operands[i] describes the destination register. */
8566
c921be7d 8567static bfd_boolean
8335d6aa 8568move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
c19d1205 8569{
53365c0d 8570 unsigned long tbit;
8335d6aa
JW
8571 bfd_boolean thumb_p = (t == CONST_THUMB);
8572 bfd_boolean arm_p = (t == CONST_ARM);
53365c0d
PB
8573
8574 if (thumb_p)
8575 tbit = (inst.instruction > 0xffff) ? THUMB2_LOAD_BIT : THUMB_LOAD_BIT;
8576 else
8577 tbit = LOAD_BIT;
8578
8579 if ((inst.instruction & tbit) == 0)
09d92015 8580 {
c19d1205 8581 inst.error = _("invalid pseudo operation");
c921be7d 8582 return TRUE;
09d92015 8583 }
ba592044 8584
e2b0ab59
AV
8585 if (inst.relocs[0].exp.X_op != O_constant
8586 && inst.relocs[0].exp.X_op != O_symbol
8587 && inst.relocs[0].exp.X_op != O_big)
09d92015
MM
8588 {
8589 inst.error = _("constant expression expected");
c921be7d 8590 return TRUE;
09d92015 8591 }
ba592044 8592
e2b0ab59
AV
8593 if (inst.relocs[0].exp.X_op == O_constant
8594 || inst.relocs[0].exp.X_op == O_big)
8335d6aa 8595 {
5fc177c8
NC
8596#if defined BFD_HOST_64_BIT
8597 bfd_int64_t v;
8598#else
ba592044 8599 offsetT v;
5fc177c8 8600#endif
e2b0ab59 8601 if (inst.relocs[0].exp.X_op == O_big)
8335d6aa 8602 {
ba592044
AM
8603 LITTLENUM_TYPE w[X_PRECISION];
8604 LITTLENUM_TYPE * l;
8605
e2b0ab59 8606 if (inst.relocs[0].exp.X_add_number == -1)
8335d6aa 8607 {
ba592044
AM
8608 gen_to_words (w, X_PRECISION, E_PRECISION);
8609 l = w;
8610 /* FIXME: Should we check words w[2..5] ? */
8335d6aa 8611 }
ba592044
AM
8612 else
8613 l = generic_bignum;
3739860c 8614
5fc177c8
NC
8615#if defined BFD_HOST_64_BIT
8616 v =
8617 ((((((((bfd_int64_t) l[3] & LITTLENUM_MASK)
8618 << LITTLENUM_NUMBER_OF_BITS)
8619 | ((bfd_int64_t) l[2] & LITTLENUM_MASK))
8620 << LITTLENUM_NUMBER_OF_BITS)
8621 | ((bfd_int64_t) l[1] & LITTLENUM_MASK))
8622 << LITTLENUM_NUMBER_OF_BITS)
8623 | ((bfd_int64_t) l[0] & LITTLENUM_MASK));
8624#else
ba592044
AM
8625 v = ((l[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
8626 | (l[0] & LITTLENUM_MASK);
5fc177c8 8627#endif
8335d6aa 8628 }
ba592044 8629 else
e2b0ab59 8630 v = inst.relocs[0].exp.X_add_number;
ba592044
AM
8631
8632 if (!inst.operands[i].issingle)
8335d6aa 8633 {
12569877 8634 if (thumb_p)
8335d6aa 8635 {
53445554
TP
8636 /* LDR should not use lead in a flag-setting instruction being
8637 chosen so we do not check whether movs can be used. */
12569877 8638
53445554 8639 if ((ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
ff8646ee 8640 || ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
53445554
TP
8641 && inst.operands[i].reg != 13
8642 && inst.operands[i].reg != 15)
12569877 8643 {
fc289b0a
TP
8644 /* Check if on thumb2 it can be done with a mov.w, mvn or
8645 movw instruction. */
12569877
AM
8646 unsigned int newimm;
8647 bfd_boolean isNegated;
8648
8649 newimm = encode_thumb32_immediate (v);
8650 if (newimm != (unsigned int) FAIL)
8651 isNegated = FALSE;
8652 else
8653 {
582cfe03 8654 newimm = encode_thumb32_immediate (~v);
12569877
AM
8655 if (newimm != (unsigned int) FAIL)
8656 isNegated = TRUE;
8657 }
8658
fc289b0a
TP
8659 /* The number can be loaded with a mov.w or mvn
8660 instruction. */
ff8646ee
TP
8661 if (newimm != (unsigned int) FAIL
8662 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
12569877 8663 {
fc289b0a 8664 inst.instruction = (0xf04f0000 /* MOV.W. */
582cfe03 8665 | (inst.operands[i].reg << 8));
fc289b0a 8666 /* Change to MOVN. */
582cfe03 8667 inst.instruction |= (isNegated ? 0x200000 : 0);
12569877
AM
8668 inst.instruction |= (newimm & 0x800) << 15;
8669 inst.instruction |= (newimm & 0x700) << 4;
8670 inst.instruction |= (newimm & 0x0ff);
8671 return TRUE;
8672 }
fc289b0a 8673 /* The number can be loaded with a movw instruction. */
ff8646ee
TP
8674 else if ((v & ~0xFFFF) == 0
8675 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
3739860c 8676 {
582cfe03 8677 int imm = v & 0xFFFF;
12569877 8678
582cfe03 8679 inst.instruction = 0xf2400000; /* MOVW. */
12569877
AM
8680 inst.instruction |= (inst.operands[i].reg << 8);
8681 inst.instruction |= (imm & 0xf000) << 4;
8682 inst.instruction |= (imm & 0x0800) << 15;
8683 inst.instruction |= (imm & 0x0700) << 4;
8684 inst.instruction |= (imm & 0x00ff);
8685 return TRUE;
8686 }
8687 }
8335d6aa 8688 }
12569877 8689 else if (arm_p)
ba592044
AM
8690 {
8691 int value = encode_arm_immediate (v);
12569877 8692
ba592044
AM
8693 if (value != FAIL)
8694 {
8695 /* This can be done with a mov instruction. */
8696 inst.instruction &= LITERAL_MASK;
8697 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
8698 inst.instruction |= value & 0xfff;
8699 return TRUE;
8700 }
8335d6aa 8701
ba592044
AM
8702 value = encode_arm_immediate (~ v);
8703 if (value != FAIL)
8704 {
8705 /* This can be done with a mvn instruction. */
8706 inst.instruction &= LITERAL_MASK;
8707 inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
8708 inst.instruction |= value & 0xfff;
8709 return TRUE;
8710 }
8711 }
934c2632 8712 else if (t == CONST_VEC && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
8335d6aa 8713 {
ba592044
AM
8714 int op = 0;
8715 unsigned immbits = 0;
8716 unsigned immlo = inst.operands[1].imm;
8717 unsigned immhi = inst.operands[1].regisimm
8718 ? inst.operands[1].reg
e2b0ab59 8719 : inst.relocs[0].exp.X_unsigned
ba592044
AM
8720 ? 0
8721 : ((bfd_int64_t)((int) immlo)) >> 32;
8722 int cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
8723 &op, 64, NT_invtype);
8724
8725 if (cmode == FAIL)
8726 {
8727 neon_invert_size (&immlo, &immhi, 64);
8728 op = !op;
8729 cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
8730 &op, 64, NT_invtype);
8731 }
8732
8733 if (cmode != FAIL)
8734 {
8735 inst.instruction = (inst.instruction & VLDR_VMOV_SAME)
8736 | (1 << 23)
8737 | (cmode << 8)
8738 | (op << 5)
8739 | (1 << 4);
8740
8741 /* Fill other bits in vmov encoding for both thumb and arm. */
8742 if (thumb_mode)
eff0bc54 8743 inst.instruction |= (0x7U << 29) | (0xF << 24);
ba592044 8744 else
eff0bc54 8745 inst.instruction |= (0xFU << 28) | (0x1 << 25);
ba592044
AM
8746 neon_write_immbits (immbits);
8747 return TRUE;
8748 }
8335d6aa
JW
8749 }
8750 }
8335d6aa 8751
ba592044
AM
8752 if (t == CONST_VEC)
8753 {
8754 /* Check if vldr Rx, =constant could be optimized to vmov Rx, #constant. */
8755 if (inst.operands[i].issingle
8756 && is_quarter_float (inst.operands[1].imm)
8757 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3xd))
8335d6aa 8758 {
ba592044
AM
8759 inst.operands[1].imm =
8760 neon_qfloat_bits (v);
8761 do_vfp_nsyn_opcode ("fconsts");
8762 return TRUE;
8335d6aa 8763 }
5fc177c8
NC
8764
8765 /* If our host does not support a 64-bit type then we cannot perform
8766 the following optimization. This mean that there will be a
8767 discrepancy between the output produced by an assembler built for
8768 a 32-bit-only host and the output produced from a 64-bit host, but
8769 this cannot be helped. */
8770#if defined BFD_HOST_64_BIT
ba592044
AM
8771 else if (!inst.operands[1].issingle
8772 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3))
8335d6aa 8773 {
ba592044
AM
8774 if (is_double_a_single (v)
8775 && is_quarter_float (double_to_single (v)))
8776 {
8777 inst.operands[1].imm =
8778 neon_qfloat_bits (double_to_single (v));
8779 do_vfp_nsyn_opcode ("fconstd");
8780 return TRUE;
8781 }
8335d6aa 8782 }
5fc177c8 8783#endif
8335d6aa
JW
8784 }
8785 }
8786
8787 if (add_to_lit_pool ((!inst.operands[i].isvec
8788 || inst.operands[i].issingle) ? 4 : 8) == FAIL)
8789 return TRUE;
8790
8791 inst.operands[1].reg = REG_PC;
8792 inst.operands[1].isreg = 1;
8793 inst.operands[1].preind = 1;
e2b0ab59
AV
8794 inst.relocs[0].pc_rel = 1;
8795 inst.relocs[0].type = (thumb_p
8335d6aa
JW
8796 ? BFD_RELOC_ARM_THUMB_OFFSET
8797 : (mode_3
8798 ? BFD_RELOC_ARM_HWLITERAL
8799 : BFD_RELOC_ARM_LITERAL));
8800 return FALSE;
8801}
8802
8803/* inst.operands[i] was set up by parse_address. Encode it into an
8804 ARM-format instruction. Reject all forms which cannot be encoded
8805 into a coprocessor load/store instruction. If wb_ok is false,
8806 reject use of writeback; if unind_ok is false, reject use of
8807 unindexed addressing. If reloc_override is not 0, use it instead
8808 of BFD_ARM_CP_OFF_IMM, unless the initial relocation is a group one
8809 (in which case it is preserved). */
8810
8811static int
8812encode_arm_cp_address (int i, int wb_ok, int unind_ok, int reloc_override)
8813{
8814 if (!inst.operands[i].isreg)
8815 {
99b2a2dd
NC
8816 /* PR 18256 */
8817 if (! inst.operands[0].isvec)
8818 {
8819 inst.error = _("invalid co-processor operand");
8820 return FAIL;
8821 }
8335d6aa
JW
8822 if (move_or_literal_pool (0, CONST_VEC, /*mode_3=*/FALSE))
8823 return SUCCESS;
8824 }
8825
8826 inst.instruction |= inst.operands[i].reg << 16;
8827
8828 gas_assert (!(inst.operands[i].preind && inst.operands[i].postind));
8829
8830 if (!inst.operands[i].preind && !inst.operands[i].postind) /* unindexed */
8831 {
8832 gas_assert (!inst.operands[i].writeback);
8833 if (!unind_ok)
8834 {
8835 inst.error = _("instruction does not support unindexed addressing");
8836 return FAIL;
8837 }
8838 inst.instruction |= inst.operands[i].imm;
8839 inst.instruction |= INDEX_UP;
8840 return SUCCESS;
8841 }
8842
8843 if (inst.operands[i].preind)
8844 inst.instruction |= PRE_INDEX;
8845
8846 if (inst.operands[i].writeback)
09d92015 8847 {
8335d6aa 8848 if (inst.operands[i].reg == REG_PC)
c19d1205 8849 {
8335d6aa
JW
8850 inst.error = _("pc may not be used with write-back");
8851 return FAIL;
c19d1205 8852 }
8335d6aa 8853 if (!wb_ok)
c19d1205 8854 {
8335d6aa
JW
8855 inst.error = _("instruction does not support writeback");
8856 return FAIL;
c19d1205 8857 }
8335d6aa 8858 inst.instruction |= WRITE_BACK;
09d92015
MM
8859 }
8860
8335d6aa 8861 if (reloc_override)
e2b0ab59
AV
8862 inst.relocs[0].type = (bfd_reloc_code_real_type) reloc_override;
8863 else if ((inst.relocs[0].type < BFD_RELOC_ARM_ALU_PC_G0_NC
8864 || inst.relocs[0].type > BFD_RELOC_ARM_LDC_SB_G2)
8865 && inst.relocs[0].type != BFD_RELOC_ARM_LDR_PC_G0)
c19d1205 8866 {
8335d6aa 8867 if (thumb_mode)
e2b0ab59 8868 inst.relocs[0].type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
8335d6aa 8869 else
e2b0ab59 8870 inst.relocs[0].type = BFD_RELOC_ARM_CP_OFF_IMM;
c19d1205 8871 }
8335d6aa
JW
8872
8873 /* Prefer + for zero encoded value. */
8874 if (!inst.operands[i].negative)
8875 inst.instruction |= INDEX_UP;
8876
8877 return SUCCESS;
09d92015
MM
8878}
8879
5f4273c7 8880/* Functions for instruction encoding, sorted by sub-architecture.
c19d1205
ZW
8881 First some generics; their names are taken from the conventional
8882 bit positions for register arguments in ARM format instructions. */
09d92015 8883
a737bd4d 8884static void
c19d1205 8885do_noargs (void)
09d92015 8886{
c19d1205 8887}
a737bd4d 8888
c19d1205
ZW
8889static void
8890do_rd (void)
8891{
8892 inst.instruction |= inst.operands[0].reg << 12;
8893}
a737bd4d 8894
16a1fa25
TP
8895static void
8896do_rn (void)
8897{
8898 inst.instruction |= inst.operands[0].reg << 16;
8899}
8900
c19d1205
ZW
8901static void
8902do_rd_rm (void)
8903{
8904 inst.instruction |= inst.operands[0].reg << 12;
8905 inst.instruction |= inst.operands[1].reg;
8906}
09d92015 8907
9eb6c0f1
MGD
8908static void
8909do_rm_rn (void)
8910{
8911 inst.instruction |= inst.operands[0].reg;
8912 inst.instruction |= inst.operands[1].reg << 16;
8913}
8914
c19d1205
ZW
8915static void
8916do_rd_rn (void)
8917{
8918 inst.instruction |= inst.operands[0].reg << 12;
8919 inst.instruction |= inst.operands[1].reg << 16;
8920}
a737bd4d 8921
c19d1205
ZW
8922static void
8923do_rn_rd (void)
8924{
8925 inst.instruction |= inst.operands[0].reg << 16;
8926 inst.instruction |= inst.operands[1].reg << 12;
8927}
09d92015 8928
4ed7ed8d
TP
8929static void
8930do_tt (void)
8931{
8932 inst.instruction |= inst.operands[0].reg << 8;
8933 inst.instruction |= inst.operands[1].reg << 16;
8934}
8935
59d09be6
MGD
8936static bfd_boolean
8937check_obsolete (const arm_feature_set *feature, const char *msg)
8938{
8939 if (ARM_CPU_IS_ANY (cpu_variant))
8940 {
5c3696f8 8941 as_tsktsk ("%s", msg);
59d09be6
MGD
8942 return TRUE;
8943 }
8944 else if (ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
8945 {
8946 as_bad ("%s", msg);
8947 return TRUE;
8948 }
8949
8950 return FALSE;
8951}
8952
c19d1205
ZW
8953static void
8954do_rd_rm_rn (void)
8955{
9a64e435 8956 unsigned Rn = inst.operands[2].reg;
708587a4 8957 /* Enforce restrictions on SWP instruction. */
9a64e435 8958 if ((inst.instruction & 0x0fbfffff) == 0x01000090)
56adecf4
DG
8959 {
8960 constraint (Rn == inst.operands[0].reg || Rn == inst.operands[1].reg,
8961 _("Rn must not overlap other operands"));
8962
59d09be6
MGD
8963 /* SWP{b} is obsolete for ARMv8-A, and deprecated for ARMv6* and ARMv7.
8964 */
8965 if (!check_obsolete (&arm_ext_v8,
8966 _("swp{b} use is obsoleted for ARMv8 and later"))
8967 && warn_on_deprecated
8968 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6))
5c3696f8 8969 as_tsktsk (_("swp{b} use is deprecated for ARMv6 and ARMv7"));
56adecf4 8970 }
59d09be6 8971
c19d1205
ZW
8972 inst.instruction |= inst.operands[0].reg << 12;
8973 inst.instruction |= inst.operands[1].reg;
9a64e435 8974 inst.instruction |= Rn << 16;
c19d1205 8975}
09d92015 8976
c19d1205
ZW
8977static void
8978do_rd_rn_rm (void)
8979{
8980 inst.instruction |= inst.operands[0].reg << 12;
8981 inst.instruction |= inst.operands[1].reg << 16;
8982 inst.instruction |= inst.operands[2].reg;
8983}
a737bd4d 8984
c19d1205
ZW
8985static void
8986do_rm_rd_rn (void)
8987{
5be8be5d 8988 constraint ((inst.operands[2].reg == REG_PC), BAD_PC);
e2b0ab59
AV
8989 constraint (((inst.relocs[0].exp.X_op != O_constant
8990 && inst.relocs[0].exp.X_op != O_illegal)
8991 || inst.relocs[0].exp.X_add_number != 0),
5be8be5d 8992 BAD_ADDR_MODE);
c19d1205
ZW
8993 inst.instruction |= inst.operands[0].reg;
8994 inst.instruction |= inst.operands[1].reg << 12;
8995 inst.instruction |= inst.operands[2].reg << 16;
8996}
09d92015 8997
c19d1205
ZW
8998static void
8999do_imm0 (void)
9000{
9001 inst.instruction |= inst.operands[0].imm;
9002}
09d92015 9003
c19d1205
ZW
9004static void
9005do_rd_cpaddr (void)
9006{
9007 inst.instruction |= inst.operands[0].reg << 12;
9008 encode_arm_cp_address (1, TRUE, TRUE, 0);
09d92015 9009}
a737bd4d 9010
c19d1205
ZW
9011/* ARM instructions, in alphabetical order by function name (except
9012 that wrapper functions appear immediately after the function they
9013 wrap). */
09d92015 9014
c19d1205
ZW
9015/* This is a pseudo-op of the form "adr rd, label" to be converted
9016 into a relative address of the form "add rd, pc, #label-.-8". */
09d92015
MM
9017
9018static void
c19d1205 9019do_adr (void)
09d92015 9020{
c19d1205 9021 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 9022
c19d1205
ZW
9023 /* Frag hacking will turn this into a sub instruction if the offset turns
9024 out to be negative. */
e2b0ab59
AV
9025 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
9026 inst.relocs[0].pc_rel = 1;
9027 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 9028
fc6141f0 9029 if (support_interwork
e2b0ab59
AV
9030 && inst.relocs[0].exp.X_op == O_symbol
9031 && inst.relocs[0].exp.X_add_symbol != NULL
9032 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
9033 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
9034 inst.relocs[0].exp.X_add_number |= 1;
c19d1205 9035}
b99bd4ef 9036
c19d1205
ZW
9037/* This is a pseudo-op of the form "adrl rd, label" to be converted
9038 into a relative address of the form:
9039 add rd, pc, #low(label-.-8)"
9040 add rd, rd, #high(label-.-8)" */
b99bd4ef 9041
c19d1205
ZW
9042static void
9043do_adrl (void)
9044{
9045 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 9046
c19d1205
ZW
9047 /* Frag hacking will turn this into a sub instruction if the offset turns
9048 out to be negative. */
e2b0ab59
AV
9049 inst.relocs[0].type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
9050 inst.relocs[0].pc_rel = 1;
c19d1205 9051 inst.size = INSN_SIZE * 2;
e2b0ab59 9052 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 9053
fc6141f0 9054 if (support_interwork
e2b0ab59
AV
9055 && inst.relocs[0].exp.X_op == O_symbol
9056 && inst.relocs[0].exp.X_add_symbol != NULL
9057 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
9058 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
9059 inst.relocs[0].exp.X_add_number |= 1;
b99bd4ef
NC
9060}
9061
b99bd4ef 9062static void
c19d1205 9063do_arit (void)
b99bd4ef 9064{
e2b0ab59
AV
9065 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
9066 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 9067 THUMB1_RELOC_ONLY);
c19d1205
ZW
9068 if (!inst.operands[1].present)
9069 inst.operands[1].reg = inst.operands[0].reg;
9070 inst.instruction |= inst.operands[0].reg << 12;
9071 inst.instruction |= inst.operands[1].reg << 16;
9072 encode_arm_shifter_operand (2);
9073}
b99bd4ef 9074
62b3e311
PB
9075static void
9076do_barrier (void)
9077{
9078 if (inst.operands[0].present)
ccb84d65 9079 inst.instruction |= inst.operands[0].imm;
62b3e311
PB
9080 else
9081 inst.instruction |= 0xf;
9082}
9083
c19d1205
ZW
9084static void
9085do_bfc (void)
9086{
9087 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
9088 constraint (msb > 32, _("bit-field extends past end of register"));
9089 /* The instruction encoding stores the LSB and MSB,
9090 not the LSB and width. */
9091 inst.instruction |= inst.operands[0].reg << 12;
9092 inst.instruction |= inst.operands[1].imm << 7;
9093 inst.instruction |= (msb - 1) << 16;
9094}
b99bd4ef 9095
c19d1205
ZW
9096static void
9097do_bfi (void)
9098{
9099 unsigned int msb;
b99bd4ef 9100
c19d1205
ZW
9101 /* #0 in second position is alternative syntax for bfc, which is
9102 the same instruction but with REG_PC in the Rm field. */
9103 if (!inst.operands[1].isreg)
9104 inst.operands[1].reg = REG_PC;
b99bd4ef 9105
c19d1205
ZW
9106 msb = inst.operands[2].imm + inst.operands[3].imm;
9107 constraint (msb > 32, _("bit-field extends past end of register"));
9108 /* The instruction encoding stores the LSB and MSB,
9109 not the LSB and width. */
9110 inst.instruction |= inst.operands[0].reg << 12;
9111 inst.instruction |= inst.operands[1].reg;
9112 inst.instruction |= inst.operands[2].imm << 7;
9113 inst.instruction |= (msb - 1) << 16;
b99bd4ef
NC
9114}
9115
b99bd4ef 9116static void
c19d1205 9117do_bfx (void)
b99bd4ef 9118{
c19d1205
ZW
9119 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
9120 _("bit-field extends past end of register"));
9121 inst.instruction |= inst.operands[0].reg << 12;
9122 inst.instruction |= inst.operands[1].reg;
9123 inst.instruction |= inst.operands[2].imm << 7;
9124 inst.instruction |= (inst.operands[3].imm - 1) << 16;
9125}
09d92015 9126
c19d1205
ZW
9127/* ARM V5 breakpoint instruction (argument parse)
9128 BKPT <16 bit unsigned immediate>
9129 Instruction is not conditional.
9130 The bit pattern given in insns[] has the COND_ALWAYS condition,
9131 and it is an error if the caller tried to override that. */
b99bd4ef 9132
c19d1205
ZW
9133static void
9134do_bkpt (void)
9135{
9136 /* Top 12 of 16 bits to bits 19:8. */
9137 inst.instruction |= (inst.operands[0].imm & 0xfff0) << 4;
09d92015 9138
c19d1205
ZW
9139 /* Bottom 4 of 16 bits to bits 3:0. */
9140 inst.instruction |= inst.operands[0].imm & 0xf;
9141}
09d92015 9142
c19d1205
ZW
9143static void
9144encode_branch (int default_reloc)
9145{
9146 if (inst.operands[0].hasreloc)
9147 {
0855e32b
NS
9148 constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32
9149 && inst.operands[0].imm != BFD_RELOC_ARM_TLS_CALL,
9150 _("the only valid suffixes here are '(plt)' and '(tlscall)'"));
e2b0ab59 9151 inst.relocs[0].type = inst.operands[0].imm == BFD_RELOC_ARM_PLT32
0855e32b
NS
9152 ? BFD_RELOC_ARM_PLT32
9153 : thumb_mode ? BFD_RELOC_ARM_THM_TLS_CALL : BFD_RELOC_ARM_TLS_CALL;
c19d1205 9154 }
b99bd4ef 9155 else
e2b0ab59
AV
9156 inst.relocs[0].type = (bfd_reloc_code_real_type) default_reloc;
9157 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
9158}
9159
b99bd4ef 9160static void
c19d1205 9161do_branch (void)
b99bd4ef 9162{
39b41c9c
PB
9163#ifdef OBJ_ELF
9164 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
9165 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
9166 else
9167#endif
9168 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
9169}
9170
9171static void
9172do_bl (void)
9173{
9174#ifdef OBJ_ELF
9175 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
9176 {
9177 if (inst.cond == COND_ALWAYS)
9178 encode_branch (BFD_RELOC_ARM_PCREL_CALL);
9179 else
9180 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
9181 }
9182 else
9183#endif
9184 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
c19d1205 9185}
b99bd4ef 9186
c19d1205
ZW
9187/* ARM V5 branch-link-exchange instruction (argument parse)
9188 BLX <target_addr> ie BLX(1)
9189 BLX{<condition>} <Rm> ie BLX(2)
9190 Unfortunately, there are two different opcodes for this mnemonic.
9191 So, the insns[].value is not used, and the code here zaps values
9192 into inst.instruction.
9193 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
b99bd4ef 9194
c19d1205
ZW
9195static void
9196do_blx (void)
9197{
9198 if (inst.operands[0].isreg)
b99bd4ef 9199 {
c19d1205
ZW
9200 /* Arg is a register; the opcode provided by insns[] is correct.
9201 It is not illegal to do "blx pc", just useless. */
9202 if (inst.operands[0].reg == REG_PC)
9203 as_tsktsk (_("use of r15 in blx in ARM mode is not really useful"));
b99bd4ef 9204
c19d1205
ZW
9205 inst.instruction |= inst.operands[0].reg;
9206 }
9207 else
b99bd4ef 9208 {
c19d1205 9209 /* Arg is an address; this instruction cannot be executed
267bf995
RR
9210 conditionally, and the opcode must be adjusted.
9211 We retain the BFD_RELOC_ARM_PCREL_BLX till the very end
9212 where we generate out a BFD_RELOC_ARM_PCREL_CALL instead. */
c19d1205 9213 constraint (inst.cond != COND_ALWAYS, BAD_COND);
2fc8bdac 9214 inst.instruction = 0xfa000000;
267bf995 9215 encode_branch (BFD_RELOC_ARM_PCREL_BLX);
b99bd4ef 9216 }
c19d1205
ZW
9217}
9218
9219static void
9220do_bx (void)
9221{
845b51d6
PB
9222 bfd_boolean want_reloc;
9223
c19d1205
ZW
9224 if (inst.operands[0].reg == REG_PC)
9225 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
b99bd4ef 9226
c19d1205 9227 inst.instruction |= inst.operands[0].reg;
845b51d6
PB
9228 /* Output R_ARM_V4BX relocations if is an EABI object that looks like
9229 it is for ARMv4t or earlier. */
9230 want_reloc = !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5);
4d354d8b
TP
9231 if (!ARM_FEATURE_ZERO (selected_object_arch)
9232 && !ARM_CPU_HAS_FEATURE (selected_object_arch, arm_ext_v5))
845b51d6
PB
9233 want_reloc = TRUE;
9234
5ad34203 9235#ifdef OBJ_ELF
845b51d6 9236 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
5ad34203 9237#endif
584206db 9238 want_reloc = FALSE;
845b51d6
PB
9239
9240 if (want_reloc)
e2b0ab59 9241 inst.relocs[0].type = BFD_RELOC_ARM_V4BX;
09d92015
MM
9242}
9243
c19d1205
ZW
9244
9245/* ARM v5TEJ. Jump to Jazelle code. */
a737bd4d
NC
9246
9247static void
c19d1205 9248do_bxj (void)
a737bd4d 9249{
c19d1205
ZW
9250 if (inst.operands[0].reg == REG_PC)
9251 as_tsktsk (_("use of r15 in bxj is not really useful"));
9252
9253 inst.instruction |= inst.operands[0].reg;
a737bd4d
NC
9254}
9255
c19d1205
ZW
9256/* Co-processor data operation:
9257 CDP{cond} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>}
9258 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>} */
9259static void
9260do_cdp (void)
9261{
9262 inst.instruction |= inst.operands[0].reg << 8;
9263 inst.instruction |= inst.operands[1].imm << 20;
9264 inst.instruction |= inst.operands[2].reg << 12;
9265 inst.instruction |= inst.operands[3].reg << 16;
9266 inst.instruction |= inst.operands[4].reg;
9267 inst.instruction |= inst.operands[5].imm << 5;
9268}
a737bd4d
NC
9269
9270static void
c19d1205 9271do_cmp (void)
a737bd4d 9272{
c19d1205
ZW
9273 inst.instruction |= inst.operands[0].reg << 16;
9274 encode_arm_shifter_operand (1);
a737bd4d
NC
9275}
9276
c19d1205
ZW
9277/* Transfer between coprocessor and ARM registers.
9278 MRC{cond} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}
9279 MRC2
9280 MCR{cond}
9281 MCR2
9282
9283 No special properties. */
09d92015 9284
dcbd0d71
MGD
9285struct deprecated_coproc_regs_s
9286{
9287 unsigned cp;
9288 int opc1;
9289 unsigned crn;
9290 unsigned crm;
9291 int opc2;
9292 arm_feature_set deprecated;
9293 arm_feature_set obsoleted;
9294 const char *dep_msg;
9295 const char *obs_msg;
9296};
9297
9298#define DEPR_ACCESS_V8 \
9299 N_("This coprocessor register access is deprecated in ARMv8")
9300
9301/* Table of all deprecated coprocessor registers. */
9302static struct deprecated_coproc_regs_s deprecated_coproc_regs[] =
9303{
9304 {15, 0, 7, 10, 5, /* CP15DMB. */
823d2571 9305 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9306 DEPR_ACCESS_V8, NULL},
9307 {15, 0, 7, 10, 4, /* CP15DSB. */
823d2571 9308 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9309 DEPR_ACCESS_V8, NULL},
9310 {15, 0, 7, 5, 4, /* CP15ISB. */
823d2571 9311 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9312 DEPR_ACCESS_V8, NULL},
9313 {14, 6, 1, 0, 0, /* TEEHBR. */
823d2571 9314 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9315 DEPR_ACCESS_V8, NULL},
9316 {14, 6, 0, 0, 0, /* TEECR. */
823d2571 9317 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9318 DEPR_ACCESS_V8, NULL},
9319};
9320
9321#undef DEPR_ACCESS_V8
9322
9323static const size_t deprecated_coproc_reg_count =
9324 sizeof (deprecated_coproc_regs) / sizeof (deprecated_coproc_regs[0]);
9325
09d92015 9326static void
c19d1205 9327do_co_reg (void)
09d92015 9328{
fdfde340 9329 unsigned Rd;
dcbd0d71 9330 size_t i;
fdfde340
JM
9331
9332 Rd = inst.operands[2].reg;
9333 if (thumb_mode)
9334 {
9335 if (inst.instruction == 0xee000010
9336 || inst.instruction == 0xfe000010)
9337 /* MCR, MCR2 */
9338 reject_bad_reg (Rd);
5c8ed6a4 9339 else if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
fdfde340
JM
9340 /* MRC, MRC2 */
9341 constraint (Rd == REG_SP, BAD_SP);
9342 }
9343 else
9344 {
9345 /* MCR */
9346 if (inst.instruction == 0xe000010)
9347 constraint (Rd == REG_PC, BAD_PC);
9348 }
9349
dcbd0d71
MGD
9350 for (i = 0; i < deprecated_coproc_reg_count; ++i)
9351 {
9352 const struct deprecated_coproc_regs_s *r =
9353 deprecated_coproc_regs + i;
9354
9355 if (inst.operands[0].reg == r->cp
9356 && inst.operands[1].imm == r->opc1
9357 && inst.operands[3].reg == r->crn
9358 && inst.operands[4].reg == r->crm
9359 && inst.operands[5].imm == r->opc2)
9360 {
b10bf8c5 9361 if (! ARM_CPU_IS_ANY (cpu_variant)
477330fc 9362 && warn_on_deprecated
dcbd0d71 9363 && ARM_CPU_HAS_FEATURE (cpu_variant, r->deprecated))
5c3696f8 9364 as_tsktsk ("%s", r->dep_msg);
dcbd0d71
MGD
9365 }
9366 }
fdfde340 9367
c19d1205
ZW
9368 inst.instruction |= inst.operands[0].reg << 8;
9369 inst.instruction |= inst.operands[1].imm << 21;
fdfde340 9370 inst.instruction |= Rd << 12;
c19d1205
ZW
9371 inst.instruction |= inst.operands[3].reg << 16;
9372 inst.instruction |= inst.operands[4].reg;
9373 inst.instruction |= inst.operands[5].imm << 5;
9374}
09d92015 9375
c19d1205
ZW
9376/* Transfer between coprocessor register and pair of ARM registers.
9377 MCRR{cond} <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
9378 MCRR2
9379 MRRC{cond}
9380 MRRC2
b99bd4ef 9381
c19d1205 9382 Two XScale instructions are special cases of these:
09d92015 9383
c19d1205
ZW
9384 MAR{cond} acc0, <RdLo>, <RdHi> == MCRR{cond} p0, #0, <RdLo>, <RdHi>, c0
9385 MRA{cond} acc0, <RdLo>, <RdHi> == MRRC{cond} p0, #0, <RdLo>, <RdHi>, c0
b99bd4ef 9386
5f4273c7 9387 Result unpredictable if Rd or Rn is R15. */
a737bd4d 9388
c19d1205
ZW
9389static void
9390do_co_reg2c (void)
9391{
fdfde340
JM
9392 unsigned Rd, Rn;
9393
9394 Rd = inst.operands[2].reg;
9395 Rn = inst.operands[3].reg;
9396
9397 if (thumb_mode)
9398 {
9399 reject_bad_reg (Rd);
9400 reject_bad_reg (Rn);
9401 }
9402 else
9403 {
9404 constraint (Rd == REG_PC, BAD_PC);
9405 constraint (Rn == REG_PC, BAD_PC);
9406 }
9407
873f10f0
TC
9408 /* Only check the MRRC{2} variants. */
9409 if ((inst.instruction & 0x0FF00000) == 0x0C500000)
9410 {
9411 /* If Rd == Rn, error that the operation is
9412 unpredictable (example MRRC p3,#1,r1,r1,c4). */
9413 constraint (Rd == Rn, BAD_OVERLAP);
9414 }
9415
c19d1205
ZW
9416 inst.instruction |= inst.operands[0].reg << 8;
9417 inst.instruction |= inst.operands[1].imm << 4;
fdfde340
JM
9418 inst.instruction |= Rd << 12;
9419 inst.instruction |= Rn << 16;
c19d1205 9420 inst.instruction |= inst.operands[4].reg;
b99bd4ef
NC
9421}
9422
c19d1205
ZW
9423static void
9424do_cpsi (void)
9425{
9426 inst.instruction |= inst.operands[0].imm << 6;
a028a6f5
PB
9427 if (inst.operands[1].present)
9428 {
9429 inst.instruction |= CPSI_MMOD;
9430 inst.instruction |= inst.operands[1].imm;
9431 }
c19d1205 9432}
b99bd4ef 9433
62b3e311
PB
9434static void
9435do_dbg (void)
9436{
9437 inst.instruction |= inst.operands[0].imm;
9438}
9439
eea54501
MGD
9440static void
9441do_div (void)
9442{
9443 unsigned Rd, Rn, Rm;
9444
9445 Rd = inst.operands[0].reg;
9446 Rn = (inst.operands[1].present
9447 ? inst.operands[1].reg : Rd);
9448 Rm = inst.operands[2].reg;
9449
9450 constraint ((Rd == REG_PC), BAD_PC);
9451 constraint ((Rn == REG_PC), BAD_PC);
9452 constraint ((Rm == REG_PC), BAD_PC);
9453
9454 inst.instruction |= Rd << 16;
9455 inst.instruction |= Rn << 0;
9456 inst.instruction |= Rm << 8;
9457}
9458
b99bd4ef 9459static void
c19d1205 9460do_it (void)
b99bd4ef 9461{
c19d1205 9462 /* There is no IT instruction in ARM mode. We
e07e6e58
NC
9463 process it to do the validation as if in
9464 thumb mode, just in case the code gets
9465 assembled for thumb using the unified syntax. */
9466
c19d1205 9467 inst.size = 0;
e07e6e58
NC
9468 if (unified_syntax)
9469 {
5ee91343
AV
9470 set_pred_insn_type (IT_INSN);
9471 now_pred.mask = (inst.instruction & 0xf) | 0x10;
9472 now_pred.cc = inst.operands[0].imm;
e07e6e58 9473 }
09d92015 9474}
b99bd4ef 9475
6530b175
NC
9476/* If there is only one register in the register list,
9477 then return its register number. Otherwise return -1. */
9478static int
9479only_one_reg_in_list (int range)
9480{
9481 int i = ffs (range) - 1;
9482 return (i > 15 || range != (1 << i)) ? -1 : i;
9483}
9484
09d92015 9485static void
6530b175 9486encode_ldmstm(int from_push_pop_mnem)
ea6ef066 9487{
c19d1205
ZW
9488 int base_reg = inst.operands[0].reg;
9489 int range = inst.operands[1].imm;
6530b175 9490 int one_reg;
ea6ef066 9491
c19d1205
ZW
9492 inst.instruction |= base_reg << 16;
9493 inst.instruction |= range;
ea6ef066 9494
c19d1205
ZW
9495 if (inst.operands[1].writeback)
9496 inst.instruction |= LDM_TYPE_2_OR_3;
09d92015 9497
c19d1205 9498 if (inst.operands[0].writeback)
ea6ef066 9499 {
c19d1205
ZW
9500 inst.instruction |= WRITE_BACK;
9501 /* Check for unpredictable uses of writeback. */
9502 if (inst.instruction & LOAD_BIT)
09d92015 9503 {
c19d1205
ZW
9504 /* Not allowed in LDM type 2. */
9505 if ((inst.instruction & LDM_TYPE_2_OR_3)
9506 && ((range & (1 << REG_PC)) == 0))
9507 as_warn (_("writeback of base register is UNPREDICTABLE"));
9508 /* Only allowed if base reg not in list for other types. */
9509 else if (range & (1 << base_reg))
9510 as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
9511 }
9512 else /* STM. */
9513 {
9514 /* Not allowed for type 2. */
9515 if (inst.instruction & LDM_TYPE_2_OR_3)
9516 as_warn (_("writeback of base register is UNPREDICTABLE"));
9517 /* Only allowed if base reg not in list, or first in list. */
9518 else if ((range & (1 << base_reg))
9519 && (range & ((1 << base_reg) - 1)))
9520 as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
09d92015 9521 }
ea6ef066 9522 }
6530b175
NC
9523
9524 /* If PUSH/POP has only one register, then use the A2 encoding. */
9525 one_reg = only_one_reg_in_list (range);
9526 if (from_push_pop_mnem && one_reg >= 0)
9527 {
9528 int is_push = (inst.instruction & A_PUSH_POP_OP_MASK) == A1_OPCODE_PUSH;
9529
4f588891
NC
9530 if (is_push && one_reg == 13 /* SP */)
9531 /* PR 22483: The A2 encoding cannot be used when
9532 pushing the stack pointer as this is UNPREDICTABLE. */
9533 return;
9534
6530b175
NC
9535 inst.instruction &= A_COND_MASK;
9536 inst.instruction |= is_push ? A2_OPCODE_PUSH : A2_OPCODE_POP;
9537 inst.instruction |= one_reg << 12;
9538 }
9539}
9540
9541static void
9542do_ldmstm (void)
9543{
9544 encode_ldmstm (/*from_push_pop_mnem=*/FALSE);
a737bd4d
NC
9545}
9546
c19d1205
ZW
9547/* ARMv5TE load-consecutive (argument parse)
9548 Mode is like LDRH.
9549
9550 LDRccD R, mode
9551 STRccD R, mode. */
9552
a737bd4d 9553static void
c19d1205 9554do_ldrd (void)
a737bd4d 9555{
c19d1205 9556 constraint (inst.operands[0].reg % 2 != 0,
c56791bb 9557 _("first transfer register must be even"));
c19d1205
ZW
9558 constraint (inst.operands[1].present
9559 && inst.operands[1].reg != inst.operands[0].reg + 1,
c56791bb 9560 _("can only transfer two consecutive registers"));
c19d1205
ZW
9561 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
9562 constraint (!inst.operands[2].isreg, _("'[' expected"));
a737bd4d 9563
c19d1205
ZW
9564 if (!inst.operands[1].present)
9565 inst.operands[1].reg = inst.operands[0].reg + 1;
5f4273c7 9566
c56791bb
RE
9567 /* encode_arm_addr_mode_3 will diagnose overlap between the base
9568 register and the first register written; we have to diagnose
9569 overlap between the base and the second register written here. */
ea6ef066 9570
c56791bb
RE
9571 if (inst.operands[2].reg == inst.operands[1].reg
9572 && (inst.operands[2].writeback || inst.operands[2].postind))
9573 as_warn (_("base register written back, and overlaps "
9574 "second transfer register"));
b05fe5cf 9575
c56791bb
RE
9576 if (!(inst.instruction & V4_STR_BIT))
9577 {
c19d1205 9578 /* For an index-register load, the index register must not overlap the
c56791bb
RE
9579 destination (even if not write-back). */
9580 if (inst.operands[2].immisreg
9581 && ((unsigned) inst.operands[2].imm == inst.operands[0].reg
9582 || (unsigned) inst.operands[2].imm == inst.operands[1].reg))
9583 as_warn (_("index register overlaps transfer register"));
b05fe5cf 9584 }
c19d1205
ZW
9585 inst.instruction |= inst.operands[0].reg << 12;
9586 encode_arm_addr_mode_3 (2, /*is_t=*/FALSE);
b05fe5cf
ZW
9587}
9588
9589static void
c19d1205 9590do_ldrex (void)
b05fe5cf 9591{
c19d1205
ZW
9592 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
9593 || inst.operands[1].postind || inst.operands[1].writeback
9594 || inst.operands[1].immisreg || inst.operands[1].shifted
01cfc07f
NC
9595 || inst.operands[1].negative
9596 /* This can arise if the programmer has written
9597 strex rN, rM, foo
9598 or if they have mistakenly used a register name as the last
9599 operand, eg:
9600 strex rN, rM, rX
9601 It is very difficult to distinguish between these two cases
9602 because "rX" might actually be a label. ie the register
9603 name has been occluded by a symbol of the same name. So we
9604 just generate a general 'bad addressing mode' type error
9605 message and leave it up to the programmer to discover the
9606 true cause and fix their mistake. */
9607 || (inst.operands[1].reg == REG_PC),
9608 BAD_ADDR_MODE);
b05fe5cf 9609
e2b0ab59
AV
9610 constraint (inst.relocs[0].exp.X_op != O_constant
9611 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9612 _("offset must be zero in ARM encoding"));
b05fe5cf 9613
5be8be5d
DG
9614 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
9615
c19d1205
ZW
9616 inst.instruction |= inst.operands[0].reg << 12;
9617 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 9618 inst.relocs[0].type = BFD_RELOC_UNUSED;
b05fe5cf
ZW
9619}
9620
9621static void
c19d1205 9622do_ldrexd (void)
b05fe5cf 9623{
c19d1205
ZW
9624 constraint (inst.operands[0].reg % 2 != 0,
9625 _("even register required"));
9626 constraint (inst.operands[1].present
9627 && inst.operands[1].reg != inst.operands[0].reg + 1,
9628 _("can only load two consecutive registers"));
9629 /* If op 1 were present and equal to PC, this function wouldn't
9630 have been called in the first place. */
9631 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
b05fe5cf 9632
c19d1205
ZW
9633 inst.instruction |= inst.operands[0].reg << 12;
9634 inst.instruction |= inst.operands[2].reg << 16;
b05fe5cf
ZW
9635}
9636
1be5fd2e
NC
9637/* In both ARM and thumb state 'ldr pc, #imm' with an immediate
9638 which is not a multiple of four is UNPREDICTABLE. */
9639static void
9640check_ldr_r15_aligned (void)
9641{
9642 constraint (!(inst.operands[1].immisreg)
9643 && (inst.operands[0].reg == REG_PC
9644 && inst.operands[1].reg == REG_PC
e2b0ab59 9645 && (inst.relocs[0].exp.X_add_number & 0x3)),
de194d85 9646 _("ldr to register 15 must be 4-byte aligned"));
1be5fd2e
NC
9647}
9648
b05fe5cf 9649static void
c19d1205 9650do_ldst (void)
b05fe5cf 9651{
c19d1205
ZW
9652 inst.instruction |= inst.operands[0].reg << 12;
9653 if (!inst.operands[1].isreg)
8335d6aa 9654 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/FALSE))
b05fe5cf 9655 return;
c19d1205 9656 encode_arm_addr_mode_2 (1, /*is_t=*/FALSE);
1be5fd2e 9657 check_ldr_r15_aligned ();
b05fe5cf
ZW
9658}
9659
9660static void
c19d1205 9661do_ldstt (void)
b05fe5cf 9662{
c19d1205
ZW
9663 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
9664 reject [Rn,...]. */
9665 if (inst.operands[1].preind)
b05fe5cf 9666 {
e2b0ab59
AV
9667 constraint (inst.relocs[0].exp.X_op != O_constant
9668 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9669 _("this instruction requires a post-indexed address"));
b05fe5cf 9670
c19d1205
ZW
9671 inst.operands[1].preind = 0;
9672 inst.operands[1].postind = 1;
9673 inst.operands[1].writeback = 1;
b05fe5cf 9674 }
c19d1205
ZW
9675 inst.instruction |= inst.operands[0].reg << 12;
9676 encode_arm_addr_mode_2 (1, /*is_t=*/TRUE);
9677}
b05fe5cf 9678
c19d1205 9679/* Halfword and signed-byte load/store operations. */
b05fe5cf 9680
c19d1205
ZW
9681static void
9682do_ldstv4 (void)
9683{
ff4a8d2b 9684 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205
ZW
9685 inst.instruction |= inst.operands[0].reg << 12;
9686 if (!inst.operands[1].isreg)
8335d6aa 9687 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/TRUE))
b05fe5cf 9688 return;
c19d1205 9689 encode_arm_addr_mode_3 (1, /*is_t=*/FALSE);
b05fe5cf
ZW
9690}
9691
9692static void
c19d1205 9693do_ldsttv4 (void)
b05fe5cf 9694{
c19d1205
ZW
9695 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
9696 reject [Rn,...]. */
9697 if (inst.operands[1].preind)
b05fe5cf 9698 {
e2b0ab59
AV
9699 constraint (inst.relocs[0].exp.X_op != O_constant
9700 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9701 _("this instruction requires a post-indexed address"));
b05fe5cf 9702
c19d1205
ZW
9703 inst.operands[1].preind = 0;
9704 inst.operands[1].postind = 1;
9705 inst.operands[1].writeback = 1;
b05fe5cf 9706 }
c19d1205
ZW
9707 inst.instruction |= inst.operands[0].reg << 12;
9708 encode_arm_addr_mode_3 (1, /*is_t=*/TRUE);
9709}
b05fe5cf 9710
c19d1205
ZW
9711/* Co-processor register load/store.
9712 Format: <LDC|STC>{cond}[L] CP#,CRd,<address> */
9713static void
9714do_lstc (void)
9715{
9716 inst.instruction |= inst.operands[0].reg << 8;
9717 inst.instruction |= inst.operands[1].reg << 12;
9718 encode_arm_cp_address (2, TRUE, TRUE, 0);
b05fe5cf
ZW
9719}
9720
b05fe5cf 9721static void
c19d1205 9722do_mlas (void)
b05fe5cf 9723{
8fb9d7b9 9724 /* This restriction does not apply to mls (nor to mla in v6 or later). */
c19d1205 9725 if (inst.operands[0].reg == inst.operands[1].reg
8fb9d7b9 9726 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6)
c19d1205 9727 && !(inst.instruction & 0x00400000))
8fb9d7b9 9728 as_tsktsk (_("Rd and Rm should be different in mla"));
b05fe5cf 9729
c19d1205
ZW
9730 inst.instruction |= inst.operands[0].reg << 16;
9731 inst.instruction |= inst.operands[1].reg;
9732 inst.instruction |= inst.operands[2].reg << 8;
9733 inst.instruction |= inst.operands[3].reg << 12;
c19d1205 9734}
b05fe5cf 9735
c19d1205
ZW
9736static void
9737do_mov (void)
9738{
e2b0ab59
AV
9739 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
9740 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 9741 THUMB1_RELOC_ONLY);
c19d1205
ZW
9742 inst.instruction |= inst.operands[0].reg << 12;
9743 encode_arm_shifter_operand (1);
9744}
b05fe5cf 9745
c19d1205
ZW
9746/* ARM V6T2 16-bit immediate register load: MOV[WT]{cond} Rd, #<imm16>. */
9747static void
9748do_mov16 (void)
9749{
b6895b4f
PB
9750 bfd_vma imm;
9751 bfd_boolean top;
9752
9753 top = (inst.instruction & 0x00400000) != 0;
e2b0ab59 9754 constraint (top && inst.relocs[0].type == BFD_RELOC_ARM_MOVW,
33eaf5de 9755 _(":lower16: not allowed in this instruction"));
e2b0ab59 9756 constraint (!top && inst.relocs[0].type == BFD_RELOC_ARM_MOVT,
33eaf5de 9757 _(":upper16: not allowed in this instruction"));
c19d1205 9758 inst.instruction |= inst.operands[0].reg << 12;
e2b0ab59 9759 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 9760 {
e2b0ab59 9761 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
9762 /* The value is in two pieces: 0:11, 16:19. */
9763 inst.instruction |= (imm & 0x00000fff);
9764 inst.instruction |= (imm & 0x0000f000) << 4;
9765 }
b05fe5cf 9766}
b99bd4ef 9767
037e8744
JB
9768static int
9769do_vfp_nsyn_mrs (void)
9770{
9771 if (inst.operands[0].isvec)
9772 {
9773 if (inst.operands[1].reg != 1)
477330fc 9774 first_error (_("operand 1 must be FPSCR"));
037e8744
JB
9775 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
9776 memset (&inst.operands[1], '\0', sizeof (inst.operands[1]));
9777 do_vfp_nsyn_opcode ("fmstat");
9778 }
9779 else if (inst.operands[1].isvec)
9780 do_vfp_nsyn_opcode ("fmrx");
9781 else
9782 return FAIL;
5f4273c7 9783
037e8744
JB
9784 return SUCCESS;
9785}
9786
9787static int
9788do_vfp_nsyn_msr (void)
9789{
9790 if (inst.operands[0].isvec)
9791 do_vfp_nsyn_opcode ("fmxr");
9792 else
9793 return FAIL;
9794
9795 return SUCCESS;
9796}
9797
f7c21dc7
NC
9798static void
9799do_vmrs (void)
9800{
9801 unsigned Rt = inst.operands[0].reg;
fa94de6b 9802
16d02dc9 9803 if (thumb_mode && Rt == REG_SP)
f7c21dc7
NC
9804 {
9805 inst.error = BAD_SP;
9806 return;
9807 }
9808
40c7d507
RR
9809 /* MVFR2 is only valid at ARMv8-A. */
9810 if (inst.operands[1].reg == 5)
9811 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
9812 _(BAD_FPU));
9813
f7c21dc7 9814 /* APSR_ sets isvec. All other refs to PC are illegal. */
16d02dc9 9815 if (!inst.operands[0].isvec && Rt == REG_PC)
f7c21dc7
NC
9816 {
9817 inst.error = BAD_PC;
9818 return;
9819 }
9820
16d02dc9
JB
9821 /* If we get through parsing the register name, we just insert the number
9822 generated into the instruction without further validation. */
9823 inst.instruction |= (inst.operands[1].reg << 16);
f7c21dc7
NC
9824 inst.instruction |= (Rt << 12);
9825}
9826
9827static void
9828do_vmsr (void)
9829{
9830 unsigned Rt = inst.operands[1].reg;
fa94de6b 9831
f7c21dc7
NC
9832 if (thumb_mode)
9833 reject_bad_reg (Rt);
9834 else if (Rt == REG_PC)
9835 {
9836 inst.error = BAD_PC;
9837 return;
9838 }
9839
40c7d507
RR
9840 /* MVFR2 is only valid for ARMv8-A. */
9841 if (inst.operands[0].reg == 5)
9842 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
9843 _(BAD_FPU));
9844
16d02dc9
JB
9845 /* If we get through parsing the register name, we just insert the number
9846 generated into the instruction without further validation. */
9847 inst.instruction |= (inst.operands[0].reg << 16);
f7c21dc7
NC
9848 inst.instruction |= (Rt << 12);
9849}
9850
b99bd4ef 9851static void
c19d1205 9852do_mrs (void)
b99bd4ef 9853{
90ec0d68
MGD
9854 unsigned br;
9855
037e8744
JB
9856 if (do_vfp_nsyn_mrs () == SUCCESS)
9857 return;
9858
ff4a8d2b 9859 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205 9860 inst.instruction |= inst.operands[0].reg << 12;
90ec0d68
MGD
9861
9862 if (inst.operands[1].isreg)
9863 {
9864 br = inst.operands[1].reg;
806ab1c0 9865 if (((br & 0x200) == 0) && ((br & 0xf0000) != 0xf0000))
90ec0d68
MGD
9866 as_bad (_("bad register for mrs"));
9867 }
9868 else
9869 {
9870 /* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all. */
9871 constraint ((inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f))
9872 != (PSR_c|PSR_f),
d2cd1205 9873 _("'APSR', 'CPSR' or 'SPSR' expected"));
90ec0d68
MGD
9874 br = (15<<16) | (inst.operands[1].imm & SPSR_BIT);
9875 }
9876
9877 inst.instruction |= br;
c19d1205 9878}
b99bd4ef 9879
c19d1205
ZW
9880/* Two possible forms:
9881 "{C|S}PSR_<field>, Rm",
9882 "{C|S}PSR_f, #expression". */
b99bd4ef 9883
c19d1205
ZW
9884static void
9885do_msr (void)
9886{
037e8744
JB
9887 if (do_vfp_nsyn_msr () == SUCCESS)
9888 return;
9889
c19d1205
ZW
9890 inst.instruction |= inst.operands[0].imm;
9891 if (inst.operands[1].isreg)
9892 inst.instruction |= inst.operands[1].reg;
9893 else
b99bd4ef 9894 {
c19d1205 9895 inst.instruction |= INST_IMMEDIATE;
e2b0ab59
AV
9896 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
9897 inst.relocs[0].pc_rel = 0;
b99bd4ef 9898 }
b99bd4ef
NC
9899}
9900
c19d1205
ZW
9901static void
9902do_mul (void)
a737bd4d 9903{
ff4a8d2b
NC
9904 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
9905
c19d1205
ZW
9906 if (!inst.operands[2].present)
9907 inst.operands[2].reg = inst.operands[0].reg;
9908 inst.instruction |= inst.operands[0].reg << 16;
9909 inst.instruction |= inst.operands[1].reg;
9910 inst.instruction |= inst.operands[2].reg << 8;
a737bd4d 9911
8fb9d7b9
MS
9912 if (inst.operands[0].reg == inst.operands[1].reg
9913 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
9914 as_tsktsk (_("Rd and Rm should be different in mul"));
a737bd4d
NC
9915}
9916
c19d1205
ZW
9917/* Long Multiply Parser
9918 UMULL RdLo, RdHi, Rm, Rs
9919 SMULL RdLo, RdHi, Rm, Rs
9920 UMLAL RdLo, RdHi, Rm, Rs
9921 SMLAL RdLo, RdHi, Rm, Rs. */
b99bd4ef
NC
9922
9923static void
c19d1205 9924do_mull (void)
b99bd4ef 9925{
c19d1205
ZW
9926 inst.instruction |= inst.operands[0].reg << 12;
9927 inst.instruction |= inst.operands[1].reg << 16;
9928 inst.instruction |= inst.operands[2].reg;
9929 inst.instruction |= inst.operands[3].reg << 8;
b99bd4ef 9930
682b27ad
PB
9931 /* rdhi and rdlo must be different. */
9932 if (inst.operands[0].reg == inst.operands[1].reg)
9933 as_tsktsk (_("rdhi and rdlo must be different"));
9934
9935 /* rdhi, rdlo and rm must all be different before armv6. */
9936 if ((inst.operands[0].reg == inst.operands[2].reg
c19d1205 9937 || inst.operands[1].reg == inst.operands[2].reg)
682b27ad 9938 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
c19d1205
ZW
9939 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
9940}
b99bd4ef 9941
c19d1205
ZW
9942static void
9943do_nop (void)
9944{
e7495e45
NS
9945 if (inst.operands[0].present
9946 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6k))
c19d1205
ZW
9947 {
9948 /* Architectural NOP hints are CPSR sets with no bits selected. */
9949 inst.instruction &= 0xf0000000;
e7495e45
NS
9950 inst.instruction |= 0x0320f000;
9951 if (inst.operands[0].present)
9952 inst.instruction |= inst.operands[0].imm;
c19d1205 9953 }
b99bd4ef
NC
9954}
9955
c19d1205
ZW
9956/* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
9957 PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
9958 Condition defaults to COND_ALWAYS.
9959 Error if Rd, Rn or Rm are R15. */
b99bd4ef
NC
9960
9961static void
c19d1205 9962do_pkhbt (void)
b99bd4ef 9963{
c19d1205
ZW
9964 inst.instruction |= inst.operands[0].reg << 12;
9965 inst.instruction |= inst.operands[1].reg << 16;
9966 inst.instruction |= inst.operands[2].reg;
9967 if (inst.operands[3].present)
9968 encode_arm_shift (3);
9969}
b99bd4ef 9970
c19d1205 9971/* ARM V6 PKHTB (Argument Parse). */
b99bd4ef 9972
c19d1205
ZW
9973static void
9974do_pkhtb (void)
9975{
9976 if (!inst.operands[3].present)
b99bd4ef 9977 {
c19d1205
ZW
9978 /* If the shift specifier is omitted, turn the instruction
9979 into pkhbt rd, rm, rn. */
9980 inst.instruction &= 0xfff00010;
9981 inst.instruction |= inst.operands[0].reg << 12;
9982 inst.instruction |= inst.operands[1].reg;
9983 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
9984 }
9985 else
9986 {
c19d1205
ZW
9987 inst.instruction |= inst.operands[0].reg << 12;
9988 inst.instruction |= inst.operands[1].reg << 16;
9989 inst.instruction |= inst.operands[2].reg;
9990 encode_arm_shift (3);
b99bd4ef
NC
9991 }
9992}
9993
c19d1205 9994/* ARMv5TE: Preload-Cache
60e5ef9f 9995 MP Extensions: Preload for write
c19d1205 9996
60e5ef9f 9997 PLD(W) <addr_mode>
c19d1205
ZW
9998
9999 Syntactically, like LDR with B=1, W=0, L=1. */
b99bd4ef
NC
10000
10001static void
c19d1205 10002do_pld (void)
b99bd4ef 10003{
c19d1205
ZW
10004 constraint (!inst.operands[0].isreg,
10005 _("'[' expected after PLD mnemonic"));
10006 constraint (inst.operands[0].postind,
10007 _("post-indexed expression used in preload instruction"));
10008 constraint (inst.operands[0].writeback,
10009 _("writeback used in preload instruction"));
10010 constraint (!inst.operands[0].preind,
10011 _("unindexed addressing used in preload instruction"));
c19d1205
ZW
10012 encode_arm_addr_mode_2 (0, /*is_t=*/FALSE);
10013}
b99bd4ef 10014
62b3e311
PB
10015/* ARMv7: PLI <addr_mode> */
10016static void
10017do_pli (void)
10018{
10019 constraint (!inst.operands[0].isreg,
10020 _("'[' expected after PLI mnemonic"));
10021 constraint (inst.operands[0].postind,
10022 _("post-indexed expression used in preload instruction"));
10023 constraint (inst.operands[0].writeback,
10024 _("writeback used in preload instruction"));
10025 constraint (!inst.operands[0].preind,
10026 _("unindexed addressing used in preload instruction"));
10027 encode_arm_addr_mode_2 (0, /*is_t=*/FALSE);
10028 inst.instruction &= ~PRE_INDEX;
10029}
10030
c19d1205
ZW
10031static void
10032do_push_pop (void)
10033{
5e0d7f77
MP
10034 constraint (inst.operands[0].writeback,
10035 _("push/pop do not support {reglist}^"));
c19d1205
ZW
10036 inst.operands[1] = inst.operands[0];
10037 memset (&inst.operands[0], 0, sizeof inst.operands[0]);
10038 inst.operands[0].isreg = 1;
10039 inst.operands[0].writeback = 1;
10040 inst.operands[0].reg = REG_SP;
6530b175 10041 encode_ldmstm (/*from_push_pop_mnem=*/TRUE);
c19d1205 10042}
b99bd4ef 10043
c19d1205
ZW
10044/* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
10045 word at the specified address and the following word
10046 respectively.
10047 Unconditionally executed.
10048 Error if Rn is R15. */
b99bd4ef 10049
c19d1205
ZW
10050static void
10051do_rfe (void)
10052{
10053 inst.instruction |= inst.operands[0].reg << 16;
10054 if (inst.operands[0].writeback)
10055 inst.instruction |= WRITE_BACK;
10056}
b99bd4ef 10057
c19d1205 10058/* ARM V6 ssat (argument parse). */
b99bd4ef 10059
c19d1205
ZW
10060static void
10061do_ssat (void)
10062{
10063 inst.instruction |= inst.operands[0].reg << 12;
10064 inst.instruction |= (inst.operands[1].imm - 1) << 16;
10065 inst.instruction |= inst.operands[2].reg;
b99bd4ef 10066
c19d1205
ZW
10067 if (inst.operands[3].present)
10068 encode_arm_shift (3);
b99bd4ef
NC
10069}
10070
c19d1205 10071/* ARM V6 usat (argument parse). */
b99bd4ef
NC
10072
10073static void
c19d1205 10074do_usat (void)
b99bd4ef 10075{
c19d1205
ZW
10076 inst.instruction |= inst.operands[0].reg << 12;
10077 inst.instruction |= inst.operands[1].imm << 16;
10078 inst.instruction |= inst.operands[2].reg;
b99bd4ef 10079
c19d1205
ZW
10080 if (inst.operands[3].present)
10081 encode_arm_shift (3);
b99bd4ef
NC
10082}
10083
c19d1205 10084/* ARM V6 ssat16 (argument parse). */
09d92015
MM
10085
10086static void
c19d1205 10087do_ssat16 (void)
09d92015 10088{
c19d1205
ZW
10089 inst.instruction |= inst.operands[0].reg << 12;
10090 inst.instruction |= ((inst.operands[1].imm - 1) << 16);
10091 inst.instruction |= inst.operands[2].reg;
09d92015
MM
10092}
10093
c19d1205
ZW
10094static void
10095do_usat16 (void)
a737bd4d 10096{
c19d1205
ZW
10097 inst.instruction |= inst.operands[0].reg << 12;
10098 inst.instruction |= inst.operands[1].imm << 16;
10099 inst.instruction |= inst.operands[2].reg;
10100}
a737bd4d 10101
c19d1205
ZW
10102/* ARM V6 SETEND (argument parse). Sets the E bit in the CPSR while
10103 preserving the other bits.
a737bd4d 10104
c19d1205
ZW
10105 setend <endian_specifier>, where <endian_specifier> is either
10106 BE or LE. */
a737bd4d 10107
c19d1205
ZW
10108static void
10109do_setend (void)
10110{
12e37cbc
MGD
10111 if (warn_on_deprecated
10112 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 10113 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 10114
c19d1205
ZW
10115 if (inst.operands[0].imm)
10116 inst.instruction |= 0x200;
a737bd4d
NC
10117}
10118
10119static void
c19d1205 10120do_shift (void)
a737bd4d 10121{
c19d1205
ZW
10122 unsigned int Rm = (inst.operands[1].present
10123 ? inst.operands[1].reg
10124 : inst.operands[0].reg);
a737bd4d 10125
c19d1205
ZW
10126 inst.instruction |= inst.operands[0].reg << 12;
10127 inst.instruction |= Rm;
10128 if (inst.operands[2].isreg) /* Rd, {Rm,} Rs */
a737bd4d 10129 {
c19d1205
ZW
10130 inst.instruction |= inst.operands[2].reg << 8;
10131 inst.instruction |= SHIFT_BY_REG;
94342ec3
NC
10132 /* PR 12854: Error on extraneous shifts. */
10133 constraint (inst.operands[2].shifted,
10134 _("extraneous shift as part of operand to shift insn"));
a737bd4d
NC
10135 }
10136 else
e2b0ab59 10137 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
a737bd4d
NC
10138}
10139
09d92015 10140static void
3eb17e6b 10141do_smc (void)
09d92015 10142{
e2b0ab59
AV
10143 inst.relocs[0].type = BFD_RELOC_ARM_SMC;
10144 inst.relocs[0].pc_rel = 0;
09d92015
MM
10145}
10146
90ec0d68
MGD
10147static void
10148do_hvc (void)
10149{
e2b0ab59
AV
10150 inst.relocs[0].type = BFD_RELOC_ARM_HVC;
10151 inst.relocs[0].pc_rel = 0;
90ec0d68
MGD
10152}
10153
09d92015 10154static void
c19d1205 10155do_swi (void)
09d92015 10156{
e2b0ab59
AV
10157 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
10158 inst.relocs[0].pc_rel = 0;
09d92015
MM
10159}
10160
ddfded2f
MW
10161static void
10162do_setpan (void)
10163{
10164 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
10165 _("selected processor does not support SETPAN instruction"));
10166
10167 inst.instruction |= ((inst.operands[0].imm & 1) << 9);
10168}
10169
10170static void
10171do_t_setpan (void)
10172{
10173 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
10174 _("selected processor does not support SETPAN instruction"));
10175
10176 inst.instruction |= (inst.operands[0].imm << 3);
10177}
10178
c19d1205
ZW
10179/* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
10180 SMLAxy{cond} Rd,Rm,Rs,Rn
10181 SMLAWy{cond} Rd,Rm,Rs,Rn
10182 Error if any register is R15. */
e16bb312 10183
c19d1205
ZW
10184static void
10185do_smla (void)
e16bb312 10186{
c19d1205
ZW
10187 inst.instruction |= inst.operands[0].reg << 16;
10188 inst.instruction |= inst.operands[1].reg;
10189 inst.instruction |= inst.operands[2].reg << 8;
10190 inst.instruction |= inst.operands[3].reg << 12;
10191}
a737bd4d 10192
c19d1205
ZW
10193/* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
10194 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
10195 Error if any register is R15.
10196 Warning if Rdlo == Rdhi. */
a737bd4d 10197
c19d1205
ZW
10198static void
10199do_smlal (void)
10200{
10201 inst.instruction |= inst.operands[0].reg << 12;
10202 inst.instruction |= inst.operands[1].reg << 16;
10203 inst.instruction |= inst.operands[2].reg;
10204 inst.instruction |= inst.operands[3].reg << 8;
a737bd4d 10205
c19d1205
ZW
10206 if (inst.operands[0].reg == inst.operands[1].reg)
10207 as_tsktsk (_("rdhi and rdlo must be different"));
10208}
a737bd4d 10209
c19d1205
ZW
10210/* ARM V5E (El Segundo) signed-multiply (argument parse)
10211 SMULxy{cond} Rd,Rm,Rs
10212 Error if any register is R15. */
a737bd4d 10213
c19d1205
ZW
10214static void
10215do_smul (void)
10216{
10217 inst.instruction |= inst.operands[0].reg << 16;
10218 inst.instruction |= inst.operands[1].reg;
10219 inst.instruction |= inst.operands[2].reg << 8;
10220}
a737bd4d 10221
b6702015
PB
10222/* ARM V6 srs (argument parse). The variable fields in the encoding are
10223 the same for both ARM and Thumb-2. */
a737bd4d 10224
c19d1205
ZW
10225static void
10226do_srs (void)
10227{
b6702015
PB
10228 int reg;
10229
10230 if (inst.operands[0].present)
10231 {
10232 reg = inst.operands[0].reg;
fdfde340 10233 constraint (reg != REG_SP, _("SRS base register must be r13"));
b6702015
PB
10234 }
10235 else
fdfde340 10236 reg = REG_SP;
b6702015
PB
10237
10238 inst.instruction |= reg << 16;
10239 inst.instruction |= inst.operands[1].imm;
10240 if (inst.operands[0].writeback || inst.operands[1].writeback)
c19d1205
ZW
10241 inst.instruction |= WRITE_BACK;
10242}
a737bd4d 10243
c19d1205 10244/* ARM V6 strex (argument parse). */
a737bd4d 10245
c19d1205
ZW
10246static void
10247do_strex (void)
10248{
10249 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
10250 || inst.operands[2].postind || inst.operands[2].writeback
10251 || inst.operands[2].immisreg || inst.operands[2].shifted
01cfc07f
NC
10252 || inst.operands[2].negative
10253 /* See comment in do_ldrex(). */
10254 || (inst.operands[2].reg == REG_PC),
10255 BAD_ADDR_MODE);
a737bd4d 10256
c19d1205
ZW
10257 constraint (inst.operands[0].reg == inst.operands[1].reg
10258 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
a737bd4d 10259
e2b0ab59
AV
10260 constraint (inst.relocs[0].exp.X_op != O_constant
10261 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 10262 _("offset must be zero in ARM encoding"));
a737bd4d 10263
c19d1205
ZW
10264 inst.instruction |= inst.operands[0].reg << 12;
10265 inst.instruction |= inst.operands[1].reg;
10266 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 10267 inst.relocs[0].type = BFD_RELOC_UNUSED;
e16bb312
NC
10268}
10269
877807f8
NC
10270static void
10271do_t_strexbh (void)
10272{
10273 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
10274 || inst.operands[2].postind || inst.operands[2].writeback
10275 || inst.operands[2].immisreg || inst.operands[2].shifted
10276 || inst.operands[2].negative,
10277 BAD_ADDR_MODE);
10278
10279 constraint (inst.operands[0].reg == inst.operands[1].reg
10280 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10281
10282 do_rm_rd_rn ();
10283}
10284
e16bb312 10285static void
c19d1205 10286do_strexd (void)
e16bb312 10287{
c19d1205
ZW
10288 constraint (inst.operands[1].reg % 2 != 0,
10289 _("even register required"));
10290 constraint (inst.operands[2].present
10291 && inst.operands[2].reg != inst.operands[1].reg + 1,
10292 _("can only store two consecutive registers"));
10293 /* If op 2 were present and equal to PC, this function wouldn't
10294 have been called in the first place. */
10295 constraint (inst.operands[1].reg == REG_LR, _("r14 not allowed here"));
e16bb312 10296
c19d1205
ZW
10297 constraint (inst.operands[0].reg == inst.operands[1].reg
10298 || inst.operands[0].reg == inst.operands[1].reg + 1
10299 || inst.operands[0].reg == inst.operands[3].reg,
10300 BAD_OVERLAP);
e16bb312 10301
c19d1205
ZW
10302 inst.instruction |= inst.operands[0].reg << 12;
10303 inst.instruction |= inst.operands[1].reg;
10304 inst.instruction |= inst.operands[3].reg << 16;
e16bb312
NC
10305}
10306
9eb6c0f1
MGD
10307/* ARM V8 STRL. */
10308static void
4b8c8c02 10309do_stlex (void)
9eb6c0f1
MGD
10310{
10311 constraint (inst.operands[0].reg == inst.operands[1].reg
10312 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10313
10314 do_rd_rm_rn ();
10315}
10316
10317static void
4b8c8c02 10318do_t_stlex (void)
9eb6c0f1
MGD
10319{
10320 constraint (inst.operands[0].reg == inst.operands[1].reg
10321 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10322
10323 do_rm_rd_rn ();
10324}
10325
c19d1205
ZW
10326/* ARM V6 SXTAH extracts a 16-bit value from a register, sign
10327 extends it to 32-bits, and adds the result to a value in another
10328 register. You can specify a rotation by 0, 8, 16, or 24 bits
10329 before extracting the 16-bit value.
10330 SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
10331 Condition defaults to COND_ALWAYS.
10332 Error if any register uses R15. */
10333
e16bb312 10334static void
c19d1205 10335do_sxtah (void)
e16bb312 10336{
c19d1205
ZW
10337 inst.instruction |= inst.operands[0].reg << 12;
10338 inst.instruction |= inst.operands[1].reg << 16;
10339 inst.instruction |= inst.operands[2].reg;
10340 inst.instruction |= inst.operands[3].imm << 10;
10341}
e16bb312 10342
c19d1205 10343/* ARM V6 SXTH.
e16bb312 10344
c19d1205
ZW
10345 SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
10346 Condition defaults to COND_ALWAYS.
10347 Error if any register uses R15. */
e16bb312
NC
10348
10349static void
c19d1205 10350do_sxth (void)
e16bb312 10351{
c19d1205
ZW
10352 inst.instruction |= inst.operands[0].reg << 12;
10353 inst.instruction |= inst.operands[1].reg;
10354 inst.instruction |= inst.operands[2].imm << 10;
e16bb312 10355}
c19d1205
ZW
10356\f
10357/* VFP instructions. In a logical order: SP variant first, monad
10358 before dyad, arithmetic then move then load/store. */
e16bb312
NC
10359
10360static void
c19d1205 10361do_vfp_sp_monadic (void)
e16bb312 10362{
57785aa2
AV
10363 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10364 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10365 _(BAD_FPU));
10366
5287ad62
JB
10367 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10368 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
10369}
10370
10371static void
c19d1205 10372do_vfp_sp_dyadic (void)
e16bb312 10373{
5287ad62
JB
10374 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10375 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
10376 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
10377}
10378
10379static void
c19d1205 10380do_vfp_sp_compare_z (void)
e16bb312 10381{
5287ad62 10382 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
e16bb312
NC
10383}
10384
10385static void
c19d1205 10386do_vfp_dp_sp_cvt (void)
e16bb312 10387{
5287ad62
JB
10388 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10389 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
10390}
10391
10392static void
c19d1205 10393do_vfp_sp_dp_cvt (void)
e16bb312 10394{
5287ad62
JB
10395 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10396 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
e16bb312
NC
10397}
10398
10399static void
c19d1205 10400do_vfp_reg_from_sp (void)
e16bb312 10401{
57785aa2
AV
10402 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10403 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10404 _(BAD_FPU));
10405
c19d1205 10406 inst.instruction |= inst.operands[0].reg << 12;
5287ad62 10407 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
e16bb312
NC
10408}
10409
10410static void
c19d1205 10411do_vfp_reg2_from_sp2 (void)
e16bb312 10412{
c19d1205
ZW
10413 constraint (inst.operands[2].imm != 2,
10414 _("only two consecutive VFP SP registers allowed here"));
10415 inst.instruction |= inst.operands[0].reg << 12;
10416 inst.instruction |= inst.operands[1].reg << 16;
5287ad62 10417 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
10418}
10419
10420static void
c19d1205 10421do_vfp_sp_from_reg (void)
e16bb312 10422{
57785aa2
AV
10423 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10424 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10425 _(BAD_FPU));
10426
5287ad62 10427 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sn);
c19d1205 10428 inst.instruction |= inst.operands[1].reg << 12;
e16bb312
NC
10429}
10430
10431static void
c19d1205 10432do_vfp_sp2_from_reg2 (void)
e16bb312 10433{
c19d1205
ZW
10434 constraint (inst.operands[0].imm != 2,
10435 _("only two consecutive VFP SP registers allowed here"));
5287ad62 10436 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sm);
c19d1205
ZW
10437 inst.instruction |= inst.operands[1].reg << 12;
10438 inst.instruction |= inst.operands[2].reg << 16;
e16bb312
NC
10439}
10440
10441static void
c19d1205 10442do_vfp_sp_ldst (void)
e16bb312 10443{
5287ad62 10444 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
c19d1205 10445 encode_arm_cp_address (1, FALSE, TRUE, 0);
e16bb312
NC
10446}
10447
10448static void
c19d1205 10449do_vfp_dp_ldst (void)
e16bb312 10450{
5287ad62 10451 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
c19d1205 10452 encode_arm_cp_address (1, FALSE, TRUE, 0);
e16bb312
NC
10453}
10454
c19d1205 10455
e16bb312 10456static void
c19d1205 10457vfp_sp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 10458{
c19d1205
ZW
10459 if (inst.operands[0].writeback)
10460 inst.instruction |= WRITE_BACK;
10461 else
10462 constraint (ldstm_type != VFP_LDSTMIA,
10463 _("this addressing mode requires base-register writeback"));
10464 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 10465 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sd);
c19d1205 10466 inst.instruction |= inst.operands[1].imm;
e16bb312
NC
10467}
10468
10469static void
c19d1205 10470vfp_dp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 10471{
c19d1205 10472 int count;
e16bb312 10473
c19d1205
ZW
10474 if (inst.operands[0].writeback)
10475 inst.instruction |= WRITE_BACK;
10476 else
10477 constraint (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX,
10478 _("this addressing mode requires base-register writeback"));
e16bb312 10479
c19d1205 10480 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 10481 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
e16bb312 10482
c19d1205
ZW
10483 count = inst.operands[1].imm << 1;
10484 if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
10485 count += 1;
e16bb312 10486
c19d1205 10487 inst.instruction |= count;
e16bb312
NC
10488}
10489
10490static void
c19d1205 10491do_vfp_sp_ldstmia (void)
e16bb312 10492{
c19d1205 10493 vfp_sp_ldstm (VFP_LDSTMIA);
e16bb312
NC
10494}
10495
10496static void
c19d1205 10497do_vfp_sp_ldstmdb (void)
e16bb312 10498{
c19d1205 10499 vfp_sp_ldstm (VFP_LDSTMDB);
e16bb312
NC
10500}
10501
10502static void
c19d1205 10503do_vfp_dp_ldstmia (void)
e16bb312 10504{
c19d1205 10505 vfp_dp_ldstm (VFP_LDSTMIA);
e16bb312
NC
10506}
10507
10508static void
c19d1205 10509do_vfp_dp_ldstmdb (void)
e16bb312 10510{
c19d1205 10511 vfp_dp_ldstm (VFP_LDSTMDB);
e16bb312
NC
10512}
10513
10514static void
c19d1205 10515do_vfp_xp_ldstmia (void)
e16bb312 10516{
c19d1205
ZW
10517 vfp_dp_ldstm (VFP_LDSTMIAX);
10518}
e16bb312 10519
c19d1205
ZW
10520static void
10521do_vfp_xp_ldstmdb (void)
10522{
10523 vfp_dp_ldstm (VFP_LDSTMDBX);
e16bb312 10524}
5287ad62
JB
10525
10526static void
10527do_vfp_dp_rd_rm (void)
10528{
57785aa2
AV
10529 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
10530 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10531 _(BAD_FPU));
10532
5287ad62
JB
10533 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10534 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
10535}
10536
10537static void
10538do_vfp_dp_rn_rd (void)
10539{
10540 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dn);
10541 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10542}
10543
10544static void
10545do_vfp_dp_rd_rn (void)
10546{
10547 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10548 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10549}
10550
10551static void
10552do_vfp_dp_rd_rn_rm (void)
10553{
57785aa2
AV
10554 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
10555 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10556 _(BAD_FPU));
10557
5287ad62
JB
10558 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10559 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10560 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dm);
10561}
10562
10563static void
10564do_vfp_dp_rd (void)
10565{
10566 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10567}
10568
10569static void
10570do_vfp_dp_rm_rd_rn (void)
10571{
57785aa2
AV
10572 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
10573 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10574 _(BAD_FPU));
10575
5287ad62
JB
10576 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dm);
10577 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10578 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dn);
10579}
10580
10581/* VFPv3 instructions. */
10582static void
10583do_vfp_sp_const (void)
10584{
10585 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
00249aaa
PB
10586 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
10587 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
10588}
10589
10590static void
10591do_vfp_dp_const (void)
10592{
10593 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
00249aaa
PB
10594 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
10595 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
10596}
10597
10598static void
10599vfp_conv (int srcsize)
10600{
5f1af56b
MGD
10601 int immbits = srcsize - inst.operands[1].imm;
10602
fa94de6b
RM
10603 if (srcsize == 16 && !(immbits >= 0 && immbits <= srcsize))
10604 {
5f1af56b 10605 /* If srcsize is 16, inst.operands[1].imm must be in the range 0-16.
477330fc 10606 i.e. immbits must be in range 0 - 16. */
5f1af56b
MGD
10607 inst.error = _("immediate value out of range, expected range [0, 16]");
10608 return;
10609 }
fa94de6b 10610 else if (srcsize == 32 && !(immbits >= 0 && immbits < srcsize))
5f1af56b
MGD
10611 {
10612 /* If srcsize is 32, inst.operands[1].imm must be in the range 1-32.
477330fc 10613 i.e. immbits must be in range 0 - 31. */
5f1af56b
MGD
10614 inst.error = _("immediate value out of range, expected range [1, 32]");
10615 return;
10616 }
10617
5287ad62
JB
10618 inst.instruction |= (immbits & 1) << 5;
10619 inst.instruction |= (immbits >> 1);
10620}
10621
10622static void
10623do_vfp_sp_conv_16 (void)
10624{
10625 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10626 vfp_conv (16);
10627}
10628
10629static void
10630do_vfp_dp_conv_16 (void)
10631{
10632 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10633 vfp_conv (16);
10634}
10635
10636static void
10637do_vfp_sp_conv_32 (void)
10638{
10639 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10640 vfp_conv (32);
10641}
10642
10643static void
10644do_vfp_dp_conv_32 (void)
10645{
10646 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10647 vfp_conv (32);
10648}
c19d1205
ZW
10649\f
10650/* FPA instructions. Also in a logical order. */
e16bb312 10651
c19d1205
ZW
10652static void
10653do_fpa_cmp (void)
10654{
10655 inst.instruction |= inst.operands[0].reg << 16;
10656 inst.instruction |= inst.operands[1].reg;
10657}
b99bd4ef
NC
10658
10659static void
c19d1205 10660do_fpa_ldmstm (void)
b99bd4ef 10661{
c19d1205
ZW
10662 inst.instruction |= inst.operands[0].reg << 12;
10663 switch (inst.operands[1].imm)
10664 {
10665 case 1: inst.instruction |= CP_T_X; break;
10666 case 2: inst.instruction |= CP_T_Y; break;
10667 case 3: inst.instruction |= CP_T_Y | CP_T_X; break;
10668 case 4: break;
10669 default: abort ();
10670 }
b99bd4ef 10671
c19d1205
ZW
10672 if (inst.instruction & (PRE_INDEX | INDEX_UP))
10673 {
10674 /* The instruction specified "ea" or "fd", so we can only accept
10675 [Rn]{!}. The instruction does not really support stacking or
10676 unstacking, so we have to emulate these by setting appropriate
10677 bits and offsets. */
e2b0ab59
AV
10678 constraint (inst.relocs[0].exp.X_op != O_constant
10679 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 10680 _("this instruction does not support indexing"));
b99bd4ef 10681
c19d1205 10682 if ((inst.instruction & PRE_INDEX) || inst.operands[2].writeback)
e2b0ab59 10683 inst.relocs[0].exp.X_add_number = 12 * inst.operands[1].imm;
b99bd4ef 10684
c19d1205 10685 if (!(inst.instruction & INDEX_UP))
e2b0ab59 10686 inst.relocs[0].exp.X_add_number = -inst.relocs[0].exp.X_add_number;
b99bd4ef 10687
c19d1205
ZW
10688 if (!(inst.instruction & PRE_INDEX) && inst.operands[2].writeback)
10689 {
10690 inst.operands[2].preind = 0;
10691 inst.operands[2].postind = 1;
10692 }
10693 }
b99bd4ef 10694
c19d1205 10695 encode_arm_cp_address (2, TRUE, TRUE, 0);
b99bd4ef 10696}
c19d1205
ZW
10697\f
10698/* iWMMXt instructions: strictly in alphabetical order. */
b99bd4ef 10699
c19d1205
ZW
10700static void
10701do_iwmmxt_tandorc (void)
10702{
10703 constraint (inst.operands[0].reg != REG_PC, _("only r15 allowed here"));
10704}
b99bd4ef 10705
c19d1205
ZW
10706static void
10707do_iwmmxt_textrc (void)
10708{
10709 inst.instruction |= inst.operands[0].reg << 12;
10710 inst.instruction |= inst.operands[1].imm;
10711}
b99bd4ef
NC
10712
10713static void
c19d1205 10714do_iwmmxt_textrm (void)
b99bd4ef 10715{
c19d1205
ZW
10716 inst.instruction |= inst.operands[0].reg << 12;
10717 inst.instruction |= inst.operands[1].reg << 16;
10718 inst.instruction |= inst.operands[2].imm;
10719}
b99bd4ef 10720
c19d1205
ZW
10721static void
10722do_iwmmxt_tinsr (void)
10723{
10724 inst.instruction |= inst.operands[0].reg << 16;
10725 inst.instruction |= inst.operands[1].reg << 12;
10726 inst.instruction |= inst.operands[2].imm;
10727}
b99bd4ef 10728
c19d1205
ZW
10729static void
10730do_iwmmxt_tmia (void)
10731{
10732 inst.instruction |= inst.operands[0].reg << 5;
10733 inst.instruction |= inst.operands[1].reg;
10734 inst.instruction |= inst.operands[2].reg << 12;
10735}
b99bd4ef 10736
c19d1205
ZW
10737static void
10738do_iwmmxt_waligni (void)
10739{
10740 inst.instruction |= inst.operands[0].reg << 12;
10741 inst.instruction |= inst.operands[1].reg << 16;
10742 inst.instruction |= inst.operands[2].reg;
10743 inst.instruction |= inst.operands[3].imm << 20;
10744}
b99bd4ef 10745
2d447fca
JM
10746static void
10747do_iwmmxt_wmerge (void)
10748{
10749 inst.instruction |= inst.operands[0].reg << 12;
10750 inst.instruction |= inst.operands[1].reg << 16;
10751 inst.instruction |= inst.operands[2].reg;
10752 inst.instruction |= inst.operands[3].imm << 21;
10753}
10754
c19d1205
ZW
10755static void
10756do_iwmmxt_wmov (void)
10757{
10758 /* WMOV rD, rN is an alias for WOR rD, rN, rN. */
10759 inst.instruction |= inst.operands[0].reg << 12;
10760 inst.instruction |= inst.operands[1].reg << 16;
10761 inst.instruction |= inst.operands[1].reg;
10762}
b99bd4ef 10763
c19d1205
ZW
10764static void
10765do_iwmmxt_wldstbh (void)
10766{
8f06b2d8 10767 int reloc;
c19d1205 10768 inst.instruction |= inst.operands[0].reg << 12;
8f06b2d8
PB
10769 if (thumb_mode)
10770 reloc = BFD_RELOC_ARM_T32_CP_OFF_IMM_S2;
10771 else
10772 reloc = BFD_RELOC_ARM_CP_OFF_IMM_S2;
10773 encode_arm_cp_address (1, TRUE, FALSE, reloc);
b99bd4ef
NC
10774}
10775
c19d1205
ZW
10776static void
10777do_iwmmxt_wldstw (void)
10778{
10779 /* RIWR_RIWC clears .isreg for a control register. */
10780 if (!inst.operands[0].isreg)
10781 {
10782 constraint (inst.cond != COND_ALWAYS, BAD_COND);
10783 inst.instruction |= 0xf0000000;
10784 }
b99bd4ef 10785
c19d1205
ZW
10786 inst.instruction |= inst.operands[0].reg << 12;
10787 encode_arm_cp_address (1, TRUE, TRUE, 0);
10788}
b99bd4ef
NC
10789
10790static void
c19d1205 10791do_iwmmxt_wldstd (void)
b99bd4ef 10792{
c19d1205 10793 inst.instruction |= inst.operands[0].reg << 12;
2d447fca
JM
10794 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2)
10795 && inst.operands[1].immisreg)
10796 {
10797 inst.instruction &= ~0x1a000ff;
eff0bc54 10798 inst.instruction |= (0xfU << 28);
2d447fca
JM
10799 if (inst.operands[1].preind)
10800 inst.instruction |= PRE_INDEX;
10801 if (!inst.operands[1].negative)
10802 inst.instruction |= INDEX_UP;
10803 if (inst.operands[1].writeback)
10804 inst.instruction |= WRITE_BACK;
10805 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 10806 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
2d447fca
JM
10807 inst.instruction |= inst.operands[1].imm;
10808 }
10809 else
10810 encode_arm_cp_address (1, TRUE, FALSE, 0);
c19d1205 10811}
b99bd4ef 10812
c19d1205
ZW
10813static void
10814do_iwmmxt_wshufh (void)
10815{
10816 inst.instruction |= inst.operands[0].reg << 12;
10817 inst.instruction |= inst.operands[1].reg << 16;
10818 inst.instruction |= ((inst.operands[2].imm & 0xf0) << 16);
10819 inst.instruction |= (inst.operands[2].imm & 0x0f);
10820}
b99bd4ef 10821
c19d1205
ZW
10822static void
10823do_iwmmxt_wzero (void)
10824{
10825 /* WZERO reg is an alias for WANDN reg, reg, reg. */
10826 inst.instruction |= inst.operands[0].reg;
10827 inst.instruction |= inst.operands[0].reg << 12;
10828 inst.instruction |= inst.operands[0].reg << 16;
10829}
2d447fca
JM
10830
10831static void
10832do_iwmmxt_wrwrwr_or_imm5 (void)
10833{
10834 if (inst.operands[2].isreg)
10835 do_rd_rn_rm ();
10836 else {
10837 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2),
10838 _("immediate operand requires iWMMXt2"));
10839 do_rd_rn ();
10840 if (inst.operands[2].imm == 0)
10841 {
10842 switch ((inst.instruction >> 20) & 0xf)
10843 {
10844 case 4:
10845 case 5:
10846 case 6:
5f4273c7 10847 case 7:
2d447fca
JM
10848 /* w...h wrd, wrn, #0 -> wrorh wrd, wrn, #16. */
10849 inst.operands[2].imm = 16;
10850 inst.instruction = (inst.instruction & 0xff0fffff) | (0x7 << 20);
10851 break;
10852 case 8:
10853 case 9:
10854 case 10:
10855 case 11:
10856 /* w...w wrd, wrn, #0 -> wrorw wrd, wrn, #32. */
10857 inst.operands[2].imm = 32;
10858 inst.instruction = (inst.instruction & 0xff0fffff) | (0xb << 20);
10859 break;
10860 case 12:
10861 case 13:
10862 case 14:
10863 case 15:
10864 {
10865 /* w...d wrd, wrn, #0 -> wor wrd, wrn, wrn. */
10866 unsigned long wrn;
10867 wrn = (inst.instruction >> 16) & 0xf;
10868 inst.instruction &= 0xff0fff0f;
10869 inst.instruction |= wrn;
10870 /* Bail out here; the instruction is now assembled. */
10871 return;
10872 }
10873 }
10874 }
10875 /* Map 32 -> 0, etc. */
10876 inst.operands[2].imm &= 0x1f;
eff0bc54 10877 inst.instruction |= (0xfU << 28) | ((inst.operands[2].imm & 0x10) << 4) | (inst.operands[2].imm & 0xf);
2d447fca
JM
10878 }
10879}
c19d1205
ZW
10880\f
10881/* Cirrus Maverick instructions. Simple 2-, 3-, and 4-register
10882 operations first, then control, shift, and load/store. */
b99bd4ef 10883
c19d1205 10884/* Insns like "foo X,Y,Z". */
b99bd4ef 10885
c19d1205
ZW
10886static void
10887do_mav_triple (void)
10888{
10889 inst.instruction |= inst.operands[0].reg << 16;
10890 inst.instruction |= inst.operands[1].reg;
10891 inst.instruction |= inst.operands[2].reg << 12;
10892}
b99bd4ef 10893
c19d1205
ZW
10894/* Insns like "foo W,X,Y,Z".
10895 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
a737bd4d 10896
c19d1205
ZW
10897static void
10898do_mav_quad (void)
10899{
10900 inst.instruction |= inst.operands[0].reg << 5;
10901 inst.instruction |= inst.operands[1].reg << 12;
10902 inst.instruction |= inst.operands[2].reg << 16;
10903 inst.instruction |= inst.operands[3].reg;
a737bd4d
NC
10904}
10905
c19d1205
ZW
10906/* cfmvsc32<cond> DSPSC,MVDX[15:0]. */
10907static void
10908do_mav_dspsc (void)
a737bd4d 10909{
c19d1205
ZW
10910 inst.instruction |= inst.operands[1].reg << 12;
10911}
a737bd4d 10912
c19d1205
ZW
10913/* Maverick shift immediate instructions.
10914 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
10915 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
a737bd4d 10916
c19d1205
ZW
10917static void
10918do_mav_shift (void)
10919{
10920 int imm = inst.operands[2].imm;
a737bd4d 10921
c19d1205
ZW
10922 inst.instruction |= inst.operands[0].reg << 12;
10923 inst.instruction |= inst.operands[1].reg << 16;
a737bd4d 10924
c19d1205
ZW
10925 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
10926 Bits 5-7 of the insn should have bits 4-6 of the immediate.
10927 Bit 4 should be 0. */
10928 imm = (imm & 0xf) | ((imm & 0x70) << 1);
a737bd4d 10929
c19d1205
ZW
10930 inst.instruction |= imm;
10931}
10932\f
10933/* XScale instructions. Also sorted arithmetic before move. */
a737bd4d 10934
c19d1205
ZW
10935/* Xscale multiply-accumulate (argument parse)
10936 MIAcc acc0,Rm,Rs
10937 MIAPHcc acc0,Rm,Rs
10938 MIAxycc acc0,Rm,Rs. */
a737bd4d 10939
c19d1205
ZW
10940static void
10941do_xsc_mia (void)
10942{
10943 inst.instruction |= inst.operands[1].reg;
10944 inst.instruction |= inst.operands[2].reg << 12;
10945}
a737bd4d 10946
c19d1205 10947/* Xscale move-accumulator-register (argument parse)
a737bd4d 10948
c19d1205 10949 MARcc acc0,RdLo,RdHi. */
b99bd4ef 10950
c19d1205
ZW
10951static void
10952do_xsc_mar (void)
10953{
10954 inst.instruction |= inst.operands[1].reg << 12;
10955 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
10956}
10957
c19d1205 10958/* Xscale move-register-accumulator (argument parse)
b99bd4ef 10959
c19d1205 10960 MRAcc RdLo,RdHi,acc0. */
b99bd4ef
NC
10961
10962static void
c19d1205 10963do_xsc_mra (void)
b99bd4ef 10964{
c19d1205
ZW
10965 constraint (inst.operands[0].reg == inst.operands[1].reg, BAD_OVERLAP);
10966 inst.instruction |= inst.operands[0].reg << 12;
10967 inst.instruction |= inst.operands[1].reg << 16;
10968}
10969\f
10970/* Encoding functions relevant only to Thumb. */
b99bd4ef 10971
c19d1205
ZW
10972/* inst.operands[i] is a shifted-register operand; encode
10973 it into inst.instruction in the format used by Thumb32. */
10974
10975static void
10976encode_thumb32_shifted_operand (int i)
10977{
e2b0ab59 10978 unsigned int value = inst.relocs[0].exp.X_add_number;
c19d1205 10979 unsigned int shift = inst.operands[i].shift_kind;
b99bd4ef 10980
9c3c69f2
PB
10981 constraint (inst.operands[i].immisreg,
10982 _("shift by register not allowed in thumb mode"));
c19d1205
ZW
10983 inst.instruction |= inst.operands[i].reg;
10984 if (shift == SHIFT_RRX)
10985 inst.instruction |= SHIFT_ROR << 4;
10986 else
b99bd4ef 10987 {
e2b0ab59 10988 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
10989 _("expression too complex"));
10990
10991 constraint (value > 32
10992 || (value == 32 && (shift == SHIFT_LSL
10993 || shift == SHIFT_ROR)),
10994 _("shift expression is too large"));
10995
10996 if (value == 0)
10997 shift = SHIFT_LSL;
10998 else if (value == 32)
10999 value = 0;
11000
11001 inst.instruction |= shift << 4;
11002 inst.instruction |= (value & 0x1c) << 10;
11003 inst.instruction |= (value & 0x03) << 6;
b99bd4ef 11004 }
c19d1205 11005}
b99bd4ef 11006
b99bd4ef 11007
c19d1205
ZW
11008/* inst.operands[i] was set up by parse_address. Encode it into a
11009 Thumb32 format load or store instruction. Reject forms that cannot
11010 be used with such instructions. If is_t is true, reject forms that
11011 cannot be used with a T instruction; if is_d is true, reject forms
5be8be5d
DG
11012 that cannot be used with a D instruction. If it is a store insn,
11013 reject PC in Rn. */
b99bd4ef 11014
c19d1205
ZW
11015static void
11016encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
11017{
5be8be5d 11018 const bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
c19d1205
ZW
11019
11020 constraint (!inst.operands[i].isreg,
53365c0d 11021 _("Instruction does not support =N addresses"));
b99bd4ef 11022
c19d1205
ZW
11023 inst.instruction |= inst.operands[i].reg << 16;
11024 if (inst.operands[i].immisreg)
b99bd4ef 11025 {
5be8be5d 11026 constraint (is_pc, BAD_PC_ADDRESSING);
c19d1205
ZW
11027 constraint (is_t || is_d, _("cannot use register index with this instruction"));
11028 constraint (inst.operands[i].negative,
11029 _("Thumb does not support negative register indexing"));
11030 constraint (inst.operands[i].postind,
11031 _("Thumb does not support register post-indexing"));
11032 constraint (inst.operands[i].writeback,
11033 _("Thumb does not support register indexing with writeback"));
11034 constraint (inst.operands[i].shifted && inst.operands[i].shift_kind != SHIFT_LSL,
11035 _("Thumb supports only LSL in shifted register indexing"));
b99bd4ef 11036
f40d1643 11037 inst.instruction |= inst.operands[i].imm;
c19d1205 11038 if (inst.operands[i].shifted)
b99bd4ef 11039 {
e2b0ab59 11040 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 11041 _("expression too complex"));
e2b0ab59
AV
11042 constraint (inst.relocs[0].exp.X_add_number < 0
11043 || inst.relocs[0].exp.X_add_number > 3,
c19d1205 11044 _("shift out of range"));
e2b0ab59 11045 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
c19d1205 11046 }
e2b0ab59 11047 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205
ZW
11048 }
11049 else if (inst.operands[i].preind)
11050 {
5be8be5d 11051 constraint (is_pc && inst.operands[i].writeback, BAD_PC_WRITEBACK);
f40d1643 11052 constraint (is_t && inst.operands[i].writeback,
c19d1205 11053 _("cannot use writeback with this instruction"));
4755303e
WN
11054 constraint (is_pc && ((inst.instruction & THUMB2_LOAD_BIT) == 0),
11055 BAD_PC_ADDRESSING);
c19d1205
ZW
11056
11057 if (is_d)
11058 {
11059 inst.instruction |= 0x01000000;
11060 if (inst.operands[i].writeback)
11061 inst.instruction |= 0x00200000;
b99bd4ef 11062 }
c19d1205 11063 else
b99bd4ef 11064 {
c19d1205
ZW
11065 inst.instruction |= 0x00000c00;
11066 if (inst.operands[i].writeback)
11067 inst.instruction |= 0x00000100;
b99bd4ef 11068 }
e2b0ab59 11069 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
b99bd4ef 11070 }
c19d1205 11071 else if (inst.operands[i].postind)
b99bd4ef 11072 {
9c2799c2 11073 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
11074 constraint (is_pc, _("cannot use post-indexing with PC-relative addressing"));
11075 constraint (is_t, _("cannot use post-indexing with this instruction"));
11076
11077 if (is_d)
11078 inst.instruction |= 0x00200000;
11079 else
11080 inst.instruction |= 0x00000900;
e2b0ab59 11081 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
c19d1205
ZW
11082 }
11083 else /* unindexed - only for coprocessor */
11084 inst.error = _("instruction does not accept unindexed addressing");
11085}
11086
11087/* Table of Thumb instructions which exist in both 16- and 32-bit
11088 encodings (the latter only in post-V6T2 cores). The index is the
11089 value used in the insns table below. When there is more than one
11090 possible 16-bit encoding for the instruction, this table always
0110f2b8
PB
11091 holds variant (1).
11092 Also contains several pseudo-instructions used during relaxation. */
c19d1205 11093#define T16_32_TAB \
21d799b5
NC
11094 X(_adc, 4140, eb400000), \
11095 X(_adcs, 4140, eb500000), \
11096 X(_add, 1c00, eb000000), \
11097 X(_adds, 1c00, eb100000), \
11098 X(_addi, 0000, f1000000), \
11099 X(_addis, 0000, f1100000), \
11100 X(_add_pc,000f, f20f0000), \
11101 X(_add_sp,000d, f10d0000), \
11102 X(_adr, 000f, f20f0000), \
11103 X(_and, 4000, ea000000), \
11104 X(_ands, 4000, ea100000), \
11105 X(_asr, 1000, fa40f000), \
11106 X(_asrs, 1000, fa50f000), \
11107 X(_b, e000, f000b000), \
11108 X(_bcond, d000, f0008000), \
4389b29a 11109 X(_bf, 0000, f040e001), \
f6b2b12d 11110 X(_bfcsel,0000, f000e001), \
f1c7f421 11111 X(_bfx, 0000, f060e001), \
65d1bc05 11112 X(_bfl, 0000, f000c001), \
f1c7f421 11113 X(_bflx, 0000, f070e001), \
21d799b5
NC
11114 X(_bic, 4380, ea200000), \
11115 X(_bics, 4380, ea300000), \
11116 X(_cmn, 42c0, eb100f00), \
11117 X(_cmp, 2800, ebb00f00), \
11118 X(_cpsie, b660, f3af8400), \
11119 X(_cpsid, b670, f3af8600), \
11120 X(_cpy, 4600, ea4f0000), \
11121 X(_dec_sp,80dd, f1ad0d00), \
60f993ce 11122 X(_dls, 0000, f040e001), \
21d799b5
NC
11123 X(_eor, 4040, ea800000), \
11124 X(_eors, 4040, ea900000), \
11125 X(_inc_sp,00dd, f10d0d00), \
11126 X(_ldmia, c800, e8900000), \
11127 X(_ldr, 6800, f8500000), \
11128 X(_ldrb, 7800, f8100000), \
11129 X(_ldrh, 8800, f8300000), \
11130 X(_ldrsb, 5600, f9100000), \
11131 X(_ldrsh, 5e00, f9300000), \
11132 X(_ldr_pc,4800, f85f0000), \
11133 X(_ldr_pc2,4800, f85f0000), \
11134 X(_ldr_sp,9800, f85d0000), \
60f993ce 11135 X(_le, 0000, f00fc001), \
21d799b5
NC
11136 X(_lsl, 0000, fa00f000), \
11137 X(_lsls, 0000, fa10f000), \
11138 X(_lsr, 0800, fa20f000), \
11139 X(_lsrs, 0800, fa30f000), \
11140 X(_mov, 2000, ea4f0000), \
11141 X(_movs, 2000, ea5f0000), \
11142 X(_mul, 4340, fb00f000), \
11143 X(_muls, 4340, ffffffff), /* no 32b muls */ \
11144 X(_mvn, 43c0, ea6f0000), \
11145 X(_mvns, 43c0, ea7f0000), \
11146 X(_neg, 4240, f1c00000), /* rsb #0 */ \
11147 X(_negs, 4240, f1d00000), /* rsbs #0 */ \
11148 X(_orr, 4300, ea400000), \
11149 X(_orrs, 4300, ea500000), \
11150 X(_pop, bc00, e8bd0000), /* ldmia sp!,... */ \
11151 X(_push, b400, e92d0000), /* stmdb sp!,... */ \
11152 X(_rev, ba00, fa90f080), \
11153 X(_rev16, ba40, fa90f090), \
11154 X(_revsh, bac0, fa90f0b0), \
11155 X(_ror, 41c0, fa60f000), \
11156 X(_rors, 41c0, fa70f000), \
11157 X(_sbc, 4180, eb600000), \
11158 X(_sbcs, 4180, eb700000), \
11159 X(_stmia, c000, e8800000), \
11160 X(_str, 6000, f8400000), \
11161 X(_strb, 7000, f8000000), \
11162 X(_strh, 8000, f8200000), \
11163 X(_str_sp,9000, f84d0000), \
11164 X(_sub, 1e00, eba00000), \
11165 X(_subs, 1e00, ebb00000), \
11166 X(_subi, 8000, f1a00000), \
11167 X(_subis, 8000, f1b00000), \
11168 X(_sxtb, b240, fa4ff080), \
11169 X(_sxth, b200, fa0ff080), \
11170 X(_tst, 4200, ea100f00), \
11171 X(_uxtb, b2c0, fa5ff080), \
11172 X(_uxth, b280, fa1ff080), \
11173 X(_nop, bf00, f3af8000), \
11174 X(_yield, bf10, f3af8001), \
11175 X(_wfe, bf20, f3af8002), \
11176 X(_wfi, bf30, f3af8003), \
60f993ce 11177 X(_wls, 0000, f040c001), \
53c4b28b 11178 X(_sev, bf40, f3af8004), \
74db7efb
NC
11179 X(_sevl, bf50, f3af8005), \
11180 X(_udf, de00, f7f0a000)
c19d1205
ZW
11181
11182/* To catch errors in encoding functions, the codes are all offset by
11183 0xF800, putting them in one of the 32-bit prefix ranges, ergo undefined
11184 as 16-bit instructions. */
21d799b5 11185#define X(a,b,c) T_MNEM##a
c19d1205
ZW
11186enum t16_32_codes { T16_32_OFFSET = 0xF7FF, T16_32_TAB };
11187#undef X
11188
11189#define X(a,b,c) 0x##b
11190static const unsigned short thumb_op16[] = { T16_32_TAB };
11191#define THUMB_OP16(n) (thumb_op16[(n) - (T16_32_OFFSET + 1)])
11192#undef X
11193
11194#define X(a,b,c) 0x##c
11195static const unsigned int thumb_op32[] = { T16_32_TAB };
c921be7d
NC
11196#define THUMB_OP32(n) (thumb_op32[(n) - (T16_32_OFFSET + 1)])
11197#define THUMB_SETS_FLAGS(n) (THUMB_OP32 (n) & 0x00100000)
c19d1205
ZW
11198#undef X
11199#undef T16_32_TAB
11200
11201/* Thumb instruction encoders, in alphabetical order. */
11202
92e90b6e 11203/* ADDW or SUBW. */
c921be7d 11204
92e90b6e
PB
11205static void
11206do_t_add_sub_w (void)
11207{
11208 int Rd, Rn;
11209
11210 Rd = inst.operands[0].reg;
11211 Rn = inst.operands[1].reg;
11212
539d4391
NC
11213 /* If Rn is REG_PC, this is ADR; if Rn is REG_SP, then this
11214 is the SP-{plus,minus}-immediate form of the instruction. */
11215 if (Rn == REG_SP)
11216 constraint (Rd == REG_PC, BAD_PC);
11217 else
11218 reject_bad_reg (Rd);
fdfde340 11219
92e90b6e 11220 inst.instruction |= (Rn << 16) | (Rd << 8);
e2b0ab59 11221 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
92e90b6e
PB
11222}
11223
c19d1205 11224/* Parse an add or subtract instruction. We get here with inst.instruction
33eaf5de 11225 equaling any of THUMB_OPCODE_add, adds, sub, or subs. */
c19d1205
ZW
11226
11227static void
11228do_t_add_sub (void)
11229{
11230 int Rd, Rs, Rn;
11231
11232 Rd = inst.operands[0].reg;
11233 Rs = (inst.operands[1].present
11234 ? inst.operands[1].reg /* Rd, Rs, foo */
11235 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11236
e07e6e58 11237 if (Rd == REG_PC)
5ee91343 11238 set_pred_insn_type_last ();
e07e6e58 11239
c19d1205
ZW
11240 if (unified_syntax)
11241 {
0110f2b8
PB
11242 bfd_boolean flags;
11243 bfd_boolean narrow;
11244 int opcode;
11245
11246 flags = (inst.instruction == T_MNEM_adds
11247 || inst.instruction == T_MNEM_subs);
11248 if (flags)
5ee91343 11249 narrow = !in_pred_block ();
0110f2b8 11250 else
5ee91343 11251 narrow = in_pred_block ();
c19d1205 11252 if (!inst.operands[2].isreg)
b99bd4ef 11253 {
16805f35
PB
11254 int add;
11255
5c8ed6a4
JW
11256 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
11257 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340 11258
16805f35
PB
11259 add = (inst.instruction == T_MNEM_add
11260 || inst.instruction == T_MNEM_adds);
0110f2b8
PB
11261 opcode = 0;
11262 if (inst.size_req != 4)
11263 {
0110f2b8 11264 /* Attempt to use a narrow opcode, with relaxation if
477330fc 11265 appropriate. */
0110f2b8
PB
11266 if (Rd == REG_SP && Rs == REG_SP && !flags)
11267 opcode = add ? T_MNEM_inc_sp : T_MNEM_dec_sp;
11268 else if (Rd <= 7 && Rs == REG_SP && add && !flags)
11269 opcode = T_MNEM_add_sp;
11270 else if (Rd <= 7 && Rs == REG_PC && add && !flags)
11271 opcode = T_MNEM_add_pc;
11272 else if (Rd <= 7 && Rs <= 7 && narrow)
11273 {
11274 if (flags)
11275 opcode = add ? T_MNEM_addis : T_MNEM_subis;
11276 else
11277 opcode = add ? T_MNEM_addi : T_MNEM_subi;
11278 }
11279 if (opcode)
11280 {
11281 inst.instruction = THUMB_OP16(opcode);
11282 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59
AV
11283 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
11284 || (inst.relocs[0].type
11285 > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC))
a9f02af8
MG
11286 {
11287 if (inst.size_req == 2)
e2b0ab59 11288 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
a9f02af8
MG
11289 else
11290 inst.relax = opcode;
11291 }
0110f2b8
PB
11292 }
11293 else
11294 constraint (inst.size_req == 2, BAD_HIREG);
11295 }
11296 if (inst.size_req == 4
11297 || (inst.size_req != 2 && !opcode))
11298 {
e2b0ab59
AV
11299 constraint ((inst.relocs[0].type
11300 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
11301 && (inst.relocs[0].type
11302 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8 11303 THUMB1_RELOC_ONLY);
efd81785
PB
11304 if (Rd == REG_PC)
11305 {
fdfde340 11306 constraint (add, BAD_PC);
efd81785
PB
11307 constraint (Rs != REG_LR || inst.instruction != T_MNEM_subs,
11308 _("only SUBS PC, LR, #const allowed"));
e2b0ab59 11309 constraint (inst.relocs[0].exp.X_op != O_constant,
efd81785 11310 _("expression too complex"));
e2b0ab59
AV
11311 constraint (inst.relocs[0].exp.X_add_number < 0
11312 || inst.relocs[0].exp.X_add_number > 0xff,
efd81785
PB
11313 _("immediate value out of range"));
11314 inst.instruction = T2_SUBS_PC_LR
e2b0ab59
AV
11315 | inst.relocs[0].exp.X_add_number;
11316 inst.relocs[0].type = BFD_RELOC_UNUSED;
efd81785
PB
11317 return;
11318 }
11319 else if (Rs == REG_PC)
16805f35
PB
11320 {
11321 /* Always use addw/subw. */
11322 inst.instruction = add ? 0xf20f0000 : 0xf2af0000;
e2b0ab59 11323 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
16805f35
PB
11324 }
11325 else
11326 {
11327 inst.instruction = THUMB_OP32 (inst.instruction);
11328 inst.instruction = (inst.instruction & 0xe1ffffff)
11329 | 0x10000000;
11330 if (flags)
e2b0ab59 11331 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
16805f35 11332 else
e2b0ab59 11333 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_IMM;
16805f35 11334 }
dc4503c6
PB
11335 inst.instruction |= Rd << 8;
11336 inst.instruction |= Rs << 16;
0110f2b8 11337 }
b99bd4ef 11338 }
c19d1205
ZW
11339 else
11340 {
e2b0ab59 11341 unsigned int value = inst.relocs[0].exp.X_add_number;
5f4cb198
NC
11342 unsigned int shift = inst.operands[2].shift_kind;
11343
c19d1205
ZW
11344 Rn = inst.operands[2].reg;
11345 /* See if we can do this with a 16-bit instruction. */
11346 if (!inst.operands[2].shifted && inst.size_req != 4)
11347 {
e27ec89e
PB
11348 if (Rd > 7 || Rs > 7 || Rn > 7)
11349 narrow = FALSE;
11350
11351 if (narrow)
c19d1205 11352 {
e27ec89e
PB
11353 inst.instruction = ((inst.instruction == T_MNEM_adds
11354 || inst.instruction == T_MNEM_add)
c19d1205
ZW
11355 ? T_OPCODE_ADD_R3
11356 : T_OPCODE_SUB_R3);
11357 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
11358 return;
11359 }
b99bd4ef 11360
7e806470 11361 if (inst.instruction == T_MNEM_add && (Rd == Rs || Rd == Rn))
c19d1205 11362 {
7e806470
PB
11363 /* Thumb-1 cores (except v6-M) require at least one high
11364 register in a narrow non flag setting add. */
11365 if (Rd > 7 || Rn > 7
11366 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2)
11367 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_msr))
c19d1205 11368 {
7e806470
PB
11369 if (Rd == Rn)
11370 {
11371 Rn = Rs;
11372 Rs = Rd;
11373 }
c19d1205
ZW
11374 inst.instruction = T_OPCODE_ADD_HI;
11375 inst.instruction |= (Rd & 8) << 4;
11376 inst.instruction |= (Rd & 7);
11377 inst.instruction |= Rn << 3;
11378 return;
11379 }
c19d1205
ZW
11380 }
11381 }
c921be7d 11382
fdfde340 11383 constraint (Rd == REG_PC, BAD_PC);
5c8ed6a4
JW
11384 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
11385 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340
JM
11386 constraint (Rs == REG_PC, BAD_PC);
11387 reject_bad_reg (Rn);
11388
c19d1205
ZW
11389 /* If we get here, it can't be done in 16 bits. */
11390 constraint (inst.operands[2].shifted && inst.operands[2].immisreg,
11391 _("shift must be constant"));
11392 inst.instruction = THUMB_OP32 (inst.instruction);
11393 inst.instruction |= Rd << 8;
11394 inst.instruction |= Rs << 16;
5f4cb198
NC
11395 constraint (Rd == REG_SP && Rs == REG_SP && value > 3,
11396 _("shift value over 3 not allowed in thumb mode"));
11397 constraint (Rd == REG_SP && Rs == REG_SP && shift != SHIFT_LSL,
11398 _("only LSL shift allowed in thumb mode"));
c19d1205
ZW
11399 encode_thumb32_shifted_operand (2);
11400 }
11401 }
11402 else
11403 {
11404 constraint (inst.instruction == T_MNEM_adds
11405 || inst.instruction == T_MNEM_subs,
11406 BAD_THUMB32);
b99bd4ef 11407
c19d1205 11408 if (!inst.operands[2].isreg) /* Rd, Rs, #imm */
b99bd4ef 11409 {
c19d1205
ZW
11410 constraint ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
11411 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC),
11412 BAD_HIREG);
11413
11414 inst.instruction = (inst.instruction == T_MNEM_add
11415 ? 0x0000 : 0x8000);
11416 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59 11417 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
b99bd4ef
NC
11418 return;
11419 }
11420
c19d1205
ZW
11421 Rn = inst.operands[2].reg;
11422 constraint (inst.operands[2].shifted, _("unshifted register required"));
b99bd4ef 11423
c19d1205
ZW
11424 /* We now have Rd, Rs, and Rn set to registers. */
11425 if (Rd > 7 || Rs > 7 || Rn > 7)
b99bd4ef 11426 {
c19d1205
ZW
11427 /* Can't do this for SUB. */
11428 constraint (inst.instruction == T_MNEM_sub, BAD_HIREG);
11429 inst.instruction = T_OPCODE_ADD_HI;
11430 inst.instruction |= (Rd & 8) << 4;
11431 inst.instruction |= (Rd & 7);
11432 if (Rs == Rd)
11433 inst.instruction |= Rn << 3;
11434 else if (Rn == Rd)
11435 inst.instruction |= Rs << 3;
11436 else
11437 constraint (1, _("dest must overlap one source register"));
11438 }
11439 else
11440 {
11441 inst.instruction = (inst.instruction == T_MNEM_add
11442 ? T_OPCODE_ADD_R3 : T_OPCODE_SUB_R3);
11443 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
b99bd4ef 11444 }
b99bd4ef 11445 }
b99bd4ef
NC
11446}
11447
c19d1205
ZW
11448static void
11449do_t_adr (void)
11450{
fdfde340
JM
11451 unsigned Rd;
11452
11453 Rd = inst.operands[0].reg;
11454 reject_bad_reg (Rd);
11455
11456 if (unified_syntax && inst.size_req == 0 && Rd <= 7)
0110f2b8
PB
11457 {
11458 /* Defer to section relaxation. */
11459 inst.relax = inst.instruction;
11460 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 11461 inst.instruction |= Rd << 4;
0110f2b8
PB
11462 }
11463 else if (unified_syntax && inst.size_req != 2)
e9f89963 11464 {
0110f2b8 11465 /* Generate a 32-bit opcode. */
e9f89963 11466 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 11467 inst.instruction |= Rd << 8;
e2b0ab59
AV
11468 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_PC12;
11469 inst.relocs[0].pc_rel = 1;
e9f89963
PB
11470 }
11471 else
11472 {
0110f2b8 11473 /* Generate a 16-bit opcode. */
e9f89963 11474 inst.instruction = THUMB_OP16 (inst.instruction);
e2b0ab59
AV
11475 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
11476 inst.relocs[0].exp.X_add_number -= 4; /* PC relative adjust. */
11477 inst.relocs[0].pc_rel = 1;
fdfde340 11478 inst.instruction |= Rd << 4;
e9f89963 11479 }
52a86f84 11480
e2b0ab59
AV
11481 if (inst.relocs[0].exp.X_op == O_symbol
11482 && inst.relocs[0].exp.X_add_symbol != NULL
11483 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
11484 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
11485 inst.relocs[0].exp.X_add_number += 1;
c19d1205 11486}
b99bd4ef 11487
c19d1205
ZW
11488/* Arithmetic instructions for which there is just one 16-bit
11489 instruction encoding, and it allows only two low registers.
11490 For maximal compatibility with ARM syntax, we allow three register
11491 operands even when Thumb-32 instructions are not available, as long
11492 as the first two are identical. For instance, both "sbc r0,r1" and
11493 "sbc r0,r0,r1" are allowed. */
b99bd4ef 11494static void
c19d1205 11495do_t_arit3 (void)
b99bd4ef 11496{
c19d1205 11497 int Rd, Rs, Rn;
b99bd4ef 11498
c19d1205
ZW
11499 Rd = inst.operands[0].reg;
11500 Rs = (inst.operands[1].present
11501 ? inst.operands[1].reg /* Rd, Rs, foo */
11502 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11503 Rn = inst.operands[2].reg;
b99bd4ef 11504
fdfde340
JM
11505 reject_bad_reg (Rd);
11506 reject_bad_reg (Rs);
11507 if (inst.operands[2].isreg)
11508 reject_bad_reg (Rn);
11509
c19d1205 11510 if (unified_syntax)
b99bd4ef 11511 {
c19d1205
ZW
11512 if (!inst.operands[2].isreg)
11513 {
11514 /* For an immediate, we always generate a 32-bit opcode;
11515 section relaxation will shrink it later if possible. */
11516 inst.instruction = THUMB_OP32 (inst.instruction);
11517 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
11518 inst.instruction |= Rd << 8;
11519 inst.instruction |= Rs << 16;
e2b0ab59 11520 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
c19d1205
ZW
11521 }
11522 else
11523 {
e27ec89e
PB
11524 bfd_boolean narrow;
11525
c19d1205 11526 /* See if we can do this with a 16-bit instruction. */
e27ec89e 11527 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 11528 narrow = !in_pred_block ();
e27ec89e 11529 else
5ee91343 11530 narrow = in_pred_block ();
e27ec89e
PB
11531
11532 if (Rd > 7 || Rn > 7 || Rs > 7)
11533 narrow = FALSE;
11534 if (inst.operands[2].shifted)
11535 narrow = FALSE;
11536 if (inst.size_req == 4)
11537 narrow = FALSE;
11538
11539 if (narrow
c19d1205
ZW
11540 && Rd == Rs)
11541 {
11542 inst.instruction = THUMB_OP16 (inst.instruction);
11543 inst.instruction |= Rd;
11544 inst.instruction |= Rn << 3;
11545 return;
11546 }
b99bd4ef 11547
c19d1205
ZW
11548 /* If we get here, it can't be done in 16 bits. */
11549 constraint (inst.operands[2].shifted
11550 && inst.operands[2].immisreg,
11551 _("shift must be constant"));
11552 inst.instruction = THUMB_OP32 (inst.instruction);
11553 inst.instruction |= Rd << 8;
11554 inst.instruction |= Rs << 16;
11555 encode_thumb32_shifted_operand (2);
11556 }
a737bd4d 11557 }
c19d1205 11558 else
b99bd4ef 11559 {
c19d1205
ZW
11560 /* On its face this is a lie - the instruction does set the
11561 flags. However, the only supported mnemonic in this mode
11562 says it doesn't. */
11563 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 11564
c19d1205
ZW
11565 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
11566 _("unshifted register required"));
11567 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
11568 constraint (Rd != Rs,
11569 _("dest and source1 must be the same register"));
a737bd4d 11570
c19d1205
ZW
11571 inst.instruction = THUMB_OP16 (inst.instruction);
11572 inst.instruction |= Rd;
11573 inst.instruction |= Rn << 3;
b99bd4ef 11574 }
a737bd4d 11575}
b99bd4ef 11576
c19d1205
ZW
11577/* Similarly, but for instructions where the arithmetic operation is
11578 commutative, so we can allow either of them to be different from
11579 the destination operand in a 16-bit instruction. For instance, all
11580 three of "adc r0,r1", "adc r0,r0,r1", and "adc r0,r1,r0" are
11581 accepted. */
11582static void
11583do_t_arit3c (void)
a737bd4d 11584{
c19d1205 11585 int Rd, Rs, Rn;
b99bd4ef 11586
c19d1205
ZW
11587 Rd = inst.operands[0].reg;
11588 Rs = (inst.operands[1].present
11589 ? inst.operands[1].reg /* Rd, Rs, foo */
11590 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11591 Rn = inst.operands[2].reg;
c921be7d 11592
fdfde340
JM
11593 reject_bad_reg (Rd);
11594 reject_bad_reg (Rs);
11595 if (inst.operands[2].isreg)
11596 reject_bad_reg (Rn);
a737bd4d 11597
c19d1205 11598 if (unified_syntax)
a737bd4d 11599 {
c19d1205 11600 if (!inst.operands[2].isreg)
b99bd4ef 11601 {
c19d1205
ZW
11602 /* For an immediate, we always generate a 32-bit opcode;
11603 section relaxation will shrink it later if possible. */
11604 inst.instruction = THUMB_OP32 (inst.instruction);
11605 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
11606 inst.instruction |= Rd << 8;
11607 inst.instruction |= Rs << 16;
e2b0ab59 11608 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 11609 }
c19d1205 11610 else
a737bd4d 11611 {
e27ec89e
PB
11612 bfd_boolean narrow;
11613
c19d1205 11614 /* See if we can do this with a 16-bit instruction. */
e27ec89e 11615 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 11616 narrow = !in_pred_block ();
e27ec89e 11617 else
5ee91343 11618 narrow = in_pred_block ();
e27ec89e
PB
11619
11620 if (Rd > 7 || Rn > 7 || Rs > 7)
11621 narrow = FALSE;
11622 if (inst.operands[2].shifted)
11623 narrow = FALSE;
11624 if (inst.size_req == 4)
11625 narrow = FALSE;
11626
11627 if (narrow)
a737bd4d 11628 {
c19d1205 11629 if (Rd == Rs)
a737bd4d 11630 {
c19d1205
ZW
11631 inst.instruction = THUMB_OP16 (inst.instruction);
11632 inst.instruction |= Rd;
11633 inst.instruction |= Rn << 3;
11634 return;
a737bd4d 11635 }
c19d1205 11636 if (Rd == Rn)
a737bd4d 11637 {
c19d1205
ZW
11638 inst.instruction = THUMB_OP16 (inst.instruction);
11639 inst.instruction |= Rd;
11640 inst.instruction |= Rs << 3;
11641 return;
a737bd4d
NC
11642 }
11643 }
c19d1205
ZW
11644
11645 /* If we get here, it can't be done in 16 bits. */
11646 constraint (inst.operands[2].shifted
11647 && inst.operands[2].immisreg,
11648 _("shift must be constant"));
11649 inst.instruction = THUMB_OP32 (inst.instruction);
11650 inst.instruction |= Rd << 8;
11651 inst.instruction |= Rs << 16;
11652 encode_thumb32_shifted_operand (2);
a737bd4d 11653 }
b99bd4ef 11654 }
c19d1205
ZW
11655 else
11656 {
11657 /* On its face this is a lie - the instruction does set the
11658 flags. However, the only supported mnemonic in this mode
11659 says it doesn't. */
11660 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 11661
c19d1205
ZW
11662 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
11663 _("unshifted register required"));
11664 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
11665
11666 inst.instruction = THUMB_OP16 (inst.instruction);
11667 inst.instruction |= Rd;
11668
11669 if (Rd == Rs)
11670 inst.instruction |= Rn << 3;
11671 else if (Rd == Rn)
11672 inst.instruction |= Rs << 3;
11673 else
11674 constraint (1, _("dest must overlap one source register"));
11675 }
a737bd4d
NC
11676}
11677
c19d1205
ZW
11678static void
11679do_t_bfc (void)
a737bd4d 11680{
fdfde340 11681 unsigned Rd;
c19d1205
ZW
11682 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
11683 constraint (msb > 32, _("bit-field extends past end of register"));
11684 /* The instruction encoding stores the LSB and MSB,
11685 not the LSB and width. */
fdfde340
JM
11686 Rd = inst.operands[0].reg;
11687 reject_bad_reg (Rd);
11688 inst.instruction |= Rd << 8;
c19d1205
ZW
11689 inst.instruction |= (inst.operands[1].imm & 0x1c) << 10;
11690 inst.instruction |= (inst.operands[1].imm & 0x03) << 6;
11691 inst.instruction |= msb - 1;
b99bd4ef
NC
11692}
11693
c19d1205
ZW
11694static void
11695do_t_bfi (void)
b99bd4ef 11696{
fdfde340 11697 int Rd, Rn;
c19d1205 11698 unsigned int msb;
b99bd4ef 11699
fdfde340
JM
11700 Rd = inst.operands[0].reg;
11701 reject_bad_reg (Rd);
11702
c19d1205
ZW
11703 /* #0 in second position is alternative syntax for bfc, which is
11704 the same instruction but with REG_PC in the Rm field. */
11705 if (!inst.operands[1].isreg)
fdfde340
JM
11706 Rn = REG_PC;
11707 else
11708 {
11709 Rn = inst.operands[1].reg;
11710 reject_bad_reg (Rn);
11711 }
b99bd4ef 11712
c19d1205
ZW
11713 msb = inst.operands[2].imm + inst.operands[3].imm;
11714 constraint (msb > 32, _("bit-field extends past end of register"));
11715 /* The instruction encoding stores the LSB and MSB,
11716 not the LSB and width. */
fdfde340
JM
11717 inst.instruction |= Rd << 8;
11718 inst.instruction |= Rn << 16;
c19d1205
ZW
11719 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
11720 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
11721 inst.instruction |= msb - 1;
b99bd4ef
NC
11722}
11723
c19d1205
ZW
11724static void
11725do_t_bfx (void)
b99bd4ef 11726{
fdfde340
JM
11727 unsigned Rd, Rn;
11728
11729 Rd = inst.operands[0].reg;
11730 Rn = inst.operands[1].reg;
11731
11732 reject_bad_reg (Rd);
11733 reject_bad_reg (Rn);
11734
c19d1205
ZW
11735 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
11736 _("bit-field extends past end of register"));
fdfde340
JM
11737 inst.instruction |= Rd << 8;
11738 inst.instruction |= Rn << 16;
c19d1205
ZW
11739 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
11740 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
11741 inst.instruction |= inst.operands[3].imm - 1;
11742}
b99bd4ef 11743
c19d1205
ZW
11744/* ARM V5 Thumb BLX (argument parse)
11745 BLX <target_addr> which is BLX(1)
11746 BLX <Rm> which is BLX(2)
11747 Unfortunately, there are two different opcodes for this mnemonic.
11748 So, the insns[].value is not used, and the code here zaps values
11749 into inst.instruction.
b99bd4ef 11750
c19d1205
ZW
11751 ??? How to take advantage of the additional two bits of displacement
11752 available in Thumb32 mode? Need new relocation? */
b99bd4ef 11753
c19d1205
ZW
11754static void
11755do_t_blx (void)
11756{
5ee91343 11757 set_pred_insn_type_last ();
e07e6e58 11758
c19d1205 11759 if (inst.operands[0].isreg)
fdfde340
JM
11760 {
11761 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
11762 /* We have a register, so this is BLX(2). */
11763 inst.instruction |= inst.operands[0].reg << 3;
11764 }
b99bd4ef
NC
11765 else
11766 {
c19d1205 11767 /* No register. This must be BLX(1). */
2fc8bdac 11768 inst.instruction = 0xf000e800;
0855e32b 11769 encode_branch (BFD_RELOC_THUMB_PCREL_BLX);
b99bd4ef
NC
11770 }
11771}
11772
c19d1205
ZW
11773static void
11774do_t_branch (void)
b99bd4ef 11775{
0110f2b8 11776 int opcode;
dfa9f0d5 11777 int cond;
2fe88214 11778 bfd_reloc_code_real_type reloc;
dfa9f0d5 11779
e07e6e58 11780 cond = inst.cond;
5ee91343 11781 set_pred_insn_type (IF_INSIDE_IT_LAST_INSN);
e07e6e58 11782
5ee91343 11783 if (in_pred_block ())
dfa9f0d5
PB
11784 {
11785 /* Conditional branches inside IT blocks are encoded as unconditional
477330fc 11786 branches. */
dfa9f0d5 11787 cond = COND_ALWAYS;
dfa9f0d5
PB
11788 }
11789 else
11790 cond = inst.cond;
11791
11792 if (cond != COND_ALWAYS)
0110f2b8
PB
11793 opcode = T_MNEM_bcond;
11794 else
11795 opcode = inst.instruction;
11796
12d6b0b7
RS
11797 if (unified_syntax
11798 && (inst.size_req == 4
10960bfb
PB
11799 || (inst.size_req != 2
11800 && (inst.operands[0].hasreloc
e2b0ab59 11801 || inst.relocs[0].exp.X_op == O_constant))))
c19d1205 11802 {
0110f2b8 11803 inst.instruction = THUMB_OP32(opcode);
dfa9f0d5 11804 if (cond == COND_ALWAYS)
9ae92b05 11805 reloc = BFD_RELOC_THUMB_PCREL_BRANCH25;
c19d1205
ZW
11806 else
11807 {
ff8646ee
TP
11808 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2),
11809 _("selected architecture does not support "
11810 "wide conditional branch instruction"));
11811
9c2799c2 11812 gas_assert (cond != 0xF);
dfa9f0d5 11813 inst.instruction |= cond << 22;
9ae92b05 11814 reloc = BFD_RELOC_THUMB_PCREL_BRANCH20;
c19d1205
ZW
11815 }
11816 }
b99bd4ef
NC
11817 else
11818 {
0110f2b8 11819 inst.instruction = THUMB_OP16(opcode);
dfa9f0d5 11820 if (cond == COND_ALWAYS)
9ae92b05 11821 reloc = BFD_RELOC_THUMB_PCREL_BRANCH12;
c19d1205 11822 else
b99bd4ef 11823 {
dfa9f0d5 11824 inst.instruction |= cond << 8;
9ae92b05 11825 reloc = BFD_RELOC_THUMB_PCREL_BRANCH9;
b99bd4ef 11826 }
0110f2b8
PB
11827 /* Allow section relaxation. */
11828 if (unified_syntax && inst.size_req != 2)
11829 inst.relax = opcode;
b99bd4ef 11830 }
e2b0ab59
AV
11831 inst.relocs[0].type = reloc;
11832 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
11833}
11834
8884b720 11835/* Actually do the work for Thumb state bkpt and hlt. The only difference
bacebabc 11836 between the two is the maximum immediate allowed - which is passed in
8884b720 11837 RANGE. */
b99bd4ef 11838static void
8884b720 11839do_t_bkpt_hlt1 (int range)
b99bd4ef 11840{
dfa9f0d5
PB
11841 constraint (inst.cond != COND_ALWAYS,
11842 _("instruction is always unconditional"));
c19d1205 11843 if (inst.operands[0].present)
b99bd4ef 11844 {
8884b720 11845 constraint (inst.operands[0].imm > range,
c19d1205
ZW
11846 _("immediate value out of range"));
11847 inst.instruction |= inst.operands[0].imm;
b99bd4ef 11848 }
8884b720 11849
5ee91343 11850 set_pred_insn_type (NEUTRAL_IT_INSN);
8884b720
MGD
11851}
11852
11853static void
11854do_t_hlt (void)
11855{
11856 do_t_bkpt_hlt1 (63);
11857}
11858
11859static void
11860do_t_bkpt (void)
11861{
11862 do_t_bkpt_hlt1 (255);
b99bd4ef
NC
11863}
11864
11865static void
c19d1205 11866do_t_branch23 (void)
b99bd4ef 11867{
5ee91343 11868 set_pred_insn_type_last ();
0855e32b 11869 encode_branch (BFD_RELOC_THUMB_PCREL_BRANCH23);
fa94de6b 11870
0855e32b
NS
11871 /* md_apply_fix blows up with 'bl foo(PLT)' where foo is defined in
11872 this file. We used to simply ignore the PLT reloc type here --
11873 the branch encoding is now needed to deal with TLSCALL relocs.
11874 So if we see a PLT reloc now, put it back to how it used to be to
11875 keep the preexisting behaviour. */
e2b0ab59
AV
11876 if (inst.relocs[0].type == BFD_RELOC_ARM_PLT32)
11877 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH23;
90e4755a 11878
4343666d 11879#if defined(OBJ_COFF)
c19d1205
ZW
11880 /* If the destination of the branch is a defined symbol which does not have
11881 the THUMB_FUNC attribute, then we must be calling a function which has
11882 the (interfacearm) attribute. We look for the Thumb entry point to that
11883 function and change the branch to refer to that function instead. */
e2b0ab59
AV
11884 if ( inst.relocs[0].exp.X_op == O_symbol
11885 && inst.relocs[0].exp.X_add_symbol != NULL
11886 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
11887 && ! THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
11888 inst.relocs[0].exp.X_add_symbol
11889 = find_real_start (inst.relocs[0].exp.X_add_symbol);
4343666d 11890#endif
90e4755a
RE
11891}
11892
11893static void
c19d1205 11894do_t_bx (void)
90e4755a 11895{
5ee91343 11896 set_pred_insn_type_last ();
c19d1205
ZW
11897 inst.instruction |= inst.operands[0].reg << 3;
11898 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
11899 should cause the alignment to be checked once it is known. This is
11900 because BX PC only works if the instruction is word aligned. */
11901}
90e4755a 11902
c19d1205
ZW
11903static void
11904do_t_bxj (void)
11905{
fdfde340 11906 int Rm;
90e4755a 11907
5ee91343 11908 set_pred_insn_type_last ();
fdfde340
JM
11909 Rm = inst.operands[0].reg;
11910 reject_bad_reg (Rm);
11911 inst.instruction |= Rm << 16;
90e4755a
RE
11912}
11913
11914static void
c19d1205 11915do_t_clz (void)
90e4755a 11916{
fdfde340
JM
11917 unsigned Rd;
11918 unsigned Rm;
11919
11920 Rd = inst.operands[0].reg;
11921 Rm = inst.operands[1].reg;
11922
11923 reject_bad_reg (Rd);
11924 reject_bad_reg (Rm);
11925
11926 inst.instruction |= Rd << 8;
11927 inst.instruction |= Rm << 16;
11928 inst.instruction |= Rm;
c19d1205 11929}
90e4755a 11930
91d8b670
JG
11931static void
11932do_t_csdb (void)
11933{
5ee91343 11934 set_pred_insn_type (OUTSIDE_PRED_INSN);
91d8b670
JG
11935}
11936
dfa9f0d5
PB
11937static void
11938do_t_cps (void)
11939{
5ee91343 11940 set_pred_insn_type (OUTSIDE_PRED_INSN);
dfa9f0d5
PB
11941 inst.instruction |= inst.operands[0].imm;
11942}
11943
c19d1205
ZW
11944static void
11945do_t_cpsi (void)
11946{
5ee91343 11947 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205 11948 if (unified_syntax
62b3e311
PB
11949 && (inst.operands[1].present || inst.size_req == 4)
11950 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6_notm))
90e4755a 11951 {
c19d1205
ZW
11952 unsigned int imod = (inst.instruction & 0x0030) >> 4;
11953 inst.instruction = 0xf3af8000;
11954 inst.instruction |= imod << 9;
11955 inst.instruction |= inst.operands[0].imm << 5;
11956 if (inst.operands[1].present)
11957 inst.instruction |= 0x100 | inst.operands[1].imm;
90e4755a 11958 }
c19d1205 11959 else
90e4755a 11960 {
62b3e311
PB
11961 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1)
11962 && (inst.operands[0].imm & 4),
11963 _("selected processor does not support 'A' form "
11964 "of this instruction"));
11965 constraint (inst.operands[1].present || inst.size_req == 4,
c19d1205
ZW
11966 _("Thumb does not support the 2-argument "
11967 "form of this instruction"));
11968 inst.instruction |= inst.operands[0].imm;
90e4755a 11969 }
90e4755a
RE
11970}
11971
c19d1205
ZW
11972/* THUMB CPY instruction (argument parse). */
11973
90e4755a 11974static void
c19d1205 11975do_t_cpy (void)
90e4755a 11976{
c19d1205 11977 if (inst.size_req == 4)
90e4755a 11978 {
c19d1205
ZW
11979 inst.instruction = THUMB_OP32 (T_MNEM_mov);
11980 inst.instruction |= inst.operands[0].reg << 8;
11981 inst.instruction |= inst.operands[1].reg;
90e4755a 11982 }
c19d1205 11983 else
90e4755a 11984 {
c19d1205
ZW
11985 inst.instruction |= (inst.operands[0].reg & 0x8) << 4;
11986 inst.instruction |= (inst.operands[0].reg & 0x7);
11987 inst.instruction |= inst.operands[1].reg << 3;
90e4755a 11988 }
90e4755a
RE
11989}
11990
90e4755a 11991static void
25fe350b 11992do_t_cbz (void)
90e4755a 11993{
5ee91343 11994 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205
ZW
11995 constraint (inst.operands[0].reg > 7, BAD_HIREG);
11996 inst.instruction |= inst.operands[0].reg;
e2b0ab59
AV
11997 inst.relocs[0].pc_rel = 1;
11998 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH7;
c19d1205 11999}
90e4755a 12000
62b3e311
PB
12001static void
12002do_t_dbg (void)
12003{
12004 inst.instruction |= inst.operands[0].imm;
12005}
12006
12007static void
12008do_t_div (void)
12009{
fdfde340
JM
12010 unsigned Rd, Rn, Rm;
12011
12012 Rd = inst.operands[0].reg;
12013 Rn = (inst.operands[1].present
12014 ? inst.operands[1].reg : Rd);
12015 Rm = inst.operands[2].reg;
12016
12017 reject_bad_reg (Rd);
12018 reject_bad_reg (Rn);
12019 reject_bad_reg (Rm);
12020
12021 inst.instruction |= Rd << 8;
12022 inst.instruction |= Rn << 16;
12023 inst.instruction |= Rm;
62b3e311
PB
12024}
12025
c19d1205
ZW
12026static void
12027do_t_hint (void)
12028{
12029 if (unified_syntax && inst.size_req == 4)
12030 inst.instruction = THUMB_OP32 (inst.instruction);
12031 else
12032 inst.instruction = THUMB_OP16 (inst.instruction);
12033}
90e4755a 12034
c19d1205
ZW
12035static void
12036do_t_it (void)
12037{
12038 unsigned int cond = inst.operands[0].imm;
e27ec89e 12039
5ee91343
AV
12040 set_pred_insn_type (IT_INSN);
12041 now_pred.mask = (inst.instruction & 0xf) | 0x10;
12042 now_pred.cc = cond;
12043 now_pred.warn_deprecated = FALSE;
12044 now_pred.type = SCALAR_PRED;
e27ec89e
PB
12045
12046 /* If the condition is a negative condition, invert the mask. */
c19d1205 12047 if ((cond & 0x1) == 0x0)
90e4755a 12048 {
c19d1205 12049 unsigned int mask = inst.instruction & 0x000f;
90e4755a 12050
c19d1205 12051 if ((mask & 0x7) == 0)
5a01bb1d
MGD
12052 {
12053 /* No conversion needed. */
5ee91343 12054 now_pred.block_length = 1;
5a01bb1d 12055 }
c19d1205 12056 else if ((mask & 0x3) == 0)
5a01bb1d
MGD
12057 {
12058 mask ^= 0x8;
5ee91343 12059 now_pred.block_length = 2;
5a01bb1d 12060 }
e27ec89e 12061 else if ((mask & 0x1) == 0)
5a01bb1d
MGD
12062 {
12063 mask ^= 0xC;
5ee91343 12064 now_pred.block_length = 3;
5a01bb1d 12065 }
c19d1205 12066 else
5a01bb1d
MGD
12067 {
12068 mask ^= 0xE;
5ee91343 12069 now_pred.block_length = 4;
5a01bb1d 12070 }
90e4755a 12071
e27ec89e
PB
12072 inst.instruction &= 0xfff0;
12073 inst.instruction |= mask;
c19d1205 12074 }
90e4755a 12075
c19d1205
ZW
12076 inst.instruction |= cond << 4;
12077}
90e4755a 12078
3c707909
PB
12079/* Helper function used for both push/pop and ldm/stm. */
12080static void
4b5a202f
AV
12081encode_thumb2_multi (bfd_boolean do_io, int base, unsigned mask,
12082 bfd_boolean writeback)
3c707909 12083{
4b5a202f 12084 bfd_boolean load, store;
3c707909 12085
4b5a202f
AV
12086 gas_assert (base != -1 || !do_io);
12087 load = do_io && ((inst.instruction & (1 << 20)) != 0);
12088 store = do_io && !load;
3c707909
PB
12089
12090 if (mask & (1 << 13))
12091 inst.error = _("SP not allowed in register list");
1e5b0379 12092
4b5a202f 12093 if (do_io && (mask & (1 << base)) != 0
1e5b0379
NC
12094 && writeback)
12095 inst.error = _("having the base register in the register list when "
12096 "using write back is UNPREDICTABLE");
12097
3c707909
PB
12098 if (load)
12099 {
e07e6e58 12100 if (mask & (1 << 15))
477330fc
RM
12101 {
12102 if (mask & (1 << 14))
12103 inst.error = _("LR and PC should not both be in register list");
12104 else
5ee91343 12105 set_pred_insn_type_last ();
477330fc 12106 }
3c707909 12107 }
4b5a202f 12108 else if (store)
3c707909
PB
12109 {
12110 if (mask & (1 << 15))
12111 inst.error = _("PC not allowed in register list");
3c707909
PB
12112 }
12113
4b5a202f 12114 if (do_io && ((mask & (mask - 1)) == 0))
3c707909
PB
12115 {
12116 /* Single register transfers implemented as str/ldr. */
12117 if (writeback)
12118 {
12119 if (inst.instruction & (1 << 23))
12120 inst.instruction = 0x00000b04; /* ia! -> [base], #4 */
12121 else
12122 inst.instruction = 0x00000d04; /* db! -> [base, #-4]! */
12123 }
12124 else
12125 {
12126 if (inst.instruction & (1 << 23))
12127 inst.instruction = 0x00800000; /* ia -> [base] */
12128 else
12129 inst.instruction = 0x00000c04; /* db -> [base, #-4] */
12130 }
12131
12132 inst.instruction |= 0xf8400000;
12133 if (load)
12134 inst.instruction |= 0x00100000;
12135
5f4273c7 12136 mask = ffs (mask) - 1;
3c707909
PB
12137 mask <<= 12;
12138 }
12139 else if (writeback)
12140 inst.instruction |= WRITE_BACK;
12141
12142 inst.instruction |= mask;
4b5a202f
AV
12143 if (do_io)
12144 inst.instruction |= base << 16;
3c707909
PB
12145}
12146
c19d1205
ZW
12147static void
12148do_t_ldmstm (void)
12149{
12150 /* This really doesn't seem worth it. */
e2b0ab59 12151 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205
ZW
12152 _("expression too complex"));
12153 constraint (inst.operands[1].writeback,
12154 _("Thumb load/store multiple does not support {reglist}^"));
90e4755a 12155
c19d1205
ZW
12156 if (unified_syntax)
12157 {
3c707909
PB
12158 bfd_boolean narrow;
12159 unsigned mask;
12160
12161 narrow = FALSE;
c19d1205
ZW
12162 /* See if we can use a 16-bit instruction. */
12163 if (inst.instruction < 0xffff /* not ldmdb/stmdb */
12164 && inst.size_req != 4
3c707909 12165 && !(inst.operands[1].imm & ~0xff))
90e4755a 12166 {
3c707909 12167 mask = 1 << inst.operands[0].reg;
90e4755a 12168
eab4f823 12169 if (inst.operands[0].reg <= 7)
90e4755a 12170 {
3c707909 12171 if (inst.instruction == T_MNEM_stmia
eab4f823
MGD
12172 ? inst.operands[0].writeback
12173 : (inst.operands[0].writeback
12174 == !(inst.operands[1].imm & mask)))
477330fc 12175 {
eab4f823
MGD
12176 if (inst.instruction == T_MNEM_stmia
12177 && (inst.operands[1].imm & mask)
12178 && (inst.operands[1].imm & (mask - 1)))
12179 as_warn (_("value stored for r%d is UNKNOWN"),
12180 inst.operands[0].reg);
3c707909 12181
eab4f823
MGD
12182 inst.instruction = THUMB_OP16 (inst.instruction);
12183 inst.instruction |= inst.operands[0].reg << 8;
12184 inst.instruction |= inst.operands[1].imm;
12185 narrow = TRUE;
12186 }
12187 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
12188 {
12189 /* This means 1 register in reg list one of 3 situations:
12190 1. Instruction is stmia, but without writeback.
12191 2. lmdia without writeback, but with Rn not in
477330fc 12192 reglist.
eab4f823
MGD
12193 3. ldmia with writeback, but with Rn in reglist.
12194 Case 3 is UNPREDICTABLE behaviour, so we handle
12195 case 1 and 2 which can be converted into a 16-bit
12196 str or ldr. The SP cases are handled below. */
12197 unsigned long opcode;
12198 /* First, record an error for Case 3. */
12199 if (inst.operands[1].imm & mask
12200 && inst.operands[0].writeback)
fa94de6b 12201 inst.error =
eab4f823
MGD
12202 _("having the base register in the register list when "
12203 "using write back is UNPREDICTABLE");
fa94de6b
RM
12204
12205 opcode = (inst.instruction == T_MNEM_stmia ? T_MNEM_str
eab4f823
MGD
12206 : T_MNEM_ldr);
12207 inst.instruction = THUMB_OP16 (opcode);
12208 inst.instruction |= inst.operands[0].reg << 3;
12209 inst.instruction |= (ffs (inst.operands[1].imm)-1);
12210 narrow = TRUE;
12211 }
90e4755a 12212 }
eab4f823 12213 else if (inst.operands[0] .reg == REG_SP)
90e4755a 12214 {
eab4f823
MGD
12215 if (inst.operands[0].writeback)
12216 {
fa94de6b 12217 inst.instruction =
eab4f823 12218 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 12219 ? T_MNEM_push : T_MNEM_pop);
eab4f823 12220 inst.instruction |= inst.operands[1].imm;
477330fc 12221 narrow = TRUE;
eab4f823
MGD
12222 }
12223 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
12224 {
fa94de6b 12225 inst.instruction =
eab4f823 12226 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 12227 ? T_MNEM_str_sp : T_MNEM_ldr_sp);
eab4f823 12228 inst.instruction |= ((ffs (inst.operands[1].imm)-1) << 8);
477330fc 12229 narrow = TRUE;
eab4f823 12230 }
90e4755a 12231 }
3c707909
PB
12232 }
12233
12234 if (!narrow)
12235 {
c19d1205
ZW
12236 if (inst.instruction < 0xffff)
12237 inst.instruction = THUMB_OP32 (inst.instruction);
3c707909 12238
4b5a202f
AV
12239 encode_thumb2_multi (TRUE /* do_io */, inst.operands[0].reg,
12240 inst.operands[1].imm,
12241 inst.operands[0].writeback);
90e4755a
RE
12242 }
12243 }
c19d1205 12244 else
90e4755a 12245 {
c19d1205
ZW
12246 constraint (inst.operands[0].reg > 7
12247 || (inst.operands[1].imm & ~0xff), BAD_HIREG);
1198ca51
PB
12248 constraint (inst.instruction != T_MNEM_ldmia
12249 && inst.instruction != T_MNEM_stmia,
12250 _("Thumb-2 instruction only valid in unified syntax"));
c19d1205 12251 if (inst.instruction == T_MNEM_stmia)
f03698e6 12252 {
c19d1205
ZW
12253 if (!inst.operands[0].writeback)
12254 as_warn (_("this instruction will write back the base register"));
12255 if ((inst.operands[1].imm & (1 << inst.operands[0].reg))
12256 && (inst.operands[1].imm & ((1 << inst.operands[0].reg) - 1)))
1e5b0379 12257 as_warn (_("value stored for r%d is UNKNOWN"),
c19d1205 12258 inst.operands[0].reg);
f03698e6 12259 }
c19d1205 12260 else
90e4755a 12261 {
c19d1205
ZW
12262 if (!inst.operands[0].writeback
12263 && !(inst.operands[1].imm & (1 << inst.operands[0].reg)))
12264 as_warn (_("this instruction will write back the base register"));
12265 else if (inst.operands[0].writeback
12266 && (inst.operands[1].imm & (1 << inst.operands[0].reg)))
12267 as_warn (_("this instruction will not write back the base register"));
90e4755a
RE
12268 }
12269
c19d1205
ZW
12270 inst.instruction = THUMB_OP16 (inst.instruction);
12271 inst.instruction |= inst.operands[0].reg << 8;
12272 inst.instruction |= inst.operands[1].imm;
12273 }
12274}
e28cd48c 12275
c19d1205
ZW
12276static void
12277do_t_ldrex (void)
12278{
12279 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
12280 || inst.operands[1].postind || inst.operands[1].writeback
12281 || inst.operands[1].immisreg || inst.operands[1].shifted
12282 || inst.operands[1].negative,
01cfc07f 12283 BAD_ADDR_MODE);
e28cd48c 12284
5be8be5d
DG
12285 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
12286
c19d1205
ZW
12287 inst.instruction |= inst.operands[0].reg << 12;
12288 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 12289 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
c19d1205 12290}
e28cd48c 12291
c19d1205
ZW
12292static void
12293do_t_ldrexd (void)
12294{
12295 if (!inst.operands[1].present)
1cac9012 12296 {
c19d1205
ZW
12297 constraint (inst.operands[0].reg == REG_LR,
12298 _("r14 not allowed as first register "
12299 "when second register is omitted"));
12300 inst.operands[1].reg = inst.operands[0].reg + 1;
b99bd4ef 12301 }
c19d1205
ZW
12302 constraint (inst.operands[0].reg == inst.operands[1].reg,
12303 BAD_OVERLAP);
b99bd4ef 12304
c19d1205
ZW
12305 inst.instruction |= inst.operands[0].reg << 12;
12306 inst.instruction |= inst.operands[1].reg << 8;
12307 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
12308}
12309
12310static void
c19d1205 12311do_t_ldst (void)
b99bd4ef 12312{
0110f2b8
PB
12313 unsigned long opcode;
12314 int Rn;
12315
e07e6e58
NC
12316 if (inst.operands[0].isreg
12317 && !inst.operands[0].preind
12318 && inst.operands[0].reg == REG_PC)
5ee91343 12319 set_pred_insn_type_last ();
e07e6e58 12320
0110f2b8 12321 opcode = inst.instruction;
c19d1205 12322 if (unified_syntax)
b99bd4ef 12323 {
53365c0d
PB
12324 if (!inst.operands[1].isreg)
12325 {
12326 if (opcode <= 0xffff)
12327 inst.instruction = THUMB_OP32 (opcode);
8335d6aa 12328 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/FALSE))
53365c0d
PB
12329 return;
12330 }
0110f2b8
PB
12331 if (inst.operands[1].isreg
12332 && !inst.operands[1].writeback
c19d1205
ZW
12333 && !inst.operands[1].shifted && !inst.operands[1].postind
12334 && !inst.operands[1].negative && inst.operands[0].reg <= 7
0110f2b8
PB
12335 && opcode <= 0xffff
12336 && inst.size_req != 4)
c19d1205 12337 {
0110f2b8
PB
12338 /* Insn may have a 16-bit form. */
12339 Rn = inst.operands[1].reg;
12340 if (inst.operands[1].immisreg)
12341 {
12342 inst.instruction = THUMB_OP16 (opcode);
5f4273c7 12343 /* [Rn, Rik] */
0110f2b8
PB
12344 if (Rn <= 7 && inst.operands[1].imm <= 7)
12345 goto op16;
5be8be5d
DG
12346 else if (opcode != T_MNEM_ldr && opcode != T_MNEM_str)
12347 reject_bad_reg (inst.operands[1].imm);
0110f2b8
PB
12348 }
12349 else if ((Rn <= 7 && opcode != T_MNEM_ldrsh
12350 && opcode != T_MNEM_ldrsb)
12351 || ((Rn == REG_PC || Rn == REG_SP) && opcode == T_MNEM_ldr)
12352 || (Rn == REG_SP && opcode == T_MNEM_str))
12353 {
12354 /* [Rn, #const] */
12355 if (Rn > 7)
12356 {
12357 if (Rn == REG_PC)
12358 {
e2b0ab59 12359 if (inst.relocs[0].pc_rel)
0110f2b8
PB
12360 opcode = T_MNEM_ldr_pc2;
12361 else
12362 opcode = T_MNEM_ldr_pc;
12363 }
12364 else
12365 {
12366 if (opcode == T_MNEM_ldr)
12367 opcode = T_MNEM_ldr_sp;
12368 else
12369 opcode = T_MNEM_str_sp;
12370 }
12371 inst.instruction = inst.operands[0].reg << 8;
12372 }
12373 else
12374 {
12375 inst.instruction = inst.operands[0].reg;
12376 inst.instruction |= inst.operands[1].reg << 3;
12377 }
12378 inst.instruction |= THUMB_OP16 (opcode);
12379 if (inst.size_req == 2)
e2b0ab59 12380 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
0110f2b8
PB
12381 else
12382 inst.relax = opcode;
12383 return;
12384 }
c19d1205 12385 }
0110f2b8 12386 /* Definitely a 32-bit variant. */
5be8be5d 12387
8d67f500
NC
12388 /* Warning for Erratum 752419. */
12389 if (opcode == T_MNEM_ldr
12390 && inst.operands[0].reg == REG_SP
12391 && inst.operands[1].writeback == 1
12392 && !inst.operands[1].immisreg)
12393 {
12394 if (no_cpu_selected ()
12395 || (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7)
477330fc
RM
12396 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a)
12397 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7r)))
8d67f500
NC
12398 as_warn (_("This instruction may be unpredictable "
12399 "if executed on M-profile cores "
12400 "with interrupts enabled."));
12401 }
12402
5be8be5d 12403 /* Do some validations regarding addressing modes. */
1be5fd2e 12404 if (inst.operands[1].immisreg)
5be8be5d
DG
12405 reject_bad_reg (inst.operands[1].imm);
12406
1be5fd2e
NC
12407 constraint (inst.operands[1].writeback == 1
12408 && inst.operands[0].reg == inst.operands[1].reg,
12409 BAD_OVERLAP);
12410
0110f2b8 12411 inst.instruction = THUMB_OP32 (opcode);
c19d1205
ZW
12412 inst.instruction |= inst.operands[0].reg << 12;
12413 encode_thumb32_addr_mode (1, /*is_t=*/FALSE, /*is_d=*/FALSE);
1be5fd2e 12414 check_ldr_r15_aligned ();
b99bd4ef
NC
12415 return;
12416 }
12417
c19d1205
ZW
12418 constraint (inst.operands[0].reg > 7, BAD_HIREG);
12419
12420 if (inst.instruction == T_MNEM_ldrsh || inst.instruction == T_MNEM_ldrsb)
b99bd4ef 12421 {
c19d1205
ZW
12422 /* Only [Rn,Rm] is acceptable. */
12423 constraint (inst.operands[1].reg > 7 || inst.operands[1].imm > 7, BAD_HIREG);
12424 constraint (!inst.operands[1].isreg || !inst.operands[1].immisreg
12425 || inst.operands[1].postind || inst.operands[1].shifted
12426 || inst.operands[1].negative,
12427 _("Thumb does not support this addressing mode"));
12428 inst.instruction = THUMB_OP16 (inst.instruction);
12429 goto op16;
b99bd4ef 12430 }
5f4273c7 12431
c19d1205
ZW
12432 inst.instruction = THUMB_OP16 (inst.instruction);
12433 if (!inst.operands[1].isreg)
8335d6aa 12434 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/FALSE))
c19d1205 12435 return;
b99bd4ef 12436
c19d1205
ZW
12437 constraint (!inst.operands[1].preind
12438 || inst.operands[1].shifted
12439 || inst.operands[1].writeback,
12440 _("Thumb does not support this addressing mode"));
12441 if (inst.operands[1].reg == REG_PC || inst.operands[1].reg == REG_SP)
90e4755a 12442 {
c19d1205
ZW
12443 constraint (inst.instruction & 0x0600,
12444 _("byte or halfword not valid for base register"));
12445 constraint (inst.operands[1].reg == REG_PC
12446 && !(inst.instruction & THUMB_LOAD_BIT),
12447 _("r15 based store not allowed"));
12448 constraint (inst.operands[1].immisreg,
12449 _("invalid base register for register offset"));
b99bd4ef 12450
c19d1205
ZW
12451 if (inst.operands[1].reg == REG_PC)
12452 inst.instruction = T_OPCODE_LDR_PC;
12453 else if (inst.instruction & THUMB_LOAD_BIT)
12454 inst.instruction = T_OPCODE_LDR_SP;
12455 else
12456 inst.instruction = T_OPCODE_STR_SP;
b99bd4ef 12457
c19d1205 12458 inst.instruction |= inst.operands[0].reg << 8;
e2b0ab59 12459 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
12460 return;
12461 }
90e4755a 12462
c19d1205
ZW
12463 constraint (inst.operands[1].reg > 7, BAD_HIREG);
12464 if (!inst.operands[1].immisreg)
12465 {
12466 /* Immediate offset. */
12467 inst.instruction |= inst.operands[0].reg;
12468 inst.instruction |= inst.operands[1].reg << 3;
e2b0ab59 12469 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
12470 return;
12471 }
90e4755a 12472
c19d1205
ZW
12473 /* Register offset. */
12474 constraint (inst.operands[1].imm > 7, BAD_HIREG);
12475 constraint (inst.operands[1].negative,
12476 _("Thumb does not support this addressing mode"));
90e4755a 12477
c19d1205
ZW
12478 op16:
12479 switch (inst.instruction)
12480 {
12481 case T_OPCODE_STR_IW: inst.instruction = T_OPCODE_STR_RW; break;
12482 case T_OPCODE_STR_IH: inst.instruction = T_OPCODE_STR_RH; break;
12483 case T_OPCODE_STR_IB: inst.instruction = T_OPCODE_STR_RB; break;
12484 case T_OPCODE_LDR_IW: inst.instruction = T_OPCODE_LDR_RW; break;
12485 case T_OPCODE_LDR_IH: inst.instruction = T_OPCODE_LDR_RH; break;
12486 case T_OPCODE_LDR_IB: inst.instruction = T_OPCODE_LDR_RB; break;
12487 case 0x5600 /* ldrsb */:
12488 case 0x5e00 /* ldrsh */: break;
12489 default: abort ();
12490 }
90e4755a 12491
c19d1205
ZW
12492 inst.instruction |= inst.operands[0].reg;
12493 inst.instruction |= inst.operands[1].reg << 3;
12494 inst.instruction |= inst.operands[1].imm << 6;
12495}
90e4755a 12496
c19d1205
ZW
12497static void
12498do_t_ldstd (void)
12499{
12500 if (!inst.operands[1].present)
b99bd4ef 12501 {
c19d1205
ZW
12502 inst.operands[1].reg = inst.operands[0].reg + 1;
12503 constraint (inst.operands[0].reg == REG_LR,
12504 _("r14 not allowed here"));
bd340a04 12505 constraint (inst.operands[0].reg == REG_R12,
477330fc 12506 _("r12 not allowed here"));
b99bd4ef 12507 }
bd340a04
MGD
12508
12509 if (inst.operands[2].writeback
12510 && (inst.operands[0].reg == inst.operands[2].reg
12511 || inst.operands[1].reg == inst.operands[2].reg))
12512 as_warn (_("base register written back, and overlaps "
477330fc 12513 "one of transfer registers"));
bd340a04 12514
c19d1205
ZW
12515 inst.instruction |= inst.operands[0].reg << 12;
12516 inst.instruction |= inst.operands[1].reg << 8;
12517 encode_thumb32_addr_mode (2, /*is_t=*/FALSE, /*is_d=*/TRUE);
b99bd4ef
NC
12518}
12519
c19d1205
ZW
12520static void
12521do_t_ldstt (void)
12522{
12523 inst.instruction |= inst.operands[0].reg << 12;
12524 encode_thumb32_addr_mode (1, /*is_t=*/TRUE, /*is_d=*/FALSE);
12525}
a737bd4d 12526
b99bd4ef 12527static void
c19d1205 12528do_t_mla (void)
b99bd4ef 12529{
fdfde340 12530 unsigned Rd, Rn, Rm, Ra;
c921be7d 12531
fdfde340
JM
12532 Rd = inst.operands[0].reg;
12533 Rn = inst.operands[1].reg;
12534 Rm = inst.operands[2].reg;
12535 Ra = inst.operands[3].reg;
12536
12537 reject_bad_reg (Rd);
12538 reject_bad_reg (Rn);
12539 reject_bad_reg (Rm);
12540 reject_bad_reg (Ra);
12541
12542 inst.instruction |= Rd << 8;
12543 inst.instruction |= Rn << 16;
12544 inst.instruction |= Rm;
12545 inst.instruction |= Ra << 12;
c19d1205 12546}
b99bd4ef 12547
c19d1205
ZW
12548static void
12549do_t_mlal (void)
12550{
fdfde340
JM
12551 unsigned RdLo, RdHi, Rn, Rm;
12552
12553 RdLo = inst.operands[0].reg;
12554 RdHi = inst.operands[1].reg;
12555 Rn = inst.operands[2].reg;
12556 Rm = inst.operands[3].reg;
12557
12558 reject_bad_reg (RdLo);
12559 reject_bad_reg (RdHi);
12560 reject_bad_reg (Rn);
12561 reject_bad_reg (Rm);
12562
12563 inst.instruction |= RdLo << 12;
12564 inst.instruction |= RdHi << 8;
12565 inst.instruction |= Rn << 16;
12566 inst.instruction |= Rm;
c19d1205 12567}
b99bd4ef 12568
c19d1205
ZW
12569static void
12570do_t_mov_cmp (void)
12571{
fdfde340
JM
12572 unsigned Rn, Rm;
12573
12574 Rn = inst.operands[0].reg;
12575 Rm = inst.operands[1].reg;
12576
e07e6e58 12577 if (Rn == REG_PC)
5ee91343 12578 set_pred_insn_type_last ();
e07e6e58 12579
c19d1205 12580 if (unified_syntax)
b99bd4ef 12581 {
c19d1205
ZW
12582 int r0off = (inst.instruction == T_MNEM_mov
12583 || inst.instruction == T_MNEM_movs) ? 8 : 16;
0110f2b8 12584 unsigned long opcode;
3d388997
PB
12585 bfd_boolean narrow;
12586 bfd_boolean low_regs;
12587
fdfde340 12588 low_regs = (Rn <= 7 && Rm <= 7);
0110f2b8 12589 opcode = inst.instruction;
5ee91343 12590 if (in_pred_block ())
0110f2b8 12591 narrow = opcode != T_MNEM_movs;
3d388997 12592 else
0110f2b8 12593 narrow = opcode != T_MNEM_movs || low_regs;
3d388997
PB
12594 if (inst.size_req == 4
12595 || inst.operands[1].shifted)
12596 narrow = FALSE;
12597
efd81785
PB
12598 /* MOVS PC, LR is encoded as SUBS PC, LR, #0. */
12599 if (opcode == T_MNEM_movs && inst.operands[1].isreg
12600 && !inst.operands[1].shifted
fdfde340
JM
12601 && Rn == REG_PC
12602 && Rm == REG_LR)
efd81785
PB
12603 {
12604 inst.instruction = T2_SUBS_PC_LR;
12605 return;
12606 }
12607
fdfde340
JM
12608 if (opcode == T_MNEM_cmp)
12609 {
12610 constraint (Rn == REG_PC, BAD_PC);
94206790
MM
12611 if (narrow)
12612 {
12613 /* In the Thumb-2 ISA, use of R13 as Rm is deprecated,
12614 but valid. */
12615 warn_deprecated_sp (Rm);
12616 /* R15 was documented as a valid choice for Rm in ARMv6,
12617 but as UNPREDICTABLE in ARMv7. ARM's proprietary
12618 tools reject R15, so we do too. */
12619 constraint (Rm == REG_PC, BAD_PC);
12620 }
12621 else
12622 reject_bad_reg (Rm);
fdfde340
JM
12623 }
12624 else if (opcode == T_MNEM_mov
12625 || opcode == T_MNEM_movs)
12626 {
12627 if (inst.operands[1].isreg)
12628 {
12629 if (opcode == T_MNEM_movs)
12630 {
12631 reject_bad_reg (Rn);
12632 reject_bad_reg (Rm);
12633 }
76fa04a4
MGD
12634 else if (narrow)
12635 {
12636 /* This is mov.n. */
12637 if ((Rn == REG_SP || Rn == REG_PC)
12638 && (Rm == REG_SP || Rm == REG_PC))
12639 {
5c3696f8 12640 as_tsktsk (_("Use of r%u as a source register is "
76fa04a4
MGD
12641 "deprecated when r%u is the destination "
12642 "register."), Rm, Rn);
12643 }
12644 }
12645 else
12646 {
12647 /* This is mov.w. */
12648 constraint (Rn == REG_PC, BAD_PC);
12649 constraint (Rm == REG_PC, BAD_PC);
5c8ed6a4
JW
12650 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
12651 constraint (Rn == REG_SP && Rm == REG_SP, BAD_SP);
76fa04a4 12652 }
fdfde340
JM
12653 }
12654 else
12655 reject_bad_reg (Rn);
12656 }
12657
c19d1205
ZW
12658 if (!inst.operands[1].isreg)
12659 {
0110f2b8 12660 /* Immediate operand. */
5ee91343 12661 if (!in_pred_block () && opcode == T_MNEM_mov)
0110f2b8
PB
12662 narrow = 0;
12663 if (low_regs && narrow)
12664 {
12665 inst.instruction = THUMB_OP16 (opcode);
fdfde340 12666 inst.instruction |= Rn << 8;
e2b0ab59
AV
12667 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
12668 || inst.relocs[0].type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
72d98d16 12669 {
a9f02af8 12670 if (inst.size_req == 2)
e2b0ab59 12671 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
a9f02af8
MG
12672 else
12673 inst.relax = opcode;
72d98d16 12674 }
0110f2b8
PB
12675 }
12676 else
12677 {
e2b0ab59
AV
12678 constraint ((inst.relocs[0].type
12679 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
12680 && (inst.relocs[0].type
12681 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8
MG
12682 THUMB1_RELOC_ONLY);
12683
0110f2b8
PB
12684 inst.instruction = THUMB_OP32 (inst.instruction);
12685 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 12686 inst.instruction |= Rn << r0off;
e2b0ab59 12687 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8 12688 }
c19d1205 12689 }
728ca7c9
PB
12690 else if (inst.operands[1].shifted && inst.operands[1].immisreg
12691 && (inst.instruction == T_MNEM_mov
12692 || inst.instruction == T_MNEM_movs))
12693 {
12694 /* Register shifts are encoded as separate shift instructions. */
12695 bfd_boolean flags = (inst.instruction == T_MNEM_movs);
12696
5ee91343 12697 if (in_pred_block ())
728ca7c9
PB
12698 narrow = !flags;
12699 else
12700 narrow = flags;
12701
12702 if (inst.size_req == 4)
12703 narrow = FALSE;
12704
12705 if (!low_regs || inst.operands[1].imm > 7)
12706 narrow = FALSE;
12707
fdfde340 12708 if (Rn != Rm)
728ca7c9
PB
12709 narrow = FALSE;
12710
12711 switch (inst.operands[1].shift_kind)
12712 {
12713 case SHIFT_LSL:
12714 opcode = narrow ? T_OPCODE_LSL_R : THUMB_OP32 (T_MNEM_lsl);
12715 break;
12716 case SHIFT_ASR:
12717 opcode = narrow ? T_OPCODE_ASR_R : THUMB_OP32 (T_MNEM_asr);
12718 break;
12719 case SHIFT_LSR:
12720 opcode = narrow ? T_OPCODE_LSR_R : THUMB_OP32 (T_MNEM_lsr);
12721 break;
12722 case SHIFT_ROR:
12723 opcode = narrow ? T_OPCODE_ROR_R : THUMB_OP32 (T_MNEM_ror);
12724 break;
12725 default:
5f4273c7 12726 abort ();
728ca7c9
PB
12727 }
12728
12729 inst.instruction = opcode;
12730 if (narrow)
12731 {
fdfde340 12732 inst.instruction |= Rn;
728ca7c9
PB
12733 inst.instruction |= inst.operands[1].imm << 3;
12734 }
12735 else
12736 {
12737 if (flags)
12738 inst.instruction |= CONDS_BIT;
12739
fdfde340
JM
12740 inst.instruction |= Rn << 8;
12741 inst.instruction |= Rm << 16;
728ca7c9
PB
12742 inst.instruction |= inst.operands[1].imm;
12743 }
12744 }
3d388997 12745 else if (!narrow)
c19d1205 12746 {
728ca7c9
PB
12747 /* Some mov with immediate shift have narrow variants.
12748 Register shifts are handled above. */
12749 if (low_regs && inst.operands[1].shifted
12750 && (inst.instruction == T_MNEM_mov
12751 || inst.instruction == T_MNEM_movs))
12752 {
5ee91343 12753 if (in_pred_block ())
728ca7c9
PB
12754 narrow = (inst.instruction == T_MNEM_mov);
12755 else
12756 narrow = (inst.instruction == T_MNEM_movs);
12757 }
12758
12759 if (narrow)
12760 {
12761 switch (inst.operands[1].shift_kind)
12762 {
12763 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
12764 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
12765 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
12766 default: narrow = FALSE; break;
12767 }
12768 }
12769
12770 if (narrow)
12771 {
fdfde340
JM
12772 inst.instruction |= Rn;
12773 inst.instruction |= Rm << 3;
e2b0ab59 12774 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
728ca7c9
PB
12775 }
12776 else
12777 {
12778 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 12779 inst.instruction |= Rn << r0off;
728ca7c9
PB
12780 encode_thumb32_shifted_operand (1);
12781 }
c19d1205
ZW
12782 }
12783 else
12784 switch (inst.instruction)
12785 {
12786 case T_MNEM_mov:
837b3435 12787 /* In v4t or v5t a move of two lowregs produces unpredictable
c6400f8a
MGD
12788 results. Don't allow this. */
12789 if (low_regs)
12790 {
12791 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6),
12792 "MOV Rd, Rs with two low registers is not "
12793 "permitted on this architecture");
fa94de6b 12794 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
c6400f8a
MGD
12795 arm_ext_v6);
12796 }
12797
c19d1205 12798 inst.instruction = T_OPCODE_MOV_HR;
fdfde340
JM
12799 inst.instruction |= (Rn & 0x8) << 4;
12800 inst.instruction |= (Rn & 0x7);
12801 inst.instruction |= Rm << 3;
c19d1205 12802 break;
b99bd4ef 12803
c19d1205
ZW
12804 case T_MNEM_movs:
12805 /* We know we have low registers at this point.
941a8a52
MGD
12806 Generate LSLS Rd, Rs, #0. */
12807 inst.instruction = T_OPCODE_LSL_I;
fdfde340
JM
12808 inst.instruction |= Rn;
12809 inst.instruction |= Rm << 3;
c19d1205
ZW
12810 break;
12811
12812 case T_MNEM_cmp:
3d388997 12813 if (low_regs)
c19d1205
ZW
12814 {
12815 inst.instruction = T_OPCODE_CMP_LR;
fdfde340
JM
12816 inst.instruction |= Rn;
12817 inst.instruction |= Rm << 3;
c19d1205
ZW
12818 }
12819 else
12820 {
12821 inst.instruction = T_OPCODE_CMP_HR;
fdfde340
JM
12822 inst.instruction |= (Rn & 0x8) << 4;
12823 inst.instruction |= (Rn & 0x7);
12824 inst.instruction |= Rm << 3;
c19d1205
ZW
12825 }
12826 break;
12827 }
b99bd4ef
NC
12828 return;
12829 }
12830
c19d1205 12831 inst.instruction = THUMB_OP16 (inst.instruction);
539d4391
NC
12832
12833 /* PR 10443: Do not silently ignore shifted operands. */
12834 constraint (inst.operands[1].shifted,
12835 _("shifts in CMP/MOV instructions are only supported in unified syntax"));
12836
c19d1205 12837 if (inst.operands[1].isreg)
b99bd4ef 12838 {
fdfde340 12839 if (Rn < 8 && Rm < 8)
b99bd4ef 12840 {
c19d1205
ZW
12841 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
12842 since a MOV instruction produces unpredictable results. */
12843 if (inst.instruction == T_OPCODE_MOV_I8)
12844 inst.instruction = T_OPCODE_ADD_I3;
b99bd4ef 12845 else
c19d1205 12846 inst.instruction = T_OPCODE_CMP_LR;
b99bd4ef 12847
fdfde340
JM
12848 inst.instruction |= Rn;
12849 inst.instruction |= Rm << 3;
b99bd4ef
NC
12850 }
12851 else
12852 {
c19d1205
ZW
12853 if (inst.instruction == T_OPCODE_MOV_I8)
12854 inst.instruction = T_OPCODE_MOV_HR;
12855 else
12856 inst.instruction = T_OPCODE_CMP_HR;
12857 do_t_cpy ();
b99bd4ef
NC
12858 }
12859 }
c19d1205 12860 else
b99bd4ef 12861 {
fdfde340 12862 constraint (Rn > 7,
c19d1205 12863 _("only lo regs allowed with immediate"));
fdfde340 12864 inst.instruction |= Rn << 8;
e2b0ab59 12865 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
c19d1205
ZW
12866 }
12867}
b99bd4ef 12868
c19d1205
ZW
12869static void
12870do_t_mov16 (void)
12871{
fdfde340 12872 unsigned Rd;
b6895b4f
PB
12873 bfd_vma imm;
12874 bfd_boolean top;
12875
12876 top = (inst.instruction & 0x00800000) != 0;
e2b0ab59 12877 if (inst.relocs[0].type == BFD_RELOC_ARM_MOVW)
b6895b4f 12878 {
33eaf5de 12879 constraint (top, _(":lower16: not allowed in this instruction"));
e2b0ab59 12880 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVW;
b6895b4f 12881 }
e2b0ab59 12882 else if (inst.relocs[0].type == BFD_RELOC_ARM_MOVT)
b6895b4f 12883 {
33eaf5de 12884 constraint (!top, _(":upper16: not allowed in this instruction"));
e2b0ab59 12885 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVT;
b6895b4f
PB
12886 }
12887
fdfde340
JM
12888 Rd = inst.operands[0].reg;
12889 reject_bad_reg (Rd);
12890
12891 inst.instruction |= Rd << 8;
e2b0ab59 12892 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 12893 {
e2b0ab59 12894 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
12895 inst.instruction |= (imm & 0xf000) << 4;
12896 inst.instruction |= (imm & 0x0800) << 15;
12897 inst.instruction |= (imm & 0x0700) << 4;
12898 inst.instruction |= (imm & 0x00ff);
12899 }
c19d1205 12900}
b99bd4ef 12901
c19d1205
ZW
12902static void
12903do_t_mvn_tst (void)
12904{
fdfde340 12905 unsigned Rn, Rm;
c921be7d 12906
fdfde340
JM
12907 Rn = inst.operands[0].reg;
12908 Rm = inst.operands[1].reg;
12909
12910 if (inst.instruction == T_MNEM_cmp
12911 || inst.instruction == T_MNEM_cmn)
12912 constraint (Rn == REG_PC, BAD_PC);
12913 else
12914 reject_bad_reg (Rn);
12915 reject_bad_reg (Rm);
12916
c19d1205
ZW
12917 if (unified_syntax)
12918 {
12919 int r0off = (inst.instruction == T_MNEM_mvn
12920 || inst.instruction == T_MNEM_mvns) ? 8 : 16;
3d388997
PB
12921 bfd_boolean narrow;
12922
12923 if (inst.size_req == 4
12924 || inst.instruction > 0xffff
12925 || inst.operands[1].shifted
fdfde340 12926 || Rn > 7 || Rm > 7)
3d388997 12927 narrow = FALSE;
fe8b4cc3
KT
12928 else if (inst.instruction == T_MNEM_cmn
12929 || inst.instruction == T_MNEM_tst)
3d388997
PB
12930 narrow = TRUE;
12931 else if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 12932 narrow = !in_pred_block ();
3d388997 12933 else
5ee91343 12934 narrow = in_pred_block ();
3d388997 12935
c19d1205 12936 if (!inst.operands[1].isreg)
b99bd4ef 12937 {
c19d1205
ZW
12938 /* For an immediate, we always generate a 32-bit opcode;
12939 section relaxation will shrink it later if possible. */
12940 if (inst.instruction < 0xffff)
12941 inst.instruction = THUMB_OP32 (inst.instruction);
12942 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 12943 inst.instruction |= Rn << r0off;
e2b0ab59 12944 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 12945 }
c19d1205 12946 else
b99bd4ef 12947 {
c19d1205 12948 /* See if we can do this with a 16-bit instruction. */
3d388997 12949 if (narrow)
b99bd4ef 12950 {
c19d1205 12951 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
12952 inst.instruction |= Rn;
12953 inst.instruction |= Rm << 3;
b99bd4ef 12954 }
c19d1205 12955 else
b99bd4ef 12956 {
c19d1205
ZW
12957 constraint (inst.operands[1].shifted
12958 && inst.operands[1].immisreg,
12959 _("shift must be constant"));
12960 if (inst.instruction < 0xffff)
12961 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 12962 inst.instruction |= Rn << r0off;
c19d1205 12963 encode_thumb32_shifted_operand (1);
b99bd4ef 12964 }
b99bd4ef
NC
12965 }
12966 }
12967 else
12968 {
c19d1205
ZW
12969 constraint (inst.instruction > 0xffff
12970 || inst.instruction == T_MNEM_mvns, BAD_THUMB32);
12971 constraint (!inst.operands[1].isreg || inst.operands[1].shifted,
12972 _("unshifted register required"));
fdfde340 12973 constraint (Rn > 7 || Rm > 7,
c19d1205 12974 BAD_HIREG);
b99bd4ef 12975
c19d1205 12976 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
12977 inst.instruction |= Rn;
12978 inst.instruction |= Rm << 3;
b99bd4ef 12979 }
b99bd4ef
NC
12980}
12981
b05fe5cf 12982static void
c19d1205 12983do_t_mrs (void)
b05fe5cf 12984{
fdfde340 12985 unsigned Rd;
037e8744
JB
12986
12987 if (do_vfp_nsyn_mrs () == SUCCESS)
12988 return;
12989
90ec0d68
MGD
12990 Rd = inst.operands[0].reg;
12991 reject_bad_reg (Rd);
12992 inst.instruction |= Rd << 8;
12993
12994 if (inst.operands[1].isreg)
62b3e311 12995 {
90ec0d68
MGD
12996 unsigned br = inst.operands[1].reg;
12997 if (((br & 0x200) == 0) && ((br & 0xf000) != 0xf000))
12998 as_bad (_("bad register for mrs"));
12999
13000 inst.instruction |= br & (0xf << 16);
13001 inst.instruction |= (br & 0x300) >> 4;
13002 inst.instruction |= (br & SPSR_BIT) >> 2;
62b3e311
PB
13003 }
13004 else
13005 {
90ec0d68 13006 int flags = inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
5f4273c7 13007
d2cd1205 13008 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
1a43faaf
NC
13009 {
13010 /* PR gas/12698: The constraint is only applied for m_profile.
13011 If the user has specified -march=all, we want to ignore it as
13012 we are building for any CPU type, including non-m variants. */
823d2571
TG
13013 bfd_boolean m_profile =
13014 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf
NC
13015 constraint ((flags != 0) && m_profile, _("selected processor does "
13016 "not support requested special purpose register"));
13017 }
90ec0d68 13018 else
d2cd1205
JB
13019 /* mrs only accepts APSR/CPSR/SPSR/CPSR_all/SPSR_all (for non-M profile
13020 devices). */
13021 constraint ((flags & ~SPSR_BIT) != (PSR_c|PSR_f),
13022 _("'APSR', 'CPSR' or 'SPSR' expected"));
fdfde340 13023
90ec0d68
MGD
13024 inst.instruction |= (flags & SPSR_BIT) >> 2;
13025 inst.instruction |= inst.operands[1].imm & 0xff;
13026 inst.instruction |= 0xf0000;
13027 }
c19d1205 13028}
b05fe5cf 13029
c19d1205
ZW
13030static void
13031do_t_msr (void)
13032{
62b3e311 13033 int flags;
fdfde340 13034 unsigned Rn;
62b3e311 13035
037e8744
JB
13036 if (do_vfp_nsyn_msr () == SUCCESS)
13037 return;
13038
c19d1205
ZW
13039 constraint (!inst.operands[1].isreg,
13040 _("Thumb encoding does not support an immediate here"));
90ec0d68
MGD
13041
13042 if (inst.operands[0].isreg)
13043 flags = (int)(inst.operands[0].reg);
13044 else
13045 flags = inst.operands[0].imm;
13046
d2cd1205 13047 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
62b3e311 13048 {
d2cd1205
JB
13049 int bits = inst.operands[0].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
13050
1a43faaf 13051 /* PR gas/12698: The constraint is only applied for m_profile.
477330fc
RM
13052 If the user has specified -march=all, we want to ignore it as
13053 we are building for any CPU type, including non-m variants. */
823d2571
TG
13054 bfd_boolean m_profile =
13055 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf 13056 constraint (((ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
477330fc
RM
13057 && (bits & ~(PSR_s | PSR_f)) != 0)
13058 || (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
13059 && bits != PSR_f)) && m_profile,
13060 _("selected processor does not support requested special "
13061 "purpose register"));
62b3e311
PB
13062 }
13063 else
d2cd1205
JB
13064 constraint ((flags & 0xff) != 0, _("selected processor does not support "
13065 "requested special purpose register"));
c921be7d 13066
fdfde340
JM
13067 Rn = inst.operands[1].reg;
13068 reject_bad_reg (Rn);
13069
62b3e311 13070 inst.instruction |= (flags & SPSR_BIT) >> 2;
90ec0d68
MGD
13071 inst.instruction |= (flags & 0xf0000) >> 8;
13072 inst.instruction |= (flags & 0x300) >> 4;
62b3e311 13073 inst.instruction |= (flags & 0xff);
fdfde340 13074 inst.instruction |= Rn << 16;
c19d1205 13075}
b05fe5cf 13076
c19d1205
ZW
13077static void
13078do_t_mul (void)
13079{
17828f45 13080 bfd_boolean narrow;
fdfde340 13081 unsigned Rd, Rn, Rm;
17828f45 13082
c19d1205
ZW
13083 if (!inst.operands[2].present)
13084 inst.operands[2].reg = inst.operands[0].reg;
b05fe5cf 13085
fdfde340
JM
13086 Rd = inst.operands[0].reg;
13087 Rn = inst.operands[1].reg;
13088 Rm = inst.operands[2].reg;
13089
17828f45 13090 if (unified_syntax)
b05fe5cf 13091 {
17828f45 13092 if (inst.size_req == 4
fdfde340
JM
13093 || (Rd != Rn
13094 && Rd != Rm)
13095 || Rn > 7
13096 || Rm > 7)
17828f45
JM
13097 narrow = FALSE;
13098 else if (inst.instruction == T_MNEM_muls)
5ee91343 13099 narrow = !in_pred_block ();
17828f45 13100 else
5ee91343 13101 narrow = in_pred_block ();
b05fe5cf 13102 }
c19d1205 13103 else
b05fe5cf 13104 {
17828f45 13105 constraint (inst.instruction == T_MNEM_muls, BAD_THUMB32);
fdfde340 13106 constraint (Rn > 7 || Rm > 7,
c19d1205 13107 BAD_HIREG);
17828f45
JM
13108 narrow = TRUE;
13109 }
b05fe5cf 13110
17828f45
JM
13111 if (narrow)
13112 {
13113 /* 16-bit MULS/Conditional MUL. */
c19d1205 13114 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 13115 inst.instruction |= Rd;
b05fe5cf 13116
fdfde340
JM
13117 if (Rd == Rn)
13118 inst.instruction |= Rm << 3;
13119 else if (Rd == Rm)
13120 inst.instruction |= Rn << 3;
c19d1205
ZW
13121 else
13122 constraint (1, _("dest must overlap one source register"));
13123 }
17828f45
JM
13124 else
13125 {
e07e6e58
NC
13126 constraint (inst.instruction != T_MNEM_mul,
13127 _("Thumb-2 MUL must not set flags"));
17828f45
JM
13128 /* 32-bit MUL. */
13129 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13130 inst.instruction |= Rd << 8;
13131 inst.instruction |= Rn << 16;
13132 inst.instruction |= Rm << 0;
13133
13134 reject_bad_reg (Rd);
13135 reject_bad_reg (Rn);
13136 reject_bad_reg (Rm);
17828f45 13137 }
c19d1205 13138}
b05fe5cf 13139
c19d1205
ZW
13140static void
13141do_t_mull (void)
13142{
fdfde340 13143 unsigned RdLo, RdHi, Rn, Rm;
b05fe5cf 13144
fdfde340
JM
13145 RdLo = inst.operands[0].reg;
13146 RdHi = inst.operands[1].reg;
13147 Rn = inst.operands[2].reg;
13148 Rm = inst.operands[3].reg;
13149
13150 reject_bad_reg (RdLo);
13151 reject_bad_reg (RdHi);
13152 reject_bad_reg (Rn);
13153 reject_bad_reg (Rm);
13154
13155 inst.instruction |= RdLo << 12;
13156 inst.instruction |= RdHi << 8;
13157 inst.instruction |= Rn << 16;
13158 inst.instruction |= Rm;
13159
13160 if (RdLo == RdHi)
c19d1205
ZW
13161 as_tsktsk (_("rdhi and rdlo must be different"));
13162}
b05fe5cf 13163
c19d1205
ZW
13164static void
13165do_t_nop (void)
13166{
5ee91343 13167 set_pred_insn_type (NEUTRAL_IT_INSN);
e07e6e58 13168
c19d1205
ZW
13169 if (unified_syntax)
13170 {
13171 if (inst.size_req == 4 || inst.operands[0].imm > 15)
b05fe5cf 13172 {
c19d1205
ZW
13173 inst.instruction = THUMB_OP32 (inst.instruction);
13174 inst.instruction |= inst.operands[0].imm;
13175 }
13176 else
13177 {
bc2d1808
NC
13178 /* PR9722: Check for Thumb2 availability before
13179 generating a thumb2 nop instruction. */
afa62d5e 13180 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2))
bc2d1808
NC
13181 {
13182 inst.instruction = THUMB_OP16 (inst.instruction);
13183 inst.instruction |= inst.operands[0].imm << 4;
13184 }
13185 else
13186 inst.instruction = 0x46c0;
c19d1205
ZW
13187 }
13188 }
13189 else
13190 {
13191 constraint (inst.operands[0].present,
13192 _("Thumb does not support NOP with hints"));
13193 inst.instruction = 0x46c0;
13194 }
13195}
b05fe5cf 13196
c19d1205
ZW
13197static void
13198do_t_neg (void)
13199{
13200 if (unified_syntax)
13201 {
3d388997
PB
13202 bfd_boolean narrow;
13203
13204 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 13205 narrow = !in_pred_block ();
3d388997 13206 else
5ee91343 13207 narrow = in_pred_block ();
3d388997
PB
13208 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
13209 narrow = FALSE;
13210 if (inst.size_req == 4)
13211 narrow = FALSE;
13212
13213 if (!narrow)
c19d1205
ZW
13214 {
13215 inst.instruction = THUMB_OP32 (inst.instruction);
13216 inst.instruction |= inst.operands[0].reg << 8;
13217 inst.instruction |= inst.operands[1].reg << 16;
b05fe5cf
ZW
13218 }
13219 else
13220 {
c19d1205
ZW
13221 inst.instruction = THUMB_OP16 (inst.instruction);
13222 inst.instruction |= inst.operands[0].reg;
13223 inst.instruction |= inst.operands[1].reg << 3;
b05fe5cf
ZW
13224 }
13225 }
13226 else
13227 {
c19d1205
ZW
13228 constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7,
13229 BAD_HIREG);
13230 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
13231
13232 inst.instruction = THUMB_OP16 (inst.instruction);
13233 inst.instruction |= inst.operands[0].reg;
13234 inst.instruction |= inst.operands[1].reg << 3;
13235 }
13236}
13237
1c444d06
JM
13238static void
13239do_t_orn (void)
13240{
13241 unsigned Rd, Rn;
13242
13243 Rd = inst.operands[0].reg;
13244 Rn = inst.operands[1].present ? inst.operands[1].reg : Rd;
13245
fdfde340
JM
13246 reject_bad_reg (Rd);
13247 /* Rn == REG_SP is unpredictable; Rn == REG_PC is MVN. */
13248 reject_bad_reg (Rn);
13249
1c444d06
JM
13250 inst.instruction |= Rd << 8;
13251 inst.instruction |= Rn << 16;
13252
13253 if (!inst.operands[2].isreg)
13254 {
13255 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 13256 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
1c444d06
JM
13257 }
13258 else
13259 {
13260 unsigned Rm;
13261
13262 Rm = inst.operands[2].reg;
fdfde340 13263 reject_bad_reg (Rm);
1c444d06
JM
13264
13265 constraint (inst.operands[2].shifted
13266 && inst.operands[2].immisreg,
13267 _("shift must be constant"));
13268 encode_thumb32_shifted_operand (2);
13269 }
13270}
13271
c19d1205
ZW
13272static void
13273do_t_pkhbt (void)
13274{
fdfde340
JM
13275 unsigned Rd, Rn, Rm;
13276
13277 Rd = inst.operands[0].reg;
13278 Rn = inst.operands[1].reg;
13279 Rm = inst.operands[2].reg;
13280
13281 reject_bad_reg (Rd);
13282 reject_bad_reg (Rn);
13283 reject_bad_reg (Rm);
13284
13285 inst.instruction |= Rd << 8;
13286 inst.instruction |= Rn << 16;
13287 inst.instruction |= Rm;
c19d1205
ZW
13288 if (inst.operands[3].present)
13289 {
e2b0ab59
AV
13290 unsigned int val = inst.relocs[0].exp.X_add_number;
13291 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
13292 _("expression too complex"));
13293 inst.instruction |= (val & 0x1c) << 10;
13294 inst.instruction |= (val & 0x03) << 6;
b05fe5cf 13295 }
c19d1205 13296}
b05fe5cf 13297
c19d1205
ZW
13298static void
13299do_t_pkhtb (void)
13300{
13301 if (!inst.operands[3].present)
1ef52f49
NC
13302 {
13303 unsigned Rtmp;
13304
13305 inst.instruction &= ~0x00000020;
13306
13307 /* PR 10168. Swap the Rm and Rn registers. */
13308 Rtmp = inst.operands[1].reg;
13309 inst.operands[1].reg = inst.operands[2].reg;
13310 inst.operands[2].reg = Rtmp;
13311 }
c19d1205 13312 do_t_pkhbt ();
b05fe5cf
ZW
13313}
13314
c19d1205
ZW
13315static void
13316do_t_pld (void)
13317{
fdfde340
JM
13318 if (inst.operands[0].immisreg)
13319 reject_bad_reg (inst.operands[0].imm);
13320
c19d1205
ZW
13321 encode_thumb32_addr_mode (0, /*is_t=*/FALSE, /*is_d=*/FALSE);
13322}
b05fe5cf 13323
c19d1205
ZW
13324static void
13325do_t_push_pop (void)
b99bd4ef 13326{
e9f89963 13327 unsigned mask;
5f4273c7 13328
c19d1205
ZW
13329 constraint (inst.operands[0].writeback,
13330 _("push/pop do not support {reglist}^"));
e2b0ab59 13331 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205 13332 _("expression too complex"));
b99bd4ef 13333
e9f89963 13334 mask = inst.operands[0].imm;
d3bfe16e 13335 if (inst.size_req != 4 && (mask & ~0xff) == 0)
3c707909 13336 inst.instruction = THUMB_OP16 (inst.instruction) | mask;
d3bfe16e 13337 else if (inst.size_req != 4
c6025a80 13338 && (mask & ~0xff) == (1U << (inst.instruction == T_MNEM_push
d3bfe16e 13339 ? REG_LR : REG_PC)))
b99bd4ef 13340 {
c19d1205
ZW
13341 inst.instruction = THUMB_OP16 (inst.instruction);
13342 inst.instruction |= THUMB_PP_PC_LR;
3c707909 13343 inst.instruction |= mask & 0xff;
c19d1205
ZW
13344 }
13345 else if (unified_syntax)
13346 {
3c707909 13347 inst.instruction = THUMB_OP32 (inst.instruction);
4b5a202f
AV
13348 encode_thumb2_multi (TRUE /* do_io */, 13, mask, TRUE);
13349 }
13350 else
13351 {
13352 inst.error = _("invalid register list to push/pop instruction");
13353 return;
c19d1205 13354 }
4b5a202f
AV
13355}
13356
13357static void
13358do_t_clrm (void)
13359{
13360 if (unified_syntax)
13361 encode_thumb2_multi (FALSE /* do_io */, -1, inst.operands[0].imm, FALSE);
c19d1205
ZW
13362 else
13363 {
13364 inst.error = _("invalid register list to push/pop instruction");
13365 return;
13366 }
c19d1205 13367}
b99bd4ef 13368
efd6b359
AV
13369static void
13370do_t_vscclrm (void)
13371{
13372 if (inst.operands[0].issingle)
13373 {
13374 inst.instruction |= (inst.operands[0].reg & 0x1) << 22;
13375 inst.instruction |= (inst.operands[0].reg & 0x1e) << 11;
13376 inst.instruction |= inst.operands[0].imm;
13377 }
13378 else
13379 {
13380 inst.instruction |= (inst.operands[0].reg & 0x10) << 18;
13381 inst.instruction |= (inst.operands[0].reg & 0xf) << 12;
13382 inst.instruction |= 1 << 8;
13383 inst.instruction |= inst.operands[0].imm << 1;
13384 }
13385}
13386
c19d1205
ZW
13387static void
13388do_t_rbit (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 inst.instruction |= Rd << 8;
13399 inst.instruction |= Rm << 16;
13400 inst.instruction |= Rm;
c19d1205 13401}
b99bd4ef 13402
c19d1205
ZW
13403static void
13404do_t_rev (void)
13405{
fdfde340
JM
13406 unsigned Rd, Rm;
13407
13408 Rd = inst.operands[0].reg;
13409 Rm = inst.operands[1].reg;
13410
13411 reject_bad_reg (Rd);
13412 reject_bad_reg (Rm);
13413
13414 if (Rd <= 7 && Rm <= 7
c19d1205
ZW
13415 && inst.size_req != 4)
13416 {
13417 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13418 inst.instruction |= Rd;
13419 inst.instruction |= Rm << 3;
c19d1205
ZW
13420 }
13421 else if (unified_syntax)
13422 {
13423 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13424 inst.instruction |= Rd << 8;
13425 inst.instruction |= Rm << 16;
13426 inst.instruction |= Rm;
c19d1205
ZW
13427 }
13428 else
13429 inst.error = BAD_HIREG;
13430}
b99bd4ef 13431
1c444d06
JM
13432static void
13433do_t_rrx (void)
13434{
13435 unsigned Rd, Rm;
13436
13437 Rd = inst.operands[0].reg;
13438 Rm = inst.operands[1].reg;
13439
fdfde340
JM
13440 reject_bad_reg (Rd);
13441 reject_bad_reg (Rm);
c921be7d 13442
1c444d06
JM
13443 inst.instruction |= Rd << 8;
13444 inst.instruction |= Rm;
13445}
13446
c19d1205
ZW
13447static void
13448do_t_rsb (void)
13449{
fdfde340 13450 unsigned Rd, Rs;
b99bd4ef 13451
c19d1205
ZW
13452 Rd = inst.operands[0].reg;
13453 Rs = (inst.operands[1].present
13454 ? inst.operands[1].reg /* Rd, Rs, foo */
13455 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
b99bd4ef 13456
fdfde340
JM
13457 reject_bad_reg (Rd);
13458 reject_bad_reg (Rs);
13459 if (inst.operands[2].isreg)
13460 reject_bad_reg (inst.operands[2].reg);
13461
c19d1205
ZW
13462 inst.instruction |= Rd << 8;
13463 inst.instruction |= Rs << 16;
13464 if (!inst.operands[2].isreg)
13465 {
026d3abb
PB
13466 bfd_boolean narrow;
13467
13468 if ((inst.instruction & 0x00100000) != 0)
5ee91343 13469 narrow = !in_pred_block ();
026d3abb 13470 else
5ee91343 13471 narrow = in_pred_block ();
026d3abb
PB
13472
13473 if (Rd > 7 || Rs > 7)
13474 narrow = FALSE;
13475
13476 if (inst.size_req == 4 || !unified_syntax)
13477 narrow = FALSE;
13478
e2b0ab59
AV
13479 if (inst.relocs[0].exp.X_op != O_constant
13480 || inst.relocs[0].exp.X_add_number != 0)
026d3abb
PB
13481 narrow = FALSE;
13482
13483 /* Turn rsb #0 into 16-bit neg. We should probably do this via
477330fc 13484 relaxation, but it doesn't seem worth the hassle. */
026d3abb
PB
13485 if (narrow)
13486 {
e2b0ab59 13487 inst.relocs[0].type = BFD_RELOC_UNUSED;
026d3abb
PB
13488 inst.instruction = THUMB_OP16 (T_MNEM_negs);
13489 inst.instruction |= Rs << 3;
13490 inst.instruction |= Rd;
13491 }
13492 else
13493 {
13494 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 13495 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
026d3abb 13496 }
c19d1205
ZW
13497 }
13498 else
13499 encode_thumb32_shifted_operand (2);
13500}
b99bd4ef 13501
c19d1205
ZW
13502static void
13503do_t_setend (void)
13504{
12e37cbc
MGD
13505 if (warn_on_deprecated
13506 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 13507 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 13508
5ee91343 13509 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205
ZW
13510 if (inst.operands[0].imm)
13511 inst.instruction |= 0x8;
13512}
b99bd4ef 13513
c19d1205
ZW
13514static void
13515do_t_shift (void)
13516{
13517 if (!inst.operands[1].present)
13518 inst.operands[1].reg = inst.operands[0].reg;
13519
13520 if (unified_syntax)
13521 {
3d388997
PB
13522 bfd_boolean narrow;
13523 int shift_kind;
13524
13525 switch (inst.instruction)
13526 {
13527 case T_MNEM_asr:
13528 case T_MNEM_asrs: shift_kind = SHIFT_ASR; break;
13529 case T_MNEM_lsl:
13530 case T_MNEM_lsls: shift_kind = SHIFT_LSL; break;
13531 case T_MNEM_lsr:
13532 case T_MNEM_lsrs: shift_kind = SHIFT_LSR; break;
13533 case T_MNEM_ror:
13534 case T_MNEM_rors: shift_kind = SHIFT_ROR; break;
13535 default: abort ();
13536 }
13537
13538 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 13539 narrow = !in_pred_block ();
3d388997 13540 else
5ee91343 13541 narrow = in_pred_block ();
3d388997
PB
13542 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
13543 narrow = FALSE;
13544 if (!inst.operands[2].isreg && shift_kind == SHIFT_ROR)
13545 narrow = FALSE;
13546 if (inst.operands[2].isreg
13547 && (inst.operands[1].reg != inst.operands[0].reg
13548 || inst.operands[2].reg > 7))
13549 narrow = FALSE;
13550 if (inst.size_req == 4)
13551 narrow = FALSE;
13552
fdfde340
JM
13553 reject_bad_reg (inst.operands[0].reg);
13554 reject_bad_reg (inst.operands[1].reg);
c921be7d 13555
3d388997 13556 if (!narrow)
c19d1205
ZW
13557 {
13558 if (inst.operands[2].isreg)
b99bd4ef 13559 {
fdfde340 13560 reject_bad_reg (inst.operands[2].reg);
c19d1205
ZW
13561 inst.instruction = THUMB_OP32 (inst.instruction);
13562 inst.instruction |= inst.operands[0].reg << 8;
13563 inst.instruction |= inst.operands[1].reg << 16;
13564 inst.instruction |= inst.operands[2].reg;
94342ec3
NC
13565
13566 /* PR 12854: Error on extraneous shifts. */
13567 constraint (inst.operands[2].shifted,
13568 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
13569 }
13570 else
13571 {
13572 inst.operands[1].shifted = 1;
3d388997 13573 inst.operands[1].shift_kind = shift_kind;
c19d1205
ZW
13574 inst.instruction = THUMB_OP32 (THUMB_SETS_FLAGS (inst.instruction)
13575 ? T_MNEM_movs : T_MNEM_mov);
13576 inst.instruction |= inst.operands[0].reg << 8;
13577 encode_thumb32_shifted_operand (1);
13578 /* Prevent the incorrect generation of an ARM_IMMEDIATE fixup. */
e2b0ab59 13579 inst.relocs[0].type = BFD_RELOC_UNUSED;
b99bd4ef
NC
13580 }
13581 }
13582 else
13583 {
c19d1205 13584 if (inst.operands[2].isreg)
b99bd4ef 13585 {
3d388997 13586 switch (shift_kind)
b99bd4ef 13587 {
3d388997
PB
13588 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_R; break;
13589 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_R; break;
13590 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_R; break;
13591 case SHIFT_ROR: inst.instruction = T_OPCODE_ROR_R; break;
c19d1205 13592 default: abort ();
b99bd4ef 13593 }
5f4273c7 13594
c19d1205
ZW
13595 inst.instruction |= inst.operands[0].reg;
13596 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
13597
13598 /* PR 12854: Error on extraneous shifts. */
13599 constraint (inst.operands[2].shifted,
13600 _("extraneous shift as part of operand to shift insn"));
b99bd4ef
NC
13601 }
13602 else
13603 {
3d388997 13604 switch (shift_kind)
b99bd4ef 13605 {
3d388997
PB
13606 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
13607 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
13608 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
c19d1205 13609 default: abort ();
b99bd4ef 13610 }
e2b0ab59 13611 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
13612 inst.instruction |= inst.operands[0].reg;
13613 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
13614 }
13615 }
c19d1205
ZW
13616 }
13617 else
13618 {
13619 constraint (inst.operands[0].reg > 7
13620 || inst.operands[1].reg > 7, BAD_HIREG);
13621 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
b99bd4ef 13622
c19d1205
ZW
13623 if (inst.operands[2].isreg) /* Rd, {Rs,} Rn */
13624 {
13625 constraint (inst.operands[2].reg > 7, BAD_HIREG);
13626 constraint (inst.operands[0].reg != inst.operands[1].reg,
13627 _("source1 and dest must be same register"));
b99bd4ef 13628
c19d1205
ZW
13629 switch (inst.instruction)
13630 {
13631 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_R; break;
13632 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_R; break;
13633 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_R; break;
13634 case T_MNEM_ror: inst.instruction = T_OPCODE_ROR_R; break;
13635 default: abort ();
13636 }
5f4273c7 13637
c19d1205
ZW
13638 inst.instruction |= inst.operands[0].reg;
13639 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
13640
13641 /* PR 12854: Error on extraneous shifts. */
13642 constraint (inst.operands[2].shifted,
13643 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
13644 }
13645 else
b99bd4ef 13646 {
c19d1205
ZW
13647 switch (inst.instruction)
13648 {
13649 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_I; break;
13650 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_I; break;
13651 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_I; break;
13652 case T_MNEM_ror: inst.error = _("ror #imm not supported"); return;
13653 default: abort ();
13654 }
e2b0ab59 13655 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
13656 inst.instruction |= inst.operands[0].reg;
13657 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
13658 }
13659 }
b99bd4ef
NC
13660}
13661
13662static void
c19d1205 13663do_t_simd (void)
b99bd4ef 13664{
fdfde340
JM
13665 unsigned Rd, Rn, Rm;
13666
13667 Rd = inst.operands[0].reg;
13668 Rn = inst.operands[1].reg;
13669 Rm = inst.operands[2].reg;
13670
13671 reject_bad_reg (Rd);
13672 reject_bad_reg (Rn);
13673 reject_bad_reg (Rm);
13674
13675 inst.instruction |= Rd << 8;
13676 inst.instruction |= Rn << 16;
13677 inst.instruction |= Rm;
c19d1205 13678}
b99bd4ef 13679
03ee1b7f
NC
13680static void
13681do_t_simd2 (void)
13682{
13683 unsigned Rd, Rn, Rm;
13684
13685 Rd = inst.operands[0].reg;
13686 Rm = inst.operands[1].reg;
13687 Rn = inst.operands[2].reg;
13688
13689 reject_bad_reg (Rd);
13690 reject_bad_reg (Rn);
13691 reject_bad_reg (Rm);
13692
13693 inst.instruction |= Rd << 8;
13694 inst.instruction |= Rn << 16;
13695 inst.instruction |= Rm;
13696}
13697
c19d1205 13698static void
3eb17e6b 13699do_t_smc (void)
c19d1205 13700{
e2b0ab59 13701 unsigned int value = inst.relocs[0].exp.X_add_number;
f4c65163
MGD
13702 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a),
13703 _("SMC is not permitted on this architecture"));
e2b0ab59 13704 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 13705 _("expression too complex"));
e2b0ab59 13706 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205
ZW
13707 inst.instruction |= (value & 0xf000) >> 12;
13708 inst.instruction |= (value & 0x0ff0);
13709 inst.instruction |= (value & 0x000f) << 16;
24382199 13710 /* PR gas/15623: SMC instructions must be last in an IT block. */
5ee91343 13711 set_pred_insn_type_last ();
c19d1205 13712}
b99bd4ef 13713
90ec0d68
MGD
13714static void
13715do_t_hvc (void)
13716{
e2b0ab59 13717 unsigned int value = inst.relocs[0].exp.X_add_number;
90ec0d68 13718
e2b0ab59 13719 inst.relocs[0].type = BFD_RELOC_UNUSED;
90ec0d68
MGD
13720 inst.instruction |= (value & 0x0fff);
13721 inst.instruction |= (value & 0xf000) << 4;
13722}
13723
c19d1205 13724static void
3a21c15a 13725do_t_ssat_usat (int bias)
c19d1205 13726{
fdfde340
JM
13727 unsigned Rd, Rn;
13728
13729 Rd = inst.operands[0].reg;
13730 Rn = inst.operands[2].reg;
13731
13732 reject_bad_reg (Rd);
13733 reject_bad_reg (Rn);
13734
13735 inst.instruction |= Rd << 8;
3a21c15a 13736 inst.instruction |= inst.operands[1].imm - bias;
fdfde340 13737 inst.instruction |= Rn << 16;
b99bd4ef 13738
c19d1205 13739 if (inst.operands[3].present)
b99bd4ef 13740 {
e2b0ab59 13741 offsetT shift_amount = inst.relocs[0].exp.X_add_number;
3a21c15a 13742
e2b0ab59 13743 inst.relocs[0].type = BFD_RELOC_UNUSED;
3a21c15a 13744
e2b0ab59 13745 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 13746 _("expression too complex"));
b99bd4ef 13747
3a21c15a 13748 if (shift_amount != 0)
6189168b 13749 {
3a21c15a
NC
13750 constraint (shift_amount > 31,
13751 _("shift expression is too large"));
13752
c19d1205 13753 if (inst.operands[3].shift_kind == SHIFT_ASR)
3a21c15a
NC
13754 inst.instruction |= 0x00200000; /* sh bit. */
13755
13756 inst.instruction |= (shift_amount & 0x1c) << 10;
13757 inst.instruction |= (shift_amount & 0x03) << 6;
6189168b
NC
13758 }
13759 }
b99bd4ef 13760}
c921be7d 13761
3a21c15a
NC
13762static void
13763do_t_ssat (void)
13764{
13765 do_t_ssat_usat (1);
13766}
b99bd4ef 13767
0dd132b6 13768static void
c19d1205 13769do_t_ssat16 (void)
0dd132b6 13770{
fdfde340
JM
13771 unsigned Rd, Rn;
13772
13773 Rd = inst.operands[0].reg;
13774 Rn = inst.operands[2].reg;
13775
13776 reject_bad_reg (Rd);
13777 reject_bad_reg (Rn);
13778
13779 inst.instruction |= Rd << 8;
c19d1205 13780 inst.instruction |= inst.operands[1].imm - 1;
fdfde340 13781 inst.instruction |= Rn << 16;
c19d1205 13782}
0dd132b6 13783
c19d1205
ZW
13784static void
13785do_t_strex (void)
13786{
13787 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
13788 || inst.operands[2].postind || inst.operands[2].writeback
13789 || inst.operands[2].immisreg || inst.operands[2].shifted
13790 || inst.operands[2].negative,
01cfc07f 13791 BAD_ADDR_MODE);
0dd132b6 13792
5be8be5d
DG
13793 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
13794
c19d1205
ZW
13795 inst.instruction |= inst.operands[0].reg << 8;
13796 inst.instruction |= inst.operands[1].reg << 12;
13797 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 13798 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
0dd132b6
NC
13799}
13800
b99bd4ef 13801static void
c19d1205 13802do_t_strexd (void)
b99bd4ef 13803{
c19d1205
ZW
13804 if (!inst.operands[2].present)
13805 inst.operands[2].reg = inst.operands[1].reg + 1;
b99bd4ef 13806
c19d1205
ZW
13807 constraint (inst.operands[0].reg == inst.operands[1].reg
13808 || inst.operands[0].reg == inst.operands[2].reg
f8a8e9d6 13809 || inst.operands[0].reg == inst.operands[3].reg,
c19d1205 13810 BAD_OVERLAP);
b99bd4ef 13811
c19d1205
ZW
13812 inst.instruction |= inst.operands[0].reg;
13813 inst.instruction |= inst.operands[1].reg << 12;
13814 inst.instruction |= inst.operands[2].reg << 8;
13815 inst.instruction |= inst.operands[3].reg << 16;
b99bd4ef
NC
13816}
13817
13818static void
c19d1205 13819do_t_sxtah (void)
b99bd4ef 13820{
fdfde340
JM
13821 unsigned Rd, Rn, Rm;
13822
13823 Rd = inst.operands[0].reg;
13824 Rn = inst.operands[1].reg;
13825 Rm = inst.operands[2].reg;
13826
13827 reject_bad_reg (Rd);
13828 reject_bad_reg (Rn);
13829 reject_bad_reg (Rm);
13830
13831 inst.instruction |= Rd << 8;
13832 inst.instruction |= Rn << 16;
13833 inst.instruction |= Rm;
c19d1205
ZW
13834 inst.instruction |= inst.operands[3].imm << 4;
13835}
b99bd4ef 13836
c19d1205
ZW
13837static void
13838do_t_sxth (void)
13839{
fdfde340
JM
13840 unsigned Rd, Rm;
13841
13842 Rd = inst.operands[0].reg;
13843 Rm = inst.operands[1].reg;
13844
13845 reject_bad_reg (Rd);
13846 reject_bad_reg (Rm);
c921be7d
NC
13847
13848 if (inst.instruction <= 0xffff
13849 && inst.size_req != 4
fdfde340 13850 && Rd <= 7 && Rm <= 7
c19d1205 13851 && (!inst.operands[2].present || inst.operands[2].imm == 0))
b99bd4ef 13852 {
c19d1205 13853 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13854 inst.instruction |= Rd;
13855 inst.instruction |= Rm << 3;
b99bd4ef 13856 }
c19d1205 13857 else if (unified_syntax)
b99bd4ef 13858 {
c19d1205
ZW
13859 if (inst.instruction <= 0xffff)
13860 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13861 inst.instruction |= Rd << 8;
13862 inst.instruction |= Rm;
c19d1205 13863 inst.instruction |= inst.operands[2].imm << 4;
b99bd4ef 13864 }
c19d1205 13865 else
b99bd4ef 13866 {
c19d1205
ZW
13867 constraint (inst.operands[2].present && inst.operands[2].imm != 0,
13868 _("Thumb encoding does not support rotation"));
13869 constraint (1, BAD_HIREG);
b99bd4ef 13870 }
c19d1205 13871}
b99bd4ef 13872
c19d1205
ZW
13873static void
13874do_t_swi (void)
13875{
e2b0ab59 13876 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
c19d1205 13877}
b99bd4ef 13878
92e90b6e
PB
13879static void
13880do_t_tb (void)
13881{
fdfde340 13882 unsigned Rn, Rm;
92e90b6e
PB
13883 int half;
13884
13885 half = (inst.instruction & 0x10) != 0;
5ee91343 13886 set_pred_insn_type_last ();
dfa9f0d5
PB
13887 constraint (inst.operands[0].immisreg,
13888 _("instruction requires register index"));
fdfde340
JM
13889
13890 Rn = inst.operands[0].reg;
13891 Rm = inst.operands[0].imm;
c921be7d 13892
5c8ed6a4
JW
13893 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
13894 constraint (Rn == REG_SP, BAD_SP);
fdfde340
JM
13895 reject_bad_reg (Rm);
13896
92e90b6e
PB
13897 constraint (!half && inst.operands[0].shifted,
13898 _("instruction does not allow shifted index"));
fdfde340 13899 inst.instruction |= (Rn << 16) | Rm;
92e90b6e
PB
13900}
13901
74db7efb
NC
13902static void
13903do_t_udf (void)
13904{
13905 if (!inst.operands[0].present)
13906 inst.operands[0].imm = 0;
13907
13908 if ((unsigned int) inst.operands[0].imm > 255 || inst.size_req == 4)
13909 {
13910 constraint (inst.size_req == 2,
13911 _("immediate value out of range"));
13912 inst.instruction = THUMB_OP32 (inst.instruction);
13913 inst.instruction |= (inst.operands[0].imm & 0xf000u) << 4;
13914 inst.instruction |= (inst.operands[0].imm & 0x0fffu) << 0;
13915 }
13916 else
13917 {
13918 inst.instruction = THUMB_OP16 (inst.instruction);
13919 inst.instruction |= inst.operands[0].imm;
13920 }
13921
5ee91343 13922 set_pred_insn_type (NEUTRAL_IT_INSN);
74db7efb
NC
13923}
13924
13925
c19d1205
ZW
13926static void
13927do_t_usat (void)
13928{
3a21c15a 13929 do_t_ssat_usat (0);
b99bd4ef
NC
13930}
13931
13932static void
c19d1205 13933do_t_usat16 (void)
b99bd4ef 13934{
fdfde340
JM
13935 unsigned Rd, Rn;
13936
13937 Rd = inst.operands[0].reg;
13938 Rn = inst.operands[2].reg;
13939
13940 reject_bad_reg (Rd);
13941 reject_bad_reg (Rn);
13942
13943 inst.instruction |= Rd << 8;
c19d1205 13944 inst.instruction |= inst.operands[1].imm;
fdfde340 13945 inst.instruction |= Rn << 16;
b99bd4ef 13946}
c19d1205 13947
e12437dc
AV
13948/* Checking the range of the branch offset (VAL) with NBITS bits
13949 and IS_SIGNED signedness. Also checks the LSB to be 0. */
13950static int
13951v8_1_branch_value_check (int val, int nbits, int is_signed)
13952{
13953 gas_assert (nbits > 0 && nbits <= 32);
13954 if (is_signed)
13955 {
13956 int cmp = (1 << (nbits - 1));
13957 if ((val < -cmp) || (val >= cmp) || (val & 0x01))
13958 return FAIL;
13959 }
13960 else
13961 {
13962 if ((val <= 0) || (val >= (1 << nbits)) || (val & 0x1))
13963 return FAIL;
13964 }
13965 return SUCCESS;
13966}
13967
4389b29a
AV
13968/* For branches in Armv8.1-M Mainline. */
13969static void
13970do_t_branch_future (void)
13971{
13972 unsigned long insn = inst.instruction;
13973
13974 inst.instruction = THUMB_OP32 (inst.instruction);
13975 if (inst.operands[0].hasreloc == 0)
13976 {
13977 if (v8_1_branch_value_check (inst.operands[0].imm, 5, FALSE) == FAIL)
13978 as_bad (BAD_BRANCH_OFF);
13979
13980 inst.instruction |= ((inst.operands[0].imm & 0x1f) >> 1) << 23;
13981 }
13982 else
13983 {
13984 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH5;
13985 inst.relocs[0].pc_rel = 1;
13986 }
13987
13988 switch (insn)
13989 {
13990 case T_MNEM_bf:
13991 if (inst.operands[1].hasreloc == 0)
13992 {
13993 int val = inst.operands[1].imm;
13994 if (v8_1_branch_value_check (inst.operands[1].imm, 17, TRUE) == FAIL)
13995 as_bad (BAD_BRANCH_OFF);
13996
13997 int immA = (val & 0x0001f000) >> 12;
13998 int immB = (val & 0x00000ffc) >> 2;
13999 int immC = (val & 0x00000002) >> 1;
14000 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14001 }
14002 else
14003 {
14004 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF17;
14005 inst.relocs[1].pc_rel = 1;
14006 }
14007 break;
14008
65d1bc05
AV
14009 case T_MNEM_bfl:
14010 if (inst.operands[1].hasreloc == 0)
14011 {
14012 int val = inst.operands[1].imm;
14013 if (v8_1_branch_value_check (inst.operands[1].imm, 19, TRUE) == FAIL)
14014 as_bad (BAD_BRANCH_OFF);
14015
14016 int immA = (val & 0x0007f000) >> 12;
14017 int immB = (val & 0x00000ffc) >> 2;
14018 int immC = (val & 0x00000002) >> 1;
14019 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14020 }
14021 else
14022 {
14023 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF19;
14024 inst.relocs[1].pc_rel = 1;
14025 }
14026 break;
14027
f6b2b12d
AV
14028 case T_MNEM_bfcsel:
14029 /* Operand 1. */
14030 if (inst.operands[1].hasreloc == 0)
14031 {
14032 int val = inst.operands[1].imm;
14033 int immA = (val & 0x00001000) >> 12;
14034 int immB = (val & 0x00000ffc) >> 2;
14035 int immC = (val & 0x00000002) >> 1;
14036 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14037 }
14038 else
14039 {
14040 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF13;
14041 inst.relocs[1].pc_rel = 1;
14042 }
14043
14044 /* Operand 2. */
14045 if (inst.operands[2].hasreloc == 0)
14046 {
14047 constraint ((inst.operands[0].hasreloc != 0), BAD_ARGS);
14048 int val2 = inst.operands[2].imm;
14049 int val0 = inst.operands[0].imm & 0x1f;
14050 int diff = val2 - val0;
14051 if (diff == 4)
14052 inst.instruction |= 1 << 17; /* T bit. */
14053 else if (diff != 2)
14054 as_bad (_("out of range label-relative fixup value"));
14055 }
14056 else
14057 {
14058 constraint ((inst.operands[0].hasreloc == 0), BAD_ARGS);
14059 inst.relocs[2].type = BFD_RELOC_THUMB_PCREL_BFCSEL;
14060 inst.relocs[2].pc_rel = 1;
14061 }
14062
14063 /* Operand 3. */
14064 constraint (inst.cond != COND_ALWAYS, BAD_COND);
14065 inst.instruction |= (inst.operands[3].imm & 0xf) << 18;
14066 break;
14067
f1c7f421
AV
14068 case T_MNEM_bfx:
14069 case T_MNEM_bflx:
14070 inst.instruction |= inst.operands[1].reg << 16;
14071 break;
14072
4389b29a
AV
14073 default: abort ();
14074 }
14075}
14076
60f993ce
AV
14077/* Helper function for do_t_loloop to handle relocations. */
14078static void
14079v8_1_loop_reloc (int is_le)
14080{
14081 if (inst.relocs[0].exp.X_op == O_constant)
14082 {
14083 int value = inst.relocs[0].exp.X_add_number;
14084 value = (is_le) ? -value : value;
14085
14086 if (v8_1_branch_value_check (value, 12, FALSE) == FAIL)
14087 as_bad (BAD_BRANCH_OFF);
14088
14089 int imml, immh;
14090
14091 immh = (value & 0x00000ffc) >> 2;
14092 imml = (value & 0x00000002) >> 1;
14093
14094 inst.instruction |= (imml << 11) | (immh << 1);
14095 }
14096 else
14097 {
14098 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_LOOP12;
14099 inst.relocs[0].pc_rel = 1;
14100 }
14101}
14102
14103/* To handle the Scalar Low Overhead Loop instructions
14104 in Armv8.1-M Mainline. */
14105static void
14106do_t_loloop (void)
14107{
14108 unsigned long insn = inst.instruction;
14109
5ee91343 14110 set_pred_insn_type (OUTSIDE_PRED_INSN);
60f993ce
AV
14111 inst.instruction = THUMB_OP32 (inst.instruction);
14112
14113 switch (insn)
14114 {
14115 case T_MNEM_le:
14116 /* le <label>. */
14117 if (!inst.operands[0].present)
14118 inst.instruction |= 1 << 21;
14119
14120 v8_1_loop_reloc (TRUE);
14121 break;
14122
14123 case T_MNEM_wls:
14124 v8_1_loop_reloc (FALSE);
14125 /* Fall through. */
14126 case T_MNEM_dls:
14127 constraint (inst.operands[1].isreg != 1, BAD_ARGS);
14128 inst.instruction |= (inst.operands[1].reg << 16);
14129 break;
14130
14131 default: abort();
14132 }
14133}
14134
a302e574
AV
14135/* MVE instruction encoder helpers. */
14136#define M_MNEM_vabav 0xee800f01
14137#define M_MNEM_vmladav 0xeef00e00
14138#define M_MNEM_vmladava 0xeef00e20
14139#define M_MNEM_vmladavx 0xeef01e00
14140#define M_MNEM_vmladavax 0xeef01e20
14141#define M_MNEM_vmlsdav 0xeef00e01
14142#define M_MNEM_vmlsdava 0xeef00e21
14143#define M_MNEM_vmlsdavx 0xeef01e01
14144#define M_MNEM_vmlsdavax 0xeef01e21
886e1c73
AV
14145#define M_MNEM_vmullt 0xee011e00
14146#define M_MNEM_vmullb 0xee010e00
35c228db
AV
14147#define M_MNEM_vst20 0xfc801e00
14148#define M_MNEM_vst21 0xfc801e20
14149#define M_MNEM_vst40 0xfc801e01
14150#define M_MNEM_vst41 0xfc801e21
14151#define M_MNEM_vst42 0xfc801e41
14152#define M_MNEM_vst43 0xfc801e61
14153#define M_MNEM_vld20 0xfc901e00
14154#define M_MNEM_vld21 0xfc901e20
14155#define M_MNEM_vld40 0xfc901e01
14156#define M_MNEM_vld41 0xfc901e21
14157#define M_MNEM_vld42 0xfc901e41
14158#define M_MNEM_vld43 0xfc901e61
f5f10c66
AV
14159#define M_MNEM_vstrb 0xec000e00
14160#define M_MNEM_vstrh 0xec000e10
14161#define M_MNEM_vstrw 0xec000e40
14162#define M_MNEM_vstrd 0xec000e50
14163#define M_MNEM_vldrb 0xec100e00
14164#define M_MNEM_vldrh 0xec100e10
14165#define M_MNEM_vldrw 0xec100e40
14166#define M_MNEM_vldrd 0xec100e50
57785aa2
AV
14167#define M_MNEM_vmovlt 0xeea01f40
14168#define M_MNEM_vmovlb 0xeea00f40
14169#define M_MNEM_vmovnt 0xfe311e81
14170#define M_MNEM_vmovnb 0xfe310e81
c2dafc2a
AV
14171#define M_MNEM_vadc 0xee300f00
14172#define M_MNEM_vadci 0xee301f00
14173#define M_MNEM_vbrsr 0xfe011e60
26c1e780
AV
14174#define M_MNEM_vaddlv 0xee890f00
14175#define M_MNEM_vaddlva 0xee890f20
14176#define M_MNEM_vaddv 0xeef10f00
14177#define M_MNEM_vaddva 0xeef10f20
b409bdb6
AV
14178#define M_MNEM_vddup 0xee011f6e
14179#define M_MNEM_vdwdup 0xee011f60
14180#define M_MNEM_vidup 0xee010f6e
14181#define M_MNEM_viwdup 0xee010f60
13ccd4c0
AV
14182#define M_MNEM_vmaxv 0xeee20f00
14183#define M_MNEM_vmaxav 0xeee00f00
14184#define M_MNEM_vminv 0xeee20f80
14185#define M_MNEM_vminav 0xeee00f80
93925576
AV
14186#define M_MNEM_vmlaldav 0xee800e00
14187#define M_MNEM_vmlaldava 0xee800e20
14188#define M_MNEM_vmlaldavx 0xee801e00
14189#define M_MNEM_vmlaldavax 0xee801e20
14190#define M_MNEM_vmlsldav 0xee800e01
14191#define M_MNEM_vmlsldava 0xee800e21
14192#define M_MNEM_vmlsldavx 0xee801e01
14193#define M_MNEM_vmlsldavax 0xee801e21
14194#define M_MNEM_vrmlaldavhx 0xee801f00
14195#define M_MNEM_vrmlaldavhax 0xee801f20
14196#define M_MNEM_vrmlsldavh 0xfe800e01
14197#define M_MNEM_vrmlsldavha 0xfe800e21
14198#define M_MNEM_vrmlsldavhx 0xfe801e01
14199#define M_MNEM_vrmlsldavhax 0xfe801e21
a302e574 14200
5287ad62 14201/* Neon instruction encoder helpers. */
5f4273c7 14202
5287ad62 14203/* Encodings for the different types for various Neon opcodes. */
b99bd4ef 14204
5287ad62
JB
14205/* An "invalid" code for the following tables. */
14206#define N_INV -1u
14207
14208struct neon_tab_entry
b99bd4ef 14209{
5287ad62
JB
14210 unsigned integer;
14211 unsigned float_or_poly;
14212 unsigned scalar_or_imm;
14213};
5f4273c7 14214
5287ad62
JB
14215/* Map overloaded Neon opcodes to their respective encodings. */
14216#define NEON_ENC_TAB \
14217 X(vabd, 0x0000700, 0x1200d00, N_INV), \
5ee91343 14218 X(vabdl, 0x0800700, N_INV, N_INV), \
5287ad62
JB
14219 X(vmax, 0x0000600, 0x0000f00, N_INV), \
14220 X(vmin, 0x0000610, 0x0200f00, N_INV), \
14221 X(vpadd, 0x0000b10, 0x1000d00, N_INV), \
14222 X(vpmax, 0x0000a00, 0x1000f00, N_INV), \
14223 X(vpmin, 0x0000a10, 0x1200f00, N_INV), \
14224 X(vadd, 0x0000800, 0x0000d00, N_INV), \
5ee91343 14225 X(vaddl, 0x0800000, N_INV, N_INV), \
5287ad62 14226 X(vsub, 0x1000800, 0x0200d00, N_INV), \
5ee91343 14227 X(vsubl, 0x0800200, N_INV, N_INV), \
5287ad62
JB
14228 X(vceq, 0x1000810, 0x0000e00, 0x1b10100), \
14229 X(vcge, 0x0000310, 0x1000e00, 0x1b10080), \
14230 X(vcgt, 0x0000300, 0x1200e00, 0x1b10000), \
14231 /* Register variants of the following two instructions are encoded as
e07e6e58 14232 vcge / vcgt with the operands reversed. */ \
92559b5b
PB
14233 X(vclt, 0x0000300, 0x1200e00, 0x1b10200), \
14234 X(vcle, 0x0000310, 0x1000e00, 0x1b10180), \
62f3b8c8
PB
14235 X(vfma, N_INV, 0x0000c10, N_INV), \
14236 X(vfms, N_INV, 0x0200c10, N_INV), \
5287ad62
JB
14237 X(vmla, 0x0000900, 0x0000d10, 0x0800040), \
14238 X(vmls, 0x1000900, 0x0200d10, 0x0800440), \
14239 X(vmul, 0x0000910, 0x1000d10, 0x0800840), \
14240 X(vmull, 0x0800c00, 0x0800e00, 0x0800a40), /* polynomial not float. */ \
14241 X(vmlal, 0x0800800, N_INV, 0x0800240), \
14242 X(vmlsl, 0x0800a00, N_INV, 0x0800640), \
14243 X(vqdmlal, 0x0800900, N_INV, 0x0800340), \
14244 X(vqdmlsl, 0x0800b00, N_INV, 0x0800740), \
14245 X(vqdmull, 0x0800d00, N_INV, 0x0800b40), \
14246 X(vqdmulh, 0x0000b00, N_INV, 0x0800c40), \
14247 X(vqrdmulh, 0x1000b00, N_INV, 0x0800d40), \
d6b4b13e
MW
14248 X(vqrdmlah, 0x3000b10, N_INV, 0x0800e40), \
14249 X(vqrdmlsh, 0x3000c10, N_INV, 0x0800f40), \
5287ad62
JB
14250 X(vshl, 0x0000400, N_INV, 0x0800510), \
14251 X(vqshl, 0x0000410, N_INV, 0x0800710), \
14252 X(vand, 0x0000110, N_INV, 0x0800030), \
14253 X(vbic, 0x0100110, N_INV, 0x0800030), \
14254 X(veor, 0x1000110, N_INV, N_INV), \
14255 X(vorn, 0x0300110, N_INV, 0x0800010), \
14256 X(vorr, 0x0200110, N_INV, 0x0800010), \
14257 X(vmvn, 0x1b00580, N_INV, 0x0800030), \
14258 X(vshll, 0x1b20300, N_INV, 0x0800a10), /* max shift, immediate. */ \
14259 X(vcvt, 0x1b30600, N_INV, 0x0800e10), /* integer, fixed-point. */ \
14260 X(vdup, 0xe800b10, N_INV, 0x1b00c00), /* arm, scalar. */ \
14261 X(vld1, 0x0200000, 0x0a00000, 0x0a00c00), /* interlv, lane, dup. */ \
14262 X(vst1, 0x0000000, 0x0800000, N_INV), \
14263 X(vld2, 0x0200100, 0x0a00100, 0x0a00d00), \
14264 X(vst2, 0x0000100, 0x0800100, N_INV), \
14265 X(vld3, 0x0200200, 0x0a00200, 0x0a00e00), \
14266 X(vst3, 0x0000200, 0x0800200, N_INV), \
14267 X(vld4, 0x0200300, 0x0a00300, 0x0a00f00), \
14268 X(vst4, 0x0000300, 0x0800300, N_INV), \
14269 X(vmovn, 0x1b20200, N_INV, N_INV), \
14270 X(vtrn, 0x1b20080, N_INV, N_INV), \
14271 X(vqmovn, 0x1b20200, N_INV, N_INV), \
037e8744
JB
14272 X(vqmovun, 0x1b20240, N_INV, N_INV), \
14273 X(vnmul, 0xe200a40, 0xe200b40, N_INV), \
e6655fda
PB
14274 X(vnmla, 0xe100a40, 0xe100b40, N_INV), \
14275 X(vnmls, 0xe100a00, 0xe100b00, N_INV), \
62f3b8c8
PB
14276 X(vfnma, 0xe900a40, 0xe900b40, N_INV), \
14277 X(vfnms, 0xe900a00, 0xe900b00, N_INV), \
037e8744
JB
14278 X(vcmp, 0xeb40a40, 0xeb40b40, N_INV), \
14279 X(vcmpz, 0xeb50a40, 0xeb50b40, N_INV), \
14280 X(vcmpe, 0xeb40ac0, 0xeb40bc0, N_INV), \
33399f07
MGD
14281 X(vcmpez, 0xeb50ac0, 0xeb50bc0, N_INV), \
14282 X(vseleq, 0xe000a00, N_INV, N_INV), \
14283 X(vselvs, 0xe100a00, N_INV, N_INV), \
14284 X(vselge, 0xe200a00, N_INV, N_INV), \
73924fbc
MGD
14285 X(vselgt, 0xe300a00, N_INV, N_INV), \
14286 X(vmaxnm, 0xe800a00, 0x3000f10, N_INV), \
7e8e6784 14287 X(vminnm, 0xe800a40, 0x3200f10, N_INV), \
30bdf752
MGD
14288 X(vcvta, 0xebc0a40, 0x3bb0000, N_INV), \
14289 X(vrintr, 0xeb60a40, 0x3ba0400, N_INV), \
91ff7894 14290 X(vrinta, 0xeb80a40, 0x3ba0400, N_INV), \
48adcd8e 14291 X(aes, 0x3b00300, N_INV, N_INV), \
3c9017d2
MGD
14292 X(sha3op, 0x2000c00, N_INV, N_INV), \
14293 X(sha1h, 0x3b902c0, N_INV, N_INV), \
14294 X(sha2op, 0x3ba0380, N_INV, N_INV)
5287ad62
JB
14295
14296enum neon_opc
14297{
14298#define X(OPC,I,F,S) N_MNEM_##OPC
14299NEON_ENC_TAB
14300#undef X
14301};
b99bd4ef 14302
5287ad62
JB
14303static const struct neon_tab_entry neon_enc_tab[] =
14304{
14305#define X(OPC,I,F,S) { (I), (F), (S) }
14306NEON_ENC_TAB
14307#undef X
14308};
b99bd4ef 14309
88714cb8
DG
14310/* Do not use these macros; instead, use NEON_ENCODE defined below. */
14311#define NEON_ENC_INTEGER_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14312#define NEON_ENC_ARMREG_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14313#define NEON_ENC_POLY_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14314#define NEON_ENC_FLOAT_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14315#define NEON_ENC_SCALAR_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14316#define NEON_ENC_IMMED_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14317#define NEON_ENC_INTERLV_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14318#define NEON_ENC_LANE_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14319#define NEON_ENC_DUP_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14320#define NEON_ENC_SINGLE_(X) \
037e8744 14321 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf0000000))
88714cb8 14322#define NEON_ENC_DOUBLE_(X) \
037e8744 14323 ((neon_enc_tab[(X) & 0x0fffffff].float_or_poly) | ((X) & 0xf0000000))
33399f07
MGD
14324#define NEON_ENC_FPV8_(X) \
14325 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf000000))
5287ad62 14326
88714cb8
DG
14327#define NEON_ENCODE(type, inst) \
14328 do \
14329 { \
14330 inst.instruction = NEON_ENC_##type##_ (inst.instruction); \
14331 inst.is_neon = 1; \
14332 } \
14333 while (0)
14334
14335#define check_neon_suffixes \
14336 do \
14337 { \
14338 if (!inst.error && inst.vectype.elems > 0 && !inst.is_neon) \
14339 { \
14340 as_bad (_("invalid neon suffix for non neon instruction")); \
14341 return; \
14342 } \
14343 } \
14344 while (0)
14345
037e8744
JB
14346/* Define shapes for instruction operands. The following mnemonic characters
14347 are used in this table:
5287ad62 14348
037e8744 14349 F - VFP S<n> register
5287ad62
JB
14350 D - Neon D<n> register
14351 Q - Neon Q<n> register
14352 I - Immediate
14353 S - Scalar
14354 R - ARM register
14355 L - D<n> register list
5f4273c7 14356
037e8744
JB
14357 This table is used to generate various data:
14358 - enumerations of the form NS_DDR to be used as arguments to
14359 neon_select_shape.
14360 - a table classifying shapes into single, double, quad, mixed.
5f4273c7 14361 - a table used to drive neon_select_shape. */
b99bd4ef 14362
037e8744 14363#define NEON_SHAPE_DEF \
93925576 14364 X(4, (R, R, Q, Q), QUAD), \
b409bdb6 14365 X(4, (Q, R, R, I), QUAD), \
57785aa2
AV
14366 X(4, (R, R, S, S), QUAD), \
14367 X(4, (S, S, R, R), QUAD), \
b409bdb6 14368 X(3, (Q, R, I), QUAD), \
1b883319
AV
14369 X(3, (I, Q, Q), QUAD), \
14370 X(3, (I, Q, R), QUAD), \
a302e574 14371 X(3, (R, Q, Q), QUAD), \
037e8744
JB
14372 X(3, (D, D, D), DOUBLE), \
14373 X(3, (Q, Q, Q), QUAD), \
14374 X(3, (D, D, I), DOUBLE), \
14375 X(3, (Q, Q, I), QUAD), \
14376 X(3, (D, D, S), DOUBLE), \
14377 X(3, (Q, Q, S), QUAD), \
5ee91343 14378 X(3, (Q, Q, R), QUAD), \
26c1e780
AV
14379 X(3, (R, R, Q), QUAD), \
14380 X(2, (R, Q), QUAD), \
037e8744
JB
14381 X(2, (D, D), DOUBLE), \
14382 X(2, (Q, Q), QUAD), \
14383 X(2, (D, S), DOUBLE), \
14384 X(2, (Q, S), QUAD), \
14385 X(2, (D, R), DOUBLE), \
14386 X(2, (Q, R), QUAD), \
14387 X(2, (D, I), DOUBLE), \
14388 X(2, (Q, I), QUAD), \
14389 X(3, (D, L, D), DOUBLE), \
14390 X(2, (D, Q), MIXED), \
14391 X(2, (Q, D), MIXED), \
14392 X(3, (D, Q, I), MIXED), \
14393 X(3, (Q, D, I), MIXED), \
14394 X(3, (Q, D, D), MIXED), \
14395 X(3, (D, Q, Q), MIXED), \
14396 X(3, (Q, Q, D), MIXED), \
14397 X(3, (Q, D, S), MIXED), \
14398 X(3, (D, Q, S), MIXED), \
14399 X(4, (D, D, D, I), DOUBLE), \
14400 X(4, (Q, Q, Q, I), QUAD), \
c28eeff2
SN
14401 X(4, (D, D, S, I), DOUBLE), \
14402 X(4, (Q, Q, S, I), QUAD), \
037e8744
JB
14403 X(2, (F, F), SINGLE), \
14404 X(3, (F, F, F), SINGLE), \
14405 X(2, (F, I), SINGLE), \
14406 X(2, (F, D), MIXED), \
14407 X(2, (D, F), MIXED), \
14408 X(3, (F, F, I), MIXED), \
14409 X(4, (R, R, F, F), SINGLE), \
14410 X(4, (F, F, R, R), SINGLE), \
14411 X(3, (D, R, R), DOUBLE), \
14412 X(3, (R, R, D), DOUBLE), \
14413 X(2, (S, R), SINGLE), \
14414 X(2, (R, S), SINGLE), \
14415 X(2, (F, R), SINGLE), \
d54af2d0
RL
14416 X(2, (R, F), SINGLE), \
14417/* Half float shape supported so far. */\
14418 X (2, (H, D), MIXED), \
14419 X (2, (D, H), MIXED), \
14420 X (2, (H, F), MIXED), \
14421 X (2, (F, H), MIXED), \
14422 X (2, (H, H), HALF), \
14423 X (2, (H, R), HALF), \
14424 X (2, (R, H), HALF), \
14425 X (2, (H, I), HALF), \
14426 X (3, (H, H, H), HALF), \
14427 X (3, (H, F, I), MIXED), \
dec41383
JW
14428 X (3, (F, H, I), MIXED), \
14429 X (3, (D, H, H), MIXED), \
14430 X (3, (D, H, S), MIXED)
037e8744
JB
14431
14432#define S2(A,B) NS_##A##B
14433#define S3(A,B,C) NS_##A##B##C
14434#define S4(A,B,C,D) NS_##A##B##C##D
14435
14436#define X(N, L, C) S##N L
14437
5287ad62
JB
14438enum neon_shape
14439{
037e8744
JB
14440 NEON_SHAPE_DEF,
14441 NS_NULL
5287ad62 14442};
b99bd4ef 14443
037e8744
JB
14444#undef X
14445#undef S2
14446#undef S3
14447#undef S4
14448
14449enum neon_shape_class
14450{
d54af2d0 14451 SC_HALF,
037e8744
JB
14452 SC_SINGLE,
14453 SC_DOUBLE,
14454 SC_QUAD,
14455 SC_MIXED
14456};
14457
14458#define X(N, L, C) SC_##C
14459
14460static enum neon_shape_class neon_shape_class[] =
14461{
14462 NEON_SHAPE_DEF
14463};
14464
14465#undef X
14466
14467enum neon_shape_el
14468{
d54af2d0 14469 SE_H,
037e8744
JB
14470 SE_F,
14471 SE_D,
14472 SE_Q,
14473 SE_I,
14474 SE_S,
14475 SE_R,
14476 SE_L
14477};
14478
14479/* Register widths of above. */
14480static unsigned neon_shape_el_size[] =
14481{
d54af2d0 14482 16,
037e8744
JB
14483 32,
14484 64,
14485 128,
14486 0,
14487 32,
14488 32,
14489 0
14490};
14491
14492struct neon_shape_info
14493{
14494 unsigned els;
14495 enum neon_shape_el el[NEON_MAX_TYPE_ELS];
14496};
14497
14498#define S2(A,B) { SE_##A, SE_##B }
14499#define S3(A,B,C) { SE_##A, SE_##B, SE_##C }
14500#define S4(A,B,C,D) { SE_##A, SE_##B, SE_##C, SE_##D }
14501
14502#define X(N, L, C) { N, S##N L }
14503
14504static struct neon_shape_info neon_shape_tab[] =
14505{
14506 NEON_SHAPE_DEF
14507};
14508
14509#undef X
14510#undef S2
14511#undef S3
14512#undef S4
14513
5287ad62
JB
14514/* Bit masks used in type checking given instructions.
14515 'N_EQK' means the type must be the same as (or based on in some way) the key
14516 type, which itself is marked with the 'N_KEY' bit. If the 'N_EQK' bit is
14517 set, various other bits can be set as well in order to modify the meaning of
14518 the type constraint. */
14519
14520enum neon_type_mask
14521{
8e79c3df
CM
14522 N_S8 = 0x0000001,
14523 N_S16 = 0x0000002,
14524 N_S32 = 0x0000004,
14525 N_S64 = 0x0000008,
14526 N_U8 = 0x0000010,
14527 N_U16 = 0x0000020,
14528 N_U32 = 0x0000040,
14529 N_U64 = 0x0000080,
14530 N_I8 = 0x0000100,
14531 N_I16 = 0x0000200,
14532 N_I32 = 0x0000400,
14533 N_I64 = 0x0000800,
14534 N_8 = 0x0001000,
14535 N_16 = 0x0002000,
14536 N_32 = 0x0004000,
14537 N_64 = 0x0008000,
14538 N_P8 = 0x0010000,
14539 N_P16 = 0x0020000,
14540 N_F16 = 0x0040000,
14541 N_F32 = 0x0080000,
14542 N_F64 = 0x0100000,
4f51b4bd 14543 N_P64 = 0x0200000,
c921be7d
NC
14544 N_KEY = 0x1000000, /* Key element (main type specifier). */
14545 N_EQK = 0x2000000, /* Given operand has the same type & size as the key. */
8e79c3df 14546 N_VFP = 0x4000000, /* VFP mode: operand size must match register width. */
91ff7894 14547 N_UNT = 0x8000000, /* Must be explicitly untyped. */
c921be7d
NC
14548 N_DBL = 0x0000001, /* If N_EQK, this operand is twice the size. */
14549 N_HLF = 0x0000002, /* If N_EQK, this operand is half the size. */
14550 N_SGN = 0x0000004, /* If N_EQK, this operand is forced to be signed. */
14551 N_UNS = 0x0000008, /* If N_EQK, this operand is forced to be unsigned. */
14552 N_INT = 0x0000010, /* If N_EQK, this operand is forced to be integer. */
14553 N_FLT = 0x0000020, /* If N_EQK, this operand is forced to be float. */
14554 N_SIZ = 0x0000040, /* If N_EQK, this operand is forced to be size-only. */
5287ad62 14555 N_UTYP = 0,
4f51b4bd 14556 N_MAX_NONSPECIAL = N_P64
5287ad62
JB
14557};
14558
dcbf9037
JB
14559#define N_ALLMODS (N_DBL | N_HLF | N_SGN | N_UNS | N_INT | N_FLT | N_SIZ)
14560
5287ad62
JB
14561#define N_SU_ALL (N_S8 | N_S16 | N_S32 | N_S64 | N_U8 | N_U16 | N_U32 | N_U64)
14562#define N_SU_32 (N_S8 | N_S16 | N_S32 | N_U8 | N_U16 | N_U32)
14563#define N_SU_16_64 (N_S16 | N_S32 | N_S64 | N_U16 | N_U32 | N_U64)
cc933301
JW
14564#define N_S_32 (N_S8 | N_S16 | N_S32)
14565#define N_F_16_32 (N_F16 | N_F32)
14566#define N_SUF_32 (N_SU_32 | N_F_16_32)
5287ad62 14567#define N_I_ALL (N_I8 | N_I16 | N_I32 | N_I64)
cc933301 14568#define N_IF_32 (N_I8 | N_I16 | N_I32 | N_F16 | N_F32)
d54af2d0 14569#define N_F_ALL (N_F16 | N_F32 | N_F64)
5ee91343
AV
14570#define N_I_MVE (N_I8 | N_I16 | N_I32)
14571#define N_F_MVE (N_F16 | N_F32)
14572#define N_SU_MVE (N_S8 | N_S16 | N_S32 | N_U8 | N_U16 | N_U32)
5287ad62
JB
14573
14574/* Pass this as the first type argument to neon_check_type to ignore types
14575 altogether. */
14576#define N_IGNORE_TYPE (N_KEY | N_EQK)
14577
037e8744
JB
14578/* Select a "shape" for the current instruction (describing register types or
14579 sizes) from a list of alternatives. Return NS_NULL if the current instruction
14580 doesn't fit. For non-polymorphic shapes, checking is usually done as a
14581 function of operand parsing, so this function doesn't need to be called.
14582 Shapes should be listed in order of decreasing length. */
5287ad62
JB
14583
14584static enum neon_shape
037e8744 14585neon_select_shape (enum neon_shape shape, ...)
5287ad62 14586{
037e8744
JB
14587 va_list ap;
14588 enum neon_shape first_shape = shape;
5287ad62
JB
14589
14590 /* Fix missing optional operands. FIXME: we don't know at this point how
14591 many arguments we should have, so this makes the assumption that we have
14592 > 1. This is true of all current Neon opcodes, I think, but may not be
14593 true in the future. */
14594 if (!inst.operands[1].present)
14595 inst.operands[1] = inst.operands[0];
14596
037e8744 14597 va_start (ap, shape);
5f4273c7 14598
21d799b5 14599 for (; shape != NS_NULL; shape = (enum neon_shape) va_arg (ap, int))
037e8744
JB
14600 {
14601 unsigned j;
14602 int matches = 1;
14603
14604 for (j = 0; j < neon_shape_tab[shape].els; j++)
477330fc
RM
14605 {
14606 if (!inst.operands[j].present)
14607 {
14608 matches = 0;
14609 break;
14610 }
14611
14612 switch (neon_shape_tab[shape].el[j])
14613 {
d54af2d0
RL
14614 /* If a .f16, .16, .u16, .s16 type specifier is given over
14615 a VFP single precision register operand, it's essentially
14616 means only half of the register is used.
14617
14618 If the type specifier is given after the mnemonics, the
14619 information is stored in inst.vectype. If the type specifier
14620 is given after register operand, the information is stored
14621 in inst.operands[].vectype.
14622
14623 When there is only one type specifier, and all the register
14624 operands are the same type of hardware register, the type
14625 specifier applies to all register operands.
14626
14627 If no type specifier is given, the shape is inferred from
14628 operand information.
14629
14630 for example:
14631 vadd.f16 s0, s1, s2: NS_HHH
14632 vabs.f16 s0, s1: NS_HH
14633 vmov.f16 s0, r1: NS_HR
14634 vmov.f16 r0, s1: NS_RH
14635 vcvt.f16 r0, s1: NS_RH
14636 vcvt.f16.s32 s2, s2, #29: NS_HFI
14637 vcvt.f16.s32 s2, s2: NS_HF
14638 */
14639 case SE_H:
14640 if (!(inst.operands[j].isreg
14641 && inst.operands[j].isvec
14642 && inst.operands[j].issingle
14643 && !inst.operands[j].isquad
14644 && ((inst.vectype.elems == 1
14645 && inst.vectype.el[0].size == 16)
14646 || (inst.vectype.elems > 1
14647 && inst.vectype.el[j].size == 16)
14648 || (inst.vectype.elems == 0
14649 && inst.operands[j].vectype.type != NT_invtype
14650 && inst.operands[j].vectype.size == 16))))
14651 matches = 0;
14652 break;
14653
477330fc
RM
14654 case SE_F:
14655 if (!(inst.operands[j].isreg
14656 && inst.operands[j].isvec
14657 && inst.operands[j].issingle
d54af2d0
RL
14658 && !inst.operands[j].isquad
14659 && ((inst.vectype.elems == 1 && inst.vectype.el[0].size == 32)
14660 || (inst.vectype.elems > 1 && inst.vectype.el[j].size == 32)
14661 || (inst.vectype.elems == 0
14662 && (inst.operands[j].vectype.size == 32
14663 || inst.operands[j].vectype.type == NT_invtype)))))
477330fc
RM
14664 matches = 0;
14665 break;
14666
14667 case SE_D:
14668 if (!(inst.operands[j].isreg
14669 && inst.operands[j].isvec
14670 && !inst.operands[j].isquad
14671 && !inst.operands[j].issingle))
14672 matches = 0;
14673 break;
14674
14675 case SE_R:
14676 if (!(inst.operands[j].isreg
14677 && !inst.operands[j].isvec))
14678 matches = 0;
14679 break;
14680
14681 case SE_Q:
14682 if (!(inst.operands[j].isreg
14683 && inst.operands[j].isvec
14684 && inst.operands[j].isquad
14685 && !inst.operands[j].issingle))
14686 matches = 0;
14687 break;
14688
14689 case SE_I:
14690 if (!(!inst.operands[j].isreg
14691 && !inst.operands[j].isscalar))
14692 matches = 0;
14693 break;
14694
14695 case SE_S:
14696 if (!(!inst.operands[j].isreg
14697 && inst.operands[j].isscalar))
14698 matches = 0;
14699 break;
14700
14701 case SE_L:
14702 break;
14703 }
3fde54a2
JZ
14704 if (!matches)
14705 break;
477330fc 14706 }
ad6cec43
MGD
14707 if (matches && (j >= ARM_IT_MAX_OPERANDS || !inst.operands[j].present))
14708 /* We've matched all the entries in the shape table, and we don't
14709 have any left over operands which have not been matched. */
477330fc 14710 break;
037e8744 14711 }
5f4273c7 14712
037e8744 14713 va_end (ap);
5287ad62 14714
037e8744
JB
14715 if (shape == NS_NULL && first_shape != NS_NULL)
14716 first_error (_("invalid instruction shape"));
5287ad62 14717
037e8744
JB
14718 return shape;
14719}
5287ad62 14720
037e8744
JB
14721/* True if SHAPE is predominantly a quadword operation (most of the time, this
14722 means the Q bit should be set). */
14723
14724static int
14725neon_quad (enum neon_shape shape)
14726{
14727 return neon_shape_class[shape] == SC_QUAD;
5287ad62 14728}
037e8744 14729
5287ad62
JB
14730static void
14731neon_modify_type_size (unsigned typebits, enum neon_el_type *g_type,
477330fc 14732 unsigned *g_size)
5287ad62
JB
14733{
14734 /* Allow modification to be made to types which are constrained to be
14735 based on the key element, based on bits set alongside N_EQK. */
14736 if ((typebits & N_EQK) != 0)
14737 {
14738 if ((typebits & N_HLF) != 0)
14739 *g_size /= 2;
14740 else if ((typebits & N_DBL) != 0)
14741 *g_size *= 2;
14742 if ((typebits & N_SGN) != 0)
14743 *g_type = NT_signed;
14744 else if ((typebits & N_UNS) != 0)
477330fc 14745 *g_type = NT_unsigned;
5287ad62 14746 else if ((typebits & N_INT) != 0)
477330fc 14747 *g_type = NT_integer;
5287ad62 14748 else if ((typebits & N_FLT) != 0)
477330fc 14749 *g_type = NT_float;
dcbf9037 14750 else if ((typebits & N_SIZ) != 0)
477330fc 14751 *g_type = NT_untyped;
5287ad62
JB
14752 }
14753}
5f4273c7 14754
5287ad62
JB
14755/* Return operand OPNO promoted by bits set in THISARG. KEY should be the "key"
14756 operand type, i.e. the single type specified in a Neon instruction when it
14757 is the only one given. */
14758
14759static struct neon_type_el
14760neon_type_promote (struct neon_type_el *key, unsigned thisarg)
14761{
14762 struct neon_type_el dest = *key;
5f4273c7 14763
9c2799c2 14764 gas_assert ((thisarg & N_EQK) != 0);
5f4273c7 14765
5287ad62
JB
14766 neon_modify_type_size (thisarg, &dest.type, &dest.size);
14767
14768 return dest;
14769}
14770
14771/* Convert Neon type and size into compact bitmask representation. */
14772
14773static enum neon_type_mask
14774type_chk_of_el_type (enum neon_el_type type, unsigned size)
14775{
14776 switch (type)
14777 {
14778 case NT_untyped:
14779 switch (size)
477330fc
RM
14780 {
14781 case 8: return N_8;
14782 case 16: return N_16;
14783 case 32: return N_32;
14784 case 64: return N_64;
14785 default: ;
14786 }
5287ad62
JB
14787 break;
14788
14789 case NT_integer:
14790 switch (size)
477330fc
RM
14791 {
14792 case 8: return N_I8;
14793 case 16: return N_I16;
14794 case 32: return N_I32;
14795 case 64: return N_I64;
14796 default: ;
14797 }
5287ad62
JB
14798 break;
14799
14800 case NT_float:
037e8744 14801 switch (size)
477330fc 14802 {
8e79c3df 14803 case 16: return N_F16;
477330fc
RM
14804 case 32: return N_F32;
14805 case 64: return N_F64;
14806 default: ;
14807 }
5287ad62
JB
14808 break;
14809
14810 case NT_poly:
14811 switch (size)
477330fc
RM
14812 {
14813 case 8: return N_P8;
14814 case 16: return N_P16;
4f51b4bd 14815 case 64: return N_P64;
477330fc
RM
14816 default: ;
14817 }
5287ad62
JB
14818 break;
14819
14820 case NT_signed:
14821 switch (size)
477330fc
RM
14822 {
14823 case 8: return N_S8;
14824 case 16: return N_S16;
14825 case 32: return N_S32;
14826 case 64: return N_S64;
14827 default: ;
14828 }
5287ad62
JB
14829 break;
14830
14831 case NT_unsigned:
14832 switch (size)
477330fc
RM
14833 {
14834 case 8: return N_U8;
14835 case 16: return N_U16;
14836 case 32: return N_U32;
14837 case 64: return N_U64;
14838 default: ;
14839 }
5287ad62
JB
14840 break;
14841
14842 default: ;
14843 }
5f4273c7 14844
5287ad62
JB
14845 return N_UTYP;
14846}
14847
14848/* Convert compact Neon bitmask type representation to a type and size. Only
14849 handles the case where a single bit is set in the mask. */
14850
dcbf9037 14851static int
5287ad62 14852el_type_of_type_chk (enum neon_el_type *type, unsigned *size,
477330fc 14853 enum neon_type_mask mask)
5287ad62 14854{
dcbf9037
JB
14855 if ((mask & N_EQK) != 0)
14856 return FAIL;
14857
5287ad62
JB
14858 if ((mask & (N_S8 | N_U8 | N_I8 | N_8 | N_P8)) != 0)
14859 *size = 8;
c70a8987 14860 else if ((mask & (N_S16 | N_U16 | N_I16 | N_16 | N_F16 | N_P16)) != 0)
5287ad62 14861 *size = 16;
dcbf9037 14862 else if ((mask & (N_S32 | N_U32 | N_I32 | N_32 | N_F32)) != 0)
5287ad62 14863 *size = 32;
4f51b4bd 14864 else if ((mask & (N_S64 | N_U64 | N_I64 | N_64 | N_F64 | N_P64)) != 0)
5287ad62 14865 *size = 64;
dcbf9037
JB
14866 else
14867 return FAIL;
14868
5287ad62
JB
14869 if ((mask & (N_S8 | N_S16 | N_S32 | N_S64)) != 0)
14870 *type = NT_signed;
dcbf9037 14871 else if ((mask & (N_U8 | N_U16 | N_U32 | N_U64)) != 0)
5287ad62 14872 *type = NT_unsigned;
dcbf9037 14873 else if ((mask & (N_I8 | N_I16 | N_I32 | N_I64)) != 0)
5287ad62 14874 *type = NT_integer;
dcbf9037 14875 else if ((mask & (N_8 | N_16 | N_32 | N_64)) != 0)
5287ad62 14876 *type = NT_untyped;
4f51b4bd 14877 else if ((mask & (N_P8 | N_P16 | N_P64)) != 0)
5287ad62 14878 *type = NT_poly;
d54af2d0 14879 else if ((mask & (N_F_ALL)) != 0)
5287ad62 14880 *type = NT_float;
dcbf9037
JB
14881 else
14882 return FAIL;
5f4273c7 14883
dcbf9037 14884 return SUCCESS;
5287ad62
JB
14885}
14886
14887/* Modify a bitmask of allowed types. This is only needed for type
14888 relaxation. */
14889
14890static unsigned
14891modify_types_allowed (unsigned allowed, unsigned mods)
14892{
14893 unsigned size;
14894 enum neon_el_type type;
14895 unsigned destmask;
14896 int i;
5f4273c7 14897
5287ad62 14898 destmask = 0;
5f4273c7 14899
5287ad62
JB
14900 for (i = 1; i <= N_MAX_NONSPECIAL; i <<= 1)
14901 {
21d799b5 14902 if (el_type_of_type_chk (&type, &size,
477330fc
RM
14903 (enum neon_type_mask) (allowed & i)) == SUCCESS)
14904 {
14905 neon_modify_type_size (mods, &type, &size);
14906 destmask |= type_chk_of_el_type (type, size);
14907 }
5287ad62 14908 }
5f4273c7 14909
5287ad62
JB
14910 return destmask;
14911}
14912
14913/* Check type and return type classification.
14914 The manual states (paraphrase): If one datatype is given, it indicates the
14915 type given in:
14916 - the second operand, if there is one
14917 - the operand, if there is no second operand
14918 - the result, if there are no operands.
14919 This isn't quite good enough though, so we use a concept of a "key" datatype
14920 which is set on a per-instruction basis, which is the one which matters when
14921 only one data type is written.
14922 Note: this function has side-effects (e.g. filling in missing operands). All
037e8744 14923 Neon instructions should call it before performing bit encoding. */
5287ad62
JB
14924
14925static struct neon_type_el
14926neon_check_type (unsigned els, enum neon_shape ns, ...)
14927{
14928 va_list ap;
14929 unsigned i, pass, key_el = 0;
14930 unsigned types[NEON_MAX_TYPE_ELS];
14931 enum neon_el_type k_type = NT_invtype;
14932 unsigned k_size = -1u;
14933 struct neon_type_el badtype = {NT_invtype, -1};
14934 unsigned key_allowed = 0;
14935
14936 /* Optional registers in Neon instructions are always (not) in operand 1.
14937 Fill in the missing operand here, if it was omitted. */
14938 if (els > 1 && !inst.operands[1].present)
14939 inst.operands[1] = inst.operands[0];
14940
14941 /* Suck up all the varargs. */
14942 va_start (ap, ns);
14943 for (i = 0; i < els; i++)
14944 {
14945 unsigned thisarg = va_arg (ap, unsigned);
14946 if (thisarg == N_IGNORE_TYPE)
477330fc
RM
14947 {
14948 va_end (ap);
14949 return badtype;
14950 }
5287ad62
JB
14951 types[i] = thisarg;
14952 if ((thisarg & N_KEY) != 0)
477330fc 14953 key_el = i;
5287ad62
JB
14954 }
14955 va_end (ap);
14956
dcbf9037
JB
14957 if (inst.vectype.elems > 0)
14958 for (i = 0; i < els; i++)
14959 if (inst.operands[i].vectype.type != NT_invtype)
477330fc
RM
14960 {
14961 first_error (_("types specified in both the mnemonic and operands"));
14962 return badtype;
14963 }
dcbf9037 14964
5287ad62
JB
14965 /* Duplicate inst.vectype elements here as necessary.
14966 FIXME: No idea if this is exactly the same as the ARM assembler,
14967 particularly when an insn takes one register and one non-register
14968 operand. */
14969 if (inst.vectype.elems == 1 && els > 1)
14970 {
14971 unsigned j;
14972 inst.vectype.elems = els;
14973 inst.vectype.el[key_el] = inst.vectype.el[0];
14974 for (j = 0; j < els; j++)
477330fc
RM
14975 if (j != key_el)
14976 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
14977 types[j]);
dcbf9037
JB
14978 }
14979 else if (inst.vectype.elems == 0 && els > 0)
14980 {
14981 unsigned j;
14982 /* No types were given after the mnemonic, so look for types specified
477330fc
RM
14983 after each operand. We allow some flexibility here; as long as the
14984 "key" operand has a type, we can infer the others. */
dcbf9037 14985 for (j = 0; j < els; j++)
477330fc
RM
14986 if (inst.operands[j].vectype.type != NT_invtype)
14987 inst.vectype.el[j] = inst.operands[j].vectype;
dcbf9037
JB
14988
14989 if (inst.operands[key_el].vectype.type != NT_invtype)
477330fc
RM
14990 {
14991 for (j = 0; j < els; j++)
14992 if (inst.operands[j].vectype.type == NT_invtype)
14993 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
14994 types[j]);
14995 }
dcbf9037 14996 else
477330fc
RM
14997 {
14998 first_error (_("operand types can't be inferred"));
14999 return badtype;
15000 }
5287ad62
JB
15001 }
15002 else if (inst.vectype.elems != els)
15003 {
dcbf9037 15004 first_error (_("type specifier has the wrong number of parts"));
5287ad62
JB
15005 return badtype;
15006 }
15007
15008 for (pass = 0; pass < 2; pass++)
15009 {
15010 for (i = 0; i < els; i++)
477330fc
RM
15011 {
15012 unsigned thisarg = types[i];
15013 unsigned types_allowed = ((thisarg & N_EQK) != 0 && pass != 0)
15014 ? modify_types_allowed (key_allowed, thisarg) : thisarg;
15015 enum neon_el_type g_type = inst.vectype.el[i].type;
15016 unsigned g_size = inst.vectype.el[i].size;
15017
15018 /* Decay more-specific signed & unsigned types to sign-insensitive
5287ad62 15019 integer types if sign-specific variants are unavailable. */
477330fc 15020 if ((g_type == NT_signed || g_type == NT_unsigned)
5287ad62
JB
15021 && (types_allowed & N_SU_ALL) == 0)
15022 g_type = NT_integer;
15023
477330fc 15024 /* If only untyped args are allowed, decay any more specific types to
5287ad62
JB
15025 them. Some instructions only care about signs for some element
15026 sizes, so handle that properly. */
477330fc 15027 if (((types_allowed & N_UNT) == 0)
91ff7894
MGD
15028 && ((g_size == 8 && (types_allowed & N_8) != 0)
15029 || (g_size == 16 && (types_allowed & N_16) != 0)
15030 || (g_size == 32 && (types_allowed & N_32) != 0)
15031 || (g_size == 64 && (types_allowed & N_64) != 0)))
5287ad62
JB
15032 g_type = NT_untyped;
15033
477330fc
RM
15034 if (pass == 0)
15035 {
15036 if ((thisarg & N_KEY) != 0)
15037 {
15038 k_type = g_type;
15039 k_size = g_size;
15040 key_allowed = thisarg & ~N_KEY;
cc933301
JW
15041
15042 /* Check architecture constraint on FP16 extension. */
15043 if (k_size == 16
15044 && k_type == NT_float
15045 && ! ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
15046 {
15047 inst.error = _(BAD_FP16);
15048 return badtype;
15049 }
477330fc
RM
15050 }
15051 }
15052 else
15053 {
15054 if ((thisarg & N_VFP) != 0)
15055 {
15056 enum neon_shape_el regshape;
15057 unsigned regwidth, match;
99b253c5
NC
15058
15059 /* PR 11136: Catch the case where we are passed a shape of NS_NULL. */
15060 if (ns == NS_NULL)
15061 {
15062 first_error (_("invalid instruction shape"));
15063 return badtype;
15064 }
477330fc
RM
15065 regshape = neon_shape_tab[ns].el[i];
15066 regwidth = neon_shape_el_size[regshape];
15067
15068 /* In VFP mode, operands must match register widths. If we
15069 have a key operand, use its width, else use the width of
15070 the current operand. */
15071 if (k_size != -1u)
15072 match = k_size;
15073 else
15074 match = g_size;
15075
9db2f6b4
RL
15076 /* FP16 will use a single precision register. */
15077 if (regwidth == 32 && match == 16)
15078 {
15079 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
15080 match = regwidth;
15081 else
15082 {
15083 inst.error = _(BAD_FP16);
15084 return badtype;
15085 }
15086 }
15087
477330fc
RM
15088 if (regwidth != match)
15089 {
15090 first_error (_("operand size must match register width"));
15091 return badtype;
15092 }
15093 }
15094
15095 if ((thisarg & N_EQK) == 0)
15096 {
15097 unsigned given_type = type_chk_of_el_type (g_type, g_size);
15098
15099 if ((given_type & types_allowed) == 0)
15100 {
a302e574 15101 first_error (BAD_SIMD_TYPE);
477330fc
RM
15102 return badtype;
15103 }
15104 }
15105 else
15106 {
15107 enum neon_el_type mod_k_type = k_type;
15108 unsigned mod_k_size = k_size;
15109 neon_modify_type_size (thisarg, &mod_k_type, &mod_k_size);
15110 if (g_type != mod_k_type || g_size != mod_k_size)
15111 {
15112 first_error (_("inconsistent types in Neon instruction"));
15113 return badtype;
15114 }
15115 }
15116 }
15117 }
5287ad62
JB
15118 }
15119
15120 return inst.vectype.el[key_el];
15121}
15122
037e8744 15123/* Neon-style VFP instruction forwarding. */
5287ad62 15124
037e8744
JB
15125/* Thumb VFP instructions have 0xE in the condition field. */
15126
15127static void
15128do_vfp_cond_or_thumb (void)
5287ad62 15129{
88714cb8
DG
15130 inst.is_neon = 1;
15131
5287ad62 15132 if (thumb_mode)
037e8744 15133 inst.instruction |= 0xe0000000;
5287ad62 15134 else
037e8744 15135 inst.instruction |= inst.cond << 28;
5287ad62
JB
15136}
15137
037e8744
JB
15138/* Look up and encode a simple mnemonic, for use as a helper function for the
15139 Neon-style VFP syntax. This avoids duplication of bits of the insns table,
15140 etc. It is assumed that operand parsing has already been done, and that the
15141 operands are in the form expected by the given opcode (this isn't necessarily
15142 the same as the form in which they were parsed, hence some massaging must
15143 take place before this function is called).
15144 Checks current arch version against that in the looked-up opcode. */
5287ad62 15145
037e8744
JB
15146static void
15147do_vfp_nsyn_opcode (const char *opname)
5287ad62 15148{
037e8744 15149 const struct asm_opcode *opcode;
5f4273c7 15150
21d799b5 15151 opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, opname);
5287ad62 15152
037e8744
JB
15153 if (!opcode)
15154 abort ();
5287ad62 15155
037e8744 15156 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant,
477330fc
RM
15157 thumb_mode ? *opcode->tvariant : *opcode->avariant),
15158 _(BAD_FPU));
5287ad62 15159
88714cb8
DG
15160 inst.is_neon = 1;
15161
037e8744
JB
15162 if (thumb_mode)
15163 {
15164 inst.instruction = opcode->tvalue;
15165 opcode->tencode ();
15166 }
15167 else
15168 {
15169 inst.instruction = (inst.cond << 28) | opcode->avalue;
15170 opcode->aencode ();
15171 }
15172}
5287ad62
JB
15173
15174static void
037e8744 15175do_vfp_nsyn_add_sub (enum neon_shape rs)
5287ad62 15176{
037e8744
JB
15177 int is_add = (inst.instruction & 0x0fffffff) == N_MNEM_vadd;
15178
9db2f6b4 15179 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
15180 {
15181 if (is_add)
477330fc 15182 do_vfp_nsyn_opcode ("fadds");
037e8744 15183 else
477330fc 15184 do_vfp_nsyn_opcode ("fsubs");
9db2f6b4
RL
15185
15186 /* ARMv8.2 fp16 instruction. */
15187 if (rs == NS_HHH)
15188 do_scalar_fp16_v82_encode ();
037e8744
JB
15189 }
15190 else
15191 {
15192 if (is_add)
477330fc 15193 do_vfp_nsyn_opcode ("faddd");
037e8744 15194 else
477330fc 15195 do_vfp_nsyn_opcode ("fsubd");
037e8744
JB
15196 }
15197}
15198
15199/* Check operand types to see if this is a VFP instruction, and if so call
15200 PFN (). */
15201
15202static int
15203try_vfp_nsyn (int args, void (*pfn) (enum neon_shape))
15204{
15205 enum neon_shape rs;
15206 struct neon_type_el et;
15207
15208 switch (args)
15209 {
15210 case 2:
9db2f6b4
RL
15211 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
15212 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
037e8744 15213 break;
5f4273c7 15214
037e8744 15215 case 3:
9db2f6b4
RL
15216 rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
15217 et = neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
15218 N_F_ALL | N_KEY | N_VFP);
037e8744
JB
15219 break;
15220
15221 default:
15222 abort ();
15223 }
15224
15225 if (et.type != NT_invtype)
15226 {
15227 pfn (rs);
15228 return SUCCESS;
15229 }
037e8744 15230
99b253c5 15231 inst.error = NULL;
037e8744
JB
15232 return FAIL;
15233}
15234
15235static void
15236do_vfp_nsyn_mla_mls (enum neon_shape rs)
15237{
15238 int is_mla = (inst.instruction & 0x0fffffff) == N_MNEM_vmla;
5f4273c7 15239
9db2f6b4 15240 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
15241 {
15242 if (is_mla)
477330fc 15243 do_vfp_nsyn_opcode ("fmacs");
037e8744 15244 else
477330fc 15245 do_vfp_nsyn_opcode ("fnmacs");
9db2f6b4
RL
15246
15247 /* ARMv8.2 fp16 instruction. */
15248 if (rs == NS_HHH)
15249 do_scalar_fp16_v82_encode ();
037e8744
JB
15250 }
15251 else
15252 {
15253 if (is_mla)
477330fc 15254 do_vfp_nsyn_opcode ("fmacd");
037e8744 15255 else
477330fc 15256 do_vfp_nsyn_opcode ("fnmacd");
037e8744
JB
15257 }
15258}
15259
62f3b8c8
PB
15260static void
15261do_vfp_nsyn_fma_fms (enum neon_shape rs)
15262{
15263 int is_fma = (inst.instruction & 0x0fffffff) == N_MNEM_vfma;
15264
9db2f6b4 15265 if (rs == NS_FFF || rs == NS_HHH)
62f3b8c8
PB
15266 {
15267 if (is_fma)
477330fc 15268 do_vfp_nsyn_opcode ("ffmas");
62f3b8c8 15269 else
477330fc 15270 do_vfp_nsyn_opcode ("ffnmas");
9db2f6b4
RL
15271
15272 /* ARMv8.2 fp16 instruction. */
15273 if (rs == NS_HHH)
15274 do_scalar_fp16_v82_encode ();
62f3b8c8
PB
15275 }
15276 else
15277 {
15278 if (is_fma)
477330fc 15279 do_vfp_nsyn_opcode ("ffmad");
62f3b8c8 15280 else
477330fc 15281 do_vfp_nsyn_opcode ("ffnmad");
62f3b8c8
PB
15282 }
15283}
15284
037e8744
JB
15285static void
15286do_vfp_nsyn_mul (enum neon_shape rs)
15287{
9db2f6b4
RL
15288 if (rs == NS_FFF || rs == NS_HHH)
15289 {
15290 do_vfp_nsyn_opcode ("fmuls");
15291
15292 /* ARMv8.2 fp16 instruction. */
15293 if (rs == NS_HHH)
15294 do_scalar_fp16_v82_encode ();
15295 }
037e8744
JB
15296 else
15297 do_vfp_nsyn_opcode ("fmuld");
15298}
15299
15300static void
15301do_vfp_nsyn_abs_neg (enum neon_shape rs)
15302{
15303 int is_neg = (inst.instruction & 0x80) != 0;
9db2f6b4 15304 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_VFP | N_KEY);
037e8744 15305
9db2f6b4 15306 if (rs == NS_FF || rs == NS_HH)
037e8744
JB
15307 {
15308 if (is_neg)
477330fc 15309 do_vfp_nsyn_opcode ("fnegs");
037e8744 15310 else
477330fc 15311 do_vfp_nsyn_opcode ("fabss");
9db2f6b4
RL
15312
15313 /* ARMv8.2 fp16 instruction. */
15314 if (rs == NS_HH)
15315 do_scalar_fp16_v82_encode ();
037e8744
JB
15316 }
15317 else
15318 {
15319 if (is_neg)
477330fc 15320 do_vfp_nsyn_opcode ("fnegd");
037e8744 15321 else
477330fc 15322 do_vfp_nsyn_opcode ("fabsd");
037e8744
JB
15323 }
15324}
15325
15326/* Encode single-precision (only!) VFP fldm/fstm instructions. Double precision
15327 insns belong to Neon, and are handled elsewhere. */
15328
15329static void
15330do_vfp_nsyn_ldm_stm (int is_dbmode)
15331{
15332 int is_ldm = (inst.instruction & (1 << 20)) != 0;
15333 if (is_ldm)
15334 {
15335 if (is_dbmode)
477330fc 15336 do_vfp_nsyn_opcode ("fldmdbs");
037e8744 15337 else
477330fc 15338 do_vfp_nsyn_opcode ("fldmias");
037e8744
JB
15339 }
15340 else
15341 {
15342 if (is_dbmode)
477330fc 15343 do_vfp_nsyn_opcode ("fstmdbs");
037e8744 15344 else
477330fc 15345 do_vfp_nsyn_opcode ("fstmias");
037e8744
JB
15346 }
15347}
15348
037e8744
JB
15349static void
15350do_vfp_nsyn_sqrt (void)
15351{
9db2f6b4
RL
15352 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
15353 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 15354
9db2f6b4
RL
15355 if (rs == NS_FF || rs == NS_HH)
15356 {
15357 do_vfp_nsyn_opcode ("fsqrts");
15358
15359 /* ARMv8.2 fp16 instruction. */
15360 if (rs == NS_HH)
15361 do_scalar_fp16_v82_encode ();
15362 }
037e8744
JB
15363 else
15364 do_vfp_nsyn_opcode ("fsqrtd");
15365}
15366
15367static void
15368do_vfp_nsyn_div (void)
15369{
9db2f6b4 15370 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 15371 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 15372 N_F_ALL | N_KEY | N_VFP);
5f4273c7 15373
9db2f6b4
RL
15374 if (rs == NS_FFF || rs == NS_HHH)
15375 {
15376 do_vfp_nsyn_opcode ("fdivs");
15377
15378 /* ARMv8.2 fp16 instruction. */
15379 if (rs == NS_HHH)
15380 do_scalar_fp16_v82_encode ();
15381 }
037e8744
JB
15382 else
15383 do_vfp_nsyn_opcode ("fdivd");
15384}
15385
15386static void
15387do_vfp_nsyn_nmul (void)
15388{
9db2f6b4 15389 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 15390 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 15391 N_F_ALL | N_KEY | N_VFP);
5f4273c7 15392
9db2f6b4 15393 if (rs == NS_FFF || rs == NS_HHH)
037e8744 15394 {
88714cb8 15395 NEON_ENCODE (SINGLE, inst);
037e8744 15396 do_vfp_sp_dyadic ();
9db2f6b4
RL
15397
15398 /* ARMv8.2 fp16 instruction. */
15399 if (rs == NS_HHH)
15400 do_scalar_fp16_v82_encode ();
037e8744
JB
15401 }
15402 else
15403 {
88714cb8 15404 NEON_ENCODE (DOUBLE, inst);
037e8744
JB
15405 do_vfp_dp_rd_rn_rm ();
15406 }
15407 do_vfp_cond_or_thumb ();
9db2f6b4 15408
037e8744
JB
15409}
15410
1b883319
AV
15411/* Turn a size (8, 16, 32, 64) into the respective bit number minus 3
15412 (0, 1, 2, 3). */
15413
15414static unsigned
15415neon_logbits (unsigned x)
15416{
15417 return ffs (x) - 4;
15418}
15419
15420#define LOW4(R) ((R) & 0xf)
15421#define HI1(R) (((R) >> 4) & 1)
15422
15423static unsigned
15424mve_get_vcmp_vpt_cond (struct neon_type_el et)
15425{
15426 switch (et.type)
15427 {
15428 default:
15429 first_error (BAD_EL_TYPE);
15430 return 0;
15431 case NT_float:
15432 switch (inst.operands[0].imm)
15433 {
15434 default:
15435 first_error (_("invalid condition"));
15436 return 0;
15437 case 0x0:
15438 /* eq. */
15439 return 0;
15440 case 0x1:
15441 /* ne. */
15442 return 1;
15443 case 0xa:
15444 /* ge/ */
15445 return 4;
15446 case 0xb:
15447 /* lt. */
15448 return 5;
15449 case 0xc:
15450 /* gt. */
15451 return 6;
15452 case 0xd:
15453 /* le. */
15454 return 7;
15455 }
15456 case NT_integer:
15457 /* only accept eq and ne. */
15458 if (inst.operands[0].imm > 1)
15459 {
15460 first_error (_("invalid condition"));
15461 return 0;
15462 }
15463 return inst.operands[0].imm;
15464 case NT_unsigned:
15465 if (inst.operands[0].imm == 0x2)
15466 return 2;
15467 else if (inst.operands[0].imm == 0x8)
15468 return 3;
15469 else
15470 {
15471 first_error (_("invalid condition"));
15472 return 0;
15473 }
15474 case NT_signed:
15475 switch (inst.operands[0].imm)
15476 {
15477 default:
15478 first_error (_("invalid condition"));
15479 return 0;
15480 case 0xa:
15481 /* ge. */
15482 return 4;
15483 case 0xb:
15484 /* lt. */
15485 return 5;
15486 case 0xc:
15487 /* gt. */
15488 return 6;
15489 case 0xd:
15490 /* le. */
15491 return 7;
15492 }
15493 }
15494 /* Should be unreachable. */
15495 abort ();
15496}
15497
15498static void
15499do_mve_vpt (void)
15500{
15501 /* We are dealing with a vector predicated block. */
15502 if (inst.operands[0].present)
15503 {
15504 enum neon_shape rs = neon_select_shape (NS_IQQ, NS_IQR, NS_NULL);
15505 struct neon_type_el et
15506 = neon_check_type (3, rs, N_EQK, N_KEY | N_F_MVE | N_I_MVE | N_SU_32,
15507 N_EQK);
15508
15509 unsigned fcond = mve_get_vcmp_vpt_cond (et);
15510
15511 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
15512
15513 if (et.type == NT_invtype)
15514 return;
15515
15516 if (et.type == NT_float)
15517 {
15518 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
15519 BAD_FPU);
15520 constraint (et.size != 16 && et.size != 32, BAD_EL_TYPE);
15521 inst.instruction |= (et.size == 16) << 28;
15522 inst.instruction |= 0x3 << 20;
15523 }
15524 else
15525 {
15526 constraint (et.size != 8 && et.size != 16 && et.size != 32,
15527 BAD_EL_TYPE);
15528 inst.instruction |= 1 << 28;
15529 inst.instruction |= neon_logbits (et.size) << 20;
15530 }
15531
15532 if (inst.operands[2].isquad)
15533 {
15534 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
15535 inst.instruction |= LOW4 (inst.operands[2].reg);
15536 inst.instruction |= (fcond & 0x2) >> 1;
15537 }
15538 else
15539 {
15540 if (inst.operands[2].reg == REG_SP)
15541 as_tsktsk (MVE_BAD_SP);
15542 inst.instruction |= 1 << 6;
15543 inst.instruction |= (fcond & 0x2) << 4;
15544 inst.instruction |= inst.operands[2].reg;
15545 }
15546 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15547 inst.instruction |= (fcond & 0x4) << 10;
15548 inst.instruction |= (fcond & 0x1) << 7;
15549
15550 }
15551 set_pred_insn_type (VPT_INSN);
15552 now_pred.cc = 0;
15553 now_pred.mask = ((inst.instruction & 0x00400000) >> 19)
15554 | ((inst.instruction & 0xe000) >> 13);
15555 now_pred.warn_deprecated = FALSE;
15556 now_pred.type = VECTOR_PRED;
15557 inst.is_neon = 1;
15558}
15559
15560static void
15561do_mve_vcmp (void)
15562{
15563 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
15564 if (!inst.operands[1].isreg || !inst.operands[1].isquad)
15565 first_error (_(reg_expected_msgs[REG_TYPE_MQ]));
15566 if (!inst.operands[2].present)
15567 first_error (_("MVE vector or ARM register expected"));
15568 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
15569
15570 /* Deal with 'else' conditional MVE's vcmp, it will be parsed as vcmpe. */
15571 if ((inst.instruction & 0xffffffff) == N_MNEM_vcmpe
15572 && inst.operands[1].isquad)
15573 {
15574 inst.instruction = N_MNEM_vcmp;
15575 inst.cond = 0x10;
15576 }
15577
15578 if (inst.cond > COND_ALWAYS)
15579 inst.pred_insn_type = INSIDE_VPT_INSN;
15580 else
15581 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15582
15583 enum neon_shape rs = neon_select_shape (NS_IQQ, NS_IQR, NS_NULL);
15584 struct neon_type_el et
15585 = neon_check_type (3, rs, N_EQK, N_KEY | N_F_MVE | N_I_MVE | N_SU_32,
15586 N_EQK);
15587
15588 constraint (rs == NS_IQR && inst.operands[2].reg == REG_PC
15589 && !inst.operands[2].iszr, BAD_PC);
15590
15591 unsigned fcond = mve_get_vcmp_vpt_cond (et);
15592
15593 inst.instruction = 0xee010f00;
15594 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15595 inst.instruction |= (fcond & 0x4) << 10;
15596 inst.instruction |= (fcond & 0x1) << 7;
15597 if (et.type == NT_float)
15598 {
15599 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
15600 BAD_FPU);
15601 inst.instruction |= (et.size == 16) << 28;
15602 inst.instruction |= 0x3 << 20;
15603 }
15604 else
15605 {
15606 inst.instruction |= 1 << 28;
15607 inst.instruction |= neon_logbits (et.size) << 20;
15608 }
15609 if (inst.operands[2].isquad)
15610 {
15611 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
15612 inst.instruction |= (fcond & 0x2) >> 1;
15613 inst.instruction |= LOW4 (inst.operands[2].reg);
15614 }
15615 else
15616 {
15617 if (inst.operands[2].reg == REG_SP)
15618 as_tsktsk (MVE_BAD_SP);
15619 inst.instruction |= 1 << 6;
15620 inst.instruction |= (fcond & 0x2) << 4;
15621 inst.instruction |= inst.operands[2].reg;
15622 }
15623
15624 inst.is_neon = 1;
15625 return;
15626}
15627
935295b5
AV
15628static void
15629do_mve_vmaxa_vmina (void)
15630{
15631 if (inst.cond > COND_ALWAYS)
15632 inst.pred_insn_type = INSIDE_VPT_INSN;
15633 else
15634 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15635
15636 enum neon_shape rs = neon_select_shape (NS_QQ, NS_NULL);
15637 struct neon_type_el et
15638 = neon_check_type (2, rs, N_EQK, N_KEY | N_S8 | N_S16 | N_S32);
15639
15640 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15641 inst.instruction |= neon_logbits (et.size) << 18;
15642 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15643 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
15644 inst.instruction |= LOW4 (inst.operands[1].reg);
15645 inst.is_neon = 1;
15646}
15647
f30ee27c
AV
15648static void
15649do_mve_vfmas (void)
15650{
15651 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
15652 struct neon_type_el et
15653 = neon_check_type (3, rs, N_F_MVE | N_KEY, N_EQK, N_EQK);
15654
15655 if (inst.cond > COND_ALWAYS)
15656 inst.pred_insn_type = INSIDE_VPT_INSN;
15657 else
15658 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15659
15660 if (inst.operands[2].reg == REG_SP)
15661 as_tsktsk (MVE_BAD_SP);
15662 else if (inst.operands[2].reg == REG_PC)
15663 as_tsktsk (MVE_BAD_PC);
15664
15665 inst.instruction |= (et.size == 16) << 28;
15666 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15667 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15668 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15669 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
15670 inst.instruction |= inst.operands[2].reg;
15671 inst.is_neon = 1;
15672}
15673
b409bdb6
AV
15674static void
15675do_mve_viddup (void)
15676{
15677 if (inst.cond > COND_ALWAYS)
15678 inst.pred_insn_type = INSIDE_VPT_INSN;
15679 else
15680 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15681
15682 unsigned imm = inst.relocs[0].exp.X_add_number;
15683 constraint (imm != 1 && imm != 2 && imm != 4 && imm != 8,
15684 _("immediate must be either 1, 2, 4 or 8"));
15685
15686 enum neon_shape rs;
15687 struct neon_type_el et;
15688 unsigned Rm;
15689 if (inst.instruction == M_MNEM_vddup || inst.instruction == M_MNEM_vidup)
15690 {
15691 rs = neon_select_shape (NS_QRI, NS_NULL);
15692 et = neon_check_type (2, rs, N_KEY | N_U8 | N_U16 | N_U32, N_EQK);
15693 Rm = 7;
15694 }
15695 else
15696 {
15697 constraint ((inst.operands[2].reg % 2) != 1, BAD_EVEN);
15698 if (inst.operands[2].reg == REG_SP)
15699 as_tsktsk (MVE_BAD_SP);
15700 else if (inst.operands[2].reg == REG_PC)
15701 first_error (BAD_PC);
15702
15703 rs = neon_select_shape (NS_QRRI, NS_NULL);
15704 et = neon_check_type (3, rs, N_KEY | N_U8 | N_U16 | N_U32, N_EQK, N_EQK);
15705 Rm = inst.operands[2].reg >> 1;
15706 }
15707 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15708 inst.instruction |= neon_logbits (et.size) << 20;
15709 inst.instruction |= inst.operands[1].reg << 16;
15710 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15711 inst.instruction |= (imm > 2) << 7;
15712 inst.instruction |= Rm << 1;
15713 inst.instruction |= (imm == 2 || imm == 8);
15714 inst.is_neon = 1;
15715}
15716
2d78f95b
AV
15717static void
15718do_mve_vmlas (void)
15719{
15720 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
15721 struct neon_type_el et
15722 = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
15723
15724 if (inst.operands[2].reg == REG_PC)
15725 as_tsktsk (MVE_BAD_PC);
15726 else if (inst.operands[2].reg == REG_SP)
15727 as_tsktsk (MVE_BAD_SP);
15728
15729 if (inst.cond > COND_ALWAYS)
15730 inst.pred_insn_type = INSIDE_VPT_INSN;
15731 else
15732 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15733
15734 inst.instruction |= (et.type == NT_unsigned) << 28;
15735 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15736 inst.instruction |= neon_logbits (et.size) << 20;
15737 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15738 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15739 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
15740 inst.instruction |= inst.operands[2].reg;
15741 inst.is_neon = 1;
15742}
15743
3063888e
AV
15744static void
15745do_mve_vpsel (void)
15746{
15747 neon_select_shape (NS_QQQ, NS_NULL);
15748
15749 if (inst.cond > COND_ALWAYS)
15750 inst.pred_insn_type = INSIDE_VPT_INSN;
15751 else
15752 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15753
15754 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15755 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15756 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15757 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
15758 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
15759 inst.instruction |= LOW4 (inst.operands[2].reg);
15760 inst.is_neon = 1;
15761}
15762
15763static void
15764do_mve_vpnot (void)
15765{
15766 if (inst.cond > COND_ALWAYS)
15767 inst.pred_insn_type = INSIDE_VPT_INSN;
15768 else
15769 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15770}
15771
935295b5
AV
15772static void
15773do_mve_vmaxnma_vminnma (void)
15774{
15775 enum neon_shape rs = neon_select_shape (NS_QQ, NS_NULL);
15776 struct neon_type_el et
15777 = neon_check_type (2, rs, N_EQK, N_F_MVE | N_KEY);
15778
15779 if (inst.cond > COND_ALWAYS)
15780 inst.pred_insn_type = INSIDE_VPT_INSN;
15781 else
15782 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15783
15784 inst.instruction |= (et.size == 16) << 28;
15785 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15786 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15787 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
15788 inst.instruction |= LOW4 (inst.operands[1].reg);
15789 inst.is_neon = 1;
15790}
15791
5d281bf0
AV
15792static void
15793do_mve_vcmul (void)
15794{
15795 enum neon_shape rs = neon_select_shape (NS_QQQI, NS_NULL);
15796 struct neon_type_el et
15797 = neon_check_type (3, rs, N_EQK, N_EQK, N_F_MVE | N_KEY);
15798
15799 if (inst.cond > COND_ALWAYS)
15800 inst.pred_insn_type = INSIDE_VPT_INSN;
15801 else
15802 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15803
15804 unsigned rot = inst.relocs[0].exp.X_add_number;
15805 constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
15806 _("immediate out of range"));
15807
15808 if (et.size == 32 && (inst.operands[0].reg == inst.operands[1].reg
15809 || inst.operands[0].reg == inst.operands[2].reg))
15810 as_tsktsk (BAD_MVE_SRCDEST);
15811
15812 inst.instruction |= (et.size == 32) << 28;
15813 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15814 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15815 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15816 inst.instruction |= (rot > 90) << 12;
15817 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
15818 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
15819 inst.instruction |= LOW4 (inst.operands[2].reg);
15820 inst.instruction |= (rot == 90 || rot == 270);
15821 inst.is_neon = 1;
15822}
15823
037e8744
JB
15824static void
15825do_vfp_nsyn_cmp (void)
15826{
9db2f6b4 15827 enum neon_shape rs;
1b883319
AV
15828 if (!inst.operands[0].isreg)
15829 {
15830 do_mve_vcmp ();
15831 return;
15832 }
15833 else
15834 {
15835 constraint (inst.operands[2].present, BAD_SYNTAX);
15836 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd),
15837 BAD_FPU);
15838 }
15839
037e8744
JB
15840 if (inst.operands[1].isreg)
15841 {
9db2f6b4
RL
15842 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
15843 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 15844
9db2f6b4 15845 if (rs == NS_FF || rs == NS_HH)
477330fc
RM
15846 {
15847 NEON_ENCODE (SINGLE, inst);
15848 do_vfp_sp_monadic ();
15849 }
037e8744 15850 else
477330fc
RM
15851 {
15852 NEON_ENCODE (DOUBLE, inst);
15853 do_vfp_dp_rd_rm ();
15854 }
037e8744
JB
15855 }
15856 else
15857 {
9db2f6b4
RL
15858 rs = neon_select_shape (NS_HI, NS_FI, NS_DI, NS_NULL);
15859 neon_check_type (2, rs, N_F_ALL | N_KEY | N_VFP, N_EQK);
037e8744
JB
15860
15861 switch (inst.instruction & 0x0fffffff)
477330fc
RM
15862 {
15863 case N_MNEM_vcmp:
15864 inst.instruction += N_MNEM_vcmpz - N_MNEM_vcmp;
15865 break;
15866 case N_MNEM_vcmpe:
15867 inst.instruction += N_MNEM_vcmpez - N_MNEM_vcmpe;
15868 break;
15869 default:
15870 abort ();
15871 }
5f4273c7 15872
9db2f6b4 15873 if (rs == NS_FI || rs == NS_HI)
477330fc
RM
15874 {
15875 NEON_ENCODE (SINGLE, inst);
15876 do_vfp_sp_compare_z ();
15877 }
037e8744 15878 else
477330fc
RM
15879 {
15880 NEON_ENCODE (DOUBLE, inst);
15881 do_vfp_dp_rd ();
15882 }
037e8744
JB
15883 }
15884 do_vfp_cond_or_thumb ();
9db2f6b4
RL
15885
15886 /* ARMv8.2 fp16 instruction. */
15887 if (rs == NS_HI || rs == NS_HH)
15888 do_scalar_fp16_v82_encode ();
037e8744
JB
15889}
15890
15891static void
15892nsyn_insert_sp (void)
15893{
15894 inst.operands[1] = inst.operands[0];
15895 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
fdfde340 15896 inst.operands[0].reg = REG_SP;
037e8744
JB
15897 inst.operands[0].isreg = 1;
15898 inst.operands[0].writeback = 1;
15899 inst.operands[0].present = 1;
15900}
15901
15902static void
15903do_vfp_nsyn_push (void)
15904{
15905 nsyn_insert_sp ();
b126985e
NC
15906
15907 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
15908 _("register list must contain at least 1 and at most 16 "
15909 "registers"));
15910
037e8744
JB
15911 if (inst.operands[1].issingle)
15912 do_vfp_nsyn_opcode ("fstmdbs");
15913 else
15914 do_vfp_nsyn_opcode ("fstmdbd");
15915}
15916
15917static void
15918do_vfp_nsyn_pop (void)
15919{
15920 nsyn_insert_sp ();
b126985e
NC
15921
15922 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
15923 _("register list must contain at least 1 and at most 16 "
15924 "registers"));
15925
037e8744 15926 if (inst.operands[1].issingle)
22b5b651 15927 do_vfp_nsyn_opcode ("fldmias");
037e8744 15928 else
22b5b651 15929 do_vfp_nsyn_opcode ("fldmiad");
037e8744
JB
15930}
15931
15932/* Fix up Neon data-processing instructions, ORing in the correct bits for
15933 ARM mode or Thumb mode and moving the encoded bit 24 to bit 28. */
15934
88714cb8
DG
15935static void
15936neon_dp_fixup (struct arm_it* insn)
037e8744 15937{
88714cb8
DG
15938 unsigned int i = insn->instruction;
15939 insn->is_neon = 1;
15940
037e8744
JB
15941 if (thumb_mode)
15942 {
15943 /* The U bit is at bit 24 by default. Move to bit 28 in Thumb mode. */
15944 if (i & (1 << 24))
477330fc 15945 i |= 1 << 28;
5f4273c7 15946
037e8744 15947 i &= ~(1 << 24);
5f4273c7 15948
037e8744
JB
15949 i |= 0xef000000;
15950 }
15951 else
15952 i |= 0xf2000000;
5f4273c7 15953
88714cb8 15954 insn->instruction = i;
037e8744
JB
15955}
15956
5ee91343 15957static void
7df54120 15958mve_encode_qqr (int size, int U, int fp)
5ee91343
AV
15959{
15960 if (inst.operands[2].reg == REG_SP)
15961 as_tsktsk (MVE_BAD_SP);
15962 else if (inst.operands[2].reg == REG_PC)
15963 as_tsktsk (MVE_BAD_PC);
15964
15965 if (fp)
15966 {
15967 /* vadd. */
15968 if (((unsigned)inst.instruction) == 0xd00)
15969 inst.instruction = 0xee300f40;
15970 /* vsub. */
15971 else if (((unsigned)inst.instruction) == 0x200d00)
15972 inst.instruction = 0xee301f40;
a8465a06
AV
15973 /* vmul. */
15974 else if (((unsigned)inst.instruction) == 0x1000d10)
15975 inst.instruction = 0xee310e60;
5ee91343
AV
15976
15977 /* Setting size which is 1 for F16 and 0 for F32. */
15978 inst.instruction |= (size == 16) << 28;
15979 }
15980 else
15981 {
15982 /* vadd. */
15983 if (((unsigned)inst.instruction) == 0x800)
15984 inst.instruction = 0xee010f40;
15985 /* vsub. */
15986 else if (((unsigned)inst.instruction) == 0x1000800)
15987 inst.instruction = 0xee011f40;
7df54120
AV
15988 /* vhadd. */
15989 else if (((unsigned)inst.instruction) == 0)
15990 inst.instruction = 0xee000f40;
15991 /* vhsub. */
15992 else if (((unsigned)inst.instruction) == 0x200)
15993 inst.instruction = 0xee001f40;
a8465a06
AV
15994 /* vmla. */
15995 else if (((unsigned)inst.instruction) == 0x900)
15996 inst.instruction = 0xee010e40;
15997 /* vmul. */
15998 else if (((unsigned)inst.instruction) == 0x910)
15999 inst.instruction = 0xee011e60;
16000 /* vqadd. */
16001 else if (((unsigned)inst.instruction) == 0x10)
16002 inst.instruction = 0xee000f60;
16003 /* vqsub. */
16004 else if (((unsigned)inst.instruction) == 0x210)
16005 inst.instruction = 0xee001f60;
42b16635
AV
16006 /* vqrdmlah. */
16007 else if (((unsigned)inst.instruction) == 0x3000b10)
16008 inst.instruction = 0xee000e40;
16009 /* vqdmulh. */
16010 else if (((unsigned)inst.instruction) == 0x0000b00)
16011 inst.instruction = 0xee010e60;
16012 /* vqrdmulh. */
16013 else if (((unsigned)inst.instruction) == 0x1000b00)
16014 inst.instruction = 0xfe010e60;
7df54120
AV
16015
16016 /* Set U-bit. */
16017 inst.instruction |= U << 28;
16018
5ee91343
AV
16019 /* Setting bits for size. */
16020 inst.instruction |= neon_logbits (size) << 20;
16021 }
16022 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16023 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16024 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16025 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16026 inst.instruction |= inst.operands[2].reg;
16027 inst.is_neon = 1;
16028}
16029
a302e574
AV
16030static void
16031mve_encode_rqq (unsigned bit28, unsigned size)
16032{
16033 inst.instruction |= bit28 << 28;
16034 inst.instruction |= neon_logbits (size) << 20;
16035 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16036 inst.instruction |= inst.operands[0].reg << 12;
16037 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16038 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16039 inst.instruction |= LOW4 (inst.operands[2].reg);
16040 inst.is_neon = 1;
16041}
16042
886e1c73
AV
16043static void
16044mve_encode_qqq (int ubit, int size)
16045{
16046
16047 inst.instruction |= (ubit != 0) << 28;
16048 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16049 inst.instruction |= neon_logbits (size) << 20;
16050 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16051 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16052 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16053 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16054 inst.instruction |= LOW4 (inst.operands[2].reg);
16055
16056 inst.is_neon = 1;
16057}
16058
26c1e780
AV
16059static void
16060mve_encode_rq (unsigned bit28, unsigned size)
16061{
16062 inst.instruction |= bit28 << 28;
16063 inst.instruction |= neon_logbits (size) << 18;
16064 inst.instruction |= inst.operands[0].reg << 12;
16065 inst.instruction |= LOW4 (inst.operands[1].reg);
16066 inst.is_neon = 1;
16067}
886e1c73 16068
93925576
AV
16069static void
16070mve_encode_rrqq (unsigned U, unsigned size)
16071{
16072 constraint (inst.operands[3].reg > 14, MVE_BAD_QREG);
16073
16074 inst.instruction |= U << 28;
16075 inst.instruction |= (inst.operands[1].reg >> 1) << 20;
16076 inst.instruction |= LOW4 (inst.operands[2].reg) << 16;
16077 inst.instruction |= (size == 32) << 16;
16078 inst.instruction |= inst.operands[0].reg << 12;
16079 inst.instruction |= HI1 (inst.operands[2].reg) << 7;
16080 inst.instruction |= inst.operands[3].reg;
16081 inst.is_neon = 1;
16082}
16083
037e8744
JB
16084/* Encode insns with bit pattern:
16085
16086 |28/24|23|22 |21 20|19 16|15 12|11 8|7|6|5|4|3 0|
16087 | U |x |D |size | Rn | Rd |x x x x|N|Q|M|x| Rm |
5f4273c7 16088
037e8744
JB
16089 SIZE is passed in bits. -1 means size field isn't changed, in case it has a
16090 different meaning for some instruction. */
16091
16092static void
16093neon_three_same (int isquad, int ubit, int size)
16094{
16095 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16096 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16097 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16098 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16099 inst.instruction |= LOW4 (inst.operands[2].reg);
16100 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16101 inst.instruction |= (isquad != 0) << 6;
16102 inst.instruction |= (ubit != 0) << 24;
16103 if (size != -1)
16104 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 16105
88714cb8 16106 neon_dp_fixup (&inst);
037e8744
JB
16107}
16108
16109/* Encode instructions of the form:
16110
16111 |28/24|23|22|21 20|19 18|17 16|15 12|11 7|6|5|4|3 0|
16112 | U |x |D |x x |size |x x | Rd |x x x x x|Q|M|x| Rm |
5287ad62
JB
16113
16114 Don't write size if SIZE == -1. */
16115
16116static void
16117neon_two_same (int qbit, int ubit, int size)
16118{
16119 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16120 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16121 inst.instruction |= LOW4 (inst.operands[1].reg);
16122 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16123 inst.instruction |= (qbit != 0) << 6;
16124 inst.instruction |= (ubit != 0) << 24;
16125
16126 if (size != -1)
16127 inst.instruction |= neon_logbits (size) << 18;
16128
88714cb8 16129 neon_dp_fixup (&inst);
5287ad62
JB
16130}
16131
7df54120
AV
16132enum vfp_or_neon_is_neon_bits
16133{
16134NEON_CHECK_CC = 1,
16135NEON_CHECK_ARCH = 2,
16136NEON_CHECK_ARCH8 = 4
16137};
16138
16139/* Call this function if an instruction which may have belonged to the VFP or
16140 Neon instruction sets, but turned out to be a Neon instruction (due to the
16141 operand types involved, etc.). We have to check and/or fix-up a couple of
16142 things:
16143
16144 - Make sure the user hasn't attempted to make a Neon instruction
16145 conditional.
16146 - Alter the value in the condition code field if necessary.
16147 - Make sure that the arch supports Neon instructions.
16148
16149 Which of these operations take place depends on bits from enum
16150 vfp_or_neon_is_neon_bits.
16151
16152 WARNING: This function has side effects! If NEON_CHECK_CC is used and the
16153 current instruction's condition is COND_ALWAYS, the condition field is
16154 changed to inst.uncond_value. This is necessary because instructions shared
16155 between VFP and Neon may be conditional for the VFP variants only, and the
16156 unconditional Neon version must have, e.g., 0xF in the condition field. */
16157
16158static int
16159vfp_or_neon_is_neon (unsigned check)
16160{
16161/* Conditions are always legal in Thumb mode (IT blocks). */
16162if (!thumb_mode && (check & NEON_CHECK_CC))
16163 {
16164 if (inst.cond != COND_ALWAYS)
16165 {
16166 first_error (_(BAD_COND));
16167 return FAIL;
16168 }
16169 if (inst.uncond_value != -1)
16170 inst.instruction |= inst.uncond_value << 28;
16171 }
16172
16173
16174 if (((check & NEON_CHECK_ARCH) && !mark_feature_used (&fpu_neon_ext_v1))
16175 || ((check & NEON_CHECK_ARCH8)
16176 && !mark_feature_used (&fpu_neon_ext_armv8)))
16177 {
16178 first_error (_(BAD_FPU));
16179 return FAIL;
16180 }
16181
16182return SUCCESS;
16183}
16184
16185static int
16186check_simd_pred_availability (int fp, unsigned check)
16187{
16188if (inst.cond > COND_ALWAYS)
16189 {
16190 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16191 {
16192 inst.error = BAD_FPU;
16193 return 1;
16194 }
16195 inst.pred_insn_type = INSIDE_VPT_INSN;
16196 }
16197else if (inst.cond < COND_ALWAYS)
16198 {
16199 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16200 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16201 else if (vfp_or_neon_is_neon (check) == FAIL)
16202 return 2;
16203 }
16204else
16205 {
16206 if (!ARM_CPU_HAS_FEATURE (cpu_variant, fp ? mve_fp_ext : mve_ext)
16207 && vfp_or_neon_is_neon (check) == FAIL)
16208 return 3;
16209
16210 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16211 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16212 }
16213return 0;
16214}
16215
5287ad62
JB
16216/* Neon instruction encoders, in approximate order of appearance. */
16217
16218static void
16219do_neon_dyadic_i_su (void)
16220{
7df54120
AV
16221 if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
16222 return;
16223
16224 enum neon_shape rs;
16225 struct neon_type_el et;
16226 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16227 rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
16228 else
16229 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
16230
16231 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_32 | N_KEY);
16232
16233
16234 if (rs != NS_QQR)
16235 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
16236 else
16237 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
5287ad62
JB
16238}
16239
16240static void
16241do_neon_dyadic_i64_su (void)
16242{
a8465a06
AV
16243 if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
16244 return;
16245 enum neon_shape rs;
16246 struct neon_type_el et;
16247 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16248 {
16249 rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
16250 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
16251 }
16252 else
16253 {
16254 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
16255 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_ALL | N_KEY);
16256 }
16257 if (rs == NS_QQR)
16258 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
16259 else
16260 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
16261}
16262
16263static void
16264neon_imm_shift (int write_ubit, int uval, int isquad, struct neon_type_el et,
477330fc 16265 unsigned immbits)
5287ad62
JB
16266{
16267 unsigned size = et.size >> 3;
16268 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16269 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16270 inst.instruction |= LOW4 (inst.operands[1].reg);
16271 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16272 inst.instruction |= (isquad != 0) << 6;
16273 inst.instruction |= immbits << 16;
16274 inst.instruction |= (size >> 3) << 7;
16275 inst.instruction |= (size & 0x7) << 19;
16276 if (write_ubit)
16277 inst.instruction |= (uval != 0) << 24;
16278
88714cb8 16279 neon_dp_fixup (&inst);
5287ad62
JB
16280}
16281
16282static void
16283do_neon_shl_imm (void)
16284{
16285 if (!inst.operands[2].isreg)
16286 {
037e8744 16287 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62 16288 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_KEY | N_I_ALL);
cb3b1e65
JB
16289 int imm = inst.operands[2].imm;
16290
16291 constraint (imm < 0 || (unsigned)imm >= et.size,
16292 _("immediate out of range for shift"));
88714cb8 16293 NEON_ENCODE (IMMED, inst);
cb3b1e65 16294 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
16295 }
16296 else
16297 {
037e8744 16298 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62 16299 struct neon_type_el et = neon_check_type (3, rs,
477330fc 16300 N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
627907b7
JB
16301 unsigned int tmp;
16302
16303 /* VSHL/VQSHL 3-register variants have syntax such as:
477330fc
RM
16304 vshl.xx Dd, Dm, Dn
16305 whereas other 3-register operations encoded by neon_three_same have
16306 syntax like:
16307 vadd.xx Dd, Dn, Dm
16308 (i.e. with Dn & Dm reversed). Swap operands[1].reg and operands[2].reg
16309 here. */
627907b7
JB
16310 tmp = inst.operands[2].reg;
16311 inst.operands[2].reg = inst.operands[1].reg;
16312 inst.operands[1].reg = tmp;
88714cb8 16313 NEON_ENCODE (INTEGER, inst);
037e8744 16314 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
16315 }
16316}
16317
16318static void
16319do_neon_qshl_imm (void)
16320{
16321 if (!inst.operands[2].isreg)
16322 {
037e8744 16323 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62 16324 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
cb3b1e65 16325 int imm = inst.operands[2].imm;
627907b7 16326
cb3b1e65
JB
16327 constraint (imm < 0 || (unsigned)imm >= et.size,
16328 _("immediate out of range for shift"));
88714cb8 16329 NEON_ENCODE (IMMED, inst);
cb3b1e65 16330 neon_imm_shift (TRUE, et.type == NT_unsigned, neon_quad (rs), et, imm);
5287ad62
JB
16331 }
16332 else
16333 {
037e8744 16334 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62 16335 struct neon_type_el et = neon_check_type (3, rs,
477330fc 16336 N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
627907b7
JB
16337 unsigned int tmp;
16338
16339 /* See note in do_neon_shl_imm. */
16340 tmp = inst.operands[2].reg;
16341 inst.operands[2].reg = inst.operands[1].reg;
16342 inst.operands[1].reg = tmp;
88714cb8 16343 NEON_ENCODE (INTEGER, inst);
037e8744 16344 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
16345 }
16346}
16347
627907b7
JB
16348static void
16349do_neon_rshl (void)
16350{
16351 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
16352 struct neon_type_el et = neon_check_type (3, rs,
16353 N_EQK, N_EQK, N_SU_ALL | N_KEY);
16354 unsigned int tmp;
16355
16356 tmp = inst.operands[2].reg;
16357 inst.operands[2].reg = inst.operands[1].reg;
16358 inst.operands[1].reg = tmp;
16359 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
16360}
16361
5287ad62
JB
16362static int
16363neon_cmode_for_logic_imm (unsigned immediate, unsigned *immbits, int size)
16364{
036dc3f7
PB
16365 /* Handle .I8 pseudo-instructions. */
16366 if (size == 8)
5287ad62 16367 {
5287ad62 16368 /* Unfortunately, this will make everything apart from zero out-of-range.
477330fc
RM
16369 FIXME is this the intended semantics? There doesn't seem much point in
16370 accepting .I8 if so. */
5287ad62
JB
16371 immediate |= immediate << 8;
16372 size = 16;
036dc3f7
PB
16373 }
16374
16375 if (size >= 32)
16376 {
16377 if (immediate == (immediate & 0x000000ff))
16378 {
16379 *immbits = immediate;
16380 return 0x1;
16381 }
16382 else if (immediate == (immediate & 0x0000ff00))
16383 {
16384 *immbits = immediate >> 8;
16385 return 0x3;
16386 }
16387 else if (immediate == (immediate & 0x00ff0000))
16388 {
16389 *immbits = immediate >> 16;
16390 return 0x5;
16391 }
16392 else if (immediate == (immediate & 0xff000000))
16393 {
16394 *immbits = immediate >> 24;
16395 return 0x7;
16396 }
16397 if ((immediate & 0xffff) != (immediate >> 16))
16398 goto bad_immediate;
16399 immediate &= 0xffff;
5287ad62
JB
16400 }
16401
16402 if (immediate == (immediate & 0x000000ff))
16403 {
16404 *immbits = immediate;
036dc3f7 16405 return 0x9;
5287ad62
JB
16406 }
16407 else if (immediate == (immediate & 0x0000ff00))
16408 {
16409 *immbits = immediate >> 8;
036dc3f7 16410 return 0xb;
5287ad62
JB
16411 }
16412
16413 bad_immediate:
dcbf9037 16414 first_error (_("immediate value out of range"));
5287ad62
JB
16415 return FAIL;
16416}
16417
5287ad62
JB
16418static void
16419do_neon_logic (void)
16420{
16421 if (inst.operands[2].present && inst.operands[2].isreg)
16422 {
037e8744 16423 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
f601a00c
AV
16424 if (rs == NS_QQQ
16425 && check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC)
16426 == FAIL)
16427 return;
16428 else if (rs != NS_QQQ
16429 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
16430 first_error (BAD_FPU);
16431
5287ad62
JB
16432 neon_check_type (3, rs, N_IGNORE_TYPE);
16433 /* U bit and size field were set as part of the bitmask. */
88714cb8 16434 NEON_ENCODE (INTEGER, inst);
037e8744 16435 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
16436 }
16437 else
16438 {
4316f0d2
DG
16439 const int three_ops_form = (inst.operands[2].present
16440 && !inst.operands[2].isreg);
16441 const int immoperand = (three_ops_form ? 2 : 1);
16442 enum neon_shape rs = (three_ops_form
16443 ? neon_select_shape (NS_DDI, NS_QQI, NS_NULL)
16444 : neon_select_shape (NS_DI, NS_QI, NS_NULL));
f601a00c
AV
16445 /* Because neon_select_shape makes the second operand a copy of the first
16446 if the second operand is not present. */
16447 if (rs == NS_QQI
16448 && check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC)
16449 == FAIL)
16450 return;
16451 else if (rs != NS_QQI
16452 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
16453 first_error (BAD_FPU);
16454
16455 struct neon_type_el et;
16456 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16457 et = neon_check_type (2, rs, N_I32 | N_I16 | N_KEY, N_EQK);
16458 else
16459 et = neon_check_type (2, rs, N_I8 | N_I16 | N_I32 | N_I64 | N_F32
16460 | N_KEY, N_EQK);
16461
16462 if (et.type == NT_invtype)
16463 return;
21d799b5 16464 enum neon_opc opcode = (enum neon_opc) inst.instruction & 0x0fffffff;
5287ad62
JB
16465 unsigned immbits;
16466 int cmode;
5f4273c7 16467
5f4273c7 16468
4316f0d2
DG
16469 if (three_ops_form)
16470 constraint (inst.operands[0].reg != inst.operands[1].reg,
16471 _("first and second operands shall be the same register"));
16472
88714cb8 16473 NEON_ENCODE (IMMED, inst);
5287ad62 16474
4316f0d2 16475 immbits = inst.operands[immoperand].imm;
036dc3f7
PB
16476 if (et.size == 64)
16477 {
16478 /* .i64 is a pseudo-op, so the immediate must be a repeating
16479 pattern. */
4316f0d2
DG
16480 if (immbits != (inst.operands[immoperand].regisimm ?
16481 inst.operands[immoperand].reg : 0))
036dc3f7
PB
16482 {
16483 /* Set immbits to an invalid constant. */
16484 immbits = 0xdeadbeef;
16485 }
16486 }
16487
5287ad62 16488 switch (opcode)
477330fc
RM
16489 {
16490 case N_MNEM_vbic:
16491 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
16492 break;
16493
16494 case N_MNEM_vorr:
16495 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
16496 break;
16497
16498 case N_MNEM_vand:
16499 /* Pseudo-instruction for VBIC. */
16500 neon_invert_size (&immbits, 0, et.size);
16501 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
16502 break;
16503
16504 case N_MNEM_vorn:
16505 /* Pseudo-instruction for VORR. */
16506 neon_invert_size (&immbits, 0, et.size);
16507 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
16508 break;
16509
16510 default:
16511 abort ();
16512 }
5287ad62
JB
16513
16514 if (cmode == FAIL)
477330fc 16515 return;
5287ad62 16516
037e8744 16517 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
16518 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16519 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16520 inst.instruction |= cmode << 8;
16521 neon_write_immbits (immbits);
5f4273c7 16522
88714cb8 16523 neon_dp_fixup (&inst);
5287ad62
JB
16524 }
16525}
16526
16527static void
16528do_neon_bitfield (void)
16529{
037e8744 16530 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
dcbf9037 16531 neon_check_type (3, rs, N_IGNORE_TYPE);
037e8744 16532 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
16533}
16534
16535static void
dcbf9037 16536neon_dyadic_misc (enum neon_el_type ubit_meaning, unsigned types,
477330fc 16537 unsigned destbits)
5287ad62 16538{
5ee91343 16539 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
dcbf9037 16540 struct neon_type_el et = neon_check_type (3, rs, N_EQK | destbits, N_EQK,
477330fc 16541 types | N_KEY);
5287ad62
JB
16542 if (et.type == NT_float)
16543 {
88714cb8 16544 NEON_ENCODE (FLOAT, inst);
5ee91343 16545 if (rs == NS_QQR)
7df54120 16546 mve_encode_qqr (et.size, 0, 1);
5ee91343
AV
16547 else
16548 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
16549 }
16550 else
16551 {
88714cb8 16552 NEON_ENCODE (INTEGER, inst);
5ee91343 16553 if (rs == NS_QQR)
a8465a06 16554 mve_encode_qqr (et.size, et.type == ubit_meaning, 0);
5ee91343
AV
16555 else
16556 neon_three_same (neon_quad (rs), et.type == ubit_meaning, et.size);
5287ad62
JB
16557 }
16558}
16559
5287ad62
JB
16560
16561static void
16562do_neon_dyadic_if_su_d (void)
16563{
16564 /* This version only allow D registers, but that constraint is enforced during
16565 operand parsing so we don't need to do anything extra here. */
dcbf9037 16566 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
5287ad62
JB
16567}
16568
5287ad62
JB
16569static void
16570do_neon_dyadic_if_i_d (void)
16571{
428e3f1f
PB
16572 /* The "untyped" case can't happen. Do this to stop the "U" bit being
16573 affected if we specify unsigned args. */
16574 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
5287ad62
JB
16575}
16576
f5f10c66
AV
16577static void
16578do_mve_vstr_vldr_QI (int size, int elsize, int load)
16579{
16580 constraint (size < 32, BAD_ADDR_MODE);
16581 constraint (size != elsize, BAD_EL_TYPE);
16582 constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
16583 constraint (!inst.operands[1].preind, BAD_ADDR_MODE);
16584 constraint (load && inst.operands[0].reg == inst.operands[1].reg,
16585 _("destination register and offset register may not be the"
16586 " same"));
16587
16588 int imm = inst.relocs[0].exp.X_add_number;
16589 int add = 1;
16590 if (imm < 0)
16591 {
16592 add = 0;
16593 imm = -imm;
16594 }
16595 constraint ((imm % (size / 8) != 0)
16596 || imm > (0x7f << neon_logbits (size)),
16597 (size == 32) ? _("immediate must be a multiple of 4 in the"
16598 " range of +/-[0,508]")
16599 : _("immediate must be a multiple of 8 in the"
16600 " range of +/-[0,1016]"));
16601 inst.instruction |= 0x11 << 24;
16602 inst.instruction |= add << 23;
16603 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16604 inst.instruction |= inst.operands[1].writeback << 21;
16605 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16606 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16607 inst.instruction |= 1 << 12;
16608 inst.instruction |= (size == 64) << 8;
16609 inst.instruction &= 0xffffff00;
16610 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16611 inst.instruction |= imm >> neon_logbits (size);
16612}
16613
16614static void
16615do_mve_vstr_vldr_RQ (int size, int elsize, int load)
16616{
16617 unsigned os = inst.operands[1].imm >> 5;
16618 constraint (os != 0 && size == 8,
16619 _("can not shift offsets when accessing less than half-word"));
16620 constraint (os && os != neon_logbits (size),
16621 _("shift immediate must be 1, 2 or 3 for half-word, word"
16622 " or double-word accesses respectively"));
16623 if (inst.operands[1].reg == REG_PC)
16624 as_tsktsk (MVE_BAD_PC);
16625
16626 switch (size)
16627 {
16628 case 8:
16629 constraint (elsize >= 64, BAD_EL_TYPE);
16630 break;
16631 case 16:
16632 constraint (elsize < 16 || elsize >= 64, BAD_EL_TYPE);
16633 break;
16634 case 32:
16635 case 64:
16636 constraint (elsize != size, BAD_EL_TYPE);
16637 break;
16638 default:
16639 break;
16640 }
16641 constraint (inst.operands[1].writeback || !inst.operands[1].preind,
16642 BAD_ADDR_MODE);
16643 if (load)
16644 {
16645 constraint (inst.operands[0].reg == (inst.operands[1].imm & 0x1f),
16646 _("destination register and offset register may not be"
16647 " the same"));
16648 constraint (size == elsize && inst.vectype.el[0].type != NT_unsigned,
16649 BAD_EL_TYPE);
16650 constraint (inst.vectype.el[0].type != NT_unsigned
16651 && inst.vectype.el[0].type != NT_signed, BAD_EL_TYPE);
16652 inst.instruction |= (inst.vectype.el[0].type == NT_unsigned) << 28;
16653 }
16654 else
16655 {
16656 constraint (inst.vectype.el[0].type != NT_untyped, BAD_EL_TYPE);
16657 }
16658
16659 inst.instruction |= 1 << 23;
16660 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16661 inst.instruction |= inst.operands[1].reg << 16;
16662 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16663 inst.instruction |= neon_logbits (elsize) << 7;
16664 inst.instruction |= HI1 (inst.operands[1].imm) << 5;
16665 inst.instruction |= LOW4 (inst.operands[1].imm);
16666 inst.instruction |= !!os;
16667}
16668
16669static void
16670do_mve_vstr_vldr_RI (int size, int elsize, int load)
16671{
16672 enum neon_el_type type = inst.vectype.el[0].type;
16673
16674 constraint (size >= 64, BAD_ADDR_MODE);
16675 switch (size)
16676 {
16677 case 16:
16678 constraint (elsize < 16 || elsize >= 64, BAD_EL_TYPE);
16679 break;
16680 case 32:
16681 constraint (elsize != size, BAD_EL_TYPE);
16682 break;
16683 default:
16684 break;
16685 }
16686 if (load)
16687 {
16688 constraint (elsize != size && type != NT_unsigned
16689 && type != NT_signed, BAD_EL_TYPE);
16690 }
16691 else
16692 {
16693 constraint (elsize != size && type != NT_untyped, BAD_EL_TYPE);
16694 }
16695
16696 int imm = inst.relocs[0].exp.X_add_number;
16697 int add = 1;
16698 if (imm < 0)
16699 {
16700 add = 0;
16701 imm = -imm;
16702 }
16703
16704 if ((imm % (size / 8) != 0) || imm > (0x7f << neon_logbits (size)))
16705 {
16706 switch (size)
16707 {
16708 case 8:
16709 constraint (1, _("immediate must be in the range of +/-[0,127]"));
16710 break;
16711 case 16:
16712 constraint (1, _("immediate must be a multiple of 2 in the"
16713 " range of +/-[0,254]"));
16714 break;
16715 case 32:
16716 constraint (1, _("immediate must be a multiple of 4 in the"
16717 " range of +/-[0,508]"));
16718 break;
16719 }
16720 }
16721
16722 if (size != elsize)
16723 {
16724 constraint (inst.operands[1].reg > 7, BAD_HIREG);
16725 constraint (inst.operands[0].reg > 14,
16726 _("MVE vector register in the range [Q0..Q7] expected"));
16727 inst.instruction |= (load && type == NT_unsigned) << 28;
16728 inst.instruction |= (size == 16) << 19;
16729 inst.instruction |= neon_logbits (elsize) << 7;
16730 }
16731 else
16732 {
16733 if (inst.operands[1].reg == REG_PC)
16734 as_tsktsk (MVE_BAD_PC);
16735 else if (inst.operands[1].reg == REG_SP && inst.operands[1].writeback)
16736 as_tsktsk (MVE_BAD_SP);
16737 inst.instruction |= 1 << 12;
16738 inst.instruction |= neon_logbits (size) << 7;
16739 }
16740 inst.instruction |= inst.operands[1].preind << 24;
16741 inst.instruction |= add << 23;
16742 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16743 inst.instruction |= inst.operands[1].writeback << 21;
16744 inst.instruction |= inst.operands[1].reg << 16;
16745 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16746 inst.instruction &= 0xffffff80;
16747 inst.instruction |= imm >> neon_logbits (size);
16748
16749}
16750
16751static void
16752do_mve_vstr_vldr (void)
16753{
16754 unsigned size;
16755 int load = 0;
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 switch (inst.instruction)
16763 {
16764 default:
16765 gas_assert (0);
16766 break;
16767 case M_MNEM_vldrb:
16768 load = 1;
16769 /* fall through. */
16770 case M_MNEM_vstrb:
16771 size = 8;
16772 break;
16773 case M_MNEM_vldrh:
16774 load = 1;
16775 /* fall through. */
16776 case M_MNEM_vstrh:
16777 size = 16;
16778 break;
16779 case M_MNEM_vldrw:
16780 load = 1;
16781 /* fall through. */
16782 case M_MNEM_vstrw:
16783 size = 32;
16784 break;
16785 case M_MNEM_vldrd:
16786 load = 1;
16787 /* fall through. */
16788 case M_MNEM_vstrd:
16789 size = 64;
16790 break;
16791 }
16792 unsigned elsize = inst.vectype.el[0].size;
16793
16794 if (inst.operands[1].isquad)
16795 {
16796 /* We are dealing with [Q, imm]{!} cases. */
16797 do_mve_vstr_vldr_QI (size, elsize, load);
16798 }
16799 else
16800 {
16801 if (inst.operands[1].immisreg == 2)
16802 {
16803 /* We are dealing with [R, Q, {UXTW #os}] cases. */
16804 do_mve_vstr_vldr_RQ (size, elsize, load);
16805 }
16806 else if (!inst.operands[1].immisreg)
16807 {
16808 /* We are dealing with [R, Imm]{!}/[R], Imm cases. */
16809 do_mve_vstr_vldr_RI (size, elsize, load);
16810 }
16811 else
16812 constraint (1, BAD_ADDR_MODE);
16813 }
16814
16815 inst.is_neon = 1;
16816}
16817
35c228db
AV
16818static void
16819do_mve_vst_vld (void)
16820{
16821 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16822 return;
16823
16824 constraint (!inst.operands[1].preind || inst.relocs[0].exp.X_add_symbol != 0
16825 || inst.relocs[0].exp.X_add_number != 0
16826 || inst.operands[1].immisreg != 0,
16827 BAD_ADDR_MODE);
16828 constraint (inst.vectype.el[0].size > 32, BAD_EL_TYPE);
16829 if (inst.operands[1].reg == REG_PC)
16830 as_tsktsk (MVE_BAD_PC);
16831 else if (inst.operands[1].reg == REG_SP && inst.operands[1].writeback)
16832 as_tsktsk (MVE_BAD_SP);
16833
16834
16835 /* These instructions are one of the "exceptions" mentioned in
16836 handle_pred_state. They are MVE instructions that are not VPT compatible
16837 and do not accept a VPT code, thus appending such a code is a syntax
16838 error. */
16839 if (inst.cond > COND_ALWAYS)
16840 first_error (BAD_SYNTAX);
16841 /* If we append a scalar condition code we can set this to
16842 MVE_OUTSIDE_PRED_INSN as it will also lead to a syntax error. */
16843 else if (inst.cond < COND_ALWAYS)
16844 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16845 else
16846 inst.pred_insn_type = MVE_UNPREDICABLE_INSN;
16847
16848 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16849 inst.instruction |= inst.operands[1].writeback << 21;
16850 inst.instruction |= inst.operands[1].reg << 16;
16851 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16852 inst.instruction |= neon_logbits (inst.vectype.el[0].size) << 7;
16853 inst.is_neon = 1;
16854}
16855
26c1e780
AV
16856static void
16857do_mve_vaddlv (void)
16858{
16859 enum neon_shape rs = neon_select_shape (NS_RRQ, NS_NULL);
16860 struct neon_type_el et
16861 = neon_check_type (3, rs, N_EQK, N_EQK, N_S32 | N_U32 | N_KEY);
16862
16863 if (et.type == NT_invtype)
16864 first_error (BAD_EL_TYPE);
16865
16866 if (inst.cond > COND_ALWAYS)
16867 inst.pred_insn_type = INSIDE_VPT_INSN;
16868 else
16869 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16870
16871 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
16872
16873 inst.instruction |= (et.type == NT_unsigned) << 28;
16874 inst.instruction |= inst.operands[1].reg << 19;
16875 inst.instruction |= inst.operands[0].reg << 12;
16876 inst.instruction |= inst.operands[2].reg;
16877 inst.is_neon = 1;
16878}
16879
5287ad62 16880static void
5ee91343 16881do_neon_dyadic_if_su (void)
5287ad62 16882{
5ee91343
AV
16883 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
16884 struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
16885 N_SUF_32 | N_KEY);
16886
935295b5
AV
16887 constraint ((inst.instruction == ((unsigned) N_MNEM_vmax)
16888 || inst.instruction == ((unsigned) N_MNEM_vmin))
16889 && et.type == NT_float
16890 && !ARM_CPU_HAS_FEATURE (cpu_variant,fpu_neon_ext_v1), BAD_FPU);
16891
5ee91343
AV
16892 if (check_simd_pred_availability (et.type == NT_float,
16893 NEON_CHECK_ARCH | NEON_CHECK_CC))
037e8744
JB
16894 return;
16895
5ee91343
AV
16896 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
16897}
16898
16899static void
16900do_neon_addsub_if_i (void)
16901{
16902 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
16903 && try_vfp_nsyn (3, do_vfp_nsyn_add_sub) == SUCCESS)
037e8744
JB
16904 return;
16905
5ee91343
AV
16906 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
16907 struct neon_type_el et = neon_check_type (3, rs, N_EQK,
16908 N_EQK, N_IF_32 | N_I64 | N_KEY);
16909
16910 constraint (rs == NS_QQR && et.size == 64, BAD_FPU);
16911 /* If we are parsing Q registers and the element types match MVE, which NEON
16912 also supports, then we must check whether this is an instruction that can
16913 be used by both MVE/NEON. This distinction can be made based on whether
16914 they are predicated or not. */
16915 if ((rs == NS_QQQ || rs == NS_QQR) && et.size != 64)
16916 {
16917 if (check_simd_pred_availability (et.type == NT_float,
16918 NEON_CHECK_ARCH | NEON_CHECK_CC))
16919 return;
16920 }
16921 else
16922 {
16923 /* If they are either in a D register or are using an unsupported. */
16924 if (rs != NS_QQR
16925 && vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
16926 return;
16927 }
16928
5287ad62
JB
16929 /* The "untyped" case can't happen. Do this to stop the "U" bit being
16930 affected if we specify unsigned args. */
dcbf9037 16931 neon_dyadic_misc (NT_untyped, N_IF_32 | N_I64, 0);
5287ad62
JB
16932}
16933
16934/* Swaps operands 1 and 2. If operand 1 (optional arg) was omitted, we want the
16935 result to be:
16936 V<op> A,B (A is operand 0, B is operand 2)
16937 to mean:
16938 V<op> A,B,A
16939 not:
16940 V<op> A,B,B
16941 so handle that case specially. */
16942
16943static void
16944neon_exchange_operands (void)
16945{
5287ad62
JB
16946 if (inst.operands[1].present)
16947 {
e1fa0163
NC
16948 void *scratch = xmalloc (sizeof (inst.operands[0]));
16949
5287ad62
JB
16950 /* Swap operands[1] and operands[2]. */
16951 memcpy (scratch, &inst.operands[1], sizeof (inst.operands[0]));
16952 inst.operands[1] = inst.operands[2];
16953 memcpy (&inst.operands[2], scratch, sizeof (inst.operands[0]));
e1fa0163 16954 free (scratch);
5287ad62
JB
16955 }
16956 else
16957 {
16958 inst.operands[1] = inst.operands[2];
16959 inst.operands[2] = inst.operands[0];
16960 }
16961}
16962
16963static void
16964neon_compare (unsigned regtypes, unsigned immtypes, int invert)
16965{
16966 if (inst.operands[2].isreg)
16967 {
16968 if (invert)
477330fc 16969 neon_exchange_operands ();
dcbf9037 16970 neon_dyadic_misc (NT_unsigned, regtypes, N_SIZ);
5287ad62
JB
16971 }
16972 else
16973 {
037e8744 16974 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
dcbf9037 16975 struct neon_type_el et = neon_check_type (2, rs,
477330fc 16976 N_EQK | N_SIZ, immtypes | N_KEY);
5287ad62 16977
88714cb8 16978 NEON_ENCODE (IMMED, inst);
5287ad62
JB
16979 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16980 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16981 inst.instruction |= LOW4 (inst.operands[1].reg);
16982 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 16983 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
16984 inst.instruction |= (et.type == NT_float) << 10;
16985 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 16986
88714cb8 16987 neon_dp_fixup (&inst);
5287ad62
JB
16988 }
16989}
16990
16991static void
16992do_neon_cmp (void)
16993{
cc933301 16994 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, FALSE);
5287ad62
JB
16995}
16996
16997static void
16998do_neon_cmp_inv (void)
16999{
cc933301 17000 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, TRUE);
5287ad62
JB
17001}
17002
17003static void
17004do_neon_ceq (void)
17005{
17006 neon_compare (N_IF_32, N_IF_32, FALSE);
17007}
17008
17009/* For multiply instructions, we have the possibility of 16-bit or 32-bit
17010 scalars, which are encoded in 5 bits, M : Rm.
17011 For 16-bit scalars, the register is encoded in Rm[2:0] and the index in
17012 M:Rm[3], and for 32-bit scalars, the register is encoded in Rm[3:0] and the
c604a79a
JW
17013 index in M.
17014
17015 Dot Product instructions are similar to multiply instructions except elsize
17016 should always be 32.
17017
17018 This function translates SCALAR, which is GAS's internal encoding of indexed
17019 scalar register, to raw encoding. There is also register and index range
17020 check based on ELSIZE. */
5287ad62
JB
17021
17022static unsigned
17023neon_scalar_for_mul (unsigned scalar, unsigned elsize)
17024{
dcbf9037
JB
17025 unsigned regno = NEON_SCALAR_REG (scalar);
17026 unsigned elno = NEON_SCALAR_INDEX (scalar);
5287ad62
JB
17027
17028 switch (elsize)
17029 {
17030 case 16:
17031 if (regno > 7 || elno > 3)
477330fc 17032 goto bad_scalar;
5287ad62 17033 return regno | (elno << 3);
5f4273c7 17034
5287ad62
JB
17035 case 32:
17036 if (regno > 15 || elno > 1)
477330fc 17037 goto bad_scalar;
5287ad62
JB
17038 return regno | (elno << 4);
17039
17040 default:
17041 bad_scalar:
dcbf9037 17042 first_error (_("scalar out of range for multiply instruction"));
5287ad62
JB
17043 }
17044
17045 return 0;
17046}
17047
17048/* Encode multiply / multiply-accumulate scalar instructions. */
17049
17050static void
17051neon_mul_mac (struct neon_type_el et, int ubit)
17052{
dcbf9037
JB
17053 unsigned scalar;
17054
17055 /* Give a more helpful error message if we have an invalid type. */
17056 if (et.type == NT_invtype)
17057 return;
5f4273c7 17058
dcbf9037 17059 scalar = neon_scalar_for_mul (inst.operands[2].reg, et.size);
5287ad62
JB
17060 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17061 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17062 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17063 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
17064 inst.instruction |= LOW4 (scalar);
17065 inst.instruction |= HI1 (scalar) << 5;
17066 inst.instruction |= (et.type == NT_float) << 8;
17067 inst.instruction |= neon_logbits (et.size) << 20;
17068 inst.instruction |= (ubit != 0) << 24;
17069
88714cb8 17070 neon_dp_fixup (&inst);
5287ad62
JB
17071}
17072
17073static void
17074do_neon_mac_maybe_scalar (void)
17075{
037e8744
JB
17076 if (try_vfp_nsyn (3, do_vfp_nsyn_mla_mls) == SUCCESS)
17077 return;
17078
a8465a06 17079 if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
037e8744
JB
17080 return;
17081
5287ad62
JB
17082 if (inst.operands[2].isscalar)
17083 {
a8465a06 17084 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
037e8744 17085 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 17086 struct neon_type_el et = neon_check_type (3, rs,
589a7d88 17087 N_EQK, N_EQK, N_I16 | N_I32 | N_F_16_32 | N_KEY);
88714cb8 17088 NEON_ENCODE (SCALAR, inst);
037e8744 17089 neon_mul_mac (et, neon_quad (rs));
5287ad62 17090 }
a8465a06
AV
17091 else if (!inst.operands[2].isvec)
17092 {
17093 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
17094
17095 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
17096 neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
17097
17098 neon_dyadic_misc (NT_unsigned, N_SU_MVE, 0);
17099 }
5287ad62 17100 else
428e3f1f 17101 {
a8465a06 17102 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
428e3f1f
PB
17103 /* The "untyped" case can't happen. Do this to stop the "U" bit being
17104 affected if we specify unsigned args. */
17105 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
17106 }
5287ad62
JB
17107}
17108
62f3b8c8
PB
17109static void
17110do_neon_fmac (void)
17111{
d58196e0
AV
17112 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_fma)
17113 && try_vfp_nsyn (3, do_vfp_nsyn_fma_fms) == SUCCESS)
62f3b8c8
PB
17114 return;
17115
d58196e0 17116 if (check_simd_pred_availability (1, NEON_CHECK_CC | NEON_CHECK_ARCH))
62f3b8c8
PB
17117 return;
17118
d58196e0
AV
17119 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
17120 {
17121 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
17122 struct neon_type_el et = neon_check_type (3, rs, N_F_MVE | N_KEY, N_EQK,
17123 N_EQK);
17124
17125 if (rs == NS_QQR)
17126 {
17127 if (inst.operands[2].reg == REG_SP)
17128 as_tsktsk (MVE_BAD_SP);
17129 else if (inst.operands[2].reg == REG_PC)
17130 as_tsktsk (MVE_BAD_PC);
17131
17132 inst.instruction = 0xee310e40;
17133 inst.instruction |= (et.size == 16) << 28;
17134 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17135 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17136 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17137 inst.instruction |= HI1 (inst.operands[1].reg) << 6;
17138 inst.instruction |= inst.operands[2].reg;
17139 inst.is_neon = 1;
17140 return;
17141 }
17142 }
17143 else
17144 {
17145 constraint (!inst.operands[2].isvec, BAD_FPU);
17146 }
17147
62f3b8c8
PB
17148 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
17149}
17150
5287ad62
JB
17151static void
17152do_neon_tst (void)
17153{
037e8744 17154 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
17155 struct neon_type_el et = neon_check_type (3, rs,
17156 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_KEY);
037e8744 17157 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
17158}
17159
17160/* VMUL with 3 registers allows the P8 type. The scalar version supports the
17161 same types as the MAC equivalents. The polynomial type for this instruction
17162 is encoded the same as the integer type. */
17163
17164static void
17165do_neon_mul (void)
17166{
037e8744
JB
17167 if (try_vfp_nsyn (3, do_vfp_nsyn_mul) == SUCCESS)
17168 return;
17169
a8465a06 17170 if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
037e8744
JB
17171 return;
17172
5287ad62 17173 if (inst.operands[2].isscalar)
a8465a06
AV
17174 {
17175 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
17176 do_neon_mac_maybe_scalar ();
17177 }
5287ad62 17178 else
a8465a06
AV
17179 {
17180 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17181 {
17182 enum neon_shape rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
17183 struct neon_type_el et
17184 = neon_check_type (3, rs, N_EQK, N_EQK, N_I_MVE | N_F_MVE | N_KEY);
17185 if (et.type == NT_float)
17186 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
17187 BAD_FPU);
17188
17189 neon_dyadic_misc (NT_float, N_I_MVE | N_F_MVE, 0);
17190 }
17191 else
17192 {
17193 constraint (!inst.operands[2].isvec, BAD_FPU);
17194 neon_dyadic_misc (NT_poly,
17195 N_I8 | N_I16 | N_I32 | N_F16 | N_F32 | N_P8, 0);
17196 }
17197 }
5287ad62
JB
17198}
17199
17200static void
17201do_neon_qdmulh (void)
17202{
42b16635
AV
17203 if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
17204 return;
17205
5287ad62
JB
17206 if (inst.operands[2].isscalar)
17207 {
42b16635 17208 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
037e8744 17209 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 17210 struct neon_type_el et = neon_check_type (3, rs,
477330fc 17211 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
88714cb8 17212 NEON_ENCODE (SCALAR, inst);
037e8744 17213 neon_mul_mac (et, neon_quad (rs));
5287ad62
JB
17214 }
17215 else
17216 {
42b16635
AV
17217 enum neon_shape rs;
17218 struct neon_type_el et;
17219 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17220 {
17221 rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
17222 et = neon_check_type (3, rs,
17223 N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
17224 }
17225 else
17226 {
17227 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17228 et = neon_check_type (3, rs,
17229 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
17230 }
17231
88714cb8 17232 NEON_ENCODE (INTEGER, inst);
42b16635
AV
17233 if (rs == NS_QQR)
17234 mve_encode_qqr (et.size, 0, 0);
17235 else
17236 /* The U bit (rounding) comes from bit mask. */
17237 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
17238 }
17239}
17240
26c1e780
AV
17241static void
17242do_mve_vaddv (void)
17243{
17244 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
17245 struct neon_type_el et
17246 = neon_check_type (2, rs, N_EQK, N_SU_32 | N_KEY);
17247
17248 if (et.type == NT_invtype)
17249 first_error (BAD_EL_TYPE);
17250
17251 if (inst.cond > COND_ALWAYS)
17252 inst.pred_insn_type = INSIDE_VPT_INSN;
17253 else
17254 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17255
17256 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
17257
17258 mve_encode_rq (et.type == NT_unsigned, et.size);
17259}
17260
7df54120
AV
17261static void
17262do_mve_vhcadd (void)
17263{
17264 enum neon_shape rs = neon_select_shape (NS_QQQI, NS_NULL);
17265 struct neon_type_el et
17266 = neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
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 unsigned rot = inst.relocs[0].exp.X_add_number;
17274 constraint (rot != 90 && rot != 270, _("immediate out of range"));
17275
17276 if (et.size == 32 && inst.operands[0].reg == inst.operands[2].reg)
17277 as_tsktsk (_("Warning: 32-bit element size and same first and third "
17278 "operand makes instruction UNPREDICTABLE"));
17279
17280 mve_encode_qqq (0, et.size);
17281 inst.instruction |= (rot == 270) << 12;
17282 inst.is_neon = 1;
17283}
17284
c2dafc2a
AV
17285static void
17286do_mve_vadc (void)
17287{
17288 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
17289 struct neon_type_el et
17290 = neon_check_type (3, rs, N_KEY | N_I32, N_EQK, N_EQK);
17291
17292 if (et.type == NT_invtype)
17293 first_error (BAD_EL_TYPE);
17294
17295 if (inst.cond > COND_ALWAYS)
17296 inst.pred_insn_type = INSIDE_VPT_INSN;
17297 else
17298 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17299
17300 mve_encode_qqq (0, 64);
17301}
17302
17303static void
17304do_mve_vbrsr (void)
17305{
17306 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
17307 struct neon_type_el et
17308 = neon_check_type (3, rs, N_EQK, N_EQK, N_8 | N_16 | N_32 | N_KEY);
17309
17310 if (inst.cond > COND_ALWAYS)
17311 inst.pred_insn_type = INSIDE_VPT_INSN;
17312 else
17313 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17314
7df54120 17315 mve_encode_qqr (et.size, 0, 0);
c2dafc2a
AV
17316}
17317
17318static void
17319do_mve_vsbc (void)
17320{
17321 neon_check_type (3, NS_QQQ, N_EQK, N_EQK, N_I32 | N_KEY);
17322
17323 if (inst.cond > COND_ALWAYS)
17324 inst.pred_insn_type = INSIDE_VPT_INSN;
17325 else
17326 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17327
17328 mve_encode_qqq (1, 64);
17329}
17330
2d78f95b
AV
17331static void
17332do_mve_vmulh (void)
17333{
17334 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
17335 struct neon_type_el et
17336 = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
17337
17338 if (inst.cond > COND_ALWAYS)
17339 inst.pred_insn_type = INSIDE_VPT_INSN;
17340 else
17341 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17342
17343 mve_encode_qqq (et.type == NT_unsigned, et.size);
17344}
17345
42b16635
AV
17346static void
17347do_mve_vqdmlah (void)
17348{
17349 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
17350 struct neon_type_el et
17351 = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
17352
17353 if (inst.cond > COND_ALWAYS)
17354 inst.pred_insn_type = INSIDE_VPT_INSN;
17355 else
17356 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17357
17358 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
17359}
8b8b22a4
AV
17360
17361static void
17362do_mve_vqdmladh (void)
17363{
17364 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
17365 struct neon_type_el et
17366 = neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
17367
17368 if (inst.cond > COND_ALWAYS)
17369 inst.pred_insn_type = INSIDE_VPT_INSN;
17370 else
17371 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17372
17373 if (et.size == 32
17374 && (inst.operands[0].reg == inst.operands[1].reg
17375 || inst.operands[0].reg == inst.operands[2].reg))
17376 as_tsktsk (BAD_MVE_SRCDEST);
17377
17378 mve_encode_qqq (0, et.size);
17379}
17380
17381
886e1c73
AV
17382static void
17383do_mve_vmull (void)
17384{
17385
17386 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_DDS,
17387 NS_QQS, NS_QQQ, NS_QQR, NS_NULL);
17388 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
17389 && inst.cond == COND_ALWAYS
17390 && ((unsigned)inst.instruction) == M_MNEM_vmullt)
17391 {
17392 if (rs == NS_QQQ)
17393 {
17394
17395 struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
17396 N_SUF_32 | N_F64 | N_P8
17397 | N_P16 | N_I_MVE | N_KEY);
17398 if (((et.type == NT_poly) && et.size == 8
17399 && ARM_CPU_IS_ANY (cpu_variant))
17400 || (et.type == NT_integer) || (et.type == NT_float))
17401 goto neon_vmul;
17402 }
17403 else
17404 goto neon_vmul;
17405 }
17406
17407 constraint (rs != NS_QQQ, BAD_FPU);
17408 struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
17409 N_SU_32 | N_P8 | N_P16 | N_KEY);
17410
17411 /* We are dealing with MVE's vmullt. */
17412 if (et.size == 32
17413 && (inst.operands[0].reg == inst.operands[1].reg
17414 || inst.operands[0].reg == inst.operands[2].reg))
17415 as_tsktsk (BAD_MVE_SRCDEST);
17416
17417 if (inst.cond > COND_ALWAYS)
17418 inst.pred_insn_type = INSIDE_VPT_INSN;
17419 else
17420 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17421
17422 if (et.type == NT_poly)
17423 mve_encode_qqq (neon_logbits (et.size), 64);
17424 else
17425 mve_encode_qqq (et.type == NT_unsigned, et.size);
17426
17427 return;
17428
17429neon_vmul:
17430 inst.instruction = N_MNEM_vmul;
17431 inst.cond = 0xb;
17432 if (thumb_mode)
17433 inst.pred_insn_type = INSIDE_IT_INSN;
17434 do_neon_mul ();
17435}
17436
a302e574
AV
17437static void
17438do_mve_vabav (void)
17439{
17440 enum neon_shape rs = neon_select_shape (NS_RQQ, NS_NULL);
17441
17442 if (rs == NS_NULL)
17443 return;
17444
17445 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17446 return;
17447
17448 struct neon_type_el et = neon_check_type (2, NS_NULL, N_EQK, N_KEY | N_S8
17449 | N_S16 | N_S32 | N_U8 | N_U16
17450 | N_U32);
17451
17452 if (inst.cond > COND_ALWAYS)
17453 inst.pred_insn_type = INSIDE_VPT_INSN;
17454 else
17455 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17456
17457 mve_encode_rqq (et.type == NT_unsigned, et.size);
17458}
17459
17460static void
17461do_mve_vmladav (void)
17462{
17463 enum neon_shape rs = neon_select_shape (NS_RQQ, NS_NULL);
17464 struct neon_type_el et = neon_check_type (3, rs,
17465 N_EQK, N_EQK, N_SU_MVE | N_KEY);
17466
17467 if (et.type == NT_unsigned
17468 && (inst.instruction == M_MNEM_vmladavx
17469 || inst.instruction == M_MNEM_vmladavax
17470 || inst.instruction == M_MNEM_vmlsdav
17471 || inst.instruction == M_MNEM_vmlsdava
17472 || inst.instruction == M_MNEM_vmlsdavx
17473 || inst.instruction == M_MNEM_vmlsdavax))
17474 first_error (BAD_SIMD_TYPE);
17475
17476 constraint (inst.operands[2].reg > 14,
17477 _("MVE vector register in the range [Q0..Q7] expected"));
17478
17479 if (inst.cond > COND_ALWAYS)
17480 inst.pred_insn_type = INSIDE_VPT_INSN;
17481 else
17482 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17483
17484 if (inst.instruction == M_MNEM_vmlsdav
17485 || inst.instruction == M_MNEM_vmlsdava
17486 || inst.instruction == M_MNEM_vmlsdavx
17487 || inst.instruction == M_MNEM_vmlsdavax)
17488 inst.instruction |= (et.size == 8) << 28;
17489 else
17490 inst.instruction |= (et.size == 8) << 8;
17491
17492 mve_encode_rqq (et.type == NT_unsigned, 64);
17493 inst.instruction |= (et.size == 32) << 16;
17494}
17495
93925576
AV
17496static void
17497do_mve_vmlaldav (void)
17498{
17499 enum neon_shape rs = neon_select_shape (NS_RRQQ, NS_NULL);
17500 struct neon_type_el et
17501 = neon_check_type (4, rs, N_EQK, N_EQK, N_EQK,
17502 N_S16 | N_S32 | N_U16 | N_U32 | N_KEY);
17503
17504 if (et.type == NT_unsigned
17505 && (inst.instruction == M_MNEM_vmlsldav
17506 || inst.instruction == M_MNEM_vmlsldava
17507 || inst.instruction == M_MNEM_vmlsldavx
17508 || inst.instruction == M_MNEM_vmlsldavax))
17509 first_error (BAD_SIMD_TYPE);
17510
17511 if (inst.cond > COND_ALWAYS)
17512 inst.pred_insn_type = INSIDE_VPT_INSN;
17513 else
17514 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17515
17516 mve_encode_rrqq (et.type == NT_unsigned, et.size);
17517}
17518
17519static void
17520do_mve_vrmlaldavh (void)
17521{
17522 struct neon_type_el et;
17523 if (inst.instruction == M_MNEM_vrmlsldavh
17524 || inst.instruction == M_MNEM_vrmlsldavha
17525 || inst.instruction == M_MNEM_vrmlsldavhx
17526 || inst.instruction == M_MNEM_vrmlsldavhax)
17527 {
17528 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK, N_S32 | N_KEY);
17529 if (inst.operands[1].reg == REG_SP)
17530 as_tsktsk (MVE_BAD_SP);
17531 }
17532 else
17533 {
17534 if (inst.instruction == M_MNEM_vrmlaldavhx
17535 || inst.instruction == M_MNEM_vrmlaldavhax)
17536 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK, N_S32 | N_KEY);
17537 else
17538 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK,
17539 N_U32 | N_S32 | N_KEY);
17540 /* vrmlaldavh's encoding with SP as the second, odd, GPR operand may alias
17541 with vmax/min instructions, making the use of SP in assembly really
17542 nonsensical, so instead of issuing a warning like we do for other uses
17543 of SP for the odd register operand we error out. */
17544 constraint (inst.operands[1].reg == REG_SP, BAD_SP);
17545 }
17546
17547 /* Make sure we still check the second operand is an odd one and that PC is
17548 disallowed. This because we are parsing for any GPR operand, to be able
17549 to distinguish between giving a warning or an error for SP as described
17550 above. */
17551 constraint ((inst.operands[1].reg % 2) != 1, BAD_EVEN);
17552 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
17553
17554 if (inst.cond > COND_ALWAYS)
17555 inst.pred_insn_type = INSIDE_VPT_INSN;
17556 else
17557 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17558
17559 mve_encode_rrqq (et.type == NT_unsigned, 0);
17560}
17561
17562
8cd78170
AV
17563static void
17564do_mve_vmaxnmv (void)
17565{
17566 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
17567 struct neon_type_el et
17568 = neon_check_type (2, rs, N_EQK, N_F_MVE | N_KEY);
17569
17570 if (inst.cond > COND_ALWAYS)
17571 inst.pred_insn_type = INSIDE_VPT_INSN;
17572 else
17573 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17574
17575 if (inst.operands[0].reg == REG_SP)
17576 as_tsktsk (MVE_BAD_SP);
17577 else if (inst.operands[0].reg == REG_PC)
17578 as_tsktsk (MVE_BAD_PC);
17579
17580 mve_encode_rq (et.size == 16, 64);
17581}
17582
13ccd4c0
AV
17583static void
17584do_mve_vmaxv (void)
17585{
17586 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
17587 struct neon_type_el et;
17588
17589 if (inst.instruction == M_MNEM_vmaxv || inst.instruction == M_MNEM_vminv)
17590 et = neon_check_type (2, rs, N_EQK, N_SU_MVE | N_KEY);
17591 else
17592 et = neon_check_type (2, rs, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
17593
17594 if (inst.cond > COND_ALWAYS)
17595 inst.pred_insn_type = INSIDE_VPT_INSN;
17596 else
17597 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17598
17599 if (inst.operands[0].reg == REG_SP)
17600 as_tsktsk (MVE_BAD_SP);
17601 else if (inst.operands[0].reg == REG_PC)
17602 as_tsktsk (MVE_BAD_PC);
17603
17604 mve_encode_rq (et.type == NT_unsigned, et.size);
17605}
17606
17607
643afb90
MW
17608static void
17609do_neon_qrdmlah (void)
17610{
42b16635
AV
17611 if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
17612 return;
17613 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
643afb90 17614 {
42b16635
AV
17615 /* Check we're on the correct architecture. */
17616 if (!mark_feature_used (&fpu_neon_ext_armv8))
17617 inst.error
17618 = _("instruction form not available on this architecture.");
17619 else if (!mark_feature_used (&fpu_neon_ext_v8_1))
17620 {
17621 as_warn (_("this instruction implies use of ARMv8.1 AdvSIMD."));
17622 record_feature_use (&fpu_neon_ext_v8_1);
17623 }
17624 if (inst.operands[2].isscalar)
17625 {
17626 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
17627 struct neon_type_el et = neon_check_type (3, rs,
17628 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
17629 NEON_ENCODE (SCALAR, inst);
17630 neon_mul_mac (et, neon_quad (rs));
17631 }
17632 else
17633 {
17634 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17635 struct neon_type_el et = neon_check_type (3, rs,
17636 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
17637 NEON_ENCODE (INTEGER, inst);
17638 /* The U bit (rounding) comes from bit mask. */
17639 neon_three_same (neon_quad (rs), 0, et.size);
17640 }
643afb90
MW
17641 }
17642 else
17643 {
42b16635
AV
17644 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
17645 struct neon_type_el et
17646 = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
17647
643afb90 17648 NEON_ENCODE (INTEGER, inst);
42b16635 17649 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
643afb90
MW
17650 }
17651}
17652
5287ad62
JB
17653static void
17654do_neon_fcmp_absolute (void)
17655{
037e8744 17656 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
17657 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
17658 N_F_16_32 | N_KEY);
5287ad62 17659 /* Size field comes from bit mask. */
cc933301 17660 neon_three_same (neon_quad (rs), 1, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
17661}
17662
17663static void
17664do_neon_fcmp_absolute_inv (void)
17665{
17666 neon_exchange_operands ();
17667 do_neon_fcmp_absolute ();
17668}
17669
17670static void
17671do_neon_step (void)
17672{
037e8744 17673 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
17674 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
17675 N_F_16_32 | N_KEY);
17676 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
17677}
17678
17679static void
17680do_neon_abs_neg (void)
17681{
037e8744
JB
17682 enum neon_shape rs;
17683 struct neon_type_el et;
5f4273c7 17684
037e8744
JB
17685 if (try_vfp_nsyn (2, do_vfp_nsyn_abs_neg) == SUCCESS)
17686 return;
17687
037e8744 17688 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
cc933301 17689 et = neon_check_type (2, rs, N_EQK, N_S_32 | N_F_16_32 | N_KEY);
5f4273c7 17690
485dee97
AV
17691 if (check_simd_pred_availability (et.type == NT_float,
17692 NEON_CHECK_ARCH | NEON_CHECK_CC))
17693 return;
17694
5287ad62
JB
17695 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17696 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17697 inst.instruction |= LOW4 (inst.operands[1].reg);
17698 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 17699 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
17700 inst.instruction |= (et.type == NT_float) << 10;
17701 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 17702
88714cb8 17703 neon_dp_fixup (&inst);
5287ad62
JB
17704}
17705
17706static void
17707do_neon_sli (void)
17708{
037e8744 17709 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
17710 struct neon_type_el et = neon_check_type (2, rs,
17711 N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
17712 int imm = inst.operands[2].imm;
17713 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 17714 _("immediate out of range for insert"));
037e8744 17715 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
17716}
17717
17718static void
17719do_neon_sri (void)
17720{
037e8744 17721 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
17722 struct neon_type_el et = neon_check_type (2, rs,
17723 N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
17724 int imm = inst.operands[2].imm;
17725 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 17726 _("immediate out of range for insert"));
037e8744 17727 neon_imm_shift (FALSE, 0, neon_quad (rs), et, et.size - imm);
5287ad62
JB
17728}
17729
17730static void
17731do_neon_qshlu_imm (void)
17732{
037e8744 17733 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
17734 struct neon_type_el et = neon_check_type (2, rs,
17735 N_EQK | N_UNS, N_S8 | N_S16 | N_S32 | N_S64 | N_KEY);
17736 int imm = inst.operands[2].imm;
17737 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 17738 _("immediate out of range for shift"));
5287ad62
JB
17739 /* Only encodes the 'U present' variant of the instruction.
17740 In this case, signed types have OP (bit 8) set to 0.
17741 Unsigned types have OP set to 1. */
17742 inst.instruction |= (et.type == NT_unsigned) << 8;
17743 /* The rest of the bits are the same as other immediate shifts. */
037e8744 17744 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
17745}
17746
17747static void
17748do_neon_qmovn (void)
17749{
17750 struct neon_type_el et = neon_check_type (2, NS_DQ,
17751 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
17752 /* Saturating move where operands can be signed or unsigned, and the
17753 destination has the same signedness. */
88714cb8 17754 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
17755 if (et.type == NT_unsigned)
17756 inst.instruction |= 0xc0;
17757 else
17758 inst.instruction |= 0x80;
17759 neon_two_same (0, 1, et.size / 2);
17760}
17761
17762static void
17763do_neon_qmovun (void)
17764{
17765 struct neon_type_el et = neon_check_type (2, NS_DQ,
17766 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
17767 /* Saturating move with unsigned results. Operands must be signed. */
88714cb8 17768 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
17769 neon_two_same (0, 1, et.size / 2);
17770}
17771
17772static void
17773do_neon_rshift_sat_narrow (void)
17774{
17775 /* FIXME: Types for narrowing. If operands are signed, results can be signed
17776 or unsigned. If operands are unsigned, results must also be unsigned. */
17777 struct neon_type_el et = neon_check_type (2, NS_DQI,
17778 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
17779 int imm = inst.operands[2].imm;
17780 /* This gets the bounds check, size encoding and immediate bits calculation
17781 right. */
17782 et.size /= 2;
5f4273c7 17783
5287ad62
JB
17784 /* VQ{R}SHRN.I<size> <Dd>, <Qm>, #0 is a synonym for
17785 VQMOVN.I<size> <Dd>, <Qm>. */
17786 if (imm == 0)
17787 {
17788 inst.operands[2].present = 0;
17789 inst.instruction = N_MNEM_vqmovn;
17790 do_neon_qmovn ();
17791 return;
17792 }
5f4273c7 17793
5287ad62 17794 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 17795 _("immediate out of range"));
5287ad62
JB
17796 neon_imm_shift (TRUE, et.type == NT_unsigned, 0, et, et.size - imm);
17797}
17798
17799static void
17800do_neon_rshift_sat_narrow_u (void)
17801{
17802 /* FIXME: Types for narrowing. If operands are signed, results can be signed
17803 or unsigned. If operands are unsigned, results must also be unsigned. */
17804 struct neon_type_el et = neon_check_type (2, NS_DQI,
17805 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
17806 int imm = inst.operands[2].imm;
17807 /* This gets the bounds check, size encoding and immediate bits calculation
17808 right. */
17809 et.size /= 2;
17810
17811 /* VQSHRUN.I<size> <Dd>, <Qm>, #0 is a synonym for
17812 VQMOVUN.I<size> <Dd>, <Qm>. */
17813 if (imm == 0)
17814 {
17815 inst.operands[2].present = 0;
17816 inst.instruction = N_MNEM_vqmovun;
17817 do_neon_qmovun ();
17818 return;
17819 }
17820
17821 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 17822 _("immediate out of range"));
5287ad62
JB
17823 /* FIXME: The manual is kind of unclear about what value U should have in
17824 VQ{R}SHRUN instructions, but U=0, op=0 definitely encodes VRSHR, so it
17825 must be 1. */
17826 neon_imm_shift (TRUE, 1, 0, et, et.size - imm);
17827}
17828
17829static void
17830do_neon_movn (void)
17831{
17832 struct neon_type_el et = neon_check_type (2, NS_DQ,
17833 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
88714cb8 17834 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
17835 neon_two_same (0, 1, et.size / 2);
17836}
17837
17838static void
17839do_neon_rshift_narrow (void)
17840{
17841 struct neon_type_el et = neon_check_type (2, NS_DQI,
17842 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
17843 int imm = inst.operands[2].imm;
17844 /* This gets the bounds check, size encoding and immediate bits calculation
17845 right. */
17846 et.size /= 2;
5f4273c7 17847
5287ad62
JB
17848 /* If immediate is zero then we are a pseudo-instruction for
17849 VMOVN.I<size> <Dd>, <Qm> */
17850 if (imm == 0)
17851 {
17852 inst.operands[2].present = 0;
17853 inst.instruction = N_MNEM_vmovn;
17854 do_neon_movn ();
17855 return;
17856 }
5f4273c7 17857
5287ad62 17858 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 17859 _("immediate out of range for narrowing operation"));
5287ad62
JB
17860 neon_imm_shift (FALSE, 0, 0, et, et.size - imm);
17861}
17862
17863static void
17864do_neon_shll (void)
17865{
17866 /* FIXME: Type checking when lengthening. */
17867 struct neon_type_el et = neon_check_type (2, NS_QDI,
17868 N_EQK | N_DBL, N_I8 | N_I16 | N_I32 | N_KEY);
17869 unsigned imm = inst.operands[2].imm;
17870
17871 if (imm == et.size)
17872 {
17873 /* Maximum shift variant. */
88714cb8 17874 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
17875 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17876 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17877 inst.instruction |= LOW4 (inst.operands[1].reg);
17878 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
17879 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 17880
88714cb8 17881 neon_dp_fixup (&inst);
5287ad62
JB
17882 }
17883 else
17884 {
17885 /* A more-specific type check for non-max versions. */
17886 et = neon_check_type (2, NS_QDI,
477330fc 17887 N_EQK | N_DBL, N_SU_32 | N_KEY);
88714cb8 17888 NEON_ENCODE (IMMED, inst);
5287ad62
JB
17889 neon_imm_shift (TRUE, et.type == NT_unsigned, 0, et, imm);
17890 }
17891}
17892
037e8744 17893/* Check the various types for the VCVT instruction, and return which version
5287ad62
JB
17894 the current instruction is. */
17895
6b9a8b67
MGD
17896#define CVT_FLAVOUR_VAR \
17897 CVT_VAR (s32_f32, N_S32, N_F32, whole_reg, "ftosls", "ftosis", "ftosizs") \
17898 CVT_VAR (u32_f32, N_U32, N_F32, whole_reg, "ftouls", "ftouis", "ftouizs") \
17899 CVT_VAR (f32_s32, N_F32, N_S32, whole_reg, "fsltos", "fsitos", NULL) \
17900 CVT_VAR (f32_u32, N_F32, N_U32, whole_reg, "fultos", "fuitos", NULL) \
17901 /* Half-precision conversions. */ \
cc933301
JW
17902 CVT_VAR (s16_f16, N_S16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
17903 CVT_VAR (u16_f16, N_U16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
17904 CVT_VAR (f16_s16, N_F16 | N_KEY, N_S16, whole_reg, NULL, NULL, NULL) \
17905 CVT_VAR (f16_u16, N_F16 | N_KEY, N_U16, whole_reg, NULL, NULL, NULL) \
6b9a8b67
MGD
17906 CVT_VAR (f32_f16, N_F32, N_F16, whole_reg, NULL, NULL, NULL) \
17907 CVT_VAR (f16_f32, N_F16, N_F32, whole_reg, NULL, NULL, NULL) \
9db2f6b4
RL
17908 /* New VCVT instructions introduced by ARMv8.2 fp16 extension. \
17909 Compared with single/double precision variants, only the co-processor \
17910 field is different, so the encoding flow is reused here. */ \
17911 CVT_VAR (f16_s32, N_F16 | N_KEY, N_S32, N_VFP, "fsltos", "fsitos", NULL) \
17912 CVT_VAR (f16_u32, N_F16 | N_KEY, N_U32, N_VFP, "fultos", "fuitos", NULL) \
17913 CVT_VAR (u32_f16, N_U32, N_F16 | N_KEY, N_VFP, "ftouls", "ftouis", "ftouizs")\
17914 CVT_VAR (s32_f16, N_S32, N_F16 | N_KEY, N_VFP, "ftosls", "ftosis", "ftosizs")\
6b9a8b67
MGD
17915 /* VFP instructions. */ \
17916 CVT_VAR (f32_f64, N_F32, N_F64, N_VFP, NULL, "fcvtsd", NULL) \
17917 CVT_VAR (f64_f32, N_F64, N_F32, N_VFP, NULL, "fcvtds", NULL) \
17918 CVT_VAR (s32_f64, N_S32, N_F64 | key, N_VFP, "ftosld", "ftosid", "ftosizd") \
17919 CVT_VAR (u32_f64, N_U32, N_F64 | key, N_VFP, "ftould", "ftouid", "ftouizd") \
17920 CVT_VAR (f64_s32, N_F64 | key, N_S32, N_VFP, "fsltod", "fsitod", NULL) \
17921 CVT_VAR (f64_u32, N_F64 | key, N_U32, N_VFP, "fultod", "fuitod", NULL) \
17922 /* VFP instructions with bitshift. */ \
17923 CVT_VAR (f32_s16, N_F32 | key, N_S16, N_VFP, "fshtos", NULL, NULL) \
17924 CVT_VAR (f32_u16, N_F32 | key, N_U16, N_VFP, "fuhtos", NULL, NULL) \
17925 CVT_VAR (f64_s16, N_F64 | key, N_S16, N_VFP, "fshtod", NULL, NULL) \
17926 CVT_VAR (f64_u16, N_F64 | key, N_U16, N_VFP, "fuhtod", NULL, NULL) \
17927 CVT_VAR (s16_f32, N_S16, N_F32 | key, N_VFP, "ftoshs", NULL, NULL) \
17928 CVT_VAR (u16_f32, N_U16, N_F32 | key, N_VFP, "ftouhs", NULL, NULL) \
17929 CVT_VAR (s16_f64, N_S16, N_F64 | key, N_VFP, "ftoshd", NULL, NULL) \
17930 CVT_VAR (u16_f64, N_U16, N_F64 | key, N_VFP, "ftouhd", NULL, NULL)
17931
17932#define CVT_VAR(C, X, Y, R, BSN, CN, ZN) \
17933 neon_cvt_flavour_##C,
17934
17935/* The different types of conversions we can do. */
17936enum neon_cvt_flavour
17937{
17938 CVT_FLAVOUR_VAR
17939 neon_cvt_flavour_invalid,
17940 neon_cvt_flavour_first_fp = neon_cvt_flavour_f32_f64
17941};
17942
17943#undef CVT_VAR
17944
17945static enum neon_cvt_flavour
17946get_neon_cvt_flavour (enum neon_shape rs)
5287ad62 17947{
6b9a8b67
MGD
17948#define CVT_VAR(C,X,Y,R,BSN,CN,ZN) \
17949 et = neon_check_type (2, rs, (R) | (X), (R) | (Y)); \
17950 if (et.type != NT_invtype) \
17951 { \
17952 inst.error = NULL; \
17953 return (neon_cvt_flavour_##C); \
5287ad62 17954 }
6b9a8b67 17955
5287ad62 17956 struct neon_type_el et;
037e8744 17957 unsigned whole_reg = (rs == NS_FFI || rs == NS_FD || rs == NS_DF
477330fc 17958 || rs == NS_FF) ? N_VFP : 0;
037e8744
JB
17959 /* The instruction versions which take an immediate take one register
17960 argument, which is extended to the width of the full register. Thus the
17961 "source" and "destination" registers must have the same width. Hack that
17962 here by making the size equal to the key (wider, in this case) operand. */
17963 unsigned key = (rs == NS_QQI || rs == NS_DDI || rs == NS_FFI) ? N_KEY : 0;
5f4273c7 17964
6b9a8b67
MGD
17965 CVT_FLAVOUR_VAR;
17966
17967 return neon_cvt_flavour_invalid;
5287ad62
JB
17968#undef CVT_VAR
17969}
17970
7e8e6784
MGD
17971enum neon_cvt_mode
17972{
17973 neon_cvt_mode_a,
17974 neon_cvt_mode_n,
17975 neon_cvt_mode_p,
17976 neon_cvt_mode_m,
17977 neon_cvt_mode_z,
30bdf752
MGD
17978 neon_cvt_mode_x,
17979 neon_cvt_mode_r
7e8e6784
MGD
17980};
17981
037e8744
JB
17982/* Neon-syntax VFP conversions. */
17983
5287ad62 17984static void
6b9a8b67 17985do_vfp_nsyn_cvt (enum neon_shape rs, enum neon_cvt_flavour flavour)
5287ad62 17986{
037e8744 17987 const char *opname = 0;
5f4273c7 17988
d54af2d0
RL
17989 if (rs == NS_DDI || rs == NS_QQI || rs == NS_FFI
17990 || rs == NS_FHI || rs == NS_HFI)
5287ad62 17991 {
037e8744
JB
17992 /* Conversions with immediate bitshift. */
17993 const char *enc[] =
477330fc 17994 {
6b9a8b67
MGD
17995#define CVT_VAR(C,A,B,R,BSN,CN,ZN) BSN,
17996 CVT_FLAVOUR_VAR
17997 NULL
17998#undef CVT_VAR
477330fc 17999 };
037e8744 18000
6b9a8b67 18001 if (flavour < (int) ARRAY_SIZE (enc))
477330fc
RM
18002 {
18003 opname = enc[flavour];
18004 constraint (inst.operands[0].reg != inst.operands[1].reg,
18005 _("operands 0 and 1 must be the same register"));
18006 inst.operands[1] = inst.operands[2];
18007 memset (&inst.operands[2], '\0', sizeof (inst.operands[2]));
18008 }
5287ad62
JB
18009 }
18010 else
18011 {
037e8744
JB
18012 /* Conversions without bitshift. */
18013 const char *enc[] =
477330fc 18014 {
6b9a8b67
MGD
18015#define CVT_VAR(C,A,B,R,BSN,CN,ZN) CN,
18016 CVT_FLAVOUR_VAR
18017 NULL
18018#undef CVT_VAR
477330fc 18019 };
037e8744 18020
6b9a8b67 18021 if (flavour < (int) ARRAY_SIZE (enc))
477330fc 18022 opname = enc[flavour];
037e8744
JB
18023 }
18024
18025 if (opname)
18026 do_vfp_nsyn_opcode (opname);
9db2f6b4
RL
18027
18028 /* ARMv8.2 fp16 VCVT instruction. */
18029 if (flavour == neon_cvt_flavour_s32_f16
18030 || flavour == neon_cvt_flavour_u32_f16
18031 || flavour == neon_cvt_flavour_f16_u32
18032 || flavour == neon_cvt_flavour_f16_s32)
18033 do_scalar_fp16_v82_encode ();
037e8744
JB
18034}
18035
18036static void
18037do_vfp_nsyn_cvtz (void)
18038{
d54af2d0 18039 enum neon_shape rs = neon_select_shape (NS_FH, NS_FF, NS_FD, NS_NULL);
6b9a8b67 18040 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744
JB
18041 const char *enc[] =
18042 {
6b9a8b67
MGD
18043#define CVT_VAR(C,A,B,R,BSN,CN,ZN) ZN,
18044 CVT_FLAVOUR_VAR
18045 NULL
18046#undef CVT_VAR
037e8744
JB
18047 };
18048
6b9a8b67 18049 if (flavour < (int) ARRAY_SIZE (enc) && enc[flavour])
037e8744
JB
18050 do_vfp_nsyn_opcode (enc[flavour]);
18051}
f31fef98 18052
037e8744 18053static void
bacebabc 18054do_vfp_nsyn_cvt_fpv8 (enum neon_cvt_flavour flavour,
7e8e6784
MGD
18055 enum neon_cvt_mode mode)
18056{
18057 int sz, op;
18058 int rm;
18059
a715796b
TG
18060 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
18061 D register operands. */
18062 if (flavour == neon_cvt_flavour_s32_f64
18063 || flavour == neon_cvt_flavour_u32_f64)
18064 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
18065 _(BAD_FPU));
18066
9db2f6b4
RL
18067 if (flavour == neon_cvt_flavour_s32_f16
18068 || flavour == neon_cvt_flavour_u32_f16)
18069 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
18070 _(BAD_FP16));
18071
5ee91343 18072 set_pred_insn_type (OUTSIDE_PRED_INSN);
7e8e6784
MGD
18073
18074 switch (flavour)
18075 {
18076 case neon_cvt_flavour_s32_f64:
18077 sz = 1;
827f64ff 18078 op = 1;
7e8e6784
MGD
18079 break;
18080 case neon_cvt_flavour_s32_f32:
18081 sz = 0;
18082 op = 1;
18083 break;
9db2f6b4
RL
18084 case neon_cvt_flavour_s32_f16:
18085 sz = 0;
18086 op = 1;
18087 break;
7e8e6784
MGD
18088 case neon_cvt_flavour_u32_f64:
18089 sz = 1;
18090 op = 0;
18091 break;
18092 case neon_cvt_flavour_u32_f32:
18093 sz = 0;
18094 op = 0;
18095 break;
9db2f6b4
RL
18096 case neon_cvt_flavour_u32_f16:
18097 sz = 0;
18098 op = 0;
18099 break;
7e8e6784
MGD
18100 default:
18101 first_error (_("invalid instruction shape"));
18102 return;
18103 }
18104
18105 switch (mode)
18106 {
18107 case neon_cvt_mode_a: rm = 0; break;
18108 case neon_cvt_mode_n: rm = 1; break;
18109 case neon_cvt_mode_p: rm = 2; break;
18110 case neon_cvt_mode_m: rm = 3; break;
18111 default: first_error (_("invalid rounding mode")); return;
18112 }
18113
18114 NEON_ENCODE (FPV8, inst);
18115 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
18116 encode_arm_vfp_reg (inst.operands[1].reg, sz == 1 ? VFP_REG_Dm : VFP_REG_Sm);
18117 inst.instruction |= sz << 8;
9db2f6b4
RL
18118
18119 /* ARMv8.2 fp16 VCVT instruction. */
18120 if (flavour == neon_cvt_flavour_s32_f16
18121 ||flavour == neon_cvt_flavour_u32_f16)
18122 do_scalar_fp16_v82_encode ();
7e8e6784
MGD
18123 inst.instruction |= op << 7;
18124 inst.instruction |= rm << 16;
18125 inst.instruction |= 0xf0000000;
18126 inst.is_neon = TRUE;
18127}
18128
18129static void
18130do_neon_cvt_1 (enum neon_cvt_mode mode)
037e8744
JB
18131{
18132 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_FFI, NS_DD, NS_QQ,
d54af2d0
RL
18133 NS_FD, NS_DF, NS_FF, NS_QD, NS_DQ,
18134 NS_FH, NS_HF, NS_FHI, NS_HFI,
18135 NS_NULL);
6b9a8b67 18136 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744 18137
cc933301
JW
18138 if (flavour == neon_cvt_flavour_invalid)
18139 return;
18140
e3e535bc 18141 /* PR11109: Handle round-to-zero for VCVT conversions. */
7e8e6784 18142 if (mode == neon_cvt_mode_z
e3e535bc 18143 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_vfp_v2)
cc933301
JW
18144 && (flavour == neon_cvt_flavour_s16_f16
18145 || flavour == neon_cvt_flavour_u16_f16
18146 || flavour == neon_cvt_flavour_s32_f32
bacebabc
RM
18147 || flavour == neon_cvt_flavour_u32_f32
18148 || flavour == neon_cvt_flavour_s32_f64
6b9a8b67 18149 || flavour == neon_cvt_flavour_u32_f64)
e3e535bc
NC
18150 && (rs == NS_FD || rs == NS_FF))
18151 {
18152 do_vfp_nsyn_cvtz ();
18153 return;
18154 }
18155
9db2f6b4
RL
18156 /* ARMv8.2 fp16 VCVT conversions. */
18157 if (mode == neon_cvt_mode_z
18158 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16)
18159 && (flavour == neon_cvt_flavour_s32_f16
18160 || flavour == neon_cvt_flavour_u32_f16)
18161 && (rs == NS_FH))
18162 {
18163 do_vfp_nsyn_cvtz ();
18164 do_scalar_fp16_v82_encode ();
18165 return;
18166 }
18167
037e8744 18168 /* VFP rather than Neon conversions. */
6b9a8b67 18169 if (flavour >= neon_cvt_flavour_first_fp)
037e8744 18170 {
7e8e6784
MGD
18171 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
18172 do_vfp_nsyn_cvt (rs, flavour);
18173 else
18174 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
18175
037e8744
JB
18176 return;
18177 }
18178
18179 switch (rs)
18180 {
037e8744 18181 case NS_QQI:
dd9634d9
AV
18182 if (mode == neon_cvt_mode_z
18183 && (flavour == neon_cvt_flavour_f16_s16
18184 || flavour == neon_cvt_flavour_f16_u16
18185 || flavour == neon_cvt_flavour_s16_f16
18186 || flavour == neon_cvt_flavour_u16_f16
18187 || flavour == neon_cvt_flavour_f32_u32
18188 || flavour == neon_cvt_flavour_f32_s32
18189 || flavour == neon_cvt_flavour_s32_f32
18190 || flavour == neon_cvt_flavour_u32_f32))
18191 {
18192 if (check_simd_pred_availability (1, NEON_CHECK_CC | NEON_CHECK_ARCH))
18193 return;
18194 }
18195 else if (mode == neon_cvt_mode_n)
18196 {
18197 /* We are dealing with vcvt with the 'ne' condition. */
18198 inst.cond = 0x1;
18199 inst.instruction = N_MNEM_vcvt;
18200 do_neon_cvt_1 (neon_cvt_mode_z);
18201 return;
18202 }
18203 /* fall through. */
18204 case NS_DDI:
037e8744 18205 {
477330fc 18206 unsigned immbits;
cc933301
JW
18207 unsigned enctab[] = {0x0000100, 0x1000100, 0x0, 0x1000000,
18208 0x0000100, 0x1000100, 0x0, 0x1000000};
35997600 18209
dd9634d9
AV
18210 if ((rs != NS_QQI || !ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
18211 && vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
18212 return;
18213
18214 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
18215 {
18216 constraint (inst.operands[2].present && inst.operands[2].imm == 0,
18217 _("immediate value out of range"));
18218 switch (flavour)
18219 {
18220 case neon_cvt_flavour_f16_s16:
18221 case neon_cvt_flavour_f16_u16:
18222 case neon_cvt_flavour_s16_f16:
18223 case neon_cvt_flavour_u16_f16:
18224 constraint (inst.operands[2].imm > 16,
18225 _("immediate value out of range"));
18226 break;
18227 case neon_cvt_flavour_f32_u32:
18228 case neon_cvt_flavour_f32_s32:
18229 case neon_cvt_flavour_s32_f32:
18230 case neon_cvt_flavour_u32_f32:
18231 constraint (inst.operands[2].imm > 32,
18232 _("immediate value out of range"));
18233 break;
18234 default:
18235 inst.error = BAD_FPU;
18236 return;
18237 }
18238 }
037e8744 18239
477330fc
RM
18240 /* Fixed-point conversion with #0 immediate is encoded as an
18241 integer conversion. */
18242 if (inst.operands[2].present && inst.operands[2].imm == 0)
18243 goto int_encode;
477330fc
RM
18244 NEON_ENCODE (IMMED, inst);
18245 if (flavour != neon_cvt_flavour_invalid)
18246 inst.instruction |= enctab[flavour];
18247 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18248 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18249 inst.instruction |= LOW4 (inst.operands[1].reg);
18250 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18251 inst.instruction |= neon_quad (rs) << 6;
18252 inst.instruction |= 1 << 21;
cc933301
JW
18253 if (flavour < neon_cvt_flavour_s16_f16)
18254 {
18255 inst.instruction |= 1 << 21;
18256 immbits = 32 - inst.operands[2].imm;
18257 inst.instruction |= immbits << 16;
18258 }
18259 else
18260 {
18261 inst.instruction |= 3 << 20;
18262 immbits = 16 - inst.operands[2].imm;
18263 inst.instruction |= immbits << 16;
18264 inst.instruction &= ~(1 << 9);
18265 }
477330fc
RM
18266
18267 neon_dp_fixup (&inst);
037e8744
JB
18268 }
18269 break;
18270
037e8744 18271 case NS_QQ:
dd9634d9
AV
18272 if ((mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
18273 || mode == neon_cvt_mode_m || mode == neon_cvt_mode_p)
18274 && (flavour == neon_cvt_flavour_s16_f16
18275 || flavour == neon_cvt_flavour_u16_f16
18276 || flavour == neon_cvt_flavour_s32_f32
18277 || flavour == neon_cvt_flavour_u32_f32))
18278 {
18279 if (check_simd_pred_availability (1,
18280 NEON_CHECK_CC | NEON_CHECK_ARCH8))
18281 return;
18282 }
18283 else if (mode == neon_cvt_mode_z
18284 && (flavour == neon_cvt_flavour_f16_s16
18285 || flavour == neon_cvt_flavour_f16_u16
18286 || flavour == neon_cvt_flavour_s16_f16
18287 || flavour == neon_cvt_flavour_u16_f16
18288 || flavour == neon_cvt_flavour_f32_u32
18289 || flavour == neon_cvt_flavour_f32_s32
18290 || flavour == neon_cvt_flavour_s32_f32
18291 || flavour == neon_cvt_flavour_u32_f32))
18292 {
18293 if (check_simd_pred_availability (1,
18294 NEON_CHECK_CC | NEON_CHECK_ARCH))
18295 return;
18296 }
18297 /* fall through. */
18298 case NS_DD:
7e8e6784
MGD
18299 if (mode != neon_cvt_mode_x && mode != neon_cvt_mode_z)
18300 {
7e8e6784 18301
dd9634d9
AV
18302 NEON_ENCODE (FLOAT, inst);
18303 if (check_simd_pred_availability (1,
18304 NEON_CHECK_CC | NEON_CHECK_ARCH8))
7e8e6784
MGD
18305 return;
18306
18307 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18308 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18309 inst.instruction |= LOW4 (inst.operands[1].reg);
18310 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18311 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
18312 inst.instruction |= (flavour == neon_cvt_flavour_u16_f16
18313 || flavour == neon_cvt_flavour_u32_f32) << 7;
7e8e6784 18314 inst.instruction |= mode << 8;
cc933301
JW
18315 if (flavour == neon_cvt_flavour_u16_f16
18316 || flavour == neon_cvt_flavour_s16_f16)
18317 /* Mask off the original size bits and reencode them. */
18318 inst.instruction = ((inst.instruction & 0xfff3ffff) | (1 << 18));
18319
7e8e6784
MGD
18320 if (thumb_mode)
18321 inst.instruction |= 0xfc000000;
18322 else
18323 inst.instruction |= 0xf0000000;
18324 }
18325 else
18326 {
037e8744 18327 int_encode:
7e8e6784 18328 {
cc933301
JW
18329 unsigned enctab[] = { 0x100, 0x180, 0x0, 0x080,
18330 0x100, 0x180, 0x0, 0x080};
037e8744 18331
7e8e6784 18332 NEON_ENCODE (INTEGER, inst);
037e8744 18333
dd9634d9
AV
18334 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
18335 {
18336 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
18337 return;
18338 }
037e8744 18339
7e8e6784
MGD
18340 if (flavour != neon_cvt_flavour_invalid)
18341 inst.instruction |= enctab[flavour];
037e8744 18342
7e8e6784
MGD
18343 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18344 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18345 inst.instruction |= LOW4 (inst.operands[1].reg);
18346 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18347 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
18348 if (flavour >= neon_cvt_flavour_s16_f16
18349 && flavour <= neon_cvt_flavour_f16_u16)
18350 /* Half precision. */
18351 inst.instruction |= 1 << 18;
18352 else
18353 inst.instruction |= 2 << 18;
037e8744 18354
7e8e6784
MGD
18355 neon_dp_fixup (&inst);
18356 }
18357 }
18358 break;
037e8744 18359
8e79c3df
CM
18360 /* Half-precision conversions for Advanced SIMD -- neon. */
18361 case NS_QD:
18362 case NS_DQ:
bc52d49c
MM
18363 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
18364 return;
8e79c3df
CM
18365
18366 if ((rs == NS_DQ)
18367 && (inst.vectype.el[0].size != 16 || inst.vectype.el[1].size != 32))
18368 {
18369 as_bad (_("operand size must match register width"));
18370 break;
18371 }
18372
18373 if ((rs == NS_QD)
18374 && ((inst.vectype.el[0].size != 32 || inst.vectype.el[1].size != 16)))
18375 {
18376 as_bad (_("operand size must match register width"));
18377 break;
18378 }
18379
18380 if (rs == NS_DQ)
477330fc 18381 inst.instruction = 0x3b60600;
8e79c3df
CM
18382 else
18383 inst.instruction = 0x3b60700;
18384
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;
88714cb8 18389 neon_dp_fixup (&inst);
8e79c3df
CM
18390 break;
18391
037e8744
JB
18392 default:
18393 /* Some VFP conversions go here (s32 <-> f32, u32 <-> f32). */
7e8e6784
MGD
18394 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
18395 do_vfp_nsyn_cvt (rs, flavour);
18396 else
18397 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
5287ad62 18398 }
5287ad62
JB
18399}
18400
e3e535bc
NC
18401static void
18402do_neon_cvtr (void)
18403{
7e8e6784 18404 do_neon_cvt_1 (neon_cvt_mode_x);
e3e535bc
NC
18405}
18406
18407static void
18408do_neon_cvt (void)
18409{
7e8e6784
MGD
18410 do_neon_cvt_1 (neon_cvt_mode_z);
18411}
18412
18413static void
18414do_neon_cvta (void)
18415{
18416 do_neon_cvt_1 (neon_cvt_mode_a);
18417}
18418
18419static void
18420do_neon_cvtn (void)
18421{
18422 do_neon_cvt_1 (neon_cvt_mode_n);
18423}
18424
18425static void
18426do_neon_cvtp (void)
18427{
18428 do_neon_cvt_1 (neon_cvt_mode_p);
18429}
18430
18431static void
18432do_neon_cvtm (void)
18433{
18434 do_neon_cvt_1 (neon_cvt_mode_m);
e3e535bc
NC
18435}
18436
8e79c3df 18437static void
c70a8987 18438do_neon_cvttb_2 (bfd_boolean t, bfd_boolean to, bfd_boolean is_double)
8e79c3df 18439{
c70a8987
MGD
18440 if (is_double)
18441 mark_feature_used (&fpu_vfp_ext_armv8);
8e79c3df 18442
c70a8987
MGD
18443 encode_arm_vfp_reg (inst.operands[0].reg,
18444 (is_double && !to) ? VFP_REG_Dd : VFP_REG_Sd);
18445 encode_arm_vfp_reg (inst.operands[1].reg,
18446 (is_double && to) ? VFP_REG_Dm : VFP_REG_Sm);
18447 inst.instruction |= to ? 0x10000 : 0;
18448 inst.instruction |= t ? 0x80 : 0;
18449 inst.instruction |= is_double ? 0x100 : 0;
18450 do_vfp_cond_or_thumb ();
18451}
8e79c3df 18452
c70a8987
MGD
18453static void
18454do_neon_cvttb_1 (bfd_boolean t)
18455{
d54af2d0 18456 enum neon_shape rs = neon_select_shape (NS_HF, NS_HD, NS_FH, NS_FF, NS_FD,
dd9634d9 18457 NS_DF, NS_DH, NS_QQ, NS_QQI, NS_NULL);
8e79c3df 18458
c70a8987
MGD
18459 if (rs == NS_NULL)
18460 return;
dd9634d9
AV
18461 else if (rs == NS_QQ || rs == NS_QQI)
18462 {
18463 int single_to_half = 0;
18464 if (check_simd_pred_availability (1, NEON_CHECK_ARCH))
18465 return;
18466
18467 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
18468
18469 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
18470 && (flavour == neon_cvt_flavour_u16_f16
18471 || flavour == neon_cvt_flavour_s16_f16
18472 || flavour == neon_cvt_flavour_f16_s16
18473 || flavour == neon_cvt_flavour_f16_u16
18474 || flavour == neon_cvt_flavour_u32_f32
18475 || flavour == neon_cvt_flavour_s32_f32
18476 || flavour == neon_cvt_flavour_f32_s32
18477 || flavour == neon_cvt_flavour_f32_u32))
18478 {
18479 inst.cond = 0xf;
18480 inst.instruction = N_MNEM_vcvt;
18481 set_pred_insn_type (INSIDE_VPT_INSN);
18482 do_neon_cvt_1 (neon_cvt_mode_z);
18483 return;
18484 }
18485 else if (rs == NS_QQ && flavour == neon_cvt_flavour_f32_f16)
18486 single_to_half = 1;
18487 else if (rs == NS_QQ && flavour != neon_cvt_flavour_f16_f32)
18488 {
18489 first_error (BAD_FPU);
18490 return;
18491 }
18492
18493 inst.instruction = 0xee3f0e01;
18494 inst.instruction |= single_to_half << 28;
18495 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18496 inst.instruction |= LOW4 (inst.operands[0].reg) << 13;
18497 inst.instruction |= t << 12;
18498 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18499 inst.instruction |= LOW4 (inst.operands[1].reg) << 1;
18500 inst.is_neon = 1;
18501 }
c70a8987
MGD
18502 else if (neon_check_type (2, rs, N_F16, N_F32 | N_VFP).type != NT_invtype)
18503 {
18504 inst.error = NULL;
18505 do_neon_cvttb_2 (t, /*to=*/TRUE, /*is_double=*/FALSE);
18506 }
18507 else if (neon_check_type (2, rs, N_F32 | N_VFP, N_F16).type != NT_invtype)
18508 {
18509 inst.error = NULL;
18510 do_neon_cvttb_2 (t, /*to=*/FALSE, /*is_double=*/FALSE);
18511 }
18512 else if (neon_check_type (2, rs, N_F16, N_F64 | N_VFP).type != NT_invtype)
18513 {
a715796b
TG
18514 /* The VCVTB and VCVTT instructions with D-register operands
18515 don't work for SP only targets. */
18516 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
18517 _(BAD_FPU));
18518
c70a8987
MGD
18519 inst.error = NULL;
18520 do_neon_cvttb_2 (t, /*to=*/TRUE, /*is_double=*/TRUE);
18521 }
18522 else if (neon_check_type (2, rs, N_F64 | N_VFP, N_F16).type != NT_invtype)
18523 {
a715796b
TG
18524 /* The VCVTB and VCVTT instructions with D-register operands
18525 don't work for SP only targets. */
18526 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
18527 _(BAD_FPU));
18528
c70a8987
MGD
18529 inst.error = NULL;
18530 do_neon_cvttb_2 (t, /*to=*/FALSE, /*is_double=*/TRUE);
18531 }
18532 else
18533 return;
18534}
18535
18536static void
18537do_neon_cvtb (void)
18538{
18539 do_neon_cvttb_1 (FALSE);
8e79c3df
CM
18540}
18541
18542
18543static void
18544do_neon_cvtt (void)
18545{
c70a8987 18546 do_neon_cvttb_1 (TRUE);
8e79c3df
CM
18547}
18548
5287ad62
JB
18549static void
18550neon_move_immediate (void)
18551{
037e8744
JB
18552 enum neon_shape rs = neon_select_shape (NS_DI, NS_QI, NS_NULL);
18553 struct neon_type_el et = neon_check_type (2, rs,
18554 N_I8 | N_I16 | N_I32 | N_I64 | N_F32 | N_KEY, N_EQK);
5287ad62 18555 unsigned immlo, immhi = 0, immbits;
c96612cc 18556 int op, cmode, float_p;
5287ad62 18557
037e8744 18558 constraint (et.type == NT_invtype,
477330fc 18559 _("operand size must be specified for immediate VMOV"));
037e8744 18560
5287ad62
JB
18561 /* We start out as an MVN instruction if OP = 1, MOV otherwise. */
18562 op = (inst.instruction & (1 << 5)) != 0;
18563
18564 immlo = inst.operands[1].imm;
18565 if (inst.operands[1].regisimm)
18566 immhi = inst.operands[1].reg;
18567
18568 constraint (et.size < 32 && (immlo & ~((1 << et.size) - 1)) != 0,
477330fc 18569 _("immediate has bits set outside the operand size"));
5287ad62 18570
c96612cc
JB
18571 float_p = inst.operands[1].immisfloat;
18572
18573 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits, &op,
477330fc 18574 et.size, et.type)) == FAIL)
5287ad62
JB
18575 {
18576 /* Invert relevant bits only. */
18577 neon_invert_size (&immlo, &immhi, et.size);
18578 /* Flip from VMOV/VMVN to VMVN/VMOV. Some immediate types are unavailable
477330fc
RM
18579 with one or the other; those cases are caught by
18580 neon_cmode_for_move_imm. */
5287ad62 18581 op = !op;
c96612cc
JB
18582 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits,
18583 &op, et.size, et.type)) == FAIL)
477330fc
RM
18584 {
18585 first_error (_("immediate out of range"));
18586 return;
18587 }
5287ad62
JB
18588 }
18589
18590 inst.instruction &= ~(1 << 5);
18591 inst.instruction |= op << 5;
18592
18593 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18594 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
037e8744 18595 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
18596 inst.instruction |= cmode << 8;
18597
18598 neon_write_immbits (immbits);
18599}
18600
18601static void
18602do_neon_mvn (void)
18603{
1a186d29
AV
18604 if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
18605 return;
18606
5287ad62
JB
18607 if (inst.operands[1].isreg)
18608 {
1a186d29
AV
18609 enum neon_shape rs;
18610 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18611 rs = neon_select_shape (NS_QQ, NS_NULL);
18612 else
18613 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5f4273c7 18614
88714cb8 18615 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18616 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18617 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18618 inst.instruction |= LOW4 (inst.operands[1].reg);
18619 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 18620 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
18621 }
18622 else
18623 {
88714cb8 18624 NEON_ENCODE (IMMED, inst);
5287ad62
JB
18625 neon_move_immediate ();
18626 }
18627
88714cb8 18628 neon_dp_fixup (&inst);
1a186d29
AV
18629
18630 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18631 {
18632 constraint (!inst.operands[1].isreg && !inst.operands[0].isquad, BAD_FPU);
18633 constraint ((inst.instruction & 0xd00) == 0xd00,
18634 _("immediate value out of range"));
18635 }
5287ad62
JB
18636}
18637
18638/* Encode instructions of form:
18639
18640 |28/24|23|22|21 20|19 16|15 12|11 8|7|6|5|4|3 0|
5f4273c7 18641 | U |x |D |size | Rn | Rd |x x x x|N|x|M|x| Rm | */
5287ad62
JB
18642
18643static void
18644neon_mixed_length (struct neon_type_el et, unsigned size)
18645{
18646 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18647 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18648 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
18649 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
18650 inst.instruction |= LOW4 (inst.operands[2].reg);
18651 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
18652 inst.instruction |= (et.type == NT_unsigned) << 24;
18653 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 18654
88714cb8 18655 neon_dp_fixup (&inst);
5287ad62
JB
18656}
18657
18658static void
18659do_neon_dyadic_long (void)
18660{
5ee91343
AV
18661 enum neon_shape rs = neon_select_shape (NS_QDD, NS_QQQ, NS_QQR, NS_NULL);
18662 if (rs == NS_QDD)
18663 {
18664 if (vfp_or_neon_is_neon (NEON_CHECK_ARCH | NEON_CHECK_CC) == FAIL)
18665 return;
18666
18667 NEON_ENCODE (INTEGER, inst);
18668 /* FIXME: Type checking for lengthening op. */
18669 struct neon_type_el et = neon_check_type (3, NS_QDD,
18670 N_EQK | N_DBL, N_EQK, N_SU_32 | N_KEY);
18671 neon_mixed_length (et, et.size);
18672 }
18673 else if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
18674 && (inst.cond == 0xf || inst.cond == 0x10))
18675 {
18676 /* If parsing for MVE, vaddl/vsubl/vabdl{e,t} can only be vadd/vsub/vabd
18677 in an IT block with le/lt conditions. */
18678
18679 if (inst.cond == 0xf)
18680 inst.cond = 0xb;
18681 else if (inst.cond == 0x10)
18682 inst.cond = 0xd;
18683
18684 inst.pred_insn_type = INSIDE_IT_INSN;
18685
18686 if (inst.instruction == N_MNEM_vaddl)
18687 {
18688 inst.instruction = N_MNEM_vadd;
18689 do_neon_addsub_if_i ();
18690 }
18691 else if (inst.instruction == N_MNEM_vsubl)
18692 {
18693 inst.instruction = N_MNEM_vsub;
18694 do_neon_addsub_if_i ();
18695 }
18696 else if (inst.instruction == N_MNEM_vabdl)
18697 {
18698 inst.instruction = N_MNEM_vabd;
18699 do_neon_dyadic_if_su ();
18700 }
18701 }
18702 else
18703 first_error (BAD_FPU);
5287ad62
JB
18704}
18705
18706static void
18707do_neon_abal (void)
18708{
18709 struct neon_type_el et = neon_check_type (3, NS_QDD,
18710 N_EQK | N_INT | N_DBL, N_EQK, N_SU_32 | N_KEY);
18711 neon_mixed_length (et, et.size);
18712}
18713
18714static void
18715neon_mac_reg_scalar_long (unsigned regtypes, unsigned scalartypes)
18716{
18717 if (inst.operands[2].isscalar)
18718 {
dcbf9037 18719 struct neon_type_el et = neon_check_type (3, NS_QDS,
477330fc 18720 N_EQK | N_DBL, N_EQK, regtypes | N_KEY);
88714cb8 18721 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
18722 neon_mul_mac (et, et.type == NT_unsigned);
18723 }
18724 else
18725 {
18726 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 18727 N_EQK | N_DBL, N_EQK, scalartypes | N_KEY);
88714cb8 18728 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18729 neon_mixed_length (et, et.size);
18730 }
18731}
18732
18733static void
18734do_neon_mac_maybe_scalar_long (void)
18735{
18736 neon_mac_reg_scalar_long (N_S16 | N_S32 | N_U16 | N_U32, N_SU_32);
18737}
18738
dec41383
JW
18739/* Like neon_scalar_for_mul, this function generate Rm encoding from GAS's
18740 internal SCALAR. QUAD_P is 1 if it's for Q format, otherwise it's 0. */
18741
18742static unsigned
18743neon_scalar_for_fmac_fp16_long (unsigned scalar, unsigned quad_p)
18744{
18745 unsigned regno = NEON_SCALAR_REG (scalar);
18746 unsigned elno = NEON_SCALAR_INDEX (scalar);
18747
18748 if (quad_p)
18749 {
18750 if (regno > 7 || elno > 3)
18751 goto bad_scalar;
18752
18753 return ((regno & 0x7)
18754 | ((elno & 0x1) << 3)
18755 | (((elno >> 1) & 0x1) << 5));
18756 }
18757 else
18758 {
18759 if (regno > 15 || elno > 1)
18760 goto bad_scalar;
18761
18762 return (((regno & 0x1) << 5)
18763 | ((regno >> 1) & 0x7)
18764 | ((elno & 0x1) << 3));
18765 }
18766
18767bad_scalar:
18768 first_error (_("scalar out of range for multiply instruction"));
18769 return 0;
18770}
18771
18772static void
18773do_neon_fmac_maybe_scalar_long (int subtype)
18774{
18775 enum neon_shape rs;
18776 int high8;
18777 /* NOTE: vfmal/vfmsl use slightly different NEON three-same encoding. 'size"
18778 field (bits[21:20]) has different meaning. For scalar index variant, it's
18779 used to differentiate add and subtract, otherwise it's with fixed value
18780 0x2. */
18781 int size = -1;
18782
18783 if (inst.cond != COND_ALWAYS)
18784 as_warn (_("vfmal/vfmsl with FP16 type cannot be conditional, the "
18785 "behaviour is UNPREDICTABLE"));
18786
01f48020 18787 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16_fml),
dec41383
JW
18788 _(BAD_FP16));
18789
18790 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
18791 _(BAD_FPU));
18792
18793 /* vfmal/vfmsl are in three-same D/Q register format or the third operand can
18794 be a scalar index register. */
18795 if (inst.operands[2].isscalar)
18796 {
18797 high8 = 0xfe000000;
18798 if (subtype)
18799 size = 16;
18800 rs = neon_select_shape (NS_DHS, NS_QDS, NS_NULL);
18801 }
18802 else
18803 {
18804 high8 = 0xfc000000;
18805 size = 32;
18806 if (subtype)
18807 inst.instruction |= (0x1 << 23);
18808 rs = neon_select_shape (NS_DHH, NS_QDD, NS_NULL);
18809 }
18810
18811 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16);
18812
18813 /* "opcode" from template has included "ubit", so simply pass 0 here. Also,
18814 the "S" bit in size field has been reused to differentiate vfmal and vfmsl,
18815 so we simply pass -1 as size. */
18816 unsigned quad_p = (rs == NS_QDD || rs == NS_QDS);
18817 neon_three_same (quad_p, 0, size);
18818
18819 /* Undo neon_dp_fixup. Redo the high eight bits. */
18820 inst.instruction &= 0x00ffffff;
18821 inst.instruction |= high8;
18822
18823#define LOW1(R) ((R) & 0x1)
18824#define HI4(R) (((R) >> 1) & 0xf)
18825 /* Unlike usually NEON three-same, encoding for Vn and Vm will depend on
18826 whether the instruction is in Q form and whether Vm is a scalar indexed
18827 operand. */
18828 if (inst.operands[2].isscalar)
18829 {
18830 unsigned rm
18831 = neon_scalar_for_fmac_fp16_long (inst.operands[2].reg, quad_p);
18832 inst.instruction &= 0xffffffd0;
18833 inst.instruction |= rm;
18834
18835 if (!quad_p)
18836 {
18837 /* Redo Rn as well. */
18838 inst.instruction &= 0xfff0ff7f;
18839 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
18840 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
18841 }
18842 }
18843 else if (!quad_p)
18844 {
18845 /* Redo Rn and Rm. */
18846 inst.instruction &= 0xfff0ff50;
18847 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
18848 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
18849 inst.instruction |= HI4 (inst.operands[2].reg);
18850 inst.instruction |= LOW1 (inst.operands[2].reg) << 5;
18851 }
18852}
18853
18854static void
18855do_neon_vfmal (void)
18856{
18857 return do_neon_fmac_maybe_scalar_long (0);
18858}
18859
18860static void
18861do_neon_vfmsl (void)
18862{
18863 return do_neon_fmac_maybe_scalar_long (1);
18864}
18865
5287ad62
JB
18866static void
18867do_neon_dyadic_wide (void)
18868{
18869 struct neon_type_el et = neon_check_type (3, NS_QQD,
18870 N_EQK | N_DBL, N_EQK | N_DBL, N_SU_32 | N_KEY);
18871 neon_mixed_length (et, et.size);
18872}
18873
18874static void
18875do_neon_dyadic_narrow (void)
18876{
18877 struct neon_type_el et = neon_check_type (3, NS_QDD,
18878 N_EQK | N_DBL, N_EQK, N_I16 | N_I32 | N_I64 | N_KEY);
428e3f1f
PB
18879 /* Operand sign is unimportant, and the U bit is part of the opcode,
18880 so force the operand type to integer. */
18881 et.type = NT_integer;
5287ad62
JB
18882 neon_mixed_length (et, et.size / 2);
18883}
18884
18885static void
18886do_neon_mul_sat_scalar_long (void)
18887{
18888 neon_mac_reg_scalar_long (N_S16 | N_S32, N_S16 | N_S32);
18889}
18890
18891static void
18892do_neon_vmull (void)
18893{
18894 if (inst.operands[2].isscalar)
18895 do_neon_mac_maybe_scalar_long ();
18896 else
18897 {
18898 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 18899 N_EQK | N_DBL, N_EQK, N_SU_32 | N_P8 | N_P64 | N_KEY);
4f51b4bd 18900
5287ad62 18901 if (et.type == NT_poly)
477330fc 18902 NEON_ENCODE (POLY, inst);
5287ad62 18903 else
477330fc 18904 NEON_ENCODE (INTEGER, inst);
4f51b4bd
MGD
18905
18906 /* For polynomial encoding the U bit must be zero, and the size must
18907 be 8 (encoded as 0b00) or, on ARMv8 or later 64 (encoded, non
18908 obviously, as 0b10). */
18909 if (et.size == 64)
18910 {
18911 /* Check we're on the correct architecture. */
18912 if (!mark_feature_used (&fpu_crypto_ext_armv8))
18913 inst.error =
18914 _("Instruction form not available on this architecture.");
18915
18916 et.size = 32;
18917 }
18918
5287ad62
JB
18919 neon_mixed_length (et, et.size);
18920 }
18921}
18922
18923static void
18924do_neon_ext (void)
18925{
037e8744 18926 enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
5287ad62
JB
18927 struct neon_type_el et = neon_check_type (3, rs,
18928 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
18929 unsigned imm = (inst.operands[3].imm * et.size) / 8;
35997600
NC
18930
18931 constraint (imm >= (unsigned) (neon_quad (rs) ? 16 : 8),
18932 _("shift out of range"));
5287ad62
JB
18933 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18934 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18935 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
18936 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
18937 inst.instruction |= LOW4 (inst.operands[2].reg);
18938 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
037e8744 18939 inst.instruction |= neon_quad (rs) << 6;
5287ad62 18940 inst.instruction |= imm << 8;
5f4273c7 18941
88714cb8 18942 neon_dp_fixup (&inst);
5287ad62
JB
18943}
18944
18945static void
18946do_neon_rev (void)
18947{
037e8744 18948 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
18949 struct neon_type_el et = neon_check_type (2, rs,
18950 N_EQK, N_8 | N_16 | N_32 | N_KEY);
18951 unsigned op = (inst.instruction >> 7) & 3;
18952 /* N (width of reversed regions) is encoded as part of the bitmask. We
18953 extract it here to check the elements to be reversed are smaller.
18954 Otherwise we'd get a reserved instruction. */
18955 unsigned elsize = (op == 2) ? 16 : (op == 1) ? 32 : (op == 0) ? 64 : 0;
9c2799c2 18956 gas_assert (elsize != 0);
5287ad62 18957 constraint (et.size >= elsize,
477330fc 18958 _("elements must be smaller than reversal region"));
037e8744 18959 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
18960}
18961
18962static void
18963do_neon_dup (void)
18964{
18965 if (inst.operands[1].isscalar)
18966 {
b409bdb6
AV
18967 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1),
18968 BAD_FPU);
037e8744 18969 enum neon_shape rs = neon_select_shape (NS_DS, NS_QS, NS_NULL);
dcbf9037 18970 struct neon_type_el et = neon_check_type (2, rs,
477330fc 18971 N_EQK, N_8 | N_16 | N_32 | N_KEY);
5287ad62 18972 unsigned sizebits = et.size >> 3;
dcbf9037 18973 unsigned dm = NEON_SCALAR_REG (inst.operands[1].reg);
5287ad62 18974 int logsize = neon_logbits (et.size);
dcbf9037 18975 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg) << logsize;
037e8744
JB
18976
18977 if (vfp_or_neon_is_neon (NEON_CHECK_CC) == FAIL)
477330fc 18978 return;
037e8744 18979
88714cb8 18980 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
18981 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18982 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18983 inst.instruction |= LOW4 (dm);
18984 inst.instruction |= HI1 (dm) << 5;
037e8744 18985 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
18986 inst.instruction |= x << 17;
18987 inst.instruction |= sizebits << 16;
5f4273c7 18988
88714cb8 18989 neon_dp_fixup (&inst);
5287ad62
JB
18990 }
18991 else
18992 {
037e8744
JB
18993 enum neon_shape rs = neon_select_shape (NS_DR, NS_QR, NS_NULL);
18994 struct neon_type_el et = neon_check_type (2, rs,
477330fc 18995 N_8 | N_16 | N_32 | N_KEY, N_EQK);
b409bdb6
AV
18996 if (rs == NS_QR)
18997 {
18998 if (check_simd_pred_availability (0, NEON_CHECK_ARCH))
18999 return;
19000 }
19001 else
19002 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1),
19003 BAD_FPU);
19004
19005 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19006 {
19007 if (inst.operands[1].reg == REG_SP)
19008 as_tsktsk (MVE_BAD_SP);
19009 else if (inst.operands[1].reg == REG_PC)
19010 as_tsktsk (MVE_BAD_PC);
19011 }
19012
5287ad62 19013 /* Duplicate ARM register to lanes of vector. */
88714cb8 19014 NEON_ENCODE (ARMREG, inst);
5287ad62 19015 switch (et.size)
477330fc
RM
19016 {
19017 case 8: inst.instruction |= 0x400000; break;
19018 case 16: inst.instruction |= 0x000020; break;
19019 case 32: inst.instruction |= 0x000000; break;
19020 default: break;
19021 }
5287ad62
JB
19022 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
19023 inst.instruction |= LOW4 (inst.operands[0].reg) << 16;
19024 inst.instruction |= HI1 (inst.operands[0].reg) << 7;
037e8744 19025 inst.instruction |= neon_quad (rs) << 21;
5287ad62 19026 /* The encoding for this instruction is identical for the ARM and Thumb
477330fc 19027 variants, except for the condition field. */
037e8744 19028 do_vfp_cond_or_thumb ();
5287ad62
JB
19029 }
19030}
19031
57785aa2
AV
19032static void
19033do_mve_mov (int toQ)
19034{
19035 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19036 return;
19037 if (inst.cond > COND_ALWAYS)
19038 inst.pred_insn_type = MVE_UNPREDICABLE_INSN;
19039
19040 unsigned Rt = 0, Rt2 = 1, Q0 = 2, Q1 = 3;
19041 if (toQ)
19042 {
19043 Q0 = 0;
19044 Q1 = 1;
19045 Rt = 2;
19046 Rt2 = 3;
19047 }
19048
19049 constraint (inst.operands[Q0].reg != inst.operands[Q1].reg + 2,
19050 _("Index one must be [2,3] and index two must be two less than"
19051 " index one."));
19052 constraint (inst.operands[Rt].reg == inst.operands[Rt2].reg,
19053 _("General purpose registers may not be the same"));
19054 constraint (inst.operands[Rt].reg == REG_SP
19055 || inst.operands[Rt2].reg == REG_SP,
19056 BAD_SP);
19057 constraint (inst.operands[Rt].reg == REG_PC
19058 || inst.operands[Rt2].reg == REG_PC,
19059 BAD_PC);
19060
19061 inst.instruction = 0xec000f00;
19062 inst.instruction |= HI1 (inst.operands[Q1].reg / 32) << 23;
19063 inst.instruction |= !!toQ << 20;
19064 inst.instruction |= inst.operands[Rt2].reg << 16;
19065 inst.instruction |= LOW4 (inst.operands[Q1].reg / 32) << 13;
19066 inst.instruction |= (inst.operands[Q1].reg % 4) << 4;
19067 inst.instruction |= inst.operands[Rt].reg;
19068}
19069
19070static void
19071do_mve_movn (void)
19072{
19073 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19074 return;
19075
19076 if (inst.cond > COND_ALWAYS)
19077 inst.pred_insn_type = INSIDE_VPT_INSN;
19078 else
19079 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
19080
19081 struct neon_type_el et = neon_check_type (2, NS_QQ, N_EQK, N_I16 | N_I32
19082 | N_KEY);
19083
19084 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19085 inst.instruction |= (neon_logbits (et.size) - 1) << 18;
19086 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19087 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19088 inst.instruction |= LOW4 (inst.operands[1].reg);
19089 inst.is_neon = 1;
19090
19091}
19092
5287ad62
JB
19093/* VMOV has particularly many variations. It can be one of:
19094 0. VMOV<c><q> <Qd>, <Qm>
19095 1. VMOV<c><q> <Dd>, <Dm>
19096 (Register operations, which are VORR with Rm = Rn.)
19097 2. VMOV<c><q>.<dt> <Qd>, #<imm>
19098 3. VMOV<c><q>.<dt> <Dd>, #<imm>
19099 (Immediate loads.)
19100 4. VMOV<c><q>.<size> <Dn[x]>, <Rd>
19101 (ARM register to scalar.)
19102 5. VMOV<c><q> <Dm>, <Rd>, <Rn>
19103 (Two ARM registers to vector.)
19104 6. VMOV<c><q>.<dt> <Rd>, <Dn[x]>
19105 (Scalar to ARM register.)
19106 7. VMOV<c><q> <Rd>, <Rn>, <Dm>
19107 (Vector to two ARM registers.)
037e8744
JB
19108 8. VMOV.F32 <Sd>, <Sm>
19109 9. VMOV.F64 <Dd>, <Dm>
19110 (VFP register moves.)
19111 10. VMOV.F32 <Sd>, #imm
19112 11. VMOV.F64 <Dd>, #imm
19113 (VFP float immediate load.)
19114 12. VMOV <Rd>, <Sm>
19115 (VFP single to ARM reg.)
19116 13. VMOV <Sd>, <Rm>
19117 (ARM reg to VFP single.)
19118 14. VMOV <Rd>, <Re>, <Sn>, <Sm>
19119 (Two ARM regs to two VFP singles.)
19120 15. VMOV <Sd>, <Se>, <Rn>, <Rm>
19121 (Two VFP singles to two ARM regs.)
57785aa2
AV
19122 16. VMOV<c> <Rt>, <Rt2>, <Qd[idx]>, <Qd[idx2]>
19123 17. VMOV<c> <Qd[idx]>, <Qd[idx2]>, <Rt>, <Rt2>
19124 18. VMOV<c>.<dt> <Rt>, <Qn[idx]>
19125 19. VMOV<c>.<dt> <Qd[idx]>, <Rt>
5f4273c7 19126
037e8744
JB
19127 These cases can be disambiguated using neon_select_shape, except cases 1/9
19128 and 3/11 which depend on the operand type too.
5f4273c7 19129
5287ad62 19130 All the encoded bits are hardcoded by this function.
5f4273c7 19131
b7fc2769
JB
19132 Cases 4, 6 may be used with VFPv1 and above (only 32-bit transfers!).
19133 Cases 5, 7 may be used with VFPv2 and above.
5f4273c7 19134
5287ad62 19135 FIXME: Some of the checking may be a bit sloppy (in a couple of cases you
5f4273c7 19136 can specify a type where it doesn't make sense to, and is ignored). */
5287ad62
JB
19137
19138static void
19139do_neon_mov (void)
19140{
57785aa2
AV
19141 enum neon_shape rs = neon_select_shape (NS_RRSS, NS_SSRR, NS_RRFF, NS_FFRR,
19142 NS_DRR, NS_RRD, NS_QQ, NS_DD, NS_QI,
19143 NS_DI, NS_SR, NS_RS, NS_FF, NS_FI,
19144 NS_RF, NS_FR, NS_HR, NS_RH, NS_HI,
19145 NS_NULL);
037e8744
JB
19146 struct neon_type_el et;
19147 const char *ldconst = 0;
5287ad62 19148
037e8744 19149 switch (rs)
5287ad62 19150 {
037e8744
JB
19151 case NS_DD: /* case 1/9. */
19152 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
19153 /* It is not an error here if no type is given. */
19154 inst.error = NULL;
19155 if (et.type == NT_float && et.size == 64)
477330fc
RM
19156 {
19157 do_vfp_nsyn_opcode ("fcpyd");
19158 break;
19159 }
037e8744 19160 /* fall through. */
5287ad62 19161
037e8744
JB
19162 case NS_QQ: /* case 0/1. */
19163 {
57785aa2 19164 if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
477330fc
RM
19165 return;
19166 /* The architecture manual I have doesn't explicitly state which
19167 value the U bit should have for register->register moves, but
19168 the equivalent VORR instruction has U = 0, so do that. */
19169 inst.instruction = 0x0200110;
19170 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19171 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19172 inst.instruction |= LOW4 (inst.operands[1].reg);
19173 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19174 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
19175 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
19176 inst.instruction |= neon_quad (rs) << 6;
19177
19178 neon_dp_fixup (&inst);
037e8744
JB
19179 }
19180 break;
5f4273c7 19181
037e8744
JB
19182 case NS_DI: /* case 3/11. */
19183 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
19184 inst.error = NULL;
19185 if (et.type == NT_float && et.size == 64)
477330fc
RM
19186 {
19187 /* case 11 (fconstd). */
19188 ldconst = "fconstd";
19189 goto encode_fconstd;
19190 }
037e8744
JB
19191 /* fall through. */
19192
19193 case NS_QI: /* case 2/3. */
57785aa2 19194 if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
477330fc 19195 return;
037e8744
JB
19196 inst.instruction = 0x0800010;
19197 neon_move_immediate ();
88714cb8 19198 neon_dp_fixup (&inst);
5287ad62 19199 break;
5f4273c7 19200
037e8744
JB
19201 case NS_SR: /* case 4. */
19202 {
477330fc
RM
19203 unsigned bcdebits = 0;
19204 int logsize;
19205 unsigned dn = NEON_SCALAR_REG (inst.operands[0].reg);
19206 unsigned x = NEON_SCALAR_INDEX (inst.operands[0].reg);
037e8744 19207
05ac0ffb
JB
19208 /* .<size> is optional here, defaulting to .32. */
19209 if (inst.vectype.elems == 0
19210 && inst.operands[0].vectype.type == NT_invtype
19211 && inst.operands[1].vectype.type == NT_invtype)
19212 {
19213 inst.vectype.el[0].type = NT_untyped;
19214 inst.vectype.el[0].size = 32;
19215 inst.vectype.elems = 1;
19216 }
19217
477330fc
RM
19218 et = neon_check_type (2, NS_NULL, N_8 | N_16 | N_32 | N_KEY, N_EQK);
19219 logsize = neon_logbits (et.size);
19220
57785aa2
AV
19221 if (et.size != 32)
19222 {
19223 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
19224 && vfp_or_neon_is_neon (NEON_CHECK_ARCH) == FAIL)
19225 return;
19226 }
19227 else
19228 {
19229 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
19230 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
19231 _(BAD_FPU));
19232 }
19233
19234 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19235 {
19236 if (inst.operands[1].reg == REG_SP)
19237 as_tsktsk (MVE_BAD_SP);
19238 else if (inst.operands[1].reg == REG_PC)
19239 as_tsktsk (MVE_BAD_PC);
19240 }
19241 unsigned size = inst.operands[0].isscalar == 1 ? 64 : 128;
19242
477330fc 19243 constraint (et.type == NT_invtype, _("bad type for scalar"));
57785aa2
AV
19244 constraint (x >= size / et.size, _("scalar index out of range"));
19245
477330fc
RM
19246
19247 switch (et.size)
19248 {
19249 case 8: bcdebits = 0x8; break;
19250 case 16: bcdebits = 0x1; break;
19251 case 32: bcdebits = 0x0; break;
19252 default: ;
19253 }
19254
57785aa2 19255 bcdebits |= (x & ((1 << (3-logsize)) - 1)) << logsize;
477330fc
RM
19256
19257 inst.instruction = 0xe000b10;
19258 do_vfp_cond_or_thumb ();
19259 inst.instruction |= LOW4 (dn) << 16;
19260 inst.instruction |= HI1 (dn) << 7;
19261 inst.instruction |= inst.operands[1].reg << 12;
19262 inst.instruction |= (bcdebits & 3) << 5;
57785aa2
AV
19263 inst.instruction |= ((bcdebits >> 2) & 3) << 21;
19264 inst.instruction |= (x >> (3-logsize)) << 16;
037e8744
JB
19265 }
19266 break;
5f4273c7 19267
037e8744 19268 case NS_DRR: /* case 5 (fmdrr). */
57785aa2
AV
19269 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
19270 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
477330fc 19271 _(BAD_FPU));
b7fc2769 19272
037e8744
JB
19273 inst.instruction = 0xc400b10;
19274 do_vfp_cond_or_thumb ();
19275 inst.instruction |= LOW4 (inst.operands[0].reg);
19276 inst.instruction |= HI1 (inst.operands[0].reg) << 5;
19277 inst.instruction |= inst.operands[1].reg << 12;
19278 inst.instruction |= inst.operands[2].reg << 16;
19279 break;
5f4273c7 19280
037e8744
JB
19281 case NS_RS: /* case 6. */
19282 {
477330fc
RM
19283 unsigned logsize;
19284 unsigned dn = NEON_SCALAR_REG (inst.operands[1].reg);
19285 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg);
19286 unsigned abcdebits = 0;
037e8744 19287
05ac0ffb
JB
19288 /* .<dt> is optional here, defaulting to .32. */
19289 if (inst.vectype.elems == 0
19290 && inst.operands[0].vectype.type == NT_invtype
19291 && inst.operands[1].vectype.type == NT_invtype)
19292 {
19293 inst.vectype.el[0].type = NT_untyped;
19294 inst.vectype.el[0].size = 32;
19295 inst.vectype.elems = 1;
19296 }
19297
91d6fa6a
NC
19298 et = neon_check_type (2, NS_NULL,
19299 N_EQK, N_S8 | N_S16 | N_U8 | N_U16 | N_32 | N_KEY);
477330fc
RM
19300 logsize = neon_logbits (et.size);
19301
57785aa2
AV
19302 if (et.size != 32)
19303 {
19304 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
19305 && vfp_or_neon_is_neon (NEON_CHECK_CC
19306 | NEON_CHECK_ARCH) == FAIL)
19307 return;
19308 }
19309 else
19310 {
19311 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
19312 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
19313 _(BAD_FPU));
19314 }
19315
19316 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19317 {
19318 if (inst.operands[0].reg == REG_SP)
19319 as_tsktsk (MVE_BAD_SP);
19320 else if (inst.operands[0].reg == REG_PC)
19321 as_tsktsk (MVE_BAD_PC);
19322 }
19323
19324 unsigned size = inst.operands[1].isscalar == 1 ? 64 : 128;
19325
477330fc 19326 constraint (et.type == NT_invtype, _("bad type for scalar"));
57785aa2 19327 constraint (x >= size / et.size, _("scalar index out of range"));
477330fc
RM
19328
19329 switch (et.size)
19330 {
19331 case 8: abcdebits = (et.type == NT_signed) ? 0x08 : 0x18; break;
19332 case 16: abcdebits = (et.type == NT_signed) ? 0x01 : 0x11; break;
19333 case 32: abcdebits = 0x00; break;
19334 default: ;
19335 }
19336
57785aa2 19337 abcdebits |= (x & ((1 << (3-logsize)) - 1)) << logsize;
477330fc
RM
19338 inst.instruction = 0xe100b10;
19339 do_vfp_cond_or_thumb ();
19340 inst.instruction |= LOW4 (dn) << 16;
19341 inst.instruction |= HI1 (dn) << 7;
19342 inst.instruction |= inst.operands[0].reg << 12;
19343 inst.instruction |= (abcdebits & 3) << 5;
19344 inst.instruction |= (abcdebits >> 2) << 21;
57785aa2 19345 inst.instruction |= (x >> (3-logsize)) << 16;
037e8744
JB
19346 }
19347 break;
5f4273c7 19348
037e8744 19349 case NS_RRD: /* case 7 (fmrrd). */
57785aa2
AV
19350 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
19351 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
477330fc 19352 _(BAD_FPU));
037e8744
JB
19353
19354 inst.instruction = 0xc500b10;
19355 do_vfp_cond_or_thumb ();
19356 inst.instruction |= inst.operands[0].reg << 12;
19357 inst.instruction |= inst.operands[1].reg << 16;
19358 inst.instruction |= LOW4 (inst.operands[2].reg);
19359 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
19360 break;
5f4273c7 19361
037e8744
JB
19362 case NS_FF: /* case 8 (fcpys). */
19363 do_vfp_nsyn_opcode ("fcpys");
19364 break;
5f4273c7 19365
9db2f6b4 19366 case NS_HI:
037e8744
JB
19367 case NS_FI: /* case 10 (fconsts). */
19368 ldconst = "fconsts";
4ef4710f 19369 encode_fconstd:
58ed5c38
TC
19370 if (!inst.operands[1].immisfloat)
19371 {
4ef4710f 19372 unsigned new_imm;
58ed5c38 19373 /* Immediate has to fit in 8 bits so float is enough. */
4ef4710f
NC
19374 float imm = (float) inst.operands[1].imm;
19375 memcpy (&new_imm, &imm, sizeof (float));
19376 /* But the assembly may have been written to provide an integer
19377 bit pattern that equates to a float, so check that the
19378 conversion has worked. */
19379 if (is_quarter_float (new_imm))
19380 {
19381 if (is_quarter_float (inst.operands[1].imm))
19382 as_warn (_("immediate constant is valid both as a bit-pattern and a floating point value (using the fp value)"));
19383
19384 inst.operands[1].imm = new_imm;
19385 inst.operands[1].immisfloat = 1;
19386 }
58ed5c38
TC
19387 }
19388
037e8744 19389 if (is_quarter_float (inst.operands[1].imm))
477330fc
RM
19390 {
19391 inst.operands[1].imm = neon_qfloat_bits (inst.operands[1].imm);
19392 do_vfp_nsyn_opcode (ldconst);
9db2f6b4
RL
19393
19394 /* ARMv8.2 fp16 vmov.f16 instruction. */
19395 if (rs == NS_HI)
19396 do_scalar_fp16_v82_encode ();
477330fc 19397 }
5287ad62 19398 else
477330fc 19399 first_error (_("immediate out of range"));
037e8744 19400 break;
5f4273c7 19401
9db2f6b4 19402 case NS_RH:
037e8744
JB
19403 case NS_RF: /* case 12 (fmrs). */
19404 do_vfp_nsyn_opcode ("fmrs");
9db2f6b4
RL
19405 /* ARMv8.2 fp16 vmov.f16 instruction. */
19406 if (rs == NS_RH)
19407 do_scalar_fp16_v82_encode ();
037e8744 19408 break;
5f4273c7 19409
9db2f6b4 19410 case NS_HR:
037e8744
JB
19411 case NS_FR: /* case 13 (fmsr). */
19412 do_vfp_nsyn_opcode ("fmsr");
9db2f6b4
RL
19413 /* ARMv8.2 fp16 vmov.f16 instruction. */
19414 if (rs == NS_HR)
19415 do_scalar_fp16_v82_encode ();
037e8744 19416 break;
5f4273c7 19417
57785aa2
AV
19418 case NS_RRSS:
19419 do_mve_mov (0);
19420 break;
19421 case NS_SSRR:
19422 do_mve_mov (1);
19423 break;
19424
037e8744
JB
19425 /* The encoders for the fmrrs and fmsrr instructions expect three operands
19426 (one of which is a list), but we have parsed four. Do some fiddling to
19427 make the operands what do_vfp_reg2_from_sp2 and do_vfp_sp2_from_reg2
19428 expect. */
19429 case NS_RRFF: /* case 14 (fmrrs). */
57785aa2
AV
19430 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
19431 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
19432 _(BAD_FPU));
037e8744 19433 constraint (inst.operands[3].reg != inst.operands[2].reg + 1,
477330fc 19434 _("VFP registers must be adjacent"));
037e8744
JB
19435 inst.operands[2].imm = 2;
19436 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
19437 do_vfp_nsyn_opcode ("fmrrs");
19438 break;
5f4273c7 19439
037e8744 19440 case NS_FFRR: /* case 15 (fmsrr). */
57785aa2
AV
19441 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
19442 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
19443 _(BAD_FPU));
037e8744 19444 constraint (inst.operands[1].reg != inst.operands[0].reg + 1,
477330fc 19445 _("VFP registers must be adjacent"));
037e8744
JB
19446 inst.operands[1] = inst.operands[2];
19447 inst.operands[2] = inst.operands[3];
19448 inst.operands[0].imm = 2;
19449 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
19450 do_vfp_nsyn_opcode ("fmsrr");
5287ad62 19451 break;
5f4273c7 19452
4c261dff
NC
19453 case NS_NULL:
19454 /* neon_select_shape has determined that the instruction
19455 shape is wrong and has already set the error message. */
19456 break;
19457
5287ad62
JB
19458 default:
19459 abort ();
19460 }
19461}
19462
57785aa2
AV
19463static void
19464do_mve_movl (void)
19465{
19466 if (!(inst.operands[0].present && inst.operands[0].isquad
19467 && inst.operands[1].present && inst.operands[1].isquad
19468 && !inst.operands[2].present))
19469 {
19470 inst.instruction = 0;
19471 inst.cond = 0xb;
19472 if (thumb_mode)
19473 set_pred_insn_type (INSIDE_IT_INSN);
19474 do_neon_mov ();
19475 return;
19476 }
19477
19478 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19479 return;
19480
19481 if (inst.cond != COND_ALWAYS)
19482 inst.pred_insn_type = INSIDE_VPT_INSN;
19483
19484 struct neon_type_el et = neon_check_type (2, NS_QQ, N_EQK, N_S8 | N_U8
19485 | N_S16 | N_U16 | N_KEY);
19486
19487 inst.instruction |= (et.type == NT_unsigned) << 28;
19488 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19489 inst.instruction |= (neon_logbits (et.size) + 1) << 19;
19490 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19491 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19492 inst.instruction |= LOW4 (inst.operands[1].reg);
19493 inst.is_neon = 1;
19494}
19495
5287ad62
JB
19496static void
19497do_neon_rshift_round_imm (void)
19498{
037e8744 19499 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
19500 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
19501 int imm = inst.operands[2].imm;
19502
19503 /* imm == 0 case is encoded as VMOV for V{R}SHR. */
19504 if (imm == 0)
19505 {
19506 inst.operands[2].present = 0;
19507 do_neon_mov ();
19508 return;
19509 }
19510
19511 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 19512 _("immediate out of range for shift"));
037e8744 19513 neon_imm_shift (TRUE, et.type == NT_unsigned, neon_quad (rs), et,
477330fc 19514 et.size - imm);
5287ad62
JB
19515}
19516
9db2f6b4
RL
19517static void
19518do_neon_movhf (void)
19519{
19520 enum neon_shape rs = neon_select_shape (NS_HH, NS_NULL);
19521 constraint (rs != NS_HH, _("invalid suffix"));
19522
7bdf778b
ASDV
19523 if (inst.cond != COND_ALWAYS)
19524 {
19525 if (thumb_mode)
19526 {
19527 as_warn (_("ARMv8.2 scalar fp16 instruction cannot be conditional,"
19528 " the behaviour is UNPREDICTABLE"));
19529 }
19530 else
19531 {
19532 inst.error = BAD_COND;
19533 return;
19534 }
19535 }
19536
9db2f6b4
RL
19537 do_vfp_sp_monadic ();
19538
19539 inst.is_neon = 1;
19540 inst.instruction |= 0xf0000000;
19541}
19542
5287ad62
JB
19543static void
19544do_neon_movl (void)
19545{
19546 struct neon_type_el et = neon_check_type (2, NS_QD,
19547 N_EQK | N_DBL, N_SU_32 | N_KEY);
19548 unsigned sizebits = et.size >> 3;
19549 inst.instruction |= sizebits << 19;
19550 neon_two_same (0, et.type == NT_unsigned, -1);
19551}
19552
19553static void
19554do_neon_trn (void)
19555{
037e8744 19556 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
19557 struct neon_type_el et = neon_check_type (2, rs,
19558 N_EQK, N_8 | N_16 | N_32 | N_KEY);
88714cb8 19559 NEON_ENCODE (INTEGER, inst);
037e8744 19560 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19561}
19562
19563static void
19564do_neon_zip_uzp (void)
19565{
037e8744 19566 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
19567 struct neon_type_el et = neon_check_type (2, rs,
19568 N_EQK, N_8 | N_16 | N_32 | N_KEY);
19569 if (rs == NS_DD && et.size == 32)
19570 {
19571 /* Special case: encode as VTRN.32 <Dd>, <Dm>. */
19572 inst.instruction = N_MNEM_vtrn;
19573 do_neon_trn ();
19574 return;
19575 }
037e8744 19576 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19577}
19578
19579static void
19580do_neon_sat_abs_neg (void)
19581{
1a186d29
AV
19582 if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
19583 return;
19584
19585 enum neon_shape rs;
19586 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19587 rs = neon_select_shape (NS_QQ, NS_NULL);
19588 else
19589 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
19590 struct neon_type_el et = neon_check_type (2, rs,
19591 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 19592 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19593}
19594
19595static void
19596do_neon_pair_long (void)
19597{
037e8744 19598 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
19599 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_32 | N_KEY);
19600 /* Unsigned is encoded in OP field (bit 7) for these instruction. */
19601 inst.instruction |= (et.type == NT_unsigned) << 7;
037e8744 19602 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19603}
19604
19605static void
19606do_neon_recip_est (void)
19607{
037e8744 19608 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62 19609 struct neon_type_el et = neon_check_type (2, rs,
cc933301 19610 N_EQK | N_FLT, N_F_16_32 | N_U32 | N_KEY);
5287ad62 19611 inst.instruction |= (et.type == NT_float) << 8;
037e8744 19612 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19613}
19614
19615static void
19616do_neon_cls (void)
19617{
f30ee27c
AV
19618 if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
19619 return;
19620
19621 enum neon_shape rs;
19622 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19623 rs = neon_select_shape (NS_QQ, NS_NULL);
19624 else
19625 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
19626
5287ad62
JB
19627 struct neon_type_el et = neon_check_type (2, rs,
19628 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 19629 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19630}
19631
19632static void
19633do_neon_clz (void)
19634{
f30ee27c
AV
19635 if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
19636 return;
19637
19638 enum neon_shape rs;
19639 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19640 rs = neon_select_shape (NS_QQ, NS_NULL);
19641 else
19642 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
19643
5287ad62
JB
19644 struct neon_type_el et = neon_check_type (2, rs,
19645 N_EQK, N_I8 | N_I16 | N_I32 | N_KEY);
037e8744 19646 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19647}
19648
19649static void
19650do_neon_cnt (void)
19651{
037e8744 19652 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
19653 struct neon_type_el et = neon_check_type (2, rs,
19654 N_EQK | N_INT, N_8 | N_KEY);
037e8744 19655 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19656}
19657
19658static void
19659do_neon_swp (void)
19660{
037e8744
JB
19661 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
19662 neon_two_same (neon_quad (rs), 1, -1);
5287ad62
JB
19663}
19664
19665static void
19666do_neon_tbl_tbx (void)
19667{
19668 unsigned listlenbits;
dcbf9037 19669 neon_check_type (3, NS_DLD, N_EQK, N_EQK, N_8 | N_KEY);
5f4273c7 19670
5287ad62
JB
19671 if (inst.operands[1].imm < 1 || inst.operands[1].imm > 4)
19672 {
dcbf9037 19673 first_error (_("bad list length for table lookup"));
5287ad62
JB
19674 return;
19675 }
5f4273c7 19676
5287ad62
JB
19677 listlenbits = inst.operands[1].imm - 1;
19678 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19679 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19680 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
19681 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
19682 inst.instruction |= LOW4 (inst.operands[2].reg);
19683 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
19684 inst.instruction |= listlenbits << 8;
5f4273c7 19685
88714cb8 19686 neon_dp_fixup (&inst);
5287ad62
JB
19687}
19688
19689static void
19690do_neon_ldm_stm (void)
19691{
19692 /* P, U and L bits are part of bitmask. */
19693 int is_dbmode = (inst.instruction & (1 << 24)) != 0;
19694 unsigned offsetbits = inst.operands[1].imm * 2;
19695
037e8744
JB
19696 if (inst.operands[1].issingle)
19697 {
19698 do_vfp_nsyn_ldm_stm (is_dbmode);
19699 return;
19700 }
19701
5287ad62 19702 constraint (is_dbmode && !inst.operands[0].writeback,
477330fc 19703 _("writeback (!) must be used for VLDMDB and VSTMDB"));
5287ad62
JB
19704
19705 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
477330fc
RM
19706 _("register list must contain at least 1 and at most 16 "
19707 "registers"));
5287ad62
JB
19708
19709 inst.instruction |= inst.operands[0].reg << 16;
19710 inst.instruction |= inst.operands[0].writeback << 21;
19711 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
19712 inst.instruction |= HI1 (inst.operands[1].reg) << 22;
19713
19714 inst.instruction |= offsetbits;
5f4273c7 19715
037e8744 19716 do_vfp_cond_or_thumb ();
5287ad62
JB
19717}
19718
19719static void
19720do_neon_ldr_str (void)
19721{
5287ad62 19722 int is_ldr = (inst.instruction & (1 << 20)) != 0;
5f4273c7 19723
6844b2c2
MGD
19724 /* Use of PC in vstr in ARM mode is deprecated in ARMv7.
19725 And is UNPREDICTABLE in thumb mode. */
fa94de6b 19726 if (!is_ldr
6844b2c2 19727 && inst.operands[1].reg == REG_PC
ba86b375 19728 && (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7) || thumb_mode))
6844b2c2 19729 {
94dcf8bf 19730 if (thumb_mode)
6844b2c2 19731 inst.error = _("Use of PC here is UNPREDICTABLE");
94dcf8bf 19732 else if (warn_on_deprecated)
5c3696f8 19733 as_tsktsk (_("Use of PC here is deprecated"));
6844b2c2
MGD
19734 }
19735
037e8744
JB
19736 if (inst.operands[0].issingle)
19737 {
cd2f129f 19738 if (is_ldr)
477330fc 19739 do_vfp_nsyn_opcode ("flds");
cd2f129f 19740 else
477330fc 19741 do_vfp_nsyn_opcode ("fsts");
9db2f6b4
RL
19742
19743 /* ARMv8.2 vldr.16/vstr.16 instruction. */
19744 if (inst.vectype.el[0].size == 16)
19745 do_scalar_fp16_v82_encode ();
5287ad62
JB
19746 }
19747 else
5287ad62 19748 {
cd2f129f 19749 if (is_ldr)
477330fc 19750 do_vfp_nsyn_opcode ("fldd");
5287ad62 19751 else
477330fc 19752 do_vfp_nsyn_opcode ("fstd");
5287ad62 19753 }
5287ad62
JB
19754}
19755
32c36c3c
AV
19756static void
19757do_t_vldr_vstr_sysreg (void)
19758{
19759 int fp_vldr_bitno = 20, sysreg_vldr_bitno = 20;
19760 bfd_boolean is_vldr = ((inst.instruction & (1 << fp_vldr_bitno)) != 0);
19761
19762 /* Use of PC is UNPREDICTABLE. */
19763 if (inst.operands[1].reg == REG_PC)
19764 inst.error = _("Use of PC here is UNPREDICTABLE");
19765
19766 if (inst.operands[1].immisreg)
19767 inst.error = _("instruction does not accept register index");
19768
19769 if (!inst.operands[1].isreg)
19770 inst.error = _("instruction does not accept PC-relative addressing");
19771
19772 if (abs (inst.operands[1].imm) >= (1 << 7))
19773 inst.error = _("immediate value out of range");
19774
19775 inst.instruction = 0xec000f80;
19776 if (is_vldr)
19777 inst.instruction |= 1 << sysreg_vldr_bitno;
19778 encode_arm_cp_address (1, TRUE, FALSE, BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM);
19779 inst.instruction |= (inst.operands[0].imm & 0x7) << 13;
19780 inst.instruction |= (inst.operands[0].imm & 0x8) << 19;
19781}
19782
19783static void
19784do_vldr_vstr (void)
19785{
19786 bfd_boolean sysreg_op = !inst.operands[0].isreg;
19787
19788 /* VLDR/VSTR (System Register). */
19789 if (sysreg_op)
19790 {
19791 if (!mark_feature_used (&arm_ext_v8_1m_main))
19792 as_bad (_("Instruction not permitted on this architecture"));
19793
19794 do_t_vldr_vstr_sysreg ();
19795 }
19796 /* VLDR/VSTR. */
19797 else
19798 {
19799 if (!mark_feature_used (&fpu_vfp_ext_v1xd))
19800 as_bad (_("Instruction not permitted on this architecture"));
19801 do_neon_ldr_str ();
19802 }
19803}
19804
5287ad62
JB
19805/* "interleave" version also handles non-interleaving register VLD1/VST1
19806 instructions. */
19807
19808static void
19809do_neon_ld_st_interleave (void)
19810{
037e8744 19811 struct neon_type_el et = neon_check_type (1, NS_NULL,
477330fc 19812 N_8 | N_16 | N_32 | N_64);
5287ad62
JB
19813 unsigned alignbits = 0;
19814 unsigned idx;
19815 /* The bits in this table go:
19816 0: register stride of one (0) or two (1)
19817 1,2: register list length, minus one (1, 2, 3, 4).
19818 3,4: <n> in instruction type, minus one (VLD<n> / VST<n>).
19819 We use -1 for invalid entries. */
19820 const int typetable[] =
19821 {
19822 0x7, -1, 0xa, -1, 0x6, -1, 0x2, -1, /* VLD1 / VST1. */
19823 -1, -1, 0x8, 0x9, -1, -1, 0x3, -1, /* VLD2 / VST2. */
19824 -1, -1, -1, -1, 0x4, 0x5, -1, -1, /* VLD3 / VST3. */
19825 -1, -1, -1, -1, -1, -1, 0x0, 0x1 /* VLD4 / VST4. */
19826 };
19827 int typebits;
19828
dcbf9037
JB
19829 if (et.type == NT_invtype)
19830 return;
19831
5287ad62
JB
19832 if (inst.operands[1].immisalign)
19833 switch (inst.operands[1].imm >> 8)
19834 {
19835 case 64: alignbits = 1; break;
19836 case 128:
477330fc 19837 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2
e23c0ad8 19838 && NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
477330fc
RM
19839 goto bad_alignment;
19840 alignbits = 2;
19841 break;
5287ad62 19842 case 256:
477330fc
RM
19843 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
19844 goto bad_alignment;
19845 alignbits = 3;
19846 break;
5287ad62
JB
19847 default:
19848 bad_alignment:
477330fc
RM
19849 first_error (_("bad alignment"));
19850 return;
5287ad62
JB
19851 }
19852
19853 inst.instruction |= alignbits << 4;
19854 inst.instruction |= neon_logbits (et.size) << 6;
19855
19856 /* Bits [4:6] of the immediate in a list specifier encode register stride
19857 (minus 1) in bit 4, and list length in bits [5:6]. We put the <n> of
19858 VLD<n>/VST<n> in bits [9:8] of the initial bitmask. Suck it out here, look
19859 up the right value for "type" in a table based on this value and the given
19860 list style, then stick it back. */
19861 idx = ((inst.operands[0].imm >> 4) & 7)
477330fc 19862 | (((inst.instruction >> 8) & 3) << 3);
5287ad62
JB
19863
19864 typebits = typetable[idx];
5f4273c7 19865
5287ad62 19866 constraint (typebits == -1, _("bad list type for instruction"));
1d50d57c 19867 constraint (((inst.instruction >> 8) & 3) && et.size == 64,
35c228db 19868 BAD_EL_TYPE);
5287ad62
JB
19869
19870 inst.instruction &= ~0xf00;
19871 inst.instruction |= typebits << 8;
19872}
19873
19874/* Check alignment is valid for do_neon_ld_st_lane and do_neon_ld_dup.
19875 *DO_ALIGN is set to 1 if the relevant alignment bit should be set, 0
19876 otherwise. The variable arguments are a list of pairs of legal (size, align)
19877 values, terminated with -1. */
19878
19879static int
aa8a0863 19880neon_alignment_bit (int size, int align, int *do_alignment, ...)
5287ad62
JB
19881{
19882 va_list ap;
19883 int result = FAIL, thissize, thisalign;
5f4273c7 19884
5287ad62
JB
19885 if (!inst.operands[1].immisalign)
19886 {
aa8a0863 19887 *do_alignment = 0;
5287ad62
JB
19888 return SUCCESS;
19889 }
5f4273c7 19890
aa8a0863 19891 va_start (ap, do_alignment);
5287ad62
JB
19892
19893 do
19894 {
19895 thissize = va_arg (ap, int);
19896 if (thissize == -1)
477330fc 19897 break;
5287ad62
JB
19898 thisalign = va_arg (ap, int);
19899
19900 if (size == thissize && align == thisalign)
477330fc 19901 result = SUCCESS;
5287ad62
JB
19902 }
19903 while (result != SUCCESS);
19904
19905 va_end (ap);
19906
19907 if (result == SUCCESS)
aa8a0863 19908 *do_alignment = 1;
5287ad62 19909 else
dcbf9037 19910 first_error (_("unsupported alignment for instruction"));
5f4273c7 19911
5287ad62
JB
19912 return result;
19913}
19914
19915static void
19916do_neon_ld_st_lane (void)
19917{
037e8744 19918 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 19919 int align_good, do_alignment = 0;
5287ad62
JB
19920 int logsize = neon_logbits (et.size);
19921 int align = inst.operands[1].imm >> 8;
19922 int n = (inst.instruction >> 8) & 3;
19923 int max_el = 64 / et.size;
5f4273c7 19924
dcbf9037
JB
19925 if (et.type == NT_invtype)
19926 return;
5f4273c7 19927
5287ad62 19928 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != n + 1,
477330fc 19929 _("bad list length"));
5287ad62 19930 constraint (NEON_LANE (inst.operands[0].imm) >= max_el,
477330fc 19931 _("scalar index out of range"));
5287ad62 19932 constraint (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2
477330fc
RM
19933 && et.size == 8,
19934 _("stride of 2 unavailable when element size is 8"));
5f4273c7 19935
5287ad62
JB
19936 switch (n)
19937 {
19938 case 0: /* VLD1 / VST1. */
aa8a0863 19939 align_good = neon_alignment_bit (et.size, align, &do_alignment, 16, 16,
477330fc 19940 32, 32, -1);
5287ad62 19941 if (align_good == FAIL)
477330fc 19942 return;
aa8a0863 19943 if (do_alignment)
477330fc
RM
19944 {
19945 unsigned alignbits = 0;
19946 switch (et.size)
19947 {
19948 case 16: alignbits = 0x1; break;
19949 case 32: alignbits = 0x3; break;
19950 default: ;
19951 }
19952 inst.instruction |= alignbits << 4;
19953 }
5287ad62
JB
19954 break;
19955
19956 case 1: /* VLD2 / VST2. */
aa8a0863
TS
19957 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 16,
19958 16, 32, 32, 64, -1);
5287ad62 19959 if (align_good == FAIL)
477330fc 19960 return;
aa8a0863 19961 if (do_alignment)
477330fc 19962 inst.instruction |= 1 << 4;
5287ad62
JB
19963 break;
19964
19965 case 2: /* VLD3 / VST3. */
19966 constraint (inst.operands[1].immisalign,
477330fc 19967 _("can't use alignment with this instruction"));
5287ad62
JB
19968 break;
19969
19970 case 3: /* VLD4 / VST4. */
aa8a0863 19971 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc 19972 16, 64, 32, 64, 32, 128, -1);
5287ad62 19973 if (align_good == FAIL)
477330fc 19974 return;
aa8a0863 19975 if (do_alignment)
477330fc
RM
19976 {
19977 unsigned alignbits = 0;
19978 switch (et.size)
19979 {
19980 case 8: alignbits = 0x1; break;
19981 case 16: alignbits = 0x1; break;
19982 case 32: alignbits = (align == 64) ? 0x1 : 0x2; break;
19983 default: ;
19984 }
19985 inst.instruction |= alignbits << 4;
19986 }
5287ad62
JB
19987 break;
19988
19989 default: ;
19990 }
19991
19992 /* Reg stride of 2 is encoded in bit 5 when size==16, bit 6 when size==32. */
19993 if (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2)
19994 inst.instruction |= 1 << (4 + logsize);
5f4273c7 19995
5287ad62
JB
19996 inst.instruction |= NEON_LANE (inst.operands[0].imm) << (logsize + 5);
19997 inst.instruction |= logsize << 10;
19998}
19999
20000/* Encode single n-element structure to all lanes VLD<n> instructions. */
20001
20002static void
20003do_neon_ld_dup (void)
20004{
037e8744 20005 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 20006 int align_good, do_alignment = 0;
5287ad62 20007
dcbf9037
JB
20008 if (et.type == NT_invtype)
20009 return;
20010
5287ad62
JB
20011 switch ((inst.instruction >> 8) & 3)
20012 {
20013 case 0: /* VLD1. */
9c2799c2 20014 gas_assert (NEON_REG_STRIDE (inst.operands[0].imm) != 2);
5287ad62 20015 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863 20016 &do_alignment, 16, 16, 32, 32, -1);
5287ad62 20017 if (align_good == FAIL)
477330fc 20018 return;
5287ad62 20019 switch (NEON_REGLIST_LENGTH (inst.operands[0].imm))
477330fc
RM
20020 {
20021 case 1: break;
20022 case 2: inst.instruction |= 1 << 5; break;
20023 default: first_error (_("bad list length")); return;
20024 }
5287ad62
JB
20025 inst.instruction |= neon_logbits (et.size) << 6;
20026 break;
20027
20028 case 1: /* VLD2. */
20029 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863
TS
20030 &do_alignment, 8, 16, 16, 32, 32, 64,
20031 -1);
5287ad62 20032 if (align_good == FAIL)
477330fc 20033 return;
5287ad62 20034 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2,
477330fc 20035 _("bad list length"));
5287ad62 20036 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 20037 inst.instruction |= 1 << 5;
5287ad62
JB
20038 inst.instruction |= neon_logbits (et.size) << 6;
20039 break;
20040
20041 case 2: /* VLD3. */
20042 constraint (inst.operands[1].immisalign,
477330fc 20043 _("can't use alignment with this instruction"));
5287ad62 20044 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 3,
477330fc 20045 _("bad list length"));
5287ad62 20046 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 20047 inst.instruction |= 1 << 5;
5287ad62
JB
20048 inst.instruction |= neon_logbits (et.size) << 6;
20049 break;
20050
20051 case 3: /* VLD4. */
20052 {
477330fc 20053 int align = inst.operands[1].imm >> 8;
aa8a0863 20054 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc
RM
20055 16, 64, 32, 64, 32, 128, -1);
20056 if (align_good == FAIL)
20057 return;
20058 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4,
20059 _("bad list length"));
20060 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
20061 inst.instruction |= 1 << 5;
20062 if (et.size == 32 && align == 128)
20063 inst.instruction |= 0x3 << 6;
20064 else
20065 inst.instruction |= neon_logbits (et.size) << 6;
5287ad62
JB
20066 }
20067 break;
20068
20069 default: ;
20070 }
20071
aa8a0863 20072 inst.instruction |= do_alignment << 4;
5287ad62
JB
20073}
20074
20075/* Disambiguate VLD<n> and VST<n> instructions, and fill in common bits (those
20076 apart from bits [11:4]. */
20077
20078static void
20079do_neon_ldx_stx (void)
20080{
b1a769ed
DG
20081 if (inst.operands[1].isreg)
20082 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
20083
5287ad62
JB
20084 switch (NEON_LANE (inst.operands[0].imm))
20085 {
20086 case NEON_INTERLEAVE_LANES:
88714cb8 20087 NEON_ENCODE (INTERLV, inst);
5287ad62
JB
20088 do_neon_ld_st_interleave ();
20089 break;
5f4273c7 20090
5287ad62 20091 case NEON_ALL_LANES:
88714cb8 20092 NEON_ENCODE (DUP, inst);
2d51fb74
JB
20093 if (inst.instruction == N_INV)
20094 {
20095 first_error ("only loads support such operands");
20096 break;
20097 }
5287ad62
JB
20098 do_neon_ld_dup ();
20099 break;
5f4273c7 20100
5287ad62 20101 default:
88714cb8 20102 NEON_ENCODE (LANE, inst);
5287ad62
JB
20103 do_neon_ld_st_lane ();
20104 }
20105
20106 /* L bit comes from bit mask. */
20107 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20108 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20109 inst.instruction |= inst.operands[1].reg << 16;
5f4273c7 20110
5287ad62
JB
20111 if (inst.operands[1].postind)
20112 {
20113 int postreg = inst.operands[1].imm & 0xf;
20114 constraint (!inst.operands[1].immisreg,
477330fc 20115 _("post-index must be a register"));
5287ad62 20116 constraint (postreg == 0xd || postreg == 0xf,
477330fc 20117 _("bad register for post-index"));
5287ad62
JB
20118 inst.instruction |= postreg;
20119 }
4f2374c7 20120 else
5287ad62 20121 {
4f2374c7 20122 constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
e2b0ab59
AV
20123 constraint (inst.relocs[0].exp.X_op != O_constant
20124 || inst.relocs[0].exp.X_add_number != 0,
4f2374c7
WN
20125 BAD_ADDR_MODE);
20126
20127 if (inst.operands[1].writeback)
20128 {
20129 inst.instruction |= 0xd;
20130 }
20131 else
20132 inst.instruction |= 0xf;
5287ad62 20133 }
5f4273c7 20134
5287ad62
JB
20135 if (thumb_mode)
20136 inst.instruction |= 0xf9000000;
20137 else
20138 inst.instruction |= 0xf4000000;
20139}
33399f07
MGD
20140
20141/* FP v8. */
20142static void
20143do_vfp_nsyn_fpv8 (enum neon_shape rs)
20144{
a715796b
TG
20145 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
20146 D register operands. */
20147 if (neon_shape_class[rs] == SC_DOUBLE)
20148 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
20149 _(BAD_FPU));
20150
33399f07
MGD
20151 NEON_ENCODE (FPV8, inst);
20152
9db2f6b4
RL
20153 if (rs == NS_FFF || rs == NS_HHH)
20154 {
20155 do_vfp_sp_dyadic ();
20156
20157 /* ARMv8.2 fp16 instruction. */
20158 if (rs == NS_HHH)
20159 do_scalar_fp16_v82_encode ();
20160 }
33399f07
MGD
20161 else
20162 do_vfp_dp_rd_rn_rm ();
20163
20164 if (rs == NS_DDD)
20165 inst.instruction |= 0x100;
20166
20167 inst.instruction |= 0xf0000000;
20168}
20169
20170static void
20171do_vsel (void)
20172{
5ee91343 20173 set_pred_insn_type (OUTSIDE_PRED_INSN);
33399f07
MGD
20174
20175 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) != SUCCESS)
20176 first_error (_("invalid instruction shape"));
20177}
20178
73924fbc
MGD
20179static void
20180do_vmaxnm (void)
20181{
935295b5
AV
20182 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20183 set_pred_insn_type (OUTSIDE_PRED_INSN);
73924fbc
MGD
20184
20185 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) == SUCCESS)
20186 return;
20187
935295b5 20188 if (check_simd_pred_availability (1, NEON_CHECK_CC | NEON_CHECK_ARCH8))
73924fbc
MGD
20189 return;
20190
cc933301 20191 neon_dyadic_misc (NT_untyped, N_F_16_32, 0);
73924fbc
MGD
20192}
20193
30bdf752
MGD
20194static void
20195do_vrint_1 (enum neon_cvt_mode mode)
20196{
9db2f6b4 20197 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_QQ, NS_NULL);
30bdf752
MGD
20198 struct neon_type_el et;
20199
20200 if (rs == NS_NULL)
20201 return;
20202
a715796b
TG
20203 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
20204 D register operands. */
20205 if (neon_shape_class[rs] == SC_DOUBLE)
20206 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
20207 _(BAD_FPU));
20208
9db2f6b4
RL
20209 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY
20210 | N_VFP);
30bdf752
MGD
20211 if (et.type != NT_invtype)
20212 {
20213 /* VFP encodings. */
20214 if (mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
20215 || mode == neon_cvt_mode_p || mode == neon_cvt_mode_m)
5ee91343 20216 set_pred_insn_type (OUTSIDE_PRED_INSN);
30bdf752
MGD
20217
20218 NEON_ENCODE (FPV8, inst);
9db2f6b4 20219 if (rs == NS_FF || rs == NS_HH)
30bdf752
MGD
20220 do_vfp_sp_monadic ();
20221 else
20222 do_vfp_dp_rd_rm ();
20223
20224 switch (mode)
20225 {
20226 case neon_cvt_mode_r: inst.instruction |= 0x00000000; break;
20227 case neon_cvt_mode_z: inst.instruction |= 0x00000080; break;
20228 case neon_cvt_mode_x: inst.instruction |= 0x00010000; break;
20229 case neon_cvt_mode_a: inst.instruction |= 0xf0000000; break;
20230 case neon_cvt_mode_n: inst.instruction |= 0xf0010000; break;
20231 case neon_cvt_mode_p: inst.instruction |= 0xf0020000; break;
20232 case neon_cvt_mode_m: inst.instruction |= 0xf0030000; break;
20233 default: abort ();
20234 }
20235
20236 inst.instruction |= (rs == NS_DD) << 8;
20237 do_vfp_cond_or_thumb ();
9db2f6b4
RL
20238
20239 /* ARMv8.2 fp16 vrint instruction. */
20240 if (rs == NS_HH)
20241 do_scalar_fp16_v82_encode ();
30bdf752
MGD
20242 }
20243 else
20244 {
20245 /* Neon encodings (or something broken...). */
20246 inst.error = NULL;
cc933301 20247 et = neon_check_type (2, rs, N_EQK, N_F_16_32 | N_KEY);
30bdf752
MGD
20248
20249 if (et.type == NT_invtype)
20250 return;
20251
5ee91343 20252 set_pred_insn_type (OUTSIDE_PRED_INSN);
30bdf752
MGD
20253 NEON_ENCODE (FLOAT, inst);
20254
20255 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH8) == FAIL)
20256 return;
20257
20258 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20259 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20260 inst.instruction |= LOW4 (inst.operands[1].reg);
20261 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
20262 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
20263 /* Mask off the original size bits and reencode them. */
20264 inst.instruction = ((inst.instruction & 0xfff3ffff)
20265 | neon_logbits (et.size) << 18);
20266
30bdf752
MGD
20267 switch (mode)
20268 {
20269 case neon_cvt_mode_z: inst.instruction |= 3 << 7; break;
20270 case neon_cvt_mode_x: inst.instruction |= 1 << 7; break;
20271 case neon_cvt_mode_a: inst.instruction |= 2 << 7; break;
20272 case neon_cvt_mode_n: inst.instruction |= 0 << 7; break;
20273 case neon_cvt_mode_p: inst.instruction |= 7 << 7; break;
20274 case neon_cvt_mode_m: inst.instruction |= 5 << 7; break;
20275 case neon_cvt_mode_r: inst.error = _("invalid rounding mode"); break;
20276 default: abort ();
20277 }
20278
20279 if (thumb_mode)
20280 inst.instruction |= 0xfc000000;
20281 else
20282 inst.instruction |= 0xf0000000;
20283 }
20284}
20285
20286static void
20287do_vrintx (void)
20288{
20289 do_vrint_1 (neon_cvt_mode_x);
20290}
20291
20292static void
20293do_vrintz (void)
20294{
20295 do_vrint_1 (neon_cvt_mode_z);
20296}
20297
20298static void
20299do_vrintr (void)
20300{
20301 do_vrint_1 (neon_cvt_mode_r);
20302}
20303
20304static void
20305do_vrinta (void)
20306{
20307 do_vrint_1 (neon_cvt_mode_a);
20308}
20309
20310static void
20311do_vrintn (void)
20312{
20313 do_vrint_1 (neon_cvt_mode_n);
20314}
20315
20316static void
20317do_vrintp (void)
20318{
20319 do_vrint_1 (neon_cvt_mode_p);
20320}
20321
20322static void
20323do_vrintm (void)
20324{
20325 do_vrint_1 (neon_cvt_mode_m);
20326}
20327
c28eeff2
SN
20328static unsigned
20329neon_scalar_for_vcmla (unsigned opnd, unsigned elsize)
20330{
20331 unsigned regno = NEON_SCALAR_REG (opnd);
20332 unsigned elno = NEON_SCALAR_INDEX (opnd);
20333
20334 if (elsize == 16 && elno < 2 && regno < 16)
20335 return regno | (elno << 4);
20336 else if (elsize == 32 && elno == 0)
20337 return regno;
20338
20339 first_error (_("scalar out of range"));
20340 return 0;
20341}
20342
20343static void
20344do_vcmla (void)
20345{
5d281bf0
AV
20346 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext)
20347 && (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8)
20348 || !mark_feature_used (&arm_ext_v8_3)), (BAD_FPU));
e2b0ab59
AV
20349 constraint (inst.relocs[0].exp.X_op != O_constant,
20350 _("expression too complex"));
20351 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2
SN
20352 constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
20353 _("immediate out of range"));
20354 rot /= 90;
5d281bf0
AV
20355
20356 if (check_simd_pred_availability (1, NEON_CHECK_ARCH8 | NEON_CHECK_CC))
20357 return;
20358
c28eeff2
SN
20359 if (inst.operands[2].isscalar)
20360 {
5d281bf0
AV
20361 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
20362 first_error (_("invalid instruction shape"));
c28eeff2
SN
20363 enum neon_shape rs = neon_select_shape (NS_DDSI, NS_QQSI, NS_NULL);
20364 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
20365 N_KEY | N_F16 | N_F32).size;
20366 unsigned m = neon_scalar_for_vcmla (inst.operands[2].reg, size);
20367 inst.is_neon = 1;
20368 inst.instruction = 0xfe000800;
20369 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20370 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20371 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
20372 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
20373 inst.instruction |= LOW4 (m);
20374 inst.instruction |= HI1 (m) << 5;
20375 inst.instruction |= neon_quad (rs) << 6;
20376 inst.instruction |= rot << 20;
20377 inst.instruction |= (size == 32) << 23;
20378 }
20379 else
20380 {
5d281bf0
AV
20381 enum neon_shape rs;
20382 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
20383 rs = neon_select_shape (NS_QQQI, NS_NULL);
20384 else
20385 rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
20386
c28eeff2
SN
20387 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
20388 N_KEY | N_F16 | N_F32).size;
5d281bf0
AV
20389 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext) && size == 32
20390 && (inst.operands[0].reg == inst.operands[1].reg
20391 || inst.operands[0].reg == inst.operands[2].reg))
20392 as_tsktsk (BAD_MVE_SRCDEST);
20393
c28eeff2
SN
20394 neon_three_same (neon_quad (rs), 0, -1);
20395 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
20396 inst.instruction |= 0xfc200800;
20397 inst.instruction |= rot << 23;
20398 inst.instruction |= (size == 32) << 20;
20399 }
20400}
20401
20402static void
20403do_vcadd (void)
20404{
5d281bf0
AV
20405 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
20406 && (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8)
20407 || !mark_feature_used (&arm_ext_v8_3)), (BAD_FPU));
e2b0ab59
AV
20408 constraint (inst.relocs[0].exp.X_op != O_constant,
20409 _("expression too complex"));
5d281bf0 20410
e2b0ab59 20411 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2 20412 constraint (rot != 90 && rot != 270, _("immediate out of range"));
5d281bf0
AV
20413 enum neon_shape rs;
20414 struct neon_type_el et;
20415 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20416 {
20417 rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
20418 et = neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16 | N_F32);
20419 }
20420 else
20421 {
20422 rs = neon_select_shape (NS_QQQI, NS_NULL);
20423 et = neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16 | N_F32 | N_I8
20424 | N_I16 | N_I32);
20425 if (et.size == 32 && inst.operands[0].reg == inst.operands[2].reg)
20426 as_tsktsk (_("Warning: 32-bit element size and same first and third "
20427 "operand makes instruction UNPREDICTABLE"));
20428 }
20429
20430 if (et.type == NT_invtype)
20431 return;
20432
20433 if (check_simd_pred_availability (et.type == NT_float, NEON_CHECK_ARCH8
20434 | NEON_CHECK_CC))
20435 return;
20436
20437 if (et.type == NT_float)
20438 {
20439 neon_three_same (neon_quad (rs), 0, -1);
20440 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
20441 inst.instruction |= 0xfc800800;
20442 inst.instruction |= (rot == 270) << 24;
20443 inst.instruction |= (et.size == 32) << 20;
20444 }
20445 else
20446 {
20447 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
20448 inst.instruction = 0xfe000f00;
20449 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20450 inst.instruction |= neon_logbits (et.size) << 20;
20451 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
20452 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20453 inst.instruction |= (rot == 270) << 12;
20454 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
20455 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
20456 inst.instruction |= LOW4 (inst.operands[2].reg);
20457 inst.is_neon = 1;
20458 }
c28eeff2
SN
20459}
20460
c604a79a
JW
20461/* Dot Product instructions encoding support. */
20462
20463static void
20464do_neon_dotproduct (int unsigned_p)
20465{
20466 enum neon_shape rs;
20467 unsigned scalar_oprd2 = 0;
20468 int high8;
20469
20470 if (inst.cond != COND_ALWAYS)
20471 as_warn (_("Dot Product instructions cannot be conditional, the behaviour "
20472 "is UNPREDICTABLE"));
20473
20474 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
20475 _(BAD_FPU));
20476
20477 /* Dot Product instructions are in three-same D/Q register format or the third
20478 operand can be a scalar index register. */
20479 if (inst.operands[2].isscalar)
20480 {
20481 scalar_oprd2 = neon_scalar_for_mul (inst.operands[2].reg, 32);
20482 high8 = 0xfe000000;
20483 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
20484 }
20485 else
20486 {
20487 high8 = 0xfc000000;
20488 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
20489 }
20490
20491 if (unsigned_p)
20492 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_U8);
20493 else
20494 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_S8);
20495
20496 /* The "U" bit in traditional Three Same encoding is fixed to 0 for Dot
20497 Product instruction, so we pass 0 as the "ubit" parameter. And the
20498 "Size" field are fixed to 0x2, so we pass 32 as the "size" parameter. */
20499 neon_three_same (neon_quad (rs), 0, 32);
20500
20501 /* Undo neon_dp_fixup. Dot Product instructions are using a slightly
20502 different NEON three-same encoding. */
20503 inst.instruction &= 0x00ffffff;
20504 inst.instruction |= high8;
20505 /* Encode 'U' bit which indicates signedness. */
20506 inst.instruction |= (unsigned_p ? 1 : 0) << 4;
20507 /* Re-encode operand2 if it's indexed scalar operand. What has been encoded
20508 from inst.operand[2].reg in neon_three_same is GAS's internal encoding, not
20509 the instruction encoding. */
20510 if (inst.operands[2].isscalar)
20511 {
20512 inst.instruction &= 0xffffffd0;
20513 inst.instruction |= LOW4 (scalar_oprd2);
20514 inst.instruction |= HI1 (scalar_oprd2) << 5;
20515 }
20516}
20517
20518/* Dot Product instructions for signed integer. */
20519
20520static void
20521do_neon_dotproduct_s (void)
20522{
20523 return do_neon_dotproduct (0);
20524}
20525
20526/* Dot Product instructions for unsigned integer. */
20527
20528static void
20529do_neon_dotproduct_u (void)
20530{
20531 return do_neon_dotproduct (1);
20532}
20533
91ff7894
MGD
20534/* Crypto v1 instructions. */
20535static void
20536do_crypto_2op_1 (unsigned elttype, int op)
20537{
5ee91343 20538 set_pred_insn_type (OUTSIDE_PRED_INSN);
91ff7894
MGD
20539
20540 if (neon_check_type (2, NS_QQ, N_EQK | N_UNT, elttype | N_UNT | N_KEY).type
20541 == NT_invtype)
20542 return;
20543
20544 inst.error = NULL;
20545
20546 NEON_ENCODE (INTEGER, inst);
20547 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20548 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20549 inst.instruction |= LOW4 (inst.operands[1].reg);
20550 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
20551 if (op != -1)
20552 inst.instruction |= op << 6;
20553
20554 if (thumb_mode)
20555 inst.instruction |= 0xfc000000;
20556 else
20557 inst.instruction |= 0xf0000000;
20558}
20559
48adcd8e
MGD
20560static void
20561do_crypto_3op_1 (int u, int op)
20562{
5ee91343 20563 set_pred_insn_type (OUTSIDE_PRED_INSN);
48adcd8e
MGD
20564
20565 if (neon_check_type (3, NS_QQQ, N_EQK | N_UNT, N_EQK | N_UNT,
20566 N_32 | N_UNT | N_KEY).type == NT_invtype)
20567 return;
20568
20569 inst.error = NULL;
20570
20571 NEON_ENCODE (INTEGER, inst);
20572 neon_three_same (1, u, 8 << op);
20573}
20574
91ff7894
MGD
20575static void
20576do_aese (void)
20577{
20578 do_crypto_2op_1 (N_8, 0);
20579}
20580
20581static void
20582do_aesd (void)
20583{
20584 do_crypto_2op_1 (N_8, 1);
20585}
20586
20587static void
20588do_aesmc (void)
20589{
20590 do_crypto_2op_1 (N_8, 2);
20591}
20592
20593static void
20594do_aesimc (void)
20595{
20596 do_crypto_2op_1 (N_8, 3);
20597}
20598
48adcd8e
MGD
20599static void
20600do_sha1c (void)
20601{
20602 do_crypto_3op_1 (0, 0);
20603}
20604
20605static void
20606do_sha1p (void)
20607{
20608 do_crypto_3op_1 (0, 1);
20609}
20610
20611static void
20612do_sha1m (void)
20613{
20614 do_crypto_3op_1 (0, 2);
20615}
20616
20617static void
20618do_sha1su0 (void)
20619{
20620 do_crypto_3op_1 (0, 3);
20621}
91ff7894 20622
48adcd8e
MGD
20623static void
20624do_sha256h (void)
20625{
20626 do_crypto_3op_1 (1, 0);
20627}
20628
20629static void
20630do_sha256h2 (void)
20631{
20632 do_crypto_3op_1 (1, 1);
20633}
20634
20635static void
20636do_sha256su1 (void)
20637{
20638 do_crypto_3op_1 (1, 2);
20639}
3c9017d2
MGD
20640
20641static void
20642do_sha1h (void)
20643{
20644 do_crypto_2op_1 (N_32, -1);
20645}
20646
20647static void
20648do_sha1su1 (void)
20649{
20650 do_crypto_2op_1 (N_32, 0);
20651}
20652
20653static void
20654do_sha256su0 (void)
20655{
20656 do_crypto_2op_1 (N_32, 1);
20657}
dd5181d5
KT
20658
20659static void
20660do_crc32_1 (unsigned int poly, unsigned int sz)
20661{
20662 unsigned int Rd = inst.operands[0].reg;
20663 unsigned int Rn = inst.operands[1].reg;
20664 unsigned int Rm = inst.operands[2].reg;
20665
5ee91343 20666 set_pred_insn_type (OUTSIDE_PRED_INSN);
dd5181d5
KT
20667 inst.instruction |= LOW4 (Rd) << (thumb_mode ? 8 : 12);
20668 inst.instruction |= LOW4 (Rn) << 16;
20669 inst.instruction |= LOW4 (Rm);
20670 inst.instruction |= sz << (thumb_mode ? 4 : 21);
20671 inst.instruction |= poly << (thumb_mode ? 20 : 9);
20672
20673 if (Rd == REG_PC || Rn == REG_PC || Rm == REG_PC)
20674 as_warn (UNPRED_REG ("r15"));
dd5181d5
KT
20675}
20676
20677static void
20678do_crc32b (void)
20679{
20680 do_crc32_1 (0, 0);
20681}
20682
20683static void
20684do_crc32h (void)
20685{
20686 do_crc32_1 (0, 1);
20687}
20688
20689static void
20690do_crc32w (void)
20691{
20692 do_crc32_1 (0, 2);
20693}
20694
20695static void
20696do_crc32cb (void)
20697{
20698 do_crc32_1 (1, 0);
20699}
20700
20701static void
20702do_crc32ch (void)
20703{
20704 do_crc32_1 (1, 1);
20705}
20706
20707static void
20708do_crc32cw (void)
20709{
20710 do_crc32_1 (1, 2);
20711}
20712
49e8a725
SN
20713static void
20714do_vjcvt (void)
20715{
20716 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
20717 _(BAD_FPU));
20718 neon_check_type (2, NS_FD, N_S32, N_F64);
20719 do_vfp_sp_dp_cvt ();
20720 do_vfp_cond_or_thumb ();
20721}
20722
5287ad62
JB
20723\f
20724/* Overall per-instruction processing. */
20725
20726/* We need to be able to fix up arbitrary expressions in some statements.
20727 This is so that we can handle symbols that are an arbitrary distance from
20728 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
20729 which returns part of an address in a form which will be valid for
20730 a data instruction. We do this by pushing the expression into a symbol
20731 in the expr_section, and creating a fix for that. */
20732
20733static void
20734fix_new_arm (fragS * frag,
20735 int where,
20736 short int size,
20737 expressionS * exp,
20738 int pc_rel,
20739 int reloc)
20740{
20741 fixS * new_fix;
20742
20743 switch (exp->X_op)
20744 {
20745 case O_constant:
6e7ce2cd
PB
20746 if (pc_rel)
20747 {
20748 /* Create an absolute valued symbol, so we have something to
477330fc
RM
20749 refer to in the object file. Unfortunately for us, gas's
20750 generic expression parsing will already have folded out
20751 any use of .set foo/.type foo %function that may have
20752 been used to set type information of the target location,
20753 that's being specified symbolically. We have to presume
20754 the user knows what they are doing. */
6e7ce2cd
PB
20755 char name[16 + 8];
20756 symbolS *symbol;
20757
20758 sprintf (name, "*ABS*0x%lx", (unsigned long)exp->X_add_number);
20759
20760 symbol = symbol_find_or_make (name);
20761 S_SET_SEGMENT (symbol, absolute_section);
20762 symbol_set_frag (symbol, &zero_address_frag);
20763 S_SET_VALUE (symbol, exp->X_add_number);
20764 exp->X_op = O_symbol;
20765 exp->X_add_symbol = symbol;
20766 exp->X_add_number = 0;
20767 }
20768 /* FALLTHROUGH */
5287ad62
JB
20769 case O_symbol:
20770 case O_add:
20771 case O_subtract:
21d799b5 20772 new_fix = fix_new_exp (frag, where, size, exp, pc_rel,
477330fc 20773 (enum bfd_reloc_code_real) reloc);
5287ad62
JB
20774 break;
20775
20776 default:
21d799b5 20777 new_fix = (fixS *) fix_new (frag, where, size, make_expr_symbol (exp), 0,
477330fc 20778 pc_rel, (enum bfd_reloc_code_real) reloc);
5287ad62
JB
20779 break;
20780 }
20781
20782 /* Mark whether the fix is to a THUMB instruction, or an ARM
20783 instruction. */
20784 new_fix->tc_fix_data = thumb_mode;
20785}
20786
20787/* Create a frg for an instruction requiring relaxation. */
20788static void
20789output_relax_insn (void)
20790{
20791 char * to;
20792 symbolS *sym;
0110f2b8
PB
20793 int offset;
20794
6e1cb1a6
PB
20795 /* The size of the instruction is unknown, so tie the debug info to the
20796 start of the instruction. */
20797 dwarf2_emit_insn (0);
6e1cb1a6 20798
e2b0ab59 20799 switch (inst.relocs[0].exp.X_op)
0110f2b8
PB
20800 {
20801 case O_symbol:
e2b0ab59
AV
20802 sym = inst.relocs[0].exp.X_add_symbol;
20803 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
20804 break;
20805 case O_constant:
20806 sym = NULL;
e2b0ab59 20807 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
20808 break;
20809 default:
e2b0ab59 20810 sym = make_expr_symbol (&inst.relocs[0].exp);
0110f2b8
PB
20811 offset = 0;
20812 break;
20813 }
20814 to = frag_var (rs_machine_dependent, INSN_SIZE, THUMB_SIZE,
20815 inst.relax, sym, offset, NULL/*offset, opcode*/);
20816 md_number_to_chars (to, inst.instruction, THUMB_SIZE);
0110f2b8
PB
20817}
20818
20819/* Write a 32-bit thumb instruction to buf. */
20820static void
20821put_thumb32_insn (char * buf, unsigned long insn)
20822{
20823 md_number_to_chars (buf, insn >> 16, THUMB_SIZE);
20824 md_number_to_chars (buf + THUMB_SIZE, insn, THUMB_SIZE);
20825}
20826
b99bd4ef 20827static void
c19d1205 20828output_inst (const char * str)
b99bd4ef 20829{
c19d1205 20830 char * to = NULL;
b99bd4ef 20831
c19d1205 20832 if (inst.error)
b99bd4ef 20833 {
c19d1205 20834 as_bad ("%s -- `%s'", inst.error, str);
b99bd4ef
NC
20835 return;
20836 }
5f4273c7
NC
20837 if (inst.relax)
20838 {
20839 output_relax_insn ();
0110f2b8 20840 return;
5f4273c7 20841 }
c19d1205
ZW
20842 if (inst.size == 0)
20843 return;
b99bd4ef 20844
c19d1205 20845 to = frag_more (inst.size);
8dc2430f
NC
20846 /* PR 9814: Record the thumb mode into the current frag so that we know
20847 what type of NOP padding to use, if necessary. We override any previous
20848 setting so that if the mode has changed then the NOPS that we use will
20849 match the encoding of the last instruction in the frag. */
cd000bff 20850 frag_now->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
c19d1205
ZW
20851
20852 if (thumb_mode && (inst.size > THUMB_SIZE))
b99bd4ef 20853 {
9c2799c2 20854 gas_assert (inst.size == (2 * THUMB_SIZE));
0110f2b8 20855 put_thumb32_insn (to, inst.instruction);
b99bd4ef 20856 }
c19d1205 20857 else if (inst.size > INSN_SIZE)
b99bd4ef 20858 {
9c2799c2 20859 gas_assert (inst.size == (2 * INSN_SIZE));
c19d1205
ZW
20860 md_number_to_chars (to, inst.instruction, INSN_SIZE);
20861 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
b99bd4ef 20862 }
c19d1205
ZW
20863 else
20864 md_number_to_chars (to, inst.instruction, inst.size);
b99bd4ef 20865
e2b0ab59
AV
20866 int r;
20867 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
20868 {
20869 if (inst.relocs[r].type != BFD_RELOC_UNUSED)
20870 fix_new_arm (frag_now, to - frag_now->fr_literal,
20871 inst.size, & inst.relocs[r].exp, inst.relocs[r].pc_rel,
20872 inst.relocs[r].type);
20873 }
b99bd4ef 20874
c19d1205 20875 dwarf2_emit_insn (inst.size);
c19d1205 20876}
b99bd4ef 20877
e07e6e58
NC
20878static char *
20879output_it_inst (int cond, int mask, char * to)
20880{
20881 unsigned long instruction = 0xbf00;
20882
20883 mask &= 0xf;
20884 instruction |= mask;
20885 instruction |= cond << 4;
20886
20887 if (to == NULL)
20888 {
20889 to = frag_more (2);
20890#ifdef OBJ_ELF
20891 dwarf2_emit_insn (2);
20892#endif
20893 }
20894
20895 md_number_to_chars (to, instruction, 2);
20896
20897 return to;
20898}
20899
c19d1205
ZW
20900/* Tag values used in struct asm_opcode's tag field. */
20901enum opcode_tag
20902{
20903 OT_unconditional, /* Instruction cannot be conditionalized.
20904 The ARM condition field is still 0xE. */
20905 OT_unconditionalF, /* Instruction cannot be conditionalized
20906 and carries 0xF in its ARM condition field. */
20907 OT_csuffix, /* Instruction takes a conditional suffix. */
5ee91343
AV
20908 OT_csuffixF, /* Some forms of the instruction take a scalar
20909 conditional suffix, others place 0xF where the
20910 condition field would be, others take a vector
20911 conditional suffix. */
c19d1205
ZW
20912 OT_cinfix3, /* Instruction takes a conditional infix,
20913 beginning at character index 3. (In
20914 unified mode, it becomes a suffix.) */
088fa78e
KH
20915 OT_cinfix3_deprecated, /* The same as OT_cinfix3. This is used for
20916 tsts, cmps, cmns, and teqs. */
e3cb604e
PB
20917 OT_cinfix3_legacy, /* Legacy instruction takes a conditional infix at
20918 character index 3, even in unified mode. Used for
20919 legacy instructions where suffix and infix forms
20920 may be ambiguous. */
c19d1205 20921 OT_csuf_or_in3, /* Instruction takes either a conditional
e3cb604e 20922 suffix or an infix at character index 3. */
c19d1205
ZW
20923 OT_odd_infix_unc, /* This is the unconditional variant of an
20924 instruction that takes a conditional infix
20925 at an unusual position. In unified mode,
20926 this variant will accept a suffix. */
20927 OT_odd_infix_0 /* Values greater than or equal to OT_odd_infix_0
20928 are the conditional variants of instructions that
20929 take conditional infixes in unusual positions.
20930 The infix appears at character index
20931 (tag - OT_odd_infix_0). These are not accepted
20932 in unified mode. */
20933};
b99bd4ef 20934
c19d1205
ZW
20935/* Subroutine of md_assemble, responsible for looking up the primary
20936 opcode from the mnemonic the user wrote. STR points to the
20937 beginning of the mnemonic.
20938
20939 This is not simply a hash table lookup, because of conditional
20940 variants. Most instructions have conditional variants, which are
20941 expressed with a _conditional affix_ to the mnemonic. If we were
20942 to encode each conditional variant as a literal string in the opcode
20943 table, it would have approximately 20,000 entries.
20944
20945 Most mnemonics take this affix as a suffix, and in unified syntax,
20946 'most' is upgraded to 'all'. However, in the divided syntax, some
20947 instructions take the affix as an infix, notably the s-variants of
20948 the arithmetic instructions. Of those instructions, all but six
20949 have the infix appear after the third character of the mnemonic.
20950
20951 Accordingly, the algorithm for looking up primary opcodes given
20952 an identifier is:
20953
20954 1. Look up the identifier in the opcode table.
20955 If we find a match, go to step U.
20956
20957 2. Look up the last two characters of the identifier in the
20958 conditions table. If we find a match, look up the first N-2
20959 characters of the identifier in the opcode table. If we
20960 find a match, go to step CE.
20961
20962 3. Look up the fourth and fifth characters of the identifier in
20963 the conditions table. If we find a match, extract those
20964 characters from the identifier, and look up the remaining
20965 characters in the opcode table. If we find a match, go
20966 to step CM.
20967
20968 4. Fail.
20969
20970 U. Examine the tag field of the opcode structure, in case this is
20971 one of the six instructions with its conditional infix in an
20972 unusual place. If it is, the tag tells us where to find the
20973 infix; look it up in the conditions table and set inst.cond
20974 accordingly. Otherwise, this is an unconditional instruction.
20975 Again set inst.cond accordingly. Return the opcode structure.
20976
20977 CE. Examine the tag field to make sure this is an instruction that
20978 should receive a conditional suffix. If it is not, fail.
20979 Otherwise, set inst.cond from the suffix we already looked up,
20980 and return the opcode structure.
20981
20982 CM. Examine the tag field to make sure this is an instruction that
20983 should receive a conditional infix after the third character.
20984 If it is not, fail. Otherwise, undo the edits to the current
20985 line of input and proceed as for case CE. */
20986
20987static const struct asm_opcode *
20988opcode_lookup (char **str)
20989{
20990 char *end, *base;
20991 char *affix;
20992 const struct asm_opcode *opcode;
20993 const struct asm_cond *cond;
e3cb604e 20994 char save[2];
c19d1205
ZW
20995
20996 /* Scan up to the end of the mnemonic, which must end in white space,
721a8186 20997 '.' (in unified mode, or for Neon/VFP instructions), or end of string. */
c19d1205 20998 for (base = end = *str; *end != '\0'; end++)
721a8186 20999 if (*end == ' ' || *end == '.')
c19d1205 21000 break;
b99bd4ef 21001
c19d1205 21002 if (end == base)
c921be7d 21003 return NULL;
b99bd4ef 21004
5287ad62 21005 /* Handle a possible width suffix and/or Neon type suffix. */
c19d1205 21006 if (end[0] == '.')
b99bd4ef 21007 {
5287ad62 21008 int offset = 2;
5f4273c7 21009
267d2029 21010 /* The .w and .n suffixes are only valid if the unified syntax is in
477330fc 21011 use. */
267d2029 21012 if (unified_syntax && end[1] == 'w')
c19d1205 21013 inst.size_req = 4;
267d2029 21014 else if (unified_syntax && end[1] == 'n')
c19d1205
ZW
21015 inst.size_req = 2;
21016 else
477330fc 21017 offset = 0;
5287ad62
JB
21018
21019 inst.vectype.elems = 0;
21020
21021 *str = end + offset;
b99bd4ef 21022
5f4273c7 21023 if (end[offset] == '.')
5287ad62 21024 {
267d2029 21025 /* See if we have a Neon type suffix (possible in either unified or
477330fc
RM
21026 non-unified ARM syntax mode). */
21027 if (parse_neon_type (&inst.vectype, str) == FAIL)
c921be7d 21028 return NULL;
477330fc 21029 }
5287ad62 21030 else if (end[offset] != '\0' && end[offset] != ' ')
477330fc 21031 return NULL;
b99bd4ef 21032 }
c19d1205
ZW
21033 else
21034 *str = end;
b99bd4ef 21035
c19d1205 21036 /* Look for unaffixed or special-case affixed mnemonic. */
21d799b5 21037 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
477330fc 21038 end - base);
c19d1205 21039 if (opcode)
b99bd4ef 21040 {
c19d1205
ZW
21041 /* step U */
21042 if (opcode->tag < OT_odd_infix_0)
b99bd4ef 21043 {
c19d1205
ZW
21044 inst.cond = COND_ALWAYS;
21045 return opcode;
b99bd4ef 21046 }
b99bd4ef 21047
278df34e 21048 if (warn_on_deprecated && unified_syntax)
5c3696f8 21049 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205 21050 affix = base + (opcode->tag - OT_odd_infix_0);
21d799b5 21051 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
9c2799c2 21052 gas_assert (cond);
b99bd4ef 21053
c19d1205
ZW
21054 inst.cond = cond->value;
21055 return opcode;
21056 }
5ee91343
AV
21057 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
21058 {
21059 /* Cannot have a conditional suffix on a mnemonic of less than a character.
21060 */
21061 if (end - base < 2)
21062 return NULL;
21063 affix = end - 1;
21064 cond = (const struct asm_cond *) hash_find_n (arm_vcond_hsh, affix, 1);
21065 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
21066 affix - base);
21067 /* If this opcode can not be vector predicated then don't accept it with a
21068 vector predication code. */
21069 if (opcode && !opcode->mayBeVecPred)
21070 opcode = NULL;
21071 }
21072 if (!opcode || !cond)
21073 {
21074 /* Cannot have a conditional suffix on a mnemonic of less than two
21075 characters. */
21076 if (end - base < 3)
21077 return NULL;
b99bd4ef 21078
5ee91343
AV
21079 /* Look for suffixed mnemonic. */
21080 affix = end - 2;
21081 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
21082 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
21083 affix - base);
21084 }
b99bd4ef 21085
c19d1205
ZW
21086 if (opcode && cond)
21087 {
21088 /* step CE */
21089 switch (opcode->tag)
21090 {
e3cb604e
PB
21091 case OT_cinfix3_legacy:
21092 /* Ignore conditional suffixes matched on infix only mnemonics. */
21093 break;
21094
c19d1205 21095 case OT_cinfix3:
088fa78e 21096 case OT_cinfix3_deprecated:
c19d1205
ZW
21097 case OT_odd_infix_unc:
21098 if (!unified_syntax)
0198d5e6 21099 return NULL;
1a0670f3 21100 /* Fall through. */
c19d1205
ZW
21101
21102 case OT_csuffix:
477330fc 21103 case OT_csuffixF:
c19d1205
ZW
21104 case OT_csuf_or_in3:
21105 inst.cond = cond->value;
21106 return opcode;
21107
21108 case OT_unconditional:
21109 case OT_unconditionalF:
dfa9f0d5 21110 if (thumb_mode)
c921be7d 21111 inst.cond = cond->value;
dfa9f0d5
PB
21112 else
21113 {
c921be7d 21114 /* Delayed diagnostic. */
dfa9f0d5
PB
21115 inst.error = BAD_COND;
21116 inst.cond = COND_ALWAYS;
21117 }
c19d1205 21118 return opcode;
b99bd4ef 21119
c19d1205 21120 default:
c921be7d 21121 return NULL;
c19d1205
ZW
21122 }
21123 }
b99bd4ef 21124
c19d1205
ZW
21125 /* Cannot have a usual-position infix on a mnemonic of less than
21126 six characters (five would be a suffix). */
21127 if (end - base < 6)
c921be7d 21128 return NULL;
b99bd4ef 21129
c19d1205
ZW
21130 /* Look for infixed mnemonic in the usual position. */
21131 affix = base + 3;
21d799b5 21132 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
e3cb604e 21133 if (!cond)
c921be7d 21134 return NULL;
e3cb604e
PB
21135
21136 memcpy (save, affix, 2);
21137 memmove (affix, affix + 2, (end - affix) - 2);
21d799b5 21138 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
477330fc 21139 (end - base) - 2);
e3cb604e
PB
21140 memmove (affix + 2, affix, (end - affix) - 2);
21141 memcpy (affix, save, 2);
21142
088fa78e
KH
21143 if (opcode
21144 && (opcode->tag == OT_cinfix3
21145 || opcode->tag == OT_cinfix3_deprecated
21146 || opcode->tag == OT_csuf_or_in3
21147 || opcode->tag == OT_cinfix3_legacy))
b99bd4ef 21148 {
c921be7d 21149 /* Step CM. */
278df34e 21150 if (warn_on_deprecated && unified_syntax
088fa78e
KH
21151 && (opcode->tag == OT_cinfix3
21152 || opcode->tag == OT_cinfix3_deprecated))
5c3696f8 21153 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205
ZW
21154
21155 inst.cond = cond->value;
21156 return opcode;
b99bd4ef
NC
21157 }
21158
c921be7d 21159 return NULL;
b99bd4ef
NC
21160}
21161
e07e6e58
NC
21162/* This function generates an initial IT instruction, leaving its block
21163 virtually open for the new instructions. Eventually,
5ee91343 21164 the mask will be updated by now_pred_add_mask () each time
e07e6e58
NC
21165 a new instruction needs to be included in the IT block.
21166 Finally, the block is closed with close_automatic_it_block ().
21167 The block closure can be requested either from md_assemble (),
21168 a tencode (), or due to a label hook. */
21169
21170static void
21171new_automatic_it_block (int cond)
21172{
5ee91343
AV
21173 now_pred.state = AUTOMATIC_PRED_BLOCK;
21174 now_pred.mask = 0x18;
21175 now_pred.cc = cond;
21176 now_pred.block_length = 1;
cd000bff 21177 mapping_state (MAP_THUMB);
5ee91343
AV
21178 now_pred.insn = output_it_inst (cond, now_pred.mask, NULL);
21179 now_pred.warn_deprecated = FALSE;
21180 now_pred.insn_cond = TRUE;
e07e6e58
NC
21181}
21182
21183/* Close an automatic IT block.
21184 See comments in new_automatic_it_block (). */
21185
21186static void
21187close_automatic_it_block (void)
21188{
5ee91343
AV
21189 now_pred.mask = 0x10;
21190 now_pred.block_length = 0;
e07e6e58
NC
21191}
21192
21193/* Update the mask of the current automatically-generated IT
21194 instruction. See comments in new_automatic_it_block (). */
21195
21196static void
5ee91343 21197now_pred_add_mask (int cond)
e07e6e58
NC
21198{
21199#define CLEAR_BIT(value, nbit) ((value) & ~(1 << (nbit)))
21200#define SET_BIT_VALUE(value, bitvalue, nbit) (CLEAR_BIT (value, nbit) \
477330fc 21201 | ((bitvalue) << (nbit)))
e07e6e58 21202 const int resulting_bit = (cond & 1);
c921be7d 21203
5ee91343
AV
21204 now_pred.mask &= 0xf;
21205 now_pred.mask = SET_BIT_VALUE (now_pred.mask,
477330fc 21206 resulting_bit,
5ee91343
AV
21207 (5 - now_pred.block_length));
21208 now_pred.mask = SET_BIT_VALUE (now_pred.mask,
477330fc 21209 1,
5ee91343
AV
21210 ((5 - now_pred.block_length) - 1));
21211 output_it_inst (now_pred.cc, now_pred.mask, now_pred.insn);
e07e6e58
NC
21212
21213#undef CLEAR_BIT
21214#undef SET_BIT_VALUE
e07e6e58
NC
21215}
21216
21217/* The IT blocks handling machinery is accessed through the these functions:
21218 it_fsm_pre_encode () from md_assemble ()
5ee91343
AV
21219 set_pred_insn_type () optional, from the tencode functions
21220 set_pred_insn_type_last () ditto
21221 in_pred_block () ditto
e07e6e58 21222 it_fsm_post_encode () from md_assemble ()
33eaf5de 21223 force_automatic_it_block_close () from label handling functions
e07e6e58
NC
21224
21225 Rationale:
21226 1) md_assemble () calls it_fsm_pre_encode () before calling tencode (),
477330fc
RM
21227 initializing the IT insn type with a generic initial value depending
21228 on the inst.condition.
e07e6e58 21229 2) During the tencode function, two things may happen:
477330fc 21230 a) The tencode function overrides the IT insn type by
5ee91343
AV
21231 calling either set_pred_insn_type (type) or
21232 set_pred_insn_type_last ().
477330fc 21233 b) The tencode function queries the IT block state by
5ee91343 21234 calling in_pred_block () (i.e. to determine narrow/not narrow mode).
477330fc 21235
5ee91343
AV
21236 Both set_pred_insn_type and in_pred_block run the internal FSM state
21237 handling function (handle_pred_state), because: a) setting the IT insn
477330fc
RM
21238 type may incur in an invalid state (exiting the function),
21239 and b) querying the state requires the FSM to be updated.
21240 Specifically we want to avoid creating an IT block for conditional
21241 branches, so it_fsm_pre_encode is actually a guess and we can't
21242 determine whether an IT block is required until the tencode () routine
21243 has decided what type of instruction this actually it.
5ee91343
AV
21244 Because of this, if set_pred_insn_type and in_pred_block have to be
21245 used, set_pred_insn_type has to be called first.
477330fc 21246
5ee91343
AV
21247 set_pred_insn_type_last () is a wrapper of set_pred_insn_type (type),
21248 that determines the insn IT type depending on the inst.cond code.
477330fc
RM
21249 When a tencode () routine encodes an instruction that can be
21250 either outside an IT block, or, in the case of being inside, has to be
5ee91343 21251 the last one, set_pred_insn_type_last () will determine the proper
477330fc 21252 IT instruction type based on the inst.cond code. Otherwise,
5ee91343 21253 set_pred_insn_type can be called for overriding that logic or
477330fc
RM
21254 for covering other cases.
21255
5ee91343
AV
21256 Calling handle_pred_state () may not transition the IT block state to
21257 OUTSIDE_PRED_BLOCK immediately, since the (current) state could be
477330fc 21258 still queried. Instead, if the FSM determines that the state should
5ee91343 21259 be transitioned to OUTSIDE_PRED_BLOCK, a flag is marked to be closed
477330fc
RM
21260 after the tencode () function: that's what it_fsm_post_encode () does.
21261
5ee91343 21262 Since in_pred_block () calls the state handling function to get an
477330fc
RM
21263 updated state, an error may occur (due to invalid insns combination).
21264 In that case, inst.error is set.
21265 Therefore, inst.error has to be checked after the execution of
21266 the tencode () routine.
e07e6e58
NC
21267
21268 3) Back in md_assemble(), it_fsm_post_encode () is called to commit
477330fc 21269 any pending state change (if any) that didn't take place in
5ee91343 21270 handle_pred_state () as explained above. */
e07e6e58
NC
21271
21272static void
21273it_fsm_pre_encode (void)
21274{
21275 if (inst.cond != COND_ALWAYS)
5ee91343 21276 inst.pred_insn_type = INSIDE_IT_INSN;
e07e6e58 21277 else
5ee91343 21278 inst.pred_insn_type = OUTSIDE_PRED_INSN;
e07e6e58 21279
5ee91343 21280 now_pred.state_handled = 0;
e07e6e58
NC
21281}
21282
21283/* IT state FSM handling function. */
5ee91343
AV
21284/* MVE instructions and non-MVE instructions are handled differently because of
21285 the introduction of VPT blocks.
21286 Specifications say that any non-MVE instruction inside a VPT block is
21287 UNPREDICTABLE, with the exception of the BKPT instruction. Whereas most MVE
21288 instructions are deemed to be UNPREDICTABLE if inside an IT block. For the
35c228db 21289 few exceptions we have MVE_UNPREDICABLE_INSN.
5ee91343
AV
21290 The error messages provided depending on the different combinations possible
21291 are described in the cases below:
21292 For 'most' MVE instructions:
21293 1) In an IT block, with an IT code: syntax error
21294 2) In an IT block, with a VPT code: error: must be in a VPT block
21295 3) In an IT block, with no code: warning: UNPREDICTABLE
21296 4) In a VPT block, with an IT code: syntax error
21297 5) In a VPT block, with a VPT code: OK!
21298 6) In a VPT block, with no code: error: missing code
21299 7) Outside a pred block, with an IT code: error: syntax error
21300 8) Outside a pred block, with a VPT code: error: should be in a VPT block
21301 9) Outside a pred block, with no code: OK!
21302 For non-MVE instructions:
21303 10) In an IT block, with an IT code: OK!
21304 11) In an IT block, with a VPT code: syntax error
21305 12) In an IT block, with no code: error: missing code
21306 13) In a VPT block, with an IT code: error: should be in an IT block
21307 14) In a VPT block, with a VPT code: syntax error
21308 15) In a VPT block, with no code: UNPREDICTABLE
21309 16) Outside a pred block, with an IT code: error: should be in an IT block
21310 17) Outside a pred block, with a VPT code: syntax error
21311 18) Outside a pred block, with no code: OK!
21312 */
21313
e07e6e58
NC
21314
21315static int
5ee91343 21316handle_pred_state (void)
e07e6e58 21317{
5ee91343
AV
21318 now_pred.state_handled = 1;
21319 now_pred.insn_cond = FALSE;
e07e6e58 21320
5ee91343 21321 switch (now_pred.state)
e07e6e58 21322 {
5ee91343
AV
21323 case OUTSIDE_PRED_BLOCK:
21324 switch (inst.pred_insn_type)
e07e6e58 21325 {
35c228db 21326 case MVE_UNPREDICABLE_INSN:
5ee91343
AV
21327 case MVE_OUTSIDE_PRED_INSN:
21328 if (inst.cond < COND_ALWAYS)
21329 {
21330 /* Case 7: Outside a pred block, with an IT code: error: syntax
21331 error. */
21332 inst.error = BAD_SYNTAX;
21333 return FAIL;
21334 }
21335 /* Case 9: Outside a pred block, with no code: OK! */
21336 break;
21337 case OUTSIDE_PRED_INSN:
21338 if (inst.cond > COND_ALWAYS)
21339 {
21340 /* Case 17: Outside a pred block, with a VPT code: syntax error.
21341 */
21342 inst.error = BAD_SYNTAX;
21343 return FAIL;
21344 }
21345 /* Case 18: Outside a pred block, with no code: OK! */
e07e6e58
NC
21346 break;
21347
5ee91343
AV
21348 case INSIDE_VPT_INSN:
21349 /* Case 8: Outside a pred block, with a VPT code: error: should be in
21350 a VPT block. */
21351 inst.error = BAD_OUT_VPT;
21352 return FAIL;
21353
e07e6e58
NC
21354 case INSIDE_IT_INSN:
21355 case INSIDE_IT_LAST_INSN:
5ee91343 21356 if (inst.cond < COND_ALWAYS)
e07e6e58 21357 {
5ee91343
AV
21358 /* Case 16: Outside a pred block, with an IT code: error: should
21359 be in an IT block. */
21360 if (thumb_mode == 0)
e07e6e58 21361 {
5ee91343
AV
21362 if (unified_syntax
21363 && !(implicit_it_mode & IMPLICIT_IT_MODE_ARM))
21364 as_tsktsk (_("Warning: conditional outside an IT block"\
21365 " for Thumb."));
e07e6e58
NC
21366 }
21367 else
21368 {
5ee91343
AV
21369 if ((implicit_it_mode & IMPLICIT_IT_MODE_THUMB)
21370 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
21371 {
21372 /* Automatically generate the IT instruction. */
21373 new_automatic_it_block (inst.cond);
21374 if (inst.pred_insn_type == INSIDE_IT_LAST_INSN)
21375 close_automatic_it_block ();
21376 }
21377 else
21378 {
21379 inst.error = BAD_OUT_IT;
21380 return FAIL;
21381 }
e07e6e58 21382 }
5ee91343 21383 break;
e07e6e58 21384 }
5ee91343
AV
21385 else if (inst.cond > COND_ALWAYS)
21386 {
21387 /* Case 17: Outside a pred block, with a VPT code: syntax error.
21388 */
21389 inst.error = BAD_SYNTAX;
21390 return FAIL;
21391 }
21392 else
21393 gas_assert (0);
e07e6e58
NC
21394 case IF_INSIDE_IT_LAST_INSN:
21395 case NEUTRAL_IT_INSN:
21396 break;
21397
5ee91343
AV
21398 case VPT_INSN:
21399 if (inst.cond != COND_ALWAYS)
21400 first_error (BAD_SYNTAX);
21401 now_pred.state = MANUAL_PRED_BLOCK;
21402 now_pred.block_length = 0;
21403 now_pred.type = VECTOR_PRED;
21404 now_pred.cc = 0;
21405 break;
e07e6e58 21406 case IT_INSN:
5ee91343
AV
21407 now_pred.state = MANUAL_PRED_BLOCK;
21408 now_pred.block_length = 0;
21409 now_pred.type = SCALAR_PRED;
e07e6e58
NC
21410 break;
21411 }
21412 break;
21413
5ee91343 21414 case AUTOMATIC_PRED_BLOCK:
e07e6e58
NC
21415 /* Three things may happen now:
21416 a) We should increment current it block size;
21417 b) We should close current it block (closing insn or 4 insns);
21418 c) We should close current it block and start a new one (due
21419 to incompatible conditions or
21420 4 insns-length block reached). */
21421
5ee91343 21422 switch (inst.pred_insn_type)
e07e6e58 21423 {
5ee91343
AV
21424 case INSIDE_VPT_INSN:
21425 case VPT_INSN:
35c228db 21426 case MVE_UNPREDICABLE_INSN:
5ee91343
AV
21427 case MVE_OUTSIDE_PRED_INSN:
21428 gas_assert (0);
21429 case OUTSIDE_PRED_INSN:
2b0f3761 21430 /* The closure of the block shall happen immediately,
5ee91343 21431 so any in_pred_block () call reports the block as closed. */
e07e6e58
NC
21432 force_automatic_it_block_close ();
21433 break;
21434
21435 case INSIDE_IT_INSN:
21436 case INSIDE_IT_LAST_INSN:
21437 case IF_INSIDE_IT_LAST_INSN:
5ee91343 21438 now_pred.block_length++;
e07e6e58 21439
5ee91343
AV
21440 if (now_pred.block_length > 4
21441 || !now_pred_compatible (inst.cond))
e07e6e58
NC
21442 {
21443 force_automatic_it_block_close ();
5ee91343 21444 if (inst.pred_insn_type != IF_INSIDE_IT_LAST_INSN)
e07e6e58
NC
21445 new_automatic_it_block (inst.cond);
21446 }
21447 else
21448 {
5ee91343
AV
21449 now_pred.insn_cond = TRUE;
21450 now_pred_add_mask (inst.cond);
e07e6e58
NC
21451 }
21452
5ee91343
AV
21453 if (now_pred.state == AUTOMATIC_PRED_BLOCK
21454 && (inst.pred_insn_type == INSIDE_IT_LAST_INSN
21455 || inst.pred_insn_type == IF_INSIDE_IT_LAST_INSN))
e07e6e58
NC
21456 close_automatic_it_block ();
21457 break;
21458
21459 case NEUTRAL_IT_INSN:
5ee91343
AV
21460 now_pred.block_length++;
21461 now_pred.insn_cond = TRUE;
e07e6e58 21462
5ee91343 21463 if (now_pred.block_length > 4)
e07e6e58
NC
21464 force_automatic_it_block_close ();
21465 else
5ee91343 21466 now_pred_add_mask (now_pred.cc & 1);
e07e6e58
NC
21467 break;
21468
21469 case IT_INSN:
21470 close_automatic_it_block ();
5ee91343 21471 now_pred.state = MANUAL_PRED_BLOCK;
e07e6e58
NC
21472 break;
21473 }
21474 break;
21475
5ee91343 21476 case MANUAL_PRED_BLOCK:
e07e6e58 21477 {
5ee91343
AV
21478 int cond, is_last;
21479 if (now_pred.type == SCALAR_PRED)
e07e6e58 21480 {
5ee91343
AV
21481 /* Check conditional suffixes. */
21482 cond = now_pred.cc ^ ((now_pred.mask >> 4) & 1) ^ 1;
21483 now_pred.mask <<= 1;
21484 now_pred.mask &= 0x1f;
21485 is_last = (now_pred.mask == 0x10);
21486 }
21487 else
21488 {
21489 now_pred.cc ^= (now_pred.mask >> 4);
21490 cond = now_pred.cc + 0xf;
21491 now_pred.mask <<= 1;
21492 now_pred.mask &= 0x1f;
21493 is_last = now_pred.mask == 0x10;
21494 }
21495 now_pred.insn_cond = TRUE;
e07e6e58 21496
5ee91343
AV
21497 switch (inst.pred_insn_type)
21498 {
21499 case OUTSIDE_PRED_INSN:
21500 if (now_pred.type == SCALAR_PRED)
21501 {
21502 if (inst.cond == COND_ALWAYS)
21503 {
21504 /* Case 12: In an IT block, with no code: error: missing
21505 code. */
21506 inst.error = BAD_NOT_IT;
21507 return FAIL;
21508 }
21509 else if (inst.cond > COND_ALWAYS)
21510 {
21511 /* Case 11: In an IT block, with a VPT code: syntax error.
21512 */
21513 inst.error = BAD_SYNTAX;
21514 return FAIL;
21515 }
21516 else if (thumb_mode)
21517 {
21518 /* This is for some special cases where a non-MVE
21519 instruction is not allowed in an IT block, such as cbz,
21520 but are put into one with a condition code.
21521 You could argue this should be a syntax error, but we
21522 gave the 'not allowed in IT block' diagnostic in the
21523 past so we will keep doing so. */
21524 inst.error = BAD_NOT_IT;
21525 return FAIL;
21526 }
21527 break;
21528 }
21529 else
21530 {
21531 /* Case 15: In a VPT block, with no code: UNPREDICTABLE. */
21532 as_tsktsk (MVE_NOT_VPT);
21533 return SUCCESS;
21534 }
21535 case MVE_OUTSIDE_PRED_INSN:
21536 if (now_pred.type == SCALAR_PRED)
21537 {
21538 if (inst.cond == COND_ALWAYS)
21539 {
21540 /* Case 3: In an IT block, with no code: warning:
21541 UNPREDICTABLE. */
21542 as_tsktsk (MVE_NOT_IT);
21543 return SUCCESS;
21544 }
21545 else if (inst.cond < COND_ALWAYS)
21546 {
21547 /* Case 1: In an IT block, with an IT code: syntax error.
21548 */
21549 inst.error = BAD_SYNTAX;
21550 return FAIL;
21551 }
21552 else
21553 gas_assert (0);
21554 }
21555 else
21556 {
21557 if (inst.cond < COND_ALWAYS)
21558 {
21559 /* Case 4: In a VPT block, with an IT code: syntax error.
21560 */
21561 inst.error = BAD_SYNTAX;
21562 return FAIL;
21563 }
21564 else if (inst.cond == COND_ALWAYS)
21565 {
21566 /* Case 6: In a VPT block, with no code: error: missing
21567 code. */
21568 inst.error = BAD_NOT_VPT;
21569 return FAIL;
21570 }
21571 else
21572 {
21573 gas_assert (0);
21574 }
21575 }
35c228db
AV
21576 case MVE_UNPREDICABLE_INSN:
21577 as_tsktsk (now_pred.type == SCALAR_PRED ? MVE_NOT_IT : MVE_NOT_VPT);
21578 return SUCCESS;
e07e6e58 21579 case INSIDE_IT_INSN:
5ee91343 21580 if (inst.cond > COND_ALWAYS)
e07e6e58 21581 {
5ee91343
AV
21582 /* Case 11: In an IT block, with a VPT code: syntax error. */
21583 /* Case 14: In a VPT block, with a VPT code: syntax error. */
21584 inst.error = BAD_SYNTAX;
21585 return FAIL;
21586 }
21587 else if (now_pred.type == SCALAR_PRED)
21588 {
21589 /* Case 10: In an IT block, with an IT code: OK! */
21590 if (cond != inst.cond)
21591 {
21592 inst.error = now_pred.type == SCALAR_PRED ? BAD_IT_COND :
21593 BAD_VPT_COND;
21594 return FAIL;
21595 }
21596 }
21597 else
21598 {
21599 /* Case 13: In a VPT block, with an IT code: error: should be
21600 in an IT block. */
21601 inst.error = BAD_OUT_IT;
e07e6e58
NC
21602 return FAIL;
21603 }
21604 break;
21605
5ee91343
AV
21606 case INSIDE_VPT_INSN:
21607 if (now_pred.type == SCALAR_PRED)
21608 {
21609 /* Case 2: In an IT block, with a VPT code: error: must be in a
21610 VPT block. */
21611 inst.error = BAD_OUT_VPT;
21612 return FAIL;
21613 }
21614 /* Case 5: In a VPT block, with a VPT code: OK! */
21615 else if (cond != inst.cond)
21616 {
21617 inst.error = BAD_VPT_COND;
21618 return FAIL;
21619 }
21620 break;
e07e6e58
NC
21621 case INSIDE_IT_LAST_INSN:
21622 case IF_INSIDE_IT_LAST_INSN:
5ee91343
AV
21623 if (now_pred.type == VECTOR_PRED || inst.cond > COND_ALWAYS)
21624 {
21625 /* Case 4: In a VPT block, with an IT code: syntax error. */
21626 /* Case 11: In an IT block, with a VPT code: syntax error. */
21627 inst.error = BAD_SYNTAX;
21628 return FAIL;
21629 }
21630 else if (cond != inst.cond)
e07e6e58
NC
21631 {
21632 inst.error = BAD_IT_COND;
21633 return FAIL;
21634 }
21635 if (!is_last)
21636 {
21637 inst.error = BAD_BRANCH;
21638 return FAIL;
21639 }
21640 break;
21641
21642 case NEUTRAL_IT_INSN:
5ee91343
AV
21643 /* The BKPT instruction is unconditional even in a IT or VPT
21644 block. */
e07e6e58
NC
21645 break;
21646
21647 case IT_INSN:
5ee91343
AV
21648 if (now_pred.type == SCALAR_PRED)
21649 {
21650 inst.error = BAD_IT_IT;
21651 return FAIL;
21652 }
21653 /* fall through. */
21654 case VPT_INSN:
21655 if (inst.cond == COND_ALWAYS)
21656 {
21657 /* Executing a VPT/VPST instruction inside an IT block or a
21658 VPT/VPST/IT instruction inside a VPT block is UNPREDICTABLE.
21659 */
21660 if (now_pred.type == SCALAR_PRED)
21661 as_tsktsk (MVE_NOT_IT);
21662 else
21663 as_tsktsk (MVE_NOT_VPT);
21664 return SUCCESS;
21665 }
21666 else
21667 {
21668 /* VPT/VPST do not accept condition codes. */
21669 inst.error = BAD_SYNTAX;
21670 return FAIL;
21671 }
e07e6e58 21672 }
5ee91343 21673 }
e07e6e58
NC
21674 break;
21675 }
21676
21677 return SUCCESS;
21678}
21679
5a01bb1d
MGD
21680struct depr_insn_mask
21681{
21682 unsigned long pattern;
21683 unsigned long mask;
21684 const char* description;
21685};
21686
21687/* List of 16-bit instruction patterns deprecated in an IT block in
21688 ARMv8. */
21689static const struct depr_insn_mask depr_it_insns[] = {
21690 { 0xc000, 0xc000, N_("Short branches, Undefined, SVC, LDM/STM") },
21691 { 0xb000, 0xb000, N_("Miscellaneous 16-bit instructions") },
21692 { 0xa000, 0xb800, N_("ADR") },
21693 { 0x4800, 0xf800, N_("Literal loads") },
21694 { 0x4478, 0xf478, N_("Hi-register ADD, MOV, CMP, BX, BLX using pc") },
21695 { 0x4487, 0xfc87, N_("Hi-register ADD, MOV, CMP using pc") },
c8de034b
JW
21696 /* NOTE: 0x00dd is not the real encoding, instead, it is the 'tvalue'
21697 field in asm_opcode. 'tvalue' is used at the stage this check happen. */
21698 { 0x00dd, 0x7fff, N_("ADD/SUB sp, sp #imm") },
5a01bb1d
MGD
21699 { 0, 0, NULL }
21700};
21701
e07e6e58
NC
21702static void
21703it_fsm_post_encode (void)
21704{
21705 int is_last;
21706
5ee91343
AV
21707 if (!now_pred.state_handled)
21708 handle_pred_state ();
e07e6e58 21709
5ee91343
AV
21710 if (now_pred.insn_cond
21711 && !now_pred.warn_deprecated
5a01bb1d 21712 && warn_on_deprecated
df9909b8
TP
21713 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)
21714 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_m))
5a01bb1d
MGD
21715 {
21716 if (inst.instruction >= 0x10000)
21717 {
5c3696f8 21718 as_tsktsk (_("IT blocks containing 32-bit Thumb instructions are "
df9909b8 21719 "performance deprecated in ARMv8-A and ARMv8-R"));
5ee91343 21720 now_pred.warn_deprecated = TRUE;
5a01bb1d
MGD
21721 }
21722 else
21723 {
21724 const struct depr_insn_mask *p = depr_it_insns;
21725
21726 while (p->mask != 0)
21727 {
21728 if ((inst.instruction & p->mask) == p->pattern)
21729 {
df9909b8
TP
21730 as_tsktsk (_("IT blocks containing 16-bit Thumb "
21731 "instructions of the following class are "
21732 "performance deprecated in ARMv8-A and "
21733 "ARMv8-R: %s"), p->description);
5ee91343 21734 now_pred.warn_deprecated = TRUE;
5a01bb1d
MGD
21735 break;
21736 }
21737
21738 ++p;
21739 }
21740 }
21741
5ee91343 21742 if (now_pred.block_length > 1)
5a01bb1d 21743 {
5c3696f8 21744 as_tsktsk (_("IT blocks containing more than one conditional "
df9909b8
TP
21745 "instruction are performance deprecated in ARMv8-A and "
21746 "ARMv8-R"));
5ee91343 21747 now_pred.warn_deprecated = TRUE;
5a01bb1d
MGD
21748 }
21749 }
21750
5ee91343
AV
21751 is_last = (now_pred.mask == 0x10);
21752 if (is_last)
21753 {
21754 now_pred.state = OUTSIDE_PRED_BLOCK;
21755 now_pred.mask = 0;
21756 }
e07e6e58
NC
21757}
21758
21759static void
21760force_automatic_it_block_close (void)
21761{
5ee91343 21762 if (now_pred.state == AUTOMATIC_PRED_BLOCK)
e07e6e58
NC
21763 {
21764 close_automatic_it_block ();
5ee91343
AV
21765 now_pred.state = OUTSIDE_PRED_BLOCK;
21766 now_pred.mask = 0;
e07e6e58
NC
21767 }
21768}
21769
21770static int
5ee91343 21771in_pred_block (void)
e07e6e58 21772{
5ee91343
AV
21773 if (!now_pred.state_handled)
21774 handle_pred_state ();
e07e6e58 21775
5ee91343 21776 return now_pred.state != OUTSIDE_PRED_BLOCK;
e07e6e58
NC
21777}
21778
ff8646ee
TP
21779/* Whether OPCODE only has T32 encoding. Since this function is only used by
21780 t32_insn_ok, OPCODE enabled by v6t2 extension bit do not need to be listed
21781 here, hence the "known" in the function name. */
fc289b0a
TP
21782
21783static bfd_boolean
ff8646ee 21784known_t32_only_insn (const struct asm_opcode *opcode)
fc289b0a
TP
21785{
21786 /* Original Thumb-1 wide instruction. */
21787 if (opcode->tencode == do_t_blx
21788 || opcode->tencode == do_t_branch23
21789 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_msr)
21790 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_barrier))
21791 return TRUE;
21792
16a1fa25
TP
21793 /* Wide-only instruction added to ARMv8-M Baseline. */
21794 if (ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v8m_m_only)
ff8646ee
TP
21795 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_atomics)
21796 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v6t2_v8m)
21797 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_div))
21798 return TRUE;
21799
21800 return FALSE;
21801}
21802
21803/* Whether wide instruction variant can be used if available for a valid OPCODE
21804 in ARCH. */
21805
21806static bfd_boolean
21807t32_insn_ok (arm_feature_set arch, const struct asm_opcode *opcode)
21808{
21809 if (known_t32_only_insn (opcode))
21810 return TRUE;
21811
21812 /* Instruction with narrow and wide encoding added to ARMv8-M. Availability
21813 of variant T3 of B.W is checked in do_t_branch. */
21814 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
21815 && opcode->tencode == do_t_branch)
21816 return TRUE;
21817
bada4342
JW
21818 /* MOV accepts T1/T3 encodings under Baseline, T3 encoding is 32bit. */
21819 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
21820 && opcode->tencode == do_t_mov_cmp
21821 /* Make sure CMP instruction is not affected. */
21822 && opcode->aencode == do_mov)
21823 return TRUE;
21824
ff8646ee
TP
21825 /* Wide instruction variants of all instructions with narrow *and* wide
21826 variants become available with ARMv6t2. Other opcodes are either
21827 narrow-only or wide-only and are thus available if OPCODE is valid. */
21828 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v6t2))
21829 return TRUE;
21830
21831 /* OPCODE with narrow only instruction variant or wide variant not
21832 available. */
fc289b0a
TP
21833 return FALSE;
21834}
21835
c19d1205
ZW
21836void
21837md_assemble (char *str)
b99bd4ef 21838{
c19d1205
ZW
21839 char *p = str;
21840 const struct asm_opcode * opcode;
b99bd4ef 21841
c19d1205
ZW
21842 /* Align the previous label if needed. */
21843 if (last_label_seen != NULL)
b99bd4ef 21844 {
c19d1205
ZW
21845 symbol_set_frag (last_label_seen, frag_now);
21846 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
21847 S_SET_SEGMENT (last_label_seen, now_seg);
b99bd4ef
NC
21848 }
21849
c19d1205 21850 memset (&inst, '\0', sizeof (inst));
e2b0ab59
AV
21851 int r;
21852 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
21853 inst.relocs[r].type = BFD_RELOC_UNUSED;
b99bd4ef 21854
c19d1205
ZW
21855 opcode = opcode_lookup (&p);
21856 if (!opcode)
b99bd4ef 21857 {
c19d1205 21858 /* It wasn't an instruction, but it might be a register alias of
dcbf9037 21859 the form alias .req reg, or a Neon .dn/.qn directive. */
c921be7d 21860 if (! create_register_alias (str, p)
477330fc 21861 && ! create_neon_reg_alias (str, p))
c19d1205 21862 as_bad (_("bad instruction `%s'"), str);
b99bd4ef 21863
b99bd4ef
NC
21864 return;
21865 }
21866
278df34e 21867 if (warn_on_deprecated && opcode->tag == OT_cinfix3_deprecated)
5c3696f8 21868 as_tsktsk (_("s suffix on comparison instruction is deprecated"));
088fa78e 21869
037e8744
JB
21870 /* The value which unconditional instructions should have in place of the
21871 condition field. */
21872 inst.uncond_value = (opcode->tag == OT_csuffixF) ? 0xf : -1;
21873
c19d1205 21874 if (thumb_mode)
b99bd4ef 21875 {
e74cfd16 21876 arm_feature_set variant;
8f06b2d8
PB
21877
21878 variant = cpu_variant;
21879 /* Only allow coprocessor instructions on Thumb-2 capable devices. */
e74cfd16
PB
21880 if (!ARM_CPU_HAS_FEATURE (variant, arm_arch_t2))
21881 ARM_CLEAR_FEATURE (variant, variant, fpu_any_hard);
c19d1205 21882 /* Check that this instruction is supported for this CPU. */
62b3e311
PB
21883 if (!opcode->tvariant
21884 || (thumb_mode == 1
21885 && !ARM_CPU_HAS_FEATURE (variant, *opcode->tvariant)))
b99bd4ef 21886 {
173205ca
TP
21887 if (opcode->tencode == do_t_swi)
21888 as_bad (_("SVC is not permitted on this architecture"));
21889 else
21890 as_bad (_("selected processor does not support `%s' in Thumb mode"), str);
b99bd4ef
NC
21891 return;
21892 }
c19d1205
ZW
21893 if (inst.cond != COND_ALWAYS && !unified_syntax
21894 && opcode->tencode != do_t_branch)
b99bd4ef 21895 {
c19d1205 21896 as_bad (_("Thumb does not support conditional execution"));
b99bd4ef
NC
21897 return;
21898 }
21899
fc289b0a
TP
21900 /* Two things are addressed here:
21901 1) Implicit require narrow instructions on Thumb-1.
21902 This avoids relaxation accidentally introducing Thumb-2
21903 instructions.
21904 2) Reject wide instructions in non Thumb-2 cores.
21905
21906 Only instructions with narrow and wide variants need to be handled
21907 but selecting all non wide-only instructions is easier. */
21908 if (!ARM_CPU_HAS_FEATURE (variant, arm_ext_v6t2)
ff8646ee 21909 && !t32_insn_ok (variant, opcode))
076d447c 21910 {
fc289b0a
TP
21911 if (inst.size_req == 0)
21912 inst.size_req = 2;
21913 else if (inst.size_req == 4)
752d5da4 21914 {
ff8646ee
TP
21915 if (ARM_CPU_HAS_FEATURE (variant, arm_ext_v8m))
21916 as_bad (_("selected processor does not support 32bit wide "
21917 "variant of instruction `%s'"), str);
21918 else
21919 as_bad (_("selected processor does not support `%s' in "
21920 "Thumb-2 mode"), str);
fc289b0a 21921 return;
752d5da4 21922 }
076d447c
PB
21923 }
21924
c19d1205
ZW
21925 inst.instruction = opcode->tvalue;
21926
5be8be5d 21927 if (!parse_operands (p, opcode->operands, /*thumb=*/TRUE))
477330fc 21928 {
5ee91343 21929 /* Prepare the pred_insn_type for those encodings that don't set
477330fc
RM
21930 it. */
21931 it_fsm_pre_encode ();
c19d1205 21932
477330fc 21933 opcode->tencode ();
e07e6e58 21934
477330fc
RM
21935 it_fsm_post_encode ();
21936 }
e27ec89e 21937
0110f2b8 21938 if (!(inst.error || inst.relax))
b99bd4ef 21939 {
9c2799c2 21940 gas_assert (inst.instruction < 0xe800 || inst.instruction > 0xffff);
c19d1205
ZW
21941 inst.size = (inst.instruction > 0xffff ? 4 : 2);
21942 if (inst.size_req && inst.size_req != inst.size)
b99bd4ef 21943 {
c19d1205 21944 as_bad (_("cannot honor width suffix -- `%s'"), str);
b99bd4ef
NC
21945 return;
21946 }
21947 }
076d447c
PB
21948
21949 /* Something has gone badly wrong if we try to relax a fixed size
477330fc 21950 instruction. */
9c2799c2 21951 gas_assert (inst.size_req == 0 || !inst.relax);
076d447c 21952
e74cfd16
PB
21953 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
21954 *opcode->tvariant);
ee065d83 21955 /* Many Thumb-2 instructions also have Thumb-1 variants, so explicitly
fc289b0a
TP
21956 set those bits when Thumb-2 32-bit instructions are seen. The impact
21957 of relaxable instructions will be considered later after we finish all
21958 relaxation. */
ff8646ee
TP
21959 if (ARM_FEATURE_CORE_EQUAL (cpu_variant, arm_arch_any))
21960 variant = arm_arch_none;
21961 else
21962 variant = cpu_variant;
21963 if (inst.size == 4 && !t32_insn_ok (variant, opcode))
e74cfd16
PB
21964 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
21965 arm_ext_v6t2);
cd000bff 21966
88714cb8
DG
21967 check_neon_suffixes;
21968
cd000bff 21969 if (!inst.error)
c877a2f2
NC
21970 {
21971 mapping_state (MAP_THUMB);
21972 }
c19d1205 21973 }
3e9e4fcf 21974 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
c19d1205 21975 {
845b51d6
PB
21976 bfd_boolean is_bx;
21977
21978 /* bx is allowed on v5 cores, and sometimes on v4 cores. */
21979 is_bx = (opcode->aencode == do_bx);
21980
c19d1205 21981 /* Check that this instruction is supported for this CPU. */
845b51d6
PB
21982 if (!(is_bx && fix_v4bx)
21983 && !(opcode->avariant &&
21984 ARM_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant)))
b99bd4ef 21985 {
84b52b66 21986 as_bad (_("selected processor does not support `%s' in ARM mode"), str);
c19d1205 21987 return;
b99bd4ef 21988 }
c19d1205 21989 if (inst.size_req)
b99bd4ef 21990 {
c19d1205
ZW
21991 as_bad (_("width suffixes are invalid in ARM mode -- `%s'"), str);
21992 return;
b99bd4ef
NC
21993 }
21994
c19d1205
ZW
21995 inst.instruction = opcode->avalue;
21996 if (opcode->tag == OT_unconditionalF)
eff0bc54 21997 inst.instruction |= 0xFU << 28;
c19d1205
ZW
21998 else
21999 inst.instruction |= inst.cond << 28;
22000 inst.size = INSN_SIZE;
5be8be5d 22001 if (!parse_operands (p, opcode->operands, /*thumb=*/FALSE))
477330fc
RM
22002 {
22003 it_fsm_pre_encode ();
22004 opcode->aencode ();
22005 it_fsm_post_encode ();
22006 }
ee065d83 22007 /* Arm mode bx is marked as both v4T and v5 because it's still required
477330fc 22008 on a hypothetical non-thumb v5 core. */
845b51d6 22009 if (is_bx)
e74cfd16 22010 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, arm_ext_v4t);
ee065d83 22011 else
e74cfd16
PB
22012 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
22013 *opcode->avariant);
88714cb8
DG
22014
22015 check_neon_suffixes;
22016
cd000bff 22017 if (!inst.error)
c877a2f2
NC
22018 {
22019 mapping_state (MAP_ARM);
22020 }
b99bd4ef 22021 }
3e9e4fcf
JB
22022 else
22023 {
22024 as_bad (_("attempt to use an ARM instruction on a Thumb-only processor "
22025 "-- `%s'"), str);
22026 return;
22027 }
c19d1205
ZW
22028 output_inst (str);
22029}
b99bd4ef 22030
e07e6e58 22031static void
5ee91343 22032check_pred_blocks_finished (void)
e07e6e58
NC
22033{
22034#ifdef OBJ_ELF
22035 asection *sect;
22036
22037 for (sect = stdoutput->sections; sect != NULL; sect = sect->next)
5ee91343
AV
22038 if (seg_info (sect)->tc_segment_info_data.current_pred.state
22039 == MANUAL_PRED_BLOCK)
e07e6e58 22040 {
5ee91343
AV
22041 if (now_pred.type == SCALAR_PRED)
22042 as_warn (_("section '%s' finished with an open IT block."),
22043 sect->name);
22044 else
22045 as_warn (_("section '%s' finished with an open VPT/VPST block."),
22046 sect->name);
e07e6e58
NC
22047 }
22048#else
5ee91343
AV
22049 if (now_pred.state == MANUAL_PRED_BLOCK)
22050 {
22051 if (now_pred.type == SCALAR_PRED)
22052 as_warn (_("file finished with an open IT block."));
22053 else
22054 as_warn (_("file finished with an open VPT/VPST block."));
22055 }
e07e6e58
NC
22056#endif
22057}
22058
c19d1205
ZW
22059/* Various frobbings of labels and their addresses. */
22060
22061void
22062arm_start_line_hook (void)
22063{
22064 last_label_seen = NULL;
b99bd4ef
NC
22065}
22066
c19d1205
ZW
22067void
22068arm_frob_label (symbolS * sym)
b99bd4ef 22069{
c19d1205 22070 last_label_seen = sym;
b99bd4ef 22071
c19d1205 22072 ARM_SET_THUMB (sym, thumb_mode);
b99bd4ef 22073
c19d1205
ZW
22074#if defined OBJ_COFF || defined OBJ_ELF
22075 ARM_SET_INTERWORK (sym, support_interwork);
22076#endif
b99bd4ef 22077
e07e6e58
NC
22078 force_automatic_it_block_close ();
22079
5f4273c7 22080 /* Note - do not allow local symbols (.Lxxx) to be labelled
c19d1205
ZW
22081 as Thumb functions. This is because these labels, whilst
22082 they exist inside Thumb code, are not the entry points for
22083 possible ARM->Thumb calls. Also, these labels can be used
22084 as part of a computed goto or switch statement. eg gcc
22085 can generate code that looks like this:
b99bd4ef 22086
c19d1205
ZW
22087 ldr r2, [pc, .Laaa]
22088 lsl r3, r3, #2
22089 ldr r2, [r3, r2]
22090 mov pc, r2
b99bd4ef 22091
c19d1205
ZW
22092 .Lbbb: .word .Lxxx
22093 .Lccc: .word .Lyyy
22094 ..etc...
22095 .Laaa: .word Lbbb
b99bd4ef 22096
c19d1205
ZW
22097 The first instruction loads the address of the jump table.
22098 The second instruction converts a table index into a byte offset.
22099 The third instruction gets the jump address out of the table.
22100 The fourth instruction performs the jump.
b99bd4ef 22101
c19d1205
ZW
22102 If the address stored at .Laaa is that of a symbol which has the
22103 Thumb_Func bit set, then the linker will arrange for this address
22104 to have the bottom bit set, which in turn would mean that the
22105 address computation performed by the third instruction would end
22106 up with the bottom bit set. Since the ARM is capable of unaligned
22107 word loads, the instruction would then load the incorrect address
22108 out of the jump table, and chaos would ensue. */
22109 if (label_is_thumb_function_name
22110 && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
22111 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
b99bd4ef 22112 {
c19d1205
ZW
22113 /* When the address of a Thumb function is taken the bottom
22114 bit of that address should be set. This will allow
22115 interworking between Arm and Thumb functions to work
22116 correctly. */
b99bd4ef 22117
c19d1205 22118 THUMB_SET_FUNC (sym, 1);
b99bd4ef 22119
c19d1205 22120 label_is_thumb_function_name = FALSE;
b99bd4ef 22121 }
07a53e5c 22122
07a53e5c 22123 dwarf2_emit_label (sym);
b99bd4ef
NC
22124}
22125
c921be7d 22126bfd_boolean
c19d1205 22127arm_data_in_code (void)
b99bd4ef 22128{
c19d1205 22129 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
b99bd4ef 22130 {
c19d1205
ZW
22131 *input_line_pointer = '/';
22132 input_line_pointer += 5;
22133 *input_line_pointer = 0;
c921be7d 22134 return TRUE;
b99bd4ef
NC
22135 }
22136
c921be7d 22137 return FALSE;
b99bd4ef
NC
22138}
22139
c19d1205
ZW
22140char *
22141arm_canonicalize_symbol_name (char * name)
b99bd4ef 22142{
c19d1205 22143 int len;
b99bd4ef 22144
c19d1205
ZW
22145 if (thumb_mode && (len = strlen (name)) > 5
22146 && streq (name + len - 5, "/data"))
22147 *(name + len - 5) = 0;
b99bd4ef 22148
c19d1205 22149 return name;
b99bd4ef 22150}
c19d1205
ZW
22151\f
22152/* Table of all register names defined by default. The user can
22153 define additional names with .req. Note that all register names
22154 should appear in both upper and lowercase variants. Some registers
22155 also have mixed-case names. */
b99bd4ef 22156
dcbf9037 22157#define REGDEF(s,n,t) { #s, n, REG_TYPE_##t, TRUE, 0 }
c19d1205 22158#define REGNUM(p,n,t) REGDEF(p##n, n, t)
5287ad62 22159#define REGNUM2(p,n,t) REGDEF(p##n, 2 * n, t)
c19d1205
ZW
22160#define REGSET(p,t) \
22161 REGNUM(p, 0,t), REGNUM(p, 1,t), REGNUM(p, 2,t), REGNUM(p, 3,t), \
22162 REGNUM(p, 4,t), REGNUM(p, 5,t), REGNUM(p, 6,t), REGNUM(p, 7,t), \
22163 REGNUM(p, 8,t), REGNUM(p, 9,t), REGNUM(p,10,t), REGNUM(p,11,t), \
22164 REGNUM(p,12,t), REGNUM(p,13,t), REGNUM(p,14,t), REGNUM(p,15,t)
5287ad62
JB
22165#define REGSETH(p,t) \
22166 REGNUM(p,16,t), REGNUM(p,17,t), REGNUM(p,18,t), REGNUM(p,19,t), \
22167 REGNUM(p,20,t), REGNUM(p,21,t), REGNUM(p,22,t), REGNUM(p,23,t), \
22168 REGNUM(p,24,t), REGNUM(p,25,t), REGNUM(p,26,t), REGNUM(p,27,t), \
22169 REGNUM(p,28,t), REGNUM(p,29,t), REGNUM(p,30,t), REGNUM(p,31,t)
22170#define REGSET2(p,t) \
22171 REGNUM2(p, 0,t), REGNUM2(p, 1,t), REGNUM2(p, 2,t), REGNUM2(p, 3,t), \
22172 REGNUM2(p, 4,t), REGNUM2(p, 5,t), REGNUM2(p, 6,t), REGNUM2(p, 7,t), \
22173 REGNUM2(p, 8,t), REGNUM2(p, 9,t), REGNUM2(p,10,t), REGNUM2(p,11,t), \
22174 REGNUM2(p,12,t), REGNUM2(p,13,t), REGNUM2(p,14,t), REGNUM2(p,15,t)
90ec0d68
MGD
22175#define SPLRBANK(base,bank,t) \
22176 REGDEF(lr_##bank, 768|((base+0)<<16), t), \
22177 REGDEF(sp_##bank, 768|((base+1)<<16), t), \
22178 REGDEF(spsr_##bank, 768|(base<<16)|SPSR_BIT, t), \
22179 REGDEF(LR_##bank, 768|((base+0)<<16), t), \
22180 REGDEF(SP_##bank, 768|((base+1)<<16), t), \
22181 REGDEF(SPSR_##bank, 768|(base<<16)|SPSR_BIT, t)
7ed4c4c5 22182
c19d1205 22183static const struct reg_entry reg_names[] =
7ed4c4c5 22184{
c19d1205
ZW
22185 /* ARM integer registers. */
22186 REGSET(r, RN), REGSET(R, RN),
7ed4c4c5 22187
c19d1205
ZW
22188 /* ATPCS synonyms. */
22189 REGDEF(a1,0,RN), REGDEF(a2,1,RN), REGDEF(a3, 2,RN), REGDEF(a4, 3,RN),
22190 REGDEF(v1,4,RN), REGDEF(v2,5,RN), REGDEF(v3, 6,RN), REGDEF(v4, 7,RN),
22191 REGDEF(v5,8,RN), REGDEF(v6,9,RN), REGDEF(v7,10,RN), REGDEF(v8,11,RN),
7ed4c4c5 22192
c19d1205
ZW
22193 REGDEF(A1,0,RN), REGDEF(A2,1,RN), REGDEF(A3, 2,RN), REGDEF(A4, 3,RN),
22194 REGDEF(V1,4,RN), REGDEF(V2,5,RN), REGDEF(V3, 6,RN), REGDEF(V4, 7,RN),
22195 REGDEF(V5,8,RN), REGDEF(V6,9,RN), REGDEF(V7,10,RN), REGDEF(V8,11,RN),
7ed4c4c5 22196
c19d1205
ZW
22197 /* Well-known aliases. */
22198 REGDEF(wr, 7,RN), REGDEF(sb, 9,RN), REGDEF(sl,10,RN), REGDEF(fp,11,RN),
22199 REGDEF(ip,12,RN), REGDEF(sp,13,RN), REGDEF(lr,14,RN), REGDEF(pc,15,RN),
22200
22201 REGDEF(WR, 7,RN), REGDEF(SB, 9,RN), REGDEF(SL,10,RN), REGDEF(FP,11,RN),
22202 REGDEF(IP,12,RN), REGDEF(SP,13,RN), REGDEF(LR,14,RN), REGDEF(PC,15,RN),
22203
1b883319
AV
22204 /* Defining the new Zero register from ARMv8.1-M. */
22205 REGDEF(zr,15,ZR),
22206 REGDEF(ZR,15,ZR),
22207
c19d1205
ZW
22208 /* Coprocessor numbers. */
22209 REGSET(p, CP), REGSET(P, CP),
22210
22211 /* Coprocessor register numbers. The "cr" variants are for backward
22212 compatibility. */
22213 REGSET(c, CN), REGSET(C, CN),
22214 REGSET(cr, CN), REGSET(CR, CN),
22215
90ec0d68
MGD
22216 /* ARM banked registers. */
22217 REGDEF(R8_usr,512|(0<<16),RNB), REGDEF(r8_usr,512|(0<<16),RNB),
22218 REGDEF(R9_usr,512|(1<<16),RNB), REGDEF(r9_usr,512|(1<<16),RNB),
22219 REGDEF(R10_usr,512|(2<<16),RNB), REGDEF(r10_usr,512|(2<<16),RNB),
22220 REGDEF(R11_usr,512|(3<<16),RNB), REGDEF(r11_usr,512|(3<<16),RNB),
22221 REGDEF(R12_usr,512|(4<<16),RNB), REGDEF(r12_usr,512|(4<<16),RNB),
22222 REGDEF(SP_usr,512|(5<<16),RNB), REGDEF(sp_usr,512|(5<<16),RNB),
22223 REGDEF(LR_usr,512|(6<<16),RNB), REGDEF(lr_usr,512|(6<<16),RNB),
22224
22225 REGDEF(R8_fiq,512|(8<<16),RNB), REGDEF(r8_fiq,512|(8<<16),RNB),
22226 REGDEF(R9_fiq,512|(9<<16),RNB), REGDEF(r9_fiq,512|(9<<16),RNB),
22227 REGDEF(R10_fiq,512|(10<<16),RNB), REGDEF(r10_fiq,512|(10<<16),RNB),
22228 REGDEF(R11_fiq,512|(11<<16),RNB), REGDEF(r11_fiq,512|(11<<16),RNB),
22229 REGDEF(R12_fiq,512|(12<<16),RNB), REGDEF(r12_fiq,512|(12<<16),RNB),
1472d06f 22230 REGDEF(SP_fiq,512|(13<<16),RNB), REGDEF(sp_fiq,512|(13<<16),RNB),
90ec0d68
MGD
22231 REGDEF(LR_fiq,512|(14<<16),RNB), REGDEF(lr_fiq,512|(14<<16),RNB),
22232 REGDEF(SPSR_fiq,512|(14<<16)|SPSR_BIT,RNB), REGDEF(spsr_fiq,512|(14<<16)|SPSR_BIT,RNB),
22233
22234 SPLRBANK(0,IRQ,RNB), SPLRBANK(0,irq,RNB),
22235 SPLRBANK(2,SVC,RNB), SPLRBANK(2,svc,RNB),
22236 SPLRBANK(4,ABT,RNB), SPLRBANK(4,abt,RNB),
22237 SPLRBANK(6,UND,RNB), SPLRBANK(6,und,RNB),
22238 SPLRBANK(12,MON,RNB), SPLRBANK(12,mon,RNB),
22239 REGDEF(elr_hyp,768|(14<<16),RNB), REGDEF(ELR_hyp,768|(14<<16),RNB),
22240 REGDEF(sp_hyp,768|(15<<16),RNB), REGDEF(SP_hyp,768|(15<<16),RNB),
fa94de6b 22241 REGDEF(spsr_hyp,768|(14<<16)|SPSR_BIT,RNB),
90ec0d68
MGD
22242 REGDEF(SPSR_hyp,768|(14<<16)|SPSR_BIT,RNB),
22243
c19d1205
ZW
22244 /* FPA registers. */
22245 REGNUM(f,0,FN), REGNUM(f,1,FN), REGNUM(f,2,FN), REGNUM(f,3,FN),
22246 REGNUM(f,4,FN), REGNUM(f,5,FN), REGNUM(f,6,FN), REGNUM(f,7, FN),
22247
22248 REGNUM(F,0,FN), REGNUM(F,1,FN), REGNUM(F,2,FN), REGNUM(F,3,FN),
22249 REGNUM(F,4,FN), REGNUM(F,5,FN), REGNUM(F,6,FN), REGNUM(F,7, FN),
22250
22251 /* VFP SP registers. */
5287ad62
JB
22252 REGSET(s,VFS), REGSET(S,VFS),
22253 REGSETH(s,VFS), REGSETH(S,VFS),
c19d1205
ZW
22254
22255 /* VFP DP Registers. */
5287ad62
JB
22256 REGSET(d,VFD), REGSET(D,VFD),
22257 /* Extra Neon DP registers. */
22258 REGSETH(d,VFD), REGSETH(D,VFD),
22259
22260 /* Neon QP registers. */
22261 REGSET2(q,NQ), REGSET2(Q,NQ),
c19d1205
ZW
22262
22263 /* VFP control registers. */
22264 REGDEF(fpsid,0,VFC), REGDEF(fpscr,1,VFC), REGDEF(fpexc,8,VFC),
22265 REGDEF(FPSID,0,VFC), REGDEF(FPSCR,1,VFC), REGDEF(FPEXC,8,VFC),
cd2cf30b
PB
22266 REGDEF(fpinst,9,VFC), REGDEF(fpinst2,10,VFC),
22267 REGDEF(FPINST,9,VFC), REGDEF(FPINST2,10,VFC),
22268 REGDEF(mvfr0,7,VFC), REGDEF(mvfr1,6,VFC),
22269 REGDEF(MVFR0,7,VFC), REGDEF(MVFR1,6,VFC),
40c7d507 22270 REGDEF(mvfr2,5,VFC), REGDEF(MVFR2,5,VFC),
c19d1205
ZW
22271
22272 /* Maverick DSP coprocessor registers. */
22273 REGSET(mvf,MVF), REGSET(mvd,MVD), REGSET(mvfx,MVFX), REGSET(mvdx,MVDX),
22274 REGSET(MVF,MVF), REGSET(MVD,MVD), REGSET(MVFX,MVFX), REGSET(MVDX,MVDX),
22275
22276 REGNUM(mvax,0,MVAX), REGNUM(mvax,1,MVAX),
22277 REGNUM(mvax,2,MVAX), REGNUM(mvax,3,MVAX),
22278 REGDEF(dspsc,0,DSPSC),
22279
22280 REGNUM(MVAX,0,MVAX), REGNUM(MVAX,1,MVAX),
22281 REGNUM(MVAX,2,MVAX), REGNUM(MVAX,3,MVAX),
22282 REGDEF(DSPSC,0,DSPSC),
22283
22284 /* iWMMXt data registers - p0, c0-15. */
22285 REGSET(wr,MMXWR), REGSET(wR,MMXWR), REGSET(WR, MMXWR),
22286
22287 /* iWMMXt control registers - p1, c0-3. */
22288 REGDEF(wcid, 0,MMXWC), REGDEF(wCID, 0,MMXWC), REGDEF(WCID, 0,MMXWC),
22289 REGDEF(wcon, 1,MMXWC), REGDEF(wCon, 1,MMXWC), REGDEF(WCON, 1,MMXWC),
22290 REGDEF(wcssf, 2,MMXWC), REGDEF(wCSSF, 2,MMXWC), REGDEF(WCSSF, 2,MMXWC),
22291 REGDEF(wcasf, 3,MMXWC), REGDEF(wCASF, 3,MMXWC), REGDEF(WCASF, 3,MMXWC),
22292
22293 /* iWMMXt scalar (constant/offset) registers - p1, c8-11. */
22294 REGDEF(wcgr0, 8,MMXWCG), REGDEF(wCGR0, 8,MMXWCG), REGDEF(WCGR0, 8,MMXWCG),
22295 REGDEF(wcgr1, 9,MMXWCG), REGDEF(wCGR1, 9,MMXWCG), REGDEF(WCGR1, 9,MMXWCG),
22296 REGDEF(wcgr2,10,MMXWCG), REGDEF(wCGR2,10,MMXWCG), REGDEF(WCGR2,10,MMXWCG),
22297 REGDEF(wcgr3,11,MMXWCG), REGDEF(wCGR3,11,MMXWCG), REGDEF(WCGR3,11,MMXWCG),
22298
22299 /* XScale accumulator registers. */
22300 REGNUM(acc,0,XSCALE), REGNUM(ACC,0,XSCALE),
22301};
22302#undef REGDEF
22303#undef REGNUM
22304#undef REGSET
7ed4c4c5 22305
c19d1205
ZW
22306/* Table of all PSR suffixes. Bare "CPSR" and "SPSR" are handled
22307 within psr_required_here. */
22308static const struct asm_psr psrs[] =
22309{
22310 /* Backward compatibility notation. Note that "all" is no longer
22311 truly all possible PSR bits. */
22312 {"all", PSR_c | PSR_f},
22313 {"flg", PSR_f},
22314 {"ctl", PSR_c},
22315
22316 /* Individual flags. */
22317 {"f", PSR_f},
22318 {"c", PSR_c},
22319 {"x", PSR_x},
22320 {"s", PSR_s},
59b42a0d 22321
c19d1205
ZW
22322 /* Combinations of flags. */
22323 {"fs", PSR_f | PSR_s},
22324 {"fx", PSR_f | PSR_x},
22325 {"fc", PSR_f | PSR_c},
22326 {"sf", PSR_s | PSR_f},
22327 {"sx", PSR_s | PSR_x},
22328 {"sc", PSR_s | PSR_c},
22329 {"xf", PSR_x | PSR_f},
22330 {"xs", PSR_x | PSR_s},
22331 {"xc", PSR_x | PSR_c},
22332 {"cf", PSR_c | PSR_f},
22333 {"cs", PSR_c | PSR_s},
22334 {"cx", PSR_c | PSR_x},
22335 {"fsx", PSR_f | PSR_s | PSR_x},
22336 {"fsc", PSR_f | PSR_s | PSR_c},
22337 {"fxs", PSR_f | PSR_x | PSR_s},
22338 {"fxc", PSR_f | PSR_x | PSR_c},
22339 {"fcs", PSR_f | PSR_c | PSR_s},
22340 {"fcx", PSR_f | PSR_c | PSR_x},
22341 {"sfx", PSR_s | PSR_f | PSR_x},
22342 {"sfc", PSR_s | PSR_f | PSR_c},
22343 {"sxf", PSR_s | PSR_x | PSR_f},
22344 {"sxc", PSR_s | PSR_x | PSR_c},
22345 {"scf", PSR_s | PSR_c | PSR_f},
22346 {"scx", PSR_s | PSR_c | PSR_x},
22347 {"xfs", PSR_x | PSR_f | PSR_s},
22348 {"xfc", PSR_x | PSR_f | PSR_c},
22349 {"xsf", PSR_x | PSR_s | PSR_f},
22350 {"xsc", PSR_x | PSR_s | PSR_c},
22351 {"xcf", PSR_x | PSR_c | PSR_f},
22352 {"xcs", PSR_x | PSR_c | PSR_s},
22353 {"cfs", PSR_c | PSR_f | PSR_s},
22354 {"cfx", PSR_c | PSR_f | PSR_x},
22355 {"csf", PSR_c | PSR_s | PSR_f},
22356 {"csx", PSR_c | PSR_s | PSR_x},
22357 {"cxf", PSR_c | PSR_x | PSR_f},
22358 {"cxs", PSR_c | PSR_x | PSR_s},
22359 {"fsxc", PSR_f | PSR_s | PSR_x | PSR_c},
22360 {"fscx", PSR_f | PSR_s | PSR_c | PSR_x},
22361 {"fxsc", PSR_f | PSR_x | PSR_s | PSR_c},
22362 {"fxcs", PSR_f | PSR_x | PSR_c | PSR_s},
22363 {"fcsx", PSR_f | PSR_c | PSR_s | PSR_x},
22364 {"fcxs", PSR_f | PSR_c | PSR_x | PSR_s},
22365 {"sfxc", PSR_s | PSR_f | PSR_x | PSR_c},
22366 {"sfcx", PSR_s | PSR_f | PSR_c | PSR_x},
22367 {"sxfc", PSR_s | PSR_x | PSR_f | PSR_c},
22368 {"sxcf", PSR_s | PSR_x | PSR_c | PSR_f},
22369 {"scfx", PSR_s | PSR_c | PSR_f | PSR_x},
22370 {"scxf", PSR_s | PSR_c | PSR_x | PSR_f},
22371 {"xfsc", PSR_x | PSR_f | PSR_s | PSR_c},
22372 {"xfcs", PSR_x | PSR_f | PSR_c | PSR_s},
22373 {"xsfc", PSR_x | PSR_s | PSR_f | PSR_c},
22374 {"xscf", PSR_x | PSR_s | PSR_c | PSR_f},
22375 {"xcfs", PSR_x | PSR_c | PSR_f | PSR_s},
22376 {"xcsf", PSR_x | PSR_c | PSR_s | PSR_f},
22377 {"cfsx", PSR_c | PSR_f | PSR_s | PSR_x},
22378 {"cfxs", PSR_c | PSR_f | PSR_x | PSR_s},
22379 {"csfx", PSR_c | PSR_s | PSR_f | PSR_x},
22380 {"csxf", PSR_c | PSR_s | PSR_x | PSR_f},
22381 {"cxfs", PSR_c | PSR_x | PSR_f | PSR_s},
22382 {"cxsf", PSR_c | PSR_x | PSR_s | PSR_f},
22383};
22384
62b3e311
PB
22385/* Table of V7M psr names. */
22386static const struct asm_psr v7m_psrs[] =
22387{
1a336194
TP
22388 {"apsr", 0x0 }, {"APSR", 0x0 },
22389 {"iapsr", 0x1 }, {"IAPSR", 0x1 },
22390 {"eapsr", 0x2 }, {"EAPSR", 0x2 },
22391 {"psr", 0x3 }, {"PSR", 0x3 },
22392 {"xpsr", 0x3 }, {"XPSR", 0x3 }, {"xPSR", 3 },
22393 {"ipsr", 0x5 }, {"IPSR", 0x5 },
22394 {"epsr", 0x6 }, {"EPSR", 0x6 },
22395 {"iepsr", 0x7 }, {"IEPSR", 0x7 },
22396 {"msp", 0x8 }, {"MSP", 0x8 },
22397 {"psp", 0x9 }, {"PSP", 0x9 },
22398 {"msplim", 0xa }, {"MSPLIM", 0xa },
22399 {"psplim", 0xb }, {"PSPLIM", 0xb },
22400 {"primask", 0x10}, {"PRIMASK", 0x10},
22401 {"basepri", 0x11}, {"BASEPRI", 0x11},
22402 {"basepri_max", 0x12}, {"BASEPRI_MAX", 0x12},
1a336194
TP
22403 {"faultmask", 0x13}, {"FAULTMASK", 0x13},
22404 {"control", 0x14}, {"CONTROL", 0x14},
22405 {"msp_ns", 0x88}, {"MSP_NS", 0x88},
22406 {"psp_ns", 0x89}, {"PSP_NS", 0x89},
22407 {"msplim_ns", 0x8a}, {"MSPLIM_NS", 0x8a},
22408 {"psplim_ns", 0x8b}, {"PSPLIM_NS", 0x8b},
22409 {"primask_ns", 0x90}, {"PRIMASK_NS", 0x90},
22410 {"basepri_ns", 0x91}, {"BASEPRI_NS", 0x91},
22411 {"faultmask_ns", 0x93}, {"FAULTMASK_NS", 0x93},
22412 {"control_ns", 0x94}, {"CONTROL_NS", 0x94},
22413 {"sp_ns", 0x98}, {"SP_NS", 0x98 }
62b3e311
PB
22414};
22415
c19d1205
ZW
22416/* Table of all shift-in-operand names. */
22417static const struct asm_shift_name shift_names [] =
b99bd4ef 22418{
c19d1205
ZW
22419 { "asl", SHIFT_LSL }, { "ASL", SHIFT_LSL },
22420 { "lsl", SHIFT_LSL }, { "LSL", SHIFT_LSL },
22421 { "lsr", SHIFT_LSR }, { "LSR", SHIFT_LSR },
22422 { "asr", SHIFT_ASR }, { "ASR", SHIFT_ASR },
22423 { "ror", SHIFT_ROR }, { "ROR", SHIFT_ROR },
f5f10c66
AV
22424 { "rrx", SHIFT_RRX }, { "RRX", SHIFT_RRX },
22425 { "uxtw", SHIFT_UXTW}, { "UXTW", SHIFT_UXTW}
c19d1205 22426};
b99bd4ef 22427
c19d1205
ZW
22428/* Table of all explicit relocation names. */
22429#ifdef OBJ_ELF
22430static struct reloc_entry reloc_names[] =
22431{
22432 { "got", BFD_RELOC_ARM_GOT32 }, { "GOT", BFD_RELOC_ARM_GOT32 },
22433 { "gotoff", BFD_RELOC_ARM_GOTOFF }, { "GOTOFF", BFD_RELOC_ARM_GOTOFF },
22434 { "plt", BFD_RELOC_ARM_PLT32 }, { "PLT", BFD_RELOC_ARM_PLT32 },
22435 { "target1", BFD_RELOC_ARM_TARGET1 }, { "TARGET1", BFD_RELOC_ARM_TARGET1 },
22436 { "target2", BFD_RELOC_ARM_TARGET2 }, { "TARGET2", BFD_RELOC_ARM_TARGET2 },
22437 { "sbrel", BFD_RELOC_ARM_SBREL32 }, { "SBREL", BFD_RELOC_ARM_SBREL32 },
22438 { "tlsgd", BFD_RELOC_ARM_TLS_GD32}, { "TLSGD", BFD_RELOC_ARM_TLS_GD32},
22439 { "tlsldm", BFD_RELOC_ARM_TLS_LDM32}, { "TLSLDM", BFD_RELOC_ARM_TLS_LDM32},
22440 { "tlsldo", BFD_RELOC_ARM_TLS_LDO32}, { "TLSLDO", BFD_RELOC_ARM_TLS_LDO32},
22441 { "gottpoff",BFD_RELOC_ARM_TLS_IE32}, { "GOTTPOFF",BFD_RELOC_ARM_TLS_IE32},
b43420e6 22442 { "tpoff", BFD_RELOC_ARM_TLS_LE32}, { "TPOFF", BFD_RELOC_ARM_TLS_LE32},
0855e32b
NS
22443 { "got_prel", BFD_RELOC_ARM_GOT_PREL}, { "GOT_PREL", BFD_RELOC_ARM_GOT_PREL},
22444 { "tlsdesc", BFD_RELOC_ARM_TLS_GOTDESC},
477330fc 22445 { "TLSDESC", BFD_RELOC_ARM_TLS_GOTDESC},
0855e32b 22446 { "tlscall", BFD_RELOC_ARM_TLS_CALL},
477330fc 22447 { "TLSCALL", BFD_RELOC_ARM_TLS_CALL},
0855e32b 22448 { "tlsdescseq", BFD_RELOC_ARM_TLS_DESCSEQ},
188fd7ae
CL
22449 { "TLSDESCSEQ", BFD_RELOC_ARM_TLS_DESCSEQ},
22450 { "gotfuncdesc", BFD_RELOC_ARM_GOTFUNCDESC },
22451 { "GOTFUNCDESC", BFD_RELOC_ARM_GOTFUNCDESC },
22452 { "gotofffuncdesc", BFD_RELOC_ARM_GOTOFFFUNCDESC },
22453 { "GOTOFFFUNCDESC", BFD_RELOC_ARM_GOTOFFFUNCDESC },
22454 { "funcdesc", BFD_RELOC_ARM_FUNCDESC },
5c5a4843
CL
22455 { "FUNCDESC", BFD_RELOC_ARM_FUNCDESC },
22456 { "tlsgd_fdpic", BFD_RELOC_ARM_TLS_GD32_FDPIC }, { "TLSGD_FDPIC", BFD_RELOC_ARM_TLS_GD32_FDPIC },
22457 { "tlsldm_fdpic", BFD_RELOC_ARM_TLS_LDM32_FDPIC }, { "TLSLDM_FDPIC", BFD_RELOC_ARM_TLS_LDM32_FDPIC },
22458 { "gottpoff_fdpic", BFD_RELOC_ARM_TLS_IE32_FDPIC }, { "GOTTPOFF_FDIC", BFD_RELOC_ARM_TLS_IE32_FDPIC },
c19d1205
ZW
22459};
22460#endif
b99bd4ef 22461
5ee91343 22462/* Table of all conditional affixes. */
c19d1205
ZW
22463static const struct asm_cond conds[] =
22464{
22465 {"eq", 0x0},
22466 {"ne", 0x1},
22467 {"cs", 0x2}, {"hs", 0x2},
22468 {"cc", 0x3}, {"ul", 0x3}, {"lo", 0x3},
22469 {"mi", 0x4},
22470 {"pl", 0x5},
22471 {"vs", 0x6},
22472 {"vc", 0x7},
22473 {"hi", 0x8},
22474 {"ls", 0x9},
22475 {"ge", 0xa},
22476 {"lt", 0xb},
22477 {"gt", 0xc},
22478 {"le", 0xd},
22479 {"al", 0xe}
22480};
5ee91343
AV
22481static const struct asm_cond vconds[] =
22482{
22483 {"t", 0xf},
22484 {"e", 0x10}
22485};
bfae80f2 22486
e797f7e0 22487#define UL_BARRIER(L,U,CODE,FEAT) \
823d2571
TG
22488 { L, CODE, ARM_FEATURE_CORE_LOW (FEAT) }, \
22489 { U, CODE, ARM_FEATURE_CORE_LOW (FEAT) }
e797f7e0 22490
62b3e311
PB
22491static struct asm_barrier_opt barrier_opt_names[] =
22492{
e797f7e0
MGD
22493 UL_BARRIER ("sy", "SY", 0xf, ARM_EXT_BARRIER),
22494 UL_BARRIER ("st", "ST", 0xe, ARM_EXT_BARRIER),
22495 UL_BARRIER ("ld", "LD", 0xd, ARM_EXT_V8),
22496 UL_BARRIER ("ish", "ISH", 0xb, ARM_EXT_BARRIER),
22497 UL_BARRIER ("sh", "SH", 0xb, ARM_EXT_BARRIER),
22498 UL_BARRIER ("ishst", "ISHST", 0xa, ARM_EXT_BARRIER),
22499 UL_BARRIER ("shst", "SHST", 0xa, ARM_EXT_BARRIER),
22500 UL_BARRIER ("ishld", "ISHLD", 0x9, ARM_EXT_V8),
22501 UL_BARRIER ("un", "UN", 0x7, ARM_EXT_BARRIER),
22502 UL_BARRIER ("nsh", "NSH", 0x7, ARM_EXT_BARRIER),
22503 UL_BARRIER ("unst", "UNST", 0x6, ARM_EXT_BARRIER),
22504 UL_BARRIER ("nshst", "NSHST", 0x6, ARM_EXT_BARRIER),
22505 UL_BARRIER ("nshld", "NSHLD", 0x5, ARM_EXT_V8),
22506 UL_BARRIER ("osh", "OSH", 0x3, ARM_EXT_BARRIER),
22507 UL_BARRIER ("oshst", "OSHST", 0x2, ARM_EXT_BARRIER),
22508 UL_BARRIER ("oshld", "OSHLD", 0x1, ARM_EXT_V8)
62b3e311
PB
22509};
22510
e797f7e0
MGD
22511#undef UL_BARRIER
22512
c19d1205
ZW
22513/* Table of ARM-format instructions. */
22514
22515/* Macros for gluing together operand strings. N.B. In all cases
22516 other than OPS0, the trailing OP_stop comes from default
22517 zero-initialization of the unspecified elements of the array. */
22518#define OPS0() { OP_stop, }
22519#define OPS1(a) { OP_##a, }
22520#define OPS2(a,b) { OP_##a,OP_##b, }
22521#define OPS3(a,b,c) { OP_##a,OP_##b,OP_##c, }
22522#define OPS4(a,b,c,d) { OP_##a,OP_##b,OP_##c,OP_##d, }
22523#define OPS5(a,b,c,d,e) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e, }
22524#define OPS6(a,b,c,d,e,f) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e,OP_##f, }
22525
5be8be5d
DG
22526/* These macros are similar to the OPSn, but do not prepend the OP_ prefix.
22527 This is useful when mixing operands for ARM and THUMB, i.e. using the
22528 MIX_ARM_THUMB_OPERANDS macro.
22529 In order to use these macros, prefix the number of operands with _
22530 e.g. _3. */
22531#define OPS_1(a) { a, }
22532#define OPS_2(a,b) { a,b, }
22533#define OPS_3(a,b,c) { a,b,c, }
22534#define OPS_4(a,b,c,d) { a,b,c,d, }
22535#define OPS_5(a,b,c,d,e) { a,b,c,d,e, }
22536#define OPS_6(a,b,c,d,e,f) { a,b,c,d,e,f, }
22537
c19d1205
ZW
22538/* These macros abstract out the exact format of the mnemonic table and
22539 save some repeated characters. */
22540
22541/* The normal sort of mnemonic; has a Thumb variant; takes a conditional suffix. */
22542#define TxCE(mnem, op, top, nops, ops, ae, te) \
21d799b5 22543 { mnem, OPS##nops ops, OT_csuffix, 0x##op, top, ARM_VARIANT, \
5ee91343 22544 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205
ZW
22545
22546/* Two variants of the above - TCE for a numeric Thumb opcode, tCE for
22547 a T_MNEM_xyz enumerator. */
22548#define TCE(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 22549 TxCE (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 22550#define tCE(mnem, aop, top, nops, ops, ae, te) \
21d799b5 22551 TxCE (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205
ZW
22552
22553/* Second most common sort of mnemonic: has a Thumb variant, takes a conditional
22554 infix after the third character. */
22555#define TxC3(mnem, op, top, nops, ops, ae, te) \
21d799b5 22556 { mnem, OPS##nops ops, OT_cinfix3, 0x##op, top, ARM_VARIANT, \
5ee91343 22557 THUMB_VARIANT, do_##ae, do_##te, 0 }
088fa78e 22558#define TxC3w(mnem, op, top, nops, ops, ae, te) \
21d799b5 22559 { mnem, OPS##nops ops, OT_cinfix3_deprecated, 0x##op, top, ARM_VARIANT, \
5ee91343 22560 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205 22561#define TC3(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 22562 TxC3 (mnem, aop, 0x##top, nops, ops, ae, te)
088fa78e 22563#define TC3w(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 22564 TxC3w (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 22565#define tC3(mnem, aop, top, nops, ops, ae, te) \
21d799b5 22566 TxC3 (mnem, aop, T_MNEM##top, nops, ops, ae, te)
088fa78e 22567#define tC3w(mnem, aop, top, nops, ops, ae, te) \
21d799b5 22568 TxC3w (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205 22569
c19d1205 22570/* Mnemonic that cannot be conditionalized. The ARM condition-code
dfa9f0d5
PB
22571 field is still 0xE. Many of the Thumb variants can be executed
22572 conditionally, so this is checked separately. */
c19d1205 22573#define TUE(mnem, op, top, nops, ops, ae, te) \
21d799b5 22574 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 22575 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205 22576
dd5181d5
KT
22577/* Same as TUE but the encoding function for ARM and Thumb modes is the same.
22578 Used by mnemonics that have very minimal differences in the encoding for
22579 ARM and Thumb variants and can be handled in a common function. */
22580#define TUEc(mnem, op, top, nops, ops, en) \
22581 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 22582 THUMB_VARIANT, do_##en, do_##en, 0 }
dd5181d5 22583
c19d1205
ZW
22584/* Mnemonic that cannot be conditionalized, and bears 0xF in its ARM
22585 condition code field. */
22586#define TUF(mnem, op, top, nops, ops, ae, te) \
21d799b5 22587 { mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 22588 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205
ZW
22589
22590/* ARM-only variants of all the above. */
6a86118a 22591#define CE(mnem, op, nops, ops, ae) \
5ee91343 22592 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
22593
22594#define C3(mnem, op, nops, ops, ae) \
5ee91343 22595 { #mnem, OPS##nops ops, OT_cinfix3, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a 22596
cf3cf39d
TP
22597/* Thumb-only variants of TCE and TUE. */
22598#define ToC(mnem, top, nops, ops, te) \
22599 { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
5ee91343 22600 do_##te, 0 }
cf3cf39d
TP
22601
22602#define ToU(mnem, top, nops, ops, te) \
22603 { mnem, OPS##nops ops, OT_unconditional, 0x0, 0x##top, 0, THUMB_VARIANT, \
5ee91343 22604 NULL, do_##te, 0 }
cf3cf39d 22605
4389b29a
AV
22606/* T_MNEM_xyz enumerator variants of ToC. */
22607#define toC(mnem, top, nops, ops, te) \
22608 { mnem, OPS##nops ops, OT_csuffix, 0x0, T_MNEM##top, 0, THUMB_VARIANT, NULL, \
5ee91343 22609 do_##te, 0 }
4389b29a 22610
f6b2b12d
AV
22611/* T_MNEM_xyz enumerator variants of ToU. */
22612#define toU(mnem, top, nops, ops, te) \
22613 { mnem, OPS##nops ops, OT_unconditional, 0x0, T_MNEM##top, 0, THUMB_VARIANT, \
5ee91343 22614 NULL, do_##te, 0 }
f6b2b12d 22615
e3cb604e
PB
22616/* Legacy mnemonics that always have conditional infix after the third
22617 character. */
22618#define CL(mnem, op, nops, ops, ae) \
21d799b5 22619 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
5ee91343 22620 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
e3cb604e 22621
8f06b2d8
PB
22622/* Coprocessor instructions. Isomorphic between Arm and Thumb-2. */
22623#define cCE(mnem, op, nops, ops, ae) \
5ee91343 22624 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
8f06b2d8 22625
57785aa2
AV
22626/* mov instructions that are shared between coprocessor and MVE. */
22627#define mcCE(mnem, op, nops, ops, ae) \
22628 { #mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, THUMB_VARIANT, do_##ae, do_##ae, 0 }
22629
e3cb604e
PB
22630/* Legacy coprocessor instructions where conditional infix and conditional
22631 suffix are ambiguous. For consistency this includes all FPA instructions,
22632 not just the potentially ambiguous ones. */
22633#define cCL(mnem, op, nops, ops, ae) \
21d799b5 22634 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
5ee91343 22635 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
e3cb604e
PB
22636
22637/* Coprocessor, takes either a suffix or a position-3 infix
22638 (for an FPA corner case). */
22639#define C3E(mnem, op, nops, ops, ae) \
21d799b5 22640 { mnem, OPS##nops ops, OT_csuf_or_in3, \
5ee91343 22641 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
8f06b2d8 22642
6a86118a 22643#define xCM_(m1, m2, m3, op, nops, ops, ae) \
21d799b5
NC
22644 { m1 #m2 m3, OPS##nops ops, \
22645 sizeof (#m2) == 1 ? OT_odd_infix_unc : OT_odd_infix_0 + sizeof (m1) - 1, \
5ee91343 22646 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
22647
22648#define CM(m1, m2, op, nops, ops, ae) \
e07e6e58
NC
22649 xCM_ (m1, , m2, op, nops, ops, ae), \
22650 xCM_ (m1, eq, m2, op, nops, ops, ae), \
22651 xCM_ (m1, ne, m2, op, nops, ops, ae), \
22652 xCM_ (m1, cs, m2, op, nops, ops, ae), \
22653 xCM_ (m1, hs, m2, op, nops, ops, ae), \
22654 xCM_ (m1, cc, m2, op, nops, ops, ae), \
22655 xCM_ (m1, ul, m2, op, nops, ops, ae), \
22656 xCM_ (m1, lo, m2, op, nops, ops, ae), \
22657 xCM_ (m1, mi, m2, op, nops, ops, ae), \
22658 xCM_ (m1, pl, m2, op, nops, ops, ae), \
22659 xCM_ (m1, vs, m2, op, nops, ops, ae), \
22660 xCM_ (m1, vc, m2, op, nops, ops, ae), \
22661 xCM_ (m1, hi, m2, op, nops, ops, ae), \
22662 xCM_ (m1, ls, m2, op, nops, ops, ae), \
22663 xCM_ (m1, ge, m2, op, nops, ops, ae), \
22664 xCM_ (m1, lt, m2, op, nops, ops, ae), \
22665 xCM_ (m1, gt, m2, op, nops, ops, ae), \
22666 xCM_ (m1, le, m2, op, nops, ops, ae), \
22667 xCM_ (m1, al, m2, op, nops, ops, ae)
6a86118a
NC
22668
22669#define UE(mnem, op, nops, ops, ae) \
5ee91343 22670 { #mnem, OPS##nops ops, OT_unconditional, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
22671
22672#define UF(mnem, op, nops, ops, ae) \
5ee91343 22673 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a 22674
5287ad62
JB
22675/* Neon data-processing. ARM versions are unconditional with cond=0xf.
22676 The Thumb and ARM variants are mostly the same (bits 0-23 and 24/28), so we
22677 use the same encoding function for each. */
22678#define NUF(mnem, op, nops, ops, enc) \
22679 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op, \
5ee91343 22680 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 0 }
5287ad62
JB
22681
22682/* Neon data processing, version which indirects through neon_enc_tab for
22683 the various overloaded versions of opcodes. */
22684#define nUF(mnem, op, nops, ops, enc) \
21d799b5 22685 { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op, \
5ee91343 22686 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 0 }
5287ad62
JB
22687
22688/* Neon insn with conditional suffix for the ARM version, non-overloaded
22689 version. */
5ee91343 22690#define NCE_tag(mnem, op, nops, ops, enc, tag, mve_p) \
037e8744 22691 { #mnem, OPS##nops ops, tag, 0x##op, 0x##op, ARM_VARIANT, \
5ee91343 22692 THUMB_VARIANT, do_##enc, do_##enc, mve_p }
5287ad62 22693
037e8744 22694#define NCE(mnem, op, nops, ops, enc) \
5ee91343 22695 NCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 0)
037e8744
JB
22696
22697#define NCEF(mnem, op, nops, ops, enc) \
5ee91343 22698 NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 0)
037e8744 22699
5287ad62 22700/* Neon insn with conditional suffix for the ARM version, overloaded types. */
5ee91343 22701#define nCE_tag(mnem, op, nops, ops, enc, tag, mve_p) \
21d799b5 22702 { #mnem, OPS##nops ops, tag, N_MNEM##op, N_MNEM##op, \
5ee91343 22703 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, mve_p }
5287ad62 22704
037e8744 22705#define nCE(mnem, op, nops, ops, enc) \
5ee91343 22706 nCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 0)
037e8744
JB
22707
22708#define nCEF(mnem, op, nops, ops, enc) \
5ee91343
AV
22709 nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 0)
22710
22711/* */
22712#define mCEF(mnem, op, nops, ops, enc) \
a302e574 22713 { #mnem, OPS##nops ops, OT_csuffixF, M_MNEM##op, M_MNEM##op, \
5ee91343
AV
22714 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
22715
22716
22717/* nCEF but for MVE predicated instructions. */
22718#define mnCEF(mnem, op, nops, ops, enc) \
22719 nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 1)
22720
22721/* nCE but for MVE predicated instructions. */
22722#define mnCE(mnem, op, nops, ops, enc) \
22723 nCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 1)
037e8744 22724
5ee91343
AV
22725/* NUF but for potentially MVE predicated instructions. */
22726#define MNUF(mnem, op, nops, ops, enc) \
22727 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op, \
22728 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
22729
22730/* nUF but for potentially MVE predicated instructions. */
22731#define mnUF(mnem, op, nops, ops, enc) \
22732 { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op, \
22733 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
22734
22735/* ToC but for potentially MVE predicated instructions. */
22736#define mToC(mnem, top, nops, ops, te) \
22737 { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
22738 do_##te, 1 }
22739
22740/* NCE but for MVE predicated instructions. */
22741#define MNCE(mnem, op, nops, ops, enc) \
22742 NCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 1)
22743
22744/* NCEF but for MVE predicated instructions. */
22745#define MNCEF(mnem, op, nops, ops, enc) \
22746 NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 1)
c19d1205
ZW
22747#define do_0 0
22748
c19d1205 22749static const struct asm_opcode insns[] =
bfae80f2 22750{
74db7efb
NC
22751#define ARM_VARIANT & arm_ext_v1 /* Core ARM Instructions. */
22752#define THUMB_VARIANT & arm_ext_v4t
21d799b5
NC
22753 tCE("and", 0000000, _and, 3, (RR, oRR, SH), arit, t_arit3c),
22754 tC3("ands", 0100000, _ands, 3, (RR, oRR, SH), arit, t_arit3c),
22755 tCE("eor", 0200000, _eor, 3, (RR, oRR, SH), arit, t_arit3c),
22756 tC3("eors", 0300000, _eors, 3, (RR, oRR, SH), arit, t_arit3c),
22757 tCE("sub", 0400000, _sub, 3, (RR, oRR, SH), arit, t_add_sub),
22758 tC3("subs", 0500000, _subs, 3, (RR, oRR, SH), arit, t_add_sub),
22759 tCE("add", 0800000, _add, 3, (RR, oRR, SHG), arit, t_add_sub),
22760 tC3("adds", 0900000, _adds, 3, (RR, oRR, SHG), arit, t_add_sub),
22761 tCE("adc", 0a00000, _adc, 3, (RR, oRR, SH), arit, t_arit3c),
22762 tC3("adcs", 0b00000, _adcs, 3, (RR, oRR, SH), arit, t_arit3c),
22763 tCE("sbc", 0c00000, _sbc, 3, (RR, oRR, SH), arit, t_arit3),
22764 tC3("sbcs", 0d00000, _sbcs, 3, (RR, oRR, SH), arit, t_arit3),
22765 tCE("orr", 1800000, _orr, 3, (RR, oRR, SH), arit, t_arit3c),
22766 tC3("orrs", 1900000, _orrs, 3, (RR, oRR, SH), arit, t_arit3c),
22767 tCE("bic", 1c00000, _bic, 3, (RR, oRR, SH), arit, t_arit3),
22768 tC3("bics", 1d00000, _bics, 3, (RR, oRR, SH), arit, t_arit3),
c19d1205
ZW
22769
22770 /* The p-variants of tst/cmp/cmn/teq (below) are the pre-V6 mechanism
22771 for setting PSR flag bits. They are obsolete in V6 and do not
22772 have Thumb equivalents. */
21d799b5
NC
22773 tCE("tst", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
22774 tC3w("tsts", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
22775 CL("tstp", 110f000, 2, (RR, SH), cmp),
22776 tCE("cmp", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
22777 tC3w("cmps", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
22778 CL("cmpp", 150f000, 2, (RR, SH), cmp),
22779 tCE("cmn", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
22780 tC3w("cmns", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
22781 CL("cmnp", 170f000, 2, (RR, SH), cmp),
22782
22783 tCE("mov", 1a00000, _mov, 2, (RR, SH), mov, t_mov_cmp),
72d98d16 22784 tC3("movs", 1b00000, _movs, 2, (RR, SHG), mov, t_mov_cmp),
21d799b5
NC
22785 tCE("mvn", 1e00000, _mvn, 2, (RR, SH), mov, t_mvn_tst),
22786 tC3("mvns", 1f00000, _mvns, 2, (RR, SH), mov, t_mvn_tst),
22787
22788 tCE("ldr", 4100000, _ldr, 2, (RR, ADDRGLDR),ldst, t_ldst),
5be8be5d
DG
22789 tC3("ldrb", 4500000, _ldrb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
22790 tCE("str", 4000000, _str, _2, (MIX_ARM_THUMB_OPERANDS (OP_RR,
22791 OP_RRnpc),
22792 OP_ADDRGLDR),ldst, t_ldst),
22793 tC3("strb", 4400000, _strb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
21d799b5
NC
22794
22795 tCE("stm", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
22796 tC3("stmia", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
22797 tC3("stmea", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
22798 tCE("ldm", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
22799 tC3("ldmia", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
22800 tC3("ldmfd", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
22801
21d799b5
NC
22802 tCE("b", a000000, _b, 1, (EXPr), branch, t_branch),
22803 TCE("bl", b000000, f000f800, 1, (EXPr), bl, t_branch23),
bfae80f2 22804
c19d1205 22805 /* Pseudo ops. */
21d799b5 22806 tCE("adr", 28f0000, _adr, 2, (RR, EXP), adr, t_adr),
2fc8bdac 22807 C3(adrl, 28f0000, 2, (RR, EXP), adrl),
21d799b5 22808 tCE("nop", 1a00000, _nop, 1, (oI255c), nop, t_nop),
74db7efb 22809 tCE("udf", 7f000f0, _udf, 1, (oIffffb), bkpt, t_udf),
c19d1205
ZW
22810
22811 /* Thumb-compatibility pseudo ops. */
21d799b5
NC
22812 tCE("lsl", 1a00000, _lsl, 3, (RR, oRR, SH), shift, t_shift),
22813 tC3("lsls", 1b00000, _lsls, 3, (RR, oRR, SH), shift, t_shift),
22814 tCE("lsr", 1a00020, _lsr, 3, (RR, oRR, SH), shift, t_shift),
22815 tC3("lsrs", 1b00020, _lsrs, 3, (RR, oRR, SH), shift, t_shift),
22816 tCE("asr", 1a00040, _asr, 3, (RR, oRR, SH), shift, t_shift),
22817 tC3("asrs", 1b00040, _asrs, 3, (RR, oRR, SH), shift, t_shift),
22818 tCE("ror", 1a00060, _ror, 3, (RR, oRR, SH), shift, t_shift),
22819 tC3("rors", 1b00060, _rors, 3, (RR, oRR, SH), shift, t_shift),
22820 tCE("neg", 2600000, _neg, 2, (RR, RR), rd_rn, t_neg),
22821 tC3("negs", 2700000, _negs, 2, (RR, RR), rd_rn, t_neg),
22822 tCE("push", 92d0000, _push, 1, (REGLST), push_pop, t_push_pop),
22823 tCE("pop", 8bd0000, _pop, 1, (REGLST), push_pop, t_push_pop),
c19d1205 22824
16a4cf17 22825 /* These may simplify to neg. */
21d799b5
NC
22826 TCE("rsb", 0600000, ebc00000, 3, (RR, oRR, SH), arit, t_rsb),
22827 TC3("rsbs", 0700000, ebd00000, 3, (RR, oRR, SH), arit, t_rsb),
16a4cf17 22828
173205ca
TP
22829#undef THUMB_VARIANT
22830#define THUMB_VARIANT & arm_ext_os
22831
22832 TCE("swi", f000000, df00, 1, (EXPi), swi, t_swi),
22833 TCE("svc", f000000, df00, 1, (EXPi), swi, t_swi),
22834
c921be7d
NC
22835#undef THUMB_VARIANT
22836#define THUMB_VARIANT & arm_ext_v6
22837
21d799b5 22838 TCE("cpy", 1a00000, 4600, 2, (RR, RR), rd_rm, t_cpy),
c19d1205
ZW
22839
22840 /* V1 instructions with no Thumb analogue prior to V6T2. */
c921be7d
NC
22841#undef THUMB_VARIANT
22842#define THUMB_VARIANT & arm_ext_v6t2
22843
21d799b5
NC
22844 TCE("teq", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
22845 TC3w("teqs", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
22846 CL("teqp", 130f000, 2, (RR, SH), cmp),
c19d1205 22847
5be8be5d
DG
22848 TC3("ldrt", 4300000, f8500e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
22849 TC3("ldrbt", 4700000, f8100e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
22850 TC3("strt", 4200000, f8400e00, 2, (RR_npcsp, ADDR), ldstt, t_ldstt),
22851 TC3("strbt", 4600000, f8000e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
c19d1205 22852
21d799b5
NC
22853 TC3("stmdb", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
22854 TC3("stmfd", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205 22855
21d799b5
NC
22856 TC3("ldmdb", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
22857 TC3("ldmea", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205
ZW
22858
22859 /* V1 instructions with no Thumb analogue at all. */
21d799b5 22860 CE("rsc", 0e00000, 3, (RR, oRR, SH), arit),
c19d1205
ZW
22861 C3(rscs, 0f00000, 3, (RR, oRR, SH), arit),
22862
22863 C3(stmib, 9800000, 2, (RRw, REGLST), ldmstm),
22864 C3(stmfa, 9800000, 2, (RRw, REGLST), ldmstm),
22865 C3(stmda, 8000000, 2, (RRw, REGLST), ldmstm),
22866 C3(stmed, 8000000, 2, (RRw, REGLST), ldmstm),
22867 C3(ldmib, 9900000, 2, (RRw, REGLST), ldmstm),
22868 C3(ldmed, 9900000, 2, (RRw, REGLST), ldmstm),
22869 C3(ldmda, 8100000, 2, (RRw, REGLST), ldmstm),
22870 C3(ldmfa, 8100000, 2, (RRw, REGLST), ldmstm),
22871
c921be7d
NC
22872#undef ARM_VARIANT
22873#define ARM_VARIANT & arm_ext_v2 /* ARM 2 - multiplies. */
22874#undef THUMB_VARIANT
22875#define THUMB_VARIANT & arm_ext_v4t
22876
21d799b5
NC
22877 tCE("mul", 0000090, _mul, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
22878 tC3("muls", 0100090, _muls, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
c19d1205 22879
c921be7d
NC
22880#undef THUMB_VARIANT
22881#define THUMB_VARIANT & arm_ext_v6t2
22882
21d799b5 22883 TCE("mla", 0200090, fb000000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
c19d1205
ZW
22884 C3(mlas, 0300090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas),
22885
22886 /* Generic coprocessor instructions. */
21d799b5
NC
22887 TCE("cdp", e000000, ee000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
22888 TCE("ldc", c100000, ec100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
22889 TC3("ldcl", c500000, ec500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
22890 TCE("stc", c000000, ec000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
22891 TC3("stcl", c400000, ec400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
22892 TCE("mcr", e000010, ee000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
db472d6f 22893 TCE("mrc", e100010, ee100010, 6, (RCP, I7b, APSR_RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 22894
c921be7d
NC
22895#undef ARM_VARIANT
22896#define ARM_VARIANT & arm_ext_v2s /* ARM 3 - swp instructions. */
22897
21d799b5 22898 CE("swp", 1000090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
c19d1205
ZW
22899 C3(swpb, 1400090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
22900
c921be7d
NC
22901#undef ARM_VARIANT
22902#define ARM_VARIANT & arm_ext_v3 /* ARM 6 Status register instructions. */
22903#undef THUMB_VARIANT
22904#define THUMB_VARIANT & arm_ext_msr
22905
d2cd1205
JB
22906 TCE("mrs", 1000000, f3e08000, 2, (RRnpc, rPSR), mrs, t_mrs),
22907 TCE("msr", 120f000, f3808000, 2, (wPSR, RR_EXi), msr, t_msr),
c19d1205 22908
c921be7d
NC
22909#undef ARM_VARIANT
22910#define ARM_VARIANT & arm_ext_v3m /* ARM 7M long multiplies. */
22911#undef THUMB_VARIANT
22912#define THUMB_VARIANT & arm_ext_v6t2
22913
21d799b5
NC
22914 TCE("smull", 0c00090, fb800000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
22915 CM("smull","s", 0d00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
22916 TCE("umull", 0800090, fba00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
22917 CM("umull","s", 0900090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
22918 TCE("smlal", 0e00090, fbc00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
22919 CM("smlal","s", 0f00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
22920 TCE("umlal", 0a00090, fbe00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
22921 CM("umlal","s", 0b00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
c19d1205 22922
c921be7d
NC
22923#undef ARM_VARIANT
22924#define ARM_VARIANT & arm_ext_v4 /* ARM Architecture 4. */
22925#undef THUMB_VARIANT
22926#define THUMB_VARIANT & arm_ext_v4t
22927
5be8be5d
DG
22928 tC3("ldrh", 01000b0, _ldrh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
22929 tC3("strh", 00000b0, _strh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
22930 tC3("ldrsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
22931 tC3("ldrsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
56c0a61f
RE
22932 tC3("ldsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
22933 tC3("ldsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
c19d1205 22934
c921be7d
NC
22935#undef ARM_VARIANT
22936#define ARM_VARIANT & arm_ext_v4t_5
22937
c19d1205
ZW
22938 /* ARM Architecture 4T. */
22939 /* Note: bx (and blx) are required on V5, even if the processor does
22940 not support Thumb. */
21d799b5 22941 TCE("bx", 12fff10, 4700, 1, (RR), bx, t_bx),
c19d1205 22942
c921be7d
NC
22943#undef ARM_VARIANT
22944#define ARM_VARIANT & arm_ext_v5 /* ARM Architecture 5T. */
22945#undef THUMB_VARIANT
22946#define THUMB_VARIANT & arm_ext_v5t
22947
c19d1205
ZW
22948 /* Note: blx has 2 variants; the .value coded here is for
22949 BLX(2). Only this variant has conditional execution. */
21d799b5
NC
22950 TCE("blx", 12fff30, 4780, 1, (RR_EXr), blx, t_blx),
22951 TUE("bkpt", 1200070, be00, 1, (oIffffb), bkpt, t_bkpt),
c19d1205 22952
c921be7d
NC
22953#undef THUMB_VARIANT
22954#define THUMB_VARIANT & arm_ext_v6t2
22955
21d799b5
NC
22956 TCE("clz", 16f0f10, fab0f080, 2, (RRnpc, RRnpc), rd_rm, t_clz),
22957 TUF("ldc2", c100000, fc100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
22958 TUF("ldc2l", c500000, fc500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
22959 TUF("stc2", c000000, fc000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
22960 TUF("stc2l", c400000, fc400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
22961 TUF("cdp2", e000000, fe000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
22962 TUF("mcr2", e000010, fe000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
22963 TUF("mrc2", e100010, fe100010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 22964
c921be7d 22965#undef ARM_VARIANT
74db7efb
NC
22966#define ARM_VARIANT & arm_ext_v5exp /* ARM Architecture 5TExP. */
22967#undef THUMB_VARIANT
22968#define THUMB_VARIANT & arm_ext_v5exp
c921be7d 22969
21d799b5
NC
22970 TCE("smlabb", 1000080, fb100000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
22971 TCE("smlatb", 10000a0, fb100020, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
22972 TCE("smlabt", 10000c0, fb100010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
22973 TCE("smlatt", 10000e0, fb100030, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 22974
21d799b5
NC
22975 TCE("smlawb", 1200080, fb300000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
22976 TCE("smlawt", 12000c0, fb300010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 22977
21d799b5
NC
22978 TCE("smlalbb", 1400080, fbc00080, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
22979 TCE("smlaltb", 14000a0, fbc000a0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
22980 TCE("smlalbt", 14000c0, fbc00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
22981 TCE("smlaltt", 14000e0, fbc000b0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
c19d1205 22982
21d799b5
NC
22983 TCE("smulbb", 1600080, fb10f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
22984 TCE("smultb", 16000a0, fb10f020, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
22985 TCE("smulbt", 16000c0, fb10f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
22986 TCE("smultt", 16000e0, fb10f030, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 22987
21d799b5
NC
22988 TCE("smulwb", 12000a0, fb30f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
22989 TCE("smulwt", 12000e0, fb30f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 22990
03ee1b7f
NC
22991 TCE("qadd", 1000050, fa80f080, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
22992 TCE("qdadd", 1400050, fa80f090, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
22993 TCE("qsub", 1200050, fa80f0a0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
22994 TCE("qdsub", 1600050, fa80f0b0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
c19d1205 22995
c921be7d 22996#undef ARM_VARIANT
74db7efb
NC
22997#define ARM_VARIANT & arm_ext_v5e /* ARM Architecture 5TE. */
22998#undef THUMB_VARIANT
22999#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 23000
21d799b5 23001 TUF("pld", 450f000, f810f000, 1, (ADDR), pld, t_pld),
5be8be5d
DG
23002 TC3("ldrd", 00000d0, e8500000, 3, (RRnpc_npcsp, oRRnpc_npcsp, ADDRGLDRS),
23003 ldrd, t_ldstd),
23004 TC3("strd", 00000f0, e8400000, 3, (RRnpc_npcsp, oRRnpc_npcsp,
23005 ADDRGLDRS), ldrd, t_ldstd),
c19d1205 23006
21d799b5
NC
23007 TCE("mcrr", c400000, ec400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
23008 TCE("mrrc", c500000, ec500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
c19d1205 23009
c921be7d
NC
23010#undef ARM_VARIANT
23011#define ARM_VARIANT & arm_ext_v5j /* ARM Architecture 5TEJ. */
23012
21d799b5 23013 TCE("bxj", 12fff20, f3c08f00, 1, (RR), bxj, t_bxj),
c19d1205 23014
c921be7d
NC
23015#undef ARM_VARIANT
23016#define ARM_VARIANT & arm_ext_v6 /* ARM V6. */
23017#undef THUMB_VARIANT
23018#define THUMB_VARIANT & arm_ext_v6
23019
21d799b5
NC
23020 TUF("cpsie", 1080000, b660, 2, (CPSF, oI31b), cpsi, t_cpsi),
23021 TUF("cpsid", 10c0000, b670, 2, (CPSF, oI31b), cpsi, t_cpsi),
23022 tCE("rev", 6bf0f30, _rev, 2, (RRnpc, RRnpc), rd_rm, t_rev),
23023 tCE("rev16", 6bf0fb0, _rev16, 2, (RRnpc, RRnpc), rd_rm, t_rev),
23024 tCE("revsh", 6ff0fb0, _revsh, 2, (RRnpc, RRnpc), rd_rm, t_rev),
23025 tCE("sxth", 6bf0070, _sxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
23026 tCE("uxth", 6ff0070, _uxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
23027 tCE("sxtb", 6af0070, _sxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
23028 tCE("uxtb", 6ef0070, _uxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
23029 TUF("setend", 1010000, b650, 1, (ENDI), setend, t_setend),
c19d1205 23030
c921be7d 23031#undef THUMB_VARIANT
ff8646ee 23032#define THUMB_VARIANT & arm_ext_v6t2_v8m
c921be7d 23033
5be8be5d
DG
23034 TCE("ldrex", 1900f9f, e8500f00, 2, (RRnpc_npcsp, ADDR), ldrex, t_ldrex),
23035 TCE("strex", 1800f90, e8400000, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
23036 strex, t_strex),
ff8646ee
TP
23037#undef THUMB_VARIANT
23038#define THUMB_VARIANT & arm_ext_v6t2
23039
21d799b5
NC
23040 TUF("mcrr2", c400000, fc400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
23041 TUF("mrrc2", c500000, fc500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
62b3e311 23042
21d799b5
NC
23043 TCE("ssat", 6a00010, f3000000, 4, (RRnpc, I32, RRnpc, oSHllar),ssat, t_ssat),
23044 TCE("usat", 6e00010, f3800000, 4, (RRnpc, I31, RRnpc, oSHllar),usat, t_usat),
62b3e311 23045
9e3c6df6 23046/* ARM V6 not included in V7M. */
c921be7d
NC
23047#undef THUMB_VARIANT
23048#define THUMB_VARIANT & arm_ext_v6_notm
9e3c6df6 23049 TUF("rfeia", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6 23050 TUF("rfe", 8900a00, e990c000, 1, (RRw), rfe, rfe),
9e3c6df6
PB
23051 UF(rfeib, 9900a00, 1, (RRw), rfe),
23052 UF(rfeda, 8100a00, 1, (RRw), rfe),
23053 TUF("rfedb", 9100a00, e810c000, 1, (RRw), rfe, rfe),
23054 TUF("rfefd", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6
RE
23055 UF(rfefa, 8100a00, 1, (RRw), rfe),
23056 TUF("rfeea", 9100a00, e810c000, 1, (RRw), rfe, rfe),
23057 UF(rfeed, 9900a00, 1, (RRw), rfe),
9e3c6df6 23058 TUF("srsia", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
d709e4e6
RE
23059 TUF("srs", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
23060 TUF("srsea", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
9e3c6df6 23061 UF(srsib, 9c00500, 2, (oRRw, I31w), srs),
d709e4e6 23062 UF(srsfa, 9c00500, 2, (oRRw, I31w), srs),
9e3c6df6 23063 UF(srsda, 8400500, 2, (oRRw, I31w), srs),
d709e4e6 23064 UF(srsed, 8400500, 2, (oRRw, I31w), srs),
9e3c6df6 23065 TUF("srsdb", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
d709e4e6 23066 TUF("srsfd", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
941c9cad 23067 TUF("cps", 1020000, f3af8100, 1, (I31b), imm0, t_cps),
c921be7d 23068
9e3c6df6
PB
23069/* ARM V6 not included in V7M (eg. integer SIMD). */
23070#undef THUMB_VARIANT
23071#define THUMB_VARIANT & arm_ext_v6_dsp
21d799b5
NC
23072 TCE("pkhbt", 6800010, eac00000, 4, (RRnpc, RRnpc, RRnpc, oSHll), pkhbt, t_pkhbt),
23073 TCE("pkhtb", 6800050, eac00020, 4, (RRnpc, RRnpc, RRnpc, oSHar), pkhtb, t_pkhtb),
23074 TCE("qadd16", 6200f10, fa90f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23075 TCE("qadd8", 6200f90, fa80f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23076 TCE("qasx", 6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23077 /* Old name for QASX. */
74db7efb 23078 TCE("qaddsubx",6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 23079 TCE("qsax", 6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23080 /* Old name for QSAX. */
74db7efb 23081 TCE("qsubaddx",6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
23082 TCE("qsub16", 6200f70, fad0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23083 TCE("qsub8", 6200ff0, fac0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23084 TCE("sadd16", 6100f10, fa90f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23085 TCE("sadd8", 6100f90, fa80f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23086 TCE("sasx", 6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23087 /* Old name for SASX. */
74db7efb 23088 TCE("saddsubx",6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
23089 TCE("shadd16", 6300f10, fa90f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23090 TCE("shadd8", 6300f90, fa80f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 23091 TCE("shasx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23092 /* Old name for SHASX. */
21d799b5 23093 TCE("shaddsubx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 23094 TCE("shsax", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23095 /* Old name for SHSAX. */
21d799b5
NC
23096 TCE("shsubaddx", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23097 TCE("shsub16", 6300f70, fad0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23098 TCE("shsub8", 6300ff0, fac0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23099 TCE("ssax", 6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23100 /* Old name for SSAX. */
74db7efb 23101 TCE("ssubaddx",6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
23102 TCE("ssub16", 6100f70, fad0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23103 TCE("ssub8", 6100ff0, fac0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23104 TCE("uadd16", 6500f10, fa90f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23105 TCE("uadd8", 6500f90, fa80f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23106 TCE("uasx", 6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23107 /* Old name for UASX. */
74db7efb 23108 TCE("uaddsubx",6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
23109 TCE("uhadd16", 6700f10, fa90f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23110 TCE("uhadd8", 6700f90, fa80f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 23111 TCE("uhasx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23112 /* Old name for UHASX. */
21d799b5
NC
23113 TCE("uhaddsubx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23114 TCE("uhsax", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23115 /* Old name for UHSAX. */
21d799b5
NC
23116 TCE("uhsubaddx", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23117 TCE("uhsub16", 6700f70, fad0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23118 TCE("uhsub8", 6700ff0, fac0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23119 TCE("uqadd16", 6600f10, fa90f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23120 TCE("uqadd8", 6600f90, fa80f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 23121 TCE("uqasx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23122 /* Old name for UQASX. */
21d799b5
NC
23123 TCE("uqaddsubx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23124 TCE("uqsax", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23125 /* Old name for UQSAX. */
21d799b5
NC
23126 TCE("uqsubaddx", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23127 TCE("uqsub16", 6600f70, fad0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23128 TCE("uqsub8", 6600ff0, fac0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23129 TCE("usub16", 6500f70, fad0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23130 TCE("usax", 6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23131 /* Old name for USAX. */
74db7efb 23132 TCE("usubaddx",6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 23133 TCE("usub8", 6500ff0, fac0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
23134 TCE("sxtah", 6b00070, fa00f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
23135 TCE("sxtab16", 6800070, fa20f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
23136 TCE("sxtab", 6a00070, fa40f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
23137 TCE("sxtb16", 68f0070, fa2ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
23138 TCE("uxtah", 6f00070, fa10f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
23139 TCE("uxtab16", 6c00070, fa30f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
23140 TCE("uxtab", 6e00070, fa50f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
23141 TCE("uxtb16", 6cf0070, fa3ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
23142 TCE("sel", 6800fb0, faa0f080, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23143 TCE("smlad", 7000010, fb200000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
23144 TCE("smladx", 7000030, fb200010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
23145 TCE("smlald", 7400010, fbc000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
23146 TCE("smlaldx", 7400030, fbc000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
23147 TCE("smlsd", 7000050, fb400000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
23148 TCE("smlsdx", 7000070, fb400010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
23149 TCE("smlsld", 7400050, fbd000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
23150 TCE("smlsldx", 7400070, fbd000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
23151 TCE("smmla", 7500010, fb500000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
23152 TCE("smmlar", 7500030, fb500010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
23153 TCE("smmls", 75000d0, fb600000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
23154 TCE("smmlsr", 75000f0, fb600010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
23155 TCE("smmul", 750f010, fb50f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
23156 TCE("smmulr", 750f030, fb50f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
23157 TCE("smuad", 700f010, fb20f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
23158 TCE("smuadx", 700f030, fb20f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
23159 TCE("smusd", 700f050, fb40f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
23160 TCE("smusdx", 700f070, fb40f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
21d799b5
NC
23161 TCE("ssat16", 6a00f30, f3200000, 3, (RRnpc, I16, RRnpc), ssat16, t_ssat16),
23162 TCE("umaal", 0400090, fbe00060, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal, t_mlal),
23163 TCE("usad8", 780f010, fb70f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
23164 TCE("usada8", 7800010, fb700000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
23165 TCE("usat16", 6e00f30, f3a00000, 3, (RRnpc, I15, RRnpc), usat16, t_usat16),
c19d1205 23166
c921be7d 23167#undef ARM_VARIANT
55e8aae7 23168#define ARM_VARIANT & arm_ext_v6k_v6t2
c921be7d 23169#undef THUMB_VARIANT
55e8aae7 23170#define THUMB_VARIANT & arm_ext_v6k_v6t2
c921be7d 23171
21d799b5
NC
23172 tCE("yield", 320f001, _yield, 0, (), noargs, t_hint),
23173 tCE("wfe", 320f002, _wfe, 0, (), noargs, t_hint),
23174 tCE("wfi", 320f003, _wfi, 0, (), noargs, t_hint),
23175 tCE("sev", 320f004, _sev, 0, (), noargs, t_hint),
c19d1205 23176
c921be7d
NC
23177#undef THUMB_VARIANT
23178#define THUMB_VARIANT & arm_ext_v6_notm
5be8be5d
DG
23179 TCE("ldrexd", 1b00f9f, e8d0007f, 3, (RRnpc_npcsp, oRRnpc_npcsp, RRnpcb),
23180 ldrexd, t_ldrexd),
23181 TCE("strexd", 1a00f90, e8c00070, 4, (RRnpc_npcsp, RRnpc_npcsp, oRRnpc_npcsp,
23182 RRnpcb), strexd, t_strexd),
ebdca51a 23183
c921be7d 23184#undef THUMB_VARIANT
ff8646ee 23185#define THUMB_VARIANT & arm_ext_v6t2_v8m
5be8be5d
DG
23186 TCE("ldrexb", 1d00f9f, e8d00f4f, 2, (RRnpc_npcsp,RRnpcb),
23187 rd_rn, rd_rn),
23188 TCE("ldrexh", 1f00f9f, e8d00f5f, 2, (RRnpc_npcsp, RRnpcb),
23189 rd_rn, rd_rn),
23190 TCE("strexb", 1c00f90, e8c00f40, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 23191 strex, t_strexbh),
5be8be5d 23192 TCE("strexh", 1e00f90, e8c00f50, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 23193 strex, t_strexbh),
21d799b5 23194 TUF("clrex", 57ff01f, f3bf8f2f, 0, (), noargs, noargs),
c19d1205 23195
c921be7d 23196#undef ARM_VARIANT
f4c65163 23197#define ARM_VARIANT & arm_ext_sec
74db7efb 23198#undef THUMB_VARIANT
f4c65163 23199#define THUMB_VARIANT & arm_ext_sec
c921be7d 23200
21d799b5 23201 TCE("smc", 1600070, f7f08000, 1, (EXPi), smc, t_smc),
c19d1205 23202
90ec0d68
MGD
23203#undef ARM_VARIANT
23204#define ARM_VARIANT & arm_ext_virt
23205#undef THUMB_VARIANT
23206#define THUMB_VARIANT & arm_ext_virt
23207
23208 TCE("hvc", 1400070, f7e08000, 1, (EXPi), hvc, t_hvc),
23209 TCE("eret", 160006e, f3de8f00, 0, (), noargs, noargs),
23210
ddfded2f
MW
23211#undef ARM_VARIANT
23212#define ARM_VARIANT & arm_ext_pan
23213#undef THUMB_VARIANT
23214#define THUMB_VARIANT & arm_ext_pan
23215
23216 TUF("setpan", 1100000, b610, 1, (I7), setpan, t_setpan),
23217
c921be7d 23218#undef ARM_VARIANT
74db7efb 23219#define ARM_VARIANT & arm_ext_v6t2
f4c65163
MGD
23220#undef THUMB_VARIANT
23221#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 23222
21d799b5
NC
23223 TCE("bfc", 7c0001f, f36f0000, 3, (RRnpc, I31, I32), bfc, t_bfc),
23224 TCE("bfi", 7c00010, f3600000, 4, (RRnpc, RRnpc_I0, I31, I32), bfi, t_bfi),
23225 TCE("sbfx", 7a00050, f3400000, 4, (RR, RR, I31, I32), bfx, t_bfx),
23226 TCE("ubfx", 7e00050, f3c00000, 4, (RR, RR, I31, I32), bfx, t_bfx),
c19d1205 23227
21d799b5 23228 TCE("mls", 0600090, fb000010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
21d799b5 23229 TCE("rbit", 6ff0f30, fa90f0a0, 2, (RR, RR), rd_rm, t_rbit),
c19d1205 23230
5be8be5d
DG
23231 TC3("ldrht", 03000b0, f8300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
23232 TC3("ldrsht", 03000f0, f9300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
23233 TC3("ldrsbt", 03000d0, f9100e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
23234 TC3("strht", 02000b0, f8200e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
c19d1205 23235
91d8b670
JG
23236#undef ARM_VARIANT
23237#define ARM_VARIANT & arm_ext_v3
23238#undef THUMB_VARIANT
23239#define THUMB_VARIANT & arm_ext_v6t2
23240
23241 TUE("csdb", 320f014, f3af8014, 0, (), noargs, t_csdb),
c597cc3d
SD
23242 TUF("ssbb", 57ff040, f3bf8f40, 0, (), noargs, t_csdb),
23243 TUF("pssbb", 57ff044, f3bf8f44, 0, (), noargs, t_csdb),
91d8b670
JG
23244
23245#undef ARM_VARIANT
23246#define ARM_VARIANT & arm_ext_v6t2
ff8646ee
TP
23247#undef THUMB_VARIANT
23248#define THUMB_VARIANT & arm_ext_v6t2_v8m
23249 TCE("movw", 3000000, f2400000, 2, (RRnpc, HALF), mov16, t_mov16),
23250 TCE("movt", 3400000, f2c00000, 2, (RRnpc, HALF), mov16, t_mov16),
23251
bf3eeda7 23252 /* Thumb-only instructions. */
74db7efb 23253#undef ARM_VARIANT
bf3eeda7
NS
23254#define ARM_VARIANT NULL
23255 TUE("cbnz", 0, b900, 2, (RR, EXP), 0, t_cbz),
23256 TUE("cbz", 0, b100, 2, (RR, EXP), 0, t_cbz),
c921be7d
NC
23257
23258 /* ARM does not really have an IT instruction, so always allow it.
23259 The opcode is copied from Thumb in order to allow warnings in
23260 -mimplicit-it=[never | arm] modes. */
23261#undef ARM_VARIANT
23262#define ARM_VARIANT & arm_ext_v1
ff8646ee
TP
23263#undef THUMB_VARIANT
23264#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 23265
21d799b5
NC
23266 TUE("it", bf08, bf08, 1, (COND), it, t_it),
23267 TUE("itt", bf0c, bf0c, 1, (COND), it, t_it),
23268 TUE("ite", bf04, bf04, 1, (COND), it, t_it),
23269 TUE("ittt", bf0e, bf0e, 1, (COND), it, t_it),
23270 TUE("itet", bf06, bf06, 1, (COND), it, t_it),
23271 TUE("itte", bf0a, bf0a, 1, (COND), it, t_it),
23272 TUE("itee", bf02, bf02, 1, (COND), it, t_it),
23273 TUE("itttt", bf0f, bf0f, 1, (COND), it, t_it),
23274 TUE("itett", bf07, bf07, 1, (COND), it, t_it),
23275 TUE("ittet", bf0b, bf0b, 1, (COND), it, t_it),
23276 TUE("iteet", bf03, bf03, 1, (COND), it, t_it),
23277 TUE("ittte", bf0d, bf0d, 1, (COND), it, t_it),
23278 TUE("itete", bf05, bf05, 1, (COND), it, t_it),
23279 TUE("ittee", bf09, bf09, 1, (COND), it, t_it),
23280 TUE("iteee", bf01, bf01, 1, (COND), it, t_it),
1c444d06 23281 /* ARM/Thumb-2 instructions with no Thumb-1 equivalent. */
21d799b5
NC
23282 TC3("rrx", 01a00060, ea4f0030, 2, (RR, RR), rd_rm, t_rrx),
23283 TC3("rrxs", 01b00060, ea5f0030, 2, (RR, RR), rd_rm, t_rrx),
c19d1205 23284
92e90b6e 23285 /* Thumb2 only instructions. */
c921be7d
NC
23286#undef ARM_VARIANT
23287#define ARM_VARIANT NULL
92e90b6e 23288
21d799b5
NC
23289 TCE("addw", 0, f2000000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
23290 TCE("subw", 0, f2a00000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
23291 TCE("orn", 0, ea600000, 3, (RR, oRR, SH), 0, t_orn),
23292 TCE("orns", 0, ea700000, 3, (RR, oRR, SH), 0, t_orn),
23293 TCE("tbb", 0, e8d0f000, 1, (TB), 0, t_tb),
23294 TCE("tbh", 0, e8d0f010, 1, (TB), 0, t_tb),
92e90b6e 23295
eea54501
MGD
23296 /* Hardware division instructions. */
23297#undef ARM_VARIANT
23298#define ARM_VARIANT & arm_ext_adiv
c921be7d
NC
23299#undef THUMB_VARIANT
23300#define THUMB_VARIANT & arm_ext_div
23301
eea54501
MGD
23302 TCE("sdiv", 710f010, fb90f0f0, 3, (RR, oRR, RR), div, t_div),
23303 TCE("udiv", 730f010, fbb0f0f0, 3, (RR, oRR, RR), div, t_div),
62b3e311 23304
7e806470 23305 /* ARM V6M/V7 instructions. */
c921be7d
NC
23306#undef ARM_VARIANT
23307#define ARM_VARIANT & arm_ext_barrier
23308#undef THUMB_VARIANT
23309#define THUMB_VARIANT & arm_ext_barrier
23310
ccb84d65
JB
23311 TUF("dmb", 57ff050, f3bf8f50, 1, (oBARRIER_I15), barrier, barrier),
23312 TUF("dsb", 57ff040, f3bf8f40, 1, (oBARRIER_I15), barrier, barrier),
23313 TUF("isb", 57ff060, f3bf8f60, 1, (oBARRIER_I15), barrier, barrier),
7e806470 23314
62b3e311 23315 /* ARM V7 instructions. */
c921be7d
NC
23316#undef ARM_VARIANT
23317#define ARM_VARIANT & arm_ext_v7
23318#undef THUMB_VARIANT
23319#define THUMB_VARIANT & arm_ext_v7
23320
21d799b5
NC
23321 TUF("pli", 450f000, f910f000, 1, (ADDR), pli, t_pld),
23322 TCE("dbg", 320f0f0, f3af80f0, 1, (I15), dbg, t_dbg),
62b3e311 23323
74db7efb 23324#undef ARM_VARIANT
60e5ef9f 23325#define ARM_VARIANT & arm_ext_mp
74db7efb 23326#undef THUMB_VARIANT
60e5ef9f
MGD
23327#define THUMB_VARIANT & arm_ext_mp
23328
23329 TUF("pldw", 410f000, f830f000, 1, (ADDR), pld, t_pld),
23330
53c4b28b
MGD
23331 /* AArchv8 instructions. */
23332#undef ARM_VARIANT
23333#define ARM_VARIANT & arm_ext_v8
4ed7ed8d
TP
23334
23335/* Instructions shared between armv8-a and armv8-m. */
53c4b28b 23336#undef THUMB_VARIANT
4ed7ed8d 23337#define THUMB_VARIANT & arm_ext_atomics
53c4b28b 23338
4ed7ed8d
TP
23339 TCE("lda", 1900c9f, e8d00faf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
23340 TCE("ldab", 1d00c9f, e8d00f8f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
23341 TCE("ldah", 1f00c9f, e8d00f9f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
23342 TCE("stl", 180fc90, e8c00faf, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
23343 TCE("stlb", 1c0fc90, e8c00f8f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
23344 TCE("stlh", 1e0fc90, e8c00f9f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
4b8c8c02 23345 TCE("ldaex", 1900e9f, e8d00fef, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
4b8c8c02
RE
23346 TCE("ldaexb", 1d00e9f, e8d00fcf, 2, (RRnpc,RRnpcb), rd_rn, rd_rn),
23347 TCE("ldaexh", 1f00e9f, e8d00fdf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
23348 TCE("stlex", 1800e90, e8c00fe0, 3, (RRnpc, RRnpc, RRnpcb),
23349 stlex, t_stlex),
4b8c8c02
RE
23350 TCE("stlexb", 1c00e90, e8c00fc0, 3, (RRnpc, RRnpc, RRnpcb),
23351 stlex, t_stlex),
23352 TCE("stlexh", 1e00e90, e8c00fd0, 3, (RRnpc, RRnpc, RRnpcb),
23353 stlex, t_stlex),
4ed7ed8d
TP
23354#undef THUMB_VARIANT
23355#define THUMB_VARIANT & arm_ext_v8
53c4b28b 23356
4ed7ed8d 23357 tCE("sevl", 320f005, _sevl, 0, (), noargs, t_hint),
4ed7ed8d
TP
23358 TCE("ldaexd", 1b00e9f, e8d000ff, 3, (RRnpc, oRRnpc, RRnpcb),
23359 ldrexd, t_ldrexd),
23360 TCE("stlexd", 1a00e90, e8c000f0, 4, (RRnpc, RRnpc, oRRnpc, RRnpcb),
23361 strexd, t_strexd),
f7dd2fb2
TC
23362
23363/* Defined in V8 but is in undefined encoding space for earlier
23364 architectures. However earlier architectures are required to treat
23365 this instuction as a semihosting trap as well. Hence while not explicitly
23366 defined as such, it is in fact correct to define the instruction for all
23367 architectures. */
23368#undef THUMB_VARIANT
23369#define THUMB_VARIANT & arm_ext_v1
23370#undef ARM_VARIANT
23371#define ARM_VARIANT & arm_ext_v1
23372 TUE("hlt", 1000070, ba80, 1, (oIffffb), bkpt, t_hlt),
23373
8884b720 23374 /* ARMv8 T32 only. */
74db7efb 23375#undef ARM_VARIANT
b79f7053
MGD
23376#define ARM_VARIANT NULL
23377 TUF("dcps1", 0, f78f8001, 0, (), noargs, noargs),
23378 TUF("dcps2", 0, f78f8002, 0, (), noargs, noargs),
23379 TUF("dcps3", 0, f78f8003, 0, (), noargs, noargs),
23380
33399f07
MGD
23381 /* FP for ARMv8. */
23382#undef ARM_VARIANT
a715796b 23383#define ARM_VARIANT & fpu_vfp_ext_armv8xd
33399f07 23384#undef THUMB_VARIANT
a715796b 23385#define THUMB_VARIANT & fpu_vfp_ext_armv8xd
33399f07
MGD
23386
23387 nUF(vseleq, _vseleq, 3, (RVSD, RVSD, RVSD), vsel),
23388 nUF(vselvs, _vselvs, 3, (RVSD, RVSD, RVSD), vsel),
23389 nUF(vselge, _vselge, 3, (RVSD, RVSD, RVSD), vsel),
23390 nUF(vselgt, _vselgt, 3, (RVSD, RVSD, RVSD), vsel),
30bdf752
MGD
23391 nCE(vrintr, _vrintr, 2, (RNSDQ, oRNSDQ), vrintr),
23392 nCE(vrintz, _vrintr, 2, (RNSDQ, oRNSDQ), vrintz),
23393 nCE(vrintx, _vrintr, 2, (RNSDQ, oRNSDQ), vrintx),
23394 nUF(vrinta, _vrinta, 2, (RNSDQ, oRNSDQ), vrinta),
23395 nUF(vrintn, _vrinta, 2, (RNSDQ, oRNSDQ), vrintn),
23396 nUF(vrintp, _vrinta, 2, (RNSDQ, oRNSDQ), vrintp),
23397 nUF(vrintm, _vrinta, 2, (RNSDQ, oRNSDQ), vrintm),
33399f07 23398
91ff7894
MGD
23399 /* Crypto v1 extensions. */
23400#undef ARM_VARIANT
23401#define ARM_VARIANT & fpu_crypto_ext_armv8
23402#undef THUMB_VARIANT
23403#define THUMB_VARIANT & fpu_crypto_ext_armv8
23404
23405 nUF(aese, _aes, 2, (RNQ, RNQ), aese),
23406 nUF(aesd, _aes, 2, (RNQ, RNQ), aesd),
23407 nUF(aesmc, _aes, 2, (RNQ, RNQ), aesmc),
23408 nUF(aesimc, _aes, 2, (RNQ, RNQ), aesimc),
48adcd8e
MGD
23409 nUF(sha1c, _sha3op, 3, (RNQ, RNQ, RNQ), sha1c),
23410 nUF(sha1p, _sha3op, 3, (RNQ, RNQ, RNQ), sha1p),
23411 nUF(sha1m, _sha3op, 3, (RNQ, RNQ, RNQ), sha1m),
23412 nUF(sha1su0, _sha3op, 3, (RNQ, RNQ, RNQ), sha1su0),
23413 nUF(sha256h, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h),
23414 nUF(sha256h2, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h2),
23415 nUF(sha256su1, _sha3op, 3, (RNQ, RNQ, RNQ), sha256su1),
3c9017d2
MGD
23416 nUF(sha1h, _sha1h, 2, (RNQ, RNQ), sha1h),
23417 nUF(sha1su1, _sha2op, 2, (RNQ, RNQ), sha1su1),
23418 nUF(sha256su0, _sha2op, 2, (RNQ, RNQ), sha256su0),
91ff7894 23419
dd5181d5 23420#undef ARM_VARIANT
74db7efb 23421#define ARM_VARIANT & crc_ext_armv8
dd5181d5
KT
23422#undef THUMB_VARIANT
23423#define THUMB_VARIANT & crc_ext_armv8
23424 TUEc("crc32b", 1000040, fac0f080, 3, (RR, oRR, RR), crc32b),
23425 TUEc("crc32h", 1200040, fac0f090, 3, (RR, oRR, RR), crc32h),
23426 TUEc("crc32w", 1400040, fac0f0a0, 3, (RR, oRR, RR), crc32w),
23427 TUEc("crc32cb",1000240, fad0f080, 3, (RR, oRR, RR), crc32cb),
23428 TUEc("crc32ch",1200240, fad0f090, 3, (RR, oRR, RR), crc32ch),
23429 TUEc("crc32cw",1400240, fad0f0a0, 3, (RR, oRR, RR), crc32cw),
23430
105bde57
MW
23431 /* ARMv8.2 RAS extension. */
23432#undef ARM_VARIANT
4d1464f2 23433#define ARM_VARIANT & arm_ext_ras
105bde57 23434#undef THUMB_VARIANT
4d1464f2 23435#define THUMB_VARIANT & arm_ext_ras
105bde57
MW
23436 TUE ("esb", 320f010, f3af8010, 0, (), noargs, noargs),
23437
49e8a725
SN
23438#undef ARM_VARIANT
23439#define ARM_VARIANT & arm_ext_v8_3
23440#undef THUMB_VARIANT
23441#define THUMB_VARIANT & arm_ext_v8_3
23442 NCE (vjcvt, eb90bc0, 2, (RVS, RVD), vjcvt),
23443
c604a79a
JW
23444#undef ARM_VARIANT
23445#define ARM_VARIANT & fpu_neon_ext_dotprod
23446#undef THUMB_VARIANT
23447#define THUMB_VARIANT & fpu_neon_ext_dotprod
23448 NUF (vsdot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_s),
23449 NUF (vudot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_u),
23450
c921be7d
NC
23451#undef ARM_VARIANT
23452#define ARM_VARIANT & fpu_fpa_ext_v1 /* Core FPA instruction set (V1). */
53c4b28b
MGD
23453#undef THUMB_VARIANT
23454#define THUMB_VARIANT NULL
c921be7d 23455
21d799b5
NC
23456 cCE("wfs", e200110, 1, (RR), rd),
23457 cCE("rfs", e300110, 1, (RR), rd),
23458 cCE("wfc", e400110, 1, (RR), rd),
23459 cCE("rfc", e500110, 1, (RR), rd),
23460
23461 cCL("ldfs", c100100, 2, (RF, ADDRGLDC), rd_cpaddr),
23462 cCL("ldfd", c108100, 2, (RF, ADDRGLDC), rd_cpaddr),
23463 cCL("ldfe", c500100, 2, (RF, ADDRGLDC), rd_cpaddr),
23464 cCL("ldfp", c508100, 2, (RF, ADDRGLDC), rd_cpaddr),
23465
23466 cCL("stfs", c000100, 2, (RF, ADDRGLDC), rd_cpaddr),
23467 cCL("stfd", c008100, 2, (RF, ADDRGLDC), rd_cpaddr),
23468 cCL("stfe", c400100, 2, (RF, ADDRGLDC), rd_cpaddr),
23469 cCL("stfp", c408100, 2, (RF, ADDRGLDC), rd_cpaddr),
23470
23471 cCL("mvfs", e008100, 2, (RF, RF_IF), rd_rm),
23472 cCL("mvfsp", e008120, 2, (RF, RF_IF), rd_rm),
23473 cCL("mvfsm", e008140, 2, (RF, RF_IF), rd_rm),
23474 cCL("mvfsz", e008160, 2, (RF, RF_IF), rd_rm),
23475 cCL("mvfd", e008180, 2, (RF, RF_IF), rd_rm),
23476 cCL("mvfdp", e0081a0, 2, (RF, RF_IF), rd_rm),
23477 cCL("mvfdm", e0081c0, 2, (RF, RF_IF), rd_rm),
23478 cCL("mvfdz", e0081e0, 2, (RF, RF_IF), rd_rm),
23479 cCL("mvfe", e088100, 2, (RF, RF_IF), rd_rm),
23480 cCL("mvfep", e088120, 2, (RF, RF_IF), rd_rm),
23481 cCL("mvfem", e088140, 2, (RF, RF_IF), rd_rm),
23482 cCL("mvfez", e088160, 2, (RF, RF_IF), rd_rm),
23483
23484 cCL("mnfs", e108100, 2, (RF, RF_IF), rd_rm),
23485 cCL("mnfsp", e108120, 2, (RF, RF_IF), rd_rm),
23486 cCL("mnfsm", e108140, 2, (RF, RF_IF), rd_rm),
23487 cCL("mnfsz", e108160, 2, (RF, RF_IF), rd_rm),
23488 cCL("mnfd", e108180, 2, (RF, RF_IF), rd_rm),
23489 cCL("mnfdp", e1081a0, 2, (RF, RF_IF), rd_rm),
23490 cCL("mnfdm", e1081c0, 2, (RF, RF_IF), rd_rm),
23491 cCL("mnfdz", e1081e0, 2, (RF, RF_IF), rd_rm),
23492 cCL("mnfe", e188100, 2, (RF, RF_IF), rd_rm),
23493 cCL("mnfep", e188120, 2, (RF, RF_IF), rd_rm),
23494 cCL("mnfem", e188140, 2, (RF, RF_IF), rd_rm),
23495 cCL("mnfez", e188160, 2, (RF, RF_IF), rd_rm),
23496
23497 cCL("abss", e208100, 2, (RF, RF_IF), rd_rm),
23498 cCL("abssp", e208120, 2, (RF, RF_IF), rd_rm),
23499 cCL("abssm", e208140, 2, (RF, RF_IF), rd_rm),
23500 cCL("abssz", e208160, 2, (RF, RF_IF), rd_rm),
23501 cCL("absd", e208180, 2, (RF, RF_IF), rd_rm),
23502 cCL("absdp", e2081a0, 2, (RF, RF_IF), rd_rm),
23503 cCL("absdm", e2081c0, 2, (RF, RF_IF), rd_rm),
23504 cCL("absdz", e2081e0, 2, (RF, RF_IF), rd_rm),
23505 cCL("abse", e288100, 2, (RF, RF_IF), rd_rm),
23506 cCL("absep", e288120, 2, (RF, RF_IF), rd_rm),
23507 cCL("absem", e288140, 2, (RF, RF_IF), rd_rm),
23508 cCL("absez", e288160, 2, (RF, RF_IF), rd_rm),
23509
23510 cCL("rnds", e308100, 2, (RF, RF_IF), rd_rm),
23511 cCL("rndsp", e308120, 2, (RF, RF_IF), rd_rm),
23512 cCL("rndsm", e308140, 2, (RF, RF_IF), rd_rm),
23513 cCL("rndsz", e308160, 2, (RF, RF_IF), rd_rm),
23514 cCL("rndd", e308180, 2, (RF, RF_IF), rd_rm),
23515 cCL("rnddp", e3081a0, 2, (RF, RF_IF), rd_rm),
23516 cCL("rnddm", e3081c0, 2, (RF, RF_IF), rd_rm),
23517 cCL("rnddz", e3081e0, 2, (RF, RF_IF), rd_rm),
23518 cCL("rnde", e388100, 2, (RF, RF_IF), rd_rm),
23519 cCL("rndep", e388120, 2, (RF, RF_IF), rd_rm),
23520 cCL("rndem", e388140, 2, (RF, RF_IF), rd_rm),
23521 cCL("rndez", e388160, 2, (RF, RF_IF), rd_rm),
23522
23523 cCL("sqts", e408100, 2, (RF, RF_IF), rd_rm),
23524 cCL("sqtsp", e408120, 2, (RF, RF_IF), rd_rm),
23525 cCL("sqtsm", e408140, 2, (RF, RF_IF), rd_rm),
23526 cCL("sqtsz", e408160, 2, (RF, RF_IF), rd_rm),
23527 cCL("sqtd", e408180, 2, (RF, RF_IF), rd_rm),
23528 cCL("sqtdp", e4081a0, 2, (RF, RF_IF), rd_rm),
23529 cCL("sqtdm", e4081c0, 2, (RF, RF_IF), rd_rm),
23530 cCL("sqtdz", e4081e0, 2, (RF, RF_IF), rd_rm),
23531 cCL("sqte", e488100, 2, (RF, RF_IF), rd_rm),
23532 cCL("sqtep", e488120, 2, (RF, RF_IF), rd_rm),
23533 cCL("sqtem", e488140, 2, (RF, RF_IF), rd_rm),
23534 cCL("sqtez", e488160, 2, (RF, RF_IF), rd_rm),
23535
23536 cCL("logs", e508100, 2, (RF, RF_IF), rd_rm),
23537 cCL("logsp", e508120, 2, (RF, RF_IF), rd_rm),
23538 cCL("logsm", e508140, 2, (RF, RF_IF), rd_rm),
23539 cCL("logsz", e508160, 2, (RF, RF_IF), rd_rm),
23540 cCL("logd", e508180, 2, (RF, RF_IF), rd_rm),
23541 cCL("logdp", e5081a0, 2, (RF, RF_IF), rd_rm),
23542 cCL("logdm", e5081c0, 2, (RF, RF_IF), rd_rm),
23543 cCL("logdz", e5081e0, 2, (RF, RF_IF), rd_rm),
23544 cCL("loge", e588100, 2, (RF, RF_IF), rd_rm),
23545 cCL("logep", e588120, 2, (RF, RF_IF), rd_rm),
23546 cCL("logem", e588140, 2, (RF, RF_IF), rd_rm),
23547 cCL("logez", e588160, 2, (RF, RF_IF), rd_rm),
23548
23549 cCL("lgns", e608100, 2, (RF, RF_IF), rd_rm),
23550 cCL("lgnsp", e608120, 2, (RF, RF_IF), rd_rm),
23551 cCL("lgnsm", e608140, 2, (RF, RF_IF), rd_rm),
23552 cCL("lgnsz", e608160, 2, (RF, RF_IF), rd_rm),
23553 cCL("lgnd", e608180, 2, (RF, RF_IF), rd_rm),
23554 cCL("lgndp", e6081a0, 2, (RF, RF_IF), rd_rm),
23555 cCL("lgndm", e6081c0, 2, (RF, RF_IF), rd_rm),
23556 cCL("lgndz", e6081e0, 2, (RF, RF_IF), rd_rm),
23557 cCL("lgne", e688100, 2, (RF, RF_IF), rd_rm),
23558 cCL("lgnep", e688120, 2, (RF, RF_IF), rd_rm),
23559 cCL("lgnem", e688140, 2, (RF, RF_IF), rd_rm),
23560 cCL("lgnez", e688160, 2, (RF, RF_IF), rd_rm),
23561
23562 cCL("exps", e708100, 2, (RF, RF_IF), rd_rm),
23563 cCL("expsp", e708120, 2, (RF, RF_IF), rd_rm),
23564 cCL("expsm", e708140, 2, (RF, RF_IF), rd_rm),
23565 cCL("expsz", e708160, 2, (RF, RF_IF), rd_rm),
23566 cCL("expd", e708180, 2, (RF, RF_IF), rd_rm),
23567 cCL("expdp", e7081a0, 2, (RF, RF_IF), rd_rm),
23568 cCL("expdm", e7081c0, 2, (RF, RF_IF), rd_rm),
23569 cCL("expdz", e7081e0, 2, (RF, RF_IF), rd_rm),
23570 cCL("expe", e788100, 2, (RF, RF_IF), rd_rm),
23571 cCL("expep", e788120, 2, (RF, RF_IF), rd_rm),
23572 cCL("expem", e788140, 2, (RF, RF_IF), rd_rm),
23573 cCL("expdz", e788160, 2, (RF, RF_IF), rd_rm),
23574
23575 cCL("sins", e808100, 2, (RF, RF_IF), rd_rm),
23576 cCL("sinsp", e808120, 2, (RF, RF_IF), rd_rm),
23577 cCL("sinsm", e808140, 2, (RF, RF_IF), rd_rm),
23578 cCL("sinsz", e808160, 2, (RF, RF_IF), rd_rm),
23579 cCL("sind", e808180, 2, (RF, RF_IF), rd_rm),
23580 cCL("sindp", e8081a0, 2, (RF, RF_IF), rd_rm),
23581 cCL("sindm", e8081c0, 2, (RF, RF_IF), rd_rm),
23582 cCL("sindz", e8081e0, 2, (RF, RF_IF), rd_rm),
23583 cCL("sine", e888100, 2, (RF, RF_IF), rd_rm),
23584 cCL("sinep", e888120, 2, (RF, RF_IF), rd_rm),
23585 cCL("sinem", e888140, 2, (RF, RF_IF), rd_rm),
23586 cCL("sinez", e888160, 2, (RF, RF_IF), rd_rm),
23587
23588 cCL("coss", e908100, 2, (RF, RF_IF), rd_rm),
23589 cCL("cossp", e908120, 2, (RF, RF_IF), rd_rm),
23590 cCL("cossm", e908140, 2, (RF, RF_IF), rd_rm),
23591 cCL("cossz", e908160, 2, (RF, RF_IF), rd_rm),
23592 cCL("cosd", e908180, 2, (RF, RF_IF), rd_rm),
23593 cCL("cosdp", e9081a0, 2, (RF, RF_IF), rd_rm),
23594 cCL("cosdm", e9081c0, 2, (RF, RF_IF), rd_rm),
23595 cCL("cosdz", e9081e0, 2, (RF, RF_IF), rd_rm),
23596 cCL("cose", e988100, 2, (RF, RF_IF), rd_rm),
23597 cCL("cosep", e988120, 2, (RF, RF_IF), rd_rm),
23598 cCL("cosem", e988140, 2, (RF, RF_IF), rd_rm),
23599 cCL("cosez", e988160, 2, (RF, RF_IF), rd_rm),
23600
23601 cCL("tans", ea08100, 2, (RF, RF_IF), rd_rm),
23602 cCL("tansp", ea08120, 2, (RF, RF_IF), rd_rm),
23603 cCL("tansm", ea08140, 2, (RF, RF_IF), rd_rm),
23604 cCL("tansz", ea08160, 2, (RF, RF_IF), rd_rm),
23605 cCL("tand", ea08180, 2, (RF, RF_IF), rd_rm),
23606 cCL("tandp", ea081a0, 2, (RF, RF_IF), rd_rm),
23607 cCL("tandm", ea081c0, 2, (RF, RF_IF), rd_rm),
23608 cCL("tandz", ea081e0, 2, (RF, RF_IF), rd_rm),
23609 cCL("tane", ea88100, 2, (RF, RF_IF), rd_rm),
23610 cCL("tanep", ea88120, 2, (RF, RF_IF), rd_rm),
23611 cCL("tanem", ea88140, 2, (RF, RF_IF), rd_rm),
23612 cCL("tanez", ea88160, 2, (RF, RF_IF), rd_rm),
23613
23614 cCL("asns", eb08100, 2, (RF, RF_IF), rd_rm),
23615 cCL("asnsp", eb08120, 2, (RF, RF_IF), rd_rm),
23616 cCL("asnsm", eb08140, 2, (RF, RF_IF), rd_rm),
23617 cCL("asnsz", eb08160, 2, (RF, RF_IF), rd_rm),
23618 cCL("asnd", eb08180, 2, (RF, RF_IF), rd_rm),
23619 cCL("asndp", eb081a0, 2, (RF, RF_IF), rd_rm),
23620 cCL("asndm", eb081c0, 2, (RF, RF_IF), rd_rm),
23621 cCL("asndz", eb081e0, 2, (RF, RF_IF), rd_rm),
23622 cCL("asne", eb88100, 2, (RF, RF_IF), rd_rm),
23623 cCL("asnep", eb88120, 2, (RF, RF_IF), rd_rm),
23624 cCL("asnem", eb88140, 2, (RF, RF_IF), rd_rm),
23625 cCL("asnez", eb88160, 2, (RF, RF_IF), rd_rm),
23626
23627 cCL("acss", ec08100, 2, (RF, RF_IF), rd_rm),
23628 cCL("acssp", ec08120, 2, (RF, RF_IF), rd_rm),
23629 cCL("acssm", ec08140, 2, (RF, RF_IF), rd_rm),
23630 cCL("acssz", ec08160, 2, (RF, RF_IF), rd_rm),
23631 cCL("acsd", ec08180, 2, (RF, RF_IF), rd_rm),
23632 cCL("acsdp", ec081a0, 2, (RF, RF_IF), rd_rm),
23633 cCL("acsdm", ec081c0, 2, (RF, RF_IF), rd_rm),
23634 cCL("acsdz", ec081e0, 2, (RF, RF_IF), rd_rm),
23635 cCL("acse", ec88100, 2, (RF, RF_IF), rd_rm),
23636 cCL("acsep", ec88120, 2, (RF, RF_IF), rd_rm),
23637 cCL("acsem", ec88140, 2, (RF, RF_IF), rd_rm),
23638 cCL("acsez", ec88160, 2, (RF, RF_IF), rd_rm),
23639
23640 cCL("atns", ed08100, 2, (RF, RF_IF), rd_rm),
23641 cCL("atnsp", ed08120, 2, (RF, RF_IF), rd_rm),
23642 cCL("atnsm", ed08140, 2, (RF, RF_IF), rd_rm),
23643 cCL("atnsz", ed08160, 2, (RF, RF_IF), rd_rm),
23644 cCL("atnd", ed08180, 2, (RF, RF_IF), rd_rm),
23645 cCL("atndp", ed081a0, 2, (RF, RF_IF), rd_rm),
23646 cCL("atndm", ed081c0, 2, (RF, RF_IF), rd_rm),
23647 cCL("atndz", ed081e0, 2, (RF, RF_IF), rd_rm),
23648 cCL("atne", ed88100, 2, (RF, RF_IF), rd_rm),
23649 cCL("atnep", ed88120, 2, (RF, RF_IF), rd_rm),
23650 cCL("atnem", ed88140, 2, (RF, RF_IF), rd_rm),
23651 cCL("atnez", ed88160, 2, (RF, RF_IF), rd_rm),
23652
23653 cCL("urds", ee08100, 2, (RF, RF_IF), rd_rm),
23654 cCL("urdsp", ee08120, 2, (RF, RF_IF), rd_rm),
23655 cCL("urdsm", ee08140, 2, (RF, RF_IF), rd_rm),
23656 cCL("urdsz", ee08160, 2, (RF, RF_IF), rd_rm),
23657 cCL("urdd", ee08180, 2, (RF, RF_IF), rd_rm),
23658 cCL("urddp", ee081a0, 2, (RF, RF_IF), rd_rm),
23659 cCL("urddm", ee081c0, 2, (RF, RF_IF), rd_rm),
23660 cCL("urddz", ee081e0, 2, (RF, RF_IF), rd_rm),
23661 cCL("urde", ee88100, 2, (RF, RF_IF), rd_rm),
23662 cCL("urdep", ee88120, 2, (RF, RF_IF), rd_rm),
23663 cCL("urdem", ee88140, 2, (RF, RF_IF), rd_rm),
23664 cCL("urdez", ee88160, 2, (RF, RF_IF), rd_rm),
23665
23666 cCL("nrms", ef08100, 2, (RF, RF_IF), rd_rm),
23667 cCL("nrmsp", ef08120, 2, (RF, RF_IF), rd_rm),
23668 cCL("nrmsm", ef08140, 2, (RF, RF_IF), rd_rm),
23669 cCL("nrmsz", ef08160, 2, (RF, RF_IF), rd_rm),
23670 cCL("nrmd", ef08180, 2, (RF, RF_IF), rd_rm),
23671 cCL("nrmdp", ef081a0, 2, (RF, RF_IF), rd_rm),
23672 cCL("nrmdm", ef081c0, 2, (RF, RF_IF), rd_rm),
23673 cCL("nrmdz", ef081e0, 2, (RF, RF_IF), rd_rm),
23674 cCL("nrme", ef88100, 2, (RF, RF_IF), rd_rm),
23675 cCL("nrmep", ef88120, 2, (RF, RF_IF), rd_rm),
23676 cCL("nrmem", ef88140, 2, (RF, RF_IF), rd_rm),
23677 cCL("nrmez", ef88160, 2, (RF, RF_IF), rd_rm),
23678
23679 cCL("adfs", e000100, 3, (RF, RF, RF_IF), rd_rn_rm),
23680 cCL("adfsp", e000120, 3, (RF, RF, RF_IF), rd_rn_rm),
23681 cCL("adfsm", e000140, 3, (RF, RF, RF_IF), rd_rn_rm),
23682 cCL("adfsz", e000160, 3, (RF, RF, RF_IF), rd_rn_rm),
23683 cCL("adfd", e000180, 3, (RF, RF, RF_IF), rd_rn_rm),
23684 cCL("adfdp", e0001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23685 cCL("adfdm", e0001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23686 cCL("adfdz", e0001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23687 cCL("adfe", e080100, 3, (RF, RF, RF_IF), rd_rn_rm),
23688 cCL("adfep", e080120, 3, (RF, RF, RF_IF), rd_rn_rm),
23689 cCL("adfem", e080140, 3, (RF, RF, RF_IF), rd_rn_rm),
23690 cCL("adfez", e080160, 3, (RF, RF, RF_IF), rd_rn_rm),
23691
23692 cCL("sufs", e200100, 3, (RF, RF, RF_IF), rd_rn_rm),
23693 cCL("sufsp", e200120, 3, (RF, RF, RF_IF), rd_rn_rm),
23694 cCL("sufsm", e200140, 3, (RF, RF, RF_IF), rd_rn_rm),
23695 cCL("sufsz", e200160, 3, (RF, RF, RF_IF), rd_rn_rm),
23696 cCL("sufd", e200180, 3, (RF, RF, RF_IF), rd_rn_rm),
23697 cCL("sufdp", e2001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23698 cCL("sufdm", e2001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23699 cCL("sufdz", e2001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23700 cCL("sufe", e280100, 3, (RF, RF, RF_IF), rd_rn_rm),
23701 cCL("sufep", e280120, 3, (RF, RF, RF_IF), rd_rn_rm),
23702 cCL("sufem", e280140, 3, (RF, RF, RF_IF), rd_rn_rm),
23703 cCL("sufez", e280160, 3, (RF, RF, RF_IF), rd_rn_rm),
23704
23705 cCL("rsfs", e300100, 3, (RF, RF, RF_IF), rd_rn_rm),
23706 cCL("rsfsp", e300120, 3, (RF, RF, RF_IF), rd_rn_rm),
23707 cCL("rsfsm", e300140, 3, (RF, RF, RF_IF), rd_rn_rm),
23708 cCL("rsfsz", e300160, 3, (RF, RF, RF_IF), rd_rn_rm),
23709 cCL("rsfd", e300180, 3, (RF, RF, RF_IF), rd_rn_rm),
23710 cCL("rsfdp", e3001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23711 cCL("rsfdm", e3001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23712 cCL("rsfdz", e3001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23713 cCL("rsfe", e380100, 3, (RF, RF, RF_IF), rd_rn_rm),
23714 cCL("rsfep", e380120, 3, (RF, RF, RF_IF), rd_rn_rm),
23715 cCL("rsfem", e380140, 3, (RF, RF, RF_IF), rd_rn_rm),
23716 cCL("rsfez", e380160, 3, (RF, RF, RF_IF), rd_rn_rm),
23717
23718 cCL("mufs", e100100, 3, (RF, RF, RF_IF), rd_rn_rm),
23719 cCL("mufsp", e100120, 3, (RF, RF, RF_IF), rd_rn_rm),
23720 cCL("mufsm", e100140, 3, (RF, RF, RF_IF), rd_rn_rm),
23721 cCL("mufsz", e100160, 3, (RF, RF, RF_IF), rd_rn_rm),
23722 cCL("mufd", e100180, 3, (RF, RF, RF_IF), rd_rn_rm),
23723 cCL("mufdp", e1001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23724 cCL("mufdm", e1001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23725 cCL("mufdz", e1001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23726 cCL("mufe", e180100, 3, (RF, RF, RF_IF), rd_rn_rm),
23727 cCL("mufep", e180120, 3, (RF, RF, RF_IF), rd_rn_rm),
23728 cCL("mufem", e180140, 3, (RF, RF, RF_IF), rd_rn_rm),
23729 cCL("mufez", e180160, 3, (RF, RF, RF_IF), rd_rn_rm),
23730
23731 cCL("dvfs", e400100, 3, (RF, RF, RF_IF), rd_rn_rm),
23732 cCL("dvfsp", e400120, 3, (RF, RF, RF_IF), rd_rn_rm),
23733 cCL("dvfsm", e400140, 3, (RF, RF, RF_IF), rd_rn_rm),
23734 cCL("dvfsz", e400160, 3, (RF, RF, RF_IF), rd_rn_rm),
23735 cCL("dvfd", e400180, 3, (RF, RF, RF_IF), rd_rn_rm),
23736 cCL("dvfdp", e4001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23737 cCL("dvfdm", e4001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23738 cCL("dvfdz", e4001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23739 cCL("dvfe", e480100, 3, (RF, RF, RF_IF), rd_rn_rm),
23740 cCL("dvfep", e480120, 3, (RF, RF, RF_IF), rd_rn_rm),
23741 cCL("dvfem", e480140, 3, (RF, RF, RF_IF), rd_rn_rm),
23742 cCL("dvfez", e480160, 3, (RF, RF, RF_IF), rd_rn_rm),
23743
23744 cCL("rdfs", e500100, 3, (RF, RF, RF_IF), rd_rn_rm),
23745 cCL("rdfsp", e500120, 3, (RF, RF, RF_IF), rd_rn_rm),
23746 cCL("rdfsm", e500140, 3, (RF, RF, RF_IF), rd_rn_rm),
23747 cCL("rdfsz", e500160, 3, (RF, RF, RF_IF), rd_rn_rm),
23748 cCL("rdfd", e500180, 3, (RF, RF, RF_IF), rd_rn_rm),
23749 cCL("rdfdp", e5001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23750 cCL("rdfdm", e5001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23751 cCL("rdfdz", e5001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23752 cCL("rdfe", e580100, 3, (RF, RF, RF_IF), rd_rn_rm),
23753 cCL("rdfep", e580120, 3, (RF, RF, RF_IF), rd_rn_rm),
23754 cCL("rdfem", e580140, 3, (RF, RF, RF_IF), rd_rn_rm),
23755 cCL("rdfez", e580160, 3, (RF, RF, RF_IF), rd_rn_rm),
23756
23757 cCL("pows", e600100, 3, (RF, RF, RF_IF), rd_rn_rm),
23758 cCL("powsp", e600120, 3, (RF, RF, RF_IF), rd_rn_rm),
23759 cCL("powsm", e600140, 3, (RF, RF, RF_IF), rd_rn_rm),
23760 cCL("powsz", e600160, 3, (RF, RF, RF_IF), rd_rn_rm),
23761 cCL("powd", e600180, 3, (RF, RF, RF_IF), rd_rn_rm),
23762 cCL("powdp", e6001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23763 cCL("powdm", e6001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23764 cCL("powdz", e6001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23765 cCL("powe", e680100, 3, (RF, RF, RF_IF), rd_rn_rm),
23766 cCL("powep", e680120, 3, (RF, RF, RF_IF), rd_rn_rm),
23767 cCL("powem", e680140, 3, (RF, RF, RF_IF), rd_rn_rm),
23768 cCL("powez", e680160, 3, (RF, RF, RF_IF), rd_rn_rm),
23769
23770 cCL("rpws", e700100, 3, (RF, RF, RF_IF), rd_rn_rm),
23771 cCL("rpwsp", e700120, 3, (RF, RF, RF_IF), rd_rn_rm),
23772 cCL("rpwsm", e700140, 3, (RF, RF, RF_IF), rd_rn_rm),
23773 cCL("rpwsz", e700160, 3, (RF, RF, RF_IF), rd_rn_rm),
23774 cCL("rpwd", e700180, 3, (RF, RF, RF_IF), rd_rn_rm),
23775 cCL("rpwdp", e7001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23776 cCL("rpwdm", e7001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23777 cCL("rpwdz", e7001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23778 cCL("rpwe", e780100, 3, (RF, RF, RF_IF), rd_rn_rm),
23779 cCL("rpwep", e780120, 3, (RF, RF, RF_IF), rd_rn_rm),
23780 cCL("rpwem", e780140, 3, (RF, RF, RF_IF), rd_rn_rm),
23781 cCL("rpwez", e780160, 3, (RF, RF, RF_IF), rd_rn_rm),
23782
23783 cCL("rmfs", e800100, 3, (RF, RF, RF_IF), rd_rn_rm),
23784 cCL("rmfsp", e800120, 3, (RF, RF, RF_IF), rd_rn_rm),
23785 cCL("rmfsm", e800140, 3, (RF, RF, RF_IF), rd_rn_rm),
23786 cCL("rmfsz", e800160, 3, (RF, RF, RF_IF), rd_rn_rm),
23787 cCL("rmfd", e800180, 3, (RF, RF, RF_IF), rd_rn_rm),
23788 cCL("rmfdp", e8001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23789 cCL("rmfdm", e8001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23790 cCL("rmfdz", e8001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23791 cCL("rmfe", e880100, 3, (RF, RF, RF_IF), rd_rn_rm),
23792 cCL("rmfep", e880120, 3, (RF, RF, RF_IF), rd_rn_rm),
23793 cCL("rmfem", e880140, 3, (RF, RF, RF_IF), rd_rn_rm),
23794 cCL("rmfez", e880160, 3, (RF, RF, RF_IF), rd_rn_rm),
23795
23796 cCL("fmls", e900100, 3, (RF, RF, RF_IF), rd_rn_rm),
23797 cCL("fmlsp", e900120, 3, (RF, RF, RF_IF), rd_rn_rm),
23798 cCL("fmlsm", e900140, 3, (RF, RF, RF_IF), rd_rn_rm),
23799 cCL("fmlsz", e900160, 3, (RF, RF, RF_IF), rd_rn_rm),
23800 cCL("fmld", e900180, 3, (RF, RF, RF_IF), rd_rn_rm),
23801 cCL("fmldp", e9001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23802 cCL("fmldm", e9001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23803 cCL("fmldz", e9001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23804 cCL("fmle", e980100, 3, (RF, RF, RF_IF), rd_rn_rm),
23805 cCL("fmlep", e980120, 3, (RF, RF, RF_IF), rd_rn_rm),
23806 cCL("fmlem", e980140, 3, (RF, RF, RF_IF), rd_rn_rm),
23807 cCL("fmlez", e980160, 3, (RF, RF, RF_IF), rd_rn_rm),
23808
23809 cCL("fdvs", ea00100, 3, (RF, RF, RF_IF), rd_rn_rm),
23810 cCL("fdvsp", ea00120, 3, (RF, RF, RF_IF), rd_rn_rm),
23811 cCL("fdvsm", ea00140, 3, (RF, RF, RF_IF), rd_rn_rm),
23812 cCL("fdvsz", ea00160, 3, (RF, RF, RF_IF), rd_rn_rm),
23813 cCL("fdvd", ea00180, 3, (RF, RF, RF_IF), rd_rn_rm),
23814 cCL("fdvdp", ea001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23815 cCL("fdvdm", ea001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23816 cCL("fdvdz", ea001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23817 cCL("fdve", ea80100, 3, (RF, RF, RF_IF), rd_rn_rm),
23818 cCL("fdvep", ea80120, 3, (RF, RF, RF_IF), rd_rn_rm),
23819 cCL("fdvem", ea80140, 3, (RF, RF, RF_IF), rd_rn_rm),
23820 cCL("fdvez", ea80160, 3, (RF, RF, RF_IF), rd_rn_rm),
23821
23822 cCL("frds", eb00100, 3, (RF, RF, RF_IF), rd_rn_rm),
23823 cCL("frdsp", eb00120, 3, (RF, RF, RF_IF), rd_rn_rm),
23824 cCL("frdsm", eb00140, 3, (RF, RF, RF_IF), rd_rn_rm),
23825 cCL("frdsz", eb00160, 3, (RF, RF, RF_IF), rd_rn_rm),
23826 cCL("frdd", eb00180, 3, (RF, RF, RF_IF), rd_rn_rm),
23827 cCL("frddp", eb001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23828 cCL("frddm", eb001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23829 cCL("frddz", eb001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23830 cCL("frde", eb80100, 3, (RF, RF, RF_IF), rd_rn_rm),
23831 cCL("frdep", eb80120, 3, (RF, RF, RF_IF), rd_rn_rm),
23832 cCL("frdem", eb80140, 3, (RF, RF, RF_IF), rd_rn_rm),
23833 cCL("frdez", eb80160, 3, (RF, RF, RF_IF), rd_rn_rm),
23834
23835 cCL("pols", ec00100, 3, (RF, RF, RF_IF), rd_rn_rm),
23836 cCL("polsp", ec00120, 3, (RF, RF, RF_IF), rd_rn_rm),
23837 cCL("polsm", ec00140, 3, (RF, RF, RF_IF), rd_rn_rm),
23838 cCL("polsz", ec00160, 3, (RF, RF, RF_IF), rd_rn_rm),
23839 cCL("pold", ec00180, 3, (RF, RF, RF_IF), rd_rn_rm),
23840 cCL("poldp", ec001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23841 cCL("poldm", ec001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23842 cCL("poldz", ec001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23843 cCL("pole", ec80100, 3, (RF, RF, RF_IF), rd_rn_rm),
23844 cCL("polep", ec80120, 3, (RF, RF, RF_IF), rd_rn_rm),
23845 cCL("polem", ec80140, 3, (RF, RF, RF_IF), rd_rn_rm),
23846 cCL("polez", ec80160, 3, (RF, RF, RF_IF), rd_rn_rm),
23847
23848 cCE("cmf", e90f110, 2, (RF, RF_IF), fpa_cmp),
23849 C3E("cmfe", ed0f110, 2, (RF, RF_IF), fpa_cmp),
23850 cCE("cnf", eb0f110, 2, (RF, RF_IF), fpa_cmp),
23851 C3E("cnfe", ef0f110, 2, (RF, RF_IF), fpa_cmp),
23852
23853 cCL("flts", e000110, 2, (RF, RR), rn_rd),
23854 cCL("fltsp", e000130, 2, (RF, RR), rn_rd),
23855 cCL("fltsm", e000150, 2, (RF, RR), rn_rd),
23856 cCL("fltsz", e000170, 2, (RF, RR), rn_rd),
23857 cCL("fltd", e000190, 2, (RF, RR), rn_rd),
23858 cCL("fltdp", e0001b0, 2, (RF, RR), rn_rd),
23859 cCL("fltdm", e0001d0, 2, (RF, RR), rn_rd),
23860 cCL("fltdz", e0001f0, 2, (RF, RR), rn_rd),
23861 cCL("flte", e080110, 2, (RF, RR), rn_rd),
23862 cCL("fltep", e080130, 2, (RF, RR), rn_rd),
23863 cCL("fltem", e080150, 2, (RF, RR), rn_rd),
23864 cCL("fltez", e080170, 2, (RF, RR), rn_rd),
b99bd4ef 23865
c19d1205
ZW
23866 /* The implementation of the FIX instruction is broken on some
23867 assemblers, in that it accepts a precision specifier as well as a
23868 rounding specifier, despite the fact that this is meaningless.
23869 To be more compatible, we accept it as well, though of course it
23870 does not set any bits. */
21d799b5
NC
23871 cCE("fix", e100110, 2, (RR, RF), rd_rm),
23872 cCL("fixp", e100130, 2, (RR, RF), rd_rm),
23873 cCL("fixm", e100150, 2, (RR, RF), rd_rm),
23874 cCL("fixz", e100170, 2, (RR, RF), rd_rm),
23875 cCL("fixsp", e100130, 2, (RR, RF), rd_rm),
23876 cCL("fixsm", e100150, 2, (RR, RF), rd_rm),
23877 cCL("fixsz", e100170, 2, (RR, RF), rd_rm),
23878 cCL("fixdp", e100130, 2, (RR, RF), rd_rm),
23879 cCL("fixdm", e100150, 2, (RR, RF), rd_rm),
23880 cCL("fixdz", e100170, 2, (RR, RF), rd_rm),
23881 cCL("fixep", e100130, 2, (RR, RF), rd_rm),
23882 cCL("fixem", e100150, 2, (RR, RF), rd_rm),
23883 cCL("fixez", e100170, 2, (RR, RF), rd_rm),
bfae80f2 23884
c19d1205 23885 /* Instructions that were new with the real FPA, call them V2. */
c921be7d
NC
23886#undef ARM_VARIANT
23887#define ARM_VARIANT & fpu_fpa_ext_v2
23888
21d799b5
NC
23889 cCE("lfm", c100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
23890 cCL("lfmfd", c900200, 3, (RF, I4b, ADDR), fpa_ldmstm),
23891 cCL("lfmea", d100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
23892 cCE("sfm", c000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
23893 cCL("sfmfd", d000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
23894 cCL("sfmea", c800200, 3, (RF, I4b, ADDR), fpa_ldmstm),
c19d1205 23895
c921be7d
NC
23896#undef ARM_VARIANT
23897#define ARM_VARIANT & fpu_vfp_ext_v1xd /* VFP V1xD (single precision). */
23898
c19d1205 23899 /* Moves and type conversions. */
21d799b5 23900 cCE("fmstat", ef1fa10, 0, (), noargs),
7465e07a
NC
23901 cCE("vmrs", ef00a10, 2, (APSR_RR, RVC), vmrs),
23902 cCE("vmsr", ee00a10, 2, (RVC, RR), vmsr),
21d799b5
NC
23903 cCE("fsitos", eb80ac0, 2, (RVS, RVS), vfp_sp_monadic),
23904 cCE("fuitos", eb80a40, 2, (RVS, RVS), vfp_sp_monadic),
23905 cCE("ftosis", ebd0a40, 2, (RVS, RVS), vfp_sp_monadic),
23906 cCE("ftosizs", ebd0ac0, 2, (RVS, RVS), vfp_sp_monadic),
23907 cCE("ftouis", ebc0a40, 2, (RVS, RVS), vfp_sp_monadic),
23908 cCE("ftouizs", ebc0ac0, 2, (RVS, RVS), vfp_sp_monadic),
23909 cCE("fmrx", ef00a10, 2, (RR, RVC), rd_rn),
23910 cCE("fmxr", ee00a10, 2, (RVC, RR), rn_rd),
c19d1205
ZW
23911
23912 /* Memory operations. */
21d799b5
NC
23913 cCE("flds", d100a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
23914 cCE("fsts", d000a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
55881a11
MGD
23915 cCE("fldmias", c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
23916 cCE("fldmfds", c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
23917 cCE("fldmdbs", d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
23918 cCE("fldmeas", d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
23919 cCE("fldmiax", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
23920 cCE("fldmfdx", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
23921 cCE("fldmdbx", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
23922 cCE("fldmeax", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
23923 cCE("fstmias", c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
23924 cCE("fstmeas", c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
23925 cCE("fstmdbs", d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
23926 cCE("fstmfds", d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
23927 cCE("fstmiax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
23928 cCE("fstmeax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
23929 cCE("fstmdbx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
23930 cCE("fstmfdx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
bfae80f2 23931
c19d1205 23932 /* Monadic operations. */
21d799b5
NC
23933 cCE("fabss", eb00ac0, 2, (RVS, RVS), vfp_sp_monadic),
23934 cCE("fnegs", eb10a40, 2, (RVS, RVS), vfp_sp_monadic),
23935 cCE("fsqrts", eb10ac0, 2, (RVS, RVS), vfp_sp_monadic),
c19d1205
ZW
23936
23937 /* Dyadic operations. */
21d799b5
NC
23938 cCE("fadds", e300a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
23939 cCE("fsubs", e300a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
23940 cCE("fmuls", e200a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
23941 cCE("fdivs", e800a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
23942 cCE("fmacs", e000a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
23943 cCE("fmscs", e100a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
23944 cCE("fnmuls", e200a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
23945 cCE("fnmacs", e000a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
23946 cCE("fnmscs", e100a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
b99bd4ef 23947
c19d1205 23948 /* Comparisons. */
21d799b5
NC
23949 cCE("fcmps", eb40a40, 2, (RVS, RVS), vfp_sp_monadic),
23950 cCE("fcmpzs", eb50a40, 1, (RVS), vfp_sp_compare_z),
23951 cCE("fcmpes", eb40ac0, 2, (RVS, RVS), vfp_sp_monadic),
23952 cCE("fcmpezs", eb50ac0, 1, (RVS), vfp_sp_compare_z),
b99bd4ef 23953
62f3b8c8
PB
23954 /* Double precision load/store are still present on single precision
23955 implementations. */
23956 cCE("fldd", d100b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
23957 cCE("fstd", d000b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
55881a11
MGD
23958 cCE("fldmiad", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
23959 cCE("fldmfdd", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
23960 cCE("fldmdbd", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
23961 cCE("fldmead", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
23962 cCE("fstmiad", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
23963 cCE("fstmead", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
23964 cCE("fstmdbd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
23965 cCE("fstmfdd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
62f3b8c8 23966
c921be7d
NC
23967#undef ARM_VARIANT
23968#define ARM_VARIANT & fpu_vfp_ext_v1 /* VFP V1 (Double precision). */
23969
c19d1205 23970 /* Moves and type conversions. */
21d799b5
NC
23971 cCE("fcvtds", eb70ac0, 2, (RVD, RVS), vfp_dp_sp_cvt),
23972 cCE("fcvtsd", eb70bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
23973 cCE("fmdhr", e200b10, 2, (RVD, RR), vfp_dp_rn_rd),
23974 cCE("fmdlr", e000b10, 2, (RVD, RR), vfp_dp_rn_rd),
23975 cCE("fmrdh", e300b10, 2, (RR, RVD), vfp_dp_rd_rn),
23976 cCE("fmrdl", e100b10, 2, (RR, RVD), vfp_dp_rd_rn),
23977 cCE("fsitod", eb80bc0, 2, (RVD, RVS), vfp_dp_sp_cvt),
23978 cCE("fuitod", eb80b40, 2, (RVD, RVS), vfp_dp_sp_cvt),
23979 cCE("ftosid", ebd0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
23980 cCE("ftosizd", ebd0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
23981 cCE("ftouid", ebc0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
23982 cCE("ftouizd", ebc0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
c19d1205 23983
c19d1205 23984 /* Monadic operations. */
21d799b5
NC
23985 cCE("fabsd", eb00bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
23986 cCE("fnegd", eb10b40, 2, (RVD, RVD), vfp_dp_rd_rm),
23987 cCE("fsqrtd", eb10bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
c19d1205
ZW
23988
23989 /* Dyadic operations. */
21d799b5
NC
23990 cCE("faddd", e300b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
23991 cCE("fsubd", e300b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
23992 cCE("fmuld", e200b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
23993 cCE("fdivd", e800b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
23994 cCE("fmacd", e000b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
23995 cCE("fmscd", e100b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
23996 cCE("fnmuld", e200b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
23997 cCE("fnmacd", e000b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
23998 cCE("fnmscd", e100b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
b99bd4ef 23999
c19d1205 24000 /* Comparisons. */
21d799b5
NC
24001 cCE("fcmpd", eb40b40, 2, (RVD, RVD), vfp_dp_rd_rm),
24002 cCE("fcmpzd", eb50b40, 1, (RVD), vfp_dp_rd),
24003 cCE("fcmped", eb40bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
24004 cCE("fcmpezd", eb50bc0, 1, (RVD), vfp_dp_rd),
c19d1205 24005
037e8744
JB
24006/* Instructions which may belong to either the Neon or VFP instruction sets.
24007 Individual encoder functions perform additional architecture checks. */
c921be7d
NC
24008#undef ARM_VARIANT
24009#define ARM_VARIANT & fpu_vfp_ext_v1xd
24010#undef THUMB_VARIANT
24011#define THUMB_VARIANT & fpu_vfp_ext_v1xd
24012
037e8744
JB
24013 /* These mnemonics are unique to VFP. */
24014 NCE(vsqrt, 0, 2, (RVSD, RVSD), vfp_nsyn_sqrt),
24015 NCE(vdiv, 0, 3, (RVSD, RVSD, RVSD), vfp_nsyn_div),
21d799b5
NC
24016 nCE(vnmul, _vnmul, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
24017 nCE(vnmla, _vnmla, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
24018 nCE(vnmls, _vnmls, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
037e8744
JB
24019 NCE(vpush, 0, 1, (VRSDLST), vfp_nsyn_push),
24020 NCE(vpop, 0, 1, (VRSDLST), vfp_nsyn_pop),
24021 NCE(vcvtz, 0, 2, (RVSD, RVSD), vfp_nsyn_cvtz),
24022
24023 /* Mnemonics shared by Neon and VFP. */
21d799b5 24024 nCEF(vmls, _vmls, 3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
037e8744 24025
55881a11
MGD
24026 NCE(vldm, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
24027 NCE(vldmia, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
24028 NCE(vldmdb, d100b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
24029 NCE(vstm, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
24030 NCE(vstmia, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
24031 NCE(vstmdb, d000b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
037e8744 24032
dd9634d9 24033 mnCEF(vcvt, _vcvt, 3, (RNSDQMQ, RNSDQMQ, oI32z), neon_cvt),
e3e535bc 24034 nCEF(vcvtr, _vcvt, 2, (RNSDQ, RNSDQ), neon_cvtr),
dd9634d9
AV
24035 MNCEF(vcvtb, eb20a40, 3, (RVSDMQ, RVSDMQ, oI32b), neon_cvtb),
24036 MNCEF(vcvtt, eb20a40, 3, (RVSDMQ, RVSDMQ, oI32b), neon_cvtt),
f31fef98 24037
037e8744
JB
24038
24039 /* NOTE: All VMOV encoding is special-cased! */
037e8744
JB
24040 NCE(vmovq, 0, 1, (VMOV), neon_mov),
24041
32c36c3c
AV
24042#undef THUMB_VARIANT
24043/* Could be either VLDR/VSTR or VLDR/VSTR (system register) which are guarded
24044 by different feature bits. Since we are setting the Thumb guard, we can
24045 require Thumb-1 which makes it a nop guard and set the right feature bit in
24046 do_vldr_vstr (). */
24047#define THUMB_VARIANT & arm_ext_v4t
24048 NCE(vldr, d100b00, 2, (VLDR, ADDRGLDC), vldr_vstr),
24049 NCE(vstr, d000b00, 2, (VLDR, ADDRGLDC), vldr_vstr),
24050
9db2f6b4
RL
24051#undef ARM_VARIANT
24052#define ARM_VARIANT & arm_ext_fp16
24053#undef THUMB_VARIANT
24054#define THUMB_VARIANT & arm_ext_fp16
24055 /* New instructions added from v8.2, allowing the extraction and insertion of
24056 the upper 16 bits of a 32-bit vector register. */
24057 NCE (vmovx, eb00a40, 2, (RVS, RVS), neon_movhf),
24058 NCE (vins, eb00ac0, 2, (RVS, RVS), neon_movhf),
24059
dec41383
JW
24060 /* New backported fma/fms instructions optional in v8.2. */
24061 NCE (vfmal, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmal),
24062 NCE (vfmsl, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmsl),
24063
c921be7d
NC
24064#undef THUMB_VARIANT
24065#define THUMB_VARIANT & fpu_neon_ext_v1
24066#undef ARM_VARIANT
24067#define ARM_VARIANT & fpu_neon_ext_v1
24068
5287ad62
JB
24069 /* Data processing with three registers of the same length. */
24070 /* integer ops, valid types S8 S16 S32 U8 U16 U32. */
24071 NUF(vaba, 0000710, 3, (RNDQ, RNDQ, RNDQ), neon_dyadic_i_su),
24072 NUF(vabaq, 0000710, 3, (RNQ, RNQ, RNQ), neon_dyadic_i_su),
5287ad62 24073 NUF(vhaddq, 0000000, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
5287ad62 24074 NUF(vrhaddq, 0000100, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
5287ad62
JB
24075 NUF(vhsubq, 0000200, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
24076 /* integer ops, valid types S8 S16 S32 S64 U8 U16 U32 U64. */
5287ad62 24077 NUF(vqaddq, 0000010, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
5287ad62 24078 NUF(vqsubq, 0000210, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
627907b7
JB
24079 NUF(vrshl, 0000500, 3, (RNDQ, oRNDQ, RNDQ), neon_rshl),
24080 NUF(vrshlq, 0000500, 3, (RNQ, oRNQ, RNQ), neon_rshl),
24081 NUF(vqrshl, 0000510, 3, (RNDQ, oRNDQ, RNDQ), neon_rshl),
24082 NUF(vqrshlq, 0000510, 3, (RNQ, oRNQ, RNQ), neon_rshl),
5287ad62
JB
24083 /* If not immediate, fall back to neon_dyadic_i64_su.
24084 shl_imm should accept I8 I16 I32 I64,
24085 qshl_imm should accept S8 S16 S32 S64 U8 U16 U32 U64. */
21d799b5
NC
24086 nUF(vshl, _vshl, 3, (RNDQ, oRNDQ, RNDQ_I63b), neon_shl_imm),
24087 nUF(vshlq, _vshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_shl_imm),
24088 nUF(vqshl, _vqshl, 3, (RNDQ, oRNDQ, RNDQ_I63b), neon_qshl_imm),
24089 nUF(vqshlq, _vqshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_qshl_imm),
5287ad62 24090 /* Logic ops, types optional & ignored. */
4316f0d2 24091 nUF(vandq, _vand, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 24092 nUF(vbicq, _vbic, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 24093 nUF(vorrq, _vorr, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 24094 nUF(vornq, _vorn, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 24095 nUF(veorq, _veor, 3, (RNQ, oRNQ, RNQ), neon_logic),
5287ad62
JB
24096 /* Bitfield ops, untyped. */
24097 NUF(vbsl, 1100110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
24098 NUF(vbslq, 1100110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
24099 NUF(vbit, 1200110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
24100 NUF(vbitq, 1200110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
24101 NUF(vbif, 1300110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
24102 NUF(vbifq, 1300110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
cc933301 24103 /* Int and float variants, types S8 S16 S32 U8 U16 U32 F16 F32. */
21d799b5 24104 nUF(vabdq, _vabd, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21d799b5 24105 nUF(vmaxq, _vmax, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21d799b5 24106 nUF(vminq, _vmin, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
5287ad62
JB
24107 /* Comparisons. Types S8 S16 S32 U8 U16 U32 F32. Non-immediate versions fall
24108 back to neon_dyadic_if_su. */
21d799b5
NC
24109 nUF(vcge, _vcge, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
24110 nUF(vcgeq, _vcge, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
24111 nUF(vcgt, _vcgt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
24112 nUF(vcgtq, _vcgt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
24113 nUF(vclt, _vclt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
24114 nUF(vcltq, _vclt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
24115 nUF(vcle, _vcle, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
24116 nUF(vcleq, _vcle, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
428e3f1f 24117 /* Comparison. Type I8 I16 I32 F32. */
21d799b5
NC
24118 nUF(vceq, _vceq, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_ceq),
24119 nUF(vceqq, _vceq, 3, (RNQ, oRNQ, RNDQ_I0), neon_ceq),
5287ad62 24120 /* As above, D registers only. */
21d799b5
NC
24121 nUF(vpmax, _vpmax, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
24122 nUF(vpmin, _vpmin, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
5287ad62 24123 /* Int and float variants, signedness unimportant. */
21d799b5
NC
24124 nUF(vmlaq, _vmla, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
24125 nUF(vmlsq, _vmls, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
24126 nUF(vpadd, _vpadd, 3, (RND, oRND, RND), neon_dyadic_if_i_d),
5287ad62 24127 /* Add/sub take types I8 I16 I32 I64 F32. */
21d799b5
NC
24128 nUF(vaddq, _vadd, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
24129 nUF(vsubq, _vsub, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
5287ad62
JB
24130 /* vtst takes sizes 8, 16, 32. */
24131 NUF(vtst, 0000810, 3, (RNDQ, oRNDQ, RNDQ), neon_tst),
24132 NUF(vtstq, 0000810, 3, (RNQ, oRNQ, RNQ), neon_tst),
24133 /* VMUL takes I8 I16 I32 F32 P8. */
21d799b5 24134 nUF(vmulq, _vmul, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mul),
5287ad62 24135 /* VQD{R}MULH takes S16 S32. */
21d799b5 24136 nUF(vqdmulhq, _vqdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
21d799b5 24137 nUF(vqrdmulhq, _vqrdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
5287ad62
JB
24138 NUF(vacge, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
24139 NUF(vacgeq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
24140 NUF(vacgt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
24141 NUF(vacgtq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
92559b5b
PB
24142 NUF(vaclt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
24143 NUF(vacltq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
24144 NUF(vacle, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
24145 NUF(vacleq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
5287ad62
JB
24146 NUF(vrecps, 0000f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
24147 NUF(vrecpsq, 0000f10, 3, (RNQ, oRNQ, RNQ), neon_step),
24148 NUF(vrsqrts, 0200f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
24149 NUF(vrsqrtsq, 0200f10, 3, (RNQ, oRNQ, RNQ), neon_step),
d6b4b13e 24150 /* ARM v8.1 extension. */
643afb90
MW
24151 nUF (vqrdmlahq, _vqrdmlah, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
24152 nUF (vqrdmlsh, _vqrdmlsh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qrdmlah),
24153 nUF (vqrdmlshq, _vqrdmlsh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
5287ad62
JB
24154
24155 /* Two address, int/float. Types S8 S16 S32 F32. */
5287ad62 24156 NUF(vabsq, 1b10300, 2, (RNQ, RNQ), neon_abs_neg),
5287ad62
JB
24157 NUF(vnegq, 1b10380, 2, (RNQ, RNQ), neon_abs_neg),
24158
24159 /* Data processing with two registers and a shift amount. */
24160 /* Right shifts, and variants with rounding.
24161 Types accepted S8 S16 S32 S64 U8 U16 U32 U64. */
24162 NUF(vshr, 0800010, 3, (RNDQ, oRNDQ, I64z), neon_rshift_round_imm),
24163 NUF(vshrq, 0800010, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
24164 NUF(vrshr, 0800210, 3, (RNDQ, oRNDQ, I64z), neon_rshift_round_imm),
24165 NUF(vrshrq, 0800210, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
24166 NUF(vsra, 0800110, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
24167 NUF(vsraq, 0800110, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
24168 NUF(vrsra, 0800310, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
24169 NUF(vrsraq, 0800310, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
24170 /* Shift and insert. Sizes accepted 8 16 32 64. */
24171 NUF(vsli, 1800510, 3, (RNDQ, oRNDQ, I63), neon_sli),
24172 NUF(vsliq, 1800510, 3, (RNQ, oRNQ, I63), neon_sli),
24173 NUF(vsri, 1800410, 3, (RNDQ, oRNDQ, I64), neon_sri),
24174 NUF(vsriq, 1800410, 3, (RNQ, oRNQ, I64), neon_sri),
24175 /* QSHL{U} immediate accepts S8 S16 S32 S64 U8 U16 U32 U64. */
24176 NUF(vqshlu, 1800610, 3, (RNDQ, oRNDQ, I63), neon_qshlu_imm),
24177 NUF(vqshluq, 1800610, 3, (RNQ, oRNQ, I63), neon_qshlu_imm),
24178 /* Right shift immediate, saturating & narrowing, with rounding variants.
24179 Types accepted S16 S32 S64 U16 U32 U64. */
24180 NUF(vqshrn, 0800910, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
24181 NUF(vqrshrn, 0800950, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
24182 /* As above, unsigned. Types accepted S16 S32 S64. */
24183 NUF(vqshrun, 0800810, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
24184 NUF(vqrshrun, 0800850, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
24185 /* Right shift narrowing. Types accepted I16 I32 I64. */
24186 NUF(vshrn, 0800810, 3, (RND, RNQ, I32z), neon_rshift_narrow),
24187 NUF(vrshrn, 0800850, 3, (RND, RNQ, I32z), neon_rshift_narrow),
24188 /* Special case. Types S8 S16 S32 U8 U16 U32. Handles max shift variant. */
21d799b5 24189 nUF(vshll, _vshll, 3, (RNQ, RND, I32), neon_shll),
5287ad62 24190 /* CVT with optional immediate for fixed-point variant. */
21d799b5 24191 nUF(vcvtq, _vcvt, 3, (RNQ, RNQ, oI32b), neon_cvt),
b7fc2769 24192
4316f0d2 24193 nUF(vmvnq, _vmvn, 2, (RNQ, RNDQ_Ibig), neon_mvn),
5287ad62
JB
24194
24195 /* Data processing, three registers of different lengths. */
24196 /* Dyadic, long insns. Types S8 S16 S32 U8 U16 U32. */
24197 NUF(vabal, 0800500, 3, (RNQ, RND, RND), neon_abal),
5287ad62
JB
24198 /* If not scalar, fall back to neon_dyadic_long.
24199 Vector types as above, scalar types S16 S32 U16 U32. */
21d799b5
NC
24200 nUF(vmlal, _vmlal, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
24201 nUF(vmlsl, _vmlsl, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
5287ad62
JB
24202 /* Dyadic, widening insns. Types S8 S16 S32 U8 U16 U32. */
24203 NUF(vaddw, 0800100, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
24204 NUF(vsubw, 0800300, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
24205 /* Dyadic, narrowing insns. Types I16 I32 I64. */
24206 NUF(vaddhn, 0800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
24207 NUF(vraddhn, 1800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
24208 NUF(vsubhn, 0800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
24209 NUF(vrsubhn, 1800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
24210 /* Saturating doubling multiplies. Types S16 S32. */
21d799b5
NC
24211 nUF(vqdmlal, _vqdmlal, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
24212 nUF(vqdmlsl, _vqdmlsl, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
24213 nUF(vqdmull, _vqdmull, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
5287ad62
JB
24214 /* VMULL. Vector types S8 S16 S32 U8 U16 U32 P8, scalar types
24215 S16 S32 U16 U32. */
21d799b5 24216 nUF(vmull, _vmull, 3, (RNQ, RND, RND_RNSC), neon_vmull),
5287ad62
JB
24217
24218 /* Extract. Size 8. */
3b8d421e
PB
24219 NUF(vext, 0b00000, 4, (RNDQ, oRNDQ, RNDQ, I15), neon_ext),
24220 NUF(vextq, 0b00000, 4, (RNQ, oRNQ, RNQ, I15), neon_ext),
5287ad62
JB
24221
24222 /* Two registers, miscellaneous. */
24223 /* Reverse. Sizes 8 16 32 (must be < size in opcode). */
24224 NUF(vrev64, 1b00000, 2, (RNDQ, RNDQ), neon_rev),
24225 NUF(vrev64q, 1b00000, 2, (RNQ, RNQ), neon_rev),
24226 NUF(vrev32, 1b00080, 2, (RNDQ, RNDQ), neon_rev),
24227 NUF(vrev32q, 1b00080, 2, (RNQ, RNQ), neon_rev),
24228 NUF(vrev16, 1b00100, 2, (RNDQ, RNDQ), neon_rev),
24229 NUF(vrev16q, 1b00100, 2, (RNQ, RNQ), neon_rev),
24230 /* Vector replicate. Sizes 8 16 32. */
21d799b5 24231 nCE(vdupq, _vdup, 2, (RNQ, RR_RNSC), neon_dup),
5287ad62
JB
24232 /* VMOVL. Types S8 S16 S32 U8 U16 U32. */
24233 NUF(vmovl, 0800a10, 2, (RNQ, RND), neon_movl),
24234 /* VMOVN. Types I16 I32 I64. */
21d799b5 24235 nUF(vmovn, _vmovn, 2, (RND, RNQ), neon_movn),
5287ad62 24236 /* VQMOVN. Types S16 S32 S64 U16 U32 U64. */
21d799b5 24237 nUF(vqmovn, _vqmovn, 2, (RND, RNQ), neon_qmovn),
5287ad62 24238 /* VQMOVUN. Types S16 S32 S64. */
21d799b5 24239 nUF(vqmovun, _vqmovun, 2, (RND, RNQ), neon_qmovun),
5287ad62
JB
24240 /* VZIP / VUZP. Sizes 8 16 32. */
24241 NUF(vzip, 1b20180, 2, (RNDQ, RNDQ), neon_zip_uzp),
24242 NUF(vzipq, 1b20180, 2, (RNQ, RNQ), neon_zip_uzp),
24243 NUF(vuzp, 1b20100, 2, (RNDQ, RNDQ), neon_zip_uzp),
24244 NUF(vuzpq, 1b20100, 2, (RNQ, RNQ), neon_zip_uzp),
24245 /* VQABS / VQNEG. Types S8 S16 S32. */
5287ad62 24246 NUF(vqabsq, 1b00700, 2, (RNQ, RNQ), neon_sat_abs_neg),
5287ad62
JB
24247 NUF(vqnegq, 1b00780, 2, (RNQ, RNQ), neon_sat_abs_neg),
24248 /* Pairwise, lengthening. Types S8 S16 S32 U8 U16 U32. */
24249 NUF(vpadal, 1b00600, 2, (RNDQ, RNDQ), neon_pair_long),
24250 NUF(vpadalq, 1b00600, 2, (RNQ, RNQ), neon_pair_long),
24251 NUF(vpaddl, 1b00200, 2, (RNDQ, RNDQ), neon_pair_long),
24252 NUF(vpaddlq, 1b00200, 2, (RNQ, RNQ), neon_pair_long),
cc933301 24253 /* Reciprocal estimates. Types U32 F16 F32. */
5287ad62
JB
24254 NUF(vrecpe, 1b30400, 2, (RNDQ, RNDQ), neon_recip_est),
24255 NUF(vrecpeq, 1b30400, 2, (RNQ, RNQ), neon_recip_est),
24256 NUF(vrsqrte, 1b30480, 2, (RNDQ, RNDQ), neon_recip_est),
24257 NUF(vrsqrteq, 1b30480, 2, (RNQ, RNQ), neon_recip_est),
24258 /* VCLS. Types S8 S16 S32. */
5287ad62
JB
24259 NUF(vclsq, 1b00400, 2, (RNQ, RNQ), neon_cls),
24260 /* VCLZ. Types I8 I16 I32. */
5287ad62
JB
24261 NUF(vclzq, 1b00480, 2, (RNQ, RNQ), neon_clz),
24262 /* VCNT. Size 8. */
24263 NUF(vcnt, 1b00500, 2, (RNDQ, RNDQ), neon_cnt),
24264 NUF(vcntq, 1b00500, 2, (RNQ, RNQ), neon_cnt),
24265 /* Two address, untyped. */
24266 NUF(vswp, 1b20000, 2, (RNDQ, RNDQ), neon_swp),
24267 NUF(vswpq, 1b20000, 2, (RNQ, RNQ), neon_swp),
24268 /* VTRN. Sizes 8 16 32. */
21d799b5
NC
24269 nUF(vtrn, _vtrn, 2, (RNDQ, RNDQ), neon_trn),
24270 nUF(vtrnq, _vtrn, 2, (RNQ, RNQ), neon_trn),
5287ad62
JB
24271
24272 /* Table lookup. Size 8. */
24273 NUF(vtbl, 1b00800, 3, (RND, NRDLST, RND), neon_tbl_tbx),
24274 NUF(vtbx, 1b00840, 3, (RND, NRDLST, RND), neon_tbl_tbx),
24275
c921be7d
NC
24276#undef THUMB_VARIANT
24277#define THUMB_VARIANT & fpu_vfp_v3_or_neon_ext
24278#undef ARM_VARIANT
24279#define ARM_VARIANT & fpu_vfp_v3_or_neon_ext
24280
5287ad62 24281 /* Neon element/structure load/store. */
21d799b5
NC
24282 nUF(vld1, _vld1, 2, (NSTRLST, ADDR), neon_ldx_stx),
24283 nUF(vst1, _vst1, 2, (NSTRLST, ADDR), neon_ldx_stx),
24284 nUF(vld2, _vld2, 2, (NSTRLST, ADDR), neon_ldx_stx),
24285 nUF(vst2, _vst2, 2, (NSTRLST, ADDR), neon_ldx_stx),
24286 nUF(vld3, _vld3, 2, (NSTRLST, ADDR), neon_ldx_stx),
24287 nUF(vst3, _vst3, 2, (NSTRLST, ADDR), neon_ldx_stx),
24288 nUF(vld4, _vld4, 2, (NSTRLST, ADDR), neon_ldx_stx),
24289 nUF(vst4, _vst4, 2, (NSTRLST, ADDR), neon_ldx_stx),
5287ad62 24290
c921be7d 24291#undef THUMB_VARIANT
74db7efb
NC
24292#define THUMB_VARIANT & fpu_vfp_ext_v3xd
24293#undef ARM_VARIANT
24294#define ARM_VARIANT & fpu_vfp_ext_v3xd
62f3b8c8
PB
24295 cCE("fconsts", eb00a00, 2, (RVS, I255), vfp_sp_const),
24296 cCE("fshtos", eba0a40, 2, (RVS, I16z), vfp_sp_conv_16),
24297 cCE("fsltos", eba0ac0, 2, (RVS, I32), vfp_sp_conv_32),
24298 cCE("fuhtos", ebb0a40, 2, (RVS, I16z), vfp_sp_conv_16),
24299 cCE("fultos", ebb0ac0, 2, (RVS, I32), vfp_sp_conv_32),
24300 cCE("ftoshs", ebe0a40, 2, (RVS, I16z), vfp_sp_conv_16),
24301 cCE("ftosls", ebe0ac0, 2, (RVS, I32), vfp_sp_conv_32),
24302 cCE("ftouhs", ebf0a40, 2, (RVS, I16z), vfp_sp_conv_16),
24303 cCE("ftouls", ebf0ac0, 2, (RVS, I32), vfp_sp_conv_32),
24304
74db7efb 24305#undef THUMB_VARIANT
c921be7d
NC
24306#define THUMB_VARIANT & fpu_vfp_ext_v3
24307#undef ARM_VARIANT
24308#define ARM_VARIANT & fpu_vfp_ext_v3
24309
21d799b5 24310 cCE("fconstd", eb00b00, 2, (RVD, I255), vfp_dp_const),
21d799b5 24311 cCE("fshtod", eba0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 24312 cCE("fsltod", eba0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 24313 cCE("fuhtod", ebb0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 24314 cCE("fultod", ebb0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 24315 cCE("ftoshd", ebe0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 24316 cCE("ftosld", ebe0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 24317 cCE("ftouhd", ebf0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 24318 cCE("ftould", ebf0bc0, 2, (RVD, I32), vfp_dp_conv_32),
c19d1205 24319
74db7efb
NC
24320#undef ARM_VARIANT
24321#define ARM_VARIANT & fpu_vfp_ext_fma
24322#undef THUMB_VARIANT
24323#define THUMB_VARIANT & fpu_vfp_ext_fma
d58196e0 24324 /* Mnemonics shared by Neon, VFP and MVE. These are included in the
62f3b8c8
PB
24325 VFP FMA variant; NEON and VFP FMA always includes the NEON
24326 FMA instructions. */
d58196e0
AV
24327 mnCEF(vfma, _vfma, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_fmac),
24328 mnCEF(vfms, _vfms, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), neon_fmac),
24329
62f3b8c8
PB
24330 /* ffmas/ffmad/ffmss/ffmsd are dummy mnemonics to satisfy gas;
24331 the v form should always be used. */
24332 cCE("ffmas", ea00a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
24333 cCE("ffnmas", ea00a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
24334 cCE("ffmad", ea00b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
24335 cCE("ffnmad", ea00b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
24336 nCE(vfnma, _vfnma, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
24337 nCE(vfnms, _vfnms, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
24338
5287ad62 24339#undef THUMB_VARIANT
c921be7d
NC
24340#undef ARM_VARIANT
24341#define ARM_VARIANT & arm_cext_xscale /* Intel XScale extensions. */
24342
21d799b5
NC
24343 cCE("mia", e200010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
24344 cCE("miaph", e280010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
24345 cCE("miabb", e2c0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
24346 cCE("miabt", e2d0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
24347 cCE("miatb", e2e0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
24348 cCE("miatt", e2f0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
24349 cCE("mar", c400000, 3, (RXA, RRnpc, RRnpc), xsc_mar),
24350 cCE("mra", c500000, 3, (RRnpc, RRnpc, RXA), xsc_mra),
c19d1205 24351
c921be7d
NC
24352#undef ARM_VARIANT
24353#define ARM_VARIANT & arm_cext_iwmmxt /* Intel Wireless MMX technology. */
24354
21d799b5
NC
24355 cCE("tandcb", e13f130, 1, (RR), iwmmxt_tandorc),
24356 cCE("tandch", e53f130, 1, (RR), iwmmxt_tandorc),
24357 cCE("tandcw", e93f130, 1, (RR), iwmmxt_tandorc),
24358 cCE("tbcstb", e400010, 2, (RIWR, RR), rn_rd),
24359 cCE("tbcsth", e400050, 2, (RIWR, RR), rn_rd),
24360 cCE("tbcstw", e400090, 2, (RIWR, RR), rn_rd),
24361 cCE("textrcb", e130170, 2, (RR, I7), iwmmxt_textrc),
24362 cCE("textrch", e530170, 2, (RR, I7), iwmmxt_textrc),
24363 cCE("textrcw", e930170, 2, (RR, I7), iwmmxt_textrc),
74db7efb
NC
24364 cCE("textrmub",e100070, 3, (RR, RIWR, I7), iwmmxt_textrm),
24365 cCE("textrmuh",e500070, 3, (RR, RIWR, I7), iwmmxt_textrm),
24366 cCE("textrmuw",e900070, 3, (RR, RIWR, I7), iwmmxt_textrm),
24367 cCE("textrmsb",e100078, 3, (RR, RIWR, I7), iwmmxt_textrm),
24368 cCE("textrmsh",e500078, 3, (RR, RIWR, I7), iwmmxt_textrm),
24369 cCE("textrmsw",e900078, 3, (RR, RIWR, I7), iwmmxt_textrm),
21d799b5
NC
24370 cCE("tinsrb", e600010, 3, (RIWR, RR, I7), iwmmxt_tinsr),
24371 cCE("tinsrh", e600050, 3, (RIWR, RR, I7), iwmmxt_tinsr),
24372 cCE("tinsrw", e600090, 3, (RIWR, RR, I7), iwmmxt_tinsr),
24373 cCE("tmcr", e000110, 2, (RIWC_RIWG, RR), rn_rd),
24374 cCE("tmcrr", c400000, 3, (RIWR, RR, RR), rm_rd_rn),
24375 cCE("tmia", e200010, 3, (RIWR, RR, RR), iwmmxt_tmia),
24376 cCE("tmiaph", e280010, 3, (RIWR, RR, RR), iwmmxt_tmia),
24377 cCE("tmiabb", e2c0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
24378 cCE("tmiabt", e2d0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
24379 cCE("tmiatb", e2e0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
24380 cCE("tmiatt", e2f0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
74db7efb
NC
24381 cCE("tmovmskb",e100030, 2, (RR, RIWR), rd_rn),
24382 cCE("tmovmskh",e500030, 2, (RR, RIWR), rd_rn),
24383 cCE("tmovmskw",e900030, 2, (RR, RIWR), rd_rn),
21d799b5
NC
24384 cCE("tmrc", e100110, 2, (RR, RIWC_RIWG), rd_rn),
24385 cCE("tmrrc", c500000, 3, (RR, RR, RIWR), rd_rn_rm),
24386 cCE("torcb", e13f150, 1, (RR), iwmmxt_tandorc),
24387 cCE("torch", e53f150, 1, (RR), iwmmxt_tandorc),
24388 cCE("torcw", e93f150, 1, (RR), iwmmxt_tandorc),
24389 cCE("waccb", e0001c0, 2, (RIWR, RIWR), rd_rn),
24390 cCE("wacch", e4001c0, 2, (RIWR, RIWR), rd_rn),
24391 cCE("waccw", e8001c0, 2, (RIWR, RIWR), rd_rn),
24392 cCE("waddbss", e300180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24393 cCE("waddb", e000180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24394 cCE("waddbus", e100180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24395 cCE("waddhss", e700180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24396 cCE("waddh", e400180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24397 cCE("waddhus", e500180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24398 cCE("waddwss", eb00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24399 cCE("waddw", e800180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24400 cCE("waddwus", e900180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24401 cCE("waligni", e000020, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_waligni),
74db7efb
NC
24402 cCE("walignr0",e800020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24403 cCE("walignr1",e900020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24404 cCE("walignr2",ea00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24405 cCE("walignr3",eb00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
24406 cCE("wand", e200000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24407 cCE("wandn", e300000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24408 cCE("wavg2b", e800000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24409 cCE("wavg2br", e900000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24410 cCE("wavg2h", ec00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24411 cCE("wavg2hr", ed00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24412 cCE("wcmpeqb", e000060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24413 cCE("wcmpeqh", e400060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24414 cCE("wcmpeqw", e800060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
24415 cCE("wcmpgtub",e100060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24416 cCE("wcmpgtuh",e500060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24417 cCE("wcmpgtuw",e900060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24418 cCE("wcmpgtsb",e300060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24419 cCE("wcmpgtsh",e700060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24420 cCE("wcmpgtsw",eb00060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
24421 cCE("wldrb", c100000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
24422 cCE("wldrh", c500000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
24423 cCE("wldrw", c100100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
24424 cCE("wldrd", c500100, 2, (RIWR, ADDR), iwmmxt_wldstd),
24425 cCE("wmacs", e600100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24426 cCE("wmacsz", e700100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24427 cCE("wmacu", e400100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24428 cCE("wmacuz", e500100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24429 cCE("wmadds", ea00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24430 cCE("wmaddu", e800100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24431 cCE("wmaxsb", e200160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24432 cCE("wmaxsh", e600160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24433 cCE("wmaxsw", ea00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24434 cCE("wmaxub", e000160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24435 cCE("wmaxuh", e400160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24436 cCE("wmaxuw", e800160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24437 cCE("wminsb", e300160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24438 cCE("wminsh", e700160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24439 cCE("wminsw", eb00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24440 cCE("wminub", e100160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24441 cCE("wminuh", e500160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24442 cCE("wminuw", e900160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24443 cCE("wmov", e000000, 2, (RIWR, RIWR), iwmmxt_wmov),
24444 cCE("wmulsm", e300100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24445 cCE("wmulsl", e200100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24446 cCE("wmulum", e100100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24447 cCE("wmulul", e000100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24448 cCE("wor", e000000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
24449 cCE("wpackhss",e700080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24450 cCE("wpackhus",e500080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24451 cCE("wpackwss",eb00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24452 cCE("wpackwus",e900080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24453 cCE("wpackdss",ef00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24454 cCE("wpackdus",ed00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
24455 cCE("wrorh", e700040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24456 cCE("wrorhg", e700148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24457 cCE("wrorw", eb00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24458 cCE("wrorwg", eb00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24459 cCE("wrord", ef00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24460 cCE("wrordg", ef00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24461 cCE("wsadb", e000120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24462 cCE("wsadbz", e100120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24463 cCE("wsadh", e400120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24464 cCE("wsadhz", e500120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24465 cCE("wshufh", e0001e0, 3, (RIWR, RIWR, I255), iwmmxt_wshufh),
24466 cCE("wsllh", e500040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24467 cCE("wsllhg", e500148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24468 cCE("wsllw", e900040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24469 cCE("wsllwg", e900148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24470 cCE("wslld", ed00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24471 cCE("wslldg", ed00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24472 cCE("wsrah", e400040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24473 cCE("wsrahg", e400148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24474 cCE("wsraw", e800040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24475 cCE("wsrawg", e800148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24476 cCE("wsrad", ec00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24477 cCE("wsradg", ec00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24478 cCE("wsrlh", e600040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24479 cCE("wsrlhg", e600148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24480 cCE("wsrlw", ea00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24481 cCE("wsrlwg", ea00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24482 cCE("wsrld", ee00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24483 cCE("wsrldg", ee00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24484 cCE("wstrb", c000000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
24485 cCE("wstrh", c400000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
24486 cCE("wstrw", c000100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
24487 cCE("wstrd", c400100, 2, (RIWR, ADDR), iwmmxt_wldstd),
24488 cCE("wsubbss", e3001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24489 cCE("wsubb", e0001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24490 cCE("wsubbus", e1001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24491 cCE("wsubhss", e7001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24492 cCE("wsubh", e4001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24493 cCE("wsubhus", e5001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24494 cCE("wsubwss", eb001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24495 cCE("wsubw", e8001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24496 cCE("wsubwus", e9001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24497 cCE("wunpckehub",e0000c0, 2, (RIWR, RIWR), rd_rn),
24498 cCE("wunpckehuh",e4000c0, 2, (RIWR, RIWR), rd_rn),
24499 cCE("wunpckehuw",e8000c0, 2, (RIWR, RIWR), rd_rn),
24500 cCE("wunpckehsb",e2000c0, 2, (RIWR, RIWR), rd_rn),
24501 cCE("wunpckehsh",e6000c0, 2, (RIWR, RIWR), rd_rn),
24502 cCE("wunpckehsw",ea000c0, 2, (RIWR, RIWR), rd_rn),
24503 cCE("wunpckihb", e1000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24504 cCE("wunpckihh", e5000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24505 cCE("wunpckihw", e9000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24506 cCE("wunpckelub",e0000e0, 2, (RIWR, RIWR), rd_rn),
24507 cCE("wunpckeluh",e4000e0, 2, (RIWR, RIWR), rd_rn),
24508 cCE("wunpckeluw",e8000e0, 2, (RIWR, RIWR), rd_rn),
24509 cCE("wunpckelsb",e2000e0, 2, (RIWR, RIWR), rd_rn),
24510 cCE("wunpckelsh",e6000e0, 2, (RIWR, RIWR), rd_rn),
24511 cCE("wunpckelsw",ea000e0, 2, (RIWR, RIWR), rd_rn),
24512 cCE("wunpckilb", e1000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24513 cCE("wunpckilh", e5000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24514 cCE("wunpckilw", e9000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24515 cCE("wxor", e100000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24516 cCE("wzero", e300000, 1, (RIWR), iwmmxt_wzero),
c19d1205 24517
c921be7d
NC
24518#undef ARM_VARIANT
24519#define ARM_VARIANT & arm_cext_iwmmxt2 /* Intel Wireless MMX technology, version 2. */
24520
21d799b5
NC
24521 cCE("torvscb", e12f190, 1, (RR), iwmmxt_tandorc),
24522 cCE("torvsch", e52f190, 1, (RR), iwmmxt_tandorc),
24523 cCE("torvscw", e92f190, 1, (RR), iwmmxt_tandorc),
24524 cCE("wabsb", e2001c0, 2, (RIWR, RIWR), rd_rn),
24525 cCE("wabsh", e6001c0, 2, (RIWR, RIWR), rd_rn),
24526 cCE("wabsw", ea001c0, 2, (RIWR, RIWR), rd_rn),
24527 cCE("wabsdiffb", e1001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24528 cCE("wabsdiffh", e5001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24529 cCE("wabsdiffw", e9001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24530 cCE("waddbhusl", e2001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24531 cCE("waddbhusm", e6001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24532 cCE("waddhc", e600180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24533 cCE("waddwc", ea00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24534 cCE("waddsubhx", ea001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24535 cCE("wavg4", e400000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24536 cCE("wavg4r", e500000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24537 cCE("wmaddsn", ee00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24538 cCE("wmaddsx", eb00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24539 cCE("wmaddun", ec00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24540 cCE("wmaddux", e900100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24541 cCE("wmerge", e000080, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_wmerge),
24542 cCE("wmiabb", e0000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24543 cCE("wmiabt", e1000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24544 cCE("wmiatb", e2000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24545 cCE("wmiatt", e3000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24546 cCE("wmiabbn", e4000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24547 cCE("wmiabtn", e5000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24548 cCE("wmiatbn", e6000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24549 cCE("wmiattn", e7000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24550 cCE("wmiawbb", e800120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24551 cCE("wmiawbt", e900120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24552 cCE("wmiawtb", ea00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24553 cCE("wmiawtt", eb00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24554 cCE("wmiawbbn", ec00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24555 cCE("wmiawbtn", ed00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24556 cCE("wmiawtbn", ee00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24557 cCE("wmiawttn", ef00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24558 cCE("wmulsmr", ef00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24559 cCE("wmulumr", ed00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24560 cCE("wmulwumr", ec000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24561 cCE("wmulwsmr", ee000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24562 cCE("wmulwum", ed000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24563 cCE("wmulwsm", ef000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24564 cCE("wmulwl", eb000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24565 cCE("wqmiabb", e8000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24566 cCE("wqmiabt", e9000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24567 cCE("wqmiatb", ea000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24568 cCE("wqmiatt", eb000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24569 cCE("wqmiabbn", ec000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24570 cCE("wqmiabtn", ed000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24571 cCE("wqmiatbn", ee000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24572 cCE("wqmiattn", ef000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24573 cCE("wqmulm", e100080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24574 cCE("wqmulmr", e300080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24575 cCE("wqmulwm", ec000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24576 cCE("wqmulwmr", ee000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24577 cCE("wsubaddhx", ed001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
2d447fca 24578
c921be7d
NC
24579#undef ARM_VARIANT
24580#define ARM_VARIANT & arm_cext_maverick /* Cirrus Maverick instructions. */
24581
21d799b5
NC
24582 cCE("cfldrs", c100400, 2, (RMF, ADDRGLDC), rd_cpaddr),
24583 cCE("cfldrd", c500400, 2, (RMD, ADDRGLDC), rd_cpaddr),
24584 cCE("cfldr32", c100500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
24585 cCE("cfldr64", c500500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
24586 cCE("cfstrs", c000400, 2, (RMF, ADDRGLDC), rd_cpaddr),
24587 cCE("cfstrd", c400400, 2, (RMD, ADDRGLDC), rd_cpaddr),
24588 cCE("cfstr32", c000500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
24589 cCE("cfstr64", c400500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
24590 cCE("cfmvsr", e000450, 2, (RMF, RR), rn_rd),
24591 cCE("cfmvrs", e100450, 2, (RR, RMF), rd_rn),
24592 cCE("cfmvdlr", e000410, 2, (RMD, RR), rn_rd),
24593 cCE("cfmvrdl", e100410, 2, (RR, RMD), rd_rn),
24594 cCE("cfmvdhr", e000430, 2, (RMD, RR), rn_rd),
24595 cCE("cfmvrdh", e100430, 2, (RR, RMD), rd_rn),
74db7efb
NC
24596 cCE("cfmv64lr",e000510, 2, (RMDX, RR), rn_rd),
24597 cCE("cfmvr64l",e100510, 2, (RR, RMDX), rd_rn),
24598 cCE("cfmv64hr",e000530, 2, (RMDX, RR), rn_rd),
24599 cCE("cfmvr64h",e100530, 2, (RR, RMDX), rd_rn),
24600 cCE("cfmval32",e200440, 2, (RMAX, RMFX), rd_rn),
24601 cCE("cfmv32al",e100440, 2, (RMFX, RMAX), rd_rn),
24602 cCE("cfmvam32",e200460, 2, (RMAX, RMFX), rd_rn),
24603 cCE("cfmv32am",e100460, 2, (RMFX, RMAX), rd_rn),
24604 cCE("cfmvah32",e200480, 2, (RMAX, RMFX), rd_rn),
24605 cCE("cfmv32ah",e100480, 2, (RMFX, RMAX), rd_rn),
21d799b5
NC
24606 cCE("cfmva32", e2004a0, 2, (RMAX, RMFX), rd_rn),
24607 cCE("cfmv32a", e1004a0, 2, (RMFX, RMAX), rd_rn),
24608 cCE("cfmva64", e2004c0, 2, (RMAX, RMDX), rd_rn),
24609 cCE("cfmv64a", e1004c0, 2, (RMDX, RMAX), rd_rn),
74db7efb
NC
24610 cCE("cfmvsc32",e2004e0, 2, (RMDS, RMDX), mav_dspsc),
24611 cCE("cfmv32sc",e1004e0, 2, (RMDX, RMDS), rd),
21d799b5
NC
24612 cCE("cfcpys", e000400, 2, (RMF, RMF), rd_rn),
24613 cCE("cfcpyd", e000420, 2, (RMD, RMD), rd_rn),
24614 cCE("cfcvtsd", e000460, 2, (RMD, RMF), rd_rn),
24615 cCE("cfcvtds", e000440, 2, (RMF, RMD), rd_rn),
74db7efb
NC
24616 cCE("cfcvt32s",e000480, 2, (RMF, RMFX), rd_rn),
24617 cCE("cfcvt32d",e0004a0, 2, (RMD, RMFX), rd_rn),
24618 cCE("cfcvt64s",e0004c0, 2, (RMF, RMDX), rd_rn),
24619 cCE("cfcvt64d",e0004e0, 2, (RMD, RMDX), rd_rn),
24620 cCE("cfcvts32",e100580, 2, (RMFX, RMF), rd_rn),
24621 cCE("cfcvtd32",e1005a0, 2, (RMFX, RMD), rd_rn),
21d799b5
NC
24622 cCE("cftruncs32",e1005c0, 2, (RMFX, RMF), rd_rn),
24623 cCE("cftruncd32",e1005e0, 2, (RMFX, RMD), rd_rn),
74db7efb
NC
24624 cCE("cfrshl32",e000550, 3, (RMFX, RMFX, RR), mav_triple),
24625 cCE("cfrshl64",e000570, 3, (RMDX, RMDX, RR), mav_triple),
21d799b5
NC
24626 cCE("cfsh32", e000500, 3, (RMFX, RMFX, I63s), mav_shift),
24627 cCE("cfsh64", e200500, 3, (RMDX, RMDX, I63s), mav_shift),
24628 cCE("cfcmps", e100490, 3, (RR, RMF, RMF), rd_rn_rm),
24629 cCE("cfcmpd", e1004b0, 3, (RR, RMD, RMD), rd_rn_rm),
24630 cCE("cfcmp32", e100590, 3, (RR, RMFX, RMFX), rd_rn_rm),
24631 cCE("cfcmp64", e1005b0, 3, (RR, RMDX, RMDX), rd_rn_rm),
24632 cCE("cfabss", e300400, 2, (RMF, RMF), rd_rn),
24633 cCE("cfabsd", e300420, 2, (RMD, RMD), rd_rn),
24634 cCE("cfnegs", e300440, 2, (RMF, RMF), rd_rn),
24635 cCE("cfnegd", e300460, 2, (RMD, RMD), rd_rn),
24636 cCE("cfadds", e300480, 3, (RMF, RMF, RMF), rd_rn_rm),
24637 cCE("cfaddd", e3004a0, 3, (RMD, RMD, RMD), rd_rn_rm),
24638 cCE("cfsubs", e3004c0, 3, (RMF, RMF, RMF), rd_rn_rm),
24639 cCE("cfsubd", e3004e0, 3, (RMD, RMD, RMD), rd_rn_rm),
24640 cCE("cfmuls", e100400, 3, (RMF, RMF, RMF), rd_rn_rm),
24641 cCE("cfmuld", e100420, 3, (RMD, RMD, RMD), rd_rn_rm),
24642 cCE("cfabs32", e300500, 2, (RMFX, RMFX), rd_rn),
24643 cCE("cfabs64", e300520, 2, (RMDX, RMDX), rd_rn),
24644 cCE("cfneg32", e300540, 2, (RMFX, RMFX), rd_rn),
24645 cCE("cfneg64", e300560, 2, (RMDX, RMDX), rd_rn),
24646 cCE("cfadd32", e300580, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
24647 cCE("cfadd64", e3005a0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
24648 cCE("cfsub32", e3005c0, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
24649 cCE("cfsub64", e3005e0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
24650 cCE("cfmul32", e100500, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
24651 cCE("cfmul64", e100520, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
24652 cCE("cfmac32", e100540, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
24653 cCE("cfmsc32", e100560, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
74db7efb
NC
24654 cCE("cfmadd32",e000600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
24655 cCE("cfmsub32",e100600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
21d799b5
NC
24656 cCE("cfmadda32", e200600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
24657 cCE("cfmsuba32", e300600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
4ed7ed8d 24658
7fadb25d
SD
24659 /* ARMv8.5-A instructions. */
24660#undef ARM_VARIANT
24661#define ARM_VARIANT & arm_ext_sb
24662#undef THUMB_VARIANT
24663#define THUMB_VARIANT & arm_ext_sb
24664 TUF("sb", 57ff070, f3bf8f70, 0, (), noargs, noargs),
24665
dad0c3bf
SD
24666#undef ARM_VARIANT
24667#define ARM_VARIANT & arm_ext_predres
24668#undef THUMB_VARIANT
24669#define THUMB_VARIANT & arm_ext_predres
24670 CE("cfprctx", e070f93, 1, (RRnpc), rd),
24671 CE("dvprctx", e070fb3, 1, (RRnpc), rd),
24672 CE("cpprctx", e070ff3, 1, (RRnpc), rd),
24673
16a1fa25 24674 /* ARMv8-M instructions. */
4ed7ed8d
TP
24675#undef ARM_VARIANT
24676#define ARM_VARIANT NULL
24677#undef THUMB_VARIANT
24678#define THUMB_VARIANT & arm_ext_v8m
cf3cf39d
TP
24679 ToU("sg", e97fe97f, 0, (), noargs),
24680 ToC("blxns", 4784, 1, (RRnpc), t_blx),
24681 ToC("bxns", 4704, 1, (RRnpc), t_bx),
24682 ToC("tt", e840f000, 2, (RRnpc, RRnpc), tt),
24683 ToC("ttt", e840f040, 2, (RRnpc, RRnpc), tt),
24684 ToC("tta", e840f080, 2, (RRnpc, RRnpc), tt),
24685 ToC("ttat", e840f0c0, 2, (RRnpc, RRnpc), tt),
16a1fa25
TP
24686
24687 /* FP for ARMv8-M Mainline. Enabled for ARMv8-M Mainline because the
24688 instructions behave as nop if no VFP is present. */
24689#undef THUMB_VARIANT
24690#define THUMB_VARIANT & arm_ext_v8m_main
cf3cf39d
TP
24691 ToC("vlldm", ec300a00, 1, (RRnpc), rn),
24692 ToC("vlstm", ec200a00, 1, (RRnpc), rn),
4389b29a
AV
24693
24694 /* Armv8.1-M Mainline instructions. */
24695#undef THUMB_VARIANT
24696#define THUMB_VARIANT & arm_ext_v8_1m_main
24697 toC("bf", _bf, 2, (EXPs, EXPs), t_branch_future),
f6b2b12d 24698 toU("bfcsel", _bfcsel, 4, (EXPs, EXPs, EXPs, COND), t_branch_future),
f1c7f421 24699 toC("bfx", _bfx, 2, (EXPs, RRnpcsp), t_branch_future),
65d1bc05 24700 toC("bfl", _bfl, 2, (EXPs, EXPs), t_branch_future),
f1c7f421 24701 toC("bflx", _bflx, 2, (EXPs, RRnpcsp), t_branch_future),
60f993ce
AV
24702
24703 toU("dls", _dls, 2, (LR, RRnpcsp), t_loloop),
24704 toU("wls", _wls, 3, (LR, RRnpcsp, EXP), t_loloop),
24705 toU("le", _le, 2, (oLR, EXP), t_loloop),
4b5a202f 24706
efd6b359 24707 ToC("clrm", e89f0000, 1, (CLRMLST), t_clrm),
5ee91343
AV
24708 ToC("vscclrm", ec9f0a00, 1, (VRSDVLST), t_vscclrm),
24709
24710#undef THUMB_VARIANT
24711#define THUMB_VARIANT & mve_ext
1b883319
AV
24712
24713 ToC("vpt", ee410f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24714 ToC("vptt", ee018f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24715 ToC("vpte", ee418f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24716 ToC("vpttt", ee014f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24717 ToC("vptte", ee01cf00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24718 ToC("vptet", ee41cf00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24719 ToC("vptee", ee414f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24720 ToC("vptttt", ee012f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24721 ToC("vpttte", ee016f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24722 ToC("vpttet", ee01ef00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24723 ToC("vpttee", ee01af00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24724 ToC("vptett", ee41af00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24725 ToC("vptete", ee41ef00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24726 ToC("vpteet", ee416f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24727 ToC("vpteee", ee412f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24728
5ee91343
AV
24729 ToC("vpst", fe710f4d, 0, (), mve_vpt),
24730 ToC("vpstt", fe318f4d, 0, (), mve_vpt),
24731 ToC("vpste", fe718f4d, 0, (), mve_vpt),
24732 ToC("vpsttt", fe314f4d, 0, (), mve_vpt),
24733 ToC("vpstte", fe31cf4d, 0, (), mve_vpt),
24734 ToC("vpstet", fe71cf4d, 0, (), mve_vpt),
24735 ToC("vpstee", fe714f4d, 0, (), mve_vpt),
24736 ToC("vpstttt", fe312f4d, 0, (), mve_vpt),
24737 ToC("vpsttte", fe316f4d, 0, (), mve_vpt),
24738 ToC("vpsttet", fe31ef4d, 0, (), mve_vpt),
24739 ToC("vpsttee", fe31af4d, 0, (), mve_vpt),
24740 ToC("vpstett", fe71af4d, 0, (), mve_vpt),
24741 ToC("vpstete", fe71ef4d, 0, (), mve_vpt),
24742 ToC("vpsteet", fe716f4d, 0, (), mve_vpt),
24743 ToC("vpsteee", fe712f4d, 0, (), mve_vpt),
24744
a302e574 24745 /* MVE and MVE FP only. */
7df54120 24746 mToC("vhcadd", ee000f00, 4, (RMQ, RMQ, RMQ, EXPi), mve_vhcadd),
c2dafc2a
AV
24747 mCEF(vadc, _vadc, 3, (RMQ, RMQ, RMQ), mve_vadc),
24748 mCEF(vadci, _vadci, 3, (RMQ, RMQ, RMQ), mve_vadc),
24749 mToC("vsbc", fe300f00, 3, (RMQ, RMQ, RMQ), mve_vsbc),
24750 mToC("vsbci", fe301f00, 3, (RMQ, RMQ, RMQ), mve_vsbc),
886e1c73 24751 mCEF(vmullb, _vmullb, 3, (RMQ, RMQ, RMQ), mve_vmull),
a302e574
AV
24752 mCEF(vabav, _vabav, 3, (RRnpcsp, RMQ, RMQ), mve_vabav),
24753 mCEF(vmladav, _vmladav, 3, (RRe, RMQ, RMQ), mve_vmladav),
24754 mCEF(vmladava, _vmladava, 3, (RRe, RMQ, RMQ), mve_vmladav),
24755 mCEF(vmladavx, _vmladavx, 3, (RRe, RMQ, RMQ), mve_vmladav),
24756 mCEF(vmladavax, _vmladavax, 3, (RRe, RMQ, RMQ), mve_vmladav),
24757 mCEF(vmlav, _vmladav, 3, (RRe, RMQ, RMQ), mve_vmladav),
24758 mCEF(vmlava, _vmladava, 3, (RRe, RMQ, RMQ), mve_vmladav),
24759 mCEF(vmlsdav, _vmlsdav, 3, (RRe, RMQ, RMQ), mve_vmladav),
24760 mCEF(vmlsdava, _vmlsdava, 3, (RRe, RMQ, RMQ), mve_vmladav),
24761 mCEF(vmlsdavx, _vmlsdavx, 3, (RRe, RMQ, RMQ), mve_vmladav),
24762 mCEF(vmlsdavax, _vmlsdavax, 3, (RRe, RMQ, RMQ), mve_vmladav),
24763
35c228db
AV
24764 mCEF(vst20, _vst20, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
24765 mCEF(vst21, _vst21, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
24766 mCEF(vst40, _vst40, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
24767 mCEF(vst41, _vst41, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
24768 mCEF(vst42, _vst42, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
24769 mCEF(vst43, _vst43, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
24770 mCEF(vld20, _vld20, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
24771 mCEF(vld21, _vld21, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
24772 mCEF(vld40, _vld40, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
24773 mCEF(vld41, _vld41, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
24774 mCEF(vld42, _vld42, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
24775 mCEF(vld43, _vld43, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
f5f10c66
AV
24776 mCEF(vstrb, _vstrb, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
24777 mCEF(vstrh, _vstrh, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
24778 mCEF(vstrw, _vstrw, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
24779 mCEF(vstrd, _vstrd, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
24780 mCEF(vldrb, _vldrb, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
24781 mCEF(vldrh, _vldrh, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
24782 mCEF(vldrw, _vldrw, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
24783 mCEF(vldrd, _vldrd, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
35c228db 24784
57785aa2
AV
24785 mCEF(vmovnt, _vmovnt, 2, (RMQ, RMQ), mve_movn),
24786 mCEF(vmovnb, _vmovnb, 2, (RMQ, RMQ), mve_movn),
c2dafc2a 24787 mCEF(vbrsr, _vbrsr, 3, (RMQ, RMQ, RR), mve_vbrsr),
26c1e780
AV
24788 mCEF(vaddlv, _vaddlv, 3, (RRe, RRo, RMQ), mve_vaddlv),
24789 mCEF(vaddlva, _vaddlva, 3, (RRe, RRo, RMQ), mve_vaddlv),
24790 mCEF(vaddv, _vaddv, 2, (RRe, RMQ), mve_vaddv),
24791 mCEF(vaddva, _vaddva, 2, (RRe, RMQ), mve_vaddv),
b409bdb6
AV
24792 mCEF(vddup, _vddup, 3, (RMQ, RRe, EXPi), mve_viddup),
24793 mCEF(vdwdup, _vdwdup, 4, (RMQ, RRe, RR, EXPi), mve_viddup),
24794 mCEF(vidup, _vidup, 3, (RMQ, RRe, EXPi), mve_viddup),
24795 mCEF(viwdup, _viwdup, 4, (RMQ, RRe, RR, EXPi), mve_viddup),
935295b5
AV
24796 mToC("vmaxa", ee330e81, 2, (RMQ, RMQ), mve_vmaxa_vmina),
24797 mToC("vmina", ee331e81, 2, (RMQ, RMQ), mve_vmaxa_vmina),
13ccd4c0
AV
24798 mCEF(vmaxv, _vmaxv, 2, (RR, RMQ), mve_vmaxv),
24799 mCEF(vmaxav, _vmaxav, 2, (RR, RMQ), mve_vmaxv),
24800 mCEF(vminv, _vminv, 2, (RR, RMQ), mve_vmaxv),
24801 mCEF(vminav, _vminav, 2, (RR, RMQ), mve_vmaxv),
57785aa2 24802
93925576
AV
24803 mCEF(vmlaldav, _vmlaldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24804 mCEF(vmlaldava, _vmlaldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24805 mCEF(vmlaldavx, _vmlaldavx, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24806 mCEF(vmlaldavax, _vmlaldavax, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24807 mCEF(vmlalv, _vmlaldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24808 mCEF(vmlalva, _vmlaldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24809 mCEF(vmlsldav, _vmlsldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24810 mCEF(vmlsldava, _vmlsldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24811 mCEF(vmlsldavx, _vmlsldavx, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24812 mCEF(vmlsldavax, _vmlsldavax, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24813 mToC("vrmlaldavh", ee800f00, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24814 mToC("vrmlaldavha",ee800f20, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24815 mCEF(vrmlaldavhx, _vrmlaldavhx, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24816 mCEF(vrmlaldavhax, _vrmlaldavhax, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24817 mToC("vrmlalvh", ee800f00, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24818 mToC("vrmlalvha", ee800f20, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24819 mCEF(vrmlsldavh, _vrmlsldavh, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24820 mCEF(vrmlsldavha, _vrmlsldavha, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24821 mCEF(vrmlsldavhx, _vrmlsldavhx, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24822 mCEF(vrmlsldavhax, _vrmlsldavhax, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24823
2d78f95b
AV
24824 mToC("vmlas", ee011e40, 3, (RMQ, RMQ, RR), mve_vmlas),
24825 mToC("vmulh", ee010e01, 3, (RMQ, RMQ, RMQ), mve_vmulh),
24826 mToC("vrmulh", ee011e01, 3, (RMQ, RMQ, RMQ), mve_vmulh),
3063888e
AV
24827 mToC("vpnot", fe310f4d, 0, (), mve_vpnot),
24828 mToC("vpsel", fe310f01, 3, (RMQ, RMQ, RMQ), mve_vpsel),
2d78f95b 24829
8b8b22a4
AV
24830 mToC("vqdmladh", ee000e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
24831 mToC("vqdmladhx", ee001e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
24832 mToC("vqrdmladh", ee000e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
24833 mToC("vqrdmladhx",ee001e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
24834 mToC("vqdmlsdh", fe000e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
24835 mToC("vqdmlsdhx", fe001e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
24836 mToC("vqrdmlsdh", fe000e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
24837 mToC("vqrdmlsdhx",fe001e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
42b16635
AV
24838 mToC("vqdmlah", ee000e60, 3, (RMQ, RMQ, RR), mve_vqdmlah),
24839 mToC("vqdmlash", ee001e60, 3, (RMQ, RMQ, RR), mve_vqdmlah),
24840 mToC("vqrdmlash", ee001e40, 3, (RMQ, RMQ, RR), mve_vqdmlah),
8b8b22a4 24841
5d281bf0
AV
24842#undef THUMB_VARIANT
24843#define THUMB_VARIANT & mve_fp_ext
24844 mToC("vcmul", ee300e00, 4, (RMQ, RMQ, RMQ, EXPi), mve_vcmul),
f30ee27c 24845 mToC("vfmas", ee311e40, 3, (RMQ, RMQ, RR), mve_vfmas),
935295b5
AV
24846 mToC("vmaxnma", ee3f0e81, 2, (RMQ, RMQ), mve_vmaxnma_vminnma),
24847 mToC("vminnma", ee3f1e81, 2, (RMQ, RMQ), mve_vmaxnma_vminnma),
8cd78170
AV
24848 mToC("vmaxnmv", eeee0f00, 2, (RR, RMQ), mve_vmaxnmv),
24849 mToC("vmaxnmav",eeec0f00, 2, (RR, RMQ), mve_vmaxnmv),
24850 mToC("vminnmv", eeee0f80, 2, (RR, RMQ), mve_vmaxnmv),
24851 mToC("vminnmav",eeec0f80, 2, (RR, RMQ), mve_vmaxnmv),
5d281bf0 24852
5ee91343 24853#undef ARM_VARIANT
57785aa2 24854#define ARM_VARIANT & fpu_vfp_ext_v1
5ee91343
AV
24855#undef THUMB_VARIANT
24856#define THUMB_VARIANT & arm_ext_v6t2
a8465a06
AV
24857 mnCEF(vmla, _vmla, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ_RR), neon_mac_maybe_scalar),
24858 mnCEF(vmul, _vmul, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ_RR), neon_mul),
5ee91343 24859
57785aa2
AV
24860 mcCE(fcpyd, eb00b40, 2, (RVD, RVD), vfp_dp_rd_rm),
24861
24862#undef ARM_VARIANT
24863#define ARM_VARIANT & fpu_vfp_ext_v1xd
24864
24865 MNCE(vmov, 0, 1, (VMOV), neon_mov),
24866 mcCE(fmrs, e100a10, 2, (RR, RVS), vfp_reg_from_sp),
24867 mcCE(fmsr, e000a10, 2, (RVS, RR), vfp_sp_from_reg),
24868 mcCE(fcpys, eb00a40, 2, (RVS, RVS), vfp_sp_monadic),
24869
886e1c73
AV
24870 mCEF(vmullt, _vmullt, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ), mve_vmull),
24871 mnCEF(vadd, _vadd, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
24872 mnCEF(vsub, _vsub, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
5ee91343 24873
485dee97
AV
24874 MNCEF(vabs, 1b10300, 2, (RNSDQMQ, RNSDQMQ), neon_abs_neg),
24875 MNCEF(vneg, 1b10380, 2, (RNSDQMQ, RNSDQMQ), neon_abs_neg),
24876
57785aa2
AV
24877 mCEF(vmovlt, _vmovlt, 1, (VMOV), mve_movl),
24878 mCEF(vmovlb, _vmovlb, 1, (VMOV), mve_movl),
24879
1b883319
AV
24880 mnCE(vcmp, _vcmp, 3, (RVSD_COND, RSVDMQ_FI0, oRMQRZ), vfp_nsyn_cmp),
24881 mnCE(vcmpe, _vcmpe, 3, (RVSD_COND, RSVDMQ_FI0, oRMQRZ), vfp_nsyn_cmp),
24882
57785aa2
AV
24883#undef ARM_VARIANT
24884#define ARM_VARIANT & fpu_vfp_ext_v2
24885
24886 mcCE(fmsrr, c400a10, 3, (VRSLST, RR, RR), vfp_sp2_from_reg2),
24887 mcCE(fmrrs, c500a10, 3, (RR, RR, VRSLST), vfp_reg2_from_sp2),
24888 mcCE(fmdrr, c400b10, 3, (RVD, RR, RR), vfp_dp_rm_rd_rn),
24889 mcCE(fmrrd, c500b10, 3, (RR, RR, RVD), vfp_dp_rd_rn_rm),
24890
dd9634d9
AV
24891#undef ARM_VARIANT
24892#define ARM_VARIANT & fpu_vfp_ext_armv8xd
24893 mnUF(vcvta, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvta),
24894 mnUF(vcvtp, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvtp),
24895 mnUF(vcvtn, _vcvta, 3, (RNSDQMQ, oRNSDQMQ, oI32z), neon_cvtn),
24896 mnUF(vcvtm, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvtm),
935295b5
AV
24897 mnUF(vmaxnm, _vmaxnm, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), vmaxnm),
24898 mnUF(vminnm, _vminnm, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), vmaxnm),
dd9634d9
AV
24899
24900#undef ARM_VARIANT
5ee91343 24901#define ARM_VARIANT & fpu_neon_ext_v1
f601a00c 24902 mnUF(vabd, _vabd, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
5ee91343
AV
24903 mnUF(vabdl, _vabdl, 3, (RNQMQ, RNDMQ, RNDMQ), neon_dyadic_long),
24904 mnUF(vaddl, _vaddl, 3, (RNQMQ, RNDMQ, RNDMQR), neon_dyadic_long),
24905 mnUF(vsubl, _vsubl, 3, (RNQMQ, RNDMQ, RNDMQR), neon_dyadic_long),
f601a00c
AV
24906 mnUF(vand, _vand, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
24907 mnUF(vbic, _vbic, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
24908 mnUF(vorr, _vorr, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
24909 mnUF(vorn, _vorn, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
24910 mnUF(veor, _veor, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_logic),
f30ee27c
AV
24911 MNUF(vcls, 1b00400, 2, (RNDQMQ, RNDQMQ), neon_cls),
24912 MNUF(vclz, 1b00480, 2, (RNDQMQ, RNDQMQ), neon_clz),
b409bdb6 24913 mnCE(vdup, _vdup, 2, (RNDQMQ, RR_RNSC), neon_dup),
7df54120
AV
24914 MNUF(vhadd, 00000000, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i_su),
24915 MNUF(vrhadd, 00000100, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_i_su),
24916 MNUF(vhsub, 00000200, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i_su),
935295b5
AV
24917 mnUF(vmin, _vmin, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
24918 mnUF(vmax, _vmax, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
a8465a06
AV
24919 MNUF(vqadd, 0000010, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i64_su),
24920 MNUF(vqsub, 0000210, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i64_su),
1a186d29
AV
24921 mnUF(vmvn, _vmvn, 2, (RNDQMQ, RNDQMQ_Ibig), neon_mvn),
24922 MNUF(vqabs, 1b00700, 2, (RNDQMQ, RNDQMQ), neon_sat_abs_neg),
24923 MNUF(vqneg, 1b00780, 2, (RNDQMQ, RNDQMQ), neon_sat_abs_neg),
42b16635
AV
24924 mnUF(vqrdmlah, _vqrdmlah,3, (RNDQMQ, oRNDQMQ, RNDQ_RNSC_RR), neon_qrdmlah),
24925 mnUF(vqdmulh, _vqdmulh, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_RNSC_RR), neon_qdmulh),
24926 mnUF(vqrdmulh, _vqrdmulh,3, (RNDQMQ, oRNDQMQ, RNDQMQ_RNSC_RR), neon_qdmulh),
5d281bf0
AV
24927
24928#undef ARM_VARIANT
24929#define ARM_VARIANT & arm_ext_v8_3
24930#undef THUMB_VARIANT
24931#define THUMB_VARIANT & arm_ext_v6t2_v8m
24932 MNUF (vcadd, 0, 4, (RNDQMQ, RNDQMQ, RNDQMQ, EXPi), vcadd),
24933 MNUF (vcmla, 0, 4, (RNDQMQ, RNDQMQ, RNDQMQ_RNSC, EXPi), vcmla),
c19d1205
ZW
24934};
24935#undef ARM_VARIANT
24936#undef THUMB_VARIANT
24937#undef TCE
c19d1205
ZW
24938#undef TUE
24939#undef TUF
24940#undef TCC
8f06b2d8 24941#undef cCE
e3cb604e
PB
24942#undef cCL
24943#undef C3E
4389b29a 24944#undef C3
c19d1205
ZW
24945#undef CE
24946#undef CM
4389b29a 24947#undef CL
c19d1205
ZW
24948#undef UE
24949#undef UF
24950#undef UT
5287ad62
JB
24951#undef NUF
24952#undef nUF
24953#undef NCE
24954#undef nCE
c19d1205
ZW
24955#undef OPS0
24956#undef OPS1
24957#undef OPS2
24958#undef OPS3
24959#undef OPS4
24960#undef OPS5
24961#undef OPS6
24962#undef do_0
4389b29a
AV
24963#undef ToC
24964#undef toC
24965#undef ToU
f6b2b12d 24966#undef toU
c19d1205
ZW
24967\f
24968/* MD interface: bits in the object file. */
bfae80f2 24969
c19d1205
ZW
24970/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
24971 for use in the a.out file, and stores them in the array pointed to by buf.
24972 This knows about the endian-ness of the target machine and does
24973 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
24974 2 (short) and 4 (long) Floating numbers are put out as a series of
24975 LITTLENUMS (shorts, here at least). */
b99bd4ef 24976
c19d1205
ZW
24977void
24978md_number_to_chars (char * buf, valueT val, int n)
24979{
24980 if (target_big_endian)
24981 number_to_chars_bigendian (buf, val, n);
24982 else
24983 number_to_chars_littleendian (buf, val, n);
bfae80f2
RE
24984}
24985
c19d1205
ZW
24986static valueT
24987md_chars_to_number (char * buf, int n)
bfae80f2 24988{
c19d1205
ZW
24989 valueT result = 0;
24990 unsigned char * where = (unsigned char *) buf;
bfae80f2 24991
c19d1205 24992 if (target_big_endian)
b99bd4ef 24993 {
c19d1205
ZW
24994 while (n--)
24995 {
24996 result <<= 8;
24997 result |= (*where++ & 255);
24998 }
b99bd4ef 24999 }
c19d1205 25000 else
b99bd4ef 25001 {
c19d1205
ZW
25002 while (n--)
25003 {
25004 result <<= 8;
25005 result |= (where[n] & 255);
25006 }
bfae80f2 25007 }
b99bd4ef 25008
c19d1205 25009 return result;
bfae80f2 25010}
b99bd4ef 25011
c19d1205 25012/* MD interface: Sections. */
b99bd4ef 25013
fa94de6b
RM
25014/* Calculate the maximum variable size (i.e., excluding fr_fix)
25015 that an rs_machine_dependent frag may reach. */
25016
25017unsigned int
25018arm_frag_max_var (fragS *fragp)
25019{
25020 /* We only use rs_machine_dependent for variable-size Thumb instructions,
25021 which are either THUMB_SIZE (2) or INSN_SIZE (4).
25022
25023 Note that we generate relaxable instructions even for cases that don't
25024 really need it, like an immediate that's a trivial constant. So we're
25025 overestimating the instruction size for some of those cases. Rather
25026 than putting more intelligence here, it would probably be better to
25027 avoid generating a relaxation frag in the first place when it can be
25028 determined up front that a short instruction will suffice. */
25029
25030 gas_assert (fragp->fr_type == rs_machine_dependent);
25031 return INSN_SIZE;
25032}
25033
0110f2b8
PB
25034/* Estimate the size of a frag before relaxing. Assume everything fits in
25035 2 bytes. */
25036
c19d1205 25037int
0110f2b8 25038md_estimate_size_before_relax (fragS * fragp,
c19d1205
ZW
25039 segT segtype ATTRIBUTE_UNUSED)
25040{
0110f2b8
PB
25041 fragp->fr_var = 2;
25042 return 2;
25043}
25044
25045/* Convert a machine dependent frag. */
25046
25047void
25048md_convert_frag (bfd *abfd, segT asec ATTRIBUTE_UNUSED, fragS *fragp)
25049{
25050 unsigned long insn;
25051 unsigned long old_op;
25052 char *buf;
25053 expressionS exp;
25054 fixS *fixp;
25055 int reloc_type;
25056 int pc_rel;
25057 int opcode;
25058
25059 buf = fragp->fr_literal + fragp->fr_fix;
25060
25061 old_op = bfd_get_16(abfd, buf);
5f4273c7
NC
25062 if (fragp->fr_symbol)
25063 {
0110f2b8
PB
25064 exp.X_op = O_symbol;
25065 exp.X_add_symbol = fragp->fr_symbol;
5f4273c7
NC
25066 }
25067 else
25068 {
0110f2b8 25069 exp.X_op = O_constant;
5f4273c7 25070 }
0110f2b8
PB
25071 exp.X_add_number = fragp->fr_offset;
25072 opcode = fragp->fr_subtype;
25073 switch (opcode)
25074 {
25075 case T_MNEM_ldr_pc:
25076 case T_MNEM_ldr_pc2:
25077 case T_MNEM_ldr_sp:
25078 case T_MNEM_str_sp:
25079 case T_MNEM_ldr:
25080 case T_MNEM_ldrb:
25081 case T_MNEM_ldrh:
25082 case T_MNEM_str:
25083 case T_MNEM_strb:
25084 case T_MNEM_strh:
25085 if (fragp->fr_var == 4)
25086 {
5f4273c7 25087 insn = THUMB_OP32 (opcode);
0110f2b8
PB
25088 if ((old_op >> 12) == 4 || (old_op >> 12) == 9)
25089 {
25090 insn |= (old_op & 0x700) << 4;
25091 }
25092 else
25093 {
25094 insn |= (old_op & 7) << 12;
25095 insn |= (old_op & 0x38) << 13;
25096 }
25097 insn |= 0x00000c00;
25098 put_thumb32_insn (buf, insn);
25099 reloc_type = BFD_RELOC_ARM_T32_OFFSET_IMM;
25100 }
25101 else
25102 {
25103 reloc_type = BFD_RELOC_ARM_THUMB_OFFSET;
25104 }
25105 pc_rel = (opcode == T_MNEM_ldr_pc2);
25106 break;
25107 case T_MNEM_adr:
25108 if (fragp->fr_var == 4)
25109 {
25110 insn = THUMB_OP32 (opcode);
25111 insn |= (old_op & 0xf0) << 4;
25112 put_thumb32_insn (buf, insn);
25113 reloc_type = BFD_RELOC_ARM_T32_ADD_PC12;
25114 }
25115 else
25116 {
25117 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
25118 exp.X_add_number -= 4;
25119 }
25120 pc_rel = 1;
25121 break;
25122 case T_MNEM_mov:
25123 case T_MNEM_movs:
25124 case T_MNEM_cmp:
25125 case T_MNEM_cmn:
25126 if (fragp->fr_var == 4)
25127 {
25128 int r0off = (opcode == T_MNEM_mov
25129 || opcode == T_MNEM_movs) ? 0 : 8;
25130 insn = THUMB_OP32 (opcode);
25131 insn = (insn & 0xe1ffffff) | 0x10000000;
25132 insn |= (old_op & 0x700) << r0off;
25133 put_thumb32_insn (buf, insn);
25134 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
25135 }
25136 else
25137 {
25138 reloc_type = BFD_RELOC_ARM_THUMB_IMM;
25139 }
25140 pc_rel = 0;
25141 break;
25142 case T_MNEM_b:
25143 if (fragp->fr_var == 4)
25144 {
25145 insn = THUMB_OP32(opcode);
25146 put_thumb32_insn (buf, insn);
25147 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH25;
25148 }
25149 else
25150 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH12;
25151 pc_rel = 1;
25152 break;
25153 case T_MNEM_bcond:
25154 if (fragp->fr_var == 4)
25155 {
25156 insn = THUMB_OP32(opcode);
25157 insn |= (old_op & 0xf00) << 14;
25158 put_thumb32_insn (buf, insn);
25159 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH20;
25160 }
25161 else
25162 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH9;
25163 pc_rel = 1;
25164 break;
25165 case T_MNEM_add_sp:
25166 case T_MNEM_add_pc:
25167 case T_MNEM_inc_sp:
25168 case T_MNEM_dec_sp:
25169 if (fragp->fr_var == 4)
25170 {
25171 /* ??? Choose between add and addw. */
25172 insn = THUMB_OP32 (opcode);
25173 insn |= (old_op & 0xf0) << 4;
25174 put_thumb32_insn (buf, insn);
16805f35
PB
25175 if (opcode == T_MNEM_add_pc)
25176 reloc_type = BFD_RELOC_ARM_T32_IMM12;
25177 else
25178 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
0110f2b8
PB
25179 }
25180 else
25181 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
25182 pc_rel = 0;
25183 break;
25184
25185 case T_MNEM_addi:
25186 case T_MNEM_addis:
25187 case T_MNEM_subi:
25188 case T_MNEM_subis:
25189 if (fragp->fr_var == 4)
25190 {
25191 insn = THUMB_OP32 (opcode);
25192 insn |= (old_op & 0xf0) << 4;
25193 insn |= (old_op & 0xf) << 16;
25194 put_thumb32_insn (buf, insn);
16805f35
PB
25195 if (insn & (1 << 20))
25196 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
25197 else
25198 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8
PB
25199 }
25200 else
25201 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
25202 pc_rel = 0;
25203 break;
25204 default:
5f4273c7 25205 abort ();
0110f2b8
PB
25206 }
25207 fixp = fix_new_exp (fragp, fragp->fr_fix, fragp->fr_var, &exp, pc_rel,
21d799b5 25208 (enum bfd_reloc_code_real) reloc_type);
0110f2b8
PB
25209 fixp->fx_file = fragp->fr_file;
25210 fixp->fx_line = fragp->fr_line;
25211 fragp->fr_fix += fragp->fr_var;
3cfdb781
TG
25212
25213 /* Set whether we use thumb-2 ISA based on final relaxation results. */
25214 if (thumb_mode && fragp->fr_var == 4 && no_cpu_selected ()
25215 && !ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_t2))
25216 ARM_MERGE_FEATURE_SETS (arm_arch_used, thumb_arch_used, arm_ext_v6t2);
0110f2b8
PB
25217}
25218
25219/* Return the size of a relaxable immediate operand instruction.
25220 SHIFT and SIZE specify the form of the allowable immediate. */
25221static int
25222relax_immediate (fragS *fragp, int size, int shift)
25223{
25224 offsetT offset;
25225 offsetT mask;
25226 offsetT low;
25227
25228 /* ??? Should be able to do better than this. */
25229 if (fragp->fr_symbol)
25230 return 4;
25231
25232 low = (1 << shift) - 1;
25233 mask = (1 << (shift + size)) - (1 << shift);
25234 offset = fragp->fr_offset;
25235 /* Force misaligned offsets to 32-bit variant. */
25236 if (offset & low)
5e77afaa 25237 return 4;
0110f2b8
PB
25238 if (offset & ~mask)
25239 return 4;
25240 return 2;
25241}
25242
5e77afaa
PB
25243/* Get the address of a symbol during relaxation. */
25244static addressT
5f4273c7 25245relaxed_symbol_addr (fragS *fragp, long stretch)
5e77afaa
PB
25246{
25247 fragS *sym_frag;
25248 addressT addr;
25249 symbolS *sym;
25250
25251 sym = fragp->fr_symbol;
25252 sym_frag = symbol_get_frag (sym);
25253 know (S_GET_SEGMENT (sym) != absolute_section
25254 || sym_frag == &zero_address_frag);
25255 addr = S_GET_VALUE (sym) + fragp->fr_offset;
25256
25257 /* If frag has yet to be reached on this pass, assume it will
25258 move by STRETCH just as we did. If this is not so, it will
25259 be because some frag between grows, and that will force
25260 another pass. */
25261
25262 if (stretch != 0
25263 && sym_frag->relax_marker != fragp->relax_marker)
4396b686
PB
25264 {
25265 fragS *f;
25266
25267 /* Adjust stretch for any alignment frag. Note that if have
25268 been expanding the earlier code, the symbol may be
25269 defined in what appears to be an earlier frag. FIXME:
25270 This doesn't handle the fr_subtype field, which specifies
25271 a maximum number of bytes to skip when doing an
25272 alignment. */
25273 for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next)
25274 {
25275 if (f->fr_type == rs_align || f->fr_type == rs_align_code)
25276 {
25277 if (stretch < 0)
25278 stretch = - ((- stretch)
25279 & ~ ((1 << (int) f->fr_offset) - 1));
25280 else
25281 stretch &= ~ ((1 << (int) f->fr_offset) - 1);
25282 if (stretch == 0)
25283 break;
25284 }
25285 }
25286 if (f != NULL)
25287 addr += stretch;
25288 }
5e77afaa
PB
25289
25290 return addr;
25291}
25292
0110f2b8
PB
25293/* Return the size of a relaxable adr pseudo-instruction or PC-relative
25294 load. */
25295static int
5e77afaa 25296relax_adr (fragS *fragp, asection *sec, long stretch)
0110f2b8
PB
25297{
25298 addressT addr;
25299 offsetT val;
25300
25301 /* Assume worst case for symbols not known to be in the same section. */
974da60d
NC
25302 if (fragp->fr_symbol == NULL
25303 || !S_IS_DEFINED (fragp->fr_symbol)
77db8e2e
NC
25304 || sec != S_GET_SEGMENT (fragp->fr_symbol)
25305 || S_IS_WEAK (fragp->fr_symbol))
0110f2b8
PB
25306 return 4;
25307
5f4273c7 25308 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
25309 addr = fragp->fr_address + fragp->fr_fix;
25310 addr = (addr + 4) & ~3;
5e77afaa 25311 /* Force misaligned targets to 32-bit variant. */
0110f2b8 25312 if (val & 3)
5e77afaa 25313 return 4;
0110f2b8
PB
25314 val -= addr;
25315 if (val < 0 || val > 1020)
25316 return 4;
25317 return 2;
25318}
25319
25320/* Return the size of a relaxable add/sub immediate instruction. */
25321static int
25322relax_addsub (fragS *fragp, asection *sec)
25323{
25324 char *buf;
25325 int op;
25326
25327 buf = fragp->fr_literal + fragp->fr_fix;
25328 op = bfd_get_16(sec->owner, buf);
25329 if ((op & 0xf) == ((op >> 4) & 0xf))
25330 return relax_immediate (fragp, 8, 0);
25331 else
25332 return relax_immediate (fragp, 3, 0);
25333}
25334
e83a675f
RE
25335/* Return TRUE iff the definition of symbol S could be pre-empted
25336 (overridden) at link or load time. */
25337static bfd_boolean
25338symbol_preemptible (symbolS *s)
25339{
25340 /* Weak symbols can always be pre-empted. */
25341 if (S_IS_WEAK (s))
25342 return TRUE;
25343
25344 /* Non-global symbols cannot be pre-empted. */
25345 if (! S_IS_EXTERNAL (s))
25346 return FALSE;
25347
25348#ifdef OBJ_ELF
25349 /* In ELF, a global symbol can be marked protected, or private. In that
25350 case it can't be pre-empted (other definitions in the same link unit
25351 would violate the ODR). */
25352 if (ELF_ST_VISIBILITY (S_GET_OTHER (s)) > STV_DEFAULT)
25353 return FALSE;
25354#endif
25355
25356 /* Other global symbols might be pre-empted. */
25357 return TRUE;
25358}
0110f2b8
PB
25359
25360/* Return the size of a relaxable branch instruction. BITS is the
25361 size of the offset field in the narrow instruction. */
25362
25363static int
5e77afaa 25364relax_branch (fragS *fragp, asection *sec, int bits, long stretch)
0110f2b8
PB
25365{
25366 addressT addr;
25367 offsetT val;
25368 offsetT limit;
25369
25370 /* Assume worst case for symbols not known to be in the same section. */
5f4273c7 25371 if (!S_IS_DEFINED (fragp->fr_symbol)
77db8e2e
NC
25372 || sec != S_GET_SEGMENT (fragp->fr_symbol)
25373 || S_IS_WEAK (fragp->fr_symbol))
0110f2b8
PB
25374 return 4;
25375
267bf995 25376#ifdef OBJ_ELF
e83a675f 25377 /* A branch to a function in ARM state will require interworking. */
267bf995
RR
25378 if (S_IS_DEFINED (fragp->fr_symbol)
25379 && ARM_IS_FUNC (fragp->fr_symbol))
25380 return 4;
e83a675f 25381#endif
0d9b4b55 25382
e83a675f 25383 if (symbol_preemptible (fragp->fr_symbol))
0d9b4b55 25384 return 4;
267bf995 25385
5f4273c7 25386 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
25387 addr = fragp->fr_address + fragp->fr_fix + 4;
25388 val -= addr;
25389
25390 /* Offset is a signed value *2 */
25391 limit = 1 << bits;
25392 if (val >= limit || val < -limit)
25393 return 4;
25394 return 2;
25395}
25396
25397
25398/* Relax a machine dependent frag. This returns the amount by which
25399 the current size of the frag should change. */
25400
25401int
5e77afaa 25402arm_relax_frag (asection *sec, fragS *fragp, long stretch)
0110f2b8
PB
25403{
25404 int oldsize;
25405 int newsize;
25406
25407 oldsize = fragp->fr_var;
25408 switch (fragp->fr_subtype)
25409 {
25410 case T_MNEM_ldr_pc2:
5f4273c7 25411 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
25412 break;
25413 case T_MNEM_ldr_pc:
25414 case T_MNEM_ldr_sp:
25415 case T_MNEM_str_sp:
5f4273c7 25416 newsize = relax_immediate (fragp, 8, 2);
0110f2b8
PB
25417 break;
25418 case T_MNEM_ldr:
25419 case T_MNEM_str:
5f4273c7 25420 newsize = relax_immediate (fragp, 5, 2);
0110f2b8
PB
25421 break;
25422 case T_MNEM_ldrh:
25423 case T_MNEM_strh:
5f4273c7 25424 newsize = relax_immediate (fragp, 5, 1);
0110f2b8
PB
25425 break;
25426 case T_MNEM_ldrb:
25427 case T_MNEM_strb:
5f4273c7 25428 newsize = relax_immediate (fragp, 5, 0);
0110f2b8
PB
25429 break;
25430 case T_MNEM_adr:
5f4273c7 25431 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
25432 break;
25433 case T_MNEM_mov:
25434 case T_MNEM_movs:
25435 case T_MNEM_cmp:
25436 case T_MNEM_cmn:
5f4273c7 25437 newsize = relax_immediate (fragp, 8, 0);
0110f2b8
PB
25438 break;
25439 case T_MNEM_b:
5f4273c7 25440 newsize = relax_branch (fragp, sec, 11, stretch);
0110f2b8
PB
25441 break;
25442 case T_MNEM_bcond:
5f4273c7 25443 newsize = relax_branch (fragp, sec, 8, stretch);
0110f2b8
PB
25444 break;
25445 case T_MNEM_add_sp:
25446 case T_MNEM_add_pc:
25447 newsize = relax_immediate (fragp, 8, 2);
25448 break;
25449 case T_MNEM_inc_sp:
25450 case T_MNEM_dec_sp:
25451 newsize = relax_immediate (fragp, 7, 2);
25452 break;
25453 case T_MNEM_addi:
25454 case T_MNEM_addis:
25455 case T_MNEM_subi:
25456 case T_MNEM_subis:
25457 newsize = relax_addsub (fragp, sec);
25458 break;
25459 default:
5f4273c7 25460 abort ();
0110f2b8 25461 }
5e77afaa
PB
25462
25463 fragp->fr_var = newsize;
25464 /* Freeze wide instructions that are at or before the same location as
25465 in the previous pass. This avoids infinite loops.
5f4273c7
NC
25466 Don't freeze them unconditionally because targets may be artificially
25467 misaligned by the expansion of preceding frags. */
5e77afaa 25468 if (stretch <= 0 && newsize > 2)
0110f2b8 25469 {
0110f2b8 25470 md_convert_frag (sec->owner, sec, fragp);
5f4273c7 25471 frag_wane (fragp);
0110f2b8 25472 }
5e77afaa 25473
0110f2b8 25474 return newsize - oldsize;
c19d1205 25475}
b99bd4ef 25476
c19d1205 25477/* Round up a section size to the appropriate boundary. */
b99bd4ef 25478
c19d1205
ZW
25479valueT
25480md_section_align (segT segment ATTRIBUTE_UNUSED,
25481 valueT size)
25482{
6844c0cc 25483 return size;
bfae80f2 25484}
b99bd4ef 25485
c19d1205
ZW
25486/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
25487 of an rs_align_code fragment. */
25488
25489void
25490arm_handle_align (fragS * fragP)
bfae80f2 25491{
d9235011 25492 static unsigned char const arm_noop[2][2][4] =
e7495e45
NS
25493 {
25494 { /* ARMv1 */
25495 {0x00, 0x00, 0xa0, 0xe1}, /* LE */
25496 {0xe1, 0xa0, 0x00, 0x00}, /* BE */
25497 },
25498 { /* ARMv6k */
25499 {0x00, 0xf0, 0x20, 0xe3}, /* LE */
25500 {0xe3, 0x20, 0xf0, 0x00}, /* BE */
25501 },
25502 };
d9235011 25503 static unsigned char const thumb_noop[2][2][2] =
e7495e45
NS
25504 {
25505 { /* Thumb-1 */
25506 {0xc0, 0x46}, /* LE */
25507 {0x46, 0xc0}, /* BE */
25508 },
25509 { /* Thumb-2 */
25510 {0x00, 0xbf}, /* LE */
25511 {0xbf, 0x00} /* BE */
25512 }
25513 };
d9235011 25514 static unsigned char const wide_thumb_noop[2][4] =
e7495e45
NS
25515 { /* Wide Thumb-2 */
25516 {0xaf, 0xf3, 0x00, 0x80}, /* LE */
25517 {0xf3, 0xaf, 0x80, 0x00}, /* BE */
25518 };
c921be7d 25519
e7495e45 25520 unsigned bytes, fix, noop_size;
c19d1205 25521 char * p;
d9235011
TS
25522 const unsigned char * noop;
25523 const unsigned char *narrow_noop = NULL;
cd000bff
DJ
25524#ifdef OBJ_ELF
25525 enum mstate state;
25526#endif
bfae80f2 25527
c19d1205 25528 if (fragP->fr_type != rs_align_code)
bfae80f2
RE
25529 return;
25530
c19d1205
ZW
25531 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
25532 p = fragP->fr_literal + fragP->fr_fix;
25533 fix = 0;
bfae80f2 25534
c19d1205
ZW
25535 if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
25536 bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
bfae80f2 25537
cd000bff 25538 gas_assert ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) != 0);
8dc2430f 25539
cd000bff 25540 if (fragP->tc_frag_data.thumb_mode & (~ MODE_RECORDED))
a737bd4d 25541 {
7f78eb34
JW
25542 if (ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
25543 ? selected_cpu : arm_arch_none, arm_ext_v6t2))
e7495e45
NS
25544 {
25545 narrow_noop = thumb_noop[1][target_big_endian];
25546 noop = wide_thumb_noop[target_big_endian];
25547 }
c19d1205 25548 else
e7495e45
NS
25549 noop = thumb_noop[0][target_big_endian];
25550 noop_size = 2;
cd000bff
DJ
25551#ifdef OBJ_ELF
25552 state = MAP_THUMB;
25553#endif
7ed4c4c5
NC
25554 }
25555 else
25556 {
7f78eb34
JW
25557 noop = arm_noop[ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
25558 ? selected_cpu : arm_arch_none,
25559 arm_ext_v6k) != 0]
e7495e45
NS
25560 [target_big_endian];
25561 noop_size = 4;
cd000bff
DJ
25562#ifdef OBJ_ELF
25563 state = MAP_ARM;
25564#endif
7ed4c4c5 25565 }
c921be7d 25566
e7495e45 25567 fragP->fr_var = noop_size;
c921be7d 25568
c19d1205 25569 if (bytes & (noop_size - 1))
7ed4c4c5 25570 {
c19d1205 25571 fix = bytes & (noop_size - 1);
cd000bff
DJ
25572#ifdef OBJ_ELF
25573 insert_data_mapping_symbol (state, fragP->fr_fix, fragP, fix);
25574#endif
c19d1205
ZW
25575 memset (p, 0, fix);
25576 p += fix;
25577 bytes -= fix;
a737bd4d 25578 }
a737bd4d 25579
e7495e45
NS
25580 if (narrow_noop)
25581 {
25582 if (bytes & noop_size)
25583 {
25584 /* Insert a narrow noop. */
25585 memcpy (p, narrow_noop, noop_size);
25586 p += noop_size;
25587 bytes -= noop_size;
25588 fix += noop_size;
25589 }
25590
25591 /* Use wide noops for the remainder */
25592 noop_size = 4;
25593 }
25594
c19d1205 25595 while (bytes >= noop_size)
a737bd4d 25596 {
c19d1205
ZW
25597 memcpy (p, noop, noop_size);
25598 p += noop_size;
25599 bytes -= noop_size;
25600 fix += noop_size;
a737bd4d
NC
25601 }
25602
c19d1205 25603 fragP->fr_fix += fix;
a737bd4d
NC
25604}
25605
c19d1205
ZW
25606/* Called from md_do_align. Used to create an alignment
25607 frag in a code section. */
25608
25609void
25610arm_frag_align_code (int n, int max)
bfae80f2 25611{
c19d1205 25612 char * p;
7ed4c4c5 25613
c19d1205 25614 /* We assume that there will never be a requirement
6ec8e702 25615 to support alignments greater than MAX_MEM_FOR_RS_ALIGN_CODE bytes. */
c19d1205 25616 if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
6ec8e702
NC
25617 {
25618 char err_msg[128];
25619
fa94de6b 25620 sprintf (err_msg,
477330fc
RM
25621 _("alignments greater than %d bytes not supported in .text sections."),
25622 MAX_MEM_FOR_RS_ALIGN_CODE + 1);
20203fb9 25623 as_fatal ("%s", err_msg);
6ec8e702 25624 }
bfae80f2 25625
c19d1205
ZW
25626 p = frag_var (rs_align_code,
25627 MAX_MEM_FOR_RS_ALIGN_CODE,
25628 1,
25629 (relax_substateT) max,
25630 (symbolS *) NULL,
25631 (offsetT) n,
25632 (char *) NULL);
25633 *p = 0;
25634}
bfae80f2 25635
8dc2430f
NC
25636/* Perform target specific initialisation of a frag.
25637 Note - despite the name this initialisation is not done when the frag
25638 is created, but only when its type is assigned. A frag can be created
25639 and used a long time before its type is set, so beware of assuming that
33eaf5de 25640 this initialisation is performed first. */
bfae80f2 25641
cd000bff
DJ
25642#ifndef OBJ_ELF
25643void
25644arm_init_frag (fragS * fragP, int max_chars ATTRIBUTE_UNUSED)
25645{
25646 /* Record whether this frag is in an ARM or a THUMB area. */
2e98972e 25647 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
cd000bff
DJ
25648}
25649
25650#else /* OBJ_ELF is defined. */
c19d1205 25651void
cd000bff 25652arm_init_frag (fragS * fragP, int max_chars)
c19d1205 25653{
e8d84ca1 25654 bfd_boolean frag_thumb_mode;
b968d18a 25655
8dc2430f
NC
25656 /* If the current ARM vs THUMB mode has not already
25657 been recorded into this frag then do so now. */
cd000bff 25658 if ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) == 0)
b968d18a
JW
25659 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
25660
e8d84ca1
NC
25661 /* PR 21809: Do not set a mapping state for debug sections
25662 - it just confuses other tools. */
25663 if (bfd_get_section_flags (NULL, now_seg) & SEC_DEBUGGING)
25664 return;
25665
b968d18a 25666 frag_thumb_mode = fragP->tc_frag_data.thumb_mode ^ MODE_RECORDED;
cd000bff 25667
f9c1b181
RL
25668 /* Record a mapping symbol for alignment frags. We will delete this
25669 later if the alignment ends up empty. */
25670 switch (fragP->fr_type)
25671 {
25672 case rs_align:
25673 case rs_align_test:
25674 case rs_fill:
25675 mapping_state_2 (MAP_DATA, max_chars);
25676 break;
25677 case rs_align_code:
b968d18a 25678 mapping_state_2 (frag_thumb_mode ? MAP_THUMB : MAP_ARM, max_chars);
f9c1b181
RL
25679 break;
25680 default:
25681 break;
cd000bff 25682 }
bfae80f2
RE
25683}
25684
c19d1205
ZW
25685/* When we change sections we need to issue a new mapping symbol. */
25686
25687void
25688arm_elf_change_section (void)
bfae80f2 25689{
c19d1205
ZW
25690 /* Link an unlinked unwind index table section to the .text section. */
25691 if (elf_section_type (now_seg) == SHT_ARM_EXIDX
25692 && elf_linked_to_section (now_seg) == NULL)
25693 elf_linked_to_section (now_seg) = text_section;
bfae80f2
RE
25694}
25695
c19d1205
ZW
25696int
25697arm_elf_section_type (const char * str, size_t len)
e45d0630 25698{
c19d1205
ZW
25699 if (len == 5 && strncmp (str, "exidx", 5) == 0)
25700 return SHT_ARM_EXIDX;
e45d0630 25701
c19d1205
ZW
25702 return -1;
25703}
25704\f
25705/* Code to deal with unwinding tables. */
e45d0630 25706
c19d1205 25707static void add_unwind_adjustsp (offsetT);
e45d0630 25708
5f4273c7 25709/* Generate any deferred unwind frame offset. */
e45d0630 25710
bfae80f2 25711static void
c19d1205 25712flush_pending_unwind (void)
bfae80f2 25713{
c19d1205 25714 offsetT offset;
bfae80f2 25715
c19d1205
ZW
25716 offset = unwind.pending_offset;
25717 unwind.pending_offset = 0;
25718 if (offset != 0)
25719 add_unwind_adjustsp (offset);
bfae80f2
RE
25720}
25721
c19d1205
ZW
25722/* Add an opcode to this list for this function. Two-byte opcodes should
25723 be passed as op[0] << 8 | op[1]. The list of opcodes is built in reverse
25724 order. */
25725
bfae80f2 25726static void
c19d1205 25727add_unwind_opcode (valueT op, int length)
bfae80f2 25728{
c19d1205
ZW
25729 /* Add any deferred stack adjustment. */
25730 if (unwind.pending_offset)
25731 flush_pending_unwind ();
bfae80f2 25732
c19d1205 25733 unwind.sp_restored = 0;
bfae80f2 25734
c19d1205 25735 if (unwind.opcode_count + length > unwind.opcode_alloc)
bfae80f2 25736 {
c19d1205
ZW
25737 unwind.opcode_alloc += ARM_OPCODE_CHUNK_SIZE;
25738 if (unwind.opcodes)
325801bd
TS
25739 unwind.opcodes = XRESIZEVEC (unsigned char, unwind.opcodes,
25740 unwind.opcode_alloc);
c19d1205 25741 else
325801bd 25742 unwind.opcodes = XNEWVEC (unsigned char, unwind.opcode_alloc);
bfae80f2 25743 }
c19d1205 25744 while (length > 0)
bfae80f2 25745 {
c19d1205
ZW
25746 length--;
25747 unwind.opcodes[unwind.opcode_count] = op & 0xff;
25748 op >>= 8;
25749 unwind.opcode_count++;
bfae80f2 25750 }
bfae80f2
RE
25751}
25752
c19d1205
ZW
25753/* Add unwind opcodes to adjust the stack pointer. */
25754
bfae80f2 25755static void
c19d1205 25756add_unwind_adjustsp (offsetT offset)
bfae80f2 25757{
c19d1205 25758 valueT op;
bfae80f2 25759
c19d1205 25760 if (offset > 0x200)
bfae80f2 25761 {
c19d1205
ZW
25762 /* We need at most 5 bytes to hold a 32-bit value in a uleb128. */
25763 char bytes[5];
25764 int n;
25765 valueT o;
bfae80f2 25766
c19d1205
ZW
25767 /* Long form: 0xb2, uleb128. */
25768 /* This might not fit in a word so add the individual bytes,
25769 remembering the list is built in reverse order. */
25770 o = (valueT) ((offset - 0x204) >> 2);
25771 if (o == 0)
25772 add_unwind_opcode (0, 1);
bfae80f2 25773
c19d1205
ZW
25774 /* Calculate the uleb128 encoding of the offset. */
25775 n = 0;
25776 while (o)
25777 {
25778 bytes[n] = o & 0x7f;
25779 o >>= 7;
25780 if (o)
25781 bytes[n] |= 0x80;
25782 n++;
25783 }
25784 /* Add the insn. */
25785 for (; n; n--)
25786 add_unwind_opcode (bytes[n - 1], 1);
25787 add_unwind_opcode (0xb2, 1);
25788 }
25789 else if (offset > 0x100)
bfae80f2 25790 {
c19d1205
ZW
25791 /* Two short opcodes. */
25792 add_unwind_opcode (0x3f, 1);
25793 op = (offset - 0x104) >> 2;
25794 add_unwind_opcode (op, 1);
bfae80f2 25795 }
c19d1205
ZW
25796 else if (offset > 0)
25797 {
25798 /* Short opcode. */
25799 op = (offset - 4) >> 2;
25800 add_unwind_opcode (op, 1);
25801 }
25802 else if (offset < 0)
bfae80f2 25803 {
c19d1205
ZW
25804 offset = -offset;
25805 while (offset > 0x100)
bfae80f2 25806 {
c19d1205
ZW
25807 add_unwind_opcode (0x7f, 1);
25808 offset -= 0x100;
bfae80f2 25809 }
c19d1205
ZW
25810 op = ((offset - 4) >> 2) | 0x40;
25811 add_unwind_opcode (op, 1);
bfae80f2 25812 }
bfae80f2
RE
25813}
25814
c19d1205 25815/* Finish the list of unwind opcodes for this function. */
0198d5e6 25816
c19d1205
ZW
25817static void
25818finish_unwind_opcodes (void)
bfae80f2 25819{
c19d1205 25820 valueT op;
bfae80f2 25821
c19d1205 25822 if (unwind.fp_used)
bfae80f2 25823 {
708587a4 25824 /* Adjust sp as necessary. */
c19d1205
ZW
25825 unwind.pending_offset += unwind.fp_offset - unwind.frame_size;
25826 flush_pending_unwind ();
bfae80f2 25827
c19d1205
ZW
25828 /* After restoring sp from the frame pointer. */
25829 op = 0x90 | unwind.fp_reg;
25830 add_unwind_opcode (op, 1);
25831 }
25832 else
25833 flush_pending_unwind ();
bfae80f2
RE
25834}
25835
bfae80f2 25836
c19d1205
ZW
25837/* Start an exception table entry. If idx is nonzero this is an index table
25838 entry. */
bfae80f2
RE
25839
25840static void
c19d1205 25841start_unwind_section (const segT text_seg, int idx)
bfae80f2 25842{
c19d1205
ZW
25843 const char * text_name;
25844 const char * prefix;
25845 const char * prefix_once;
25846 const char * group_name;
c19d1205 25847 char * sec_name;
c19d1205
ZW
25848 int type;
25849 int flags;
25850 int linkonce;
bfae80f2 25851
c19d1205 25852 if (idx)
bfae80f2 25853 {
c19d1205
ZW
25854 prefix = ELF_STRING_ARM_unwind;
25855 prefix_once = ELF_STRING_ARM_unwind_once;
25856 type = SHT_ARM_EXIDX;
bfae80f2 25857 }
c19d1205 25858 else
bfae80f2 25859 {
c19d1205
ZW
25860 prefix = ELF_STRING_ARM_unwind_info;
25861 prefix_once = ELF_STRING_ARM_unwind_info_once;
25862 type = SHT_PROGBITS;
bfae80f2
RE
25863 }
25864
c19d1205
ZW
25865 text_name = segment_name (text_seg);
25866 if (streq (text_name, ".text"))
25867 text_name = "";
25868
25869 if (strncmp (text_name, ".gnu.linkonce.t.",
25870 strlen (".gnu.linkonce.t.")) == 0)
bfae80f2 25871 {
c19d1205
ZW
25872 prefix = prefix_once;
25873 text_name += strlen (".gnu.linkonce.t.");
bfae80f2
RE
25874 }
25875
29a2809e 25876 sec_name = concat (prefix, text_name, (char *) NULL);
bfae80f2 25877
c19d1205
ZW
25878 flags = SHF_ALLOC;
25879 linkonce = 0;
25880 group_name = 0;
bfae80f2 25881
c19d1205
ZW
25882 /* Handle COMDAT group. */
25883 if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
bfae80f2 25884 {
c19d1205
ZW
25885 group_name = elf_group_name (text_seg);
25886 if (group_name == NULL)
25887 {
bd3ba5d1 25888 as_bad (_("Group section `%s' has no group signature"),
c19d1205
ZW
25889 segment_name (text_seg));
25890 ignore_rest_of_line ();
25891 return;
25892 }
25893 flags |= SHF_GROUP;
25894 linkonce = 1;
bfae80f2
RE
25895 }
25896
a91e1603
L
25897 obj_elf_change_section (sec_name, type, 0, flags, 0, group_name,
25898 linkonce, 0);
bfae80f2 25899
5f4273c7 25900 /* Set the section link for index tables. */
c19d1205
ZW
25901 if (idx)
25902 elf_linked_to_section (now_seg) = text_seg;
bfae80f2
RE
25903}
25904
bfae80f2 25905
c19d1205
ZW
25906/* Start an unwind table entry. HAVE_DATA is nonzero if we have additional
25907 personality routine data. Returns zero, or the index table value for
cad0da33 25908 an inline entry. */
c19d1205
ZW
25909
25910static valueT
25911create_unwind_entry (int have_data)
bfae80f2 25912{
c19d1205
ZW
25913 int size;
25914 addressT where;
25915 char *ptr;
25916 /* The current word of data. */
25917 valueT data;
25918 /* The number of bytes left in this word. */
25919 int n;
bfae80f2 25920
c19d1205 25921 finish_unwind_opcodes ();
bfae80f2 25922
c19d1205
ZW
25923 /* Remember the current text section. */
25924 unwind.saved_seg = now_seg;
25925 unwind.saved_subseg = now_subseg;
bfae80f2 25926
c19d1205 25927 start_unwind_section (now_seg, 0);
bfae80f2 25928
c19d1205 25929 if (unwind.personality_routine == NULL)
bfae80f2 25930 {
c19d1205
ZW
25931 if (unwind.personality_index == -2)
25932 {
25933 if (have_data)
5f4273c7 25934 as_bad (_("handlerdata in cantunwind frame"));
c19d1205
ZW
25935 return 1; /* EXIDX_CANTUNWIND. */
25936 }
bfae80f2 25937
c19d1205
ZW
25938 /* Use a default personality routine if none is specified. */
25939 if (unwind.personality_index == -1)
25940 {
25941 if (unwind.opcode_count > 3)
25942 unwind.personality_index = 1;
25943 else
25944 unwind.personality_index = 0;
25945 }
bfae80f2 25946
c19d1205
ZW
25947 /* Space for the personality routine entry. */
25948 if (unwind.personality_index == 0)
25949 {
25950 if (unwind.opcode_count > 3)
25951 as_bad (_("too many unwind opcodes for personality routine 0"));
bfae80f2 25952
c19d1205
ZW
25953 if (!have_data)
25954 {
25955 /* All the data is inline in the index table. */
25956 data = 0x80;
25957 n = 3;
25958 while (unwind.opcode_count > 0)
25959 {
25960 unwind.opcode_count--;
25961 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
25962 n--;
25963 }
bfae80f2 25964
c19d1205
ZW
25965 /* Pad with "finish" opcodes. */
25966 while (n--)
25967 data = (data << 8) | 0xb0;
bfae80f2 25968
c19d1205
ZW
25969 return data;
25970 }
25971 size = 0;
25972 }
25973 else
25974 /* We get two opcodes "free" in the first word. */
25975 size = unwind.opcode_count - 2;
25976 }
25977 else
5011093d 25978 {
cad0da33
NC
25979 /* PR 16765: Missing or misplaced unwind directives can trigger this. */
25980 if (unwind.personality_index != -1)
25981 {
25982 as_bad (_("attempt to recreate an unwind entry"));
25983 return 1;
25984 }
5011093d
NC
25985
25986 /* An extra byte is required for the opcode count. */
25987 size = unwind.opcode_count + 1;
25988 }
bfae80f2 25989
c19d1205
ZW
25990 size = (size + 3) >> 2;
25991 if (size > 0xff)
25992 as_bad (_("too many unwind opcodes"));
bfae80f2 25993
c19d1205
ZW
25994 frag_align (2, 0, 0);
25995 record_alignment (now_seg, 2);
25996 unwind.table_entry = expr_build_dot ();
25997
25998 /* Allocate the table entry. */
25999 ptr = frag_more ((size << 2) + 4);
74929e7b
NC
26000 /* PR 13449: Zero the table entries in case some of them are not used. */
26001 memset (ptr, 0, (size << 2) + 4);
c19d1205 26002 where = frag_now_fix () - ((size << 2) + 4);
bfae80f2 26003
c19d1205 26004 switch (unwind.personality_index)
bfae80f2 26005 {
c19d1205
ZW
26006 case -1:
26007 /* ??? Should this be a PLT generating relocation? */
26008 /* Custom personality routine. */
26009 fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1,
26010 BFD_RELOC_ARM_PREL31);
bfae80f2 26011
c19d1205
ZW
26012 where += 4;
26013 ptr += 4;
bfae80f2 26014
c19d1205 26015 /* Set the first byte to the number of additional words. */
5011093d 26016 data = size > 0 ? size - 1 : 0;
c19d1205
ZW
26017 n = 3;
26018 break;
bfae80f2 26019
c19d1205
ZW
26020 /* ABI defined personality routines. */
26021 case 0:
26022 /* Three opcodes bytes are packed into the first word. */
26023 data = 0x80;
26024 n = 3;
26025 break;
bfae80f2 26026
c19d1205
ZW
26027 case 1:
26028 case 2:
26029 /* The size and first two opcode bytes go in the first word. */
26030 data = ((0x80 + unwind.personality_index) << 8) | size;
26031 n = 2;
26032 break;
bfae80f2 26033
c19d1205
ZW
26034 default:
26035 /* Should never happen. */
26036 abort ();
26037 }
bfae80f2 26038
c19d1205
ZW
26039 /* Pack the opcodes into words (MSB first), reversing the list at the same
26040 time. */
26041 while (unwind.opcode_count > 0)
26042 {
26043 if (n == 0)
26044 {
26045 md_number_to_chars (ptr, data, 4);
26046 ptr += 4;
26047 n = 4;
26048 data = 0;
26049 }
26050 unwind.opcode_count--;
26051 n--;
26052 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
26053 }
26054
26055 /* Finish off the last word. */
26056 if (n < 4)
26057 {
26058 /* Pad with "finish" opcodes. */
26059 while (n--)
26060 data = (data << 8) | 0xb0;
26061
26062 md_number_to_chars (ptr, data, 4);
26063 }
26064
26065 if (!have_data)
26066 {
26067 /* Add an empty descriptor if there is no user-specified data. */
26068 ptr = frag_more (4);
26069 md_number_to_chars (ptr, 0, 4);
26070 }
26071
26072 return 0;
bfae80f2
RE
26073}
26074
f0927246
NC
26075
26076/* Initialize the DWARF-2 unwind information for this procedure. */
26077
26078void
26079tc_arm_frame_initial_instructions (void)
26080{
26081 cfi_add_CFA_def_cfa (REG_SP, 0);
26082}
26083#endif /* OBJ_ELF */
26084
c19d1205
ZW
26085/* Convert REGNAME to a DWARF-2 register number. */
26086
26087int
1df69f4f 26088tc_arm_regname_to_dw2regnum (char *regname)
bfae80f2 26089{
1df69f4f 26090 int reg = arm_reg_parse (&regname, REG_TYPE_RN);
1f5afe1c
NC
26091 if (reg != FAIL)
26092 return reg;
c19d1205 26093
1f5afe1c
NC
26094 /* PR 16694: Allow VFP registers as well. */
26095 reg = arm_reg_parse (&regname, REG_TYPE_VFS);
26096 if (reg != FAIL)
26097 return 64 + reg;
c19d1205 26098
1f5afe1c
NC
26099 reg = arm_reg_parse (&regname, REG_TYPE_VFD);
26100 if (reg != FAIL)
26101 return reg + 256;
26102
0198d5e6 26103 return FAIL;
bfae80f2
RE
26104}
26105
f0927246 26106#ifdef TE_PE
c19d1205 26107void
f0927246 26108tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
bfae80f2 26109{
91d6fa6a 26110 expressionS exp;
bfae80f2 26111
91d6fa6a
NC
26112 exp.X_op = O_secrel;
26113 exp.X_add_symbol = symbol;
26114 exp.X_add_number = 0;
26115 emit_expr (&exp, size);
f0927246
NC
26116}
26117#endif
bfae80f2 26118
c19d1205 26119/* MD interface: Symbol and relocation handling. */
bfae80f2 26120
2fc8bdac
ZW
26121/* Return the address within the segment that a PC-relative fixup is
26122 relative to. For ARM, PC-relative fixups applied to instructions
26123 are generally relative to the location of the fixup plus 8 bytes.
26124 Thumb branches are offset by 4, and Thumb loads relative to PC
26125 require special handling. */
bfae80f2 26126
c19d1205 26127long
2fc8bdac 26128md_pcrel_from_section (fixS * fixP, segT seg)
bfae80f2 26129{
2fc8bdac
ZW
26130 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
26131
26132 /* If this is pc-relative and we are going to emit a relocation
26133 then we just want to put out any pipeline compensation that the linker
53baae48
NC
26134 will need. Otherwise we want to use the calculated base.
26135 For WinCE we skip the bias for externals as well, since this
26136 is how the MS ARM-CE assembler behaves and we want to be compatible. */
5f4273c7 26137 if (fixP->fx_pcrel
2fc8bdac 26138 && ((fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != seg)
53baae48
NC
26139 || (arm_force_relocation (fixP)
26140#ifdef TE_WINCE
26141 && !S_IS_EXTERNAL (fixP->fx_addsy)
26142#endif
26143 )))
2fc8bdac 26144 base = 0;
bfae80f2 26145
267bf995 26146
c19d1205 26147 switch (fixP->fx_r_type)
bfae80f2 26148 {
2fc8bdac
ZW
26149 /* PC relative addressing on the Thumb is slightly odd as the
26150 bottom two bits of the PC are forced to zero for the
26151 calculation. This happens *after* application of the
26152 pipeline offset. However, Thumb adrl already adjusts for
26153 this, so we need not do it again. */
c19d1205 26154 case BFD_RELOC_ARM_THUMB_ADD:
2fc8bdac 26155 return base & ~3;
c19d1205
ZW
26156
26157 case BFD_RELOC_ARM_THUMB_OFFSET:
26158 case BFD_RELOC_ARM_T32_OFFSET_IMM:
e9f89963 26159 case BFD_RELOC_ARM_T32_ADD_PC12:
8f06b2d8 26160 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
2fc8bdac 26161 return (base + 4) & ~3;
c19d1205 26162
2fc8bdac 26163 /* Thumb branches are simply offset by +4. */
e12437dc 26164 case BFD_RELOC_THUMB_PCREL_BRANCH5:
2fc8bdac
ZW
26165 case BFD_RELOC_THUMB_PCREL_BRANCH7:
26166 case BFD_RELOC_THUMB_PCREL_BRANCH9:
26167 case BFD_RELOC_THUMB_PCREL_BRANCH12:
26168 case BFD_RELOC_THUMB_PCREL_BRANCH20:
2fc8bdac 26169 case BFD_RELOC_THUMB_PCREL_BRANCH25:
f6b2b12d 26170 case BFD_RELOC_THUMB_PCREL_BFCSEL:
e5d6e09e 26171 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 26172 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 26173 case BFD_RELOC_ARM_THUMB_BF13:
60f993ce 26174 case BFD_RELOC_ARM_THUMB_LOOP12:
2fc8bdac 26175 return base + 4;
bfae80f2 26176
267bf995 26177 case BFD_RELOC_THUMB_PCREL_BRANCH23:
486499d0
CL
26178 if (fixP->fx_addsy
26179 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 26180 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995 26181 && ARM_IS_FUNC (fixP->fx_addsy)
477330fc
RM
26182 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
26183 base = fixP->fx_where + fixP->fx_frag->fr_address;
267bf995
RR
26184 return base + 4;
26185
00adf2d4
JB
26186 /* BLX is like branches above, but forces the low two bits of PC to
26187 zero. */
486499d0
CL
26188 case BFD_RELOC_THUMB_PCREL_BLX:
26189 if (fixP->fx_addsy
26190 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 26191 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
26192 && THUMB_IS_FUNC (fixP->fx_addsy)
26193 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
26194 base = fixP->fx_where + fixP->fx_frag->fr_address;
00adf2d4
JB
26195 return (base + 4) & ~3;
26196
2fc8bdac
ZW
26197 /* ARM mode branches are offset by +8. However, the Windows CE
26198 loader expects the relocation not to take this into account. */
267bf995 26199 case BFD_RELOC_ARM_PCREL_BLX:
486499d0
CL
26200 if (fixP->fx_addsy
26201 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 26202 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
26203 && ARM_IS_FUNC (fixP->fx_addsy)
26204 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
26205 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 26206 return base + 8;
267bf995 26207
486499d0
CL
26208 case BFD_RELOC_ARM_PCREL_CALL:
26209 if (fixP->fx_addsy
26210 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 26211 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
26212 && THUMB_IS_FUNC (fixP->fx_addsy)
26213 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
26214 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 26215 return base + 8;
267bf995 26216
2fc8bdac 26217 case BFD_RELOC_ARM_PCREL_BRANCH:
39b41c9c 26218 case BFD_RELOC_ARM_PCREL_JUMP:
2fc8bdac 26219 case BFD_RELOC_ARM_PLT32:
c19d1205 26220#ifdef TE_WINCE
5f4273c7 26221 /* When handling fixups immediately, because we have already
477330fc 26222 discovered the value of a symbol, or the address of the frag involved
53baae48 26223 we must account for the offset by +8, as the OS loader will never see the reloc.
477330fc
RM
26224 see fixup_segment() in write.c
26225 The S_IS_EXTERNAL test handles the case of global symbols.
26226 Those need the calculated base, not just the pipe compensation the linker will need. */
53baae48
NC
26227 if (fixP->fx_pcrel
26228 && fixP->fx_addsy != NULL
26229 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
26230 && (S_IS_EXTERNAL (fixP->fx_addsy) || !arm_force_relocation (fixP)))
26231 return base + 8;
2fc8bdac 26232 return base;
c19d1205 26233#else
2fc8bdac 26234 return base + 8;
c19d1205 26235#endif
2fc8bdac 26236
267bf995 26237
2fc8bdac
ZW
26238 /* ARM mode loads relative to PC are also offset by +8. Unlike
26239 branches, the Windows CE loader *does* expect the relocation
26240 to take this into account. */
26241 case BFD_RELOC_ARM_OFFSET_IMM:
26242 case BFD_RELOC_ARM_OFFSET_IMM8:
26243 case BFD_RELOC_ARM_HWLITERAL:
26244 case BFD_RELOC_ARM_LITERAL:
26245 case BFD_RELOC_ARM_CP_OFF_IMM:
26246 return base + 8;
26247
26248
26249 /* Other PC-relative relocations are un-offset. */
26250 default:
26251 return base;
26252 }
bfae80f2
RE
26253}
26254
8b2d793c
NC
26255static bfd_boolean flag_warn_syms = TRUE;
26256
ae8714c2
NC
26257bfd_boolean
26258arm_tc_equal_in_insn (int c ATTRIBUTE_UNUSED, char * name)
bfae80f2 26259{
8b2d793c
NC
26260 /* PR 18347 - Warn if the user attempts to create a symbol with the same
26261 name as an ARM instruction. Whilst strictly speaking it is allowed, it
26262 does mean that the resulting code might be very confusing to the reader.
26263 Also this warning can be triggered if the user omits an operand before
26264 an immediate address, eg:
26265
26266 LDR =foo
26267
26268 GAS treats this as an assignment of the value of the symbol foo to a
26269 symbol LDR, and so (without this code) it will not issue any kind of
26270 warning or error message.
26271
26272 Note - ARM instructions are case-insensitive but the strings in the hash
26273 table are all stored in lower case, so we must first ensure that name is
ae8714c2
NC
26274 lower case too. */
26275 if (flag_warn_syms && arm_ops_hsh)
8b2d793c
NC
26276 {
26277 char * nbuf = strdup (name);
26278 char * p;
26279
26280 for (p = nbuf; *p; p++)
26281 *p = TOLOWER (*p);
26282 if (hash_find (arm_ops_hsh, nbuf) != NULL)
26283 {
26284 static struct hash_control * already_warned = NULL;
26285
26286 if (already_warned == NULL)
26287 already_warned = hash_new ();
26288 /* Only warn about the symbol once. To keep the code
26289 simple we let hash_insert do the lookup for us. */
3076e594 26290 if (hash_insert (already_warned, nbuf, NULL) == NULL)
ae8714c2 26291 as_warn (_("[-mwarn-syms]: Assignment makes a symbol match an ARM instruction: %s"), name);
8b2d793c
NC
26292 }
26293 else
26294 free (nbuf);
26295 }
3739860c 26296
ae8714c2
NC
26297 return FALSE;
26298}
26299
26300/* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
26301 Otherwise we have no need to default values of symbols. */
26302
26303symbolS *
26304md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
26305{
26306#ifdef OBJ_ELF
26307 if (name[0] == '_' && name[1] == 'G'
26308 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
26309 {
26310 if (!GOT_symbol)
26311 {
26312 if (symbol_find (name))
26313 as_bad (_("GOT already in the symbol table"));
26314
26315 GOT_symbol = symbol_new (name, undefined_section,
26316 (valueT) 0, & zero_address_frag);
26317 }
26318
26319 return GOT_symbol;
26320 }
26321#endif
26322
c921be7d 26323 return NULL;
bfae80f2
RE
26324}
26325
55cf6793 26326/* Subroutine of md_apply_fix. Check to see if an immediate can be
c19d1205
ZW
26327 computed as two separate immediate values, added together. We
26328 already know that this value cannot be computed by just one ARM
26329 instruction. */
26330
26331static unsigned int
26332validate_immediate_twopart (unsigned int val,
26333 unsigned int * highpart)
bfae80f2 26334{
c19d1205
ZW
26335 unsigned int a;
26336 unsigned int i;
bfae80f2 26337
c19d1205
ZW
26338 for (i = 0; i < 32; i += 2)
26339 if (((a = rotate_left (val, i)) & 0xff) != 0)
26340 {
26341 if (a & 0xff00)
26342 {
26343 if (a & ~ 0xffff)
26344 continue;
26345 * highpart = (a >> 8) | ((i + 24) << 7);
26346 }
26347 else if (a & 0xff0000)
26348 {
26349 if (a & 0xff000000)
26350 continue;
26351 * highpart = (a >> 16) | ((i + 16) << 7);
26352 }
26353 else
26354 {
9c2799c2 26355 gas_assert (a & 0xff000000);
c19d1205
ZW
26356 * highpart = (a >> 24) | ((i + 8) << 7);
26357 }
bfae80f2 26358
c19d1205
ZW
26359 return (a & 0xff) | (i << 7);
26360 }
bfae80f2 26361
c19d1205 26362 return FAIL;
bfae80f2
RE
26363}
26364
c19d1205
ZW
26365static int
26366validate_offset_imm (unsigned int val, int hwse)
26367{
26368 if ((hwse && val > 255) || val > 4095)
26369 return FAIL;
26370 return val;
26371}
bfae80f2 26372
55cf6793 26373/* Subroutine of md_apply_fix. Do those data_ops which can take a
c19d1205
ZW
26374 negative immediate constant by altering the instruction. A bit of
26375 a hack really.
26376 MOV <-> MVN
26377 AND <-> BIC
26378 ADC <-> SBC
26379 by inverting the second operand, and
26380 ADD <-> SUB
26381 CMP <-> CMN
26382 by negating the second operand. */
bfae80f2 26383
c19d1205
ZW
26384static int
26385negate_data_op (unsigned long * instruction,
26386 unsigned long value)
bfae80f2 26387{
c19d1205
ZW
26388 int op, new_inst;
26389 unsigned long negated, inverted;
bfae80f2 26390
c19d1205
ZW
26391 negated = encode_arm_immediate (-value);
26392 inverted = encode_arm_immediate (~value);
bfae80f2 26393
c19d1205
ZW
26394 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
26395 switch (op)
bfae80f2 26396 {
c19d1205
ZW
26397 /* First negates. */
26398 case OPCODE_SUB: /* ADD <-> SUB */
26399 new_inst = OPCODE_ADD;
26400 value = negated;
26401 break;
bfae80f2 26402
c19d1205
ZW
26403 case OPCODE_ADD:
26404 new_inst = OPCODE_SUB;
26405 value = negated;
26406 break;
bfae80f2 26407
c19d1205
ZW
26408 case OPCODE_CMP: /* CMP <-> CMN */
26409 new_inst = OPCODE_CMN;
26410 value = negated;
26411 break;
bfae80f2 26412
c19d1205
ZW
26413 case OPCODE_CMN:
26414 new_inst = OPCODE_CMP;
26415 value = negated;
26416 break;
bfae80f2 26417
c19d1205
ZW
26418 /* Now Inverted ops. */
26419 case OPCODE_MOV: /* MOV <-> MVN */
26420 new_inst = OPCODE_MVN;
26421 value = inverted;
26422 break;
bfae80f2 26423
c19d1205
ZW
26424 case OPCODE_MVN:
26425 new_inst = OPCODE_MOV;
26426 value = inverted;
26427 break;
bfae80f2 26428
c19d1205
ZW
26429 case OPCODE_AND: /* AND <-> BIC */
26430 new_inst = OPCODE_BIC;
26431 value = inverted;
26432 break;
bfae80f2 26433
c19d1205
ZW
26434 case OPCODE_BIC:
26435 new_inst = OPCODE_AND;
26436 value = inverted;
26437 break;
bfae80f2 26438
c19d1205
ZW
26439 case OPCODE_ADC: /* ADC <-> SBC */
26440 new_inst = OPCODE_SBC;
26441 value = inverted;
26442 break;
bfae80f2 26443
c19d1205
ZW
26444 case OPCODE_SBC:
26445 new_inst = OPCODE_ADC;
26446 value = inverted;
26447 break;
bfae80f2 26448
c19d1205
ZW
26449 /* We cannot do anything. */
26450 default:
26451 return FAIL;
b99bd4ef
NC
26452 }
26453
c19d1205
ZW
26454 if (value == (unsigned) FAIL)
26455 return FAIL;
26456
26457 *instruction &= OPCODE_MASK;
26458 *instruction |= new_inst << DATA_OP_SHIFT;
26459 return value;
b99bd4ef
NC
26460}
26461
ef8d22e6
PB
26462/* Like negate_data_op, but for Thumb-2. */
26463
26464static unsigned int
16dd5e42 26465thumb32_negate_data_op (offsetT *instruction, unsigned int value)
ef8d22e6
PB
26466{
26467 int op, new_inst;
26468 int rd;
16dd5e42 26469 unsigned int negated, inverted;
ef8d22e6
PB
26470
26471 negated = encode_thumb32_immediate (-value);
26472 inverted = encode_thumb32_immediate (~value);
26473
26474 rd = (*instruction >> 8) & 0xf;
26475 op = (*instruction >> T2_DATA_OP_SHIFT) & 0xf;
26476 switch (op)
26477 {
26478 /* ADD <-> SUB. Includes CMP <-> CMN. */
26479 case T2_OPCODE_SUB:
26480 new_inst = T2_OPCODE_ADD;
26481 value = negated;
26482 break;
26483
26484 case T2_OPCODE_ADD:
26485 new_inst = T2_OPCODE_SUB;
26486 value = negated;
26487 break;
26488
26489 /* ORR <-> ORN. Includes MOV <-> MVN. */
26490 case T2_OPCODE_ORR:
26491 new_inst = T2_OPCODE_ORN;
26492 value = inverted;
26493 break;
26494
26495 case T2_OPCODE_ORN:
26496 new_inst = T2_OPCODE_ORR;
26497 value = inverted;
26498 break;
26499
26500 /* AND <-> BIC. TST has no inverted equivalent. */
26501 case T2_OPCODE_AND:
26502 new_inst = T2_OPCODE_BIC;
26503 if (rd == 15)
26504 value = FAIL;
26505 else
26506 value = inverted;
26507 break;
26508
26509 case T2_OPCODE_BIC:
26510 new_inst = T2_OPCODE_AND;
26511 value = inverted;
26512 break;
26513
26514 /* ADC <-> SBC */
26515 case T2_OPCODE_ADC:
26516 new_inst = T2_OPCODE_SBC;
26517 value = inverted;
26518 break;
26519
26520 case T2_OPCODE_SBC:
26521 new_inst = T2_OPCODE_ADC;
26522 value = inverted;
26523 break;
26524
26525 /* We cannot do anything. */
26526 default:
26527 return FAIL;
26528 }
26529
16dd5e42 26530 if (value == (unsigned int)FAIL)
ef8d22e6
PB
26531 return FAIL;
26532
26533 *instruction &= T2_OPCODE_MASK;
26534 *instruction |= new_inst << T2_DATA_OP_SHIFT;
26535 return value;
26536}
26537
8f06b2d8 26538/* Read a 32-bit thumb instruction from buf. */
0198d5e6 26539
8f06b2d8
PB
26540static unsigned long
26541get_thumb32_insn (char * buf)
26542{
26543 unsigned long insn;
26544 insn = md_chars_to_number (buf, THUMB_SIZE) << 16;
26545 insn |= md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
26546
26547 return insn;
26548}
26549
a8bc6c78
PB
26550/* We usually want to set the low bit on the address of thumb function
26551 symbols. In particular .word foo - . should have the low bit set.
26552 Generic code tries to fold the difference of two symbols to
26553 a constant. Prevent this and force a relocation when the first symbols
26554 is a thumb function. */
c921be7d
NC
26555
26556bfd_boolean
a8bc6c78
PB
26557arm_optimize_expr (expressionS *l, operatorT op, expressionS *r)
26558{
26559 if (op == O_subtract
26560 && l->X_op == O_symbol
26561 && r->X_op == O_symbol
26562 && THUMB_IS_FUNC (l->X_add_symbol))
26563 {
26564 l->X_op = O_subtract;
26565 l->X_op_symbol = r->X_add_symbol;
26566 l->X_add_number -= r->X_add_number;
c921be7d 26567 return TRUE;
a8bc6c78 26568 }
c921be7d 26569
a8bc6c78 26570 /* Process as normal. */
c921be7d 26571 return FALSE;
a8bc6c78
PB
26572}
26573
4a42ebbc
RR
26574/* Encode Thumb2 unconditional branches and calls. The encoding
26575 for the 2 are identical for the immediate values. */
26576
26577static void
26578encode_thumb2_b_bl_offset (char * buf, offsetT value)
26579{
26580#define T2I1I2MASK ((1 << 13) | (1 << 11))
26581 offsetT newval;
26582 offsetT newval2;
26583 addressT S, I1, I2, lo, hi;
26584
26585 S = (value >> 24) & 0x01;
26586 I1 = (value >> 23) & 0x01;
26587 I2 = (value >> 22) & 0x01;
26588 hi = (value >> 12) & 0x3ff;
fa94de6b 26589 lo = (value >> 1) & 0x7ff;
4a42ebbc
RR
26590 newval = md_chars_to_number (buf, THUMB_SIZE);
26591 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
26592 newval |= (S << 10) | hi;
26593 newval2 &= ~T2I1I2MASK;
26594 newval2 |= (((I1 ^ S) << 13) | ((I2 ^ S) << 11) | lo) ^ T2I1I2MASK;
26595 md_number_to_chars (buf, newval, THUMB_SIZE);
26596 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
26597}
26598
c19d1205 26599void
55cf6793 26600md_apply_fix (fixS * fixP,
c19d1205
ZW
26601 valueT * valP,
26602 segT seg)
26603{
26604 offsetT value = * valP;
26605 offsetT newval;
26606 unsigned int newimm;
26607 unsigned long temp;
26608 int sign;
26609 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
b99bd4ef 26610
9c2799c2 26611 gas_assert (fixP->fx_r_type <= BFD_RELOC_UNUSED);
b99bd4ef 26612
c19d1205 26613 /* Note whether this will delete the relocation. */
4962c51a 26614
c19d1205
ZW
26615 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
26616 fixP->fx_done = 1;
b99bd4ef 26617
adbaf948 26618 /* On a 64-bit host, silently truncate 'value' to 32 bits for
5f4273c7 26619 consistency with the behaviour on 32-bit hosts. Remember value
adbaf948
ZW
26620 for emit_reloc. */
26621 value &= 0xffffffff;
26622 value ^= 0x80000000;
5f4273c7 26623 value -= 0x80000000;
adbaf948
ZW
26624
26625 *valP = value;
c19d1205 26626 fixP->fx_addnumber = value;
b99bd4ef 26627
adbaf948
ZW
26628 /* Same treatment for fixP->fx_offset. */
26629 fixP->fx_offset &= 0xffffffff;
26630 fixP->fx_offset ^= 0x80000000;
26631 fixP->fx_offset -= 0x80000000;
26632
c19d1205 26633 switch (fixP->fx_r_type)
b99bd4ef 26634 {
c19d1205
ZW
26635 case BFD_RELOC_NONE:
26636 /* This will need to go in the object file. */
26637 fixP->fx_done = 0;
26638 break;
b99bd4ef 26639
c19d1205
ZW
26640 case BFD_RELOC_ARM_IMMEDIATE:
26641 /* We claim that this fixup has been processed here,
26642 even if in fact we generate an error because we do
26643 not have a reloc for it, so tc_gen_reloc will reject it. */
26644 fixP->fx_done = 1;
b99bd4ef 26645
77db8e2e 26646 if (fixP->fx_addsy)
b99bd4ef 26647 {
77db8e2e 26648 const char *msg = 0;
b99bd4ef 26649
77db8e2e
NC
26650 if (! S_IS_DEFINED (fixP->fx_addsy))
26651 msg = _("undefined symbol %s used as an immediate value");
26652 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
26653 msg = _("symbol %s is in a different section");
26654 else if (S_IS_WEAK (fixP->fx_addsy))
26655 msg = _("symbol %s is weak and may be overridden later");
26656
26657 if (msg)
26658 {
26659 as_bad_where (fixP->fx_file, fixP->fx_line,
26660 msg, S_GET_NAME (fixP->fx_addsy));
26661 break;
26662 }
42e5fcbf
AS
26663 }
26664
c19d1205
ZW
26665 temp = md_chars_to_number (buf, INSN_SIZE);
26666
5e73442d
SL
26667 /* If the offset is negative, we should use encoding A2 for ADR. */
26668 if ((temp & 0xfff0000) == 0x28f0000 && value < 0)
26669 newimm = negate_data_op (&temp, value);
26670 else
26671 {
26672 newimm = encode_arm_immediate (value);
26673
26674 /* If the instruction will fail, see if we can fix things up by
26675 changing the opcode. */
26676 if (newimm == (unsigned int) FAIL)
26677 newimm = negate_data_op (&temp, value);
bada4342
JW
26678 /* MOV accepts both ARM modified immediate (A1 encoding) and
26679 UINT16 (A2 encoding) when possible, MOVW only accepts UINT16.
26680 When disassembling, MOV is preferred when there is no encoding
26681 overlap. */
26682 if (newimm == (unsigned int) FAIL
26683 && ((temp >> DATA_OP_SHIFT) & 0xf) == OPCODE_MOV
26684 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
26685 && !((temp >> SBIT_SHIFT) & 0x1)
26686 && value >= 0 && value <= 0xffff)
26687 {
26688 /* Clear bits[23:20] to change encoding from A1 to A2. */
26689 temp &= 0xff0fffff;
26690 /* Encoding high 4bits imm. Code below will encode the remaining
26691 low 12bits. */
26692 temp |= (value & 0x0000f000) << 4;
26693 newimm = value & 0x00000fff;
26694 }
5e73442d
SL
26695 }
26696
26697 if (newimm == (unsigned int) FAIL)
b99bd4ef 26698 {
c19d1205
ZW
26699 as_bad_where (fixP->fx_file, fixP->fx_line,
26700 _("invalid constant (%lx) after fixup"),
26701 (unsigned long) value);
26702 break;
b99bd4ef 26703 }
b99bd4ef 26704
c19d1205
ZW
26705 newimm |= (temp & 0xfffff000);
26706 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
26707 break;
b99bd4ef 26708
c19d1205
ZW
26709 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
26710 {
26711 unsigned int highpart = 0;
26712 unsigned int newinsn = 0xe1a00000; /* nop. */
b99bd4ef 26713
77db8e2e 26714 if (fixP->fx_addsy)
42e5fcbf 26715 {
77db8e2e 26716 const char *msg = 0;
42e5fcbf 26717
77db8e2e
NC
26718 if (! S_IS_DEFINED (fixP->fx_addsy))
26719 msg = _("undefined symbol %s used as an immediate value");
26720 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
26721 msg = _("symbol %s is in a different section");
26722 else if (S_IS_WEAK (fixP->fx_addsy))
26723 msg = _("symbol %s is weak and may be overridden later");
42e5fcbf 26724
77db8e2e
NC
26725 if (msg)
26726 {
26727 as_bad_where (fixP->fx_file, fixP->fx_line,
26728 msg, S_GET_NAME (fixP->fx_addsy));
26729 break;
26730 }
26731 }
fa94de6b 26732
c19d1205
ZW
26733 newimm = encode_arm_immediate (value);
26734 temp = md_chars_to_number (buf, INSN_SIZE);
b99bd4ef 26735
c19d1205
ZW
26736 /* If the instruction will fail, see if we can fix things up by
26737 changing the opcode. */
26738 if (newimm == (unsigned int) FAIL
26739 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
26740 {
26741 /* No ? OK - try using two ADD instructions to generate
26742 the value. */
26743 newimm = validate_immediate_twopart (value, & highpart);
b99bd4ef 26744
c19d1205
ZW
26745 /* Yes - then make sure that the second instruction is
26746 also an add. */
26747 if (newimm != (unsigned int) FAIL)
26748 newinsn = temp;
26749 /* Still No ? Try using a negated value. */
26750 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
26751 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
26752 /* Otherwise - give up. */
26753 else
26754 {
26755 as_bad_where (fixP->fx_file, fixP->fx_line,
26756 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
26757 (long) value);
26758 break;
26759 }
b99bd4ef 26760
c19d1205
ZW
26761 /* Replace the first operand in the 2nd instruction (which
26762 is the PC) with the destination register. We have
26763 already added in the PC in the first instruction and we
26764 do not want to do it again. */
26765 newinsn &= ~ 0xf0000;
26766 newinsn |= ((newinsn & 0x0f000) << 4);
26767 }
b99bd4ef 26768
c19d1205
ZW
26769 newimm |= (temp & 0xfffff000);
26770 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
b99bd4ef 26771
c19d1205
ZW
26772 highpart |= (newinsn & 0xfffff000);
26773 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
26774 }
26775 break;
b99bd4ef 26776
c19d1205 26777 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
26778 if (!fixP->fx_done && seg->use_rela_p)
26779 value = 0;
1a0670f3 26780 /* Fall through. */
00a97672 26781
c19d1205 26782 case BFD_RELOC_ARM_LITERAL:
26d97720 26783 sign = value > 0;
b99bd4ef 26784
c19d1205
ZW
26785 if (value < 0)
26786 value = - value;
b99bd4ef 26787
c19d1205 26788 if (validate_offset_imm (value, 0) == FAIL)
f03698e6 26789 {
c19d1205
ZW
26790 if (fixP->fx_r_type == BFD_RELOC_ARM_LITERAL)
26791 as_bad_where (fixP->fx_file, fixP->fx_line,
26792 _("invalid literal constant: pool needs to be closer"));
26793 else
26794 as_bad_where (fixP->fx_file, fixP->fx_line,
26795 _("bad immediate value for offset (%ld)"),
26796 (long) value);
26797 break;
f03698e6
RE
26798 }
26799
c19d1205 26800 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
26801 if (value == 0)
26802 newval &= 0xfffff000;
26803 else
26804 {
26805 newval &= 0xff7ff000;
26806 newval |= value | (sign ? INDEX_UP : 0);
26807 }
c19d1205
ZW
26808 md_number_to_chars (buf, newval, INSN_SIZE);
26809 break;
b99bd4ef 26810
c19d1205
ZW
26811 case BFD_RELOC_ARM_OFFSET_IMM8:
26812 case BFD_RELOC_ARM_HWLITERAL:
26d97720 26813 sign = value > 0;
b99bd4ef 26814
c19d1205
ZW
26815 if (value < 0)
26816 value = - value;
b99bd4ef 26817
c19d1205 26818 if (validate_offset_imm (value, 1) == FAIL)
b99bd4ef 26819 {
c19d1205
ZW
26820 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
26821 as_bad_where (fixP->fx_file, fixP->fx_line,
26822 _("invalid literal constant: pool needs to be closer"));
26823 else
427d0db6
RM
26824 as_bad_where (fixP->fx_file, fixP->fx_line,
26825 _("bad immediate value for 8-bit offset (%ld)"),
26826 (long) value);
c19d1205 26827 break;
b99bd4ef
NC
26828 }
26829
c19d1205 26830 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
26831 if (value == 0)
26832 newval &= 0xfffff0f0;
26833 else
26834 {
26835 newval &= 0xff7ff0f0;
26836 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
26837 }
c19d1205
ZW
26838 md_number_to_chars (buf, newval, INSN_SIZE);
26839 break;
b99bd4ef 26840
c19d1205
ZW
26841 case BFD_RELOC_ARM_T32_OFFSET_U8:
26842 if (value < 0 || value > 1020 || value % 4 != 0)
26843 as_bad_where (fixP->fx_file, fixP->fx_line,
26844 _("bad immediate value for offset (%ld)"), (long) value);
26845 value /= 4;
b99bd4ef 26846
c19d1205 26847 newval = md_chars_to_number (buf+2, THUMB_SIZE);
c19d1205
ZW
26848 newval |= value;
26849 md_number_to_chars (buf+2, newval, THUMB_SIZE);
26850 break;
b99bd4ef 26851
c19d1205
ZW
26852 case BFD_RELOC_ARM_T32_OFFSET_IMM:
26853 /* This is a complicated relocation used for all varieties of Thumb32
26854 load/store instruction with immediate offset:
26855
26856 1110 100P u1WL NNNN XXXX YYYY iiii iiii - +/-(U) pre/post(P) 8-bit,
477330fc 26857 *4, optional writeback(W)
c19d1205
ZW
26858 (doubleword load/store)
26859
26860 1111 100S uTTL 1111 XXXX iiii iiii iiii - +/-(U) 12-bit PC-rel
26861 1111 100S 0TTL NNNN XXXX 1Pu1 iiii iiii - +/-(U) pre/post(P) 8-bit
26862 1111 100S 0TTL NNNN XXXX 1110 iiii iiii - positive 8-bit (T instruction)
26863 1111 100S 1TTL NNNN XXXX iiii iiii iiii - positive 12-bit
26864 1111 100S 0TTL NNNN XXXX 1100 iiii iiii - negative 8-bit
26865
26866 Uppercase letters indicate bits that are already encoded at
26867 this point. Lowercase letters are our problem. For the
26868 second block of instructions, the secondary opcode nybble
26869 (bits 8..11) is present, and bit 23 is zero, even if this is
26870 a PC-relative operation. */
26871 newval = md_chars_to_number (buf, THUMB_SIZE);
26872 newval <<= 16;
26873 newval |= md_chars_to_number (buf+THUMB_SIZE, THUMB_SIZE);
b99bd4ef 26874
c19d1205 26875 if ((newval & 0xf0000000) == 0xe0000000)
b99bd4ef 26876 {
c19d1205
ZW
26877 /* Doubleword load/store: 8-bit offset, scaled by 4. */
26878 if (value >= 0)
26879 newval |= (1 << 23);
26880 else
26881 value = -value;
26882 if (value % 4 != 0)
26883 {
26884 as_bad_where (fixP->fx_file, fixP->fx_line,
26885 _("offset not a multiple of 4"));
26886 break;
26887 }
26888 value /= 4;
216d22bc 26889 if (value > 0xff)
c19d1205
ZW
26890 {
26891 as_bad_where (fixP->fx_file, fixP->fx_line,
26892 _("offset out of range"));
26893 break;
26894 }
26895 newval &= ~0xff;
b99bd4ef 26896 }
c19d1205 26897 else if ((newval & 0x000f0000) == 0x000f0000)
b99bd4ef 26898 {
c19d1205
ZW
26899 /* PC-relative, 12-bit offset. */
26900 if (value >= 0)
26901 newval |= (1 << 23);
26902 else
26903 value = -value;
216d22bc 26904 if (value > 0xfff)
c19d1205
ZW
26905 {
26906 as_bad_where (fixP->fx_file, fixP->fx_line,
26907 _("offset out of range"));
26908 break;
26909 }
26910 newval &= ~0xfff;
b99bd4ef 26911 }
c19d1205 26912 else if ((newval & 0x00000100) == 0x00000100)
b99bd4ef 26913 {
c19d1205
ZW
26914 /* Writeback: 8-bit, +/- offset. */
26915 if (value >= 0)
26916 newval |= (1 << 9);
26917 else
26918 value = -value;
216d22bc 26919 if (value > 0xff)
c19d1205
ZW
26920 {
26921 as_bad_where (fixP->fx_file, fixP->fx_line,
26922 _("offset out of range"));
26923 break;
26924 }
26925 newval &= ~0xff;
b99bd4ef 26926 }
c19d1205 26927 else if ((newval & 0x00000f00) == 0x00000e00)
b99bd4ef 26928 {
c19d1205 26929 /* T-instruction: positive 8-bit offset. */
216d22bc 26930 if (value < 0 || value > 0xff)
b99bd4ef 26931 {
c19d1205
ZW
26932 as_bad_where (fixP->fx_file, fixP->fx_line,
26933 _("offset out of range"));
26934 break;
b99bd4ef 26935 }
c19d1205
ZW
26936 newval &= ~0xff;
26937 newval |= value;
b99bd4ef
NC
26938 }
26939 else
b99bd4ef 26940 {
c19d1205
ZW
26941 /* Positive 12-bit or negative 8-bit offset. */
26942 int limit;
26943 if (value >= 0)
b99bd4ef 26944 {
c19d1205
ZW
26945 newval |= (1 << 23);
26946 limit = 0xfff;
26947 }
26948 else
26949 {
26950 value = -value;
26951 limit = 0xff;
26952 }
26953 if (value > limit)
26954 {
26955 as_bad_where (fixP->fx_file, fixP->fx_line,
26956 _("offset out of range"));
26957 break;
b99bd4ef 26958 }
c19d1205 26959 newval &= ~limit;
b99bd4ef 26960 }
b99bd4ef 26961
c19d1205
ZW
26962 newval |= value;
26963 md_number_to_chars (buf, (newval >> 16) & 0xffff, THUMB_SIZE);
26964 md_number_to_chars (buf + THUMB_SIZE, newval & 0xffff, THUMB_SIZE);
26965 break;
404ff6b5 26966
c19d1205
ZW
26967 case BFD_RELOC_ARM_SHIFT_IMM:
26968 newval = md_chars_to_number (buf, INSN_SIZE);
26969 if (((unsigned long) value) > 32
26970 || (value == 32
26971 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
26972 {
26973 as_bad_where (fixP->fx_file, fixP->fx_line,
26974 _("shift expression is too large"));
26975 break;
26976 }
404ff6b5 26977
c19d1205
ZW
26978 if (value == 0)
26979 /* Shifts of zero must be done as lsl. */
26980 newval &= ~0x60;
26981 else if (value == 32)
26982 value = 0;
26983 newval &= 0xfffff07f;
26984 newval |= (value & 0x1f) << 7;
26985 md_number_to_chars (buf, newval, INSN_SIZE);
26986 break;
404ff6b5 26987
c19d1205 26988 case BFD_RELOC_ARM_T32_IMMEDIATE:
16805f35 26989 case BFD_RELOC_ARM_T32_ADD_IMM:
92e90b6e 26990 case BFD_RELOC_ARM_T32_IMM12:
e9f89963 26991 case BFD_RELOC_ARM_T32_ADD_PC12:
c19d1205
ZW
26992 /* We claim that this fixup has been processed here,
26993 even if in fact we generate an error because we do
26994 not have a reloc for it, so tc_gen_reloc will reject it. */
26995 fixP->fx_done = 1;
404ff6b5 26996
c19d1205
ZW
26997 if (fixP->fx_addsy
26998 && ! S_IS_DEFINED (fixP->fx_addsy))
26999 {
27000 as_bad_where (fixP->fx_file, fixP->fx_line,
27001 _("undefined symbol %s used as an immediate value"),
27002 S_GET_NAME (fixP->fx_addsy));
27003 break;
27004 }
404ff6b5 27005
c19d1205
ZW
27006 newval = md_chars_to_number (buf, THUMB_SIZE);
27007 newval <<= 16;
27008 newval |= md_chars_to_number (buf+2, THUMB_SIZE);
404ff6b5 27009
16805f35 27010 newimm = FAIL;
bada4342
JW
27011 if ((fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
27012 /* ARMv8-M Baseline MOV will reach here, but it doesn't support
27013 Thumb2 modified immediate encoding (T2). */
27014 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
16805f35 27015 || fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
ef8d22e6
PB
27016 {
27017 newimm = encode_thumb32_immediate (value);
27018 if (newimm == (unsigned int) FAIL)
27019 newimm = thumb32_negate_data_op (&newval, value);
27020 }
bada4342 27021 if (newimm == (unsigned int) FAIL)
92e90b6e 27022 {
bada4342 27023 if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE)
e9f89963 27024 {
bada4342
JW
27025 /* Turn add/sum into addw/subw. */
27026 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
27027 newval = (newval & 0xfeffffff) | 0x02000000;
27028 /* No flat 12-bit imm encoding for addsw/subsw. */
27029 if ((newval & 0x00100000) == 0)
40f246e3 27030 {
bada4342
JW
27031 /* 12 bit immediate for addw/subw. */
27032 if (value < 0)
27033 {
27034 value = -value;
27035 newval ^= 0x00a00000;
27036 }
27037 if (value > 0xfff)
27038 newimm = (unsigned int) FAIL;
27039 else
27040 newimm = value;
27041 }
27042 }
27043 else
27044 {
27045 /* MOV accepts both Thumb2 modified immediate (T2 encoding) and
27046 UINT16 (T3 encoding), MOVW only accepts UINT16. When
27047 disassembling, MOV is preferred when there is no encoding
db7bf105 27048 overlap. */
bada4342 27049 if (((newval >> T2_DATA_OP_SHIFT) & 0xf) == T2_OPCODE_ORR
db7bf105
NC
27050 /* NOTE: MOV uses the ORR opcode in Thumb 2 mode
27051 but with the Rn field [19:16] set to 1111. */
27052 && (((newval >> 16) & 0xf) == 0xf)
bada4342
JW
27053 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m)
27054 && !((newval >> T2_SBIT_SHIFT) & 0x1)
db7bf105 27055 && value >= 0 && value <= 0xffff)
bada4342
JW
27056 {
27057 /* Toggle bit[25] to change encoding from T2 to T3. */
27058 newval ^= 1 << 25;
27059 /* Clear bits[19:16]. */
27060 newval &= 0xfff0ffff;
27061 /* Encoding high 4bits imm. Code below will encode the
27062 remaining low 12bits. */
27063 newval |= (value & 0x0000f000) << 4;
27064 newimm = value & 0x00000fff;
40f246e3 27065 }
e9f89963 27066 }
92e90b6e 27067 }
cc8a6dd0 27068
c19d1205 27069 if (newimm == (unsigned int)FAIL)
3631a3c8 27070 {
c19d1205
ZW
27071 as_bad_where (fixP->fx_file, fixP->fx_line,
27072 _("invalid constant (%lx) after fixup"),
27073 (unsigned long) value);
27074 break;
3631a3c8
NC
27075 }
27076
c19d1205
ZW
27077 newval |= (newimm & 0x800) << 15;
27078 newval |= (newimm & 0x700) << 4;
27079 newval |= (newimm & 0x0ff);
cc8a6dd0 27080
c19d1205
ZW
27081 md_number_to_chars (buf, (valueT) ((newval >> 16) & 0xffff), THUMB_SIZE);
27082 md_number_to_chars (buf+2, (valueT) (newval & 0xffff), THUMB_SIZE);
27083 break;
a737bd4d 27084
3eb17e6b 27085 case BFD_RELOC_ARM_SMC:
c19d1205
ZW
27086 if (((unsigned long) value) > 0xffff)
27087 as_bad_where (fixP->fx_file, fixP->fx_line,
3eb17e6b 27088 _("invalid smc expression"));
2fc8bdac 27089 newval = md_chars_to_number (buf, INSN_SIZE);
c19d1205
ZW
27090 newval |= (value & 0xf) | ((value & 0xfff0) << 4);
27091 md_number_to_chars (buf, newval, INSN_SIZE);
27092 break;
a737bd4d 27093
90ec0d68
MGD
27094 case BFD_RELOC_ARM_HVC:
27095 if (((unsigned long) value) > 0xffff)
27096 as_bad_where (fixP->fx_file, fixP->fx_line,
27097 _("invalid hvc expression"));
27098 newval = md_chars_to_number (buf, INSN_SIZE);
27099 newval |= (value & 0xf) | ((value & 0xfff0) << 4);
27100 md_number_to_chars (buf, newval, INSN_SIZE);
27101 break;
27102
c19d1205 27103 case BFD_RELOC_ARM_SWI:
adbaf948 27104 if (fixP->tc_fix_data != 0)
c19d1205
ZW
27105 {
27106 if (((unsigned long) value) > 0xff)
27107 as_bad_where (fixP->fx_file, fixP->fx_line,
27108 _("invalid swi expression"));
2fc8bdac 27109 newval = md_chars_to_number (buf, THUMB_SIZE);
c19d1205
ZW
27110 newval |= value;
27111 md_number_to_chars (buf, newval, THUMB_SIZE);
27112 }
27113 else
27114 {
27115 if (((unsigned long) value) > 0x00ffffff)
27116 as_bad_where (fixP->fx_file, fixP->fx_line,
27117 _("invalid swi expression"));
2fc8bdac 27118 newval = md_chars_to_number (buf, INSN_SIZE);
c19d1205
ZW
27119 newval |= value;
27120 md_number_to_chars (buf, newval, INSN_SIZE);
27121 }
27122 break;
a737bd4d 27123
c19d1205
ZW
27124 case BFD_RELOC_ARM_MULTI:
27125 if (((unsigned long) value) > 0xffff)
27126 as_bad_where (fixP->fx_file, fixP->fx_line,
27127 _("invalid expression in load/store multiple"));
27128 newval = value | md_chars_to_number (buf, INSN_SIZE);
27129 md_number_to_chars (buf, newval, INSN_SIZE);
27130 break;
a737bd4d 27131
c19d1205 27132#ifdef OBJ_ELF
39b41c9c 27133 case BFD_RELOC_ARM_PCREL_CALL:
267bf995
RR
27134
27135 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
27136 && fixP->fx_addsy
34e77a92 27137 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
27138 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
27139 && THUMB_IS_FUNC (fixP->fx_addsy))
27140 /* Flip the bl to blx. This is a simple flip
27141 bit here because we generate PCREL_CALL for
27142 unconditional bls. */
27143 {
27144 newval = md_chars_to_number (buf, INSN_SIZE);
27145 newval = newval | 0x10000000;
27146 md_number_to_chars (buf, newval, INSN_SIZE);
27147 temp = 1;
27148 fixP->fx_done = 1;
27149 }
39b41c9c
PB
27150 else
27151 temp = 3;
27152 goto arm_branch_common;
27153
27154 case BFD_RELOC_ARM_PCREL_JUMP:
267bf995
RR
27155 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
27156 && fixP->fx_addsy
34e77a92 27157 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
27158 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
27159 && THUMB_IS_FUNC (fixP->fx_addsy))
27160 {
27161 /* This would map to a bl<cond>, b<cond>,
27162 b<always> to a Thumb function. We
27163 need to force a relocation for this particular
27164 case. */
27165 newval = md_chars_to_number (buf, INSN_SIZE);
27166 fixP->fx_done = 0;
27167 }
1a0670f3 27168 /* Fall through. */
267bf995 27169
2fc8bdac 27170 case BFD_RELOC_ARM_PLT32:
c19d1205 27171#endif
39b41c9c
PB
27172 case BFD_RELOC_ARM_PCREL_BRANCH:
27173 temp = 3;
27174 goto arm_branch_common;
a737bd4d 27175
39b41c9c 27176 case BFD_RELOC_ARM_PCREL_BLX:
267bf995 27177
39b41c9c 27178 temp = 1;
267bf995
RR
27179 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
27180 && fixP->fx_addsy
34e77a92 27181 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
27182 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
27183 && ARM_IS_FUNC (fixP->fx_addsy))
27184 {
27185 /* Flip the blx to a bl and warn. */
27186 const char *name = S_GET_NAME (fixP->fx_addsy);
27187 newval = 0xeb000000;
27188 as_warn_where (fixP->fx_file, fixP->fx_line,
27189 _("blx to '%s' an ARM ISA state function changed to bl"),
27190 name);
27191 md_number_to_chars (buf, newval, INSN_SIZE);
27192 temp = 3;
27193 fixP->fx_done = 1;
27194 }
27195
27196#ifdef OBJ_ELF
27197 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
477330fc 27198 fixP->fx_r_type = BFD_RELOC_ARM_PCREL_CALL;
267bf995
RR
27199#endif
27200
39b41c9c 27201 arm_branch_common:
c19d1205 27202 /* We are going to store value (shifted right by two) in the
39b41c9c
PB
27203 instruction, in a 24 bit, signed field. Bits 26 through 32 either
27204 all clear or all set and bit 0 must be clear. For B/BL bit 1 must
de194d85 27205 also be clear. */
39b41c9c 27206 if (value & temp)
c19d1205 27207 as_bad_where (fixP->fx_file, fixP->fx_line,
2fc8bdac
ZW
27208 _("misaligned branch destination"));
27209 if ((value & (offsetT)0xfe000000) != (offsetT)0
27210 && (value & (offsetT)0xfe000000) != (offsetT)0xfe000000)
08f10d51 27211 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 27212
2fc8bdac 27213 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 27214 {
2fc8bdac
ZW
27215 newval = md_chars_to_number (buf, INSN_SIZE);
27216 newval |= (value >> 2) & 0x00ffffff;
7ae2971b
PB
27217 /* Set the H bit on BLX instructions. */
27218 if (temp == 1)
27219 {
27220 if (value & 2)
27221 newval |= 0x01000000;
27222 else
27223 newval &= ~0x01000000;
27224 }
2fc8bdac 27225 md_number_to_chars (buf, newval, INSN_SIZE);
c19d1205 27226 }
c19d1205 27227 break;
a737bd4d 27228
25fe350b
MS
27229 case BFD_RELOC_THUMB_PCREL_BRANCH7: /* CBZ */
27230 /* CBZ can only branch forward. */
a737bd4d 27231
738755b0 27232 /* Attempts to use CBZ to branch to the next instruction
477330fc
RM
27233 (which, strictly speaking, are prohibited) will be turned into
27234 no-ops.
738755b0
MS
27235
27236 FIXME: It may be better to remove the instruction completely and
27237 perform relaxation. */
27238 if (value == -2)
2fc8bdac
ZW
27239 {
27240 newval = md_chars_to_number (buf, THUMB_SIZE);
738755b0 27241 newval = 0xbf00; /* NOP encoding T1 */
2fc8bdac
ZW
27242 md_number_to_chars (buf, newval, THUMB_SIZE);
27243 }
738755b0
MS
27244 else
27245 {
27246 if (value & ~0x7e)
08f10d51 27247 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
738755b0 27248
477330fc 27249 if (fixP->fx_done || !seg->use_rela_p)
738755b0
MS
27250 {
27251 newval = md_chars_to_number (buf, THUMB_SIZE);
27252 newval |= ((value & 0x3e) << 2) | ((value & 0x40) << 3);
27253 md_number_to_chars (buf, newval, THUMB_SIZE);
27254 }
27255 }
c19d1205 27256 break;
a737bd4d 27257
c19d1205 27258 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
2fc8bdac 27259 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
08f10d51 27260 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 27261
2fc8bdac
ZW
27262 if (fixP->fx_done || !seg->use_rela_p)
27263 {
27264 newval = md_chars_to_number (buf, THUMB_SIZE);
27265 newval |= (value & 0x1ff) >> 1;
27266 md_number_to_chars (buf, newval, THUMB_SIZE);
27267 }
c19d1205 27268 break;
a737bd4d 27269
c19d1205 27270 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
2fc8bdac 27271 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
08f10d51 27272 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 27273
2fc8bdac
ZW
27274 if (fixP->fx_done || !seg->use_rela_p)
27275 {
27276 newval = md_chars_to_number (buf, THUMB_SIZE);
27277 newval |= (value & 0xfff) >> 1;
27278 md_number_to_chars (buf, newval, THUMB_SIZE);
27279 }
c19d1205 27280 break;
a737bd4d 27281
c19d1205 27282 case BFD_RELOC_THUMB_PCREL_BRANCH20:
267bf995
RR
27283 if (fixP->fx_addsy
27284 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 27285 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
27286 && ARM_IS_FUNC (fixP->fx_addsy)
27287 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
27288 {
27289 /* Force a relocation for a branch 20 bits wide. */
27290 fixP->fx_done = 0;
27291 }
08f10d51 27292 if ((value & ~0x1fffff) && ((value & ~0x0fffff) != ~0x0fffff))
2fc8bdac
ZW
27293 as_bad_where (fixP->fx_file, fixP->fx_line,
27294 _("conditional branch out of range"));
404ff6b5 27295
2fc8bdac
ZW
27296 if (fixP->fx_done || !seg->use_rela_p)
27297 {
27298 offsetT newval2;
27299 addressT S, J1, J2, lo, hi;
404ff6b5 27300
2fc8bdac
ZW
27301 S = (value & 0x00100000) >> 20;
27302 J2 = (value & 0x00080000) >> 19;
27303 J1 = (value & 0x00040000) >> 18;
27304 hi = (value & 0x0003f000) >> 12;
27305 lo = (value & 0x00000ffe) >> 1;
6c43fab6 27306
2fc8bdac
ZW
27307 newval = md_chars_to_number (buf, THUMB_SIZE);
27308 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
27309 newval |= (S << 10) | hi;
27310 newval2 |= (J1 << 13) | (J2 << 11) | lo;
27311 md_number_to_chars (buf, newval, THUMB_SIZE);
27312 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
27313 }
c19d1205 27314 break;
6c43fab6 27315
c19d1205 27316 case BFD_RELOC_THUMB_PCREL_BLX:
267bf995
RR
27317 /* If there is a blx from a thumb state function to
27318 another thumb function flip this to a bl and warn
27319 about it. */
27320
27321 if (fixP->fx_addsy
34e77a92 27322 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
27323 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
27324 && THUMB_IS_FUNC (fixP->fx_addsy))
27325 {
27326 const char *name = S_GET_NAME (fixP->fx_addsy);
27327 as_warn_where (fixP->fx_file, fixP->fx_line,
27328 _("blx to Thumb func '%s' from Thumb ISA state changed to bl"),
27329 name);
27330 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
27331 newval = newval | 0x1000;
27332 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
27333 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
27334 fixP->fx_done = 1;
27335 }
27336
27337
27338 goto thumb_bl_common;
27339
c19d1205 27340 case BFD_RELOC_THUMB_PCREL_BRANCH23:
267bf995
RR
27341 /* A bl from Thumb state ISA to an internal ARM state function
27342 is converted to a blx. */
27343 if (fixP->fx_addsy
27344 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 27345 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
27346 && ARM_IS_FUNC (fixP->fx_addsy)
27347 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
27348 {
27349 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
27350 newval = newval & ~0x1000;
27351 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
27352 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BLX;
27353 fixP->fx_done = 1;
27354 }
27355
27356 thumb_bl_common:
27357
2fc8bdac
ZW
27358 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
27359 /* For a BLX instruction, make sure that the relocation is rounded up
27360 to a word boundary. This follows the semantics of the instruction
27361 which specifies that bit 1 of the target address will come from bit
27362 1 of the base address. */
d406f3e4
JB
27363 value = (value + 3) & ~ 3;
27364
27365#ifdef OBJ_ELF
27366 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4
27367 && fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
27368 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
27369#endif
404ff6b5 27370
2b2f5df9
NC
27371 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
27372 {
fc289b0a 27373 if (!(ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)))
2b2f5df9
NC
27374 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
27375 else if ((value & ~0x1ffffff)
27376 && ((value & ~0x1ffffff) != ~0x1ffffff))
27377 as_bad_where (fixP->fx_file, fixP->fx_line,
27378 _("Thumb2 branch out of range"));
27379 }
4a42ebbc
RR
27380
27381 if (fixP->fx_done || !seg->use_rela_p)
27382 encode_thumb2_b_bl_offset (buf, value);
27383
c19d1205 27384 break;
404ff6b5 27385
c19d1205 27386 case BFD_RELOC_THUMB_PCREL_BRANCH25:
08f10d51
NC
27387 if ((value & ~0x0ffffff) && ((value & ~0x0ffffff) != ~0x0ffffff))
27388 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
6c43fab6 27389
2fc8bdac 27390 if (fixP->fx_done || !seg->use_rela_p)
4a42ebbc 27391 encode_thumb2_b_bl_offset (buf, value);
6c43fab6 27392
2fc8bdac 27393 break;
a737bd4d 27394
2fc8bdac
ZW
27395 case BFD_RELOC_8:
27396 if (fixP->fx_done || !seg->use_rela_p)
4b1a927e 27397 *buf = value;
c19d1205 27398 break;
a737bd4d 27399
c19d1205 27400 case BFD_RELOC_16:
2fc8bdac 27401 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 27402 md_number_to_chars (buf, value, 2);
c19d1205 27403 break;
a737bd4d 27404
c19d1205 27405#ifdef OBJ_ELF
0855e32b
NS
27406 case BFD_RELOC_ARM_TLS_CALL:
27407 case BFD_RELOC_ARM_THM_TLS_CALL:
27408 case BFD_RELOC_ARM_TLS_DESCSEQ:
27409 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
0855e32b 27410 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205
ZW
27411 case BFD_RELOC_ARM_TLS_GD32:
27412 case BFD_RELOC_ARM_TLS_LE32:
27413 case BFD_RELOC_ARM_TLS_IE32:
27414 case BFD_RELOC_ARM_TLS_LDM32:
27415 case BFD_RELOC_ARM_TLS_LDO32:
27416 S_SET_THREAD_LOCAL (fixP->fx_addsy);
4b1a927e 27417 break;
6c43fab6 27418
5c5a4843
CL
27419 /* Same handling as above, but with the arm_fdpic guard. */
27420 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
27421 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
27422 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
27423 if (arm_fdpic)
27424 {
27425 S_SET_THREAD_LOCAL (fixP->fx_addsy);
27426 }
27427 else
27428 {
27429 as_bad_where (fixP->fx_file, fixP->fx_line,
27430 _("Relocation supported only in FDPIC mode"));
27431 }
27432 break;
27433
c19d1205
ZW
27434 case BFD_RELOC_ARM_GOT32:
27435 case BFD_RELOC_ARM_GOTOFF:
c19d1205 27436 break;
b43420e6
NC
27437
27438 case BFD_RELOC_ARM_GOT_PREL:
27439 if (fixP->fx_done || !seg->use_rela_p)
477330fc 27440 md_number_to_chars (buf, value, 4);
b43420e6
NC
27441 break;
27442
9a6f4e97
NS
27443 case BFD_RELOC_ARM_TARGET2:
27444 /* TARGET2 is not partial-inplace, so we need to write the
477330fc
RM
27445 addend here for REL targets, because it won't be written out
27446 during reloc processing later. */
9a6f4e97
NS
27447 if (fixP->fx_done || !seg->use_rela_p)
27448 md_number_to_chars (buf, fixP->fx_offset, 4);
27449 break;
188fd7ae
CL
27450
27451 /* Relocations for FDPIC. */
27452 case BFD_RELOC_ARM_GOTFUNCDESC:
27453 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
27454 case BFD_RELOC_ARM_FUNCDESC:
27455 if (arm_fdpic)
27456 {
27457 if (fixP->fx_done || !seg->use_rela_p)
27458 md_number_to_chars (buf, 0, 4);
27459 }
27460 else
27461 {
27462 as_bad_where (fixP->fx_file, fixP->fx_line,
27463 _("Relocation supported only in FDPIC mode"));
27464 }
27465 break;
c19d1205 27466#endif
6c43fab6 27467
c19d1205
ZW
27468 case BFD_RELOC_RVA:
27469 case BFD_RELOC_32:
27470 case BFD_RELOC_ARM_TARGET1:
27471 case BFD_RELOC_ARM_ROSEGREL32:
27472 case BFD_RELOC_ARM_SBREL32:
27473 case BFD_RELOC_32_PCREL:
f0927246
NC
27474#ifdef TE_PE
27475 case BFD_RELOC_32_SECREL:
27476#endif
2fc8bdac 27477 if (fixP->fx_done || !seg->use_rela_p)
53baae48
NC
27478#ifdef TE_WINCE
27479 /* For WinCE we only do this for pcrel fixups. */
27480 if (fixP->fx_done || fixP->fx_pcrel)
27481#endif
27482 md_number_to_chars (buf, value, 4);
c19d1205 27483 break;
6c43fab6 27484
c19d1205
ZW
27485#ifdef OBJ_ELF
27486 case BFD_RELOC_ARM_PREL31:
2fc8bdac 27487 if (fixP->fx_done || !seg->use_rela_p)
c19d1205
ZW
27488 {
27489 newval = md_chars_to_number (buf, 4) & 0x80000000;
27490 if ((value ^ (value >> 1)) & 0x40000000)
27491 {
27492 as_bad_where (fixP->fx_file, fixP->fx_line,
27493 _("rel31 relocation overflow"));
27494 }
27495 newval |= value & 0x7fffffff;
27496 md_number_to_chars (buf, newval, 4);
27497 }
27498 break;
c19d1205 27499#endif
a737bd4d 27500
c19d1205 27501 case BFD_RELOC_ARM_CP_OFF_IMM:
8f06b2d8 27502 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
32c36c3c 27503 case BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM:
9db2f6b4
RL
27504 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM)
27505 newval = md_chars_to_number (buf, INSN_SIZE);
27506 else
27507 newval = get_thumb32_insn (buf);
27508 if ((newval & 0x0f200f00) == 0x0d000900)
27509 {
27510 /* This is a fp16 vstr/vldr. The immediate offset in the mnemonic
27511 has permitted values that are multiples of 2, in the range 0
27512 to 510. */
27513 if (value < -510 || value > 510 || (value & 1))
27514 as_bad_where (fixP->fx_file, fixP->fx_line,
27515 _("co-processor offset out of range"));
27516 }
32c36c3c
AV
27517 else if ((newval & 0xfe001f80) == 0xec000f80)
27518 {
27519 if (value < -511 || value > 512 || (value & 3))
27520 as_bad_where (fixP->fx_file, fixP->fx_line,
27521 _("co-processor offset out of range"));
27522 }
9db2f6b4 27523 else if (value < -1023 || value > 1023 || (value & 3))
c19d1205
ZW
27524 as_bad_where (fixP->fx_file, fixP->fx_line,
27525 _("co-processor offset out of range"));
27526 cp_off_common:
26d97720 27527 sign = value > 0;
c19d1205
ZW
27528 if (value < 0)
27529 value = -value;
8f06b2d8
PB
27530 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
27531 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
27532 newval = md_chars_to_number (buf, INSN_SIZE);
27533 else
27534 newval = get_thumb32_insn (buf);
26d97720 27535 if (value == 0)
32c36c3c
AV
27536 {
27537 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM)
27538 newval &= 0xffffff80;
27539 else
27540 newval &= 0xffffff00;
27541 }
26d97720
NS
27542 else
27543 {
32c36c3c
AV
27544 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM)
27545 newval &= 0xff7fff80;
27546 else
27547 newval &= 0xff7fff00;
9db2f6b4
RL
27548 if ((newval & 0x0f200f00) == 0x0d000900)
27549 {
27550 /* This is a fp16 vstr/vldr.
27551
27552 It requires the immediate offset in the instruction is shifted
27553 left by 1 to be a half-word offset.
27554
27555 Here, left shift by 1 first, and later right shift by 2
27556 should get the right offset. */
27557 value <<= 1;
27558 }
26d97720
NS
27559 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
27560 }
8f06b2d8
PB
27561 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
27562 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
27563 md_number_to_chars (buf, newval, INSN_SIZE);
27564 else
27565 put_thumb32_insn (buf, newval);
c19d1205 27566 break;
a737bd4d 27567
c19d1205 27568 case BFD_RELOC_ARM_CP_OFF_IMM_S2:
8f06b2d8 27569 case BFD_RELOC_ARM_T32_CP_OFF_IMM_S2:
c19d1205
ZW
27570 if (value < -255 || value > 255)
27571 as_bad_where (fixP->fx_file, fixP->fx_line,
27572 _("co-processor offset out of range"));
df7849c5 27573 value *= 4;
c19d1205 27574 goto cp_off_common;
6c43fab6 27575
c19d1205
ZW
27576 case BFD_RELOC_ARM_THUMB_OFFSET:
27577 newval = md_chars_to_number (buf, THUMB_SIZE);
27578 /* Exactly what ranges, and where the offset is inserted depends
27579 on the type of instruction, we can establish this from the
27580 top 4 bits. */
27581 switch (newval >> 12)
27582 {
27583 case 4: /* PC load. */
27584 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
27585 forced to zero for these loads; md_pcrel_from has already
27586 compensated for this. */
27587 if (value & 3)
27588 as_bad_where (fixP->fx_file, fixP->fx_line,
27589 _("invalid offset, target not word aligned (0x%08lX)"),
0359e808
NC
27590 (((unsigned long) fixP->fx_frag->fr_address
27591 + (unsigned long) fixP->fx_where) & ~3)
27592 + (unsigned long) value);
a737bd4d 27593
c19d1205
ZW
27594 if (value & ~0x3fc)
27595 as_bad_where (fixP->fx_file, fixP->fx_line,
27596 _("invalid offset, value too big (0x%08lX)"),
27597 (long) value);
a737bd4d 27598
c19d1205
ZW
27599 newval |= value >> 2;
27600 break;
a737bd4d 27601
c19d1205
ZW
27602 case 9: /* SP load/store. */
27603 if (value & ~0x3fc)
27604 as_bad_where (fixP->fx_file, fixP->fx_line,
27605 _("invalid offset, value too big (0x%08lX)"),
27606 (long) value);
27607 newval |= value >> 2;
27608 break;
6c43fab6 27609
c19d1205
ZW
27610 case 6: /* Word load/store. */
27611 if (value & ~0x7c)
27612 as_bad_where (fixP->fx_file, fixP->fx_line,
27613 _("invalid offset, value too big (0x%08lX)"),
27614 (long) value);
27615 newval |= value << 4; /* 6 - 2. */
27616 break;
a737bd4d 27617
c19d1205
ZW
27618 case 7: /* Byte load/store. */
27619 if (value & ~0x1f)
27620 as_bad_where (fixP->fx_file, fixP->fx_line,
27621 _("invalid offset, value too big (0x%08lX)"),
27622 (long) value);
27623 newval |= value << 6;
27624 break;
a737bd4d 27625
c19d1205
ZW
27626 case 8: /* Halfword load/store. */
27627 if (value & ~0x3e)
27628 as_bad_where (fixP->fx_file, fixP->fx_line,
27629 _("invalid offset, value too big (0x%08lX)"),
27630 (long) value);
27631 newval |= value << 5; /* 6 - 1. */
27632 break;
a737bd4d 27633
c19d1205
ZW
27634 default:
27635 as_bad_where (fixP->fx_file, fixP->fx_line,
27636 "Unable to process relocation for thumb opcode: %lx",
27637 (unsigned long) newval);
27638 break;
27639 }
27640 md_number_to_chars (buf, newval, THUMB_SIZE);
27641 break;
a737bd4d 27642
c19d1205
ZW
27643 case BFD_RELOC_ARM_THUMB_ADD:
27644 /* This is a complicated relocation, since we use it for all of
27645 the following immediate relocations:
a737bd4d 27646
c19d1205
ZW
27647 3bit ADD/SUB
27648 8bit ADD/SUB
27649 9bit ADD/SUB SP word-aligned
27650 10bit ADD PC/SP word-aligned
a737bd4d 27651
c19d1205
ZW
27652 The type of instruction being processed is encoded in the
27653 instruction field:
a737bd4d 27654
c19d1205
ZW
27655 0x8000 SUB
27656 0x00F0 Rd
27657 0x000F Rs
27658 */
27659 newval = md_chars_to_number (buf, THUMB_SIZE);
27660 {
27661 int rd = (newval >> 4) & 0xf;
27662 int rs = newval & 0xf;
27663 int subtract = !!(newval & 0x8000);
a737bd4d 27664
c19d1205
ZW
27665 /* Check for HI regs, only very restricted cases allowed:
27666 Adjusting SP, and using PC or SP to get an address. */
27667 if ((rd > 7 && (rd != REG_SP || rs != REG_SP))
27668 || (rs > 7 && rs != REG_SP && rs != REG_PC))
27669 as_bad_where (fixP->fx_file, fixP->fx_line,
27670 _("invalid Hi register with immediate"));
a737bd4d 27671
c19d1205
ZW
27672 /* If value is negative, choose the opposite instruction. */
27673 if (value < 0)
27674 {
27675 value = -value;
27676 subtract = !subtract;
27677 if (value < 0)
27678 as_bad_where (fixP->fx_file, fixP->fx_line,
27679 _("immediate value out of range"));
27680 }
a737bd4d 27681
c19d1205
ZW
27682 if (rd == REG_SP)
27683 {
75c11999 27684 if (value & ~0x1fc)
c19d1205
ZW
27685 as_bad_where (fixP->fx_file, fixP->fx_line,
27686 _("invalid immediate for stack address calculation"));
27687 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
27688 newval |= value >> 2;
27689 }
27690 else if (rs == REG_PC || rs == REG_SP)
27691 {
c12d2c9d
NC
27692 /* PR gas/18541. If the addition is for a defined symbol
27693 within range of an ADR instruction then accept it. */
27694 if (subtract
27695 && value == 4
27696 && fixP->fx_addsy != NULL)
27697 {
27698 subtract = 0;
27699
27700 if (! S_IS_DEFINED (fixP->fx_addsy)
27701 || S_GET_SEGMENT (fixP->fx_addsy) != seg
27702 || S_IS_WEAK (fixP->fx_addsy))
27703 {
27704 as_bad_where (fixP->fx_file, fixP->fx_line,
27705 _("address calculation needs a strongly defined nearby symbol"));
27706 }
27707 else
27708 {
27709 offsetT v = fixP->fx_where + fixP->fx_frag->fr_address;
27710
27711 /* Round up to the next 4-byte boundary. */
27712 if (v & 3)
27713 v = (v + 3) & ~ 3;
27714 else
27715 v += 4;
27716 v = S_GET_VALUE (fixP->fx_addsy) - v;
27717
27718 if (v & ~0x3fc)
27719 {
27720 as_bad_where (fixP->fx_file, fixP->fx_line,
27721 _("symbol too far away"));
27722 }
27723 else
27724 {
27725 fixP->fx_done = 1;
27726 value = v;
27727 }
27728 }
27729 }
27730
c19d1205
ZW
27731 if (subtract || value & ~0x3fc)
27732 as_bad_where (fixP->fx_file, fixP->fx_line,
27733 _("invalid immediate for address calculation (value = 0x%08lX)"),
5fc177c8 27734 (unsigned long) (subtract ? - value : value));
c19d1205
ZW
27735 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
27736 newval |= rd << 8;
27737 newval |= value >> 2;
27738 }
27739 else if (rs == rd)
27740 {
27741 if (value & ~0xff)
27742 as_bad_where (fixP->fx_file, fixP->fx_line,
27743 _("immediate value out of range"));
27744 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
27745 newval |= (rd << 8) | value;
27746 }
27747 else
27748 {
27749 if (value & ~0x7)
27750 as_bad_where (fixP->fx_file, fixP->fx_line,
27751 _("immediate value out of range"));
27752 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
27753 newval |= rd | (rs << 3) | (value << 6);
27754 }
27755 }
27756 md_number_to_chars (buf, newval, THUMB_SIZE);
27757 break;
a737bd4d 27758
c19d1205
ZW
27759 case BFD_RELOC_ARM_THUMB_IMM:
27760 newval = md_chars_to_number (buf, THUMB_SIZE);
27761 if (value < 0 || value > 255)
27762 as_bad_where (fixP->fx_file, fixP->fx_line,
4e6e072b 27763 _("invalid immediate: %ld is out of range"),
c19d1205
ZW
27764 (long) value);
27765 newval |= value;
27766 md_number_to_chars (buf, newval, THUMB_SIZE);
27767 break;
a737bd4d 27768
c19d1205
ZW
27769 case BFD_RELOC_ARM_THUMB_SHIFT:
27770 /* 5bit shift value (0..32). LSL cannot take 32. */
27771 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf83f;
27772 temp = newval & 0xf800;
27773 if (value < 0 || value > 32 || (value == 32 && temp == T_OPCODE_LSL_I))
27774 as_bad_where (fixP->fx_file, fixP->fx_line,
27775 _("invalid shift value: %ld"), (long) value);
27776 /* Shifts of zero must be encoded as LSL. */
27777 if (value == 0)
27778 newval = (newval & 0x003f) | T_OPCODE_LSL_I;
27779 /* Shifts of 32 are encoded as zero. */
27780 else if (value == 32)
27781 value = 0;
27782 newval |= value << 6;
27783 md_number_to_chars (buf, newval, THUMB_SIZE);
27784 break;
a737bd4d 27785
c19d1205
ZW
27786 case BFD_RELOC_VTABLE_INHERIT:
27787 case BFD_RELOC_VTABLE_ENTRY:
27788 fixP->fx_done = 0;
27789 return;
6c43fab6 27790
b6895b4f
PB
27791 case BFD_RELOC_ARM_MOVW:
27792 case BFD_RELOC_ARM_MOVT:
27793 case BFD_RELOC_ARM_THUMB_MOVW:
27794 case BFD_RELOC_ARM_THUMB_MOVT:
27795 if (fixP->fx_done || !seg->use_rela_p)
27796 {
27797 /* REL format relocations are limited to a 16-bit addend. */
27798 if (!fixP->fx_done)
27799 {
39623e12 27800 if (value < -0x8000 || value > 0x7fff)
b6895b4f 27801 as_bad_where (fixP->fx_file, fixP->fx_line,
ff5075ca 27802 _("offset out of range"));
b6895b4f
PB
27803 }
27804 else if (fixP->fx_r_type == BFD_RELOC_ARM_MOVT
27805 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
27806 {
27807 value >>= 16;
27808 }
27809
27810 if (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
27811 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
27812 {
27813 newval = get_thumb32_insn (buf);
27814 newval &= 0xfbf08f00;
27815 newval |= (value & 0xf000) << 4;
27816 newval |= (value & 0x0800) << 15;
27817 newval |= (value & 0x0700) << 4;
27818 newval |= (value & 0x00ff);
27819 put_thumb32_insn (buf, newval);
27820 }
27821 else
27822 {
27823 newval = md_chars_to_number (buf, 4);
27824 newval &= 0xfff0f000;
27825 newval |= value & 0x0fff;
27826 newval |= (value & 0xf000) << 4;
27827 md_number_to_chars (buf, newval, 4);
27828 }
27829 }
27830 return;
27831
72d98d16
MG
27832 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
27833 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
27834 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
27835 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
27836 gas_assert (!fixP->fx_done);
27837 {
27838 bfd_vma insn;
27839 bfd_boolean is_mov;
27840 bfd_vma encoded_addend = value;
27841
27842 /* Check that addend can be encoded in instruction. */
27843 if (!seg->use_rela_p && (value < 0 || value > 255))
27844 as_bad_where (fixP->fx_file, fixP->fx_line,
27845 _("the offset 0x%08lX is not representable"),
27846 (unsigned long) encoded_addend);
27847
27848 /* Extract the instruction. */
27849 insn = md_chars_to_number (buf, THUMB_SIZE);
27850 is_mov = (insn & 0xf800) == 0x2000;
27851
27852 /* Encode insn. */
27853 if (is_mov)
27854 {
27855 if (!seg->use_rela_p)
27856 insn |= encoded_addend;
27857 }
27858 else
27859 {
27860 int rd, rs;
27861
27862 /* Extract the instruction. */
27863 /* Encoding is the following
27864 0x8000 SUB
27865 0x00F0 Rd
27866 0x000F Rs
27867 */
27868 /* The following conditions must be true :
27869 - ADD
27870 - Rd == Rs
27871 - Rd <= 7
27872 */
27873 rd = (insn >> 4) & 0xf;
27874 rs = insn & 0xf;
27875 if ((insn & 0x8000) || (rd != rs) || rd > 7)
27876 as_bad_where (fixP->fx_file, fixP->fx_line,
27877 _("Unable to process relocation for thumb opcode: %lx"),
27878 (unsigned long) insn);
27879
27880 /* Encode as ADD immediate8 thumb 1 code. */
27881 insn = 0x3000 | (rd << 8);
27882
27883 /* Place the encoded addend into the first 8 bits of the
27884 instruction. */
27885 if (!seg->use_rela_p)
27886 insn |= encoded_addend;
27887 }
27888
27889 /* Update the instruction. */
27890 md_number_to_chars (buf, insn, THUMB_SIZE);
27891 }
27892 break;
27893
4962c51a
MS
27894 case BFD_RELOC_ARM_ALU_PC_G0_NC:
27895 case BFD_RELOC_ARM_ALU_PC_G0:
27896 case BFD_RELOC_ARM_ALU_PC_G1_NC:
27897 case BFD_RELOC_ARM_ALU_PC_G1:
27898 case BFD_RELOC_ARM_ALU_PC_G2:
27899 case BFD_RELOC_ARM_ALU_SB_G0_NC:
27900 case BFD_RELOC_ARM_ALU_SB_G0:
27901 case BFD_RELOC_ARM_ALU_SB_G1_NC:
27902 case BFD_RELOC_ARM_ALU_SB_G1:
27903 case BFD_RELOC_ARM_ALU_SB_G2:
9c2799c2 27904 gas_assert (!fixP->fx_done);
4962c51a
MS
27905 if (!seg->use_rela_p)
27906 {
477330fc
RM
27907 bfd_vma insn;
27908 bfd_vma encoded_addend;
3ca4a8ec 27909 bfd_vma addend_abs = llabs (value);
477330fc
RM
27910
27911 /* Check that the absolute value of the addend can be
27912 expressed as an 8-bit constant plus a rotation. */
27913 encoded_addend = encode_arm_immediate (addend_abs);
27914 if (encoded_addend == (unsigned int) FAIL)
4962c51a 27915 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
27916 _("the offset 0x%08lX is not representable"),
27917 (unsigned long) addend_abs);
27918
27919 /* Extract the instruction. */
27920 insn = md_chars_to_number (buf, INSN_SIZE);
27921
27922 /* If the addend is positive, use an ADD instruction.
27923 Otherwise use a SUB. Take care not to destroy the S bit. */
27924 insn &= 0xff1fffff;
27925 if (value < 0)
27926 insn |= 1 << 22;
27927 else
27928 insn |= 1 << 23;
27929
27930 /* Place the encoded addend into the first 12 bits of the
27931 instruction. */
27932 insn &= 0xfffff000;
27933 insn |= encoded_addend;
27934
27935 /* Update the instruction. */
27936 md_number_to_chars (buf, insn, INSN_SIZE);
4962c51a
MS
27937 }
27938 break;
27939
27940 case BFD_RELOC_ARM_LDR_PC_G0:
27941 case BFD_RELOC_ARM_LDR_PC_G1:
27942 case BFD_RELOC_ARM_LDR_PC_G2:
27943 case BFD_RELOC_ARM_LDR_SB_G0:
27944 case BFD_RELOC_ARM_LDR_SB_G1:
27945 case BFD_RELOC_ARM_LDR_SB_G2:
9c2799c2 27946 gas_assert (!fixP->fx_done);
4962c51a 27947 if (!seg->use_rela_p)
477330fc
RM
27948 {
27949 bfd_vma insn;
3ca4a8ec 27950 bfd_vma addend_abs = llabs (value);
4962c51a 27951
477330fc
RM
27952 /* Check that the absolute value of the addend can be
27953 encoded in 12 bits. */
27954 if (addend_abs >= 0x1000)
4962c51a 27955 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
27956 _("bad offset 0x%08lX (only 12 bits available for the magnitude)"),
27957 (unsigned long) addend_abs);
27958
27959 /* Extract the instruction. */
27960 insn = md_chars_to_number (buf, INSN_SIZE);
27961
27962 /* If the addend is negative, clear bit 23 of the instruction.
27963 Otherwise set it. */
27964 if (value < 0)
27965 insn &= ~(1 << 23);
27966 else
27967 insn |= 1 << 23;
27968
27969 /* Place the absolute value of the addend into the first 12 bits
27970 of the instruction. */
27971 insn &= 0xfffff000;
27972 insn |= addend_abs;
27973
27974 /* Update the instruction. */
27975 md_number_to_chars (buf, insn, INSN_SIZE);
27976 }
4962c51a
MS
27977 break;
27978
27979 case BFD_RELOC_ARM_LDRS_PC_G0:
27980 case BFD_RELOC_ARM_LDRS_PC_G1:
27981 case BFD_RELOC_ARM_LDRS_PC_G2:
27982 case BFD_RELOC_ARM_LDRS_SB_G0:
27983 case BFD_RELOC_ARM_LDRS_SB_G1:
27984 case BFD_RELOC_ARM_LDRS_SB_G2:
9c2799c2 27985 gas_assert (!fixP->fx_done);
4962c51a 27986 if (!seg->use_rela_p)
477330fc
RM
27987 {
27988 bfd_vma insn;
3ca4a8ec 27989 bfd_vma addend_abs = llabs (value);
4962c51a 27990
477330fc
RM
27991 /* Check that the absolute value of the addend can be
27992 encoded in 8 bits. */
27993 if (addend_abs >= 0x100)
4962c51a 27994 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
27995 _("bad offset 0x%08lX (only 8 bits available for the magnitude)"),
27996 (unsigned long) addend_abs);
27997
27998 /* Extract the instruction. */
27999 insn = md_chars_to_number (buf, INSN_SIZE);
28000
28001 /* If the addend is negative, clear bit 23 of the instruction.
28002 Otherwise set it. */
28003 if (value < 0)
28004 insn &= ~(1 << 23);
28005 else
28006 insn |= 1 << 23;
28007
28008 /* Place the first four bits of the absolute value of the addend
28009 into the first 4 bits of the instruction, and the remaining
28010 four into bits 8 .. 11. */
28011 insn &= 0xfffff0f0;
28012 insn |= (addend_abs & 0xf) | ((addend_abs & 0xf0) << 4);
28013
28014 /* Update the instruction. */
28015 md_number_to_chars (buf, insn, INSN_SIZE);
28016 }
4962c51a
MS
28017 break;
28018
28019 case BFD_RELOC_ARM_LDC_PC_G0:
28020 case BFD_RELOC_ARM_LDC_PC_G1:
28021 case BFD_RELOC_ARM_LDC_PC_G2:
28022 case BFD_RELOC_ARM_LDC_SB_G0:
28023 case BFD_RELOC_ARM_LDC_SB_G1:
28024 case BFD_RELOC_ARM_LDC_SB_G2:
9c2799c2 28025 gas_assert (!fixP->fx_done);
4962c51a 28026 if (!seg->use_rela_p)
477330fc
RM
28027 {
28028 bfd_vma insn;
3ca4a8ec 28029 bfd_vma addend_abs = llabs (value);
4962c51a 28030
477330fc
RM
28031 /* Check that the absolute value of the addend is a multiple of
28032 four and, when divided by four, fits in 8 bits. */
28033 if (addend_abs & 0x3)
4962c51a 28034 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
28035 _("bad offset 0x%08lX (must be word-aligned)"),
28036 (unsigned long) addend_abs);
4962c51a 28037
477330fc 28038 if ((addend_abs >> 2) > 0xff)
4962c51a 28039 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
28040 _("bad offset 0x%08lX (must be an 8-bit number of words)"),
28041 (unsigned long) addend_abs);
28042
28043 /* Extract the instruction. */
28044 insn = md_chars_to_number (buf, INSN_SIZE);
28045
28046 /* If the addend is negative, clear bit 23 of the instruction.
28047 Otherwise set it. */
28048 if (value < 0)
28049 insn &= ~(1 << 23);
28050 else
28051 insn |= 1 << 23;
28052
28053 /* Place the addend (divided by four) into the first eight
28054 bits of the instruction. */
28055 insn &= 0xfffffff0;
28056 insn |= addend_abs >> 2;
28057
28058 /* Update the instruction. */
28059 md_number_to_chars (buf, insn, INSN_SIZE);
28060 }
4962c51a
MS
28061 break;
28062
e12437dc
AV
28063 case BFD_RELOC_THUMB_PCREL_BRANCH5:
28064 if (fixP->fx_addsy
28065 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28066 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
28067 && ARM_IS_FUNC (fixP->fx_addsy)
28068 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
28069 {
28070 /* Force a relocation for a branch 5 bits wide. */
28071 fixP->fx_done = 0;
28072 }
28073 if (v8_1_branch_value_check (value, 5, FALSE) == FAIL)
28074 as_bad_where (fixP->fx_file, fixP->fx_line,
28075 BAD_BRANCH_OFF);
28076
28077 if (fixP->fx_done || !seg->use_rela_p)
28078 {
28079 addressT boff = value >> 1;
28080
28081 newval = md_chars_to_number (buf, THUMB_SIZE);
28082 newval |= (boff << 7);
28083 md_number_to_chars (buf, newval, THUMB_SIZE);
28084 }
28085 break;
28086
f6b2b12d
AV
28087 case BFD_RELOC_THUMB_PCREL_BFCSEL:
28088 if (fixP->fx_addsy
28089 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28090 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
28091 && ARM_IS_FUNC (fixP->fx_addsy)
28092 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
28093 {
28094 fixP->fx_done = 0;
28095 }
28096 if ((value & ~0x7f) && ((value & ~0x3f) != ~0x3f))
28097 as_bad_where (fixP->fx_file, fixP->fx_line,
28098 _("branch out of range"));
28099
28100 if (fixP->fx_done || !seg->use_rela_p)
28101 {
28102 newval = md_chars_to_number (buf, THUMB_SIZE);
28103
28104 addressT boff = ((newval & 0x0780) >> 7) << 1;
28105 addressT diff = value - boff;
28106
28107 if (diff == 4)
28108 {
28109 newval |= 1 << 1; /* T bit. */
28110 }
28111 else if (diff != 2)
28112 {
28113 as_bad_where (fixP->fx_file, fixP->fx_line,
28114 _("out of range label-relative fixup value"));
28115 }
28116 md_number_to_chars (buf, newval, THUMB_SIZE);
28117 }
28118 break;
28119
e5d6e09e
AV
28120 case BFD_RELOC_ARM_THUMB_BF17:
28121 if (fixP->fx_addsy
28122 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28123 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
28124 && ARM_IS_FUNC (fixP->fx_addsy)
28125 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
28126 {
28127 /* Force a relocation for a branch 17 bits wide. */
28128 fixP->fx_done = 0;
28129 }
28130
28131 if (v8_1_branch_value_check (value, 17, TRUE) == FAIL)
28132 as_bad_where (fixP->fx_file, fixP->fx_line,
28133 BAD_BRANCH_OFF);
28134
28135 if (fixP->fx_done || !seg->use_rela_p)
28136 {
28137 offsetT newval2;
28138 addressT immA, immB, immC;
28139
28140 immA = (value & 0x0001f000) >> 12;
28141 immB = (value & 0x00000ffc) >> 2;
28142 immC = (value & 0x00000002) >> 1;
28143
28144 newval = md_chars_to_number (buf, THUMB_SIZE);
28145 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
28146 newval |= immA;
28147 newval2 |= (immC << 11) | (immB << 1);
28148 md_number_to_chars (buf, newval, THUMB_SIZE);
28149 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
28150 }
28151 break;
28152
1caf72a5
AV
28153 case BFD_RELOC_ARM_THUMB_BF19:
28154 if (fixP->fx_addsy
28155 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28156 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
28157 && ARM_IS_FUNC (fixP->fx_addsy)
28158 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
28159 {
28160 /* Force a relocation for a branch 19 bits wide. */
28161 fixP->fx_done = 0;
28162 }
28163
28164 if (v8_1_branch_value_check (value, 19, TRUE) == FAIL)
28165 as_bad_where (fixP->fx_file, fixP->fx_line,
28166 BAD_BRANCH_OFF);
28167
28168 if (fixP->fx_done || !seg->use_rela_p)
28169 {
28170 offsetT newval2;
28171 addressT immA, immB, immC;
28172
28173 immA = (value & 0x0007f000) >> 12;
28174 immB = (value & 0x00000ffc) >> 2;
28175 immC = (value & 0x00000002) >> 1;
28176
28177 newval = md_chars_to_number (buf, THUMB_SIZE);
28178 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
28179 newval |= immA;
28180 newval2 |= (immC << 11) | (immB << 1);
28181 md_number_to_chars (buf, newval, THUMB_SIZE);
28182 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
28183 }
28184 break;
28185
1889da70
AV
28186 case BFD_RELOC_ARM_THUMB_BF13:
28187 if (fixP->fx_addsy
28188 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28189 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
28190 && ARM_IS_FUNC (fixP->fx_addsy)
28191 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
28192 {
28193 /* Force a relocation for a branch 13 bits wide. */
28194 fixP->fx_done = 0;
28195 }
28196
28197 if (v8_1_branch_value_check (value, 13, TRUE) == FAIL)
28198 as_bad_where (fixP->fx_file, fixP->fx_line,
28199 BAD_BRANCH_OFF);
28200
28201 if (fixP->fx_done || !seg->use_rela_p)
28202 {
28203 offsetT newval2;
28204 addressT immA, immB, immC;
28205
28206 immA = (value & 0x00001000) >> 12;
28207 immB = (value & 0x00000ffc) >> 2;
28208 immC = (value & 0x00000002) >> 1;
28209
28210 newval = md_chars_to_number (buf, THUMB_SIZE);
28211 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
28212 newval |= immA;
28213 newval2 |= (immC << 11) | (immB << 1);
28214 md_number_to_chars (buf, newval, THUMB_SIZE);
28215 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
28216 }
28217 break;
28218
60f993ce
AV
28219 case BFD_RELOC_ARM_THUMB_LOOP12:
28220 if (fixP->fx_addsy
28221 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28222 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
28223 && ARM_IS_FUNC (fixP->fx_addsy)
28224 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
28225 {
28226 /* Force a relocation for a branch 12 bits wide. */
28227 fixP->fx_done = 0;
28228 }
28229
28230 bfd_vma insn = get_thumb32_insn (buf);
28231 /* le lr, <label> or le <label> */
28232 if (((insn & 0xffffffff) == 0xf00fc001)
28233 || ((insn & 0xffffffff) == 0xf02fc001))
28234 value = -value;
28235
28236 if (v8_1_branch_value_check (value, 12, FALSE) == FAIL)
28237 as_bad_where (fixP->fx_file, fixP->fx_line,
28238 BAD_BRANCH_OFF);
28239 if (fixP->fx_done || !seg->use_rela_p)
28240 {
28241 addressT imml, immh;
28242
28243 immh = (value & 0x00000ffc) >> 2;
28244 imml = (value & 0x00000002) >> 1;
28245
28246 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
28247 newval |= (imml << 11) | (immh << 1);
28248 md_number_to_chars (buf + THUMB_SIZE, newval, THUMB_SIZE);
28249 }
28250 break;
28251
845b51d6
PB
28252 case BFD_RELOC_ARM_V4BX:
28253 /* This will need to go in the object file. */
28254 fixP->fx_done = 0;
28255 break;
28256
c19d1205
ZW
28257 case BFD_RELOC_UNUSED:
28258 default:
28259 as_bad_where (fixP->fx_file, fixP->fx_line,
28260 _("bad relocation fixup type (%d)"), fixP->fx_r_type);
28261 }
6c43fab6
RE
28262}
28263
c19d1205
ZW
28264/* Translate internal representation of relocation info to BFD target
28265 format. */
a737bd4d 28266
c19d1205 28267arelent *
00a97672 28268tc_gen_reloc (asection *section, fixS *fixp)
a737bd4d 28269{
c19d1205
ZW
28270 arelent * reloc;
28271 bfd_reloc_code_real_type code;
a737bd4d 28272
325801bd 28273 reloc = XNEW (arelent);
a737bd4d 28274
325801bd 28275 reloc->sym_ptr_ptr = XNEW (asymbol *);
c19d1205
ZW
28276 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
28277 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
a737bd4d 28278
2fc8bdac 28279 if (fixp->fx_pcrel)
00a97672
RS
28280 {
28281 if (section->use_rela_p)
28282 fixp->fx_offset -= md_pcrel_from_section (fixp, section);
28283 else
28284 fixp->fx_offset = reloc->address;
28285 }
c19d1205 28286 reloc->addend = fixp->fx_offset;
a737bd4d 28287
c19d1205 28288 switch (fixp->fx_r_type)
a737bd4d 28289 {
c19d1205
ZW
28290 case BFD_RELOC_8:
28291 if (fixp->fx_pcrel)
28292 {
28293 code = BFD_RELOC_8_PCREL;
28294 break;
28295 }
1a0670f3 28296 /* Fall through. */
a737bd4d 28297
c19d1205
ZW
28298 case BFD_RELOC_16:
28299 if (fixp->fx_pcrel)
28300 {
28301 code = BFD_RELOC_16_PCREL;
28302 break;
28303 }
1a0670f3 28304 /* Fall through. */
6c43fab6 28305
c19d1205
ZW
28306 case BFD_RELOC_32:
28307 if (fixp->fx_pcrel)
28308 {
28309 code = BFD_RELOC_32_PCREL;
28310 break;
28311 }
1a0670f3 28312 /* Fall through. */
a737bd4d 28313
b6895b4f
PB
28314 case BFD_RELOC_ARM_MOVW:
28315 if (fixp->fx_pcrel)
28316 {
28317 code = BFD_RELOC_ARM_MOVW_PCREL;
28318 break;
28319 }
1a0670f3 28320 /* Fall through. */
b6895b4f
PB
28321
28322 case BFD_RELOC_ARM_MOVT:
28323 if (fixp->fx_pcrel)
28324 {
28325 code = BFD_RELOC_ARM_MOVT_PCREL;
28326 break;
28327 }
1a0670f3 28328 /* Fall through. */
b6895b4f
PB
28329
28330 case BFD_RELOC_ARM_THUMB_MOVW:
28331 if (fixp->fx_pcrel)
28332 {
28333 code = BFD_RELOC_ARM_THUMB_MOVW_PCREL;
28334 break;
28335 }
1a0670f3 28336 /* Fall through. */
b6895b4f
PB
28337
28338 case BFD_RELOC_ARM_THUMB_MOVT:
28339 if (fixp->fx_pcrel)
28340 {
28341 code = BFD_RELOC_ARM_THUMB_MOVT_PCREL;
28342 break;
28343 }
1a0670f3 28344 /* Fall through. */
b6895b4f 28345
c19d1205
ZW
28346 case BFD_RELOC_NONE:
28347 case BFD_RELOC_ARM_PCREL_BRANCH:
28348 case BFD_RELOC_ARM_PCREL_BLX:
28349 case BFD_RELOC_RVA:
28350 case BFD_RELOC_THUMB_PCREL_BRANCH7:
28351 case BFD_RELOC_THUMB_PCREL_BRANCH9:
28352 case BFD_RELOC_THUMB_PCREL_BRANCH12:
28353 case BFD_RELOC_THUMB_PCREL_BRANCH20:
28354 case BFD_RELOC_THUMB_PCREL_BRANCH23:
28355 case BFD_RELOC_THUMB_PCREL_BRANCH25:
c19d1205
ZW
28356 case BFD_RELOC_VTABLE_ENTRY:
28357 case BFD_RELOC_VTABLE_INHERIT:
f0927246
NC
28358#ifdef TE_PE
28359 case BFD_RELOC_32_SECREL:
28360#endif
c19d1205
ZW
28361 code = fixp->fx_r_type;
28362 break;
a737bd4d 28363
00adf2d4
JB
28364 case BFD_RELOC_THUMB_PCREL_BLX:
28365#ifdef OBJ_ELF
28366 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
28367 code = BFD_RELOC_THUMB_PCREL_BRANCH23;
28368 else
28369#endif
28370 code = BFD_RELOC_THUMB_PCREL_BLX;
28371 break;
28372
c19d1205
ZW
28373 case BFD_RELOC_ARM_LITERAL:
28374 case BFD_RELOC_ARM_HWLITERAL:
28375 /* If this is called then the a literal has
28376 been referenced across a section boundary. */
28377 as_bad_where (fixp->fx_file, fixp->fx_line,
28378 _("literal referenced across section boundary"));
28379 return NULL;
a737bd4d 28380
c19d1205 28381#ifdef OBJ_ELF
0855e32b
NS
28382 case BFD_RELOC_ARM_TLS_CALL:
28383 case BFD_RELOC_ARM_THM_TLS_CALL:
28384 case BFD_RELOC_ARM_TLS_DESCSEQ:
28385 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
c19d1205
ZW
28386 case BFD_RELOC_ARM_GOT32:
28387 case BFD_RELOC_ARM_GOTOFF:
b43420e6 28388 case BFD_RELOC_ARM_GOT_PREL:
c19d1205
ZW
28389 case BFD_RELOC_ARM_PLT32:
28390 case BFD_RELOC_ARM_TARGET1:
28391 case BFD_RELOC_ARM_ROSEGREL32:
28392 case BFD_RELOC_ARM_SBREL32:
28393 case BFD_RELOC_ARM_PREL31:
28394 case BFD_RELOC_ARM_TARGET2:
c19d1205 28395 case BFD_RELOC_ARM_TLS_LDO32:
39b41c9c
PB
28396 case BFD_RELOC_ARM_PCREL_CALL:
28397 case BFD_RELOC_ARM_PCREL_JUMP:
4962c51a
MS
28398 case BFD_RELOC_ARM_ALU_PC_G0_NC:
28399 case BFD_RELOC_ARM_ALU_PC_G0:
28400 case BFD_RELOC_ARM_ALU_PC_G1_NC:
28401 case BFD_RELOC_ARM_ALU_PC_G1:
28402 case BFD_RELOC_ARM_ALU_PC_G2:
28403 case BFD_RELOC_ARM_LDR_PC_G0:
28404 case BFD_RELOC_ARM_LDR_PC_G1:
28405 case BFD_RELOC_ARM_LDR_PC_G2:
28406 case BFD_RELOC_ARM_LDRS_PC_G0:
28407 case BFD_RELOC_ARM_LDRS_PC_G1:
28408 case BFD_RELOC_ARM_LDRS_PC_G2:
28409 case BFD_RELOC_ARM_LDC_PC_G0:
28410 case BFD_RELOC_ARM_LDC_PC_G1:
28411 case BFD_RELOC_ARM_LDC_PC_G2:
28412 case BFD_RELOC_ARM_ALU_SB_G0_NC:
28413 case BFD_RELOC_ARM_ALU_SB_G0:
28414 case BFD_RELOC_ARM_ALU_SB_G1_NC:
28415 case BFD_RELOC_ARM_ALU_SB_G1:
28416 case BFD_RELOC_ARM_ALU_SB_G2:
28417 case BFD_RELOC_ARM_LDR_SB_G0:
28418 case BFD_RELOC_ARM_LDR_SB_G1:
28419 case BFD_RELOC_ARM_LDR_SB_G2:
28420 case BFD_RELOC_ARM_LDRS_SB_G0:
28421 case BFD_RELOC_ARM_LDRS_SB_G1:
28422 case BFD_RELOC_ARM_LDRS_SB_G2:
28423 case BFD_RELOC_ARM_LDC_SB_G0:
28424 case BFD_RELOC_ARM_LDC_SB_G1:
28425 case BFD_RELOC_ARM_LDC_SB_G2:
845b51d6 28426 case BFD_RELOC_ARM_V4BX:
72d98d16
MG
28427 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
28428 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
28429 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
28430 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
188fd7ae
CL
28431 case BFD_RELOC_ARM_GOTFUNCDESC:
28432 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
28433 case BFD_RELOC_ARM_FUNCDESC:
e5d6e09e 28434 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 28435 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 28436 case BFD_RELOC_ARM_THUMB_BF13:
c19d1205
ZW
28437 code = fixp->fx_r_type;
28438 break;
a737bd4d 28439
0855e32b 28440 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205 28441 case BFD_RELOC_ARM_TLS_GD32:
5c5a4843 28442 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
75c11999 28443 case BFD_RELOC_ARM_TLS_LE32:
c19d1205 28444 case BFD_RELOC_ARM_TLS_IE32:
5c5a4843 28445 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
c19d1205 28446 case BFD_RELOC_ARM_TLS_LDM32:
5c5a4843 28447 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
c19d1205
ZW
28448 /* BFD will include the symbol's address in the addend.
28449 But we don't want that, so subtract it out again here. */
28450 if (!S_IS_COMMON (fixp->fx_addsy))
28451 reloc->addend -= (*reloc->sym_ptr_ptr)->value;
28452 code = fixp->fx_r_type;
28453 break;
28454#endif
a737bd4d 28455
c19d1205
ZW
28456 case BFD_RELOC_ARM_IMMEDIATE:
28457 as_bad_where (fixp->fx_file, fixp->fx_line,
28458 _("internal relocation (type: IMMEDIATE) not fixed up"));
28459 return NULL;
a737bd4d 28460
c19d1205
ZW
28461 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
28462 as_bad_where (fixp->fx_file, fixp->fx_line,
28463 _("ADRL used for a symbol not defined in the same file"));
28464 return NULL;
a737bd4d 28465
e12437dc 28466 case BFD_RELOC_THUMB_PCREL_BRANCH5:
f6b2b12d 28467 case BFD_RELOC_THUMB_PCREL_BFCSEL:
60f993ce 28468 case BFD_RELOC_ARM_THUMB_LOOP12:
e12437dc
AV
28469 as_bad_where (fixp->fx_file, fixp->fx_line,
28470 _("%s used for a symbol not defined in the same file"),
28471 bfd_get_reloc_code_name (fixp->fx_r_type));
28472 return NULL;
28473
c19d1205 28474 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
28475 if (section->use_rela_p)
28476 {
28477 code = fixp->fx_r_type;
28478 break;
28479 }
28480
c19d1205
ZW
28481 if (fixp->fx_addsy != NULL
28482 && !S_IS_DEFINED (fixp->fx_addsy)
28483 && S_IS_LOCAL (fixp->fx_addsy))
a737bd4d 28484 {
c19d1205
ZW
28485 as_bad_where (fixp->fx_file, fixp->fx_line,
28486 _("undefined local label `%s'"),
28487 S_GET_NAME (fixp->fx_addsy));
28488 return NULL;
a737bd4d
NC
28489 }
28490
c19d1205
ZW
28491 as_bad_where (fixp->fx_file, fixp->fx_line,
28492 _("internal_relocation (type: OFFSET_IMM) not fixed up"));
28493 return NULL;
a737bd4d 28494
c19d1205
ZW
28495 default:
28496 {
e0471c16 28497 const char * type;
6c43fab6 28498
c19d1205
ZW
28499 switch (fixp->fx_r_type)
28500 {
28501 case BFD_RELOC_NONE: type = "NONE"; break;
28502 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
28503 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
3eb17e6b 28504 case BFD_RELOC_ARM_SMC: type = "SMC"; break;
c19d1205
ZW
28505 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
28506 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
28507 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
db187cb9 28508 case BFD_RELOC_ARM_T32_OFFSET_IMM: type = "T32_OFFSET_IMM"; break;
8f06b2d8 28509 case BFD_RELOC_ARM_T32_CP_OFF_IMM: type = "T32_CP_OFF_IMM"; break;
c19d1205
ZW
28510 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
28511 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
28512 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
28513 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
28514 default: type = _("<unknown>"); break;
28515 }
28516 as_bad_where (fixp->fx_file, fixp->fx_line,
28517 _("cannot represent %s relocation in this object file format"),
28518 type);
28519 return NULL;
28520 }
a737bd4d 28521 }
6c43fab6 28522
c19d1205
ZW
28523#ifdef OBJ_ELF
28524 if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
28525 && GOT_symbol
28526 && fixp->fx_addsy == GOT_symbol)
28527 {
28528 code = BFD_RELOC_ARM_GOTPC;
28529 reloc->addend = fixp->fx_offset = reloc->address;
28530 }
28531#endif
6c43fab6 28532
c19d1205 28533 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
6c43fab6 28534
c19d1205
ZW
28535 if (reloc->howto == NULL)
28536 {
28537 as_bad_where (fixp->fx_file, fixp->fx_line,
28538 _("cannot represent %s relocation in this object file format"),
28539 bfd_get_reloc_code_name (code));
28540 return NULL;
28541 }
6c43fab6 28542
c19d1205
ZW
28543 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
28544 vtable entry to be used in the relocation's section offset. */
28545 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
28546 reloc->address = fixp->fx_offset;
6c43fab6 28547
c19d1205 28548 return reloc;
6c43fab6
RE
28549}
28550
c19d1205 28551/* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6c43fab6 28552
c19d1205
ZW
28553void
28554cons_fix_new_arm (fragS * frag,
28555 int where,
28556 int size,
62ebcb5c
AM
28557 expressionS * exp,
28558 bfd_reloc_code_real_type reloc)
6c43fab6 28559{
c19d1205 28560 int pcrel = 0;
6c43fab6 28561
c19d1205
ZW
28562 /* Pick a reloc.
28563 FIXME: @@ Should look at CPU word size. */
28564 switch (size)
28565 {
28566 case 1:
62ebcb5c 28567 reloc = BFD_RELOC_8;
c19d1205
ZW
28568 break;
28569 case 2:
62ebcb5c 28570 reloc = BFD_RELOC_16;
c19d1205
ZW
28571 break;
28572 case 4:
28573 default:
62ebcb5c 28574 reloc = BFD_RELOC_32;
c19d1205
ZW
28575 break;
28576 case 8:
62ebcb5c 28577 reloc = BFD_RELOC_64;
c19d1205
ZW
28578 break;
28579 }
6c43fab6 28580
f0927246
NC
28581#ifdef TE_PE
28582 if (exp->X_op == O_secrel)
28583 {
28584 exp->X_op = O_symbol;
62ebcb5c 28585 reloc = BFD_RELOC_32_SECREL;
f0927246
NC
28586 }
28587#endif
28588
62ebcb5c 28589 fix_new_exp (frag, where, size, exp, pcrel, reloc);
c19d1205 28590}
6c43fab6 28591
4343666d 28592#if defined (OBJ_COFF)
c19d1205
ZW
28593void
28594arm_validate_fix (fixS * fixP)
6c43fab6 28595{
c19d1205
ZW
28596 /* If the destination of the branch is a defined symbol which does not have
28597 the THUMB_FUNC attribute, then we must be calling a function which has
28598 the (interfacearm) attribute. We look for the Thumb entry point to that
28599 function and change the branch to refer to that function instead. */
28600 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
28601 && fixP->fx_addsy != NULL
28602 && S_IS_DEFINED (fixP->fx_addsy)
28603 && ! THUMB_IS_FUNC (fixP->fx_addsy))
6c43fab6 28604 {
c19d1205 28605 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
6c43fab6 28606 }
c19d1205
ZW
28607}
28608#endif
6c43fab6 28609
267bf995 28610
c19d1205
ZW
28611int
28612arm_force_relocation (struct fix * fixp)
28613{
28614#if defined (OBJ_COFF) && defined (TE_PE)
28615 if (fixp->fx_r_type == BFD_RELOC_RVA)
28616 return 1;
28617#endif
6c43fab6 28618
267bf995
RR
28619 /* In case we have a call or a branch to a function in ARM ISA mode from
28620 a thumb function or vice-versa force the relocation. These relocations
28621 are cleared off for some cores that might have blx and simple transformations
28622 are possible. */
28623
28624#ifdef OBJ_ELF
28625 switch (fixp->fx_r_type)
28626 {
28627 case BFD_RELOC_ARM_PCREL_JUMP:
28628 case BFD_RELOC_ARM_PCREL_CALL:
28629 case BFD_RELOC_THUMB_PCREL_BLX:
28630 if (THUMB_IS_FUNC (fixp->fx_addsy))
28631 return 1;
28632 break;
28633
28634 case BFD_RELOC_ARM_PCREL_BLX:
28635 case BFD_RELOC_THUMB_PCREL_BRANCH25:
28636 case BFD_RELOC_THUMB_PCREL_BRANCH20:
28637 case BFD_RELOC_THUMB_PCREL_BRANCH23:
28638 if (ARM_IS_FUNC (fixp->fx_addsy))
28639 return 1;
28640 break;
28641
28642 default:
28643 break;
28644 }
28645#endif
28646
b5884301
PB
28647 /* Resolve these relocations even if the symbol is extern or weak.
28648 Technically this is probably wrong due to symbol preemption.
28649 In practice these relocations do not have enough range to be useful
28650 at dynamic link time, and some code (e.g. in the Linux kernel)
28651 expects these references to be resolved. */
c19d1205
ZW
28652 if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
28653 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
b5884301 28654 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM8
0110f2b8 28655 || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE
b5884301
PB
28656 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
28657 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2
28658 || fixp->fx_r_type == BFD_RELOC_ARM_THUMB_OFFSET
16805f35 28659 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM
0110f2b8
PB
28660 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
28661 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMM12
b5884301
PB
28662 || fixp->fx_r_type == BFD_RELOC_ARM_T32_OFFSET_IMM
28663 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_PC12
28664 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM
28665 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM_S2)
c19d1205 28666 return 0;
a737bd4d 28667
4962c51a
MS
28668 /* Always leave these relocations for the linker. */
28669 if ((fixp->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
28670 && fixp->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
28671 || fixp->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
28672 return 1;
28673
f0291e4c
PB
28674 /* Always generate relocations against function symbols. */
28675 if (fixp->fx_r_type == BFD_RELOC_32
28676 && fixp->fx_addsy
28677 && (symbol_get_bfdsym (fixp->fx_addsy)->flags & BSF_FUNCTION))
28678 return 1;
28679
c19d1205 28680 return generic_force_reloc (fixp);
404ff6b5
AH
28681}
28682
0ffdc86c 28683#if defined (OBJ_ELF) || defined (OBJ_COFF)
e28387c3
PB
28684/* Relocations against function names must be left unadjusted,
28685 so that the linker can use this information to generate interworking
28686 stubs. The MIPS version of this function
c19d1205
ZW
28687 also prevents relocations that are mips-16 specific, but I do not
28688 know why it does this.
404ff6b5 28689
c19d1205
ZW
28690 FIXME:
28691 There is one other problem that ought to be addressed here, but
28692 which currently is not: Taking the address of a label (rather
28693 than a function) and then later jumping to that address. Such
28694 addresses also ought to have their bottom bit set (assuming that
28695 they reside in Thumb code), but at the moment they will not. */
404ff6b5 28696
c19d1205
ZW
28697bfd_boolean
28698arm_fix_adjustable (fixS * fixP)
404ff6b5 28699{
c19d1205
ZW
28700 if (fixP->fx_addsy == NULL)
28701 return 1;
404ff6b5 28702
e28387c3
PB
28703 /* Preserve relocations against symbols with function type. */
28704 if (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_FUNCTION)
c921be7d 28705 return FALSE;
e28387c3 28706
c19d1205
ZW
28707 if (THUMB_IS_FUNC (fixP->fx_addsy)
28708 && fixP->fx_subsy == NULL)
c921be7d 28709 return FALSE;
a737bd4d 28710
c19d1205
ZW
28711 /* We need the symbol name for the VTABLE entries. */
28712 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
28713 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
c921be7d 28714 return FALSE;
404ff6b5 28715
c19d1205
ZW
28716 /* Don't allow symbols to be discarded on GOT related relocs. */
28717 if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
28718 || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
28719 || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
28720 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32
5c5a4843 28721 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32_FDPIC
c19d1205
ZW
28722 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LE32
28723 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32
5c5a4843 28724 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32_FDPIC
c19d1205 28725 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32
5c5a4843 28726 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32_FDPIC
c19d1205 28727 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDO32
0855e32b
NS
28728 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GOTDESC
28729 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_CALL
28730 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_CALL
28731 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_DESCSEQ
28732 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_DESCSEQ
c19d1205 28733 || fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
c921be7d 28734 return FALSE;
a737bd4d 28735
4962c51a
MS
28736 /* Similarly for group relocations. */
28737 if ((fixP->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
28738 && fixP->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
28739 || fixP->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
c921be7d 28740 return FALSE;
4962c51a 28741
79947c54
CD
28742 /* MOVW/MOVT REL relocations have limited offsets, so keep the symbols. */
28743 if (fixP->fx_r_type == BFD_RELOC_ARM_MOVW
28744 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT
28745 || fixP->fx_r_type == BFD_RELOC_ARM_MOVW_PCREL
28746 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT_PCREL
28747 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
28748 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT
28749 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW_PCREL
28750 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT_PCREL)
c921be7d 28751 return FALSE;
79947c54 28752
72d98d16
MG
28753 /* BFD_RELOC_ARM_THUMB_ALU_ABS_Gx_NC relocations have VERY limited
28754 offsets, so keep these symbols. */
28755 if (fixP->fx_r_type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
28756 && fixP->fx_r_type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
28757 return FALSE;
28758
c921be7d 28759 return TRUE;
a737bd4d 28760}
0ffdc86c
NC
28761#endif /* defined (OBJ_ELF) || defined (OBJ_COFF) */
28762
28763#ifdef OBJ_ELF
c19d1205
ZW
28764const char *
28765elf32_arm_target_format (void)
404ff6b5 28766{
c19d1205
ZW
28767#ifdef TE_SYMBIAN
28768 return (target_big_endian
28769 ? "elf32-bigarm-symbian"
28770 : "elf32-littlearm-symbian");
28771#elif defined (TE_VXWORKS)
28772 return (target_big_endian
28773 ? "elf32-bigarm-vxworks"
28774 : "elf32-littlearm-vxworks");
b38cadfb
NC
28775#elif defined (TE_NACL)
28776 return (target_big_endian
28777 ? "elf32-bigarm-nacl"
28778 : "elf32-littlearm-nacl");
c19d1205 28779#else
18a20338
CL
28780 if (arm_fdpic)
28781 {
28782 if (target_big_endian)
28783 return "elf32-bigarm-fdpic";
28784 else
28785 return "elf32-littlearm-fdpic";
28786 }
c19d1205 28787 else
18a20338
CL
28788 {
28789 if (target_big_endian)
28790 return "elf32-bigarm";
28791 else
28792 return "elf32-littlearm";
28793 }
c19d1205 28794#endif
404ff6b5
AH
28795}
28796
c19d1205
ZW
28797void
28798armelf_frob_symbol (symbolS * symp,
28799 int * puntp)
404ff6b5 28800{
c19d1205
ZW
28801 elf_frob_symbol (symp, puntp);
28802}
28803#endif
404ff6b5 28804
c19d1205 28805/* MD interface: Finalization. */
a737bd4d 28806
c19d1205
ZW
28807void
28808arm_cleanup (void)
28809{
28810 literal_pool * pool;
a737bd4d 28811
5ee91343
AV
28812 /* Ensure that all the predication blocks are properly closed. */
28813 check_pred_blocks_finished ();
e07e6e58 28814
c19d1205
ZW
28815 for (pool = list_of_pools; pool; pool = pool->next)
28816 {
5f4273c7 28817 /* Put it at the end of the relevant section. */
c19d1205
ZW
28818 subseg_set (pool->section, pool->sub_section);
28819#ifdef OBJ_ELF
28820 arm_elf_change_section ();
28821#endif
28822 s_ltorg (0);
28823 }
404ff6b5
AH
28824}
28825
cd000bff
DJ
28826#ifdef OBJ_ELF
28827/* Remove any excess mapping symbols generated for alignment frags in
28828 SEC. We may have created a mapping symbol before a zero byte
28829 alignment; remove it if there's a mapping symbol after the
28830 alignment. */
28831static void
28832check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
28833 void *dummy ATTRIBUTE_UNUSED)
28834{
28835 segment_info_type *seginfo = seg_info (sec);
28836 fragS *fragp;
28837
28838 if (seginfo == NULL || seginfo->frchainP == NULL)
28839 return;
28840
28841 for (fragp = seginfo->frchainP->frch_root;
28842 fragp != NULL;
28843 fragp = fragp->fr_next)
28844 {
28845 symbolS *sym = fragp->tc_frag_data.last_map;
28846 fragS *next = fragp->fr_next;
28847
28848 /* Variable-sized frags have been converted to fixed size by
28849 this point. But if this was variable-sized to start with,
28850 there will be a fixed-size frag after it. So don't handle
28851 next == NULL. */
28852 if (sym == NULL || next == NULL)
28853 continue;
28854
28855 if (S_GET_VALUE (sym) < next->fr_address)
28856 /* Not at the end of this frag. */
28857 continue;
28858 know (S_GET_VALUE (sym) == next->fr_address);
28859
28860 do
28861 {
28862 if (next->tc_frag_data.first_map != NULL)
28863 {
28864 /* Next frag starts with a mapping symbol. Discard this
28865 one. */
28866 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
28867 break;
28868 }
28869
28870 if (next->fr_next == NULL)
28871 {
28872 /* This mapping symbol is at the end of the section. Discard
28873 it. */
28874 know (next->fr_fix == 0 && next->fr_var == 0);
28875 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
28876 break;
28877 }
28878
28879 /* As long as we have empty frags without any mapping symbols,
28880 keep looking. */
28881 /* If the next frag is non-empty and does not start with a
28882 mapping symbol, then this mapping symbol is required. */
28883 if (next->fr_address != next->fr_next->fr_address)
28884 break;
28885
28886 next = next->fr_next;
28887 }
28888 while (next != NULL);
28889 }
28890}
28891#endif
28892
c19d1205
ZW
28893/* Adjust the symbol table. This marks Thumb symbols as distinct from
28894 ARM ones. */
404ff6b5 28895
c19d1205
ZW
28896void
28897arm_adjust_symtab (void)
404ff6b5 28898{
c19d1205
ZW
28899#ifdef OBJ_COFF
28900 symbolS * sym;
404ff6b5 28901
c19d1205
ZW
28902 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
28903 {
28904 if (ARM_IS_THUMB (sym))
28905 {
28906 if (THUMB_IS_FUNC (sym))
28907 {
28908 /* Mark the symbol as a Thumb function. */
28909 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
28910 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
28911 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
404ff6b5 28912
c19d1205
ZW
28913 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
28914 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
28915 else
28916 as_bad (_("%s: unexpected function type: %d"),
28917 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
28918 }
28919 else switch (S_GET_STORAGE_CLASS (sym))
28920 {
28921 case C_EXT:
28922 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
28923 break;
28924 case C_STAT:
28925 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
28926 break;
28927 case C_LABEL:
28928 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
28929 break;
28930 default:
28931 /* Do nothing. */
28932 break;
28933 }
28934 }
a737bd4d 28935
c19d1205
ZW
28936 if (ARM_IS_INTERWORK (sym))
28937 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
404ff6b5 28938 }
c19d1205
ZW
28939#endif
28940#ifdef OBJ_ELF
28941 symbolS * sym;
28942 char bind;
404ff6b5 28943
c19d1205 28944 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
404ff6b5 28945 {
c19d1205
ZW
28946 if (ARM_IS_THUMB (sym))
28947 {
28948 elf_symbol_type * elf_sym;
404ff6b5 28949
c19d1205
ZW
28950 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
28951 bind = ELF_ST_BIND (elf_sym->internal_elf_sym.st_info);
404ff6b5 28952
b0796911
PB
28953 if (! bfd_is_arm_special_symbol_name (elf_sym->symbol.name,
28954 BFD_ARM_SPECIAL_SYM_TYPE_ANY))
c19d1205
ZW
28955 {
28956 /* If it's a .thumb_func, declare it as so,
28957 otherwise tag label as .code 16. */
28958 if (THUMB_IS_FUNC (sym))
39d911fc
TP
28959 ARM_SET_SYM_BRANCH_TYPE (elf_sym->internal_elf_sym.st_target_internal,
28960 ST_BRANCH_TO_THUMB);
3ba67470 28961 else if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
c19d1205
ZW
28962 elf_sym->internal_elf_sym.st_info =
28963 ELF_ST_INFO (bind, STT_ARM_16BIT);
28964 }
28965 }
28966 }
cd000bff
DJ
28967
28968 /* Remove any overlapping mapping symbols generated by alignment frags. */
28969 bfd_map_over_sections (stdoutput, check_mapping_symbols, (char *) 0);
709001e9
MM
28970 /* Now do generic ELF adjustments. */
28971 elf_adjust_symtab ();
c19d1205 28972#endif
404ff6b5
AH
28973}
28974
c19d1205 28975/* MD interface: Initialization. */
404ff6b5 28976
a737bd4d 28977static void
c19d1205 28978set_constant_flonums (void)
a737bd4d 28979{
c19d1205 28980 int i;
404ff6b5 28981
c19d1205
ZW
28982 for (i = 0; i < NUM_FLOAT_VALS; i++)
28983 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
28984 abort ();
a737bd4d 28985}
404ff6b5 28986
3e9e4fcf
JB
28987/* Auto-select Thumb mode if it's the only available instruction set for the
28988 given architecture. */
28989
28990static void
28991autoselect_thumb_from_cpu_variant (void)
28992{
28993 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
28994 opcode_select (16);
28995}
28996
c19d1205
ZW
28997void
28998md_begin (void)
a737bd4d 28999{
c19d1205
ZW
29000 unsigned mach;
29001 unsigned int i;
404ff6b5 29002
c19d1205
ZW
29003 if ( (arm_ops_hsh = hash_new ()) == NULL
29004 || (arm_cond_hsh = hash_new ()) == NULL
5ee91343 29005 || (arm_vcond_hsh = hash_new ()) == NULL
c19d1205
ZW
29006 || (arm_shift_hsh = hash_new ()) == NULL
29007 || (arm_psr_hsh = hash_new ()) == NULL
62b3e311 29008 || (arm_v7m_psr_hsh = hash_new ()) == NULL
c19d1205 29009 || (arm_reg_hsh = hash_new ()) == NULL
62b3e311
PB
29010 || (arm_reloc_hsh = hash_new ()) == NULL
29011 || (arm_barrier_opt_hsh = hash_new ()) == NULL)
c19d1205
ZW
29012 as_fatal (_("virtual memory exhausted"));
29013
29014 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
d3ce72d0 29015 hash_insert (arm_ops_hsh, insns[i].template_name, (void *) (insns + i));
c19d1205 29016 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
d3ce72d0 29017 hash_insert (arm_cond_hsh, conds[i].template_name, (void *) (conds + i));
5ee91343
AV
29018 for (i = 0; i < sizeof (vconds) / sizeof (struct asm_cond); i++)
29019 hash_insert (arm_vcond_hsh, vconds[i].template_name, (void *) (vconds + i));
c19d1205 29020 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
5a49b8ac 29021 hash_insert (arm_shift_hsh, shift_names[i].name, (void *) (shift_names + i));
c19d1205 29022 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
d3ce72d0 29023 hash_insert (arm_psr_hsh, psrs[i].template_name, (void *) (psrs + i));
62b3e311 29024 for (i = 0; i < sizeof (v7m_psrs) / sizeof (struct asm_psr); i++)
d3ce72d0 29025 hash_insert (arm_v7m_psr_hsh, v7m_psrs[i].template_name,
477330fc 29026 (void *) (v7m_psrs + i));
c19d1205 29027 for (i = 0; i < sizeof (reg_names) / sizeof (struct reg_entry); i++)
5a49b8ac 29028 hash_insert (arm_reg_hsh, reg_names[i].name, (void *) (reg_names + i));
62b3e311
PB
29029 for (i = 0;
29030 i < sizeof (barrier_opt_names) / sizeof (struct asm_barrier_opt);
29031 i++)
d3ce72d0 29032 hash_insert (arm_barrier_opt_hsh, barrier_opt_names[i].template_name,
5a49b8ac 29033 (void *) (barrier_opt_names + i));
c19d1205 29034#ifdef OBJ_ELF
3da1d841
NC
29035 for (i = 0; i < ARRAY_SIZE (reloc_names); i++)
29036 {
29037 struct reloc_entry * entry = reloc_names + i;
29038
29039 if (arm_is_eabi() && entry->reloc == BFD_RELOC_ARM_PLT32)
29040 /* This makes encode_branch() use the EABI versions of this relocation. */
29041 entry->reloc = BFD_RELOC_UNUSED;
29042
29043 hash_insert (arm_reloc_hsh, entry->name, (void *) entry);
29044 }
c19d1205
ZW
29045#endif
29046
29047 set_constant_flonums ();
404ff6b5 29048
c19d1205
ZW
29049 /* Set the cpu variant based on the command-line options. We prefer
29050 -mcpu= over -march= if both are set (as for GCC); and we prefer
29051 -mfpu= over any other way of setting the floating point unit.
29052 Use of legacy options with new options are faulted. */
e74cfd16 29053 if (legacy_cpu)
404ff6b5 29054 {
e74cfd16 29055 if (mcpu_cpu_opt || march_cpu_opt)
c19d1205
ZW
29056 as_bad (_("use of old and new-style options to set CPU type"));
29057
4d354d8b 29058 selected_arch = *legacy_cpu;
404ff6b5 29059 }
4d354d8b
TP
29060 else if (mcpu_cpu_opt)
29061 {
29062 selected_arch = *mcpu_cpu_opt;
29063 selected_ext = *mcpu_ext_opt;
29064 }
29065 else if (march_cpu_opt)
c168ce07 29066 {
4d354d8b
TP
29067 selected_arch = *march_cpu_opt;
29068 selected_ext = *march_ext_opt;
c168ce07 29069 }
4d354d8b 29070 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
404ff6b5 29071
e74cfd16 29072 if (legacy_fpu)
c19d1205 29073 {
e74cfd16 29074 if (mfpu_opt)
c19d1205 29075 as_bad (_("use of old and new-style options to set FPU type"));
03b1477f 29076
4d354d8b 29077 selected_fpu = *legacy_fpu;
03b1477f 29078 }
4d354d8b
TP
29079 else if (mfpu_opt)
29080 selected_fpu = *mfpu_opt;
29081 else
03b1477f 29082 {
45eb4c1b
NS
29083#if !(defined (EABI_DEFAULT) || defined (TE_LINUX) \
29084 || defined (TE_NetBSD) || defined (TE_VXWORKS))
39c2da32
RE
29085 /* Some environments specify a default FPU. If they don't, infer it
29086 from the processor. */
e74cfd16 29087 if (mcpu_fpu_opt)
4d354d8b 29088 selected_fpu = *mcpu_fpu_opt;
e7da50fa 29089 else if (march_fpu_opt)
4d354d8b 29090 selected_fpu = *march_fpu_opt;
39c2da32 29091#else
4d354d8b 29092 selected_fpu = fpu_default;
39c2da32 29093#endif
03b1477f
RE
29094 }
29095
4d354d8b 29096 if (ARM_FEATURE_ZERO (selected_fpu))
03b1477f 29097 {
4d354d8b
TP
29098 if (!no_cpu_selected ())
29099 selected_fpu = fpu_default;
03b1477f 29100 else
4d354d8b 29101 selected_fpu = fpu_arch_fpa;
03b1477f
RE
29102 }
29103
ee065d83 29104#ifdef CPU_DEFAULT
4d354d8b 29105 if (ARM_FEATURE_ZERO (selected_arch))
ee065d83 29106 {
4d354d8b
TP
29107 selected_arch = cpu_default;
29108 selected_cpu = selected_arch;
ee065d83 29109 }
4d354d8b 29110 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
e74cfd16 29111#else
4d354d8b
TP
29112 /* Autodection of feature mode: allow all features in cpu_variant but leave
29113 selected_cpu unset. It will be set in aeabi_set_public_attributes ()
29114 after all instruction have been processed and we can decide what CPU
29115 should be selected. */
29116 if (ARM_FEATURE_ZERO (selected_arch))
29117 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
ee065d83 29118 else
4d354d8b 29119 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83 29120#endif
03b1477f 29121
3e9e4fcf
JB
29122 autoselect_thumb_from_cpu_variant ();
29123
e74cfd16 29124 arm_arch_used = thumb_arch_used = arm_arch_none;
ee065d83 29125
f17c130b 29126#if defined OBJ_COFF || defined OBJ_ELF
b99bd4ef 29127 {
7cc69913
NC
29128 unsigned int flags = 0;
29129
29130#if defined OBJ_ELF
29131 flags = meabi_flags;
d507cf36
PB
29132
29133 switch (meabi_flags)
33a392fb 29134 {
d507cf36 29135 case EF_ARM_EABI_UNKNOWN:
7cc69913 29136#endif
d507cf36
PB
29137 /* Set the flags in the private structure. */
29138 if (uses_apcs_26) flags |= F_APCS26;
29139 if (support_interwork) flags |= F_INTERWORK;
29140 if (uses_apcs_float) flags |= F_APCS_FLOAT;
c19d1205 29141 if (pic_code) flags |= F_PIC;
e74cfd16 29142 if (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_any_hard))
7cc69913
NC
29143 flags |= F_SOFT_FLOAT;
29144
d507cf36
PB
29145 switch (mfloat_abi_opt)
29146 {
29147 case ARM_FLOAT_ABI_SOFT:
29148 case ARM_FLOAT_ABI_SOFTFP:
29149 flags |= F_SOFT_FLOAT;
29150 break;
33a392fb 29151
d507cf36
PB
29152 case ARM_FLOAT_ABI_HARD:
29153 if (flags & F_SOFT_FLOAT)
29154 as_bad (_("hard-float conflicts with specified fpu"));
29155 break;
29156 }
03b1477f 29157
e74cfd16
PB
29158 /* Using pure-endian doubles (even if soft-float). */
29159 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_endian_pure))
7cc69913 29160 flags |= F_VFP_FLOAT;
f17c130b 29161
fde78edd 29162#if defined OBJ_ELF
e74cfd16 29163 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_maverick))
d507cf36 29164 flags |= EF_ARM_MAVERICK_FLOAT;
d507cf36
PB
29165 break;
29166
8cb51566 29167 case EF_ARM_EABI_VER4:
3a4a14e9 29168 case EF_ARM_EABI_VER5:
c19d1205 29169 /* No additional flags to set. */
d507cf36
PB
29170 break;
29171
29172 default:
29173 abort ();
29174 }
7cc69913 29175#endif
b99bd4ef
NC
29176 bfd_set_private_flags (stdoutput, flags);
29177
29178 /* We have run out flags in the COFF header to encode the
29179 status of ATPCS support, so instead we create a dummy,
c19d1205 29180 empty, debug section called .arm.atpcs. */
b99bd4ef
NC
29181 if (atpcs)
29182 {
29183 asection * sec;
29184
29185 sec = bfd_make_section (stdoutput, ".arm.atpcs");
29186
29187 if (sec != NULL)
29188 {
29189 bfd_set_section_flags
29190 (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
29191 bfd_set_section_size (stdoutput, sec, 0);
29192 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
29193 }
29194 }
7cc69913 29195 }
f17c130b 29196#endif
b99bd4ef
NC
29197
29198 /* Record the CPU type as well. */
2d447fca
JM
29199 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2))
29200 mach = bfd_mach_arm_iWMMXt2;
29201 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt))
e16bb312 29202 mach = bfd_mach_arm_iWMMXt;
e74cfd16 29203 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_xscale))
b99bd4ef 29204 mach = bfd_mach_arm_XScale;
e74cfd16 29205 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_maverick))
fde78edd 29206 mach = bfd_mach_arm_ep9312;
e74cfd16 29207 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5e))
b99bd4ef 29208 mach = bfd_mach_arm_5TE;
e74cfd16 29209 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5))
b99bd4ef 29210 {
e74cfd16 29211 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
29212 mach = bfd_mach_arm_5T;
29213 else
29214 mach = bfd_mach_arm_5;
29215 }
e74cfd16 29216 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4))
b99bd4ef 29217 {
e74cfd16 29218 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
29219 mach = bfd_mach_arm_4T;
29220 else
29221 mach = bfd_mach_arm_4;
29222 }
e74cfd16 29223 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3m))
b99bd4ef 29224 mach = bfd_mach_arm_3M;
e74cfd16
PB
29225 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3))
29226 mach = bfd_mach_arm_3;
29227 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2s))
29228 mach = bfd_mach_arm_2a;
29229 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2))
29230 mach = bfd_mach_arm_2;
29231 else
29232 mach = bfd_mach_arm_unknown;
b99bd4ef
NC
29233
29234 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
29235}
29236
c19d1205 29237/* Command line processing. */
b99bd4ef 29238
c19d1205
ZW
29239/* md_parse_option
29240 Invocation line includes a switch not recognized by the base assembler.
29241 See if it's a processor-specific option.
b99bd4ef 29242
c19d1205
ZW
29243 This routine is somewhat complicated by the need for backwards
29244 compatibility (since older releases of gcc can't be changed).
29245 The new options try to make the interface as compatible as
29246 possible with GCC.
b99bd4ef 29247
c19d1205 29248 New options (supported) are:
b99bd4ef 29249
c19d1205
ZW
29250 -mcpu=<cpu name> Assemble for selected processor
29251 -march=<architecture name> Assemble for selected architecture
29252 -mfpu=<fpu architecture> Assemble for selected FPU.
29253 -EB/-mbig-endian Big-endian
29254 -EL/-mlittle-endian Little-endian
29255 -k Generate PIC code
29256 -mthumb Start in Thumb mode
29257 -mthumb-interwork Code supports ARM/Thumb interworking
b99bd4ef 29258
278df34e 29259 -m[no-]warn-deprecated Warn about deprecated features
8b2d793c 29260 -m[no-]warn-syms Warn when symbols match instructions
267bf995 29261
c19d1205 29262 For now we will also provide support for:
b99bd4ef 29263
c19d1205
ZW
29264 -mapcs-32 32-bit Program counter
29265 -mapcs-26 26-bit Program counter
29266 -macps-float Floats passed in FP registers
29267 -mapcs-reentrant Reentrant code
29268 -matpcs
29269 (sometime these will probably be replaced with -mapcs=<list of options>
29270 and -matpcs=<list of options>)
b99bd4ef 29271
c19d1205
ZW
29272 The remaining options are only supported for back-wards compatibility.
29273 Cpu variants, the arm part is optional:
29274 -m[arm]1 Currently not supported.
29275 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
29276 -m[arm]3 Arm 3 processor
29277 -m[arm]6[xx], Arm 6 processors
29278 -m[arm]7[xx][t][[d]m] Arm 7 processors
29279 -m[arm]8[10] Arm 8 processors
29280 -m[arm]9[20][tdmi] Arm 9 processors
29281 -mstrongarm[110[0]] StrongARM processors
29282 -mxscale XScale processors
29283 -m[arm]v[2345[t[e]]] Arm architectures
29284 -mall All (except the ARM1)
29285 FP variants:
29286 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
29287 -mfpe-old (No float load/store multiples)
29288 -mvfpxd VFP Single precision
29289 -mvfp All VFP
29290 -mno-fpu Disable all floating point instructions
b99bd4ef 29291
c19d1205
ZW
29292 The following CPU names are recognized:
29293 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
29294 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
29295 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
29296 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
29297 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
29298 arm10t arm10e, arm1020t, arm1020e, arm10200e,
29299 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
b99bd4ef 29300
c19d1205 29301 */
b99bd4ef 29302
c19d1205 29303const char * md_shortopts = "m:k";
b99bd4ef 29304
c19d1205
ZW
29305#ifdef ARM_BI_ENDIAN
29306#define OPTION_EB (OPTION_MD_BASE + 0)
29307#define OPTION_EL (OPTION_MD_BASE + 1)
b99bd4ef 29308#else
c19d1205
ZW
29309#if TARGET_BYTES_BIG_ENDIAN
29310#define OPTION_EB (OPTION_MD_BASE + 0)
b99bd4ef 29311#else
c19d1205
ZW
29312#define OPTION_EL (OPTION_MD_BASE + 1)
29313#endif
b99bd4ef 29314#endif
845b51d6 29315#define OPTION_FIX_V4BX (OPTION_MD_BASE + 2)
18a20338 29316#define OPTION_FDPIC (OPTION_MD_BASE + 3)
b99bd4ef 29317
c19d1205 29318struct option md_longopts[] =
b99bd4ef 29319{
c19d1205
ZW
29320#ifdef OPTION_EB
29321 {"EB", no_argument, NULL, OPTION_EB},
29322#endif
29323#ifdef OPTION_EL
29324 {"EL", no_argument, NULL, OPTION_EL},
b99bd4ef 29325#endif
845b51d6 29326 {"fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX},
18a20338
CL
29327#ifdef OBJ_ELF
29328 {"fdpic", no_argument, NULL, OPTION_FDPIC},
29329#endif
c19d1205
ZW
29330 {NULL, no_argument, NULL, 0}
29331};
b99bd4ef 29332
c19d1205 29333size_t md_longopts_size = sizeof (md_longopts);
b99bd4ef 29334
c19d1205 29335struct arm_option_table
b99bd4ef 29336{
0198d5e6
TC
29337 const char * option; /* Option name to match. */
29338 const char * help; /* Help information. */
29339 int * var; /* Variable to change. */
29340 int value; /* What to change it to. */
29341 const char * deprecated; /* If non-null, print this message. */
c19d1205 29342};
b99bd4ef 29343
c19d1205
ZW
29344struct arm_option_table arm_opts[] =
29345{
29346 {"k", N_("generate PIC code"), &pic_code, 1, NULL},
29347 {"mthumb", N_("assemble Thumb code"), &thumb_mode, 1, NULL},
29348 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
29349 &support_interwork, 1, NULL},
29350 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
29351 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
29352 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
29353 1, NULL},
29354 {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
29355 {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
29356 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
29357 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 0,
29358 NULL},
b99bd4ef 29359
c19d1205
ZW
29360 /* These are recognized by the assembler, but have no affect on code. */
29361 {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
29362 {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
278df34e
NS
29363
29364 {"mwarn-deprecated", NULL, &warn_on_deprecated, 1, NULL},
29365 {"mno-warn-deprecated", N_("do not warn on use of deprecated feature"),
29366 &warn_on_deprecated, 0, NULL},
8b2d793c
NC
29367 {"mwarn-syms", N_("warn about symbols that match instruction names [default]"), (int *) (& flag_warn_syms), TRUE, NULL},
29368 {"mno-warn-syms", N_("disable warnings about symobls that match instructions"), (int *) (& flag_warn_syms), FALSE, NULL},
e74cfd16
PB
29369 {NULL, NULL, NULL, 0, NULL}
29370};
29371
29372struct arm_legacy_option_table
29373{
0198d5e6
TC
29374 const char * option; /* Option name to match. */
29375 const arm_feature_set ** var; /* Variable to change. */
29376 const arm_feature_set value; /* What to change it to. */
29377 const char * deprecated; /* If non-null, print this message. */
e74cfd16 29378};
b99bd4ef 29379
e74cfd16
PB
29380const struct arm_legacy_option_table arm_legacy_opts[] =
29381{
c19d1205
ZW
29382 /* DON'T add any new processors to this list -- we want the whole list
29383 to go away... Add them to the processors table instead. */
e74cfd16
PB
29384 {"marm1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
29385 {"m1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
29386 {"marm2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
29387 {"m2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
29388 {"marm250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
29389 {"m250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
29390 {"marm3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
29391 {"m3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
29392 {"marm6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
29393 {"m6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
29394 {"marm600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
29395 {"m600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
29396 {"marm610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
29397 {"m610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
29398 {"marm620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
29399 {"m620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
29400 {"marm7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
29401 {"m7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
29402 {"marm70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
29403 {"m70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
29404 {"marm700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
29405 {"m700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
29406 {"marm700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
29407 {"m700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
29408 {"marm710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
29409 {"m710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
29410 {"marm710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
29411 {"m710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
29412 {"marm720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
29413 {"m720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
29414 {"marm7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
29415 {"m7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
29416 {"marm7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
29417 {"m7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
29418 {"marm7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
29419 {"m7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
29420 {"marm7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
29421 {"m7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
29422 {"marm7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
29423 {"m7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
29424 {"marm7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
29425 {"m7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
29426 {"marm7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
29427 {"m7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
29428 {"marm7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
29429 {"m7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
29430 {"marm7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
29431 {"m7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
29432 {"marm7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
29433 {"m7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
29434 {"marm710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
29435 {"m710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
29436 {"marm720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
29437 {"m720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
29438 {"marm740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
29439 {"m740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
29440 {"marm8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
29441 {"m8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
29442 {"marm810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
29443 {"m810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
29444 {"marm9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
29445 {"m9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
29446 {"marm9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
29447 {"m9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
29448 {"marm920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
29449 {"m920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
29450 {"marm940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
29451 {"m940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
29452 {"mstrongarm", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")},
29453 {"mstrongarm110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 29454 N_("use -mcpu=strongarm110")},
e74cfd16 29455 {"mstrongarm1100", &legacy_cpu, ARM_ARCH_V4,
c19d1205 29456 N_("use -mcpu=strongarm1100")},
e74cfd16 29457 {"mstrongarm1110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 29458 N_("use -mcpu=strongarm1110")},
e74cfd16
PB
29459 {"mxscale", &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
29460 {"miwmmxt", &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
29461 {"mall", &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
7ed4c4c5 29462
c19d1205 29463 /* Architecture variants -- don't add any more to this list either. */
e74cfd16
PB
29464 {"mv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
29465 {"marmv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
29466 {"mv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
29467 {"marmv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
29468 {"mv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
29469 {"marmv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
29470 {"mv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
29471 {"marmv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
29472 {"mv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
29473 {"marmv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
29474 {"mv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
29475 {"marmv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
29476 {"mv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
29477 {"marmv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
29478 {"mv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
29479 {"marmv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
29480 {"mv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
29481 {"marmv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
7ed4c4c5 29482
c19d1205 29483 /* Floating point variants -- don't add any more to this list either. */
0198d5e6
TC
29484 {"mfpe-old", &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
29485 {"mfpa10", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
29486 {"mfpa11", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
29487 {"mno-fpu", &legacy_fpu, ARM_ARCH_NONE,
c19d1205 29488 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
7ed4c4c5 29489
e74cfd16 29490 {NULL, NULL, ARM_ARCH_NONE, NULL}
c19d1205 29491};
7ed4c4c5 29492
c19d1205 29493struct arm_cpu_option_table
7ed4c4c5 29494{
0198d5e6
TC
29495 const char * name;
29496 size_t name_len;
29497 const arm_feature_set value;
29498 const arm_feature_set ext;
c19d1205
ZW
29499 /* For some CPUs we assume an FPU unless the user explicitly sets
29500 -mfpu=... */
0198d5e6 29501 const arm_feature_set default_fpu;
ee065d83
PB
29502 /* The canonical name of the CPU, or NULL to use NAME converted to upper
29503 case. */
0198d5e6 29504 const char * canonical_name;
c19d1205 29505};
7ed4c4c5 29506
c19d1205
ZW
29507/* This list should, at a minimum, contain all the cpu names
29508 recognized by GCC. */
996b5569 29509#define ARM_CPU_OPT(N, CN, V, E, DF) { N, sizeof (N) - 1, V, E, DF, CN }
0198d5e6 29510
e74cfd16 29511static const struct arm_cpu_option_table arm_cpus[] =
c19d1205 29512{
996b5569
TP
29513 ARM_CPU_OPT ("all", NULL, ARM_ANY,
29514 ARM_ARCH_NONE,
29515 FPU_ARCH_FPA),
29516 ARM_CPU_OPT ("arm1", NULL, ARM_ARCH_V1,
29517 ARM_ARCH_NONE,
29518 FPU_ARCH_FPA),
29519 ARM_CPU_OPT ("arm2", NULL, ARM_ARCH_V2,
29520 ARM_ARCH_NONE,
29521 FPU_ARCH_FPA),
29522 ARM_CPU_OPT ("arm250", NULL, ARM_ARCH_V2S,
29523 ARM_ARCH_NONE,
29524 FPU_ARCH_FPA),
29525 ARM_CPU_OPT ("arm3", NULL, ARM_ARCH_V2S,
29526 ARM_ARCH_NONE,
29527 FPU_ARCH_FPA),
29528 ARM_CPU_OPT ("arm6", NULL, ARM_ARCH_V3,
29529 ARM_ARCH_NONE,
29530 FPU_ARCH_FPA),
29531 ARM_CPU_OPT ("arm60", NULL, ARM_ARCH_V3,
29532 ARM_ARCH_NONE,
29533 FPU_ARCH_FPA),
29534 ARM_CPU_OPT ("arm600", NULL, ARM_ARCH_V3,
29535 ARM_ARCH_NONE,
29536 FPU_ARCH_FPA),
29537 ARM_CPU_OPT ("arm610", NULL, ARM_ARCH_V3,
29538 ARM_ARCH_NONE,
29539 FPU_ARCH_FPA),
29540 ARM_CPU_OPT ("arm620", NULL, ARM_ARCH_V3,
29541 ARM_ARCH_NONE,
29542 FPU_ARCH_FPA),
29543 ARM_CPU_OPT ("arm7", NULL, ARM_ARCH_V3,
29544 ARM_ARCH_NONE,
29545 FPU_ARCH_FPA),
29546 ARM_CPU_OPT ("arm7m", NULL, ARM_ARCH_V3M,
29547 ARM_ARCH_NONE,
29548 FPU_ARCH_FPA),
29549 ARM_CPU_OPT ("arm7d", NULL, ARM_ARCH_V3,
29550 ARM_ARCH_NONE,
29551 FPU_ARCH_FPA),
29552 ARM_CPU_OPT ("arm7dm", NULL, ARM_ARCH_V3M,
29553 ARM_ARCH_NONE,
29554 FPU_ARCH_FPA),
29555 ARM_CPU_OPT ("arm7di", NULL, ARM_ARCH_V3,
29556 ARM_ARCH_NONE,
29557 FPU_ARCH_FPA),
29558 ARM_CPU_OPT ("arm7dmi", NULL, ARM_ARCH_V3M,
29559 ARM_ARCH_NONE,
29560 FPU_ARCH_FPA),
29561 ARM_CPU_OPT ("arm70", NULL, ARM_ARCH_V3,
29562 ARM_ARCH_NONE,
29563 FPU_ARCH_FPA),
29564 ARM_CPU_OPT ("arm700", NULL, ARM_ARCH_V3,
29565 ARM_ARCH_NONE,
29566 FPU_ARCH_FPA),
29567 ARM_CPU_OPT ("arm700i", NULL, ARM_ARCH_V3,
29568 ARM_ARCH_NONE,
29569 FPU_ARCH_FPA),
29570 ARM_CPU_OPT ("arm710", NULL, ARM_ARCH_V3,
29571 ARM_ARCH_NONE,
29572 FPU_ARCH_FPA),
29573 ARM_CPU_OPT ("arm710t", NULL, ARM_ARCH_V4T,
29574 ARM_ARCH_NONE,
29575 FPU_ARCH_FPA),
29576 ARM_CPU_OPT ("arm720", NULL, ARM_ARCH_V3,
29577 ARM_ARCH_NONE,
29578 FPU_ARCH_FPA),
29579 ARM_CPU_OPT ("arm720t", NULL, ARM_ARCH_V4T,
29580 ARM_ARCH_NONE,
29581 FPU_ARCH_FPA),
29582 ARM_CPU_OPT ("arm740t", NULL, ARM_ARCH_V4T,
29583 ARM_ARCH_NONE,
29584 FPU_ARCH_FPA),
29585 ARM_CPU_OPT ("arm710c", NULL, ARM_ARCH_V3,
29586 ARM_ARCH_NONE,
29587 FPU_ARCH_FPA),
29588 ARM_CPU_OPT ("arm7100", NULL, ARM_ARCH_V3,
29589 ARM_ARCH_NONE,
29590 FPU_ARCH_FPA),
29591 ARM_CPU_OPT ("arm7500", NULL, ARM_ARCH_V3,
29592 ARM_ARCH_NONE,
29593 FPU_ARCH_FPA),
29594 ARM_CPU_OPT ("arm7500fe", NULL, ARM_ARCH_V3,
29595 ARM_ARCH_NONE,
29596 FPU_ARCH_FPA),
29597 ARM_CPU_OPT ("arm7t", NULL, ARM_ARCH_V4T,
29598 ARM_ARCH_NONE,
29599 FPU_ARCH_FPA),
29600 ARM_CPU_OPT ("arm7tdmi", NULL, ARM_ARCH_V4T,
29601 ARM_ARCH_NONE,
29602 FPU_ARCH_FPA),
29603 ARM_CPU_OPT ("arm7tdmi-s", NULL, ARM_ARCH_V4T,
29604 ARM_ARCH_NONE,
29605 FPU_ARCH_FPA),
29606 ARM_CPU_OPT ("arm8", NULL, ARM_ARCH_V4,
29607 ARM_ARCH_NONE,
29608 FPU_ARCH_FPA),
29609 ARM_CPU_OPT ("arm810", NULL, ARM_ARCH_V4,
29610 ARM_ARCH_NONE,
29611 FPU_ARCH_FPA),
29612 ARM_CPU_OPT ("strongarm", NULL, ARM_ARCH_V4,
29613 ARM_ARCH_NONE,
29614 FPU_ARCH_FPA),
29615 ARM_CPU_OPT ("strongarm1", NULL, ARM_ARCH_V4,
29616 ARM_ARCH_NONE,
29617 FPU_ARCH_FPA),
29618 ARM_CPU_OPT ("strongarm110", NULL, ARM_ARCH_V4,
29619 ARM_ARCH_NONE,
29620 FPU_ARCH_FPA),
29621 ARM_CPU_OPT ("strongarm1100", NULL, ARM_ARCH_V4,
29622 ARM_ARCH_NONE,
29623 FPU_ARCH_FPA),
29624 ARM_CPU_OPT ("strongarm1110", NULL, ARM_ARCH_V4,
29625 ARM_ARCH_NONE,
29626 FPU_ARCH_FPA),
29627 ARM_CPU_OPT ("arm9", NULL, ARM_ARCH_V4T,
29628 ARM_ARCH_NONE,
29629 FPU_ARCH_FPA),
29630 ARM_CPU_OPT ("arm920", "ARM920T", ARM_ARCH_V4T,
29631 ARM_ARCH_NONE,
29632 FPU_ARCH_FPA),
29633 ARM_CPU_OPT ("arm920t", NULL, ARM_ARCH_V4T,
29634 ARM_ARCH_NONE,
29635 FPU_ARCH_FPA),
29636 ARM_CPU_OPT ("arm922t", NULL, ARM_ARCH_V4T,
29637 ARM_ARCH_NONE,
29638 FPU_ARCH_FPA),
29639 ARM_CPU_OPT ("arm940t", NULL, ARM_ARCH_V4T,
29640 ARM_ARCH_NONE,
29641 FPU_ARCH_FPA),
29642 ARM_CPU_OPT ("arm9tdmi", NULL, ARM_ARCH_V4T,
29643 ARM_ARCH_NONE,
29644 FPU_ARCH_FPA),
29645 ARM_CPU_OPT ("fa526", NULL, ARM_ARCH_V4,
29646 ARM_ARCH_NONE,
29647 FPU_ARCH_FPA),
29648 ARM_CPU_OPT ("fa626", NULL, ARM_ARCH_V4,
29649 ARM_ARCH_NONE,
29650 FPU_ARCH_FPA),
29651
c19d1205
ZW
29652 /* For V5 or later processors we default to using VFP; but the user
29653 should really set the FPU type explicitly. */
996b5569
TP
29654 ARM_CPU_OPT ("arm9e-r0", NULL, ARM_ARCH_V5TExP,
29655 ARM_ARCH_NONE,
29656 FPU_ARCH_VFP_V2),
29657 ARM_CPU_OPT ("arm9e", NULL, ARM_ARCH_V5TE,
29658 ARM_ARCH_NONE,
29659 FPU_ARCH_VFP_V2),
29660 ARM_CPU_OPT ("arm926ej", "ARM926EJ-S", ARM_ARCH_V5TEJ,
29661 ARM_ARCH_NONE,
29662 FPU_ARCH_VFP_V2),
29663 ARM_CPU_OPT ("arm926ejs", "ARM926EJ-S", ARM_ARCH_V5TEJ,
29664 ARM_ARCH_NONE,
29665 FPU_ARCH_VFP_V2),
29666 ARM_CPU_OPT ("arm926ej-s", NULL, ARM_ARCH_V5TEJ,
29667 ARM_ARCH_NONE,
29668 FPU_ARCH_VFP_V2),
29669 ARM_CPU_OPT ("arm946e-r0", NULL, ARM_ARCH_V5TExP,
29670 ARM_ARCH_NONE,
29671 FPU_ARCH_VFP_V2),
29672 ARM_CPU_OPT ("arm946e", "ARM946E-S", ARM_ARCH_V5TE,
29673 ARM_ARCH_NONE,
29674 FPU_ARCH_VFP_V2),
29675 ARM_CPU_OPT ("arm946e-s", NULL, ARM_ARCH_V5TE,
29676 ARM_ARCH_NONE,
29677 FPU_ARCH_VFP_V2),
29678 ARM_CPU_OPT ("arm966e-r0", NULL, ARM_ARCH_V5TExP,
29679 ARM_ARCH_NONE,
29680 FPU_ARCH_VFP_V2),
29681 ARM_CPU_OPT ("arm966e", "ARM966E-S", ARM_ARCH_V5TE,
29682 ARM_ARCH_NONE,
29683 FPU_ARCH_VFP_V2),
29684 ARM_CPU_OPT ("arm966e-s", NULL, ARM_ARCH_V5TE,
29685 ARM_ARCH_NONE,
29686 FPU_ARCH_VFP_V2),
29687 ARM_CPU_OPT ("arm968e-s", NULL, ARM_ARCH_V5TE,
29688 ARM_ARCH_NONE,
29689 FPU_ARCH_VFP_V2),
29690 ARM_CPU_OPT ("arm10t", NULL, ARM_ARCH_V5T,
29691 ARM_ARCH_NONE,
29692 FPU_ARCH_VFP_V1),
29693 ARM_CPU_OPT ("arm10tdmi", NULL, ARM_ARCH_V5T,
29694 ARM_ARCH_NONE,
29695 FPU_ARCH_VFP_V1),
29696 ARM_CPU_OPT ("arm10e", NULL, ARM_ARCH_V5TE,
29697 ARM_ARCH_NONE,
29698 FPU_ARCH_VFP_V2),
29699 ARM_CPU_OPT ("arm1020", "ARM1020E", ARM_ARCH_V5TE,
29700 ARM_ARCH_NONE,
29701 FPU_ARCH_VFP_V2),
29702 ARM_CPU_OPT ("arm1020t", NULL, ARM_ARCH_V5T,
29703 ARM_ARCH_NONE,
29704 FPU_ARCH_VFP_V1),
29705 ARM_CPU_OPT ("arm1020e", NULL, ARM_ARCH_V5TE,
29706 ARM_ARCH_NONE,
29707 FPU_ARCH_VFP_V2),
29708 ARM_CPU_OPT ("arm1022e", NULL, ARM_ARCH_V5TE,
29709 ARM_ARCH_NONE,
29710 FPU_ARCH_VFP_V2),
29711 ARM_CPU_OPT ("arm1026ejs", "ARM1026EJ-S", ARM_ARCH_V5TEJ,
29712 ARM_ARCH_NONE,
29713 FPU_ARCH_VFP_V2),
29714 ARM_CPU_OPT ("arm1026ej-s", NULL, ARM_ARCH_V5TEJ,
29715 ARM_ARCH_NONE,
29716 FPU_ARCH_VFP_V2),
29717 ARM_CPU_OPT ("fa606te", NULL, ARM_ARCH_V5TE,
29718 ARM_ARCH_NONE,
29719 FPU_ARCH_VFP_V2),
29720 ARM_CPU_OPT ("fa616te", NULL, ARM_ARCH_V5TE,
29721 ARM_ARCH_NONE,
29722 FPU_ARCH_VFP_V2),
29723 ARM_CPU_OPT ("fa626te", NULL, ARM_ARCH_V5TE,
29724 ARM_ARCH_NONE,
29725 FPU_ARCH_VFP_V2),
29726 ARM_CPU_OPT ("fmp626", NULL, ARM_ARCH_V5TE,
29727 ARM_ARCH_NONE,
29728 FPU_ARCH_VFP_V2),
29729 ARM_CPU_OPT ("fa726te", NULL, ARM_ARCH_V5TE,
29730 ARM_ARCH_NONE,
29731 FPU_ARCH_VFP_V2),
29732 ARM_CPU_OPT ("arm1136js", "ARM1136J-S", ARM_ARCH_V6,
29733 ARM_ARCH_NONE,
29734 FPU_NONE),
29735 ARM_CPU_OPT ("arm1136j-s", NULL, ARM_ARCH_V6,
29736 ARM_ARCH_NONE,
29737 FPU_NONE),
29738 ARM_CPU_OPT ("arm1136jfs", "ARM1136JF-S", ARM_ARCH_V6,
29739 ARM_ARCH_NONE,
29740 FPU_ARCH_VFP_V2),
29741 ARM_CPU_OPT ("arm1136jf-s", NULL, ARM_ARCH_V6,
29742 ARM_ARCH_NONE,
29743 FPU_ARCH_VFP_V2),
29744 ARM_CPU_OPT ("mpcore", "MPCore", ARM_ARCH_V6K,
29745 ARM_ARCH_NONE,
29746 FPU_ARCH_VFP_V2),
29747 ARM_CPU_OPT ("mpcorenovfp", "MPCore", ARM_ARCH_V6K,
29748 ARM_ARCH_NONE,
29749 FPU_NONE),
29750 ARM_CPU_OPT ("arm1156t2-s", NULL, ARM_ARCH_V6T2,
29751 ARM_ARCH_NONE,
29752 FPU_NONE),
29753 ARM_CPU_OPT ("arm1156t2f-s", NULL, ARM_ARCH_V6T2,
29754 ARM_ARCH_NONE,
29755 FPU_ARCH_VFP_V2),
29756 ARM_CPU_OPT ("arm1176jz-s", NULL, ARM_ARCH_V6KZ,
29757 ARM_ARCH_NONE,
29758 FPU_NONE),
29759 ARM_CPU_OPT ("arm1176jzf-s", NULL, ARM_ARCH_V6KZ,
29760 ARM_ARCH_NONE,
29761 FPU_ARCH_VFP_V2),
29762 ARM_CPU_OPT ("cortex-a5", "Cortex-A5", ARM_ARCH_V7A,
29763 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
29764 FPU_NONE),
29765 ARM_CPU_OPT ("cortex-a7", "Cortex-A7", ARM_ARCH_V7VE,
29766 ARM_ARCH_NONE,
29767 FPU_ARCH_NEON_VFP_V4),
29768 ARM_CPU_OPT ("cortex-a8", "Cortex-A8", ARM_ARCH_V7A,
29769 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
29770 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
29771 ARM_CPU_OPT ("cortex-a9", "Cortex-A9", ARM_ARCH_V7A,
29772 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
29773 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
29774 ARM_CPU_OPT ("cortex-a12", "Cortex-A12", ARM_ARCH_V7VE,
29775 ARM_ARCH_NONE,
29776 FPU_ARCH_NEON_VFP_V4),
29777 ARM_CPU_OPT ("cortex-a15", "Cortex-A15", ARM_ARCH_V7VE,
29778 ARM_ARCH_NONE,
29779 FPU_ARCH_NEON_VFP_V4),
29780 ARM_CPU_OPT ("cortex-a17", "Cortex-A17", ARM_ARCH_V7VE,
29781 ARM_ARCH_NONE,
29782 FPU_ARCH_NEON_VFP_V4),
29783 ARM_CPU_OPT ("cortex-a32", "Cortex-A32", ARM_ARCH_V8A,
29784 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29785 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
29786 ARM_CPU_OPT ("cortex-a35", "Cortex-A35", ARM_ARCH_V8A,
29787 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29788 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
29789 ARM_CPU_OPT ("cortex-a53", "Cortex-A53", ARM_ARCH_V8A,
29790 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29791 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
29792 ARM_CPU_OPT ("cortex-a55", "Cortex-A55", ARM_ARCH_V8_2A,
29793 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 29794 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569
TP
29795 ARM_CPU_OPT ("cortex-a57", "Cortex-A57", ARM_ARCH_V8A,
29796 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29797 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
29798 ARM_CPU_OPT ("cortex-a72", "Cortex-A72", ARM_ARCH_V8A,
29799 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29800 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
29801 ARM_CPU_OPT ("cortex-a73", "Cortex-A73", ARM_ARCH_V8A,
29802 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29803 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
29804 ARM_CPU_OPT ("cortex-a75", "Cortex-A75", ARM_ARCH_V8_2A,
29805 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 29806 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
7ebd1359 29807 ARM_CPU_OPT ("cortex-a76", "Cortex-A76", ARM_ARCH_V8_2A,
29808 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
29809 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
ef8df4ca
KT
29810 ARM_CPU_OPT ("ares", "Ares", ARM_ARCH_V8_2A,
29811 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
29812 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569
TP
29813 ARM_CPU_OPT ("cortex-r4", "Cortex-R4", ARM_ARCH_V7R,
29814 ARM_ARCH_NONE,
29815 FPU_NONE),
29816 ARM_CPU_OPT ("cortex-r4f", "Cortex-R4F", ARM_ARCH_V7R,
29817 ARM_ARCH_NONE,
29818 FPU_ARCH_VFP_V3D16),
29819 ARM_CPU_OPT ("cortex-r5", "Cortex-R5", ARM_ARCH_V7R,
29820 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
29821 FPU_NONE),
29822 ARM_CPU_OPT ("cortex-r7", "Cortex-R7", ARM_ARCH_V7R,
29823 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
29824 FPU_ARCH_VFP_V3D16),
29825 ARM_CPU_OPT ("cortex-r8", "Cortex-R8", ARM_ARCH_V7R,
29826 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
29827 FPU_ARCH_VFP_V3D16),
0cda1e19
TP
29828 ARM_CPU_OPT ("cortex-r52", "Cortex-R52", ARM_ARCH_V8R,
29829 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29830 FPU_ARCH_NEON_VFP_ARMV8),
996b5569
TP
29831 ARM_CPU_OPT ("cortex-m33", "Cortex-M33", ARM_ARCH_V8M_MAIN,
29832 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
29833 FPU_NONE),
29834 ARM_CPU_OPT ("cortex-m23", "Cortex-M23", ARM_ARCH_V8M_BASE,
29835 ARM_ARCH_NONE,
29836 FPU_NONE),
29837 ARM_CPU_OPT ("cortex-m7", "Cortex-M7", ARM_ARCH_V7EM,
29838 ARM_ARCH_NONE,
29839 FPU_NONE),
29840 ARM_CPU_OPT ("cortex-m4", "Cortex-M4", ARM_ARCH_V7EM,
29841 ARM_ARCH_NONE,
29842 FPU_NONE),
29843 ARM_CPU_OPT ("cortex-m3", "Cortex-M3", ARM_ARCH_V7M,
29844 ARM_ARCH_NONE,
29845 FPU_NONE),
29846 ARM_CPU_OPT ("cortex-m1", "Cortex-M1", ARM_ARCH_V6SM,
29847 ARM_ARCH_NONE,
29848 FPU_NONE),
29849 ARM_CPU_OPT ("cortex-m0", "Cortex-M0", ARM_ARCH_V6SM,
29850 ARM_ARCH_NONE,
29851 FPU_NONE),
29852 ARM_CPU_OPT ("cortex-m0plus", "Cortex-M0+", ARM_ARCH_V6SM,
29853 ARM_ARCH_NONE,
29854 FPU_NONE),
29855 ARM_CPU_OPT ("exynos-m1", "Samsung Exynos M1", ARM_ARCH_V8A,
29856 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29857 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
83f43c83
KT
29858 ARM_CPU_OPT ("neoverse-n1", "Neoverse N1", ARM_ARCH_V8_2A,
29859 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
29860 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
c19d1205 29861 /* ??? XSCALE is really an architecture. */
996b5569
TP
29862 ARM_CPU_OPT ("xscale", NULL, ARM_ARCH_XSCALE,
29863 ARM_ARCH_NONE,
29864 FPU_ARCH_VFP_V2),
29865
c19d1205 29866 /* ??? iwmmxt is not a processor. */
996b5569
TP
29867 ARM_CPU_OPT ("iwmmxt", NULL, ARM_ARCH_IWMMXT,
29868 ARM_ARCH_NONE,
29869 FPU_ARCH_VFP_V2),
29870 ARM_CPU_OPT ("iwmmxt2", NULL, ARM_ARCH_IWMMXT2,
29871 ARM_ARCH_NONE,
29872 FPU_ARCH_VFP_V2),
29873 ARM_CPU_OPT ("i80200", NULL, ARM_ARCH_XSCALE,
29874 ARM_ARCH_NONE,
29875 FPU_ARCH_VFP_V2),
29876
0198d5e6 29877 /* Maverick. */
996b5569
TP
29878 ARM_CPU_OPT ("ep9312", "ARM920T",
29879 ARM_FEATURE_LOW (ARM_AEXT_V4T, ARM_CEXT_MAVERICK),
29880 ARM_ARCH_NONE, FPU_ARCH_MAVERICK),
29881
da4339ed 29882 /* Marvell processors. */
996b5569
TP
29883 ARM_CPU_OPT ("marvell-pj4", NULL, ARM_ARCH_V7A,
29884 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
29885 FPU_ARCH_VFP_V3D16),
29886 ARM_CPU_OPT ("marvell-whitney", NULL, ARM_ARCH_V7A,
29887 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
29888 FPU_ARCH_NEON_VFP_V4),
da4339ed 29889
996b5569
TP
29890 /* APM X-Gene family. */
29891 ARM_CPU_OPT ("xgene1", "APM X-Gene 1", ARM_ARCH_V8A,
29892 ARM_ARCH_NONE,
29893 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
29894 ARM_CPU_OPT ("xgene2", "APM X-Gene 2", ARM_ARCH_V8A,
29895 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29896 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
29897
29898 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 29899};
f3bad469 29900#undef ARM_CPU_OPT
7ed4c4c5 29901
34ef62f4
AV
29902struct arm_ext_table
29903{
29904 const char * name;
29905 size_t name_len;
29906 const arm_feature_set merge;
29907 const arm_feature_set clear;
29908};
29909
c19d1205 29910struct arm_arch_option_table
7ed4c4c5 29911{
34ef62f4
AV
29912 const char * name;
29913 size_t name_len;
29914 const arm_feature_set value;
29915 const arm_feature_set default_fpu;
29916 const struct arm_ext_table * ext_table;
29917};
29918
29919/* Used to add support for +E and +noE extension. */
29920#define ARM_EXT(E, M, C) { E, sizeof (E) - 1, M, C }
29921/* Used to add support for a +E extension. */
29922#define ARM_ADD(E, M) { E, sizeof(E) - 1, M, ARM_ARCH_NONE }
29923/* Used to add support for a +noE extension. */
29924#define ARM_REMOVE(E, C) { E, sizeof(E) -1, ARM_ARCH_NONE, C }
29925
29926#define ALL_FP ARM_FEATURE (0, ARM_EXT2_FP16_INST | ARM_EXT2_FP16_FML, \
29927 ~0 & ~FPU_ENDIAN_PURE)
29928
29929static const struct arm_ext_table armv5te_ext_table[] =
29930{
29931 ARM_EXT ("fp", FPU_ARCH_VFP_V2, ALL_FP),
29932 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
29933};
29934
29935static const struct arm_ext_table armv7_ext_table[] =
29936{
29937 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
29938 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
29939};
29940
29941static const struct arm_ext_table armv7ve_ext_table[] =
29942{
29943 ARM_EXT ("fp", FPU_ARCH_VFP_V4D16, ALL_FP),
29944 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16),
29945 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
29946 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
29947 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
29948 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16), /* Alias for +fp. */
29949 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
29950
29951 ARM_EXT ("simd", FPU_ARCH_NEON_VFP_V4,
29952 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
29953
29954 /* Aliases for +simd. */
29955 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
29956
29957 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
29958 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
29959 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
29960
29961 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
29962};
29963
29964static const struct arm_ext_table armv7a_ext_table[] =
29965{
29966 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
29967 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
29968 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
29969 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
29970 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
29971 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16),
29972 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
29973
29974 ARM_EXT ("simd", FPU_ARCH_VFP_V3_PLUS_NEON_V1,
29975 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
29976
29977 /* Aliases for +simd. */
29978 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
29979 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
29980
29981 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
29982 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
29983
29984 ARM_ADD ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP)),
29985 ARM_ADD ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC)),
29986 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
29987};
29988
29989static const struct arm_ext_table armv7r_ext_table[] =
29990{
29991 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V3xD),
29992 ARM_ADD ("vfpv3xd", FPU_ARCH_VFP_V3xD), /* Alias for +fp.sp. */
29993 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
29994 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
29995 ARM_ADD ("vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16),
29996 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
29997 ARM_EXT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
29998 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV)),
29999 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30000};
30001
30002static const struct arm_ext_table armv7em_ext_table[] =
30003{
30004 ARM_EXT ("fp", FPU_ARCH_VFP_V4_SP_D16, ALL_FP),
30005 /* Alias for +fp, used to be known as fpv4-sp-d16. */
30006 ARM_ADD ("vfpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16),
30007 ARM_ADD ("fpv5", FPU_ARCH_VFP_V5_SP_D16),
30008 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
30009 ARM_ADD ("fpv5-d16", FPU_ARCH_VFP_V5D16),
30010 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30011};
30012
30013static const struct arm_ext_table armv8a_ext_table[] =
30014{
30015 ARM_ADD ("crc", ARCH_CRC_ARMV8),
30016 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
30017 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
30018 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
30019
30020 /* Armv8-a does not allow an FP implementation without SIMD, so the user
30021 should use the +simd option to turn on FP. */
30022 ARM_REMOVE ("fp", ALL_FP),
30023 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
30024 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
30025 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30026};
30027
30028
30029static const struct arm_ext_table armv81a_ext_table[] =
30030{
30031 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
30032 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
30033 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
30034
30035 /* Armv8-a does not allow an FP implementation without SIMD, so the user
30036 should use the +simd option to turn on FP. */
30037 ARM_REMOVE ("fp", ALL_FP),
30038 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
30039 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
30040 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30041};
30042
30043static const struct arm_ext_table armv82a_ext_table[] =
30044{
30045 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
30046 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_2_FP16),
30047 ARM_ADD ("fp16fml", FPU_ARCH_NEON_VFP_ARMV8_2_FP16FML),
30048 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
30049 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
30050 ARM_ADD ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
30051
30052 /* Armv8-a does not allow an FP implementation without SIMD, so the user
30053 should use the +simd option to turn on FP. */
30054 ARM_REMOVE ("fp", ALL_FP),
30055 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
30056 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
30057 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30058};
30059
30060static const struct arm_ext_table armv84a_ext_table[] =
30061{
30062 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
30063 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
30064 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
30065 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
30066
30067 /* Armv8-a does not allow an FP implementation without SIMD, so the user
30068 should use the +simd option to turn on FP. */
30069 ARM_REMOVE ("fp", ALL_FP),
30070 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
30071 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
30072 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30073};
30074
30075static const struct arm_ext_table armv85a_ext_table[] =
30076{
30077 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
30078 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
30079 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
30080 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
30081
30082 /* Armv8-a does not allow an FP implementation without SIMD, so the user
30083 should use the +simd option to turn on FP. */
30084 ARM_REMOVE ("fp", ALL_FP),
30085 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30086};
30087
30088static const struct arm_ext_table armv8m_main_ext_table[] =
30089{
30090 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
30091 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP)),
30092 ARM_EXT ("fp", FPU_ARCH_VFP_V5_SP_D16, ALL_FP),
30093 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
30094 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30095};
30096
e0991585
AV
30097static const struct arm_ext_table armv8_1m_main_ext_table[] =
30098{
30099 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
30100 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP)),
30101 ARM_EXT ("fp",
30102 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
30103 FPU_VFP_V5_SP_D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA),
30104 ALL_FP),
30105 ARM_ADD ("fp.dp",
30106 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
30107 FPU_VFP_V5D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
a7ad558c
AV
30108 ARM_EXT ("mve", ARM_FEATURE_COPROC (FPU_MVE),
30109 ARM_FEATURE_COPROC (FPU_MVE | FPU_MVE_FP)),
30110 ARM_ADD ("mve.fp",
30111 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
30112 FPU_MVE | FPU_MVE_FP | FPU_VFP_V5_SP_D16 |
30113 FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
e0991585
AV
30114 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30115};
30116
34ef62f4
AV
30117static const struct arm_ext_table armv8r_ext_table[] =
30118{
30119 ARM_ADD ("crc", ARCH_CRC_ARMV8),
30120 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
30121 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
30122 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
30123 ARM_REMOVE ("fp", ALL_FP),
30124 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V5_SP_D16),
30125 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
c19d1205 30126};
7ed4c4c5 30127
c19d1205
ZW
30128/* This list should, at a minimum, contain all the architecture names
30129 recognized by GCC. */
34ef62f4
AV
30130#define ARM_ARCH_OPT(N, V, DF) { N, sizeof (N) - 1, V, DF, NULL }
30131#define ARM_ARCH_OPT2(N, V, DF, ext) \
30132 { N, sizeof (N) - 1, V, DF, ext##_ext_table }
0198d5e6 30133
e74cfd16 30134static const struct arm_arch_option_table arm_archs[] =
c19d1205 30135{
497d849d
TP
30136 ARM_ARCH_OPT ("all", ARM_ANY, FPU_ARCH_FPA),
30137 ARM_ARCH_OPT ("armv1", ARM_ARCH_V1, FPU_ARCH_FPA),
30138 ARM_ARCH_OPT ("armv2", ARM_ARCH_V2, FPU_ARCH_FPA),
30139 ARM_ARCH_OPT ("armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA),
30140 ARM_ARCH_OPT ("armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA),
30141 ARM_ARCH_OPT ("armv3", ARM_ARCH_V3, FPU_ARCH_FPA),
30142 ARM_ARCH_OPT ("armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA),
30143 ARM_ARCH_OPT ("armv4", ARM_ARCH_V4, FPU_ARCH_FPA),
30144 ARM_ARCH_OPT ("armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA),
30145 ARM_ARCH_OPT ("armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA),
30146 ARM_ARCH_OPT ("armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA),
30147 ARM_ARCH_OPT ("armv5", ARM_ARCH_V5, FPU_ARCH_VFP),
30148 ARM_ARCH_OPT ("armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP),
30149 ARM_ARCH_OPT ("armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP),
34ef62f4
AV
30150 ARM_ARCH_OPT2 ("armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP, armv5te),
30151 ARM_ARCH_OPT2 ("armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP, armv5te),
30152 ARM_ARCH_OPT2 ("armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP, armv5te),
30153 ARM_ARCH_OPT2 ("armv6", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
30154 ARM_ARCH_OPT2 ("armv6j", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
30155 ARM_ARCH_OPT2 ("armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP, armv5te),
30156 ARM_ARCH_OPT2 ("armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP, armv5te),
f33026a9
MW
30157 /* The official spelling of this variant is ARMv6KZ, the name "armv6zk" is
30158 kept to preserve existing behaviour. */
34ef62f4
AV
30159 ARM_ARCH_OPT2 ("armv6kz", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
30160 ARM_ARCH_OPT2 ("armv6zk", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
30161 ARM_ARCH_OPT2 ("armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP, armv5te),
30162 ARM_ARCH_OPT2 ("armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP, armv5te),
30163 ARM_ARCH_OPT2 ("armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP, armv5te),
f33026a9
MW
30164 /* The official spelling of this variant is ARMv6KZ, the name "armv6zkt2" is
30165 kept to preserve existing behaviour. */
34ef62f4
AV
30166 ARM_ARCH_OPT2 ("armv6kzt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
30167 ARM_ARCH_OPT2 ("armv6zkt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
497d849d
TP
30168 ARM_ARCH_OPT ("armv6-m", ARM_ARCH_V6M, FPU_ARCH_VFP),
30169 ARM_ARCH_OPT ("armv6s-m", ARM_ARCH_V6SM, FPU_ARCH_VFP),
34ef62f4 30170 ARM_ARCH_OPT2 ("armv7", ARM_ARCH_V7, FPU_ARCH_VFP, armv7),
c450d570
PB
30171 /* The official spelling of the ARMv7 profile variants is the dashed form.
30172 Accept the non-dashed form for compatibility with old toolchains. */
34ef62f4
AV
30173 ARM_ARCH_OPT2 ("armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
30174 ARM_ARCH_OPT2 ("armv7ve", ARM_ARCH_V7VE, FPU_ARCH_VFP, armv7ve),
30175 ARM_ARCH_OPT2 ("armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 30176 ARM_ARCH_OPT ("armv7m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4
AV
30177 ARM_ARCH_OPT2 ("armv7-a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
30178 ARM_ARCH_OPT2 ("armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 30179 ARM_ARCH_OPT ("armv7-m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4 30180 ARM_ARCH_OPT2 ("armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP, armv7em),
497d849d 30181 ARM_ARCH_OPT ("armv8-m.base", ARM_ARCH_V8M_BASE, FPU_ARCH_VFP),
34ef62f4
AV
30182 ARM_ARCH_OPT2 ("armv8-m.main", ARM_ARCH_V8M_MAIN, FPU_ARCH_VFP,
30183 armv8m_main),
e0991585
AV
30184 ARM_ARCH_OPT2 ("armv8.1-m.main", ARM_ARCH_V8_1M_MAIN, FPU_ARCH_VFP,
30185 armv8_1m_main),
34ef62f4
AV
30186 ARM_ARCH_OPT2 ("armv8-a", ARM_ARCH_V8A, FPU_ARCH_VFP, armv8a),
30187 ARM_ARCH_OPT2 ("armv8.1-a", ARM_ARCH_V8_1A, FPU_ARCH_VFP, armv81a),
30188 ARM_ARCH_OPT2 ("armv8.2-a", ARM_ARCH_V8_2A, FPU_ARCH_VFP, armv82a),
30189 ARM_ARCH_OPT2 ("armv8.3-a", ARM_ARCH_V8_3A, FPU_ARCH_VFP, armv82a),
30190 ARM_ARCH_OPT2 ("armv8-r", ARM_ARCH_V8R, FPU_ARCH_VFP, armv8r),
30191 ARM_ARCH_OPT2 ("armv8.4-a", ARM_ARCH_V8_4A, FPU_ARCH_VFP, armv84a),
30192 ARM_ARCH_OPT2 ("armv8.5-a", ARM_ARCH_V8_5A, FPU_ARCH_VFP, armv85a),
497d849d
TP
30193 ARM_ARCH_OPT ("xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP),
30194 ARM_ARCH_OPT ("iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP),
30195 ARM_ARCH_OPT ("iwmmxt2", ARM_ARCH_IWMMXT2, FPU_ARCH_VFP),
34ef62f4 30196 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 30197};
f3bad469 30198#undef ARM_ARCH_OPT
7ed4c4c5 30199
69133863 30200/* ISA extensions in the co-processor and main instruction set space. */
0198d5e6 30201
69133863 30202struct arm_option_extension_value_table
c19d1205 30203{
0198d5e6
TC
30204 const char * name;
30205 size_t name_len;
30206 const arm_feature_set merge_value;
30207 const arm_feature_set clear_value;
d942732e
TP
30208 /* List of architectures for which an extension is available. ARM_ARCH_NONE
30209 indicates that an extension is available for all architectures while
30210 ARM_ANY marks an empty entry. */
0198d5e6 30211 const arm_feature_set allowed_archs[2];
c19d1205 30212};
7ed4c4c5 30213
0198d5e6
TC
30214/* The following table must be in alphabetical order with a NULL last entry. */
30215
d942732e
TP
30216#define ARM_EXT_OPT(N, M, C, AA) { N, sizeof (N) - 1, M, C, { AA, ARM_ANY } }
30217#define ARM_EXT_OPT2(N, M, C, AA1, AA2) { N, sizeof (N) - 1, M, C, {AA1, AA2} }
0198d5e6 30218
34ef62f4
AV
30219/* DEPRECATED: Refrain from using this table to add any new extensions, instead
30220 use the context sensitive approach using arm_ext_table's. */
69133863 30221static const struct arm_option_extension_value_table arm_extensions[] =
c19d1205 30222{
823d2571
TG
30223 ARM_EXT_OPT ("crc", ARCH_CRC_ARMV8, ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
30224 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
bca38921 30225 ARM_EXT_OPT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
823d2571
TG
30226 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8),
30227 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
c604a79a
JW
30228 ARM_EXT_OPT ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8,
30229 ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD),
30230 ARM_ARCH_V8_2A),
15afaa63
TP
30231 ARM_EXT_OPT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
30232 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
30233 ARM_FEATURE_CORE (ARM_EXT_V7M, ARM_EXT2_V8M)),
823d2571
TG
30234 ARM_EXT_OPT ("fp", FPU_ARCH_VFP_ARMV8, ARM_FEATURE_COPROC (FPU_VFP_ARMV8),
30235 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
b8ec4e87
JW
30236 ARM_EXT_OPT ("fp16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
30237 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
30238 ARM_ARCH_V8_2A),
01f48020
TC
30239 ARM_EXT_OPT ("fp16fml", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
30240 | ARM_EXT2_FP16_FML),
30241 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
30242 | ARM_EXT2_FP16_FML),
30243 ARM_ARCH_V8_2A),
d942732e 30244 ARM_EXT_OPT2 ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
823d2571 30245 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
d942732e
TP
30246 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
30247 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
3d030cdb
TP
30248 /* Duplicate entry for the purpose of allowing ARMv7 to match in presence of
30249 Thumb divide instruction. Due to this having the same name as the
30250 previous entry, this will be ignored when doing command-line parsing and
30251 only considered by build attribute selection code. */
30252 ARM_EXT_OPT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
30253 ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
30254 ARM_FEATURE_CORE_LOW (ARM_EXT_V7)),
823d2571 30255 ARM_EXT_OPT ("iwmmxt",ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT),
d942732e 30256 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT), ARM_ARCH_NONE),
823d2571 30257 ARM_EXT_OPT ("iwmmxt2", ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2),
d942732e 30258 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2), ARM_ARCH_NONE),
823d2571 30259 ARM_EXT_OPT ("maverick", ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK),
d942732e
TP
30260 ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK), ARM_ARCH_NONE),
30261 ARM_EXT_OPT2 ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
823d2571 30262 ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
d942732e
TP
30263 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
30264 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
823d2571
TG
30265 ARM_EXT_OPT ("os", ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
30266 ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
30267 ARM_FEATURE_CORE_LOW (ARM_EXT_V6M)),
ddfded2f
MW
30268 ARM_EXT_OPT ("pan", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN),
30269 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_PAN, 0),
ced40572 30270 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
dad0c3bf
SD
30271 ARM_EXT_OPT ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
30272 ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
30273 ARM_ARCH_V8A),
4d1464f2
MW
30274 ARM_EXT_OPT ("ras", ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS),
30275 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_RAS, 0),
ced40572 30276 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
643afb90
MW
30277 ARM_EXT_OPT ("rdma", FPU_ARCH_NEON_VFP_ARMV8_1,
30278 ARM_FEATURE_COPROC (FPU_NEON_ARMV8 | FPU_NEON_EXT_RDMA),
ced40572 30279 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
7fadb25d
SD
30280 ARM_EXT_OPT ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
30281 ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
30282 ARM_ARCH_V8A),
d942732e 30283 ARM_EXT_OPT2 ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
823d2571 30284 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
d942732e
TP
30285 ARM_FEATURE_CORE_LOW (ARM_EXT_V6K),
30286 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
643afb90
MW
30287 ARM_EXT_OPT ("simd", FPU_ARCH_NEON_VFP_ARMV8,
30288 ARM_FEATURE_COPROC (FPU_NEON_ARMV8),
30289 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
823d2571
TG
30290 ARM_EXT_OPT ("virt", ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT | ARM_EXT_ADIV
30291 | ARM_EXT_DIV),
30292 ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT),
30293 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
30294 ARM_EXT_OPT ("xscale",ARM_FEATURE_COPROC (ARM_CEXT_XSCALE),
d942732e
TP
30295 ARM_FEATURE_COPROC (ARM_CEXT_XSCALE), ARM_ARCH_NONE),
30296 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, { ARM_ARCH_NONE, ARM_ARCH_NONE } }
69133863 30297};
f3bad469 30298#undef ARM_EXT_OPT
69133863
MGD
30299
30300/* ISA floating-point and Advanced SIMD extensions. */
30301struct arm_option_fpu_value_table
30302{
0198d5e6
TC
30303 const char * name;
30304 const arm_feature_set value;
c19d1205 30305};
7ed4c4c5 30306
c19d1205
ZW
30307/* This list should, at a minimum, contain all the fpu names
30308 recognized by GCC. */
69133863 30309static const struct arm_option_fpu_value_table arm_fpus[] =
c19d1205
ZW
30310{
30311 {"softfpa", FPU_NONE},
30312 {"fpe", FPU_ARCH_FPE},
30313 {"fpe2", FPU_ARCH_FPE},
30314 {"fpe3", FPU_ARCH_FPA}, /* Third release supports LFM/SFM. */
30315 {"fpa", FPU_ARCH_FPA},
30316 {"fpa10", FPU_ARCH_FPA},
30317 {"fpa11", FPU_ARCH_FPA},
30318 {"arm7500fe", FPU_ARCH_FPA},
30319 {"softvfp", FPU_ARCH_VFP},
30320 {"softvfp+vfp", FPU_ARCH_VFP_V2},
30321 {"vfp", FPU_ARCH_VFP_V2},
30322 {"vfp9", FPU_ARCH_VFP_V2},
d5e0ba9c 30323 {"vfp3", FPU_ARCH_VFP_V3}, /* Undocumented, use vfpv3. */
c19d1205
ZW
30324 {"vfp10", FPU_ARCH_VFP_V2},
30325 {"vfp10-r0", FPU_ARCH_VFP_V1},
30326 {"vfpxd", FPU_ARCH_VFP_V1xD},
b1cc4aeb
PB
30327 {"vfpv2", FPU_ARCH_VFP_V2},
30328 {"vfpv3", FPU_ARCH_VFP_V3},
62f3b8c8 30329 {"vfpv3-fp16", FPU_ARCH_VFP_V3_FP16},
b1cc4aeb 30330 {"vfpv3-d16", FPU_ARCH_VFP_V3D16},
62f3b8c8
PB
30331 {"vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16},
30332 {"vfpv3xd", FPU_ARCH_VFP_V3xD},
30333 {"vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16},
c19d1205
ZW
30334 {"arm1020t", FPU_ARCH_VFP_V1},
30335 {"arm1020e", FPU_ARCH_VFP_V2},
d5e0ba9c 30336 {"arm1136jfs", FPU_ARCH_VFP_V2}, /* Undocumented, use arm1136jf-s. */
c19d1205
ZW
30337 {"arm1136jf-s", FPU_ARCH_VFP_V2},
30338 {"maverick", FPU_ARCH_MAVERICK},
d5e0ba9c 30339 {"neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
d3375ddd 30340 {"neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
8e79c3df 30341 {"neon-fp16", FPU_ARCH_NEON_FP16},
62f3b8c8
PB
30342 {"vfpv4", FPU_ARCH_VFP_V4},
30343 {"vfpv4-d16", FPU_ARCH_VFP_V4D16},
ada65aa3 30344 {"fpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16},
a715796b
TG
30345 {"fpv5-d16", FPU_ARCH_VFP_V5D16},
30346 {"fpv5-sp-d16", FPU_ARCH_VFP_V5_SP_D16},
62f3b8c8 30347 {"neon-vfpv4", FPU_ARCH_NEON_VFP_V4},
bca38921
MGD
30348 {"fp-armv8", FPU_ARCH_VFP_ARMV8},
30349 {"neon-fp-armv8", FPU_ARCH_NEON_VFP_ARMV8},
30350 {"crypto-neon-fp-armv8",
30351 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8},
d6b4b13e 30352 {"neon-fp-armv8.1", FPU_ARCH_NEON_VFP_ARMV8_1},
081e4c7d
MW
30353 {"crypto-neon-fp-armv8.1",
30354 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1},
e74cfd16
PB
30355 {NULL, ARM_ARCH_NONE}
30356};
30357
30358struct arm_option_value_table
30359{
e0471c16 30360 const char *name;
e74cfd16 30361 long value;
c19d1205 30362};
7ed4c4c5 30363
e74cfd16 30364static const struct arm_option_value_table arm_float_abis[] =
c19d1205
ZW
30365{
30366 {"hard", ARM_FLOAT_ABI_HARD},
30367 {"softfp", ARM_FLOAT_ABI_SOFTFP},
30368 {"soft", ARM_FLOAT_ABI_SOFT},
e74cfd16 30369 {NULL, 0}
c19d1205 30370};
7ed4c4c5 30371
c19d1205 30372#ifdef OBJ_ELF
3a4a14e9 30373/* We only know how to output GNU and ver 4/5 (AAELF) formats. */
e74cfd16 30374static const struct arm_option_value_table arm_eabis[] =
c19d1205
ZW
30375{
30376 {"gnu", EF_ARM_EABI_UNKNOWN},
30377 {"4", EF_ARM_EABI_VER4},
3a4a14e9 30378 {"5", EF_ARM_EABI_VER5},
e74cfd16 30379 {NULL, 0}
c19d1205
ZW
30380};
30381#endif
7ed4c4c5 30382
c19d1205
ZW
30383struct arm_long_option_table
30384{
0198d5e6 30385 const char * option; /* Substring to match. */
e0471c16 30386 const char * help; /* Help information. */
17b9d67d 30387 int (* func) (const char * subopt); /* Function to decode sub-option. */
e0471c16 30388 const char * deprecated; /* If non-null, print this message. */
c19d1205 30389};
7ed4c4c5 30390
c921be7d 30391static bfd_boolean
c168ce07 30392arm_parse_extension (const char *str, const arm_feature_set *opt_set,
34ef62f4
AV
30393 arm_feature_set *ext_set,
30394 const struct arm_ext_table *ext_table)
7ed4c4c5 30395{
69133863 30396 /* We insist on extensions being specified in alphabetical order, and with
fa94de6b
RM
30397 extensions being added before being removed. We achieve this by having
30398 the global ARM_EXTENSIONS table in alphabetical order, and using the
69133863 30399 ADDING_VALUE variable to indicate whether we are adding an extension (1)
fa94de6b 30400 or removing it (0) and only allowing it to change in the order
69133863
MGD
30401 -1 -> 1 -> 0. */
30402 const struct arm_option_extension_value_table * opt = NULL;
d942732e 30403 const arm_feature_set arm_any = ARM_ANY;
69133863
MGD
30404 int adding_value = -1;
30405
c19d1205 30406 while (str != NULL && *str != 0)
7ed4c4c5 30407 {
82b8a785 30408 const char *ext;
f3bad469 30409 size_t len;
7ed4c4c5 30410
c19d1205
ZW
30411 if (*str != '+')
30412 {
30413 as_bad (_("invalid architectural extension"));
c921be7d 30414 return FALSE;
c19d1205 30415 }
7ed4c4c5 30416
c19d1205
ZW
30417 str++;
30418 ext = strchr (str, '+');
7ed4c4c5 30419
c19d1205 30420 if (ext != NULL)
f3bad469 30421 len = ext - str;
c19d1205 30422 else
f3bad469 30423 len = strlen (str);
7ed4c4c5 30424
f3bad469 30425 if (len >= 2 && strncmp (str, "no", 2) == 0)
69133863
MGD
30426 {
30427 if (adding_value != 0)
30428 {
30429 adding_value = 0;
30430 opt = arm_extensions;
30431 }
30432
f3bad469 30433 len -= 2;
69133863
MGD
30434 str += 2;
30435 }
f3bad469 30436 else if (len > 0)
69133863
MGD
30437 {
30438 if (adding_value == -1)
30439 {
30440 adding_value = 1;
30441 opt = arm_extensions;
30442 }
30443 else if (adding_value != 1)
30444 {
30445 as_bad (_("must specify extensions to add before specifying "
30446 "those to remove"));
30447 return FALSE;
30448 }
30449 }
30450
f3bad469 30451 if (len == 0)
c19d1205
ZW
30452 {
30453 as_bad (_("missing architectural extension"));
c921be7d 30454 return FALSE;
c19d1205 30455 }
7ed4c4c5 30456
69133863
MGD
30457 gas_assert (adding_value != -1);
30458 gas_assert (opt != NULL);
30459
34ef62f4
AV
30460 if (ext_table != NULL)
30461 {
30462 const struct arm_ext_table * ext_opt = ext_table;
30463 bfd_boolean found = FALSE;
30464 for (; ext_opt->name != NULL; ext_opt++)
30465 if (ext_opt->name_len == len
30466 && strncmp (ext_opt->name, str, len) == 0)
30467 {
30468 if (adding_value)
30469 {
30470 if (ARM_FEATURE_ZERO (ext_opt->merge))
30471 /* TODO: Option not supported. When we remove the
30472 legacy table this case should error out. */
30473 continue;
30474
30475 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, ext_opt->merge);
30476 }
30477 else
30478 {
30479 if (ARM_FEATURE_ZERO (ext_opt->clear))
30480 /* TODO: Option not supported. When we remove the
30481 legacy table this case should error out. */
30482 continue;
30483 ARM_CLEAR_FEATURE (*ext_set, *ext_set, ext_opt->clear);
30484 }
30485 found = TRUE;
30486 break;
30487 }
30488 if (found)
30489 {
30490 str = ext;
30491 continue;
30492 }
30493 }
30494
69133863
MGD
30495 /* Scan over the options table trying to find an exact match. */
30496 for (; opt->name != NULL; opt++)
f3bad469 30497 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 30498 {
d942732e
TP
30499 int i, nb_allowed_archs =
30500 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
69133863 30501 /* Check we can apply the extension to this architecture. */
d942732e
TP
30502 for (i = 0; i < nb_allowed_archs; i++)
30503 {
30504 /* Empty entry. */
30505 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_any))
30506 continue;
c168ce07 30507 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *opt_set))
d942732e
TP
30508 break;
30509 }
30510 if (i == nb_allowed_archs)
69133863
MGD
30511 {
30512 as_bad (_("extension does not apply to the base architecture"));
30513 return FALSE;
30514 }
30515
30516 /* Add or remove the extension. */
30517 if (adding_value)
4d354d8b 30518 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, opt->merge_value);
69133863 30519 else
4d354d8b 30520 ARM_CLEAR_FEATURE (*ext_set, *ext_set, opt->clear_value);
69133863 30521
3d030cdb
TP
30522 /* Allowing Thumb division instructions for ARMv7 in autodetection
30523 rely on this break so that duplicate extensions (extensions
30524 with the same name as a previous extension in the list) are not
30525 considered for command-line parsing. */
c19d1205
ZW
30526 break;
30527 }
7ed4c4c5 30528
c19d1205
ZW
30529 if (opt->name == NULL)
30530 {
69133863
MGD
30531 /* Did we fail to find an extension because it wasn't specified in
30532 alphabetical order, or because it does not exist? */
30533
30534 for (opt = arm_extensions; opt->name != NULL; opt++)
f3bad469 30535 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
69133863
MGD
30536 break;
30537
30538 if (opt->name == NULL)
30539 as_bad (_("unknown architectural extension `%s'"), str);
30540 else
30541 as_bad (_("architectural extensions must be specified in "
30542 "alphabetical order"));
30543
c921be7d 30544 return FALSE;
c19d1205 30545 }
69133863
MGD
30546 else
30547 {
30548 /* We should skip the extension we've just matched the next time
30549 round. */
30550 opt++;
30551 }
7ed4c4c5 30552
c19d1205
ZW
30553 str = ext;
30554 };
7ed4c4c5 30555
c921be7d 30556 return TRUE;
c19d1205 30557}
7ed4c4c5 30558
c921be7d 30559static bfd_boolean
17b9d67d 30560arm_parse_cpu (const char *str)
7ed4c4c5 30561{
f3bad469 30562 const struct arm_cpu_option_table *opt;
82b8a785 30563 const char *ext = strchr (str, '+');
f3bad469 30564 size_t len;
7ed4c4c5 30565
c19d1205 30566 if (ext != NULL)
f3bad469 30567 len = ext - str;
7ed4c4c5 30568 else
f3bad469 30569 len = strlen (str);
7ed4c4c5 30570
f3bad469 30571 if (len == 0)
7ed4c4c5 30572 {
c19d1205 30573 as_bad (_("missing cpu name `%s'"), str);
c921be7d 30574 return FALSE;
7ed4c4c5
NC
30575 }
30576
c19d1205 30577 for (opt = arm_cpus; opt->name != NULL; opt++)
f3bad469 30578 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 30579 {
c168ce07 30580 mcpu_cpu_opt = &opt->value;
4d354d8b
TP
30581 if (mcpu_ext_opt == NULL)
30582 mcpu_ext_opt = XNEW (arm_feature_set);
30583 *mcpu_ext_opt = opt->ext;
e74cfd16 30584 mcpu_fpu_opt = &opt->default_fpu;
ee065d83 30585 if (opt->canonical_name)
ef8e6722
JW
30586 {
30587 gas_assert (sizeof selected_cpu_name > strlen (opt->canonical_name));
30588 strcpy (selected_cpu_name, opt->canonical_name);
30589 }
ee065d83
PB
30590 else
30591 {
f3bad469 30592 size_t i;
c921be7d 30593
ef8e6722
JW
30594 if (len >= sizeof selected_cpu_name)
30595 len = (sizeof selected_cpu_name) - 1;
30596
f3bad469 30597 for (i = 0; i < len; i++)
ee065d83
PB
30598 selected_cpu_name[i] = TOUPPER (opt->name[i]);
30599 selected_cpu_name[i] = 0;
30600 }
7ed4c4c5 30601
c19d1205 30602 if (ext != NULL)
34ef62f4 30603 return arm_parse_extension (ext, mcpu_cpu_opt, mcpu_ext_opt, NULL);
7ed4c4c5 30604
c921be7d 30605 return TRUE;
c19d1205 30606 }
7ed4c4c5 30607
c19d1205 30608 as_bad (_("unknown cpu `%s'"), str);
c921be7d 30609 return FALSE;
7ed4c4c5
NC
30610}
30611
c921be7d 30612static bfd_boolean
17b9d67d 30613arm_parse_arch (const char *str)
7ed4c4c5 30614{
e74cfd16 30615 const struct arm_arch_option_table *opt;
82b8a785 30616 const char *ext = strchr (str, '+');
f3bad469 30617 size_t len;
7ed4c4c5 30618
c19d1205 30619 if (ext != NULL)
f3bad469 30620 len = ext - str;
7ed4c4c5 30621 else
f3bad469 30622 len = strlen (str);
7ed4c4c5 30623
f3bad469 30624 if (len == 0)
7ed4c4c5 30625 {
c19d1205 30626 as_bad (_("missing architecture name `%s'"), str);
c921be7d 30627 return FALSE;
7ed4c4c5
NC
30628 }
30629
c19d1205 30630 for (opt = arm_archs; opt->name != NULL; opt++)
f3bad469 30631 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 30632 {
e74cfd16 30633 march_cpu_opt = &opt->value;
4d354d8b
TP
30634 if (march_ext_opt == NULL)
30635 march_ext_opt = XNEW (arm_feature_set);
30636 *march_ext_opt = arm_arch_none;
e74cfd16 30637 march_fpu_opt = &opt->default_fpu;
5f4273c7 30638 strcpy (selected_cpu_name, opt->name);
7ed4c4c5 30639
c19d1205 30640 if (ext != NULL)
34ef62f4
AV
30641 return arm_parse_extension (ext, march_cpu_opt, march_ext_opt,
30642 opt->ext_table);
7ed4c4c5 30643
c921be7d 30644 return TRUE;
c19d1205
ZW
30645 }
30646
30647 as_bad (_("unknown architecture `%s'\n"), str);
c921be7d 30648 return FALSE;
7ed4c4c5 30649}
eb043451 30650
c921be7d 30651static bfd_boolean
17b9d67d 30652arm_parse_fpu (const char * str)
c19d1205 30653{
69133863 30654 const struct arm_option_fpu_value_table * opt;
b99bd4ef 30655
c19d1205
ZW
30656 for (opt = arm_fpus; opt->name != NULL; opt++)
30657 if (streq (opt->name, str))
30658 {
e74cfd16 30659 mfpu_opt = &opt->value;
c921be7d 30660 return TRUE;
c19d1205 30661 }
b99bd4ef 30662
c19d1205 30663 as_bad (_("unknown floating point format `%s'\n"), str);
c921be7d 30664 return FALSE;
c19d1205
ZW
30665}
30666
c921be7d 30667static bfd_boolean
17b9d67d 30668arm_parse_float_abi (const char * str)
b99bd4ef 30669{
e74cfd16 30670 const struct arm_option_value_table * opt;
b99bd4ef 30671
c19d1205
ZW
30672 for (opt = arm_float_abis; opt->name != NULL; opt++)
30673 if (streq (opt->name, str))
30674 {
30675 mfloat_abi_opt = opt->value;
c921be7d 30676 return TRUE;
c19d1205 30677 }
cc8a6dd0 30678
c19d1205 30679 as_bad (_("unknown floating point abi `%s'\n"), str);
c921be7d 30680 return FALSE;
c19d1205 30681}
b99bd4ef 30682
c19d1205 30683#ifdef OBJ_ELF
c921be7d 30684static bfd_boolean
17b9d67d 30685arm_parse_eabi (const char * str)
c19d1205 30686{
e74cfd16 30687 const struct arm_option_value_table *opt;
cc8a6dd0 30688
c19d1205
ZW
30689 for (opt = arm_eabis; opt->name != NULL; opt++)
30690 if (streq (opt->name, str))
30691 {
30692 meabi_flags = opt->value;
c921be7d 30693 return TRUE;
c19d1205
ZW
30694 }
30695 as_bad (_("unknown EABI `%s'\n"), str);
c921be7d 30696 return FALSE;
c19d1205
ZW
30697}
30698#endif
cc8a6dd0 30699
c921be7d 30700static bfd_boolean
17b9d67d 30701arm_parse_it_mode (const char * str)
e07e6e58 30702{
c921be7d 30703 bfd_boolean ret = TRUE;
e07e6e58
NC
30704
30705 if (streq ("arm", str))
30706 implicit_it_mode = IMPLICIT_IT_MODE_ARM;
30707 else if (streq ("thumb", str))
30708 implicit_it_mode = IMPLICIT_IT_MODE_THUMB;
30709 else if (streq ("always", str))
30710 implicit_it_mode = IMPLICIT_IT_MODE_ALWAYS;
30711 else if (streq ("never", str))
30712 implicit_it_mode = IMPLICIT_IT_MODE_NEVER;
30713 else
30714 {
30715 as_bad (_("unknown implicit IT mode `%s', should be "\
477330fc 30716 "arm, thumb, always, or never."), str);
c921be7d 30717 ret = FALSE;
e07e6e58
NC
30718 }
30719
30720 return ret;
30721}
30722
2e6976a8 30723static bfd_boolean
17b9d67d 30724arm_ccs_mode (const char * unused ATTRIBUTE_UNUSED)
2e6976a8
DG
30725{
30726 codecomposer_syntax = TRUE;
30727 arm_comment_chars[0] = ';';
30728 arm_line_separator_chars[0] = 0;
30729 return TRUE;
30730}
30731
c19d1205
ZW
30732struct arm_long_option_table arm_long_opts[] =
30733{
30734 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
30735 arm_parse_cpu, NULL},
30736 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
30737 arm_parse_arch, NULL},
30738 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
30739 arm_parse_fpu, NULL},
30740 {"mfloat-abi=", N_("<abi>\t assemble for floating point ABI <abi>"),
30741 arm_parse_float_abi, NULL},
30742#ifdef OBJ_ELF
7fac0536 30743 {"meabi=", N_("<ver>\t\t assemble for eabi version <ver>"),
c19d1205
ZW
30744 arm_parse_eabi, NULL},
30745#endif
e07e6e58
NC
30746 {"mimplicit-it=", N_("<mode>\t controls implicit insertion of IT instructions"),
30747 arm_parse_it_mode, NULL},
2e6976a8
DG
30748 {"mccs", N_("\t\t\t TI CodeComposer Studio syntax compatibility mode"),
30749 arm_ccs_mode, NULL},
c19d1205
ZW
30750 {NULL, NULL, 0, NULL}
30751};
cc8a6dd0 30752
c19d1205 30753int
17b9d67d 30754md_parse_option (int c, const char * arg)
c19d1205
ZW
30755{
30756 struct arm_option_table *opt;
e74cfd16 30757 const struct arm_legacy_option_table *fopt;
c19d1205 30758 struct arm_long_option_table *lopt;
b99bd4ef 30759
c19d1205 30760 switch (c)
b99bd4ef 30761 {
c19d1205
ZW
30762#ifdef OPTION_EB
30763 case OPTION_EB:
30764 target_big_endian = 1;
30765 break;
30766#endif
cc8a6dd0 30767
c19d1205
ZW
30768#ifdef OPTION_EL
30769 case OPTION_EL:
30770 target_big_endian = 0;
30771 break;
30772#endif
b99bd4ef 30773
845b51d6
PB
30774 case OPTION_FIX_V4BX:
30775 fix_v4bx = TRUE;
30776 break;
30777
18a20338
CL
30778#ifdef OBJ_ELF
30779 case OPTION_FDPIC:
30780 arm_fdpic = TRUE;
30781 break;
30782#endif /* OBJ_ELF */
30783
c19d1205
ZW
30784 case 'a':
30785 /* Listing option. Just ignore these, we don't support additional
30786 ones. */
30787 return 0;
b99bd4ef 30788
c19d1205
ZW
30789 default:
30790 for (opt = arm_opts; opt->option != NULL; opt++)
30791 {
30792 if (c == opt->option[0]
30793 && ((arg == NULL && opt->option[1] == 0)
30794 || streq (arg, opt->option + 1)))
30795 {
c19d1205 30796 /* If the option is deprecated, tell the user. */
278df34e 30797 if (warn_on_deprecated && opt->deprecated != NULL)
c19d1205
ZW
30798 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
30799 arg ? arg : "", _(opt->deprecated));
b99bd4ef 30800
c19d1205
ZW
30801 if (opt->var != NULL)
30802 *opt->var = opt->value;
cc8a6dd0 30803
c19d1205
ZW
30804 return 1;
30805 }
30806 }
b99bd4ef 30807
e74cfd16
PB
30808 for (fopt = arm_legacy_opts; fopt->option != NULL; fopt++)
30809 {
30810 if (c == fopt->option[0]
30811 && ((arg == NULL && fopt->option[1] == 0)
30812 || streq (arg, fopt->option + 1)))
30813 {
e74cfd16 30814 /* If the option is deprecated, tell the user. */
278df34e 30815 if (warn_on_deprecated && fopt->deprecated != NULL)
e74cfd16
PB
30816 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
30817 arg ? arg : "", _(fopt->deprecated));
e74cfd16
PB
30818
30819 if (fopt->var != NULL)
30820 *fopt->var = &fopt->value;
30821
30822 return 1;
30823 }
30824 }
30825
c19d1205
ZW
30826 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
30827 {
30828 /* These options are expected to have an argument. */
30829 if (c == lopt->option[0]
30830 && arg != NULL
30831 && strncmp (arg, lopt->option + 1,
30832 strlen (lopt->option + 1)) == 0)
30833 {
c19d1205 30834 /* If the option is deprecated, tell the user. */
278df34e 30835 if (warn_on_deprecated && lopt->deprecated != NULL)
c19d1205
ZW
30836 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
30837 _(lopt->deprecated));
b99bd4ef 30838
c19d1205
ZW
30839 /* Call the sup-option parser. */
30840 return lopt->func (arg + strlen (lopt->option) - 1);
30841 }
30842 }
a737bd4d 30843
c19d1205
ZW
30844 return 0;
30845 }
a394c00f 30846
c19d1205
ZW
30847 return 1;
30848}
a394c00f 30849
c19d1205
ZW
30850void
30851md_show_usage (FILE * fp)
a394c00f 30852{
c19d1205
ZW
30853 struct arm_option_table *opt;
30854 struct arm_long_option_table *lopt;
a394c00f 30855
c19d1205 30856 fprintf (fp, _(" ARM-specific assembler options:\n"));
a394c00f 30857
c19d1205
ZW
30858 for (opt = arm_opts; opt->option != NULL; opt++)
30859 if (opt->help != NULL)
30860 fprintf (fp, " -%-23s%s\n", opt->option, _(opt->help));
a394c00f 30861
c19d1205
ZW
30862 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
30863 if (lopt->help != NULL)
30864 fprintf (fp, " -%s%s\n", lopt->option, _(lopt->help));
a394c00f 30865
c19d1205
ZW
30866#ifdef OPTION_EB
30867 fprintf (fp, _("\
30868 -EB assemble code for a big-endian cpu\n"));
a394c00f
NC
30869#endif
30870
c19d1205
ZW
30871#ifdef OPTION_EL
30872 fprintf (fp, _("\
30873 -EL assemble code for a little-endian cpu\n"));
a737bd4d 30874#endif
845b51d6
PB
30875
30876 fprintf (fp, _("\
30877 --fix-v4bx Allow BX in ARMv4 code\n"));
18a20338
CL
30878
30879#ifdef OBJ_ELF
30880 fprintf (fp, _("\
30881 --fdpic generate an FDPIC object file\n"));
30882#endif /* OBJ_ELF */
c19d1205 30883}
ee065d83 30884
ee065d83 30885#ifdef OBJ_ELF
0198d5e6 30886
62b3e311
PB
30887typedef struct
30888{
30889 int val;
30890 arm_feature_set flags;
30891} cpu_arch_ver_table;
30892
2c6b98ea
TP
30893/* Mapping from CPU features to EABI CPU arch values. Table must be sorted
30894 chronologically for architectures, with an exception for ARMv6-M and
30895 ARMv6S-M due to legacy reasons. No new architecture should have a
30896 special case. This allows for build attribute selection results to be
30897 stable when new architectures are added. */
62b3e311
PB
30898static const cpu_arch_ver_table cpu_arch_ver[] =
30899{
031254f2
AV
30900 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V1},
30901 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2},
30902 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2S},
30903 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3},
30904 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3M},
30905 {TAG_CPU_ARCH_V4, ARM_ARCH_V4xM},
30906 {TAG_CPU_ARCH_V4, ARM_ARCH_V4},
30907 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4TxM},
30908 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4T},
30909 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5xM},
30910 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5},
30911 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5TxM},
30912 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5T},
30913 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TExP},
30914 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TE},
30915 {TAG_CPU_ARCH_V5TEJ, ARM_ARCH_V5TEJ},
30916 {TAG_CPU_ARCH_V6, ARM_ARCH_V6},
30917 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6Z},
30918 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6KZ},
30919 {TAG_CPU_ARCH_V6K, ARM_ARCH_V6K},
30920 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6T2},
30921 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KT2},
30922 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6ZT2},
30923 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KZT2},
2c6b98ea
TP
30924
30925 /* When assembling a file with only ARMv6-M or ARMv6S-M instruction, GNU as
30926 always selected build attributes to match those of ARMv6-M
30927 (resp. ARMv6S-M). However, due to these architectures being a strict
30928 subset of ARMv7-M in terms of instructions available, ARMv7-M attributes
30929 would be selected when fully respecting chronology of architectures.
30930 It is thus necessary to make a special case of ARMv6-M and ARMv6S-M and
30931 move them before ARMv7 architectures. */
031254f2
AV
30932 {TAG_CPU_ARCH_V6_M, ARM_ARCH_V6M},
30933 {TAG_CPU_ARCH_V6S_M, ARM_ARCH_V6SM},
30934
30935 {TAG_CPU_ARCH_V7, ARM_ARCH_V7},
30936 {TAG_CPU_ARCH_V7, ARM_ARCH_V7A},
30937 {TAG_CPU_ARCH_V7, ARM_ARCH_V7R},
30938 {TAG_CPU_ARCH_V7, ARM_ARCH_V7M},
30939 {TAG_CPU_ARCH_V7, ARM_ARCH_V7VE},
30940 {TAG_CPU_ARCH_V7E_M, ARM_ARCH_V7EM},
30941 {TAG_CPU_ARCH_V8, ARM_ARCH_V8A},
30942 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_1A},
30943 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_2A},
30944 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_3A},
30945 {TAG_CPU_ARCH_V8M_BASE, ARM_ARCH_V8M_BASE},
30946 {TAG_CPU_ARCH_V8M_MAIN, ARM_ARCH_V8M_MAIN},
30947 {TAG_CPU_ARCH_V8R, ARM_ARCH_V8R},
30948 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_4A},
30949 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_5A},
30950 {TAG_CPU_ARCH_V8_1M_MAIN, ARM_ARCH_V8_1M_MAIN},
30951 {-1, ARM_ARCH_NONE}
62b3e311
PB
30952};
30953
ee3c0378 30954/* Set an attribute if it has not already been set by the user. */
0198d5e6 30955
ee3c0378
AS
30956static void
30957aeabi_set_attribute_int (int tag, int value)
30958{
30959 if (tag < 1
30960 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
30961 || !attributes_set_explicitly[tag])
30962 bfd_elf_add_proc_attr_int (stdoutput, tag, value);
30963}
30964
30965static void
30966aeabi_set_attribute_string (int tag, const char *value)
30967{
30968 if (tag < 1
30969 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
30970 || !attributes_set_explicitly[tag])
30971 bfd_elf_add_proc_attr_string (stdoutput, tag, value);
30972}
30973
2c6b98ea
TP
30974/* Return whether features in the *NEEDED feature set are available via
30975 extensions for the architecture whose feature set is *ARCH_FSET. */
0198d5e6 30976
2c6b98ea
TP
30977static bfd_boolean
30978have_ext_for_needed_feat_p (const arm_feature_set *arch_fset,
30979 const arm_feature_set *needed)
30980{
30981 int i, nb_allowed_archs;
30982 arm_feature_set ext_fset;
30983 const struct arm_option_extension_value_table *opt;
30984
30985 ext_fset = arm_arch_none;
30986 for (opt = arm_extensions; opt->name != NULL; opt++)
30987 {
30988 /* Extension does not provide any feature we need. */
30989 if (!ARM_CPU_HAS_FEATURE (*needed, opt->merge_value))
30990 continue;
30991
30992 nb_allowed_archs =
30993 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
30994 for (i = 0; i < nb_allowed_archs; i++)
30995 {
30996 /* Empty entry. */
30997 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_arch_any))
30998 break;
30999
31000 /* Extension is available, add it. */
31001 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *arch_fset))
31002 ARM_MERGE_FEATURE_SETS (ext_fset, ext_fset, opt->merge_value);
31003 }
31004 }
31005
31006 /* Can we enable all features in *needed? */
31007 return ARM_FSET_CPU_SUBSET (*needed, ext_fset);
31008}
31009
31010/* Select value for Tag_CPU_arch and Tag_CPU_arch_profile build attributes for
31011 a given architecture feature set *ARCH_EXT_FSET including extension feature
31012 set *EXT_FSET. Selection logic used depend on EXACT_MATCH:
31013 - if true, check for an exact match of the architecture modulo extensions;
31014 - otherwise, select build attribute value of the first superset
31015 architecture released so that results remains stable when new architectures
31016 are added.
31017 For -march/-mcpu=all the build attribute value of the most featureful
31018 architecture is returned. Tag_CPU_arch_profile result is returned in
31019 PROFILE. */
0198d5e6 31020
2c6b98ea
TP
31021static int
31022get_aeabi_cpu_arch_from_fset (const arm_feature_set *arch_ext_fset,
31023 const arm_feature_set *ext_fset,
31024 char *profile, int exact_match)
31025{
31026 arm_feature_set arch_fset;
31027 const cpu_arch_ver_table *p_ver, *p_ver_ret = NULL;
31028
31029 /* Select most featureful architecture with all its extensions if building
31030 for -march=all as the feature sets used to set build attributes. */
31031 if (ARM_FEATURE_EQUAL (*arch_ext_fset, arm_arch_any))
31032 {
31033 /* Force revisiting of decision for each new architecture. */
031254f2 31034 gas_assert (MAX_TAG_CPU_ARCH <= TAG_CPU_ARCH_V8_1M_MAIN);
2c6b98ea
TP
31035 *profile = 'A';
31036 return TAG_CPU_ARCH_V8;
31037 }
31038
31039 ARM_CLEAR_FEATURE (arch_fset, *arch_ext_fset, *ext_fset);
31040
31041 for (p_ver = cpu_arch_ver; p_ver->val != -1; p_ver++)
31042 {
31043 arm_feature_set known_arch_fset;
31044
31045 ARM_CLEAR_FEATURE (known_arch_fset, p_ver->flags, fpu_any);
31046 if (exact_match)
31047 {
31048 /* Base architecture match user-specified architecture and
31049 extensions, eg. ARMv6S-M matching -march=armv6-m+os. */
31050 if (ARM_FEATURE_EQUAL (*arch_ext_fset, known_arch_fset))
31051 {
31052 p_ver_ret = p_ver;
31053 goto found;
31054 }
31055 /* Base architecture match user-specified architecture only
31056 (eg. ARMv6-M in the same case as above). Record it in case we
31057 find a match with above condition. */
31058 else if (p_ver_ret == NULL
31059 && ARM_FEATURE_EQUAL (arch_fset, known_arch_fset))
31060 p_ver_ret = p_ver;
31061 }
31062 else
31063 {
31064
31065 /* Architecture has all features wanted. */
31066 if (ARM_FSET_CPU_SUBSET (arch_fset, known_arch_fset))
31067 {
31068 arm_feature_set added_fset;
31069
31070 /* Compute features added by this architecture over the one
31071 recorded in p_ver_ret. */
31072 if (p_ver_ret != NULL)
31073 ARM_CLEAR_FEATURE (added_fset, known_arch_fset,
31074 p_ver_ret->flags);
31075 /* First architecture that match incl. with extensions, or the
31076 only difference in features over the recorded match is
31077 features that were optional and are now mandatory. */
31078 if (p_ver_ret == NULL
31079 || ARM_FSET_CPU_SUBSET (added_fset, arch_fset))
31080 {
31081 p_ver_ret = p_ver;
31082 goto found;
31083 }
31084 }
31085 else if (p_ver_ret == NULL)
31086 {
31087 arm_feature_set needed_ext_fset;
31088
31089 ARM_CLEAR_FEATURE (needed_ext_fset, arch_fset, known_arch_fset);
31090
31091 /* Architecture has all features needed when using some
31092 extensions. Record it and continue searching in case there
31093 exist an architecture providing all needed features without
31094 the need for extensions (eg. ARMv6S-M Vs ARMv6-M with
31095 OS extension). */
31096 if (have_ext_for_needed_feat_p (&known_arch_fset,
31097 &needed_ext_fset))
31098 p_ver_ret = p_ver;
31099 }
31100 }
31101 }
31102
31103 if (p_ver_ret == NULL)
31104 return -1;
31105
31106found:
31107 /* Tag_CPU_arch_profile. */
31108 if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7a)
31109 || ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8)
31110 || (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_atomics)
31111 && !ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8m_m_only)))
31112 *profile = 'A';
31113 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7r))
31114 *profile = 'R';
31115 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_m))
31116 *profile = 'M';
31117 else
31118 *profile = '\0';
31119 return p_ver_ret->val;
31120}
31121
ee065d83 31122/* Set the public EABI object attributes. */
0198d5e6 31123
c168ce07 31124static void
ee065d83
PB
31125aeabi_set_public_attributes (void)
31126{
b90d5ba0 31127 char profile = '\0';
2c6b98ea 31128 int arch = -1;
90ec0d68 31129 int virt_sec = 0;
bca38921 31130 int fp16_optional = 0;
2c6b98ea
TP
31131 int skip_exact_match = 0;
31132 arm_feature_set flags, flags_arch, flags_ext;
ee065d83 31133
54bab281
TP
31134 /* Autodetection mode, choose the architecture based the instructions
31135 actually used. */
31136 if (no_cpu_selected ())
31137 {
31138 ARM_MERGE_FEATURE_SETS (flags, arm_arch_used, thumb_arch_used);
ddd7f988 31139
54bab281
TP
31140 if (ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any))
31141 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v1);
ddd7f988 31142
54bab281
TP
31143 if (ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_any))
31144 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v4t);
ddd7f988 31145
54bab281 31146 /* Code run during relaxation relies on selected_cpu being set. */
4d354d8b
TP
31147 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
31148 flags_ext = arm_arch_none;
31149 ARM_CLEAR_FEATURE (selected_arch, flags_arch, flags_ext);
31150 selected_ext = flags_ext;
54bab281
TP
31151 selected_cpu = flags;
31152 }
31153 /* Otherwise, choose the architecture based on the capabilities of the
31154 requested cpu. */
31155 else
4d354d8b
TP
31156 {
31157 ARM_MERGE_FEATURE_SETS (flags_arch, selected_arch, selected_ext);
31158 ARM_CLEAR_FEATURE (flags_arch, flags_arch, fpu_any);
31159 flags_ext = selected_ext;
31160 flags = selected_cpu;
31161 }
31162 ARM_MERGE_FEATURE_SETS (flags, flags, selected_fpu);
7f78eb34 31163
ddd7f988 31164 /* Allow the user to override the reported architecture. */
4d354d8b 31165 if (!ARM_FEATURE_ZERO (selected_object_arch))
7a1d4c38 31166 {
4d354d8b 31167 ARM_CLEAR_FEATURE (flags_arch, selected_object_arch, fpu_any);
2c6b98ea 31168 flags_ext = arm_arch_none;
7a1d4c38 31169 }
2c6b98ea 31170 else
4d354d8b 31171 skip_exact_match = ARM_FEATURE_EQUAL (selected_cpu, arm_arch_any);
2c6b98ea
TP
31172
31173 /* When this function is run again after relaxation has happened there is no
31174 way to determine whether an architecture or CPU was specified by the user:
31175 - selected_cpu is set above for relaxation to work;
31176 - march_cpu_opt is not set if only -mcpu or .cpu is used;
31177 - mcpu_cpu_opt is set to arm_arch_any for autodetection.
31178 Therefore, if not in -march=all case we first try an exact match and fall
31179 back to autodetection. */
31180 if (!skip_exact_match)
31181 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 1);
31182 if (arch == -1)
31183 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 0);
31184 if (arch == -1)
31185 as_bad (_("no architecture contains all the instructions used\n"));
9e3c6df6 31186
ee065d83
PB
31187 /* Tag_CPU_name. */
31188 if (selected_cpu_name[0])
31189 {
91d6fa6a 31190 char *q;
ee065d83 31191
91d6fa6a
NC
31192 q = selected_cpu_name;
31193 if (strncmp (q, "armv", 4) == 0)
ee065d83
PB
31194 {
31195 int i;
5f4273c7 31196
91d6fa6a
NC
31197 q += 4;
31198 for (i = 0; q[i]; i++)
31199 q[i] = TOUPPER (q[i]);
ee065d83 31200 }
91d6fa6a 31201 aeabi_set_attribute_string (Tag_CPU_name, q);
ee065d83 31202 }
62f3b8c8 31203
ee065d83 31204 /* Tag_CPU_arch. */
ee3c0378 31205 aeabi_set_attribute_int (Tag_CPU_arch, arch);
62f3b8c8 31206
62b3e311 31207 /* Tag_CPU_arch_profile. */
69239280
MGD
31208 if (profile != '\0')
31209 aeabi_set_attribute_int (Tag_CPU_arch_profile, profile);
62f3b8c8 31210
15afaa63 31211 /* Tag_DSP_extension. */
4d354d8b 31212 if (ARM_CPU_HAS_FEATURE (selected_ext, arm_ext_dsp))
6c290d53 31213 aeabi_set_attribute_int (Tag_DSP_extension, 1);
15afaa63 31214
2c6b98ea 31215 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
ee065d83 31216 /* Tag_ARM_ISA_use. */
ee3c0378 31217 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v1)
2c6b98ea 31218 || ARM_FEATURE_ZERO (flags_arch))
ee3c0378 31219 aeabi_set_attribute_int (Tag_ARM_ISA_use, 1);
62f3b8c8 31220
ee065d83 31221 /* Tag_THUMB_ISA_use. */
ee3c0378 31222 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v4t)
2c6b98ea 31223 || ARM_FEATURE_ZERO (flags_arch))
4ed7ed8d
TP
31224 {
31225 int thumb_isa_use;
31226
31227 if (!ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
16a1fa25 31228 && ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m_m_only))
4ed7ed8d
TP
31229 thumb_isa_use = 3;
31230 else if (ARM_CPU_HAS_FEATURE (flags, arm_arch_t2))
31231 thumb_isa_use = 2;
31232 else
31233 thumb_isa_use = 1;
31234 aeabi_set_attribute_int (Tag_THUMB_ISA_use, thumb_isa_use);
31235 }
62f3b8c8 31236
ee065d83 31237 /* Tag_VFP_arch. */
a715796b
TG
31238 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_armv8xd))
31239 aeabi_set_attribute_int (Tag_VFP_arch,
31240 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
31241 ? 7 : 8);
bca38921 31242 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_fma))
62f3b8c8
PB
31243 aeabi_set_attribute_int (Tag_VFP_arch,
31244 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
31245 ? 5 : 6);
31246 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32))
bca38921
MGD
31247 {
31248 fp16_optional = 1;
31249 aeabi_set_attribute_int (Tag_VFP_arch, 3);
31250 }
ada65aa3 31251 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v3xd))
bca38921
MGD
31252 {
31253 aeabi_set_attribute_int (Tag_VFP_arch, 4);
31254 fp16_optional = 1;
31255 }
ee3c0378
AS
31256 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v2))
31257 aeabi_set_attribute_int (Tag_VFP_arch, 2);
31258 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1)
477330fc 31259 || ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd))
ee3c0378 31260 aeabi_set_attribute_int (Tag_VFP_arch, 1);
62f3b8c8 31261
4547cb56
NC
31262 /* Tag_ABI_HardFP_use. */
31263 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd)
31264 && !ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1))
31265 aeabi_set_attribute_int (Tag_ABI_HardFP_use, 1);
31266
ee065d83 31267 /* Tag_WMMX_arch. */
ee3c0378
AS
31268 if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt2))
31269 aeabi_set_attribute_int (Tag_WMMX_arch, 2);
31270 else if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt))
31271 aeabi_set_attribute_int (Tag_WMMX_arch, 1);
62f3b8c8 31272
ee3c0378 31273 /* Tag_Advanced_SIMD_arch (formerly Tag_NEON_arch). */
9411fd44
MW
31274 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v8_1))
31275 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 4);
31276 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_armv8))
bca38921
MGD
31277 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 3);
31278 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v1))
31279 {
31280 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_fma))
31281 {
31282 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 2);
31283 }
31284 else
31285 {
31286 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 1);
31287 fp16_optional = 1;
31288 }
31289 }
fa94de6b 31290
a7ad558c
AV
31291 if (ARM_CPU_HAS_FEATURE (flags, mve_fp_ext))
31292 aeabi_set_attribute_int (Tag_MVE_arch, 2);
31293 else if (ARM_CPU_HAS_FEATURE (flags, mve_ext))
31294 aeabi_set_attribute_int (Tag_MVE_arch, 1);
31295
ee3c0378 31296 /* Tag_VFP_HP_extension (formerly Tag_NEON_FP16_arch). */
bca38921 31297 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_fp16) && fp16_optional)
ee3c0378 31298 aeabi_set_attribute_int (Tag_VFP_HP_extension, 1);
4547cb56 31299
69239280
MGD
31300 /* Tag_DIV_use.
31301
31302 We set Tag_DIV_use to two when integer divide instructions have been used
31303 in ARM state, or when Thumb integer divide instructions have been used,
31304 but we have no architecture profile set, nor have we any ARM instructions.
31305
4ed7ed8d
TP
31306 For ARMv8-A and ARMv8-M we set the tag to 0 as integer divide is implied
31307 by the base architecture.
bca38921 31308
69239280 31309 For new architectures we will have to check these tests. */
031254f2 31310 gas_assert (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
4ed7ed8d
TP
31311 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
31312 || ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m))
bca38921
MGD
31313 aeabi_set_attribute_int (Tag_DIV_use, 0);
31314 else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_adiv)
31315 || (profile == '\0'
31316 && ARM_CPU_HAS_FEATURE (flags, arm_ext_div)
31317 && !ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any)))
eea54501 31318 aeabi_set_attribute_int (Tag_DIV_use, 2);
60e5ef9f
MGD
31319
31320 /* Tag_MP_extension_use. */
31321 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_mp))
31322 aeabi_set_attribute_int (Tag_MPextension_use, 1);
f4c65163
MGD
31323
31324 /* Tag Virtualization_use. */
31325 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_sec))
90ec0d68
MGD
31326 virt_sec |= 1;
31327 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_virt))
31328 virt_sec |= 2;
31329 if (virt_sec != 0)
31330 aeabi_set_attribute_int (Tag_Virtualization_use, virt_sec);
ee065d83
PB
31331}
31332
c168ce07
TP
31333/* Post relaxation hook. Recompute ARM attributes now that relaxation is
31334 finished and free extension feature bits which will not be used anymore. */
0198d5e6 31335
c168ce07
TP
31336void
31337arm_md_post_relax (void)
31338{
31339 aeabi_set_public_attributes ();
4d354d8b
TP
31340 XDELETE (mcpu_ext_opt);
31341 mcpu_ext_opt = NULL;
31342 XDELETE (march_ext_opt);
31343 march_ext_opt = NULL;
c168ce07
TP
31344}
31345
104d59d1 31346/* Add the default contents for the .ARM.attributes section. */
0198d5e6 31347
ee065d83
PB
31348void
31349arm_md_end (void)
31350{
ee065d83
PB
31351 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
31352 return;
31353
31354 aeabi_set_public_attributes ();
ee065d83 31355}
8463be01 31356#endif /* OBJ_ELF */
ee065d83 31357
ee065d83
PB
31358/* Parse a .cpu directive. */
31359
31360static void
31361s_arm_cpu (int ignored ATTRIBUTE_UNUSED)
31362{
e74cfd16 31363 const struct arm_cpu_option_table *opt;
ee065d83
PB
31364 char *name;
31365 char saved_char;
31366
31367 name = input_line_pointer;
5f4273c7 31368 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
31369 input_line_pointer++;
31370 saved_char = *input_line_pointer;
31371 *input_line_pointer = 0;
31372
31373 /* Skip the first "all" entry. */
31374 for (opt = arm_cpus + 1; opt->name != NULL; opt++)
31375 if (streq (opt->name, name))
31376 {
4d354d8b
TP
31377 selected_arch = opt->value;
31378 selected_ext = opt->ext;
31379 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
ee065d83 31380 if (opt->canonical_name)
5f4273c7 31381 strcpy (selected_cpu_name, opt->canonical_name);
ee065d83
PB
31382 else
31383 {
31384 int i;
31385 for (i = 0; opt->name[i]; i++)
31386 selected_cpu_name[i] = TOUPPER (opt->name[i]);
f3bad469 31387
ee065d83
PB
31388 selected_cpu_name[i] = 0;
31389 }
4d354d8b
TP
31390 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
31391
ee065d83
PB
31392 *input_line_pointer = saved_char;
31393 demand_empty_rest_of_line ();
31394 return;
31395 }
31396 as_bad (_("unknown cpu `%s'"), name);
31397 *input_line_pointer = saved_char;
31398 ignore_rest_of_line ();
31399}
31400
ee065d83
PB
31401/* Parse a .arch directive. */
31402
31403static void
31404s_arm_arch (int ignored ATTRIBUTE_UNUSED)
31405{
e74cfd16 31406 const struct arm_arch_option_table *opt;
ee065d83
PB
31407 char saved_char;
31408 char *name;
31409
31410 name = input_line_pointer;
5f4273c7 31411 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
31412 input_line_pointer++;
31413 saved_char = *input_line_pointer;
31414 *input_line_pointer = 0;
31415
31416 /* Skip the first "all" entry. */
31417 for (opt = arm_archs + 1; opt->name != NULL; opt++)
31418 if (streq (opt->name, name))
31419 {
4d354d8b
TP
31420 selected_arch = opt->value;
31421 selected_ext = arm_arch_none;
31422 selected_cpu = selected_arch;
5f4273c7 31423 strcpy (selected_cpu_name, opt->name);
4d354d8b 31424 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83
PB
31425 *input_line_pointer = saved_char;
31426 demand_empty_rest_of_line ();
31427 return;
31428 }
31429
31430 as_bad (_("unknown architecture `%s'\n"), name);
31431 *input_line_pointer = saved_char;
31432 ignore_rest_of_line ();
31433}
31434
7a1d4c38
PB
31435/* Parse a .object_arch directive. */
31436
31437static void
31438s_arm_object_arch (int ignored ATTRIBUTE_UNUSED)
31439{
31440 const struct arm_arch_option_table *opt;
31441 char saved_char;
31442 char *name;
31443
31444 name = input_line_pointer;
5f4273c7 31445 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
7a1d4c38
PB
31446 input_line_pointer++;
31447 saved_char = *input_line_pointer;
31448 *input_line_pointer = 0;
31449
31450 /* Skip the first "all" entry. */
31451 for (opt = arm_archs + 1; opt->name != NULL; opt++)
31452 if (streq (opt->name, name))
31453 {
4d354d8b 31454 selected_object_arch = opt->value;
7a1d4c38
PB
31455 *input_line_pointer = saved_char;
31456 demand_empty_rest_of_line ();
31457 return;
31458 }
31459
31460 as_bad (_("unknown architecture `%s'\n"), name);
31461 *input_line_pointer = saved_char;
31462 ignore_rest_of_line ();
31463}
31464
69133863
MGD
31465/* Parse a .arch_extension directive. */
31466
31467static void
31468s_arm_arch_extension (int ignored ATTRIBUTE_UNUSED)
31469{
31470 const struct arm_option_extension_value_table *opt;
31471 char saved_char;
31472 char *name;
31473 int adding_value = 1;
31474
31475 name = input_line_pointer;
31476 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
31477 input_line_pointer++;
31478 saved_char = *input_line_pointer;
31479 *input_line_pointer = 0;
31480
31481 if (strlen (name) >= 2
31482 && strncmp (name, "no", 2) == 0)
31483 {
31484 adding_value = 0;
31485 name += 2;
31486 }
31487
31488 for (opt = arm_extensions; opt->name != NULL; opt++)
31489 if (streq (opt->name, name))
31490 {
d942732e
TP
31491 int i, nb_allowed_archs =
31492 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[i]);
31493 for (i = 0; i < nb_allowed_archs; i++)
31494 {
31495 /* Empty entry. */
4d354d8b 31496 if (ARM_CPU_IS_ANY (opt->allowed_archs[i]))
d942732e 31497 continue;
4d354d8b 31498 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], selected_arch))
d942732e
TP
31499 break;
31500 }
31501
31502 if (i == nb_allowed_archs)
69133863
MGD
31503 {
31504 as_bad (_("architectural extension `%s' is not allowed for the "
31505 "current base architecture"), name);
31506 break;
31507 }
31508
31509 if (adding_value)
4d354d8b 31510 ARM_MERGE_FEATURE_SETS (selected_ext, selected_ext,
5a70a223 31511 opt->merge_value);
69133863 31512 else
4d354d8b 31513 ARM_CLEAR_FEATURE (selected_ext, selected_ext, opt->clear_value);
69133863 31514
4d354d8b
TP
31515 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
31516 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
69133863
MGD
31517 *input_line_pointer = saved_char;
31518 demand_empty_rest_of_line ();
3d030cdb
TP
31519 /* Allowing Thumb division instructions for ARMv7 in autodetection rely
31520 on this return so that duplicate extensions (extensions with the
31521 same name as a previous extension in the list) are not considered
31522 for command-line parsing. */
69133863
MGD
31523 return;
31524 }
31525
31526 if (opt->name == NULL)
e673710a 31527 as_bad (_("unknown architecture extension `%s'\n"), name);
69133863
MGD
31528
31529 *input_line_pointer = saved_char;
31530 ignore_rest_of_line ();
31531}
31532
ee065d83
PB
31533/* Parse a .fpu directive. */
31534
31535static void
31536s_arm_fpu (int ignored ATTRIBUTE_UNUSED)
31537{
69133863 31538 const struct arm_option_fpu_value_table *opt;
ee065d83
PB
31539 char saved_char;
31540 char *name;
31541
31542 name = input_line_pointer;
5f4273c7 31543 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
31544 input_line_pointer++;
31545 saved_char = *input_line_pointer;
31546 *input_line_pointer = 0;
5f4273c7 31547
ee065d83
PB
31548 for (opt = arm_fpus; opt->name != NULL; opt++)
31549 if (streq (opt->name, name))
31550 {
4d354d8b
TP
31551 selected_fpu = opt->value;
31552#ifndef CPU_DEFAULT
31553 if (no_cpu_selected ())
31554 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
31555 else
31556#endif
31557 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83
PB
31558 *input_line_pointer = saved_char;
31559 demand_empty_rest_of_line ();
31560 return;
31561 }
31562
31563 as_bad (_("unknown floating point format `%s'\n"), name);
31564 *input_line_pointer = saved_char;
31565 ignore_rest_of_line ();
31566}
ee065d83 31567
794ba86a 31568/* Copy symbol information. */
f31fef98 31569
794ba86a
DJ
31570void
31571arm_copy_symbol_attributes (symbolS *dest, symbolS *src)
31572{
31573 ARM_GET_FLAG (dest) = ARM_GET_FLAG (src);
31574}
e04befd0 31575
f31fef98 31576#ifdef OBJ_ELF
e04befd0
AS
31577/* Given a symbolic attribute NAME, return the proper integer value.
31578 Returns -1 if the attribute is not known. */
f31fef98 31579
e04befd0
AS
31580int
31581arm_convert_symbolic_attribute (const char *name)
31582{
f31fef98
NC
31583 static const struct
31584 {
31585 const char * name;
31586 const int tag;
31587 }
31588 attribute_table[] =
31589 {
31590 /* When you modify this table you should
31591 also modify the list in doc/c-arm.texi. */
e04befd0 31592#define T(tag) {#tag, tag}
f31fef98
NC
31593 T (Tag_CPU_raw_name),
31594 T (Tag_CPU_name),
31595 T (Tag_CPU_arch),
31596 T (Tag_CPU_arch_profile),
31597 T (Tag_ARM_ISA_use),
31598 T (Tag_THUMB_ISA_use),
75375b3e 31599 T (Tag_FP_arch),
f31fef98
NC
31600 T (Tag_VFP_arch),
31601 T (Tag_WMMX_arch),
31602 T (Tag_Advanced_SIMD_arch),
31603 T (Tag_PCS_config),
31604 T (Tag_ABI_PCS_R9_use),
31605 T (Tag_ABI_PCS_RW_data),
31606 T (Tag_ABI_PCS_RO_data),
31607 T (Tag_ABI_PCS_GOT_use),
31608 T (Tag_ABI_PCS_wchar_t),
31609 T (Tag_ABI_FP_rounding),
31610 T (Tag_ABI_FP_denormal),
31611 T (Tag_ABI_FP_exceptions),
31612 T (Tag_ABI_FP_user_exceptions),
31613 T (Tag_ABI_FP_number_model),
75375b3e 31614 T (Tag_ABI_align_needed),
f31fef98 31615 T (Tag_ABI_align8_needed),
75375b3e 31616 T (Tag_ABI_align_preserved),
f31fef98
NC
31617 T (Tag_ABI_align8_preserved),
31618 T (Tag_ABI_enum_size),
31619 T (Tag_ABI_HardFP_use),
31620 T (Tag_ABI_VFP_args),
31621 T (Tag_ABI_WMMX_args),
31622 T (Tag_ABI_optimization_goals),
31623 T (Tag_ABI_FP_optimization_goals),
31624 T (Tag_compatibility),
31625 T (Tag_CPU_unaligned_access),
75375b3e 31626 T (Tag_FP_HP_extension),
f31fef98
NC
31627 T (Tag_VFP_HP_extension),
31628 T (Tag_ABI_FP_16bit_format),
cd21e546
MGD
31629 T (Tag_MPextension_use),
31630 T (Tag_DIV_use),
f31fef98
NC
31631 T (Tag_nodefaults),
31632 T (Tag_also_compatible_with),
31633 T (Tag_conformance),
31634 T (Tag_T2EE_use),
31635 T (Tag_Virtualization_use),
15afaa63 31636 T (Tag_DSP_extension),
a7ad558c 31637 T (Tag_MVE_arch),
cd21e546 31638 /* We deliberately do not include Tag_MPextension_use_legacy. */
e04befd0 31639#undef T
f31fef98 31640 };
e04befd0
AS
31641 unsigned int i;
31642
31643 if (name == NULL)
31644 return -1;
31645
f31fef98 31646 for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
c921be7d 31647 if (streq (name, attribute_table[i].name))
e04befd0
AS
31648 return attribute_table[i].tag;
31649
31650 return -1;
31651}
267bf995 31652
93ef582d
NC
31653/* Apply sym value for relocations only in the case that they are for
31654 local symbols in the same segment as the fixup and you have the
31655 respective architectural feature for blx and simple switches. */
0198d5e6 31656
267bf995 31657int
93ef582d 31658arm_apply_sym_value (struct fix * fixP, segT this_seg)
267bf995
RR
31659{
31660 if (fixP->fx_addsy
31661 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
93ef582d
NC
31662 /* PR 17444: If the local symbol is in a different section then a reloc
31663 will always be generated for it, so applying the symbol value now
31664 will result in a double offset being stored in the relocation. */
31665 && (S_GET_SEGMENT (fixP->fx_addsy) == this_seg)
34e77a92 31666 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE))
267bf995
RR
31667 {
31668 switch (fixP->fx_r_type)
31669 {
31670 case BFD_RELOC_ARM_PCREL_BLX:
31671 case BFD_RELOC_THUMB_PCREL_BRANCH23:
31672 if (ARM_IS_FUNC (fixP->fx_addsy))
31673 return 1;
31674 break;
31675
31676 case BFD_RELOC_ARM_PCREL_CALL:
31677 case BFD_RELOC_THUMB_PCREL_BLX:
31678 if (THUMB_IS_FUNC (fixP->fx_addsy))
93ef582d 31679 return 1;
267bf995
RR
31680 break;
31681
31682 default:
31683 break;
31684 }
31685
31686 }
31687 return 0;
31688}
f31fef98 31689#endif /* OBJ_ELF */
This page took 4.633383 seconds and 4 git commands to generate.