[binutils][Arm] Fix Branch Future relocation handling and testisms
[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. */
35d1cfc2 6926 OP_RMQRR, /* MVE vector or ARM register. */
a302e574 6927
60f993ce
AV
6928 /* New operands for Armv8.1-M Mainline. */
6929 OP_LR, /* ARM LR register */
a302e574
AV
6930 OP_RRe, /* ARM register, only even numbered. */
6931 OP_RRo, /* ARM register, only odd numbered, not r13 or r15. */
60f993ce
AV
6932 OP_RRnpcsp_I32, /* ARM register (no BadReg) or literal 1 .. 32 */
6933
c19d1205 6934 OP_REGLST, /* ARM register list */
4b5a202f 6935 OP_CLRMLST, /* CLRM register list */
c19d1205
ZW
6936 OP_VRSLST, /* VFP single-precision register list */
6937 OP_VRDLST, /* VFP double-precision register list */
037e8744 6938 OP_VRSDLST, /* VFP single or double-precision register list (& quad) */
5287ad62
JB
6939 OP_NRDLST, /* Neon double-precision register list (d0-d31, qN aliases) */
6940 OP_NSTRLST, /* Neon element/structure list */
efd6b359 6941 OP_VRSDVLST, /* VFP single or double-precision register list and VPR */
35c228db
AV
6942 OP_MSTRLST2, /* MVE vector list with two elements. */
6943 OP_MSTRLST4, /* MVE vector list with four elements. */
5287ad62 6944
5287ad62 6945 OP_RNDQ_I0, /* Neon D or Q reg, or immediate zero. */
037e8744 6946 OP_RVSD_I0, /* VFP S or D reg, or immediate zero. */
aacf0b33 6947 OP_RSVD_FI0, /* VFP S or D reg, or floating point immediate zero. */
1b883319
AV
6948 OP_RSVDMQ_FI0, /* VFP S, D, MVE vector register or floating point immediate
6949 zero. */
5287ad62 6950 OP_RR_RNSC, /* ARM reg or Neon scalar. */
dec41383 6951 OP_RNSD_RNSC, /* Neon S or D reg, or Neon scalar. */
037e8744 6952 OP_RNSDQ_RNSC, /* Vector S, D or Q reg, or Neon scalar. */
886e1c73
AV
6953 OP_RNSDQ_RNSC_MQ, /* Vector S, D or Q reg, Neon scalar or MVE vector register.
6954 */
a8465a06
AV
6955 OP_RNSDQ_RNSC_MQ_RR, /* Vector S, D or Q reg, or MVE vector reg , or Neon
6956 scalar, or ARM register. */
5287ad62 6957 OP_RNDQ_RNSC, /* Neon D or Q reg, or Neon scalar. */
42b16635
AV
6958 OP_RNDQ_RNSC_RR, /* Neon D or Q reg, Neon scalar, or ARM register. */
6959 OP_RNDQMQ_RNSC_RR, /* Neon D or Q reg, Neon scalar, MVE vector or ARM
6960 register. */
5d281bf0 6961 OP_RNDQMQ_RNSC, /* Neon D, Q or MVE vector reg, or Neon scalar. */
5287ad62
JB
6962 OP_RND_RNSC, /* Neon D reg, or Neon scalar. */
6963 OP_VMOV, /* Neon VMOV operands. */
4316f0d2 6964 OP_RNDQ_Ibig, /* Neon D or Q reg, or big immediate for logic and VMVN. */
f601a00c
AV
6965 /* Neon D, Q or MVE vector register, or big immediate for logic and VMVN. */
6966 OP_RNDQMQ_Ibig,
5287ad62 6967 OP_RNDQ_I63b, /* Neon D or Q reg, or immediate for shift. */
5150f0d8
AV
6968 OP_RNDQMQ_I63b_RR, /* Neon D or Q reg, immediate for shift, MVE vector or
6969 ARM register. */
2d447fca 6970 OP_RIWR_I32z, /* iWMMXt wR register, or immediate 0 .. 32 for iWMMXt2. */
32c36c3c 6971 OP_VLDR, /* VLDR operand. */
5287ad62
JB
6972
6973 OP_I0, /* immediate zero */
c19d1205
ZW
6974 OP_I7, /* immediate value 0 .. 7 */
6975 OP_I15, /* 0 .. 15 */
6976 OP_I16, /* 1 .. 16 */
5287ad62 6977 OP_I16z, /* 0 .. 16 */
c19d1205
ZW
6978 OP_I31, /* 0 .. 31 */
6979 OP_I31w, /* 0 .. 31, optional trailing ! */
6980 OP_I32, /* 1 .. 32 */
5287ad62
JB
6981 OP_I32z, /* 0 .. 32 */
6982 OP_I63, /* 0 .. 63 */
c19d1205 6983 OP_I63s, /* -64 .. 63 */
5287ad62
JB
6984 OP_I64, /* 1 .. 64 */
6985 OP_I64z, /* 0 .. 64 */
c19d1205 6986 OP_I255, /* 0 .. 255 */
c19d1205
ZW
6987
6988 OP_I4b, /* immediate, prefix optional, 1 .. 4 */
6989 OP_I7b, /* 0 .. 7 */
6990 OP_I15b, /* 0 .. 15 */
6991 OP_I31b, /* 0 .. 31 */
6992
6993 OP_SH, /* shifter operand */
4962c51a 6994 OP_SHG, /* shifter operand with possible group relocation */
c19d1205 6995 OP_ADDR, /* Memory address expression (any mode) */
35c228db 6996 OP_ADDRMVE, /* Memory address expression for MVE's VSTR/VLDR. */
4962c51a
MS
6997 OP_ADDRGLDR, /* Mem addr expr (any mode) with possible LDR group reloc */
6998 OP_ADDRGLDRS, /* Mem addr expr (any mode) with possible LDRS group reloc */
6999 OP_ADDRGLDC, /* Mem addr expr (any mode) with possible LDC group reloc */
c19d1205
ZW
7000 OP_EXP, /* arbitrary expression */
7001 OP_EXPi, /* same, with optional immediate prefix */
7002 OP_EXPr, /* same, with optional relocation suffix */
e2b0ab59 7003 OP_EXPs, /* same, with optional non-first operand relocation suffix */
b6895b4f 7004 OP_HALF, /* 0 .. 65535 or low/high reloc. */
c28eeff2
SN
7005 OP_IROT1, /* VCADD rotate immediate: 90, 270. */
7006 OP_IROT2, /* VCMLA rotate immediate: 0, 90, 180, 270. */
c19d1205
ZW
7007
7008 OP_CPSF, /* CPS flags */
7009 OP_ENDI, /* Endianness specifier */
d2cd1205
JB
7010 OP_wPSR, /* CPSR/SPSR/APSR mask for msr (writing). */
7011 OP_rPSR, /* CPSR/SPSR/APSR mask for msr (reading). */
c19d1205 7012 OP_COND, /* conditional code */
92e90b6e 7013 OP_TB, /* Table branch. */
c19d1205 7014
037e8744
JB
7015 OP_APSR_RR, /* ARM register or "APSR_nzcv". */
7016
c19d1205 7017 OP_RRnpc_I0, /* ARM register or literal 0 */
33eaf5de 7018 OP_RR_EXr, /* ARM register or expression with opt. reloc stuff. */
c19d1205
ZW
7019 OP_RR_EXi, /* ARM register or expression with imm prefix */
7020 OP_RF_IF, /* FPA register or immediate */
7021 OP_RIWR_RIWC, /* iWMMXt R or C reg */
41adaa5c 7022 OP_RIWC_RIWG, /* iWMMXt wC or wCG reg */
c19d1205
ZW
7023
7024 /* Optional operands. */
7025 OP_oI7b, /* immediate, prefix optional, 0 .. 7 */
7026 OP_oI31b, /* 0 .. 31 */
5287ad62 7027 OP_oI32b, /* 1 .. 32 */
5f1af56b 7028 OP_oI32z, /* 0 .. 32 */
c19d1205
ZW
7029 OP_oIffffb, /* 0 .. 65535 */
7030 OP_oI255c, /* curly-brace enclosed, 0 .. 255 */
7031
7032 OP_oRR, /* ARM register */
60f993ce 7033 OP_oLR, /* ARM LR register */
c19d1205 7034 OP_oRRnpc, /* ARM register, not the PC */
5be8be5d 7035 OP_oRRnpcsp, /* ARM register, neither the PC nor the SP (a.k.a. BadReg) */
b6702015 7036 OP_oRRw, /* ARM register, not r15, optional trailing ! */
5287ad62
JB
7037 OP_oRND, /* Optional Neon double precision register */
7038 OP_oRNQ, /* Optional Neon quad precision register */
5ee91343 7039 OP_oRNDQMQ, /* Optional Neon double, quad or MVE vector register. */
5287ad62 7040 OP_oRNDQ, /* Optional Neon double or quad precision register */
037e8744 7041 OP_oRNSDQ, /* Optional single, double or quad precision vector register */
5ee91343
AV
7042 OP_oRNSDQMQ, /* Optional single, double or quad register or MVE vector
7043 register. */
c19d1205
ZW
7044 OP_oSHll, /* LSL immediate */
7045 OP_oSHar, /* ASR immediate */
7046 OP_oSHllar, /* LSL or ASR immediate */
7047 OP_oROR, /* ROR 0/8/16/24 */
52e7f43d 7048 OP_oBARRIER_I15, /* Option argument for a barrier instruction. */
c19d1205 7049
1b883319
AV
7050 OP_oRMQRZ, /* optional MVE vector or ARM register including ZR. */
7051
5be8be5d
DG
7052 /* Some pre-defined mixed (ARM/THUMB) operands. */
7053 OP_RR_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RR, OP_RRnpcsp),
7054 OP_RRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RRnpc, OP_RRnpcsp),
7055 OP_oRRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_oRRnpc, OP_oRRnpcsp),
7056
c19d1205
ZW
7057 OP_FIRST_OPTIONAL = OP_oI7b
7058};
a737bd4d 7059
c19d1205
ZW
7060/* Generic instruction operand parser. This does no encoding and no
7061 semantic validation; it merely squirrels values away in the inst
7062 structure. Returns SUCCESS or FAIL depending on whether the
7063 specified grammar matched. */
7064static int
5be8be5d 7065parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
c19d1205 7066{
5be8be5d 7067 unsigned const int *upat = pattern;
c19d1205
ZW
7068 char *backtrack_pos = 0;
7069 const char *backtrack_error = 0;
99aad254 7070 int i, val = 0, backtrack_index = 0;
5287ad62 7071 enum arm_reg_type rtype;
4962c51a 7072 parse_operand_result result;
5be8be5d 7073 unsigned int op_parse_code;
efd6b359 7074 bfd_boolean partial_match;
c19d1205 7075
e07e6e58
NC
7076#define po_char_or_fail(chr) \
7077 do \
7078 { \
7079 if (skip_past_char (&str, chr) == FAIL) \
477330fc 7080 goto bad_args; \
e07e6e58
NC
7081 } \
7082 while (0)
c19d1205 7083
e07e6e58
NC
7084#define po_reg_or_fail(regtype) \
7085 do \
dcbf9037 7086 { \
e07e6e58 7087 val = arm_typed_reg_parse (& str, regtype, & rtype, \
477330fc 7088 & inst.operands[i].vectype); \
e07e6e58 7089 if (val == FAIL) \
477330fc
RM
7090 { \
7091 first_error (_(reg_expected_msgs[regtype])); \
7092 goto failure; \
7093 } \
e07e6e58
NC
7094 inst.operands[i].reg = val; \
7095 inst.operands[i].isreg = 1; \
7096 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
7097 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
7098 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc
RM
7099 || rtype == REG_TYPE_VFD \
7100 || rtype == REG_TYPE_NQ); \
1b883319 7101 inst.operands[i].iszr = (rtype == REG_TYPE_ZR); \
dcbf9037 7102 } \
e07e6e58
NC
7103 while (0)
7104
7105#define po_reg_or_goto(regtype, label) \
7106 do \
7107 { \
7108 val = arm_typed_reg_parse (& str, regtype, & rtype, \
7109 & inst.operands[i].vectype); \
7110 if (val == FAIL) \
7111 goto label; \
dcbf9037 7112 \
e07e6e58
NC
7113 inst.operands[i].reg = val; \
7114 inst.operands[i].isreg = 1; \
7115 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
7116 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
7117 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc 7118 || rtype == REG_TYPE_VFD \
e07e6e58 7119 || rtype == REG_TYPE_NQ); \
1b883319 7120 inst.operands[i].iszr = (rtype == REG_TYPE_ZR); \
e07e6e58
NC
7121 } \
7122 while (0)
7123
7124#define po_imm_or_fail(min, max, popt) \
7125 do \
7126 { \
7127 if (parse_immediate (&str, &val, min, max, popt) == FAIL) \
7128 goto failure; \
7129 inst.operands[i].imm = val; \
7130 } \
7131 while (0)
7132
57785aa2 7133#define po_scalar_or_goto(elsz, label, reg_type) \
e07e6e58
NC
7134 do \
7135 { \
57785aa2
AV
7136 val = parse_scalar (& str, elsz, & inst.operands[i].vectype, \
7137 reg_type); \
e07e6e58
NC
7138 if (val == FAIL) \
7139 goto label; \
7140 inst.operands[i].reg = val; \
7141 inst.operands[i].isscalar = 1; \
7142 } \
7143 while (0)
7144
7145#define po_misc_or_fail(expr) \
7146 do \
7147 { \
7148 if (expr) \
7149 goto failure; \
7150 } \
7151 while (0)
7152
7153#define po_misc_or_fail_no_backtrack(expr) \
7154 do \
7155 { \
7156 result = expr; \
7157 if (result == PARSE_OPERAND_FAIL_NO_BACKTRACK) \
7158 backtrack_pos = 0; \
7159 if (result != PARSE_OPERAND_SUCCESS) \
7160 goto failure; \
7161 } \
7162 while (0)
4962c51a 7163
52e7f43d
RE
7164#define po_barrier_or_imm(str) \
7165 do \
7166 { \
7167 val = parse_barrier (&str); \
ccb84d65
JB
7168 if (val == FAIL && ! ISALPHA (*str)) \
7169 goto immediate; \
7170 if (val == FAIL \
7171 /* ISB can only take SY as an option. */ \
7172 || ((inst.instruction & 0xf0) == 0x60 \
7173 && val != 0xf)) \
52e7f43d 7174 { \
ccb84d65
JB
7175 inst.error = _("invalid barrier type"); \
7176 backtrack_pos = 0; \
7177 goto failure; \
52e7f43d
RE
7178 } \
7179 } \
7180 while (0)
7181
c19d1205
ZW
7182 skip_whitespace (str);
7183
7184 for (i = 0; upat[i] != OP_stop; i++)
7185 {
5be8be5d
DG
7186 op_parse_code = upat[i];
7187 if (op_parse_code >= 1<<16)
7188 op_parse_code = thumb ? (op_parse_code >> 16)
7189 : (op_parse_code & ((1<<16)-1));
7190
7191 if (op_parse_code >= OP_FIRST_OPTIONAL)
c19d1205
ZW
7192 {
7193 /* Remember where we are in case we need to backtrack. */
c19d1205
ZW
7194 backtrack_pos = str;
7195 backtrack_error = inst.error;
7196 backtrack_index = i;
7197 }
7198
b6702015 7199 if (i > 0 && (i > 1 || inst.operands[0].present))
c19d1205
ZW
7200 po_char_or_fail (',');
7201
5be8be5d 7202 switch (op_parse_code)
c19d1205
ZW
7203 {
7204 /* Registers */
7205 case OP_oRRnpc:
5be8be5d 7206 case OP_oRRnpcsp:
c19d1205 7207 case OP_RRnpc:
5be8be5d 7208 case OP_RRnpcsp:
c19d1205 7209 case OP_oRR:
a302e574
AV
7210 case OP_RRe:
7211 case OP_RRo:
60f993ce
AV
7212 case OP_LR:
7213 case OP_oLR:
c19d1205
ZW
7214 case OP_RR: po_reg_or_fail (REG_TYPE_RN); break;
7215 case OP_RCP: po_reg_or_fail (REG_TYPE_CP); break;
7216 case OP_RCN: po_reg_or_fail (REG_TYPE_CN); break;
7217 case OP_RF: po_reg_or_fail (REG_TYPE_FN); break;
7218 case OP_RVS: po_reg_or_fail (REG_TYPE_VFS); break;
7219 case OP_RVD: po_reg_or_fail (REG_TYPE_VFD); break;
477330fc 7220 case OP_oRND:
5ee91343
AV
7221 case OP_RNDMQR:
7222 po_reg_or_goto (REG_TYPE_RN, try_rndmq);
7223 break;
7224 try_rndmq:
7225 case OP_RNDMQ:
7226 po_reg_or_goto (REG_TYPE_MQ, try_rnd);
7227 break;
7228 try_rnd:
5287ad62 7229 case OP_RND: po_reg_or_fail (REG_TYPE_VFD); break;
cd2cf30b
PB
7230 case OP_RVC:
7231 po_reg_or_goto (REG_TYPE_VFC, coproc_reg);
7232 break;
7233 /* Also accept generic coprocessor regs for unknown registers. */
7234 coproc_reg:
7235 po_reg_or_fail (REG_TYPE_CN);
7236 break;
c19d1205
ZW
7237 case OP_RMF: po_reg_or_fail (REG_TYPE_MVF); break;
7238 case OP_RMD: po_reg_or_fail (REG_TYPE_MVD); break;
7239 case OP_RMFX: po_reg_or_fail (REG_TYPE_MVFX); break;
7240 case OP_RMDX: po_reg_or_fail (REG_TYPE_MVDX); break;
7241 case OP_RMAX: po_reg_or_fail (REG_TYPE_MVAX); break;
7242 case OP_RMDS: po_reg_or_fail (REG_TYPE_DSPSC); break;
7243 case OP_RIWR: po_reg_or_fail (REG_TYPE_MMXWR); break;
7244 case OP_RIWC: po_reg_or_fail (REG_TYPE_MMXWC); break;
7245 case OP_RIWG: po_reg_or_fail (REG_TYPE_MMXWCG); break;
7246 case OP_RXA: po_reg_or_fail (REG_TYPE_XSCALE); break;
477330fc 7247 case OP_oRNQ:
5ee91343
AV
7248 case OP_RNQMQ:
7249 po_reg_or_goto (REG_TYPE_MQ, try_nq);
7250 break;
7251 try_nq:
5287ad62 7252 case OP_RNQ: po_reg_or_fail (REG_TYPE_NQ); break;
dec41383 7253 case OP_RNSD: po_reg_or_fail (REG_TYPE_NSD); break;
7df54120
AV
7254 case OP_RNDQMQR:
7255 po_reg_or_goto (REG_TYPE_RN, try_rndqmq);
7256 break;
7257 try_rndqmq:
5ee91343
AV
7258 case OP_oRNDQMQ:
7259 case OP_RNDQMQ:
7260 po_reg_or_goto (REG_TYPE_MQ, try_rndq);
7261 break;
7262 try_rndq:
477330fc 7263 case OP_oRNDQ:
5287ad62 7264 case OP_RNDQ: po_reg_or_fail (REG_TYPE_NDQ); break;
dd9634d9
AV
7265 case OP_RVSDMQ:
7266 po_reg_or_goto (REG_TYPE_MQ, try_rvsd);
7267 break;
7268 try_rvsd:
477330fc 7269 case OP_RVSD: po_reg_or_fail (REG_TYPE_VFSD); break;
1b883319
AV
7270 case OP_RVSD_COND:
7271 po_reg_or_goto (REG_TYPE_VFSD, try_cond);
7272 break;
477330fc
RM
7273 case OP_oRNSDQ:
7274 case OP_RNSDQ: po_reg_or_fail (REG_TYPE_NSDQ); break;
5ee91343
AV
7275 case OP_RNSDQMQR:
7276 po_reg_or_goto (REG_TYPE_RN, try_mq);
7277 break;
7278 try_mq:
7279 case OP_oRNSDQMQ:
7280 case OP_RNSDQMQ:
7281 po_reg_or_goto (REG_TYPE_MQ, try_nsdq2);
7282 break;
7283 try_nsdq2:
7284 po_reg_or_fail (REG_TYPE_NSDQ);
7285 inst.error = 0;
7286 break;
35d1cfc2
AV
7287 case OP_RMQRR:
7288 po_reg_or_goto (REG_TYPE_RN, try_rmq);
7289 break;
7290 try_rmq:
a302e574
AV
7291 case OP_RMQ:
7292 po_reg_or_fail (REG_TYPE_MQ);
7293 break;
477330fc
RM
7294 /* Neon scalar. Using an element size of 8 means that some invalid
7295 scalars are accepted here, so deal with those in later code. */
57785aa2 7296 case OP_RNSC: po_scalar_or_goto (8, failure, REG_TYPE_VFD); break;
477330fc
RM
7297
7298 case OP_RNDQ_I0:
7299 {
7300 po_reg_or_goto (REG_TYPE_NDQ, try_imm0);
7301 break;
7302 try_imm0:
7303 po_imm_or_fail (0, 0, TRUE);
7304 }
7305 break;
7306
7307 case OP_RVSD_I0:
7308 po_reg_or_goto (REG_TYPE_VFSD, try_imm0);
7309 break;
7310
1b883319
AV
7311 case OP_RSVDMQ_FI0:
7312 po_reg_or_goto (REG_TYPE_MQ, try_rsvd_fi0);
7313 break;
7314 try_rsvd_fi0:
aacf0b33
KT
7315 case OP_RSVD_FI0:
7316 {
7317 po_reg_or_goto (REG_TYPE_VFSD, try_ifimm0);
7318 break;
7319 try_ifimm0:
7320 if (parse_ifimm_zero (&str))
7321 inst.operands[i].imm = 0;
7322 else
7323 {
7324 inst.error
7325 = _("only floating point zero is allowed as immediate value");
7326 goto failure;
7327 }
7328 }
7329 break;
7330
477330fc
RM
7331 case OP_RR_RNSC:
7332 {
57785aa2 7333 po_scalar_or_goto (8, try_rr, REG_TYPE_VFD);
477330fc
RM
7334 break;
7335 try_rr:
7336 po_reg_or_fail (REG_TYPE_RN);
7337 }
7338 break;
7339
a8465a06
AV
7340 case OP_RNSDQ_RNSC_MQ_RR:
7341 po_reg_or_goto (REG_TYPE_RN, try_rnsdq_rnsc_mq);
7342 break;
7343 try_rnsdq_rnsc_mq:
886e1c73
AV
7344 case OP_RNSDQ_RNSC_MQ:
7345 po_reg_or_goto (REG_TYPE_MQ, try_rnsdq_rnsc);
7346 break;
7347 try_rnsdq_rnsc:
477330fc
RM
7348 case OP_RNSDQ_RNSC:
7349 {
57785aa2
AV
7350 po_scalar_or_goto (8, try_nsdq, REG_TYPE_VFD);
7351 inst.error = 0;
477330fc
RM
7352 break;
7353 try_nsdq:
7354 po_reg_or_fail (REG_TYPE_NSDQ);
57785aa2 7355 inst.error = 0;
477330fc
RM
7356 }
7357 break;
7358
dec41383
JW
7359 case OP_RNSD_RNSC:
7360 {
57785aa2 7361 po_scalar_or_goto (8, try_s_scalar, REG_TYPE_VFD);
dec41383
JW
7362 break;
7363 try_s_scalar:
57785aa2 7364 po_scalar_or_goto (4, try_nsd, REG_TYPE_VFS);
dec41383
JW
7365 break;
7366 try_nsd:
7367 po_reg_or_fail (REG_TYPE_NSD);
7368 }
7369 break;
7370
42b16635
AV
7371 case OP_RNDQMQ_RNSC_RR:
7372 po_reg_or_goto (REG_TYPE_MQ, try_rndq_rnsc_rr);
7373 break;
7374 try_rndq_rnsc_rr:
7375 case OP_RNDQ_RNSC_RR:
7376 po_reg_or_goto (REG_TYPE_RN, try_rndq_rnsc);
7377 break;
5d281bf0
AV
7378 case OP_RNDQMQ_RNSC:
7379 po_reg_or_goto (REG_TYPE_MQ, try_rndq_rnsc);
7380 break;
7381 try_rndq_rnsc:
477330fc
RM
7382 case OP_RNDQ_RNSC:
7383 {
57785aa2 7384 po_scalar_or_goto (8, try_ndq, REG_TYPE_VFD);
477330fc
RM
7385 break;
7386 try_ndq:
7387 po_reg_or_fail (REG_TYPE_NDQ);
7388 }
7389 break;
7390
7391 case OP_RND_RNSC:
7392 {
57785aa2 7393 po_scalar_or_goto (8, try_vfd, REG_TYPE_VFD);
477330fc
RM
7394 break;
7395 try_vfd:
7396 po_reg_or_fail (REG_TYPE_VFD);
7397 }
7398 break;
7399
7400 case OP_VMOV:
7401 /* WARNING: parse_neon_mov can move the operand counter, i. If we're
7402 not careful then bad things might happen. */
7403 po_misc_or_fail (parse_neon_mov (&str, &i) == FAIL);
7404 break;
7405
f601a00c
AV
7406 case OP_RNDQMQ_Ibig:
7407 po_reg_or_goto (REG_TYPE_MQ, try_rndq_ibig);
7408 break;
7409 try_rndq_ibig:
477330fc
RM
7410 case OP_RNDQ_Ibig:
7411 {
7412 po_reg_or_goto (REG_TYPE_NDQ, try_immbig);
7413 break;
7414 try_immbig:
7415 /* There's a possibility of getting a 64-bit immediate here, so
7416 we need special handling. */
8335d6aa
JW
7417 if (parse_big_immediate (&str, i, NULL, /*allow_symbol_p=*/FALSE)
7418 == FAIL)
477330fc
RM
7419 {
7420 inst.error = _("immediate value is out of range");
7421 goto failure;
7422 }
7423 }
7424 break;
7425
5150f0d8
AV
7426 case OP_RNDQMQ_I63b_RR:
7427 po_reg_or_goto (REG_TYPE_MQ, try_rndq_i63b_rr);
7428 break;
7429 try_rndq_i63b_rr:
7430 po_reg_or_goto (REG_TYPE_RN, try_rndq_i63b);
7431 break;
7432 try_rndq_i63b:
477330fc
RM
7433 case OP_RNDQ_I63b:
7434 {
7435 po_reg_or_goto (REG_TYPE_NDQ, try_shimm);
7436 break;
7437 try_shimm:
7438 po_imm_or_fail (0, 63, TRUE);
7439 }
7440 break;
c19d1205
ZW
7441
7442 case OP_RRnpcb:
7443 po_char_or_fail ('[');
7444 po_reg_or_fail (REG_TYPE_RN);
7445 po_char_or_fail (']');
7446 break;
a737bd4d 7447
55881a11 7448 case OP_RRnpctw:
c19d1205 7449 case OP_RRw:
b6702015 7450 case OP_oRRw:
c19d1205
ZW
7451 po_reg_or_fail (REG_TYPE_RN);
7452 if (skip_past_char (&str, '!') == SUCCESS)
7453 inst.operands[i].writeback = 1;
7454 break;
7455
7456 /* Immediates */
7457 case OP_I7: po_imm_or_fail ( 0, 7, FALSE); break;
7458 case OP_I15: po_imm_or_fail ( 0, 15, FALSE); break;
7459 case OP_I16: po_imm_or_fail ( 1, 16, FALSE); break;
477330fc 7460 case OP_I16z: po_imm_or_fail ( 0, 16, FALSE); break;
c19d1205
ZW
7461 case OP_I31: po_imm_or_fail ( 0, 31, FALSE); break;
7462 case OP_I32: po_imm_or_fail ( 1, 32, FALSE); break;
477330fc 7463 case OP_I32z: po_imm_or_fail ( 0, 32, FALSE); break;
c19d1205 7464 case OP_I63s: po_imm_or_fail (-64, 63, FALSE); break;
477330fc
RM
7465 case OP_I63: po_imm_or_fail ( 0, 63, FALSE); break;
7466 case OP_I64: po_imm_or_fail ( 1, 64, FALSE); break;
7467 case OP_I64z: po_imm_or_fail ( 0, 64, FALSE); break;
c19d1205 7468 case OP_I255: po_imm_or_fail ( 0, 255, FALSE); break;
c19d1205
ZW
7469
7470 case OP_I4b: po_imm_or_fail ( 1, 4, TRUE); break;
7471 case OP_oI7b:
7472 case OP_I7b: po_imm_or_fail ( 0, 7, TRUE); break;
7473 case OP_I15b: po_imm_or_fail ( 0, 15, TRUE); break;
7474 case OP_oI31b:
7475 case OP_I31b: po_imm_or_fail ( 0, 31, TRUE); break;
477330fc
RM
7476 case OP_oI32b: po_imm_or_fail ( 1, 32, TRUE); break;
7477 case OP_oI32z: po_imm_or_fail ( 0, 32, TRUE); break;
c19d1205
ZW
7478 case OP_oIffffb: po_imm_or_fail ( 0, 0xffff, TRUE); break;
7479
7480 /* Immediate variants */
7481 case OP_oI255c:
7482 po_char_or_fail ('{');
7483 po_imm_or_fail (0, 255, TRUE);
7484 po_char_or_fail ('}');
7485 break;
7486
7487 case OP_I31w:
7488 /* The expression parser chokes on a trailing !, so we have
7489 to find it first and zap it. */
7490 {
7491 char *s = str;
7492 while (*s && *s != ',')
7493 s++;
7494 if (s[-1] == '!')
7495 {
7496 s[-1] = '\0';
7497 inst.operands[i].writeback = 1;
7498 }
7499 po_imm_or_fail (0, 31, TRUE);
7500 if (str == s - 1)
7501 str = s;
7502 }
7503 break;
7504
7505 /* Expressions */
7506 case OP_EXPi: EXPi:
e2b0ab59 7507 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7508 GE_OPT_PREFIX));
7509 break;
7510
7511 case OP_EXP:
e2b0ab59 7512 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7513 GE_NO_PREFIX));
7514 break;
7515
7516 case OP_EXPr: EXPr:
e2b0ab59 7517 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205 7518 GE_NO_PREFIX));
e2b0ab59 7519 if (inst.relocs[0].exp.X_op == O_symbol)
a737bd4d 7520 {
c19d1205
ZW
7521 val = parse_reloc (&str);
7522 if (val == -1)
7523 {
7524 inst.error = _("unrecognized relocation suffix");
7525 goto failure;
7526 }
7527 else if (val != BFD_RELOC_UNUSED)
7528 {
7529 inst.operands[i].imm = val;
7530 inst.operands[i].hasreloc = 1;
7531 }
a737bd4d 7532 }
c19d1205 7533 break;
a737bd4d 7534
e2b0ab59
AV
7535 case OP_EXPs:
7536 po_misc_or_fail (my_get_expression (&inst.relocs[i].exp, &str,
7537 GE_NO_PREFIX));
7538 if (inst.relocs[i].exp.X_op == O_symbol)
7539 {
7540 inst.operands[i].hasreloc = 1;
7541 }
7542 else if (inst.relocs[i].exp.X_op == O_constant)
7543 {
7544 inst.operands[i].imm = inst.relocs[i].exp.X_add_number;
7545 inst.operands[i].hasreloc = 0;
7546 }
7547 break;
7548
b6895b4f
PB
7549 /* Operand for MOVW or MOVT. */
7550 case OP_HALF:
7551 po_misc_or_fail (parse_half (&str));
7552 break;
7553
e07e6e58 7554 /* Register or expression. */
c19d1205
ZW
7555 case OP_RR_EXr: po_reg_or_goto (REG_TYPE_RN, EXPr); break;
7556 case OP_RR_EXi: po_reg_or_goto (REG_TYPE_RN, EXPi); break;
a737bd4d 7557
e07e6e58 7558 /* Register or immediate. */
c19d1205
ZW
7559 case OP_RRnpc_I0: po_reg_or_goto (REG_TYPE_RN, I0); break;
7560 I0: po_imm_or_fail (0, 0, FALSE); break;
a737bd4d 7561
c19d1205
ZW
7562 case OP_RF_IF: po_reg_or_goto (REG_TYPE_FN, IF); break;
7563 IF:
7564 if (!is_immediate_prefix (*str))
7565 goto bad_args;
7566 str++;
7567 val = parse_fpa_immediate (&str);
7568 if (val == FAIL)
7569 goto failure;
7570 /* FPA immediates are encoded as registers 8-15.
7571 parse_fpa_immediate has already applied the offset. */
7572 inst.operands[i].reg = val;
7573 inst.operands[i].isreg = 1;
7574 break;
09d92015 7575
2d447fca
JM
7576 case OP_RIWR_I32z: po_reg_or_goto (REG_TYPE_MMXWR, I32z); break;
7577 I32z: po_imm_or_fail (0, 32, FALSE); break;
7578
e07e6e58 7579 /* Two kinds of register. */
c19d1205
ZW
7580 case OP_RIWR_RIWC:
7581 {
7582 struct reg_entry *rege = arm_reg_parse_multi (&str);
97f87066
JM
7583 if (!rege
7584 || (rege->type != REG_TYPE_MMXWR
7585 && rege->type != REG_TYPE_MMXWC
7586 && rege->type != REG_TYPE_MMXWCG))
c19d1205
ZW
7587 {
7588 inst.error = _("iWMMXt data or control register expected");
7589 goto failure;
7590 }
7591 inst.operands[i].reg = rege->number;
7592 inst.operands[i].isreg = (rege->type == REG_TYPE_MMXWR);
7593 }
7594 break;
09d92015 7595
41adaa5c
JM
7596 case OP_RIWC_RIWG:
7597 {
7598 struct reg_entry *rege = arm_reg_parse_multi (&str);
7599 if (!rege
7600 || (rege->type != REG_TYPE_MMXWC
7601 && rege->type != REG_TYPE_MMXWCG))
7602 {
7603 inst.error = _("iWMMXt control register expected");
7604 goto failure;
7605 }
7606 inst.operands[i].reg = rege->number;
7607 inst.operands[i].isreg = 1;
7608 }
7609 break;
7610
c19d1205
ZW
7611 /* Misc */
7612 case OP_CPSF: val = parse_cps_flags (&str); break;
7613 case OP_ENDI: val = parse_endian_specifier (&str); break;
7614 case OP_oROR: val = parse_ror (&str); break;
1b883319 7615 try_cond:
c19d1205 7616 case OP_COND: val = parse_cond (&str); break;
52e7f43d
RE
7617 case OP_oBARRIER_I15:
7618 po_barrier_or_imm (str); break;
7619 immediate:
7620 if (parse_immediate (&str, &val, 0, 15, TRUE) == FAIL)
477330fc 7621 goto failure;
52e7f43d 7622 break;
c19d1205 7623
fa94de6b 7624 case OP_wPSR:
d2cd1205 7625 case OP_rPSR:
90ec0d68
MGD
7626 po_reg_or_goto (REG_TYPE_RNB, try_psr);
7627 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_virt))
7628 {
7629 inst.error = _("Banked registers are not available with this "
7630 "architecture.");
7631 goto failure;
7632 }
7633 break;
d2cd1205
JB
7634 try_psr:
7635 val = parse_psr (&str, op_parse_code == OP_wPSR);
7636 break;
037e8744 7637
32c36c3c
AV
7638 case OP_VLDR:
7639 po_reg_or_goto (REG_TYPE_VFSD, try_sysreg);
7640 break;
7641 try_sysreg:
7642 val = parse_sys_vldr_vstr (&str);
7643 break;
7644
477330fc
RM
7645 case OP_APSR_RR:
7646 po_reg_or_goto (REG_TYPE_RN, try_apsr);
7647 break;
7648 try_apsr:
7649 /* Parse "APSR_nvzc" operand (for FMSTAT-equivalent MRS
7650 instruction). */
7651 if (strncasecmp (str, "APSR_", 5) == 0)
7652 {
7653 unsigned found = 0;
7654 str += 5;
7655 while (found < 15)
7656 switch (*str++)
7657 {
7658 case 'c': found = (found & 1) ? 16 : found | 1; break;
7659 case 'n': found = (found & 2) ? 16 : found | 2; break;
7660 case 'z': found = (found & 4) ? 16 : found | 4; break;
7661 case 'v': found = (found & 8) ? 16 : found | 8; break;
7662 default: found = 16;
7663 }
7664 if (found != 15)
7665 goto failure;
7666 inst.operands[i].isvec = 1;
f7c21dc7
NC
7667 /* APSR_nzcv is encoded in instructions as if it were the REG_PC. */
7668 inst.operands[i].reg = REG_PC;
477330fc
RM
7669 }
7670 else
7671 goto failure;
7672 break;
037e8744 7673
92e90b6e
PB
7674 case OP_TB:
7675 po_misc_or_fail (parse_tb (&str));
7676 break;
7677
e07e6e58 7678 /* Register lists. */
c19d1205 7679 case OP_REGLST:
4b5a202f 7680 val = parse_reg_list (&str, REGLIST_RN);
c19d1205
ZW
7681 if (*str == '^')
7682 {
5e0d7f77 7683 inst.operands[i].writeback = 1;
c19d1205
ZW
7684 str++;
7685 }
7686 break;
09d92015 7687
4b5a202f
AV
7688 case OP_CLRMLST:
7689 val = parse_reg_list (&str, REGLIST_CLRM);
7690 break;
7691
c19d1205 7692 case OP_VRSLST:
efd6b359
AV
7693 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_S,
7694 &partial_match);
c19d1205 7695 break;
09d92015 7696
c19d1205 7697 case OP_VRDLST:
efd6b359
AV
7698 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_D,
7699 &partial_match);
c19d1205 7700 break;
a737bd4d 7701
477330fc
RM
7702 case OP_VRSDLST:
7703 /* Allow Q registers too. */
7704 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359 7705 REGLIST_NEON_D, &partial_match);
477330fc
RM
7706 if (val == FAIL)
7707 {
7708 inst.error = NULL;
7709 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359
AV
7710 REGLIST_VFP_S, &partial_match);
7711 inst.operands[i].issingle = 1;
7712 }
7713 break;
7714
7715 case OP_VRSDVLST:
7716 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
7717 REGLIST_VFP_D_VPR, &partial_match);
7718 if (val == FAIL && !partial_match)
7719 {
7720 inst.error = NULL;
7721 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
7722 REGLIST_VFP_S_VPR, &partial_match);
477330fc
RM
7723 inst.operands[i].issingle = 1;
7724 }
7725 break;
7726
7727 case OP_NRDLST:
7728 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359 7729 REGLIST_NEON_D, &partial_match);
477330fc 7730 break;
5287ad62 7731
35c228db
AV
7732 case OP_MSTRLST4:
7733 case OP_MSTRLST2:
7734 val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
7735 1, &inst.operands[i].vectype);
7736 if (val != (((op_parse_code == OP_MSTRLST2) ? 3 : 7) << 5 | 0xe))
7737 goto failure;
7738 break;
5287ad62 7739 case OP_NSTRLST:
477330fc 7740 val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
35c228db 7741 0, &inst.operands[i].vectype);
477330fc 7742 break;
5287ad62 7743
c19d1205 7744 /* Addressing modes */
35c228db
AV
7745 case OP_ADDRMVE:
7746 po_misc_or_fail (parse_address_group_reloc (&str, i, GROUP_MVE));
7747 break;
7748
c19d1205
ZW
7749 case OP_ADDR:
7750 po_misc_or_fail (parse_address (&str, i));
7751 break;
09d92015 7752
4962c51a
MS
7753 case OP_ADDRGLDR:
7754 po_misc_or_fail_no_backtrack (
477330fc 7755 parse_address_group_reloc (&str, i, GROUP_LDR));
4962c51a
MS
7756 break;
7757
7758 case OP_ADDRGLDRS:
7759 po_misc_or_fail_no_backtrack (
477330fc 7760 parse_address_group_reloc (&str, i, GROUP_LDRS));
4962c51a
MS
7761 break;
7762
7763 case OP_ADDRGLDC:
7764 po_misc_or_fail_no_backtrack (
477330fc 7765 parse_address_group_reloc (&str, i, GROUP_LDC));
4962c51a
MS
7766 break;
7767
c19d1205
ZW
7768 case OP_SH:
7769 po_misc_or_fail (parse_shifter_operand (&str, i));
7770 break;
09d92015 7771
4962c51a
MS
7772 case OP_SHG:
7773 po_misc_or_fail_no_backtrack (
477330fc 7774 parse_shifter_operand_group_reloc (&str, i));
4962c51a
MS
7775 break;
7776
c19d1205
ZW
7777 case OP_oSHll:
7778 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_IMMEDIATE));
7779 break;
09d92015 7780
c19d1205
ZW
7781 case OP_oSHar:
7782 po_misc_or_fail (parse_shift (&str, i, SHIFT_ASR_IMMEDIATE));
7783 break;
09d92015 7784
c19d1205
ZW
7785 case OP_oSHllar:
7786 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_OR_ASR_IMMEDIATE));
7787 break;
09d92015 7788
1b883319
AV
7789 case OP_RMQRZ:
7790 case OP_oRMQRZ:
7791 po_reg_or_goto (REG_TYPE_MQ, try_rr_zr);
7792 break;
7793 try_rr_zr:
7794 po_reg_or_goto (REG_TYPE_RN, ZR);
7795 break;
7796 ZR:
7797 po_reg_or_fail (REG_TYPE_ZR);
7798 break;
7799
c19d1205 7800 default:
5be8be5d 7801 as_fatal (_("unhandled operand code %d"), op_parse_code);
c19d1205 7802 }
09d92015 7803
c19d1205
ZW
7804 /* Various value-based sanity checks and shared operations. We
7805 do not signal immediate failures for the register constraints;
7806 this allows a syntax error to take precedence. */
5be8be5d 7807 switch (op_parse_code)
c19d1205
ZW
7808 {
7809 case OP_oRRnpc:
7810 case OP_RRnpc:
7811 case OP_RRnpcb:
7812 case OP_RRw:
b6702015 7813 case OP_oRRw:
c19d1205
ZW
7814 case OP_RRnpc_I0:
7815 if (inst.operands[i].isreg && inst.operands[i].reg == REG_PC)
7816 inst.error = BAD_PC;
7817 break;
09d92015 7818
5be8be5d
DG
7819 case OP_oRRnpcsp:
7820 case OP_RRnpcsp:
7821 if (inst.operands[i].isreg)
7822 {
7823 if (inst.operands[i].reg == REG_PC)
7824 inst.error = BAD_PC;
5c8ed6a4
JW
7825 else if (inst.operands[i].reg == REG_SP
7826 /* The restriction on Rd/Rt/Rt2 on Thumb mode has been
7827 relaxed since ARMv8-A. */
7828 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
7829 {
7830 gas_assert (thumb);
7831 inst.error = BAD_SP;
7832 }
5be8be5d
DG
7833 }
7834 break;
7835
55881a11 7836 case OP_RRnpctw:
fa94de6b
RM
7837 if (inst.operands[i].isreg
7838 && inst.operands[i].reg == REG_PC
55881a11
MGD
7839 && (inst.operands[i].writeback || thumb))
7840 inst.error = BAD_PC;
7841 break;
7842
1b883319 7843 case OP_RVSD_COND:
32c36c3c
AV
7844 case OP_VLDR:
7845 if (inst.operands[i].isreg)
7846 break;
7847 /* fall through. */
1b883319 7848
c19d1205
ZW
7849 case OP_CPSF:
7850 case OP_ENDI:
7851 case OP_oROR:
d2cd1205
JB
7852 case OP_wPSR:
7853 case OP_rPSR:
c19d1205 7854 case OP_COND:
52e7f43d 7855 case OP_oBARRIER_I15:
c19d1205 7856 case OP_REGLST:
4b5a202f 7857 case OP_CLRMLST:
c19d1205
ZW
7858 case OP_VRSLST:
7859 case OP_VRDLST:
477330fc 7860 case OP_VRSDLST:
efd6b359 7861 case OP_VRSDVLST:
477330fc
RM
7862 case OP_NRDLST:
7863 case OP_NSTRLST:
35c228db
AV
7864 case OP_MSTRLST2:
7865 case OP_MSTRLST4:
c19d1205
ZW
7866 if (val == FAIL)
7867 goto failure;
7868 inst.operands[i].imm = val;
7869 break;
a737bd4d 7870
60f993ce
AV
7871 case OP_LR:
7872 case OP_oLR:
7873 if (inst.operands[i].reg != REG_LR)
7874 inst.error = _("operand must be LR register");
7875 break;
7876
1b883319
AV
7877 case OP_RMQRZ:
7878 case OP_oRMQRZ:
7879 if (!inst.operands[i].iszr && inst.operands[i].reg == REG_PC)
7880 inst.error = BAD_PC;
7881 break;
7882
a302e574
AV
7883 case OP_RRe:
7884 if (inst.operands[i].isreg
7885 && (inst.operands[i].reg & 0x00000001) != 0)
7886 inst.error = BAD_ODD;
7887 break;
7888
7889 case OP_RRo:
7890 if (inst.operands[i].isreg)
7891 {
7892 if ((inst.operands[i].reg & 0x00000001) != 1)
7893 inst.error = BAD_EVEN;
7894 else if (inst.operands[i].reg == REG_SP)
7895 as_tsktsk (MVE_BAD_SP);
7896 else if (inst.operands[i].reg == REG_PC)
7897 inst.error = BAD_PC;
7898 }
7899 break;
7900
c19d1205
ZW
7901 default:
7902 break;
7903 }
09d92015 7904
c19d1205
ZW
7905 /* If we get here, this operand was successfully parsed. */
7906 inst.operands[i].present = 1;
7907 continue;
09d92015 7908
c19d1205 7909 bad_args:
09d92015 7910 inst.error = BAD_ARGS;
c19d1205
ZW
7911
7912 failure:
7913 if (!backtrack_pos)
d252fdde
PB
7914 {
7915 /* The parse routine should already have set inst.error, but set a
5f4273c7 7916 default here just in case. */
d252fdde 7917 if (!inst.error)
5ee91343 7918 inst.error = BAD_SYNTAX;
d252fdde
PB
7919 return FAIL;
7920 }
c19d1205
ZW
7921
7922 /* Do not backtrack over a trailing optional argument that
7923 absorbed some text. We will only fail again, with the
7924 'garbage following instruction' error message, which is
7925 probably less helpful than the current one. */
7926 if (backtrack_index == i && backtrack_pos != str
7927 && upat[i+1] == OP_stop)
d252fdde
PB
7928 {
7929 if (!inst.error)
5ee91343 7930 inst.error = BAD_SYNTAX;
d252fdde
PB
7931 return FAIL;
7932 }
c19d1205
ZW
7933
7934 /* Try again, skipping the optional argument at backtrack_pos. */
7935 str = backtrack_pos;
7936 inst.error = backtrack_error;
7937 inst.operands[backtrack_index].present = 0;
7938 i = backtrack_index;
7939 backtrack_pos = 0;
09d92015 7940 }
09d92015 7941
c19d1205
ZW
7942 /* Check that we have parsed all the arguments. */
7943 if (*str != '\0' && !inst.error)
7944 inst.error = _("garbage following instruction");
09d92015 7945
c19d1205 7946 return inst.error ? FAIL : SUCCESS;
09d92015
MM
7947}
7948
c19d1205
ZW
7949#undef po_char_or_fail
7950#undef po_reg_or_fail
7951#undef po_reg_or_goto
7952#undef po_imm_or_fail
5287ad62 7953#undef po_scalar_or_fail
52e7f43d 7954#undef po_barrier_or_imm
e07e6e58 7955
c19d1205 7956/* Shorthand macro for instruction encoding functions issuing errors. */
e07e6e58
NC
7957#define constraint(expr, err) \
7958 do \
c19d1205 7959 { \
e07e6e58
NC
7960 if (expr) \
7961 { \
7962 inst.error = err; \
7963 return; \
7964 } \
c19d1205 7965 } \
e07e6e58 7966 while (0)
c19d1205 7967
fdfde340
JM
7968/* Reject "bad registers" for Thumb-2 instructions. Many Thumb-2
7969 instructions are unpredictable if these registers are used. This
5c8ed6a4
JW
7970 is the BadReg predicate in ARM's Thumb-2 documentation.
7971
7972 Before ARMv8-A, REG_PC and REG_SP were not allowed in quite a few
7973 places, while the restriction on REG_SP was relaxed since ARMv8-A. */
7974#define reject_bad_reg(reg) \
7975 do \
7976 if (reg == REG_PC) \
7977 { \
7978 inst.error = BAD_PC; \
7979 return; \
7980 } \
7981 else if (reg == REG_SP \
7982 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)) \
7983 { \
7984 inst.error = BAD_SP; \
7985 return; \
7986 } \
fdfde340
JM
7987 while (0)
7988
94206790
MM
7989/* If REG is R13 (the stack pointer), warn that its use is
7990 deprecated. */
7991#define warn_deprecated_sp(reg) \
7992 do \
7993 if (warn_on_deprecated && reg == REG_SP) \
5c3696f8 7994 as_tsktsk (_("use of r13 is deprecated")); \
94206790
MM
7995 while (0)
7996
c19d1205
ZW
7997/* Functions for operand encoding. ARM, then Thumb. */
7998
d840c081 7999#define rotate_left(v, n) (v << (n & 31) | v >> ((32 - n) & 31))
c19d1205 8000
9db2f6b4
RL
8001/* If the current inst is scalar ARMv8.2 fp16 instruction, do special encoding.
8002
8003 The only binary encoding difference is the Coprocessor number. Coprocessor
8004 9 is used for half-precision calculations or conversions. The format of the
2b0f3761 8005 instruction is the same as the equivalent Coprocessor 10 instruction that
9db2f6b4
RL
8006 exists for Single-Precision operation. */
8007
8008static void
8009do_scalar_fp16_v82_encode (void)
8010{
5ee91343 8011 if (inst.cond < COND_ALWAYS)
9db2f6b4
RL
8012 as_warn (_("ARMv8.2 scalar fp16 instruction cannot be conditional,"
8013 " the behaviour is UNPREDICTABLE"));
8014 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
8015 _(BAD_FP16));
8016
8017 inst.instruction = (inst.instruction & 0xfffff0ff) | 0x900;
8018 mark_feature_used (&arm_ext_fp16);
8019}
8020
c19d1205
ZW
8021/* If VAL can be encoded in the immediate field of an ARM instruction,
8022 return the encoded form. Otherwise, return FAIL. */
8023
8024static unsigned int
8025encode_arm_immediate (unsigned int val)
09d92015 8026{
c19d1205
ZW
8027 unsigned int a, i;
8028
4f1d6205
L
8029 if (val <= 0xff)
8030 return val;
8031
8032 for (i = 2; i < 32; i += 2)
c19d1205
ZW
8033 if ((a = rotate_left (val, i)) <= 0xff)
8034 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
8035
8036 return FAIL;
09d92015
MM
8037}
8038
c19d1205
ZW
8039/* If VAL can be encoded in the immediate field of a Thumb32 instruction,
8040 return the encoded form. Otherwise, return FAIL. */
8041static unsigned int
8042encode_thumb32_immediate (unsigned int val)
09d92015 8043{
c19d1205 8044 unsigned int a, i;
09d92015 8045
9c3c69f2 8046 if (val <= 0xff)
c19d1205 8047 return val;
a737bd4d 8048
9c3c69f2 8049 for (i = 1; i <= 24; i++)
09d92015 8050 {
9c3c69f2
PB
8051 a = val >> i;
8052 if ((val & ~(0xff << i)) == 0)
8053 return ((val >> i) & 0x7f) | ((32 - i) << 7);
09d92015 8054 }
a737bd4d 8055
c19d1205
ZW
8056 a = val & 0xff;
8057 if (val == ((a << 16) | a))
8058 return 0x100 | a;
8059 if (val == ((a << 24) | (a << 16) | (a << 8) | a))
8060 return 0x300 | a;
09d92015 8061
c19d1205
ZW
8062 a = val & 0xff00;
8063 if (val == ((a << 16) | a))
8064 return 0x200 | (a >> 8);
a737bd4d 8065
c19d1205 8066 return FAIL;
09d92015 8067}
5287ad62 8068/* Encode a VFP SP or DP register number into inst.instruction. */
09d92015
MM
8069
8070static void
5287ad62
JB
8071encode_arm_vfp_reg (int reg, enum vfp_reg_pos pos)
8072{
8073 if ((pos == VFP_REG_Dd || pos == VFP_REG_Dn || pos == VFP_REG_Dm)
8074 && reg > 15)
8075 {
b1cc4aeb 8076 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
477330fc
RM
8077 {
8078 if (thumb_mode)
8079 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
8080 fpu_vfp_ext_d32);
8081 else
8082 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
8083 fpu_vfp_ext_d32);
8084 }
5287ad62 8085 else
477330fc
RM
8086 {
8087 first_error (_("D register out of range for selected VFP version"));
8088 return;
8089 }
5287ad62
JB
8090 }
8091
c19d1205 8092 switch (pos)
09d92015 8093 {
c19d1205
ZW
8094 case VFP_REG_Sd:
8095 inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
8096 break;
8097
8098 case VFP_REG_Sn:
8099 inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
8100 break;
8101
8102 case VFP_REG_Sm:
8103 inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
8104 break;
8105
5287ad62
JB
8106 case VFP_REG_Dd:
8107 inst.instruction |= ((reg & 15) << 12) | ((reg >> 4) << 22);
8108 break;
5f4273c7 8109
5287ad62
JB
8110 case VFP_REG_Dn:
8111 inst.instruction |= ((reg & 15) << 16) | ((reg >> 4) << 7);
8112 break;
5f4273c7 8113
5287ad62
JB
8114 case VFP_REG_Dm:
8115 inst.instruction |= (reg & 15) | ((reg >> 4) << 5);
8116 break;
8117
c19d1205
ZW
8118 default:
8119 abort ();
09d92015 8120 }
09d92015
MM
8121}
8122
c19d1205 8123/* Encode a <shift> in an ARM-format instruction. The immediate,
55cf6793 8124 if any, is handled by md_apply_fix. */
09d92015 8125static void
c19d1205 8126encode_arm_shift (int i)
09d92015 8127{
008a97ef
RL
8128 /* register-shifted register. */
8129 if (inst.operands[i].immisreg)
8130 {
bf355b69
MR
8131 int op_index;
8132 for (op_index = 0; op_index <= i; ++op_index)
008a97ef 8133 {
5689c942
RL
8134 /* Check the operand only when it's presented. In pre-UAL syntax,
8135 if the destination register is the same as the first operand, two
8136 register form of the instruction can be used. */
bf355b69
MR
8137 if (inst.operands[op_index].present && inst.operands[op_index].isreg
8138 && inst.operands[op_index].reg == REG_PC)
008a97ef
RL
8139 as_warn (UNPRED_REG ("r15"));
8140 }
8141
8142 if (inst.operands[i].imm == REG_PC)
8143 as_warn (UNPRED_REG ("r15"));
8144 }
8145
c19d1205
ZW
8146 if (inst.operands[i].shift_kind == SHIFT_RRX)
8147 inst.instruction |= SHIFT_ROR << 5;
8148 else
09d92015 8149 {
c19d1205
ZW
8150 inst.instruction |= inst.operands[i].shift_kind << 5;
8151 if (inst.operands[i].immisreg)
8152 {
8153 inst.instruction |= SHIFT_BY_REG;
8154 inst.instruction |= inst.operands[i].imm << 8;
8155 }
8156 else
e2b0ab59 8157 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
09d92015 8158 }
c19d1205 8159}
09d92015 8160
c19d1205
ZW
8161static void
8162encode_arm_shifter_operand (int i)
8163{
8164 if (inst.operands[i].isreg)
09d92015 8165 {
c19d1205
ZW
8166 inst.instruction |= inst.operands[i].reg;
8167 encode_arm_shift (i);
09d92015 8168 }
c19d1205 8169 else
a415b1cd
JB
8170 {
8171 inst.instruction |= INST_IMMEDIATE;
e2b0ab59 8172 if (inst.relocs[0].type != BFD_RELOC_ARM_IMMEDIATE)
a415b1cd
JB
8173 inst.instruction |= inst.operands[i].imm;
8174 }
09d92015
MM
8175}
8176
c19d1205 8177/* Subroutine of encode_arm_addr_mode_2 and encode_arm_addr_mode_3. */
09d92015 8178static void
c19d1205 8179encode_arm_addr_mode_common (int i, bfd_boolean is_t)
09d92015 8180{
2b2f5df9
NC
8181 /* PR 14260:
8182 Generate an error if the operand is not a register. */
8183 constraint (!inst.operands[i].isreg,
8184 _("Instruction does not support =N addresses"));
8185
c19d1205 8186 inst.instruction |= inst.operands[i].reg << 16;
a737bd4d 8187
c19d1205 8188 if (inst.operands[i].preind)
09d92015 8189 {
c19d1205
ZW
8190 if (is_t)
8191 {
8192 inst.error = _("instruction does not accept preindexed addressing");
8193 return;
8194 }
8195 inst.instruction |= PRE_INDEX;
8196 if (inst.operands[i].writeback)
8197 inst.instruction |= WRITE_BACK;
09d92015 8198
c19d1205
ZW
8199 }
8200 else if (inst.operands[i].postind)
8201 {
9c2799c2 8202 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
8203 if (is_t)
8204 inst.instruction |= WRITE_BACK;
8205 }
8206 else /* unindexed - only for coprocessor */
09d92015 8207 {
c19d1205 8208 inst.error = _("instruction does not accept unindexed addressing");
09d92015
MM
8209 return;
8210 }
8211
c19d1205
ZW
8212 if (((inst.instruction & WRITE_BACK) || !(inst.instruction & PRE_INDEX))
8213 && (((inst.instruction & 0x000f0000) >> 16)
8214 == ((inst.instruction & 0x0000f000) >> 12)))
8215 as_warn ((inst.instruction & LOAD_BIT)
8216 ? _("destination register same as write-back base")
8217 : _("source register same as write-back base"));
09d92015
MM
8218}
8219
c19d1205
ZW
8220/* inst.operands[i] was set up by parse_address. Encode it into an
8221 ARM-format mode 2 load or store instruction. If is_t is true,
8222 reject forms that cannot be used with a T instruction (i.e. not
8223 post-indexed). */
a737bd4d 8224static void
c19d1205 8225encode_arm_addr_mode_2 (int i, bfd_boolean is_t)
09d92015 8226{
5be8be5d
DG
8227 const bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
8228
c19d1205 8229 encode_arm_addr_mode_common (i, is_t);
a737bd4d 8230
c19d1205 8231 if (inst.operands[i].immisreg)
09d92015 8232 {
5be8be5d
DG
8233 constraint ((inst.operands[i].imm == REG_PC
8234 || (is_pc && inst.operands[i].writeback)),
8235 BAD_PC_ADDRESSING);
c19d1205
ZW
8236 inst.instruction |= INST_IMMEDIATE; /* yes, this is backwards */
8237 inst.instruction |= inst.operands[i].imm;
8238 if (!inst.operands[i].negative)
8239 inst.instruction |= INDEX_UP;
8240 if (inst.operands[i].shifted)
8241 {
8242 if (inst.operands[i].shift_kind == SHIFT_RRX)
8243 inst.instruction |= SHIFT_ROR << 5;
8244 else
8245 {
8246 inst.instruction |= inst.operands[i].shift_kind << 5;
e2b0ab59 8247 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
c19d1205
ZW
8248 }
8249 }
09d92015 8250 }
e2b0ab59 8251 else /* immediate offset in inst.relocs[0] */
09d92015 8252 {
e2b0ab59 8253 if (is_pc && !inst.relocs[0].pc_rel)
5be8be5d
DG
8254 {
8255 const bfd_boolean is_load = ((inst.instruction & LOAD_BIT) != 0);
23a10334
JZ
8256
8257 /* If is_t is TRUE, it's called from do_ldstt. ldrt/strt
8258 cannot use PC in addressing.
8259 PC cannot be used in writeback addressing, either. */
8260 constraint ((is_t || inst.operands[i].writeback),
5be8be5d 8261 BAD_PC_ADDRESSING);
23a10334 8262
dc5ec521 8263 /* Use of PC in str is deprecated for ARMv7. */
23a10334
JZ
8264 if (warn_on_deprecated
8265 && !is_load
8266 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7))
5c3696f8 8267 as_tsktsk (_("use of PC in this instruction is deprecated"));
5be8be5d
DG
8268 }
8269
e2b0ab59 8270 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
8271 {
8272 /* Prefer + for zero encoded value. */
8273 if (!inst.operands[i].negative)
8274 inst.instruction |= INDEX_UP;
e2b0ab59 8275 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM;
26d97720 8276 }
09d92015 8277 }
09d92015
MM
8278}
8279
c19d1205
ZW
8280/* inst.operands[i] was set up by parse_address. Encode it into an
8281 ARM-format mode 3 load or store instruction. Reject forms that
8282 cannot be used with such instructions. If is_t is true, reject
8283 forms that cannot be used with a T instruction (i.e. not
8284 post-indexed). */
8285static void
8286encode_arm_addr_mode_3 (int i, bfd_boolean is_t)
09d92015 8287{
c19d1205 8288 if (inst.operands[i].immisreg && inst.operands[i].shifted)
09d92015 8289 {
c19d1205
ZW
8290 inst.error = _("instruction does not accept scaled register index");
8291 return;
09d92015 8292 }
a737bd4d 8293
c19d1205 8294 encode_arm_addr_mode_common (i, is_t);
a737bd4d 8295
c19d1205
ZW
8296 if (inst.operands[i].immisreg)
8297 {
5be8be5d 8298 constraint ((inst.operands[i].imm == REG_PC
eb9f3f00 8299 || (is_t && inst.operands[i].reg == REG_PC)),
5be8be5d 8300 BAD_PC_ADDRESSING);
eb9f3f00
JB
8301 constraint (inst.operands[i].reg == REG_PC && inst.operands[i].writeback,
8302 BAD_PC_WRITEBACK);
c19d1205
ZW
8303 inst.instruction |= inst.operands[i].imm;
8304 if (!inst.operands[i].negative)
8305 inst.instruction |= INDEX_UP;
8306 }
e2b0ab59 8307 else /* immediate offset in inst.relocs[0] */
c19d1205 8308 {
e2b0ab59 8309 constraint ((inst.operands[i].reg == REG_PC && !inst.relocs[0].pc_rel
5be8be5d
DG
8310 && inst.operands[i].writeback),
8311 BAD_PC_WRITEBACK);
c19d1205 8312 inst.instruction |= HWOFFSET_IMM;
e2b0ab59 8313 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
8314 {
8315 /* Prefer + for zero encoded value. */
8316 if (!inst.operands[i].negative)
8317 inst.instruction |= INDEX_UP;
8318
e2b0ab59 8319 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM8;
26d97720 8320 }
c19d1205 8321 }
a737bd4d
NC
8322}
8323
8335d6aa
JW
8324/* Write immediate bits [7:0] to the following locations:
8325
8326 |28/24|23 19|18 16|15 4|3 0|
8327 | 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|
8328
8329 This function is used by VMOV/VMVN/VORR/VBIC. */
8330
8331static void
8332neon_write_immbits (unsigned immbits)
8333{
8334 inst.instruction |= immbits & 0xf;
8335 inst.instruction |= ((immbits >> 4) & 0x7) << 16;
8336 inst.instruction |= ((immbits >> 7) & 0x1) << (thumb_mode ? 28 : 24);
8337}
8338
8339/* Invert low-order SIZE bits of XHI:XLO. */
8340
8341static void
8342neon_invert_size (unsigned *xlo, unsigned *xhi, int size)
8343{
8344 unsigned immlo = xlo ? *xlo : 0;
8345 unsigned immhi = xhi ? *xhi : 0;
8346
8347 switch (size)
8348 {
8349 case 8:
8350 immlo = (~immlo) & 0xff;
8351 break;
8352
8353 case 16:
8354 immlo = (~immlo) & 0xffff;
8355 break;
8356
8357 case 64:
8358 immhi = (~immhi) & 0xffffffff;
8359 /* fall through. */
8360
8361 case 32:
8362 immlo = (~immlo) & 0xffffffff;
8363 break;
8364
8365 default:
8366 abort ();
8367 }
8368
8369 if (xlo)
8370 *xlo = immlo;
8371
8372 if (xhi)
8373 *xhi = immhi;
8374}
8375
8376/* True if IMM has form 0bAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD for bits
8377 A, B, C, D. */
09d92015 8378
c19d1205 8379static int
8335d6aa 8380neon_bits_same_in_bytes (unsigned imm)
09d92015 8381{
8335d6aa
JW
8382 return ((imm & 0x000000ff) == 0 || (imm & 0x000000ff) == 0x000000ff)
8383 && ((imm & 0x0000ff00) == 0 || (imm & 0x0000ff00) == 0x0000ff00)
8384 && ((imm & 0x00ff0000) == 0 || (imm & 0x00ff0000) == 0x00ff0000)
8385 && ((imm & 0xff000000) == 0 || (imm & 0xff000000) == 0xff000000);
8386}
a737bd4d 8387
8335d6aa 8388/* For immediate of above form, return 0bABCD. */
09d92015 8389
8335d6aa
JW
8390static unsigned
8391neon_squash_bits (unsigned imm)
8392{
8393 return (imm & 0x01) | ((imm & 0x0100) >> 7) | ((imm & 0x010000) >> 14)
8394 | ((imm & 0x01000000) >> 21);
8395}
8396
8397/* Compress quarter-float representation to 0b...000 abcdefgh. */
8398
8399static unsigned
8400neon_qfloat_bits (unsigned imm)
8401{
8402 return ((imm >> 19) & 0x7f) | ((imm >> 24) & 0x80);
8403}
8404
8405/* Returns CMODE. IMMBITS [7:0] is set to bits suitable for inserting into
8406 the instruction. *OP is passed as the initial value of the op field, and
8407 may be set to a different value depending on the constant (i.e.
8408 "MOV I64, 0bAAAAAAAABBBB..." which uses OP = 1 despite being MOV not
8409 MVN). If the immediate looks like a repeated pattern then also
8410 try smaller element sizes. */
8411
8412static int
8413neon_cmode_for_move_imm (unsigned immlo, unsigned immhi, int float_p,
8414 unsigned *immbits, int *op, int size,
8415 enum neon_el_type type)
8416{
8417 /* Only permit float immediates (including 0.0/-0.0) if the operand type is
8418 float. */
8419 if (type == NT_float && !float_p)
8420 return FAIL;
8421
8422 if (type == NT_float && is_quarter_float (immlo) && immhi == 0)
09d92015 8423 {
8335d6aa
JW
8424 if (size != 32 || *op == 1)
8425 return FAIL;
8426 *immbits = neon_qfloat_bits (immlo);
8427 return 0xf;
8428 }
8429
8430 if (size == 64)
8431 {
8432 if (neon_bits_same_in_bytes (immhi)
8433 && neon_bits_same_in_bytes (immlo))
c19d1205 8434 {
8335d6aa
JW
8435 if (*op == 1)
8436 return FAIL;
8437 *immbits = (neon_squash_bits (immhi) << 4)
8438 | neon_squash_bits (immlo);
8439 *op = 1;
8440 return 0xe;
c19d1205 8441 }
a737bd4d 8442
8335d6aa
JW
8443 if (immhi != immlo)
8444 return FAIL;
8445 }
a737bd4d 8446
8335d6aa 8447 if (size >= 32)
09d92015 8448 {
8335d6aa 8449 if (immlo == (immlo & 0x000000ff))
c19d1205 8450 {
8335d6aa
JW
8451 *immbits = immlo;
8452 return 0x0;
c19d1205 8453 }
8335d6aa 8454 else if (immlo == (immlo & 0x0000ff00))
c19d1205 8455 {
8335d6aa
JW
8456 *immbits = immlo >> 8;
8457 return 0x2;
c19d1205 8458 }
8335d6aa
JW
8459 else if (immlo == (immlo & 0x00ff0000))
8460 {
8461 *immbits = immlo >> 16;
8462 return 0x4;
8463 }
8464 else if (immlo == (immlo & 0xff000000))
8465 {
8466 *immbits = immlo >> 24;
8467 return 0x6;
8468 }
8469 else if (immlo == ((immlo & 0x0000ff00) | 0x000000ff))
8470 {
8471 *immbits = (immlo >> 8) & 0xff;
8472 return 0xc;
8473 }
8474 else if (immlo == ((immlo & 0x00ff0000) | 0x0000ffff))
8475 {
8476 *immbits = (immlo >> 16) & 0xff;
8477 return 0xd;
8478 }
8479
8480 if ((immlo & 0xffff) != (immlo >> 16))
8481 return FAIL;
8482 immlo &= 0xffff;
09d92015 8483 }
a737bd4d 8484
8335d6aa 8485 if (size >= 16)
4962c51a 8486 {
8335d6aa
JW
8487 if (immlo == (immlo & 0x000000ff))
8488 {
8489 *immbits = immlo;
8490 return 0x8;
8491 }
8492 else if (immlo == (immlo & 0x0000ff00))
8493 {
8494 *immbits = immlo >> 8;
8495 return 0xa;
8496 }
8497
8498 if ((immlo & 0xff) != (immlo >> 8))
8499 return FAIL;
8500 immlo &= 0xff;
4962c51a
MS
8501 }
8502
8335d6aa
JW
8503 if (immlo == (immlo & 0x000000ff))
8504 {
8505 /* Don't allow MVN with 8-bit immediate. */
8506 if (*op == 1)
8507 return FAIL;
8508 *immbits = immlo;
8509 return 0xe;
8510 }
26d97720 8511
8335d6aa 8512 return FAIL;
c19d1205 8513}
a737bd4d 8514
5fc177c8 8515#if defined BFD_HOST_64_BIT
ba592044
AM
8516/* Returns TRUE if double precision value V may be cast
8517 to single precision without loss of accuracy. */
8518
8519static bfd_boolean
5fc177c8 8520is_double_a_single (bfd_int64_t v)
ba592044 8521{
5fc177c8 8522 int exp = (int)((v >> 52) & 0x7FF);
8fe3f3d6 8523 bfd_int64_t mantissa = (v & (bfd_int64_t)0xFFFFFFFFFFFFFULL);
ba592044
AM
8524
8525 return (exp == 0 || exp == 0x7FF
8526 || (exp >= 1023 - 126 && exp <= 1023 + 127))
8527 && (mantissa & 0x1FFFFFFFl) == 0;
8528}
8529
3739860c 8530/* Returns a double precision value casted to single precision
ba592044
AM
8531 (ignoring the least significant bits in exponent and mantissa). */
8532
8533static int
5fc177c8 8534double_to_single (bfd_int64_t v)
ba592044
AM
8535{
8536 int sign = (int) ((v >> 63) & 1l);
5fc177c8 8537 int exp = (int) ((v >> 52) & 0x7FF);
8fe3f3d6 8538 bfd_int64_t mantissa = (v & (bfd_int64_t)0xFFFFFFFFFFFFFULL);
ba592044
AM
8539
8540 if (exp == 0x7FF)
8541 exp = 0xFF;
8542 else
8543 {
8544 exp = exp - 1023 + 127;
8545 if (exp >= 0xFF)
8546 {
8547 /* Infinity. */
8548 exp = 0x7F;
8549 mantissa = 0;
8550 }
8551 else if (exp < 0)
8552 {
8553 /* No denormalized numbers. */
8554 exp = 0;
8555 mantissa = 0;
8556 }
8557 }
8558 mantissa >>= 29;
8559 return (sign << 31) | (exp << 23) | mantissa;
8560}
5fc177c8 8561#endif /* BFD_HOST_64_BIT */
ba592044 8562
8335d6aa
JW
8563enum lit_type
8564{
8565 CONST_THUMB,
8566 CONST_ARM,
8567 CONST_VEC
8568};
8569
ba592044
AM
8570static void do_vfp_nsyn_opcode (const char *);
8571
e2b0ab59 8572/* inst.relocs[0].exp describes an "=expr" load pseudo-operation.
c19d1205
ZW
8573 Determine whether it can be performed with a move instruction; if
8574 it can, convert inst.instruction to that move instruction and
c921be7d
NC
8575 return TRUE; if it can't, convert inst.instruction to a literal-pool
8576 load and return FALSE. If this is not a valid thing to do in the
8577 current context, set inst.error and return TRUE.
a737bd4d 8578
c19d1205
ZW
8579 inst.operands[i] describes the destination register. */
8580
c921be7d 8581static bfd_boolean
8335d6aa 8582move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
c19d1205 8583{
53365c0d 8584 unsigned long tbit;
8335d6aa
JW
8585 bfd_boolean thumb_p = (t == CONST_THUMB);
8586 bfd_boolean arm_p = (t == CONST_ARM);
53365c0d
PB
8587
8588 if (thumb_p)
8589 tbit = (inst.instruction > 0xffff) ? THUMB2_LOAD_BIT : THUMB_LOAD_BIT;
8590 else
8591 tbit = LOAD_BIT;
8592
8593 if ((inst.instruction & tbit) == 0)
09d92015 8594 {
c19d1205 8595 inst.error = _("invalid pseudo operation");
c921be7d 8596 return TRUE;
09d92015 8597 }
ba592044 8598
e2b0ab59
AV
8599 if (inst.relocs[0].exp.X_op != O_constant
8600 && inst.relocs[0].exp.X_op != O_symbol
8601 && inst.relocs[0].exp.X_op != O_big)
09d92015
MM
8602 {
8603 inst.error = _("constant expression expected");
c921be7d 8604 return TRUE;
09d92015 8605 }
ba592044 8606
e2b0ab59
AV
8607 if (inst.relocs[0].exp.X_op == O_constant
8608 || inst.relocs[0].exp.X_op == O_big)
8335d6aa 8609 {
5fc177c8
NC
8610#if defined BFD_HOST_64_BIT
8611 bfd_int64_t v;
8612#else
ba592044 8613 offsetT v;
5fc177c8 8614#endif
e2b0ab59 8615 if (inst.relocs[0].exp.X_op == O_big)
8335d6aa 8616 {
ba592044
AM
8617 LITTLENUM_TYPE w[X_PRECISION];
8618 LITTLENUM_TYPE * l;
8619
e2b0ab59 8620 if (inst.relocs[0].exp.X_add_number == -1)
8335d6aa 8621 {
ba592044
AM
8622 gen_to_words (w, X_PRECISION, E_PRECISION);
8623 l = w;
8624 /* FIXME: Should we check words w[2..5] ? */
8335d6aa 8625 }
ba592044
AM
8626 else
8627 l = generic_bignum;
3739860c 8628
5fc177c8
NC
8629#if defined BFD_HOST_64_BIT
8630 v =
8631 ((((((((bfd_int64_t) l[3] & LITTLENUM_MASK)
8632 << LITTLENUM_NUMBER_OF_BITS)
8633 | ((bfd_int64_t) l[2] & LITTLENUM_MASK))
8634 << LITTLENUM_NUMBER_OF_BITS)
8635 | ((bfd_int64_t) l[1] & LITTLENUM_MASK))
8636 << LITTLENUM_NUMBER_OF_BITS)
8637 | ((bfd_int64_t) l[0] & LITTLENUM_MASK));
8638#else
ba592044
AM
8639 v = ((l[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
8640 | (l[0] & LITTLENUM_MASK);
5fc177c8 8641#endif
8335d6aa 8642 }
ba592044 8643 else
e2b0ab59 8644 v = inst.relocs[0].exp.X_add_number;
ba592044
AM
8645
8646 if (!inst.operands[i].issingle)
8335d6aa 8647 {
12569877 8648 if (thumb_p)
8335d6aa 8649 {
53445554
TP
8650 /* LDR should not use lead in a flag-setting instruction being
8651 chosen so we do not check whether movs can be used. */
12569877 8652
53445554 8653 if ((ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
ff8646ee 8654 || ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
53445554
TP
8655 && inst.operands[i].reg != 13
8656 && inst.operands[i].reg != 15)
12569877 8657 {
fc289b0a
TP
8658 /* Check if on thumb2 it can be done with a mov.w, mvn or
8659 movw instruction. */
12569877
AM
8660 unsigned int newimm;
8661 bfd_boolean isNegated;
8662
8663 newimm = encode_thumb32_immediate (v);
8664 if (newimm != (unsigned int) FAIL)
8665 isNegated = FALSE;
8666 else
8667 {
582cfe03 8668 newimm = encode_thumb32_immediate (~v);
12569877
AM
8669 if (newimm != (unsigned int) FAIL)
8670 isNegated = TRUE;
8671 }
8672
fc289b0a
TP
8673 /* The number can be loaded with a mov.w or mvn
8674 instruction. */
ff8646ee
TP
8675 if (newimm != (unsigned int) FAIL
8676 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
12569877 8677 {
fc289b0a 8678 inst.instruction = (0xf04f0000 /* MOV.W. */
582cfe03 8679 | (inst.operands[i].reg << 8));
fc289b0a 8680 /* Change to MOVN. */
582cfe03 8681 inst.instruction |= (isNegated ? 0x200000 : 0);
12569877
AM
8682 inst.instruction |= (newimm & 0x800) << 15;
8683 inst.instruction |= (newimm & 0x700) << 4;
8684 inst.instruction |= (newimm & 0x0ff);
8685 return TRUE;
8686 }
fc289b0a 8687 /* The number can be loaded with a movw instruction. */
ff8646ee
TP
8688 else if ((v & ~0xFFFF) == 0
8689 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
3739860c 8690 {
582cfe03 8691 int imm = v & 0xFFFF;
12569877 8692
582cfe03 8693 inst.instruction = 0xf2400000; /* MOVW. */
12569877
AM
8694 inst.instruction |= (inst.operands[i].reg << 8);
8695 inst.instruction |= (imm & 0xf000) << 4;
8696 inst.instruction |= (imm & 0x0800) << 15;
8697 inst.instruction |= (imm & 0x0700) << 4;
8698 inst.instruction |= (imm & 0x00ff);
8699 return TRUE;
8700 }
8701 }
8335d6aa 8702 }
12569877 8703 else if (arm_p)
ba592044
AM
8704 {
8705 int value = encode_arm_immediate (v);
12569877 8706
ba592044
AM
8707 if (value != FAIL)
8708 {
8709 /* This can be done with a mov instruction. */
8710 inst.instruction &= LITERAL_MASK;
8711 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
8712 inst.instruction |= value & 0xfff;
8713 return TRUE;
8714 }
8335d6aa 8715
ba592044
AM
8716 value = encode_arm_immediate (~ v);
8717 if (value != FAIL)
8718 {
8719 /* This can be done with a mvn instruction. */
8720 inst.instruction &= LITERAL_MASK;
8721 inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
8722 inst.instruction |= value & 0xfff;
8723 return TRUE;
8724 }
8725 }
934c2632 8726 else if (t == CONST_VEC && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
8335d6aa 8727 {
ba592044
AM
8728 int op = 0;
8729 unsigned immbits = 0;
8730 unsigned immlo = inst.operands[1].imm;
8731 unsigned immhi = inst.operands[1].regisimm
8732 ? inst.operands[1].reg
e2b0ab59 8733 : inst.relocs[0].exp.X_unsigned
ba592044
AM
8734 ? 0
8735 : ((bfd_int64_t)((int) immlo)) >> 32;
8736 int cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
8737 &op, 64, NT_invtype);
8738
8739 if (cmode == FAIL)
8740 {
8741 neon_invert_size (&immlo, &immhi, 64);
8742 op = !op;
8743 cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
8744 &op, 64, NT_invtype);
8745 }
8746
8747 if (cmode != FAIL)
8748 {
8749 inst.instruction = (inst.instruction & VLDR_VMOV_SAME)
8750 | (1 << 23)
8751 | (cmode << 8)
8752 | (op << 5)
8753 | (1 << 4);
8754
8755 /* Fill other bits in vmov encoding for both thumb and arm. */
8756 if (thumb_mode)
eff0bc54 8757 inst.instruction |= (0x7U << 29) | (0xF << 24);
ba592044 8758 else
eff0bc54 8759 inst.instruction |= (0xFU << 28) | (0x1 << 25);
ba592044
AM
8760 neon_write_immbits (immbits);
8761 return TRUE;
8762 }
8335d6aa
JW
8763 }
8764 }
8335d6aa 8765
ba592044
AM
8766 if (t == CONST_VEC)
8767 {
8768 /* Check if vldr Rx, =constant could be optimized to vmov Rx, #constant. */
8769 if (inst.operands[i].issingle
8770 && is_quarter_float (inst.operands[1].imm)
8771 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3xd))
8335d6aa 8772 {
ba592044
AM
8773 inst.operands[1].imm =
8774 neon_qfloat_bits (v);
8775 do_vfp_nsyn_opcode ("fconsts");
8776 return TRUE;
8335d6aa 8777 }
5fc177c8
NC
8778
8779 /* If our host does not support a 64-bit type then we cannot perform
8780 the following optimization. This mean that there will be a
8781 discrepancy between the output produced by an assembler built for
8782 a 32-bit-only host and the output produced from a 64-bit host, but
8783 this cannot be helped. */
8784#if defined BFD_HOST_64_BIT
ba592044
AM
8785 else if (!inst.operands[1].issingle
8786 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3))
8335d6aa 8787 {
ba592044
AM
8788 if (is_double_a_single (v)
8789 && is_quarter_float (double_to_single (v)))
8790 {
8791 inst.operands[1].imm =
8792 neon_qfloat_bits (double_to_single (v));
8793 do_vfp_nsyn_opcode ("fconstd");
8794 return TRUE;
8795 }
8335d6aa 8796 }
5fc177c8 8797#endif
8335d6aa
JW
8798 }
8799 }
8800
8801 if (add_to_lit_pool ((!inst.operands[i].isvec
8802 || inst.operands[i].issingle) ? 4 : 8) == FAIL)
8803 return TRUE;
8804
8805 inst.operands[1].reg = REG_PC;
8806 inst.operands[1].isreg = 1;
8807 inst.operands[1].preind = 1;
e2b0ab59
AV
8808 inst.relocs[0].pc_rel = 1;
8809 inst.relocs[0].type = (thumb_p
8335d6aa
JW
8810 ? BFD_RELOC_ARM_THUMB_OFFSET
8811 : (mode_3
8812 ? BFD_RELOC_ARM_HWLITERAL
8813 : BFD_RELOC_ARM_LITERAL));
8814 return FALSE;
8815}
8816
8817/* inst.operands[i] was set up by parse_address. Encode it into an
8818 ARM-format instruction. Reject all forms which cannot be encoded
8819 into a coprocessor load/store instruction. If wb_ok is false,
8820 reject use of writeback; if unind_ok is false, reject use of
8821 unindexed addressing. If reloc_override is not 0, use it instead
8822 of BFD_ARM_CP_OFF_IMM, unless the initial relocation is a group one
8823 (in which case it is preserved). */
8824
8825static int
8826encode_arm_cp_address (int i, int wb_ok, int unind_ok, int reloc_override)
8827{
8828 if (!inst.operands[i].isreg)
8829 {
99b2a2dd
NC
8830 /* PR 18256 */
8831 if (! inst.operands[0].isvec)
8832 {
8833 inst.error = _("invalid co-processor operand");
8834 return FAIL;
8835 }
8335d6aa
JW
8836 if (move_or_literal_pool (0, CONST_VEC, /*mode_3=*/FALSE))
8837 return SUCCESS;
8838 }
8839
8840 inst.instruction |= inst.operands[i].reg << 16;
8841
8842 gas_assert (!(inst.operands[i].preind && inst.operands[i].postind));
8843
8844 if (!inst.operands[i].preind && !inst.operands[i].postind) /* unindexed */
8845 {
8846 gas_assert (!inst.operands[i].writeback);
8847 if (!unind_ok)
8848 {
8849 inst.error = _("instruction does not support unindexed addressing");
8850 return FAIL;
8851 }
8852 inst.instruction |= inst.operands[i].imm;
8853 inst.instruction |= INDEX_UP;
8854 return SUCCESS;
8855 }
8856
8857 if (inst.operands[i].preind)
8858 inst.instruction |= PRE_INDEX;
8859
8860 if (inst.operands[i].writeback)
09d92015 8861 {
8335d6aa 8862 if (inst.operands[i].reg == REG_PC)
c19d1205 8863 {
8335d6aa
JW
8864 inst.error = _("pc may not be used with write-back");
8865 return FAIL;
c19d1205 8866 }
8335d6aa 8867 if (!wb_ok)
c19d1205 8868 {
8335d6aa
JW
8869 inst.error = _("instruction does not support writeback");
8870 return FAIL;
c19d1205 8871 }
8335d6aa 8872 inst.instruction |= WRITE_BACK;
09d92015
MM
8873 }
8874
8335d6aa 8875 if (reloc_override)
e2b0ab59
AV
8876 inst.relocs[0].type = (bfd_reloc_code_real_type) reloc_override;
8877 else if ((inst.relocs[0].type < BFD_RELOC_ARM_ALU_PC_G0_NC
8878 || inst.relocs[0].type > BFD_RELOC_ARM_LDC_SB_G2)
8879 && inst.relocs[0].type != BFD_RELOC_ARM_LDR_PC_G0)
c19d1205 8880 {
8335d6aa 8881 if (thumb_mode)
e2b0ab59 8882 inst.relocs[0].type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
8335d6aa 8883 else
e2b0ab59 8884 inst.relocs[0].type = BFD_RELOC_ARM_CP_OFF_IMM;
c19d1205 8885 }
8335d6aa
JW
8886
8887 /* Prefer + for zero encoded value. */
8888 if (!inst.operands[i].negative)
8889 inst.instruction |= INDEX_UP;
8890
8891 return SUCCESS;
09d92015
MM
8892}
8893
5f4273c7 8894/* Functions for instruction encoding, sorted by sub-architecture.
c19d1205
ZW
8895 First some generics; their names are taken from the conventional
8896 bit positions for register arguments in ARM format instructions. */
09d92015 8897
a737bd4d 8898static void
c19d1205 8899do_noargs (void)
09d92015 8900{
c19d1205 8901}
a737bd4d 8902
c19d1205
ZW
8903static void
8904do_rd (void)
8905{
8906 inst.instruction |= inst.operands[0].reg << 12;
8907}
a737bd4d 8908
16a1fa25
TP
8909static void
8910do_rn (void)
8911{
8912 inst.instruction |= inst.operands[0].reg << 16;
8913}
8914
c19d1205
ZW
8915static void
8916do_rd_rm (void)
8917{
8918 inst.instruction |= inst.operands[0].reg << 12;
8919 inst.instruction |= inst.operands[1].reg;
8920}
09d92015 8921
9eb6c0f1
MGD
8922static void
8923do_rm_rn (void)
8924{
8925 inst.instruction |= inst.operands[0].reg;
8926 inst.instruction |= inst.operands[1].reg << 16;
8927}
8928
c19d1205
ZW
8929static void
8930do_rd_rn (void)
8931{
8932 inst.instruction |= inst.operands[0].reg << 12;
8933 inst.instruction |= inst.operands[1].reg << 16;
8934}
a737bd4d 8935
c19d1205
ZW
8936static void
8937do_rn_rd (void)
8938{
8939 inst.instruction |= inst.operands[0].reg << 16;
8940 inst.instruction |= inst.operands[1].reg << 12;
8941}
09d92015 8942
4ed7ed8d
TP
8943static void
8944do_tt (void)
8945{
8946 inst.instruction |= inst.operands[0].reg << 8;
8947 inst.instruction |= inst.operands[1].reg << 16;
8948}
8949
59d09be6
MGD
8950static bfd_boolean
8951check_obsolete (const arm_feature_set *feature, const char *msg)
8952{
8953 if (ARM_CPU_IS_ANY (cpu_variant))
8954 {
5c3696f8 8955 as_tsktsk ("%s", msg);
59d09be6
MGD
8956 return TRUE;
8957 }
8958 else if (ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
8959 {
8960 as_bad ("%s", msg);
8961 return TRUE;
8962 }
8963
8964 return FALSE;
8965}
8966
c19d1205
ZW
8967static void
8968do_rd_rm_rn (void)
8969{
9a64e435 8970 unsigned Rn = inst.operands[2].reg;
708587a4 8971 /* Enforce restrictions on SWP instruction. */
9a64e435 8972 if ((inst.instruction & 0x0fbfffff) == 0x01000090)
56adecf4
DG
8973 {
8974 constraint (Rn == inst.operands[0].reg || Rn == inst.operands[1].reg,
8975 _("Rn must not overlap other operands"));
8976
59d09be6
MGD
8977 /* SWP{b} is obsolete for ARMv8-A, and deprecated for ARMv6* and ARMv7.
8978 */
8979 if (!check_obsolete (&arm_ext_v8,
8980 _("swp{b} use is obsoleted for ARMv8 and later"))
8981 && warn_on_deprecated
8982 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6))
5c3696f8 8983 as_tsktsk (_("swp{b} use is deprecated for ARMv6 and ARMv7"));
56adecf4 8984 }
59d09be6 8985
c19d1205
ZW
8986 inst.instruction |= inst.operands[0].reg << 12;
8987 inst.instruction |= inst.operands[1].reg;
9a64e435 8988 inst.instruction |= Rn << 16;
c19d1205 8989}
09d92015 8990
c19d1205
ZW
8991static void
8992do_rd_rn_rm (void)
8993{
8994 inst.instruction |= inst.operands[0].reg << 12;
8995 inst.instruction |= inst.operands[1].reg << 16;
8996 inst.instruction |= inst.operands[2].reg;
8997}
a737bd4d 8998
c19d1205
ZW
8999static void
9000do_rm_rd_rn (void)
9001{
5be8be5d 9002 constraint ((inst.operands[2].reg == REG_PC), BAD_PC);
e2b0ab59
AV
9003 constraint (((inst.relocs[0].exp.X_op != O_constant
9004 && inst.relocs[0].exp.X_op != O_illegal)
9005 || inst.relocs[0].exp.X_add_number != 0),
5be8be5d 9006 BAD_ADDR_MODE);
c19d1205
ZW
9007 inst.instruction |= inst.operands[0].reg;
9008 inst.instruction |= inst.operands[1].reg << 12;
9009 inst.instruction |= inst.operands[2].reg << 16;
9010}
09d92015 9011
c19d1205
ZW
9012static void
9013do_imm0 (void)
9014{
9015 inst.instruction |= inst.operands[0].imm;
9016}
09d92015 9017
c19d1205
ZW
9018static void
9019do_rd_cpaddr (void)
9020{
9021 inst.instruction |= inst.operands[0].reg << 12;
9022 encode_arm_cp_address (1, TRUE, TRUE, 0);
09d92015 9023}
a737bd4d 9024
c19d1205
ZW
9025/* ARM instructions, in alphabetical order by function name (except
9026 that wrapper functions appear immediately after the function they
9027 wrap). */
09d92015 9028
c19d1205
ZW
9029/* This is a pseudo-op of the form "adr rd, label" to be converted
9030 into a relative address of the form "add rd, pc, #label-.-8". */
09d92015
MM
9031
9032static void
c19d1205 9033do_adr (void)
09d92015 9034{
c19d1205 9035 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 9036
c19d1205
ZW
9037 /* Frag hacking will turn this into a sub instruction if the offset turns
9038 out to be negative. */
e2b0ab59
AV
9039 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
9040 inst.relocs[0].pc_rel = 1;
9041 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 9042
fc6141f0 9043 if (support_interwork
e2b0ab59
AV
9044 && inst.relocs[0].exp.X_op == O_symbol
9045 && inst.relocs[0].exp.X_add_symbol != NULL
9046 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
9047 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
9048 inst.relocs[0].exp.X_add_number |= 1;
c19d1205 9049}
b99bd4ef 9050
c19d1205
ZW
9051/* This is a pseudo-op of the form "adrl rd, label" to be converted
9052 into a relative address of the form:
9053 add rd, pc, #low(label-.-8)"
9054 add rd, rd, #high(label-.-8)" */
b99bd4ef 9055
c19d1205
ZW
9056static void
9057do_adrl (void)
9058{
9059 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 9060
c19d1205
ZW
9061 /* Frag hacking will turn this into a sub instruction if the offset turns
9062 out to be negative. */
e2b0ab59
AV
9063 inst.relocs[0].type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
9064 inst.relocs[0].pc_rel = 1;
c19d1205 9065 inst.size = INSN_SIZE * 2;
e2b0ab59 9066 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 9067
fc6141f0 9068 if (support_interwork
e2b0ab59
AV
9069 && inst.relocs[0].exp.X_op == O_symbol
9070 && inst.relocs[0].exp.X_add_symbol != NULL
9071 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
9072 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
9073 inst.relocs[0].exp.X_add_number |= 1;
b99bd4ef
NC
9074}
9075
b99bd4ef 9076static void
c19d1205 9077do_arit (void)
b99bd4ef 9078{
e2b0ab59
AV
9079 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
9080 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 9081 THUMB1_RELOC_ONLY);
c19d1205
ZW
9082 if (!inst.operands[1].present)
9083 inst.operands[1].reg = inst.operands[0].reg;
9084 inst.instruction |= inst.operands[0].reg << 12;
9085 inst.instruction |= inst.operands[1].reg << 16;
9086 encode_arm_shifter_operand (2);
9087}
b99bd4ef 9088
62b3e311
PB
9089static void
9090do_barrier (void)
9091{
9092 if (inst.operands[0].present)
ccb84d65 9093 inst.instruction |= inst.operands[0].imm;
62b3e311
PB
9094 else
9095 inst.instruction |= 0xf;
9096}
9097
c19d1205
ZW
9098static void
9099do_bfc (void)
9100{
9101 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
9102 constraint (msb > 32, _("bit-field extends past end of register"));
9103 /* The instruction encoding stores the LSB and MSB,
9104 not the LSB and width. */
9105 inst.instruction |= inst.operands[0].reg << 12;
9106 inst.instruction |= inst.operands[1].imm << 7;
9107 inst.instruction |= (msb - 1) << 16;
9108}
b99bd4ef 9109
c19d1205
ZW
9110static void
9111do_bfi (void)
9112{
9113 unsigned int msb;
b99bd4ef 9114
c19d1205
ZW
9115 /* #0 in second position is alternative syntax for bfc, which is
9116 the same instruction but with REG_PC in the Rm field. */
9117 if (!inst.operands[1].isreg)
9118 inst.operands[1].reg = REG_PC;
b99bd4ef 9119
c19d1205
ZW
9120 msb = inst.operands[2].imm + inst.operands[3].imm;
9121 constraint (msb > 32, _("bit-field extends past end of register"));
9122 /* The instruction encoding stores the LSB and MSB,
9123 not the LSB and width. */
9124 inst.instruction |= inst.operands[0].reg << 12;
9125 inst.instruction |= inst.operands[1].reg;
9126 inst.instruction |= inst.operands[2].imm << 7;
9127 inst.instruction |= (msb - 1) << 16;
b99bd4ef
NC
9128}
9129
b99bd4ef 9130static void
c19d1205 9131do_bfx (void)
b99bd4ef 9132{
c19d1205
ZW
9133 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
9134 _("bit-field extends past end of register"));
9135 inst.instruction |= inst.operands[0].reg << 12;
9136 inst.instruction |= inst.operands[1].reg;
9137 inst.instruction |= inst.operands[2].imm << 7;
9138 inst.instruction |= (inst.operands[3].imm - 1) << 16;
9139}
09d92015 9140
c19d1205
ZW
9141/* ARM V5 breakpoint instruction (argument parse)
9142 BKPT <16 bit unsigned immediate>
9143 Instruction is not conditional.
9144 The bit pattern given in insns[] has the COND_ALWAYS condition,
9145 and it is an error if the caller tried to override that. */
b99bd4ef 9146
c19d1205
ZW
9147static void
9148do_bkpt (void)
9149{
9150 /* Top 12 of 16 bits to bits 19:8. */
9151 inst.instruction |= (inst.operands[0].imm & 0xfff0) << 4;
09d92015 9152
c19d1205
ZW
9153 /* Bottom 4 of 16 bits to bits 3:0. */
9154 inst.instruction |= inst.operands[0].imm & 0xf;
9155}
09d92015 9156
c19d1205
ZW
9157static void
9158encode_branch (int default_reloc)
9159{
9160 if (inst.operands[0].hasreloc)
9161 {
0855e32b
NS
9162 constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32
9163 && inst.operands[0].imm != BFD_RELOC_ARM_TLS_CALL,
9164 _("the only valid suffixes here are '(plt)' and '(tlscall)'"));
e2b0ab59 9165 inst.relocs[0].type = inst.operands[0].imm == BFD_RELOC_ARM_PLT32
0855e32b
NS
9166 ? BFD_RELOC_ARM_PLT32
9167 : thumb_mode ? BFD_RELOC_ARM_THM_TLS_CALL : BFD_RELOC_ARM_TLS_CALL;
c19d1205 9168 }
b99bd4ef 9169 else
e2b0ab59
AV
9170 inst.relocs[0].type = (bfd_reloc_code_real_type) default_reloc;
9171 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
9172}
9173
b99bd4ef 9174static void
c19d1205 9175do_branch (void)
b99bd4ef 9176{
39b41c9c
PB
9177#ifdef OBJ_ELF
9178 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
9179 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
9180 else
9181#endif
9182 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
9183}
9184
9185static void
9186do_bl (void)
9187{
9188#ifdef OBJ_ELF
9189 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
9190 {
9191 if (inst.cond == COND_ALWAYS)
9192 encode_branch (BFD_RELOC_ARM_PCREL_CALL);
9193 else
9194 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
9195 }
9196 else
9197#endif
9198 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
c19d1205 9199}
b99bd4ef 9200
c19d1205
ZW
9201/* ARM V5 branch-link-exchange instruction (argument parse)
9202 BLX <target_addr> ie BLX(1)
9203 BLX{<condition>} <Rm> ie BLX(2)
9204 Unfortunately, there are two different opcodes for this mnemonic.
9205 So, the insns[].value is not used, and the code here zaps values
9206 into inst.instruction.
9207 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
b99bd4ef 9208
c19d1205
ZW
9209static void
9210do_blx (void)
9211{
9212 if (inst.operands[0].isreg)
b99bd4ef 9213 {
c19d1205
ZW
9214 /* Arg is a register; the opcode provided by insns[] is correct.
9215 It is not illegal to do "blx pc", just useless. */
9216 if (inst.operands[0].reg == REG_PC)
9217 as_tsktsk (_("use of r15 in blx in ARM mode is not really useful"));
b99bd4ef 9218
c19d1205
ZW
9219 inst.instruction |= inst.operands[0].reg;
9220 }
9221 else
b99bd4ef 9222 {
c19d1205 9223 /* Arg is an address; this instruction cannot be executed
267bf995
RR
9224 conditionally, and the opcode must be adjusted.
9225 We retain the BFD_RELOC_ARM_PCREL_BLX till the very end
9226 where we generate out a BFD_RELOC_ARM_PCREL_CALL instead. */
c19d1205 9227 constraint (inst.cond != COND_ALWAYS, BAD_COND);
2fc8bdac 9228 inst.instruction = 0xfa000000;
267bf995 9229 encode_branch (BFD_RELOC_ARM_PCREL_BLX);
b99bd4ef 9230 }
c19d1205
ZW
9231}
9232
9233static void
9234do_bx (void)
9235{
845b51d6
PB
9236 bfd_boolean want_reloc;
9237
c19d1205
ZW
9238 if (inst.operands[0].reg == REG_PC)
9239 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
b99bd4ef 9240
c19d1205 9241 inst.instruction |= inst.operands[0].reg;
845b51d6
PB
9242 /* Output R_ARM_V4BX relocations if is an EABI object that looks like
9243 it is for ARMv4t or earlier. */
9244 want_reloc = !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5);
4d354d8b
TP
9245 if (!ARM_FEATURE_ZERO (selected_object_arch)
9246 && !ARM_CPU_HAS_FEATURE (selected_object_arch, arm_ext_v5))
845b51d6
PB
9247 want_reloc = TRUE;
9248
5ad34203 9249#ifdef OBJ_ELF
845b51d6 9250 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
5ad34203 9251#endif
584206db 9252 want_reloc = FALSE;
845b51d6
PB
9253
9254 if (want_reloc)
e2b0ab59 9255 inst.relocs[0].type = BFD_RELOC_ARM_V4BX;
09d92015
MM
9256}
9257
c19d1205
ZW
9258
9259/* ARM v5TEJ. Jump to Jazelle code. */
a737bd4d
NC
9260
9261static void
c19d1205 9262do_bxj (void)
a737bd4d 9263{
c19d1205
ZW
9264 if (inst.operands[0].reg == REG_PC)
9265 as_tsktsk (_("use of r15 in bxj is not really useful"));
9266
9267 inst.instruction |= inst.operands[0].reg;
a737bd4d
NC
9268}
9269
c19d1205
ZW
9270/* Co-processor data operation:
9271 CDP{cond} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>}
9272 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>} */
9273static void
9274do_cdp (void)
9275{
9276 inst.instruction |= inst.operands[0].reg << 8;
9277 inst.instruction |= inst.operands[1].imm << 20;
9278 inst.instruction |= inst.operands[2].reg << 12;
9279 inst.instruction |= inst.operands[3].reg << 16;
9280 inst.instruction |= inst.operands[4].reg;
9281 inst.instruction |= inst.operands[5].imm << 5;
9282}
a737bd4d
NC
9283
9284static void
c19d1205 9285do_cmp (void)
a737bd4d 9286{
c19d1205
ZW
9287 inst.instruction |= inst.operands[0].reg << 16;
9288 encode_arm_shifter_operand (1);
a737bd4d
NC
9289}
9290
c19d1205
ZW
9291/* Transfer between coprocessor and ARM registers.
9292 MRC{cond} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}
9293 MRC2
9294 MCR{cond}
9295 MCR2
9296
9297 No special properties. */
09d92015 9298
dcbd0d71
MGD
9299struct deprecated_coproc_regs_s
9300{
9301 unsigned cp;
9302 int opc1;
9303 unsigned crn;
9304 unsigned crm;
9305 int opc2;
9306 arm_feature_set deprecated;
9307 arm_feature_set obsoleted;
9308 const char *dep_msg;
9309 const char *obs_msg;
9310};
9311
9312#define DEPR_ACCESS_V8 \
9313 N_("This coprocessor register access is deprecated in ARMv8")
9314
9315/* Table of all deprecated coprocessor registers. */
9316static struct deprecated_coproc_regs_s deprecated_coproc_regs[] =
9317{
9318 {15, 0, 7, 10, 5, /* CP15DMB. */
823d2571 9319 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9320 DEPR_ACCESS_V8, NULL},
9321 {15, 0, 7, 10, 4, /* CP15DSB. */
823d2571 9322 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9323 DEPR_ACCESS_V8, NULL},
9324 {15, 0, 7, 5, 4, /* CP15ISB. */
823d2571 9325 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9326 DEPR_ACCESS_V8, NULL},
9327 {14, 6, 1, 0, 0, /* TEEHBR. */
823d2571 9328 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9329 DEPR_ACCESS_V8, NULL},
9330 {14, 6, 0, 0, 0, /* TEECR. */
823d2571 9331 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9332 DEPR_ACCESS_V8, NULL},
9333};
9334
9335#undef DEPR_ACCESS_V8
9336
9337static const size_t deprecated_coproc_reg_count =
9338 sizeof (deprecated_coproc_regs) / sizeof (deprecated_coproc_regs[0]);
9339
09d92015 9340static void
c19d1205 9341do_co_reg (void)
09d92015 9342{
fdfde340 9343 unsigned Rd;
dcbd0d71 9344 size_t i;
fdfde340
JM
9345
9346 Rd = inst.operands[2].reg;
9347 if (thumb_mode)
9348 {
9349 if (inst.instruction == 0xee000010
9350 || inst.instruction == 0xfe000010)
9351 /* MCR, MCR2 */
9352 reject_bad_reg (Rd);
5c8ed6a4 9353 else if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
fdfde340
JM
9354 /* MRC, MRC2 */
9355 constraint (Rd == REG_SP, BAD_SP);
9356 }
9357 else
9358 {
9359 /* MCR */
9360 if (inst.instruction == 0xe000010)
9361 constraint (Rd == REG_PC, BAD_PC);
9362 }
9363
dcbd0d71
MGD
9364 for (i = 0; i < deprecated_coproc_reg_count; ++i)
9365 {
9366 const struct deprecated_coproc_regs_s *r =
9367 deprecated_coproc_regs + i;
9368
9369 if (inst.operands[0].reg == r->cp
9370 && inst.operands[1].imm == r->opc1
9371 && inst.operands[3].reg == r->crn
9372 && inst.operands[4].reg == r->crm
9373 && inst.operands[5].imm == r->opc2)
9374 {
b10bf8c5 9375 if (! ARM_CPU_IS_ANY (cpu_variant)
477330fc 9376 && warn_on_deprecated
dcbd0d71 9377 && ARM_CPU_HAS_FEATURE (cpu_variant, r->deprecated))
5c3696f8 9378 as_tsktsk ("%s", r->dep_msg);
dcbd0d71
MGD
9379 }
9380 }
fdfde340 9381
c19d1205
ZW
9382 inst.instruction |= inst.operands[0].reg << 8;
9383 inst.instruction |= inst.operands[1].imm << 21;
fdfde340 9384 inst.instruction |= Rd << 12;
c19d1205
ZW
9385 inst.instruction |= inst.operands[3].reg << 16;
9386 inst.instruction |= inst.operands[4].reg;
9387 inst.instruction |= inst.operands[5].imm << 5;
9388}
09d92015 9389
c19d1205
ZW
9390/* Transfer between coprocessor register and pair of ARM registers.
9391 MCRR{cond} <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
9392 MCRR2
9393 MRRC{cond}
9394 MRRC2
b99bd4ef 9395
c19d1205 9396 Two XScale instructions are special cases of these:
09d92015 9397
c19d1205
ZW
9398 MAR{cond} acc0, <RdLo>, <RdHi> == MCRR{cond} p0, #0, <RdLo>, <RdHi>, c0
9399 MRA{cond} acc0, <RdLo>, <RdHi> == MRRC{cond} p0, #0, <RdLo>, <RdHi>, c0
b99bd4ef 9400
5f4273c7 9401 Result unpredictable if Rd or Rn is R15. */
a737bd4d 9402
c19d1205
ZW
9403static void
9404do_co_reg2c (void)
9405{
fdfde340
JM
9406 unsigned Rd, Rn;
9407
9408 Rd = inst.operands[2].reg;
9409 Rn = inst.operands[3].reg;
9410
9411 if (thumb_mode)
9412 {
9413 reject_bad_reg (Rd);
9414 reject_bad_reg (Rn);
9415 }
9416 else
9417 {
9418 constraint (Rd == REG_PC, BAD_PC);
9419 constraint (Rn == REG_PC, BAD_PC);
9420 }
9421
873f10f0
TC
9422 /* Only check the MRRC{2} variants. */
9423 if ((inst.instruction & 0x0FF00000) == 0x0C500000)
9424 {
9425 /* If Rd == Rn, error that the operation is
9426 unpredictable (example MRRC p3,#1,r1,r1,c4). */
9427 constraint (Rd == Rn, BAD_OVERLAP);
9428 }
9429
c19d1205
ZW
9430 inst.instruction |= inst.operands[0].reg << 8;
9431 inst.instruction |= inst.operands[1].imm << 4;
fdfde340
JM
9432 inst.instruction |= Rd << 12;
9433 inst.instruction |= Rn << 16;
c19d1205 9434 inst.instruction |= inst.operands[4].reg;
b99bd4ef
NC
9435}
9436
c19d1205
ZW
9437static void
9438do_cpsi (void)
9439{
9440 inst.instruction |= inst.operands[0].imm << 6;
a028a6f5
PB
9441 if (inst.operands[1].present)
9442 {
9443 inst.instruction |= CPSI_MMOD;
9444 inst.instruction |= inst.operands[1].imm;
9445 }
c19d1205 9446}
b99bd4ef 9447
62b3e311
PB
9448static void
9449do_dbg (void)
9450{
9451 inst.instruction |= inst.operands[0].imm;
9452}
9453
eea54501
MGD
9454static void
9455do_div (void)
9456{
9457 unsigned Rd, Rn, Rm;
9458
9459 Rd = inst.operands[0].reg;
9460 Rn = (inst.operands[1].present
9461 ? inst.operands[1].reg : Rd);
9462 Rm = inst.operands[2].reg;
9463
9464 constraint ((Rd == REG_PC), BAD_PC);
9465 constraint ((Rn == REG_PC), BAD_PC);
9466 constraint ((Rm == REG_PC), BAD_PC);
9467
9468 inst.instruction |= Rd << 16;
9469 inst.instruction |= Rn << 0;
9470 inst.instruction |= Rm << 8;
9471}
9472
b99bd4ef 9473static void
c19d1205 9474do_it (void)
b99bd4ef 9475{
c19d1205 9476 /* There is no IT instruction in ARM mode. We
e07e6e58
NC
9477 process it to do the validation as if in
9478 thumb mode, just in case the code gets
9479 assembled for thumb using the unified syntax. */
9480
c19d1205 9481 inst.size = 0;
e07e6e58
NC
9482 if (unified_syntax)
9483 {
5ee91343
AV
9484 set_pred_insn_type (IT_INSN);
9485 now_pred.mask = (inst.instruction & 0xf) | 0x10;
9486 now_pred.cc = inst.operands[0].imm;
e07e6e58 9487 }
09d92015 9488}
b99bd4ef 9489
6530b175
NC
9490/* If there is only one register in the register list,
9491 then return its register number. Otherwise return -1. */
9492static int
9493only_one_reg_in_list (int range)
9494{
9495 int i = ffs (range) - 1;
9496 return (i > 15 || range != (1 << i)) ? -1 : i;
9497}
9498
09d92015 9499static void
6530b175 9500encode_ldmstm(int from_push_pop_mnem)
ea6ef066 9501{
c19d1205
ZW
9502 int base_reg = inst.operands[0].reg;
9503 int range = inst.operands[1].imm;
6530b175 9504 int one_reg;
ea6ef066 9505
c19d1205
ZW
9506 inst.instruction |= base_reg << 16;
9507 inst.instruction |= range;
ea6ef066 9508
c19d1205
ZW
9509 if (inst.operands[1].writeback)
9510 inst.instruction |= LDM_TYPE_2_OR_3;
09d92015 9511
c19d1205 9512 if (inst.operands[0].writeback)
ea6ef066 9513 {
c19d1205
ZW
9514 inst.instruction |= WRITE_BACK;
9515 /* Check for unpredictable uses of writeback. */
9516 if (inst.instruction & LOAD_BIT)
09d92015 9517 {
c19d1205
ZW
9518 /* Not allowed in LDM type 2. */
9519 if ((inst.instruction & LDM_TYPE_2_OR_3)
9520 && ((range & (1 << REG_PC)) == 0))
9521 as_warn (_("writeback of base register is UNPREDICTABLE"));
9522 /* Only allowed if base reg not in list for other types. */
9523 else if (range & (1 << base_reg))
9524 as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
9525 }
9526 else /* STM. */
9527 {
9528 /* Not allowed for type 2. */
9529 if (inst.instruction & LDM_TYPE_2_OR_3)
9530 as_warn (_("writeback of base register is UNPREDICTABLE"));
9531 /* Only allowed if base reg not in list, or first in list. */
9532 else if ((range & (1 << base_reg))
9533 && (range & ((1 << base_reg) - 1)))
9534 as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
09d92015 9535 }
ea6ef066 9536 }
6530b175
NC
9537
9538 /* If PUSH/POP has only one register, then use the A2 encoding. */
9539 one_reg = only_one_reg_in_list (range);
9540 if (from_push_pop_mnem && one_reg >= 0)
9541 {
9542 int is_push = (inst.instruction & A_PUSH_POP_OP_MASK) == A1_OPCODE_PUSH;
9543
4f588891
NC
9544 if (is_push && one_reg == 13 /* SP */)
9545 /* PR 22483: The A2 encoding cannot be used when
9546 pushing the stack pointer as this is UNPREDICTABLE. */
9547 return;
9548
6530b175
NC
9549 inst.instruction &= A_COND_MASK;
9550 inst.instruction |= is_push ? A2_OPCODE_PUSH : A2_OPCODE_POP;
9551 inst.instruction |= one_reg << 12;
9552 }
9553}
9554
9555static void
9556do_ldmstm (void)
9557{
9558 encode_ldmstm (/*from_push_pop_mnem=*/FALSE);
a737bd4d
NC
9559}
9560
c19d1205
ZW
9561/* ARMv5TE load-consecutive (argument parse)
9562 Mode is like LDRH.
9563
9564 LDRccD R, mode
9565 STRccD R, mode. */
9566
a737bd4d 9567static void
c19d1205 9568do_ldrd (void)
a737bd4d 9569{
c19d1205 9570 constraint (inst.operands[0].reg % 2 != 0,
c56791bb 9571 _("first transfer register must be even"));
c19d1205
ZW
9572 constraint (inst.operands[1].present
9573 && inst.operands[1].reg != inst.operands[0].reg + 1,
c56791bb 9574 _("can only transfer two consecutive registers"));
c19d1205
ZW
9575 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
9576 constraint (!inst.operands[2].isreg, _("'[' expected"));
a737bd4d 9577
c19d1205
ZW
9578 if (!inst.operands[1].present)
9579 inst.operands[1].reg = inst.operands[0].reg + 1;
5f4273c7 9580
c56791bb
RE
9581 /* encode_arm_addr_mode_3 will diagnose overlap between the base
9582 register and the first register written; we have to diagnose
9583 overlap between the base and the second register written here. */
ea6ef066 9584
c56791bb
RE
9585 if (inst.operands[2].reg == inst.operands[1].reg
9586 && (inst.operands[2].writeback || inst.operands[2].postind))
9587 as_warn (_("base register written back, and overlaps "
9588 "second transfer register"));
b05fe5cf 9589
c56791bb
RE
9590 if (!(inst.instruction & V4_STR_BIT))
9591 {
c19d1205 9592 /* For an index-register load, the index register must not overlap the
c56791bb
RE
9593 destination (even if not write-back). */
9594 if (inst.operands[2].immisreg
9595 && ((unsigned) inst.operands[2].imm == inst.operands[0].reg
9596 || (unsigned) inst.operands[2].imm == inst.operands[1].reg))
9597 as_warn (_("index register overlaps transfer register"));
b05fe5cf 9598 }
c19d1205
ZW
9599 inst.instruction |= inst.operands[0].reg << 12;
9600 encode_arm_addr_mode_3 (2, /*is_t=*/FALSE);
b05fe5cf
ZW
9601}
9602
9603static void
c19d1205 9604do_ldrex (void)
b05fe5cf 9605{
c19d1205
ZW
9606 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
9607 || inst.operands[1].postind || inst.operands[1].writeback
9608 || inst.operands[1].immisreg || inst.operands[1].shifted
01cfc07f
NC
9609 || inst.operands[1].negative
9610 /* This can arise if the programmer has written
9611 strex rN, rM, foo
9612 or if they have mistakenly used a register name as the last
9613 operand, eg:
9614 strex rN, rM, rX
9615 It is very difficult to distinguish between these two cases
9616 because "rX" might actually be a label. ie the register
9617 name has been occluded by a symbol of the same name. So we
9618 just generate a general 'bad addressing mode' type error
9619 message and leave it up to the programmer to discover the
9620 true cause and fix their mistake. */
9621 || (inst.operands[1].reg == REG_PC),
9622 BAD_ADDR_MODE);
b05fe5cf 9623
e2b0ab59
AV
9624 constraint (inst.relocs[0].exp.X_op != O_constant
9625 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9626 _("offset must be zero in ARM encoding"));
b05fe5cf 9627
5be8be5d
DG
9628 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
9629
c19d1205
ZW
9630 inst.instruction |= inst.operands[0].reg << 12;
9631 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 9632 inst.relocs[0].type = BFD_RELOC_UNUSED;
b05fe5cf
ZW
9633}
9634
9635static void
c19d1205 9636do_ldrexd (void)
b05fe5cf 9637{
c19d1205
ZW
9638 constraint (inst.operands[0].reg % 2 != 0,
9639 _("even register required"));
9640 constraint (inst.operands[1].present
9641 && inst.operands[1].reg != inst.operands[0].reg + 1,
9642 _("can only load two consecutive registers"));
9643 /* If op 1 were present and equal to PC, this function wouldn't
9644 have been called in the first place. */
9645 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
b05fe5cf 9646
c19d1205
ZW
9647 inst.instruction |= inst.operands[0].reg << 12;
9648 inst.instruction |= inst.operands[2].reg << 16;
b05fe5cf
ZW
9649}
9650
1be5fd2e
NC
9651/* In both ARM and thumb state 'ldr pc, #imm' with an immediate
9652 which is not a multiple of four is UNPREDICTABLE. */
9653static void
9654check_ldr_r15_aligned (void)
9655{
9656 constraint (!(inst.operands[1].immisreg)
9657 && (inst.operands[0].reg == REG_PC
9658 && inst.operands[1].reg == REG_PC
e2b0ab59 9659 && (inst.relocs[0].exp.X_add_number & 0x3)),
de194d85 9660 _("ldr to register 15 must be 4-byte aligned"));
1be5fd2e
NC
9661}
9662
b05fe5cf 9663static void
c19d1205 9664do_ldst (void)
b05fe5cf 9665{
c19d1205
ZW
9666 inst.instruction |= inst.operands[0].reg << 12;
9667 if (!inst.operands[1].isreg)
8335d6aa 9668 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/FALSE))
b05fe5cf 9669 return;
c19d1205 9670 encode_arm_addr_mode_2 (1, /*is_t=*/FALSE);
1be5fd2e 9671 check_ldr_r15_aligned ();
b05fe5cf
ZW
9672}
9673
9674static void
c19d1205 9675do_ldstt (void)
b05fe5cf 9676{
c19d1205
ZW
9677 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
9678 reject [Rn,...]. */
9679 if (inst.operands[1].preind)
b05fe5cf 9680 {
e2b0ab59
AV
9681 constraint (inst.relocs[0].exp.X_op != O_constant
9682 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9683 _("this instruction requires a post-indexed address"));
b05fe5cf 9684
c19d1205
ZW
9685 inst.operands[1].preind = 0;
9686 inst.operands[1].postind = 1;
9687 inst.operands[1].writeback = 1;
b05fe5cf 9688 }
c19d1205
ZW
9689 inst.instruction |= inst.operands[0].reg << 12;
9690 encode_arm_addr_mode_2 (1, /*is_t=*/TRUE);
9691}
b05fe5cf 9692
c19d1205 9693/* Halfword and signed-byte load/store operations. */
b05fe5cf 9694
c19d1205
ZW
9695static void
9696do_ldstv4 (void)
9697{
ff4a8d2b 9698 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205
ZW
9699 inst.instruction |= inst.operands[0].reg << 12;
9700 if (!inst.operands[1].isreg)
8335d6aa 9701 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/TRUE))
b05fe5cf 9702 return;
c19d1205 9703 encode_arm_addr_mode_3 (1, /*is_t=*/FALSE);
b05fe5cf
ZW
9704}
9705
9706static void
c19d1205 9707do_ldsttv4 (void)
b05fe5cf 9708{
c19d1205
ZW
9709 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
9710 reject [Rn,...]. */
9711 if (inst.operands[1].preind)
b05fe5cf 9712 {
e2b0ab59
AV
9713 constraint (inst.relocs[0].exp.X_op != O_constant
9714 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9715 _("this instruction requires a post-indexed address"));
b05fe5cf 9716
c19d1205
ZW
9717 inst.operands[1].preind = 0;
9718 inst.operands[1].postind = 1;
9719 inst.operands[1].writeback = 1;
b05fe5cf 9720 }
c19d1205
ZW
9721 inst.instruction |= inst.operands[0].reg << 12;
9722 encode_arm_addr_mode_3 (1, /*is_t=*/TRUE);
9723}
b05fe5cf 9724
c19d1205
ZW
9725/* Co-processor register load/store.
9726 Format: <LDC|STC>{cond}[L] CP#,CRd,<address> */
9727static void
9728do_lstc (void)
9729{
9730 inst.instruction |= inst.operands[0].reg << 8;
9731 inst.instruction |= inst.operands[1].reg << 12;
9732 encode_arm_cp_address (2, TRUE, TRUE, 0);
b05fe5cf
ZW
9733}
9734
b05fe5cf 9735static void
c19d1205 9736do_mlas (void)
b05fe5cf 9737{
8fb9d7b9 9738 /* This restriction does not apply to mls (nor to mla in v6 or later). */
c19d1205 9739 if (inst.operands[0].reg == inst.operands[1].reg
8fb9d7b9 9740 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6)
c19d1205 9741 && !(inst.instruction & 0x00400000))
8fb9d7b9 9742 as_tsktsk (_("Rd and Rm should be different in mla"));
b05fe5cf 9743
c19d1205
ZW
9744 inst.instruction |= inst.operands[0].reg << 16;
9745 inst.instruction |= inst.operands[1].reg;
9746 inst.instruction |= inst.operands[2].reg << 8;
9747 inst.instruction |= inst.operands[3].reg << 12;
c19d1205 9748}
b05fe5cf 9749
c19d1205
ZW
9750static void
9751do_mov (void)
9752{
e2b0ab59
AV
9753 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
9754 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 9755 THUMB1_RELOC_ONLY);
c19d1205
ZW
9756 inst.instruction |= inst.operands[0].reg << 12;
9757 encode_arm_shifter_operand (1);
9758}
b05fe5cf 9759
c19d1205
ZW
9760/* ARM V6T2 16-bit immediate register load: MOV[WT]{cond} Rd, #<imm16>. */
9761static void
9762do_mov16 (void)
9763{
b6895b4f
PB
9764 bfd_vma imm;
9765 bfd_boolean top;
9766
9767 top = (inst.instruction & 0x00400000) != 0;
e2b0ab59 9768 constraint (top && inst.relocs[0].type == BFD_RELOC_ARM_MOVW,
33eaf5de 9769 _(":lower16: not allowed in this instruction"));
e2b0ab59 9770 constraint (!top && inst.relocs[0].type == BFD_RELOC_ARM_MOVT,
33eaf5de 9771 _(":upper16: not allowed in this instruction"));
c19d1205 9772 inst.instruction |= inst.operands[0].reg << 12;
e2b0ab59 9773 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 9774 {
e2b0ab59 9775 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
9776 /* The value is in two pieces: 0:11, 16:19. */
9777 inst.instruction |= (imm & 0x00000fff);
9778 inst.instruction |= (imm & 0x0000f000) << 4;
9779 }
b05fe5cf 9780}
b99bd4ef 9781
037e8744
JB
9782static int
9783do_vfp_nsyn_mrs (void)
9784{
9785 if (inst.operands[0].isvec)
9786 {
9787 if (inst.operands[1].reg != 1)
477330fc 9788 first_error (_("operand 1 must be FPSCR"));
037e8744
JB
9789 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
9790 memset (&inst.operands[1], '\0', sizeof (inst.operands[1]));
9791 do_vfp_nsyn_opcode ("fmstat");
9792 }
9793 else if (inst.operands[1].isvec)
9794 do_vfp_nsyn_opcode ("fmrx");
9795 else
9796 return FAIL;
5f4273c7 9797
037e8744
JB
9798 return SUCCESS;
9799}
9800
9801static int
9802do_vfp_nsyn_msr (void)
9803{
9804 if (inst.operands[0].isvec)
9805 do_vfp_nsyn_opcode ("fmxr");
9806 else
9807 return FAIL;
9808
9809 return SUCCESS;
9810}
9811
f7c21dc7
NC
9812static void
9813do_vmrs (void)
9814{
9815 unsigned Rt = inst.operands[0].reg;
fa94de6b 9816
16d02dc9 9817 if (thumb_mode && Rt == REG_SP)
f7c21dc7
NC
9818 {
9819 inst.error = BAD_SP;
9820 return;
9821 }
9822
40c7d507
RR
9823 /* MVFR2 is only valid at ARMv8-A. */
9824 if (inst.operands[1].reg == 5)
9825 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
9826 _(BAD_FPU));
9827
f7c21dc7 9828 /* APSR_ sets isvec. All other refs to PC are illegal. */
16d02dc9 9829 if (!inst.operands[0].isvec && Rt == REG_PC)
f7c21dc7
NC
9830 {
9831 inst.error = BAD_PC;
9832 return;
9833 }
9834
16d02dc9
JB
9835 /* If we get through parsing the register name, we just insert the number
9836 generated into the instruction without further validation. */
9837 inst.instruction |= (inst.operands[1].reg << 16);
f7c21dc7
NC
9838 inst.instruction |= (Rt << 12);
9839}
9840
9841static void
9842do_vmsr (void)
9843{
9844 unsigned Rt = inst.operands[1].reg;
fa94de6b 9845
f7c21dc7
NC
9846 if (thumb_mode)
9847 reject_bad_reg (Rt);
9848 else if (Rt == REG_PC)
9849 {
9850 inst.error = BAD_PC;
9851 return;
9852 }
9853
40c7d507
RR
9854 /* MVFR2 is only valid for ARMv8-A. */
9855 if (inst.operands[0].reg == 5)
9856 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
9857 _(BAD_FPU));
9858
16d02dc9
JB
9859 /* If we get through parsing the register name, we just insert the number
9860 generated into the instruction without further validation. */
9861 inst.instruction |= (inst.operands[0].reg << 16);
f7c21dc7
NC
9862 inst.instruction |= (Rt << 12);
9863}
9864
b99bd4ef 9865static void
c19d1205 9866do_mrs (void)
b99bd4ef 9867{
90ec0d68
MGD
9868 unsigned br;
9869
037e8744
JB
9870 if (do_vfp_nsyn_mrs () == SUCCESS)
9871 return;
9872
ff4a8d2b 9873 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205 9874 inst.instruction |= inst.operands[0].reg << 12;
90ec0d68
MGD
9875
9876 if (inst.operands[1].isreg)
9877 {
9878 br = inst.operands[1].reg;
806ab1c0 9879 if (((br & 0x200) == 0) && ((br & 0xf0000) != 0xf0000))
90ec0d68
MGD
9880 as_bad (_("bad register for mrs"));
9881 }
9882 else
9883 {
9884 /* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all. */
9885 constraint ((inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f))
9886 != (PSR_c|PSR_f),
d2cd1205 9887 _("'APSR', 'CPSR' or 'SPSR' expected"));
90ec0d68
MGD
9888 br = (15<<16) | (inst.operands[1].imm & SPSR_BIT);
9889 }
9890
9891 inst.instruction |= br;
c19d1205 9892}
b99bd4ef 9893
c19d1205
ZW
9894/* Two possible forms:
9895 "{C|S}PSR_<field>, Rm",
9896 "{C|S}PSR_f, #expression". */
b99bd4ef 9897
c19d1205
ZW
9898static void
9899do_msr (void)
9900{
037e8744
JB
9901 if (do_vfp_nsyn_msr () == SUCCESS)
9902 return;
9903
c19d1205
ZW
9904 inst.instruction |= inst.operands[0].imm;
9905 if (inst.operands[1].isreg)
9906 inst.instruction |= inst.operands[1].reg;
9907 else
b99bd4ef 9908 {
c19d1205 9909 inst.instruction |= INST_IMMEDIATE;
e2b0ab59
AV
9910 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
9911 inst.relocs[0].pc_rel = 0;
b99bd4ef 9912 }
b99bd4ef
NC
9913}
9914
c19d1205
ZW
9915static void
9916do_mul (void)
a737bd4d 9917{
ff4a8d2b
NC
9918 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
9919
c19d1205
ZW
9920 if (!inst.operands[2].present)
9921 inst.operands[2].reg = inst.operands[0].reg;
9922 inst.instruction |= inst.operands[0].reg << 16;
9923 inst.instruction |= inst.operands[1].reg;
9924 inst.instruction |= inst.operands[2].reg << 8;
a737bd4d 9925
8fb9d7b9
MS
9926 if (inst.operands[0].reg == inst.operands[1].reg
9927 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
9928 as_tsktsk (_("Rd and Rm should be different in mul"));
a737bd4d
NC
9929}
9930
c19d1205
ZW
9931/* Long Multiply Parser
9932 UMULL RdLo, RdHi, Rm, Rs
9933 SMULL RdLo, RdHi, Rm, Rs
9934 UMLAL RdLo, RdHi, Rm, Rs
9935 SMLAL RdLo, RdHi, Rm, Rs. */
b99bd4ef
NC
9936
9937static void
c19d1205 9938do_mull (void)
b99bd4ef 9939{
c19d1205
ZW
9940 inst.instruction |= inst.operands[0].reg << 12;
9941 inst.instruction |= inst.operands[1].reg << 16;
9942 inst.instruction |= inst.operands[2].reg;
9943 inst.instruction |= inst.operands[3].reg << 8;
b99bd4ef 9944
682b27ad
PB
9945 /* rdhi and rdlo must be different. */
9946 if (inst.operands[0].reg == inst.operands[1].reg)
9947 as_tsktsk (_("rdhi and rdlo must be different"));
9948
9949 /* rdhi, rdlo and rm must all be different before armv6. */
9950 if ((inst.operands[0].reg == inst.operands[2].reg
c19d1205 9951 || inst.operands[1].reg == inst.operands[2].reg)
682b27ad 9952 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
c19d1205
ZW
9953 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
9954}
b99bd4ef 9955
c19d1205
ZW
9956static void
9957do_nop (void)
9958{
e7495e45
NS
9959 if (inst.operands[0].present
9960 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6k))
c19d1205
ZW
9961 {
9962 /* Architectural NOP hints are CPSR sets with no bits selected. */
9963 inst.instruction &= 0xf0000000;
e7495e45
NS
9964 inst.instruction |= 0x0320f000;
9965 if (inst.operands[0].present)
9966 inst.instruction |= inst.operands[0].imm;
c19d1205 9967 }
b99bd4ef
NC
9968}
9969
c19d1205
ZW
9970/* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
9971 PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
9972 Condition defaults to COND_ALWAYS.
9973 Error if Rd, Rn or Rm are R15. */
b99bd4ef
NC
9974
9975static void
c19d1205 9976do_pkhbt (void)
b99bd4ef 9977{
c19d1205
ZW
9978 inst.instruction |= inst.operands[0].reg << 12;
9979 inst.instruction |= inst.operands[1].reg << 16;
9980 inst.instruction |= inst.operands[2].reg;
9981 if (inst.operands[3].present)
9982 encode_arm_shift (3);
9983}
b99bd4ef 9984
c19d1205 9985/* ARM V6 PKHTB (Argument Parse). */
b99bd4ef 9986
c19d1205
ZW
9987static void
9988do_pkhtb (void)
9989{
9990 if (!inst.operands[3].present)
b99bd4ef 9991 {
c19d1205
ZW
9992 /* If the shift specifier is omitted, turn the instruction
9993 into pkhbt rd, rm, rn. */
9994 inst.instruction &= 0xfff00010;
9995 inst.instruction |= inst.operands[0].reg << 12;
9996 inst.instruction |= inst.operands[1].reg;
9997 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
9998 }
9999 else
10000 {
c19d1205
ZW
10001 inst.instruction |= inst.operands[0].reg << 12;
10002 inst.instruction |= inst.operands[1].reg << 16;
10003 inst.instruction |= inst.operands[2].reg;
10004 encode_arm_shift (3);
b99bd4ef
NC
10005 }
10006}
10007
c19d1205 10008/* ARMv5TE: Preload-Cache
60e5ef9f 10009 MP Extensions: Preload for write
c19d1205 10010
60e5ef9f 10011 PLD(W) <addr_mode>
c19d1205
ZW
10012
10013 Syntactically, like LDR with B=1, W=0, L=1. */
b99bd4ef
NC
10014
10015static void
c19d1205 10016do_pld (void)
b99bd4ef 10017{
c19d1205
ZW
10018 constraint (!inst.operands[0].isreg,
10019 _("'[' expected after PLD mnemonic"));
10020 constraint (inst.operands[0].postind,
10021 _("post-indexed expression used in preload instruction"));
10022 constraint (inst.operands[0].writeback,
10023 _("writeback used in preload instruction"));
10024 constraint (!inst.operands[0].preind,
10025 _("unindexed addressing used in preload instruction"));
c19d1205
ZW
10026 encode_arm_addr_mode_2 (0, /*is_t=*/FALSE);
10027}
b99bd4ef 10028
62b3e311
PB
10029/* ARMv7: PLI <addr_mode> */
10030static void
10031do_pli (void)
10032{
10033 constraint (!inst.operands[0].isreg,
10034 _("'[' expected after PLI mnemonic"));
10035 constraint (inst.operands[0].postind,
10036 _("post-indexed expression used in preload instruction"));
10037 constraint (inst.operands[0].writeback,
10038 _("writeback used in preload instruction"));
10039 constraint (!inst.operands[0].preind,
10040 _("unindexed addressing used in preload instruction"));
10041 encode_arm_addr_mode_2 (0, /*is_t=*/FALSE);
10042 inst.instruction &= ~PRE_INDEX;
10043}
10044
c19d1205
ZW
10045static void
10046do_push_pop (void)
10047{
5e0d7f77
MP
10048 constraint (inst.operands[0].writeback,
10049 _("push/pop do not support {reglist}^"));
c19d1205
ZW
10050 inst.operands[1] = inst.operands[0];
10051 memset (&inst.operands[0], 0, sizeof inst.operands[0]);
10052 inst.operands[0].isreg = 1;
10053 inst.operands[0].writeback = 1;
10054 inst.operands[0].reg = REG_SP;
6530b175 10055 encode_ldmstm (/*from_push_pop_mnem=*/TRUE);
c19d1205 10056}
b99bd4ef 10057
c19d1205
ZW
10058/* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
10059 word at the specified address and the following word
10060 respectively.
10061 Unconditionally executed.
10062 Error if Rn is R15. */
b99bd4ef 10063
c19d1205
ZW
10064static void
10065do_rfe (void)
10066{
10067 inst.instruction |= inst.operands[0].reg << 16;
10068 if (inst.operands[0].writeback)
10069 inst.instruction |= WRITE_BACK;
10070}
b99bd4ef 10071
c19d1205 10072/* ARM V6 ssat (argument parse). */
b99bd4ef 10073
c19d1205
ZW
10074static void
10075do_ssat (void)
10076{
10077 inst.instruction |= inst.operands[0].reg << 12;
10078 inst.instruction |= (inst.operands[1].imm - 1) << 16;
10079 inst.instruction |= inst.operands[2].reg;
b99bd4ef 10080
c19d1205
ZW
10081 if (inst.operands[3].present)
10082 encode_arm_shift (3);
b99bd4ef
NC
10083}
10084
c19d1205 10085/* ARM V6 usat (argument parse). */
b99bd4ef
NC
10086
10087static void
c19d1205 10088do_usat (void)
b99bd4ef 10089{
c19d1205
ZW
10090 inst.instruction |= inst.operands[0].reg << 12;
10091 inst.instruction |= inst.operands[1].imm << 16;
10092 inst.instruction |= inst.operands[2].reg;
b99bd4ef 10093
c19d1205
ZW
10094 if (inst.operands[3].present)
10095 encode_arm_shift (3);
b99bd4ef
NC
10096}
10097
c19d1205 10098/* ARM V6 ssat16 (argument parse). */
09d92015
MM
10099
10100static void
c19d1205 10101do_ssat16 (void)
09d92015 10102{
c19d1205
ZW
10103 inst.instruction |= inst.operands[0].reg << 12;
10104 inst.instruction |= ((inst.operands[1].imm - 1) << 16);
10105 inst.instruction |= inst.operands[2].reg;
09d92015
MM
10106}
10107
c19d1205
ZW
10108static void
10109do_usat16 (void)
a737bd4d 10110{
c19d1205
ZW
10111 inst.instruction |= inst.operands[0].reg << 12;
10112 inst.instruction |= inst.operands[1].imm << 16;
10113 inst.instruction |= inst.operands[2].reg;
10114}
a737bd4d 10115
c19d1205
ZW
10116/* ARM V6 SETEND (argument parse). Sets the E bit in the CPSR while
10117 preserving the other bits.
a737bd4d 10118
c19d1205
ZW
10119 setend <endian_specifier>, where <endian_specifier> is either
10120 BE or LE. */
a737bd4d 10121
c19d1205
ZW
10122static void
10123do_setend (void)
10124{
12e37cbc
MGD
10125 if (warn_on_deprecated
10126 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 10127 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 10128
c19d1205
ZW
10129 if (inst.operands[0].imm)
10130 inst.instruction |= 0x200;
a737bd4d
NC
10131}
10132
10133static void
c19d1205 10134do_shift (void)
a737bd4d 10135{
c19d1205
ZW
10136 unsigned int Rm = (inst.operands[1].present
10137 ? inst.operands[1].reg
10138 : inst.operands[0].reg);
a737bd4d 10139
c19d1205
ZW
10140 inst.instruction |= inst.operands[0].reg << 12;
10141 inst.instruction |= Rm;
10142 if (inst.operands[2].isreg) /* Rd, {Rm,} Rs */
a737bd4d 10143 {
c19d1205
ZW
10144 inst.instruction |= inst.operands[2].reg << 8;
10145 inst.instruction |= SHIFT_BY_REG;
94342ec3
NC
10146 /* PR 12854: Error on extraneous shifts. */
10147 constraint (inst.operands[2].shifted,
10148 _("extraneous shift as part of operand to shift insn"));
a737bd4d
NC
10149 }
10150 else
e2b0ab59 10151 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
a737bd4d
NC
10152}
10153
09d92015 10154static void
3eb17e6b 10155do_smc (void)
09d92015 10156{
e2b0ab59
AV
10157 inst.relocs[0].type = BFD_RELOC_ARM_SMC;
10158 inst.relocs[0].pc_rel = 0;
09d92015
MM
10159}
10160
90ec0d68
MGD
10161static void
10162do_hvc (void)
10163{
e2b0ab59
AV
10164 inst.relocs[0].type = BFD_RELOC_ARM_HVC;
10165 inst.relocs[0].pc_rel = 0;
90ec0d68
MGD
10166}
10167
09d92015 10168static void
c19d1205 10169do_swi (void)
09d92015 10170{
e2b0ab59
AV
10171 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
10172 inst.relocs[0].pc_rel = 0;
09d92015
MM
10173}
10174
ddfded2f
MW
10175static void
10176do_setpan (void)
10177{
10178 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
10179 _("selected processor does not support SETPAN instruction"));
10180
10181 inst.instruction |= ((inst.operands[0].imm & 1) << 9);
10182}
10183
10184static void
10185do_t_setpan (void)
10186{
10187 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
10188 _("selected processor does not support SETPAN instruction"));
10189
10190 inst.instruction |= (inst.operands[0].imm << 3);
10191}
10192
c19d1205
ZW
10193/* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
10194 SMLAxy{cond} Rd,Rm,Rs,Rn
10195 SMLAWy{cond} Rd,Rm,Rs,Rn
10196 Error if any register is R15. */
e16bb312 10197
c19d1205
ZW
10198static void
10199do_smla (void)
e16bb312 10200{
c19d1205
ZW
10201 inst.instruction |= inst.operands[0].reg << 16;
10202 inst.instruction |= inst.operands[1].reg;
10203 inst.instruction |= inst.operands[2].reg << 8;
10204 inst.instruction |= inst.operands[3].reg << 12;
10205}
a737bd4d 10206
c19d1205
ZW
10207/* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
10208 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
10209 Error if any register is R15.
10210 Warning if Rdlo == Rdhi. */
a737bd4d 10211
c19d1205
ZW
10212static void
10213do_smlal (void)
10214{
10215 inst.instruction |= inst.operands[0].reg << 12;
10216 inst.instruction |= inst.operands[1].reg << 16;
10217 inst.instruction |= inst.operands[2].reg;
10218 inst.instruction |= inst.operands[3].reg << 8;
a737bd4d 10219
c19d1205
ZW
10220 if (inst.operands[0].reg == inst.operands[1].reg)
10221 as_tsktsk (_("rdhi and rdlo must be different"));
10222}
a737bd4d 10223
c19d1205
ZW
10224/* ARM V5E (El Segundo) signed-multiply (argument parse)
10225 SMULxy{cond} Rd,Rm,Rs
10226 Error if any register is R15. */
a737bd4d 10227
c19d1205
ZW
10228static void
10229do_smul (void)
10230{
10231 inst.instruction |= inst.operands[0].reg << 16;
10232 inst.instruction |= inst.operands[1].reg;
10233 inst.instruction |= inst.operands[2].reg << 8;
10234}
a737bd4d 10235
b6702015
PB
10236/* ARM V6 srs (argument parse). The variable fields in the encoding are
10237 the same for both ARM and Thumb-2. */
a737bd4d 10238
c19d1205
ZW
10239static void
10240do_srs (void)
10241{
b6702015
PB
10242 int reg;
10243
10244 if (inst.operands[0].present)
10245 {
10246 reg = inst.operands[0].reg;
fdfde340 10247 constraint (reg != REG_SP, _("SRS base register must be r13"));
b6702015
PB
10248 }
10249 else
fdfde340 10250 reg = REG_SP;
b6702015
PB
10251
10252 inst.instruction |= reg << 16;
10253 inst.instruction |= inst.operands[1].imm;
10254 if (inst.operands[0].writeback || inst.operands[1].writeback)
c19d1205
ZW
10255 inst.instruction |= WRITE_BACK;
10256}
a737bd4d 10257
c19d1205 10258/* ARM V6 strex (argument parse). */
a737bd4d 10259
c19d1205
ZW
10260static void
10261do_strex (void)
10262{
10263 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
10264 || inst.operands[2].postind || inst.operands[2].writeback
10265 || inst.operands[2].immisreg || inst.operands[2].shifted
01cfc07f
NC
10266 || inst.operands[2].negative
10267 /* See comment in do_ldrex(). */
10268 || (inst.operands[2].reg == REG_PC),
10269 BAD_ADDR_MODE);
a737bd4d 10270
c19d1205
ZW
10271 constraint (inst.operands[0].reg == inst.operands[1].reg
10272 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
a737bd4d 10273
e2b0ab59
AV
10274 constraint (inst.relocs[0].exp.X_op != O_constant
10275 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 10276 _("offset must be zero in ARM encoding"));
a737bd4d 10277
c19d1205
ZW
10278 inst.instruction |= inst.operands[0].reg << 12;
10279 inst.instruction |= inst.operands[1].reg;
10280 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 10281 inst.relocs[0].type = BFD_RELOC_UNUSED;
e16bb312
NC
10282}
10283
877807f8
NC
10284static void
10285do_t_strexbh (void)
10286{
10287 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
10288 || inst.operands[2].postind || inst.operands[2].writeback
10289 || inst.operands[2].immisreg || inst.operands[2].shifted
10290 || inst.operands[2].negative,
10291 BAD_ADDR_MODE);
10292
10293 constraint (inst.operands[0].reg == inst.operands[1].reg
10294 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10295
10296 do_rm_rd_rn ();
10297}
10298
e16bb312 10299static void
c19d1205 10300do_strexd (void)
e16bb312 10301{
c19d1205
ZW
10302 constraint (inst.operands[1].reg % 2 != 0,
10303 _("even register required"));
10304 constraint (inst.operands[2].present
10305 && inst.operands[2].reg != inst.operands[1].reg + 1,
10306 _("can only store two consecutive registers"));
10307 /* If op 2 were present and equal to PC, this function wouldn't
10308 have been called in the first place. */
10309 constraint (inst.operands[1].reg == REG_LR, _("r14 not allowed here"));
e16bb312 10310
c19d1205
ZW
10311 constraint (inst.operands[0].reg == inst.operands[1].reg
10312 || inst.operands[0].reg == inst.operands[1].reg + 1
10313 || inst.operands[0].reg == inst.operands[3].reg,
10314 BAD_OVERLAP);
e16bb312 10315
c19d1205
ZW
10316 inst.instruction |= inst.operands[0].reg << 12;
10317 inst.instruction |= inst.operands[1].reg;
10318 inst.instruction |= inst.operands[3].reg << 16;
e16bb312
NC
10319}
10320
9eb6c0f1
MGD
10321/* ARM V8 STRL. */
10322static void
4b8c8c02 10323do_stlex (void)
9eb6c0f1
MGD
10324{
10325 constraint (inst.operands[0].reg == inst.operands[1].reg
10326 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10327
10328 do_rd_rm_rn ();
10329}
10330
10331static void
4b8c8c02 10332do_t_stlex (void)
9eb6c0f1
MGD
10333{
10334 constraint (inst.operands[0].reg == inst.operands[1].reg
10335 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10336
10337 do_rm_rd_rn ();
10338}
10339
c19d1205
ZW
10340/* ARM V6 SXTAH extracts a 16-bit value from a register, sign
10341 extends it to 32-bits, and adds the result to a value in another
10342 register. You can specify a rotation by 0, 8, 16, or 24 bits
10343 before extracting the 16-bit value.
10344 SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
10345 Condition defaults to COND_ALWAYS.
10346 Error if any register uses R15. */
10347
e16bb312 10348static void
c19d1205 10349do_sxtah (void)
e16bb312 10350{
c19d1205
ZW
10351 inst.instruction |= inst.operands[0].reg << 12;
10352 inst.instruction |= inst.operands[1].reg << 16;
10353 inst.instruction |= inst.operands[2].reg;
10354 inst.instruction |= inst.operands[3].imm << 10;
10355}
e16bb312 10356
c19d1205 10357/* ARM V6 SXTH.
e16bb312 10358
c19d1205
ZW
10359 SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
10360 Condition defaults to COND_ALWAYS.
10361 Error if any register uses R15. */
e16bb312
NC
10362
10363static void
c19d1205 10364do_sxth (void)
e16bb312 10365{
c19d1205
ZW
10366 inst.instruction |= inst.operands[0].reg << 12;
10367 inst.instruction |= inst.operands[1].reg;
10368 inst.instruction |= inst.operands[2].imm << 10;
e16bb312 10369}
c19d1205
ZW
10370\f
10371/* VFP instructions. In a logical order: SP variant first, monad
10372 before dyad, arithmetic then move then load/store. */
e16bb312
NC
10373
10374static void
c19d1205 10375do_vfp_sp_monadic (void)
e16bb312 10376{
57785aa2
AV
10377 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10378 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10379 _(BAD_FPU));
10380
5287ad62
JB
10381 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10382 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
10383}
10384
10385static void
c19d1205 10386do_vfp_sp_dyadic (void)
e16bb312 10387{
5287ad62
JB
10388 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10389 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
10390 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
10391}
10392
10393static void
c19d1205 10394do_vfp_sp_compare_z (void)
e16bb312 10395{
5287ad62 10396 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
e16bb312
NC
10397}
10398
10399static void
c19d1205 10400do_vfp_dp_sp_cvt (void)
e16bb312 10401{
5287ad62
JB
10402 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10403 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
10404}
10405
10406static void
c19d1205 10407do_vfp_sp_dp_cvt (void)
e16bb312 10408{
5287ad62
JB
10409 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10410 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
e16bb312
NC
10411}
10412
10413static void
c19d1205 10414do_vfp_reg_from_sp (void)
e16bb312 10415{
57785aa2
AV
10416 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10417 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10418 _(BAD_FPU));
10419
c19d1205 10420 inst.instruction |= inst.operands[0].reg << 12;
5287ad62 10421 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
e16bb312
NC
10422}
10423
10424static void
c19d1205 10425do_vfp_reg2_from_sp2 (void)
e16bb312 10426{
c19d1205
ZW
10427 constraint (inst.operands[2].imm != 2,
10428 _("only two consecutive VFP SP registers allowed here"));
10429 inst.instruction |= inst.operands[0].reg << 12;
10430 inst.instruction |= inst.operands[1].reg << 16;
5287ad62 10431 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
10432}
10433
10434static void
c19d1205 10435do_vfp_sp_from_reg (void)
e16bb312 10436{
57785aa2
AV
10437 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10438 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10439 _(BAD_FPU));
10440
5287ad62 10441 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sn);
c19d1205 10442 inst.instruction |= inst.operands[1].reg << 12;
e16bb312
NC
10443}
10444
10445static void
c19d1205 10446do_vfp_sp2_from_reg2 (void)
e16bb312 10447{
c19d1205
ZW
10448 constraint (inst.operands[0].imm != 2,
10449 _("only two consecutive VFP SP registers allowed here"));
5287ad62 10450 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sm);
c19d1205
ZW
10451 inst.instruction |= inst.operands[1].reg << 12;
10452 inst.instruction |= inst.operands[2].reg << 16;
e16bb312
NC
10453}
10454
10455static void
c19d1205 10456do_vfp_sp_ldst (void)
e16bb312 10457{
5287ad62 10458 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
c19d1205 10459 encode_arm_cp_address (1, FALSE, TRUE, 0);
e16bb312
NC
10460}
10461
10462static void
c19d1205 10463do_vfp_dp_ldst (void)
e16bb312 10464{
5287ad62 10465 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
c19d1205 10466 encode_arm_cp_address (1, FALSE, TRUE, 0);
e16bb312
NC
10467}
10468
c19d1205 10469
e16bb312 10470static void
c19d1205 10471vfp_sp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 10472{
c19d1205
ZW
10473 if (inst.operands[0].writeback)
10474 inst.instruction |= WRITE_BACK;
10475 else
10476 constraint (ldstm_type != VFP_LDSTMIA,
10477 _("this addressing mode requires base-register writeback"));
10478 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 10479 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sd);
c19d1205 10480 inst.instruction |= inst.operands[1].imm;
e16bb312
NC
10481}
10482
10483static void
c19d1205 10484vfp_dp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 10485{
c19d1205 10486 int count;
e16bb312 10487
c19d1205
ZW
10488 if (inst.operands[0].writeback)
10489 inst.instruction |= WRITE_BACK;
10490 else
10491 constraint (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX,
10492 _("this addressing mode requires base-register writeback"));
e16bb312 10493
c19d1205 10494 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 10495 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
e16bb312 10496
c19d1205
ZW
10497 count = inst.operands[1].imm << 1;
10498 if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
10499 count += 1;
e16bb312 10500
c19d1205 10501 inst.instruction |= count;
e16bb312
NC
10502}
10503
10504static void
c19d1205 10505do_vfp_sp_ldstmia (void)
e16bb312 10506{
c19d1205 10507 vfp_sp_ldstm (VFP_LDSTMIA);
e16bb312
NC
10508}
10509
10510static void
c19d1205 10511do_vfp_sp_ldstmdb (void)
e16bb312 10512{
c19d1205 10513 vfp_sp_ldstm (VFP_LDSTMDB);
e16bb312
NC
10514}
10515
10516static void
c19d1205 10517do_vfp_dp_ldstmia (void)
e16bb312 10518{
c19d1205 10519 vfp_dp_ldstm (VFP_LDSTMIA);
e16bb312
NC
10520}
10521
10522static void
c19d1205 10523do_vfp_dp_ldstmdb (void)
e16bb312 10524{
c19d1205 10525 vfp_dp_ldstm (VFP_LDSTMDB);
e16bb312
NC
10526}
10527
10528static void
c19d1205 10529do_vfp_xp_ldstmia (void)
e16bb312 10530{
c19d1205
ZW
10531 vfp_dp_ldstm (VFP_LDSTMIAX);
10532}
e16bb312 10533
c19d1205
ZW
10534static void
10535do_vfp_xp_ldstmdb (void)
10536{
10537 vfp_dp_ldstm (VFP_LDSTMDBX);
e16bb312 10538}
5287ad62
JB
10539
10540static void
10541do_vfp_dp_rd_rm (void)
10542{
57785aa2
AV
10543 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
10544 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10545 _(BAD_FPU));
10546
5287ad62
JB
10547 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10548 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
10549}
10550
10551static void
10552do_vfp_dp_rn_rd (void)
10553{
10554 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dn);
10555 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10556}
10557
10558static void
10559do_vfp_dp_rd_rn (void)
10560{
10561 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10562 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10563}
10564
10565static void
10566do_vfp_dp_rd_rn_rm (void)
10567{
57785aa2
AV
10568 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
10569 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10570 _(BAD_FPU));
10571
5287ad62
JB
10572 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10573 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10574 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dm);
10575}
10576
10577static void
10578do_vfp_dp_rd (void)
10579{
10580 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10581}
10582
10583static void
10584do_vfp_dp_rm_rd_rn (void)
10585{
57785aa2
AV
10586 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
10587 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10588 _(BAD_FPU));
10589
5287ad62
JB
10590 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dm);
10591 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10592 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dn);
10593}
10594
10595/* VFPv3 instructions. */
10596static void
10597do_vfp_sp_const (void)
10598{
10599 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
00249aaa
PB
10600 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
10601 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
10602}
10603
10604static void
10605do_vfp_dp_const (void)
10606{
10607 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
00249aaa
PB
10608 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
10609 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
10610}
10611
10612static void
10613vfp_conv (int srcsize)
10614{
5f1af56b
MGD
10615 int immbits = srcsize - inst.operands[1].imm;
10616
fa94de6b
RM
10617 if (srcsize == 16 && !(immbits >= 0 && immbits <= srcsize))
10618 {
5f1af56b 10619 /* If srcsize is 16, inst.operands[1].imm must be in the range 0-16.
477330fc 10620 i.e. immbits must be in range 0 - 16. */
5f1af56b
MGD
10621 inst.error = _("immediate value out of range, expected range [0, 16]");
10622 return;
10623 }
fa94de6b 10624 else if (srcsize == 32 && !(immbits >= 0 && immbits < srcsize))
5f1af56b
MGD
10625 {
10626 /* If srcsize is 32, inst.operands[1].imm must be in the range 1-32.
477330fc 10627 i.e. immbits must be in range 0 - 31. */
5f1af56b
MGD
10628 inst.error = _("immediate value out of range, expected range [1, 32]");
10629 return;
10630 }
10631
5287ad62
JB
10632 inst.instruction |= (immbits & 1) << 5;
10633 inst.instruction |= (immbits >> 1);
10634}
10635
10636static void
10637do_vfp_sp_conv_16 (void)
10638{
10639 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10640 vfp_conv (16);
10641}
10642
10643static void
10644do_vfp_dp_conv_16 (void)
10645{
10646 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10647 vfp_conv (16);
10648}
10649
10650static void
10651do_vfp_sp_conv_32 (void)
10652{
10653 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10654 vfp_conv (32);
10655}
10656
10657static void
10658do_vfp_dp_conv_32 (void)
10659{
10660 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10661 vfp_conv (32);
10662}
c19d1205
ZW
10663\f
10664/* FPA instructions. Also in a logical order. */
e16bb312 10665
c19d1205
ZW
10666static void
10667do_fpa_cmp (void)
10668{
10669 inst.instruction |= inst.operands[0].reg << 16;
10670 inst.instruction |= inst.operands[1].reg;
10671}
b99bd4ef
NC
10672
10673static void
c19d1205 10674do_fpa_ldmstm (void)
b99bd4ef 10675{
c19d1205
ZW
10676 inst.instruction |= inst.operands[0].reg << 12;
10677 switch (inst.operands[1].imm)
10678 {
10679 case 1: inst.instruction |= CP_T_X; break;
10680 case 2: inst.instruction |= CP_T_Y; break;
10681 case 3: inst.instruction |= CP_T_Y | CP_T_X; break;
10682 case 4: break;
10683 default: abort ();
10684 }
b99bd4ef 10685
c19d1205
ZW
10686 if (inst.instruction & (PRE_INDEX | INDEX_UP))
10687 {
10688 /* The instruction specified "ea" or "fd", so we can only accept
10689 [Rn]{!}. The instruction does not really support stacking or
10690 unstacking, so we have to emulate these by setting appropriate
10691 bits and offsets. */
e2b0ab59
AV
10692 constraint (inst.relocs[0].exp.X_op != O_constant
10693 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 10694 _("this instruction does not support indexing"));
b99bd4ef 10695
c19d1205 10696 if ((inst.instruction & PRE_INDEX) || inst.operands[2].writeback)
e2b0ab59 10697 inst.relocs[0].exp.X_add_number = 12 * inst.operands[1].imm;
b99bd4ef 10698
c19d1205 10699 if (!(inst.instruction & INDEX_UP))
e2b0ab59 10700 inst.relocs[0].exp.X_add_number = -inst.relocs[0].exp.X_add_number;
b99bd4ef 10701
c19d1205
ZW
10702 if (!(inst.instruction & PRE_INDEX) && inst.operands[2].writeback)
10703 {
10704 inst.operands[2].preind = 0;
10705 inst.operands[2].postind = 1;
10706 }
10707 }
b99bd4ef 10708
c19d1205 10709 encode_arm_cp_address (2, TRUE, TRUE, 0);
b99bd4ef 10710}
c19d1205
ZW
10711\f
10712/* iWMMXt instructions: strictly in alphabetical order. */
b99bd4ef 10713
c19d1205
ZW
10714static void
10715do_iwmmxt_tandorc (void)
10716{
10717 constraint (inst.operands[0].reg != REG_PC, _("only r15 allowed here"));
10718}
b99bd4ef 10719
c19d1205
ZW
10720static void
10721do_iwmmxt_textrc (void)
10722{
10723 inst.instruction |= inst.operands[0].reg << 12;
10724 inst.instruction |= inst.operands[1].imm;
10725}
b99bd4ef
NC
10726
10727static void
c19d1205 10728do_iwmmxt_textrm (void)
b99bd4ef 10729{
c19d1205
ZW
10730 inst.instruction |= inst.operands[0].reg << 12;
10731 inst.instruction |= inst.operands[1].reg << 16;
10732 inst.instruction |= inst.operands[2].imm;
10733}
b99bd4ef 10734
c19d1205
ZW
10735static void
10736do_iwmmxt_tinsr (void)
10737{
10738 inst.instruction |= inst.operands[0].reg << 16;
10739 inst.instruction |= inst.operands[1].reg << 12;
10740 inst.instruction |= inst.operands[2].imm;
10741}
b99bd4ef 10742
c19d1205
ZW
10743static void
10744do_iwmmxt_tmia (void)
10745{
10746 inst.instruction |= inst.operands[0].reg << 5;
10747 inst.instruction |= inst.operands[1].reg;
10748 inst.instruction |= inst.operands[2].reg << 12;
10749}
b99bd4ef 10750
c19d1205
ZW
10751static void
10752do_iwmmxt_waligni (void)
10753{
10754 inst.instruction |= inst.operands[0].reg << 12;
10755 inst.instruction |= inst.operands[1].reg << 16;
10756 inst.instruction |= inst.operands[2].reg;
10757 inst.instruction |= inst.operands[3].imm << 20;
10758}
b99bd4ef 10759
2d447fca
JM
10760static void
10761do_iwmmxt_wmerge (void)
10762{
10763 inst.instruction |= inst.operands[0].reg << 12;
10764 inst.instruction |= inst.operands[1].reg << 16;
10765 inst.instruction |= inst.operands[2].reg;
10766 inst.instruction |= inst.operands[3].imm << 21;
10767}
10768
c19d1205
ZW
10769static void
10770do_iwmmxt_wmov (void)
10771{
10772 /* WMOV rD, rN is an alias for WOR rD, rN, rN. */
10773 inst.instruction |= inst.operands[0].reg << 12;
10774 inst.instruction |= inst.operands[1].reg << 16;
10775 inst.instruction |= inst.operands[1].reg;
10776}
b99bd4ef 10777
c19d1205
ZW
10778static void
10779do_iwmmxt_wldstbh (void)
10780{
8f06b2d8 10781 int reloc;
c19d1205 10782 inst.instruction |= inst.operands[0].reg << 12;
8f06b2d8
PB
10783 if (thumb_mode)
10784 reloc = BFD_RELOC_ARM_T32_CP_OFF_IMM_S2;
10785 else
10786 reloc = BFD_RELOC_ARM_CP_OFF_IMM_S2;
10787 encode_arm_cp_address (1, TRUE, FALSE, reloc);
b99bd4ef
NC
10788}
10789
c19d1205
ZW
10790static void
10791do_iwmmxt_wldstw (void)
10792{
10793 /* RIWR_RIWC clears .isreg for a control register. */
10794 if (!inst.operands[0].isreg)
10795 {
10796 constraint (inst.cond != COND_ALWAYS, BAD_COND);
10797 inst.instruction |= 0xf0000000;
10798 }
b99bd4ef 10799
c19d1205
ZW
10800 inst.instruction |= inst.operands[0].reg << 12;
10801 encode_arm_cp_address (1, TRUE, TRUE, 0);
10802}
b99bd4ef
NC
10803
10804static void
c19d1205 10805do_iwmmxt_wldstd (void)
b99bd4ef 10806{
c19d1205 10807 inst.instruction |= inst.operands[0].reg << 12;
2d447fca
JM
10808 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2)
10809 && inst.operands[1].immisreg)
10810 {
10811 inst.instruction &= ~0x1a000ff;
eff0bc54 10812 inst.instruction |= (0xfU << 28);
2d447fca
JM
10813 if (inst.operands[1].preind)
10814 inst.instruction |= PRE_INDEX;
10815 if (!inst.operands[1].negative)
10816 inst.instruction |= INDEX_UP;
10817 if (inst.operands[1].writeback)
10818 inst.instruction |= WRITE_BACK;
10819 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 10820 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
2d447fca
JM
10821 inst.instruction |= inst.operands[1].imm;
10822 }
10823 else
10824 encode_arm_cp_address (1, TRUE, FALSE, 0);
c19d1205 10825}
b99bd4ef 10826
c19d1205
ZW
10827static void
10828do_iwmmxt_wshufh (void)
10829{
10830 inst.instruction |= inst.operands[0].reg << 12;
10831 inst.instruction |= inst.operands[1].reg << 16;
10832 inst.instruction |= ((inst.operands[2].imm & 0xf0) << 16);
10833 inst.instruction |= (inst.operands[2].imm & 0x0f);
10834}
b99bd4ef 10835
c19d1205
ZW
10836static void
10837do_iwmmxt_wzero (void)
10838{
10839 /* WZERO reg is an alias for WANDN reg, reg, reg. */
10840 inst.instruction |= inst.operands[0].reg;
10841 inst.instruction |= inst.operands[0].reg << 12;
10842 inst.instruction |= inst.operands[0].reg << 16;
10843}
2d447fca
JM
10844
10845static void
10846do_iwmmxt_wrwrwr_or_imm5 (void)
10847{
10848 if (inst.operands[2].isreg)
10849 do_rd_rn_rm ();
10850 else {
10851 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2),
10852 _("immediate operand requires iWMMXt2"));
10853 do_rd_rn ();
10854 if (inst.operands[2].imm == 0)
10855 {
10856 switch ((inst.instruction >> 20) & 0xf)
10857 {
10858 case 4:
10859 case 5:
10860 case 6:
5f4273c7 10861 case 7:
2d447fca
JM
10862 /* w...h wrd, wrn, #0 -> wrorh wrd, wrn, #16. */
10863 inst.operands[2].imm = 16;
10864 inst.instruction = (inst.instruction & 0xff0fffff) | (0x7 << 20);
10865 break;
10866 case 8:
10867 case 9:
10868 case 10:
10869 case 11:
10870 /* w...w wrd, wrn, #0 -> wrorw wrd, wrn, #32. */
10871 inst.operands[2].imm = 32;
10872 inst.instruction = (inst.instruction & 0xff0fffff) | (0xb << 20);
10873 break;
10874 case 12:
10875 case 13:
10876 case 14:
10877 case 15:
10878 {
10879 /* w...d wrd, wrn, #0 -> wor wrd, wrn, wrn. */
10880 unsigned long wrn;
10881 wrn = (inst.instruction >> 16) & 0xf;
10882 inst.instruction &= 0xff0fff0f;
10883 inst.instruction |= wrn;
10884 /* Bail out here; the instruction is now assembled. */
10885 return;
10886 }
10887 }
10888 }
10889 /* Map 32 -> 0, etc. */
10890 inst.operands[2].imm &= 0x1f;
eff0bc54 10891 inst.instruction |= (0xfU << 28) | ((inst.operands[2].imm & 0x10) << 4) | (inst.operands[2].imm & 0xf);
2d447fca
JM
10892 }
10893}
c19d1205
ZW
10894\f
10895/* Cirrus Maverick instructions. Simple 2-, 3-, and 4-register
10896 operations first, then control, shift, and load/store. */
b99bd4ef 10897
c19d1205 10898/* Insns like "foo X,Y,Z". */
b99bd4ef 10899
c19d1205
ZW
10900static void
10901do_mav_triple (void)
10902{
10903 inst.instruction |= inst.operands[0].reg << 16;
10904 inst.instruction |= inst.operands[1].reg;
10905 inst.instruction |= inst.operands[2].reg << 12;
10906}
b99bd4ef 10907
c19d1205
ZW
10908/* Insns like "foo W,X,Y,Z".
10909 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
a737bd4d 10910
c19d1205
ZW
10911static void
10912do_mav_quad (void)
10913{
10914 inst.instruction |= inst.operands[0].reg << 5;
10915 inst.instruction |= inst.operands[1].reg << 12;
10916 inst.instruction |= inst.operands[2].reg << 16;
10917 inst.instruction |= inst.operands[3].reg;
a737bd4d
NC
10918}
10919
c19d1205
ZW
10920/* cfmvsc32<cond> DSPSC,MVDX[15:0]. */
10921static void
10922do_mav_dspsc (void)
a737bd4d 10923{
c19d1205
ZW
10924 inst.instruction |= inst.operands[1].reg << 12;
10925}
a737bd4d 10926
c19d1205
ZW
10927/* Maverick shift immediate instructions.
10928 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
10929 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
a737bd4d 10930
c19d1205
ZW
10931static void
10932do_mav_shift (void)
10933{
10934 int imm = inst.operands[2].imm;
a737bd4d 10935
c19d1205
ZW
10936 inst.instruction |= inst.operands[0].reg << 12;
10937 inst.instruction |= inst.operands[1].reg << 16;
a737bd4d 10938
c19d1205
ZW
10939 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
10940 Bits 5-7 of the insn should have bits 4-6 of the immediate.
10941 Bit 4 should be 0. */
10942 imm = (imm & 0xf) | ((imm & 0x70) << 1);
a737bd4d 10943
c19d1205
ZW
10944 inst.instruction |= imm;
10945}
10946\f
10947/* XScale instructions. Also sorted arithmetic before move. */
a737bd4d 10948
c19d1205
ZW
10949/* Xscale multiply-accumulate (argument parse)
10950 MIAcc acc0,Rm,Rs
10951 MIAPHcc acc0,Rm,Rs
10952 MIAxycc acc0,Rm,Rs. */
a737bd4d 10953
c19d1205
ZW
10954static void
10955do_xsc_mia (void)
10956{
10957 inst.instruction |= inst.operands[1].reg;
10958 inst.instruction |= inst.operands[2].reg << 12;
10959}
a737bd4d 10960
c19d1205 10961/* Xscale move-accumulator-register (argument parse)
a737bd4d 10962
c19d1205 10963 MARcc acc0,RdLo,RdHi. */
b99bd4ef 10964
c19d1205
ZW
10965static void
10966do_xsc_mar (void)
10967{
10968 inst.instruction |= inst.operands[1].reg << 12;
10969 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
10970}
10971
c19d1205 10972/* Xscale move-register-accumulator (argument parse)
b99bd4ef 10973
c19d1205 10974 MRAcc RdLo,RdHi,acc0. */
b99bd4ef
NC
10975
10976static void
c19d1205 10977do_xsc_mra (void)
b99bd4ef 10978{
c19d1205
ZW
10979 constraint (inst.operands[0].reg == inst.operands[1].reg, BAD_OVERLAP);
10980 inst.instruction |= inst.operands[0].reg << 12;
10981 inst.instruction |= inst.operands[1].reg << 16;
10982}
10983\f
10984/* Encoding functions relevant only to Thumb. */
b99bd4ef 10985
c19d1205
ZW
10986/* inst.operands[i] is a shifted-register operand; encode
10987 it into inst.instruction in the format used by Thumb32. */
10988
10989static void
10990encode_thumb32_shifted_operand (int i)
10991{
e2b0ab59 10992 unsigned int value = inst.relocs[0].exp.X_add_number;
c19d1205 10993 unsigned int shift = inst.operands[i].shift_kind;
b99bd4ef 10994
9c3c69f2
PB
10995 constraint (inst.operands[i].immisreg,
10996 _("shift by register not allowed in thumb mode"));
c19d1205
ZW
10997 inst.instruction |= inst.operands[i].reg;
10998 if (shift == SHIFT_RRX)
10999 inst.instruction |= SHIFT_ROR << 4;
11000 else
b99bd4ef 11001 {
e2b0ab59 11002 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
11003 _("expression too complex"));
11004
11005 constraint (value > 32
11006 || (value == 32 && (shift == SHIFT_LSL
11007 || shift == SHIFT_ROR)),
11008 _("shift expression is too large"));
11009
11010 if (value == 0)
11011 shift = SHIFT_LSL;
11012 else if (value == 32)
11013 value = 0;
11014
11015 inst.instruction |= shift << 4;
11016 inst.instruction |= (value & 0x1c) << 10;
11017 inst.instruction |= (value & 0x03) << 6;
b99bd4ef 11018 }
c19d1205 11019}
b99bd4ef 11020
b99bd4ef 11021
c19d1205
ZW
11022/* inst.operands[i] was set up by parse_address. Encode it into a
11023 Thumb32 format load or store instruction. Reject forms that cannot
11024 be used with such instructions. If is_t is true, reject forms that
11025 cannot be used with a T instruction; if is_d is true, reject forms
5be8be5d
DG
11026 that cannot be used with a D instruction. If it is a store insn,
11027 reject PC in Rn. */
b99bd4ef 11028
c19d1205
ZW
11029static void
11030encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
11031{
5be8be5d 11032 const bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
c19d1205
ZW
11033
11034 constraint (!inst.operands[i].isreg,
53365c0d 11035 _("Instruction does not support =N addresses"));
b99bd4ef 11036
c19d1205
ZW
11037 inst.instruction |= inst.operands[i].reg << 16;
11038 if (inst.operands[i].immisreg)
b99bd4ef 11039 {
5be8be5d 11040 constraint (is_pc, BAD_PC_ADDRESSING);
c19d1205
ZW
11041 constraint (is_t || is_d, _("cannot use register index with this instruction"));
11042 constraint (inst.operands[i].negative,
11043 _("Thumb does not support negative register indexing"));
11044 constraint (inst.operands[i].postind,
11045 _("Thumb does not support register post-indexing"));
11046 constraint (inst.operands[i].writeback,
11047 _("Thumb does not support register indexing with writeback"));
11048 constraint (inst.operands[i].shifted && inst.operands[i].shift_kind != SHIFT_LSL,
11049 _("Thumb supports only LSL in shifted register indexing"));
b99bd4ef 11050
f40d1643 11051 inst.instruction |= inst.operands[i].imm;
c19d1205 11052 if (inst.operands[i].shifted)
b99bd4ef 11053 {
e2b0ab59 11054 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 11055 _("expression too complex"));
e2b0ab59
AV
11056 constraint (inst.relocs[0].exp.X_add_number < 0
11057 || inst.relocs[0].exp.X_add_number > 3,
c19d1205 11058 _("shift out of range"));
e2b0ab59 11059 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
c19d1205 11060 }
e2b0ab59 11061 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205
ZW
11062 }
11063 else if (inst.operands[i].preind)
11064 {
5be8be5d 11065 constraint (is_pc && inst.operands[i].writeback, BAD_PC_WRITEBACK);
f40d1643 11066 constraint (is_t && inst.operands[i].writeback,
c19d1205 11067 _("cannot use writeback with this instruction"));
4755303e
WN
11068 constraint (is_pc && ((inst.instruction & THUMB2_LOAD_BIT) == 0),
11069 BAD_PC_ADDRESSING);
c19d1205
ZW
11070
11071 if (is_d)
11072 {
11073 inst.instruction |= 0x01000000;
11074 if (inst.operands[i].writeback)
11075 inst.instruction |= 0x00200000;
b99bd4ef 11076 }
c19d1205 11077 else
b99bd4ef 11078 {
c19d1205
ZW
11079 inst.instruction |= 0x00000c00;
11080 if (inst.operands[i].writeback)
11081 inst.instruction |= 0x00000100;
b99bd4ef 11082 }
e2b0ab59 11083 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
b99bd4ef 11084 }
c19d1205 11085 else if (inst.operands[i].postind)
b99bd4ef 11086 {
9c2799c2 11087 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
11088 constraint (is_pc, _("cannot use post-indexing with PC-relative addressing"));
11089 constraint (is_t, _("cannot use post-indexing with this instruction"));
11090
11091 if (is_d)
11092 inst.instruction |= 0x00200000;
11093 else
11094 inst.instruction |= 0x00000900;
e2b0ab59 11095 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
c19d1205
ZW
11096 }
11097 else /* unindexed - only for coprocessor */
11098 inst.error = _("instruction does not accept unindexed addressing");
11099}
11100
11101/* Table of Thumb instructions which exist in both 16- and 32-bit
11102 encodings (the latter only in post-V6T2 cores). The index is the
11103 value used in the insns table below. When there is more than one
11104 possible 16-bit encoding for the instruction, this table always
0110f2b8
PB
11105 holds variant (1).
11106 Also contains several pseudo-instructions used during relaxation. */
c19d1205 11107#define T16_32_TAB \
21d799b5
NC
11108 X(_adc, 4140, eb400000), \
11109 X(_adcs, 4140, eb500000), \
11110 X(_add, 1c00, eb000000), \
11111 X(_adds, 1c00, eb100000), \
11112 X(_addi, 0000, f1000000), \
11113 X(_addis, 0000, f1100000), \
11114 X(_add_pc,000f, f20f0000), \
11115 X(_add_sp,000d, f10d0000), \
11116 X(_adr, 000f, f20f0000), \
11117 X(_and, 4000, ea000000), \
11118 X(_ands, 4000, ea100000), \
11119 X(_asr, 1000, fa40f000), \
11120 X(_asrs, 1000, fa50f000), \
11121 X(_b, e000, f000b000), \
11122 X(_bcond, d000, f0008000), \
4389b29a 11123 X(_bf, 0000, f040e001), \
f6b2b12d 11124 X(_bfcsel,0000, f000e001), \
f1c7f421 11125 X(_bfx, 0000, f060e001), \
65d1bc05 11126 X(_bfl, 0000, f000c001), \
f1c7f421 11127 X(_bflx, 0000, f070e001), \
21d799b5
NC
11128 X(_bic, 4380, ea200000), \
11129 X(_bics, 4380, ea300000), \
11130 X(_cmn, 42c0, eb100f00), \
11131 X(_cmp, 2800, ebb00f00), \
11132 X(_cpsie, b660, f3af8400), \
11133 X(_cpsid, b670, f3af8600), \
11134 X(_cpy, 4600, ea4f0000), \
11135 X(_dec_sp,80dd, f1ad0d00), \
60f993ce 11136 X(_dls, 0000, f040e001), \
1f6234a3 11137 X(_dlstp, 0000, f000e001), \
21d799b5
NC
11138 X(_eor, 4040, ea800000), \
11139 X(_eors, 4040, ea900000), \
11140 X(_inc_sp,00dd, f10d0d00), \
1f6234a3 11141 X(_lctp, 0000, f00fe001), \
21d799b5
NC
11142 X(_ldmia, c800, e8900000), \
11143 X(_ldr, 6800, f8500000), \
11144 X(_ldrb, 7800, f8100000), \
11145 X(_ldrh, 8800, f8300000), \
11146 X(_ldrsb, 5600, f9100000), \
11147 X(_ldrsh, 5e00, f9300000), \
11148 X(_ldr_pc,4800, f85f0000), \
11149 X(_ldr_pc2,4800, f85f0000), \
11150 X(_ldr_sp,9800, f85d0000), \
60f993ce 11151 X(_le, 0000, f00fc001), \
1f6234a3 11152 X(_letp, 0000, f01fc001), \
21d799b5
NC
11153 X(_lsl, 0000, fa00f000), \
11154 X(_lsls, 0000, fa10f000), \
11155 X(_lsr, 0800, fa20f000), \
11156 X(_lsrs, 0800, fa30f000), \
11157 X(_mov, 2000, ea4f0000), \
11158 X(_movs, 2000, ea5f0000), \
11159 X(_mul, 4340, fb00f000), \
11160 X(_muls, 4340, ffffffff), /* no 32b muls */ \
11161 X(_mvn, 43c0, ea6f0000), \
11162 X(_mvns, 43c0, ea7f0000), \
11163 X(_neg, 4240, f1c00000), /* rsb #0 */ \
11164 X(_negs, 4240, f1d00000), /* rsbs #0 */ \
11165 X(_orr, 4300, ea400000), \
11166 X(_orrs, 4300, ea500000), \
11167 X(_pop, bc00, e8bd0000), /* ldmia sp!,... */ \
11168 X(_push, b400, e92d0000), /* stmdb sp!,... */ \
11169 X(_rev, ba00, fa90f080), \
11170 X(_rev16, ba40, fa90f090), \
11171 X(_revsh, bac0, fa90f0b0), \
11172 X(_ror, 41c0, fa60f000), \
11173 X(_rors, 41c0, fa70f000), \
11174 X(_sbc, 4180, eb600000), \
11175 X(_sbcs, 4180, eb700000), \
11176 X(_stmia, c000, e8800000), \
11177 X(_str, 6000, f8400000), \
11178 X(_strb, 7000, f8000000), \
11179 X(_strh, 8000, f8200000), \
11180 X(_str_sp,9000, f84d0000), \
11181 X(_sub, 1e00, eba00000), \
11182 X(_subs, 1e00, ebb00000), \
11183 X(_subi, 8000, f1a00000), \
11184 X(_subis, 8000, f1b00000), \
11185 X(_sxtb, b240, fa4ff080), \
11186 X(_sxth, b200, fa0ff080), \
11187 X(_tst, 4200, ea100f00), \
11188 X(_uxtb, b2c0, fa5ff080), \
11189 X(_uxth, b280, fa1ff080), \
11190 X(_nop, bf00, f3af8000), \
11191 X(_yield, bf10, f3af8001), \
11192 X(_wfe, bf20, f3af8002), \
11193 X(_wfi, bf30, f3af8003), \
60f993ce 11194 X(_wls, 0000, f040c001), \
1f6234a3 11195 X(_wlstp, 0000, f000c001), \
53c4b28b 11196 X(_sev, bf40, f3af8004), \
74db7efb
NC
11197 X(_sevl, bf50, f3af8005), \
11198 X(_udf, de00, f7f0a000)
c19d1205
ZW
11199
11200/* To catch errors in encoding functions, the codes are all offset by
11201 0xF800, putting them in one of the 32-bit prefix ranges, ergo undefined
11202 as 16-bit instructions. */
21d799b5 11203#define X(a,b,c) T_MNEM##a
c19d1205
ZW
11204enum t16_32_codes { T16_32_OFFSET = 0xF7FF, T16_32_TAB };
11205#undef X
11206
11207#define X(a,b,c) 0x##b
11208static const unsigned short thumb_op16[] = { T16_32_TAB };
11209#define THUMB_OP16(n) (thumb_op16[(n) - (T16_32_OFFSET + 1)])
11210#undef X
11211
11212#define X(a,b,c) 0x##c
11213static const unsigned int thumb_op32[] = { T16_32_TAB };
c921be7d
NC
11214#define THUMB_OP32(n) (thumb_op32[(n) - (T16_32_OFFSET + 1)])
11215#define THUMB_SETS_FLAGS(n) (THUMB_OP32 (n) & 0x00100000)
c19d1205
ZW
11216#undef X
11217#undef T16_32_TAB
11218
11219/* Thumb instruction encoders, in alphabetical order. */
11220
92e90b6e 11221/* ADDW or SUBW. */
c921be7d 11222
92e90b6e
PB
11223static void
11224do_t_add_sub_w (void)
11225{
11226 int Rd, Rn;
11227
11228 Rd = inst.operands[0].reg;
11229 Rn = inst.operands[1].reg;
11230
539d4391
NC
11231 /* If Rn is REG_PC, this is ADR; if Rn is REG_SP, then this
11232 is the SP-{plus,minus}-immediate form of the instruction. */
11233 if (Rn == REG_SP)
11234 constraint (Rd == REG_PC, BAD_PC);
11235 else
11236 reject_bad_reg (Rd);
fdfde340 11237
92e90b6e 11238 inst.instruction |= (Rn << 16) | (Rd << 8);
e2b0ab59 11239 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
92e90b6e
PB
11240}
11241
c19d1205 11242/* Parse an add or subtract instruction. We get here with inst.instruction
33eaf5de 11243 equaling any of THUMB_OPCODE_add, adds, sub, or subs. */
c19d1205
ZW
11244
11245static void
11246do_t_add_sub (void)
11247{
11248 int Rd, Rs, Rn;
11249
11250 Rd = inst.operands[0].reg;
11251 Rs = (inst.operands[1].present
11252 ? inst.operands[1].reg /* Rd, Rs, foo */
11253 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11254
e07e6e58 11255 if (Rd == REG_PC)
5ee91343 11256 set_pred_insn_type_last ();
e07e6e58 11257
c19d1205
ZW
11258 if (unified_syntax)
11259 {
0110f2b8
PB
11260 bfd_boolean flags;
11261 bfd_boolean narrow;
11262 int opcode;
11263
11264 flags = (inst.instruction == T_MNEM_adds
11265 || inst.instruction == T_MNEM_subs);
11266 if (flags)
5ee91343 11267 narrow = !in_pred_block ();
0110f2b8 11268 else
5ee91343 11269 narrow = in_pred_block ();
c19d1205 11270 if (!inst.operands[2].isreg)
b99bd4ef 11271 {
16805f35
PB
11272 int add;
11273
5c8ed6a4
JW
11274 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
11275 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340 11276
16805f35
PB
11277 add = (inst.instruction == T_MNEM_add
11278 || inst.instruction == T_MNEM_adds);
0110f2b8
PB
11279 opcode = 0;
11280 if (inst.size_req != 4)
11281 {
0110f2b8 11282 /* Attempt to use a narrow opcode, with relaxation if
477330fc 11283 appropriate. */
0110f2b8
PB
11284 if (Rd == REG_SP && Rs == REG_SP && !flags)
11285 opcode = add ? T_MNEM_inc_sp : T_MNEM_dec_sp;
11286 else if (Rd <= 7 && Rs == REG_SP && add && !flags)
11287 opcode = T_MNEM_add_sp;
11288 else if (Rd <= 7 && Rs == REG_PC && add && !flags)
11289 opcode = T_MNEM_add_pc;
11290 else if (Rd <= 7 && Rs <= 7 && narrow)
11291 {
11292 if (flags)
11293 opcode = add ? T_MNEM_addis : T_MNEM_subis;
11294 else
11295 opcode = add ? T_MNEM_addi : T_MNEM_subi;
11296 }
11297 if (opcode)
11298 {
11299 inst.instruction = THUMB_OP16(opcode);
11300 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59
AV
11301 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
11302 || (inst.relocs[0].type
11303 > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC))
a9f02af8
MG
11304 {
11305 if (inst.size_req == 2)
e2b0ab59 11306 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
a9f02af8
MG
11307 else
11308 inst.relax = opcode;
11309 }
0110f2b8
PB
11310 }
11311 else
11312 constraint (inst.size_req == 2, BAD_HIREG);
11313 }
11314 if (inst.size_req == 4
11315 || (inst.size_req != 2 && !opcode))
11316 {
e2b0ab59
AV
11317 constraint ((inst.relocs[0].type
11318 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
11319 && (inst.relocs[0].type
11320 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8 11321 THUMB1_RELOC_ONLY);
efd81785
PB
11322 if (Rd == REG_PC)
11323 {
fdfde340 11324 constraint (add, BAD_PC);
efd81785
PB
11325 constraint (Rs != REG_LR || inst.instruction != T_MNEM_subs,
11326 _("only SUBS PC, LR, #const allowed"));
e2b0ab59 11327 constraint (inst.relocs[0].exp.X_op != O_constant,
efd81785 11328 _("expression too complex"));
e2b0ab59
AV
11329 constraint (inst.relocs[0].exp.X_add_number < 0
11330 || inst.relocs[0].exp.X_add_number > 0xff,
efd81785
PB
11331 _("immediate value out of range"));
11332 inst.instruction = T2_SUBS_PC_LR
e2b0ab59
AV
11333 | inst.relocs[0].exp.X_add_number;
11334 inst.relocs[0].type = BFD_RELOC_UNUSED;
efd81785
PB
11335 return;
11336 }
11337 else if (Rs == REG_PC)
16805f35
PB
11338 {
11339 /* Always use addw/subw. */
11340 inst.instruction = add ? 0xf20f0000 : 0xf2af0000;
e2b0ab59 11341 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
16805f35
PB
11342 }
11343 else
11344 {
11345 inst.instruction = THUMB_OP32 (inst.instruction);
11346 inst.instruction = (inst.instruction & 0xe1ffffff)
11347 | 0x10000000;
11348 if (flags)
e2b0ab59 11349 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
16805f35 11350 else
e2b0ab59 11351 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_IMM;
16805f35 11352 }
dc4503c6
PB
11353 inst.instruction |= Rd << 8;
11354 inst.instruction |= Rs << 16;
0110f2b8 11355 }
b99bd4ef 11356 }
c19d1205
ZW
11357 else
11358 {
e2b0ab59 11359 unsigned int value = inst.relocs[0].exp.X_add_number;
5f4cb198
NC
11360 unsigned int shift = inst.operands[2].shift_kind;
11361
c19d1205
ZW
11362 Rn = inst.operands[2].reg;
11363 /* See if we can do this with a 16-bit instruction. */
11364 if (!inst.operands[2].shifted && inst.size_req != 4)
11365 {
e27ec89e
PB
11366 if (Rd > 7 || Rs > 7 || Rn > 7)
11367 narrow = FALSE;
11368
11369 if (narrow)
c19d1205 11370 {
e27ec89e
PB
11371 inst.instruction = ((inst.instruction == T_MNEM_adds
11372 || inst.instruction == T_MNEM_add)
c19d1205
ZW
11373 ? T_OPCODE_ADD_R3
11374 : T_OPCODE_SUB_R3);
11375 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
11376 return;
11377 }
b99bd4ef 11378
7e806470 11379 if (inst.instruction == T_MNEM_add && (Rd == Rs || Rd == Rn))
c19d1205 11380 {
7e806470
PB
11381 /* Thumb-1 cores (except v6-M) require at least one high
11382 register in a narrow non flag setting add. */
11383 if (Rd > 7 || Rn > 7
11384 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2)
11385 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_msr))
c19d1205 11386 {
7e806470
PB
11387 if (Rd == Rn)
11388 {
11389 Rn = Rs;
11390 Rs = Rd;
11391 }
c19d1205
ZW
11392 inst.instruction = T_OPCODE_ADD_HI;
11393 inst.instruction |= (Rd & 8) << 4;
11394 inst.instruction |= (Rd & 7);
11395 inst.instruction |= Rn << 3;
11396 return;
11397 }
c19d1205
ZW
11398 }
11399 }
c921be7d 11400
fdfde340 11401 constraint (Rd == REG_PC, BAD_PC);
5c8ed6a4
JW
11402 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
11403 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340
JM
11404 constraint (Rs == REG_PC, BAD_PC);
11405 reject_bad_reg (Rn);
11406
c19d1205
ZW
11407 /* If we get here, it can't be done in 16 bits. */
11408 constraint (inst.operands[2].shifted && inst.operands[2].immisreg,
11409 _("shift must be constant"));
11410 inst.instruction = THUMB_OP32 (inst.instruction);
11411 inst.instruction |= Rd << 8;
11412 inst.instruction |= Rs << 16;
5f4cb198
NC
11413 constraint (Rd == REG_SP && Rs == REG_SP && value > 3,
11414 _("shift value over 3 not allowed in thumb mode"));
11415 constraint (Rd == REG_SP && Rs == REG_SP && shift != SHIFT_LSL,
11416 _("only LSL shift allowed in thumb mode"));
c19d1205
ZW
11417 encode_thumb32_shifted_operand (2);
11418 }
11419 }
11420 else
11421 {
11422 constraint (inst.instruction == T_MNEM_adds
11423 || inst.instruction == T_MNEM_subs,
11424 BAD_THUMB32);
b99bd4ef 11425
c19d1205 11426 if (!inst.operands[2].isreg) /* Rd, Rs, #imm */
b99bd4ef 11427 {
c19d1205
ZW
11428 constraint ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
11429 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC),
11430 BAD_HIREG);
11431
11432 inst.instruction = (inst.instruction == T_MNEM_add
11433 ? 0x0000 : 0x8000);
11434 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59 11435 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
b99bd4ef
NC
11436 return;
11437 }
11438
c19d1205
ZW
11439 Rn = inst.operands[2].reg;
11440 constraint (inst.operands[2].shifted, _("unshifted register required"));
b99bd4ef 11441
c19d1205
ZW
11442 /* We now have Rd, Rs, and Rn set to registers. */
11443 if (Rd > 7 || Rs > 7 || Rn > 7)
b99bd4ef 11444 {
c19d1205
ZW
11445 /* Can't do this for SUB. */
11446 constraint (inst.instruction == T_MNEM_sub, BAD_HIREG);
11447 inst.instruction = T_OPCODE_ADD_HI;
11448 inst.instruction |= (Rd & 8) << 4;
11449 inst.instruction |= (Rd & 7);
11450 if (Rs == Rd)
11451 inst.instruction |= Rn << 3;
11452 else if (Rn == Rd)
11453 inst.instruction |= Rs << 3;
11454 else
11455 constraint (1, _("dest must overlap one source register"));
11456 }
11457 else
11458 {
11459 inst.instruction = (inst.instruction == T_MNEM_add
11460 ? T_OPCODE_ADD_R3 : T_OPCODE_SUB_R3);
11461 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
b99bd4ef 11462 }
b99bd4ef 11463 }
b99bd4ef
NC
11464}
11465
c19d1205
ZW
11466static void
11467do_t_adr (void)
11468{
fdfde340
JM
11469 unsigned Rd;
11470
11471 Rd = inst.operands[0].reg;
11472 reject_bad_reg (Rd);
11473
11474 if (unified_syntax && inst.size_req == 0 && Rd <= 7)
0110f2b8
PB
11475 {
11476 /* Defer to section relaxation. */
11477 inst.relax = inst.instruction;
11478 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 11479 inst.instruction |= Rd << 4;
0110f2b8
PB
11480 }
11481 else if (unified_syntax && inst.size_req != 2)
e9f89963 11482 {
0110f2b8 11483 /* Generate a 32-bit opcode. */
e9f89963 11484 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 11485 inst.instruction |= Rd << 8;
e2b0ab59
AV
11486 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_PC12;
11487 inst.relocs[0].pc_rel = 1;
e9f89963
PB
11488 }
11489 else
11490 {
0110f2b8 11491 /* Generate a 16-bit opcode. */
e9f89963 11492 inst.instruction = THUMB_OP16 (inst.instruction);
e2b0ab59
AV
11493 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
11494 inst.relocs[0].exp.X_add_number -= 4; /* PC relative adjust. */
11495 inst.relocs[0].pc_rel = 1;
fdfde340 11496 inst.instruction |= Rd << 4;
e9f89963 11497 }
52a86f84 11498
e2b0ab59
AV
11499 if (inst.relocs[0].exp.X_op == O_symbol
11500 && inst.relocs[0].exp.X_add_symbol != NULL
11501 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
11502 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
11503 inst.relocs[0].exp.X_add_number += 1;
c19d1205 11504}
b99bd4ef 11505
c19d1205
ZW
11506/* Arithmetic instructions for which there is just one 16-bit
11507 instruction encoding, and it allows only two low registers.
11508 For maximal compatibility with ARM syntax, we allow three register
11509 operands even when Thumb-32 instructions are not available, as long
11510 as the first two are identical. For instance, both "sbc r0,r1" and
11511 "sbc r0,r0,r1" are allowed. */
b99bd4ef 11512static void
c19d1205 11513do_t_arit3 (void)
b99bd4ef 11514{
c19d1205 11515 int Rd, Rs, Rn;
b99bd4ef 11516
c19d1205
ZW
11517 Rd = inst.operands[0].reg;
11518 Rs = (inst.operands[1].present
11519 ? inst.operands[1].reg /* Rd, Rs, foo */
11520 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11521 Rn = inst.operands[2].reg;
b99bd4ef 11522
fdfde340
JM
11523 reject_bad_reg (Rd);
11524 reject_bad_reg (Rs);
11525 if (inst.operands[2].isreg)
11526 reject_bad_reg (Rn);
11527
c19d1205 11528 if (unified_syntax)
b99bd4ef 11529 {
c19d1205
ZW
11530 if (!inst.operands[2].isreg)
11531 {
11532 /* For an immediate, we always generate a 32-bit opcode;
11533 section relaxation will shrink it later if possible. */
11534 inst.instruction = THUMB_OP32 (inst.instruction);
11535 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
11536 inst.instruction |= Rd << 8;
11537 inst.instruction |= Rs << 16;
e2b0ab59 11538 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
c19d1205
ZW
11539 }
11540 else
11541 {
e27ec89e
PB
11542 bfd_boolean narrow;
11543
c19d1205 11544 /* See if we can do this with a 16-bit instruction. */
e27ec89e 11545 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 11546 narrow = !in_pred_block ();
e27ec89e 11547 else
5ee91343 11548 narrow = in_pred_block ();
e27ec89e
PB
11549
11550 if (Rd > 7 || Rn > 7 || Rs > 7)
11551 narrow = FALSE;
11552 if (inst.operands[2].shifted)
11553 narrow = FALSE;
11554 if (inst.size_req == 4)
11555 narrow = FALSE;
11556
11557 if (narrow
c19d1205
ZW
11558 && Rd == Rs)
11559 {
11560 inst.instruction = THUMB_OP16 (inst.instruction);
11561 inst.instruction |= Rd;
11562 inst.instruction |= Rn << 3;
11563 return;
11564 }
b99bd4ef 11565
c19d1205
ZW
11566 /* If we get here, it can't be done in 16 bits. */
11567 constraint (inst.operands[2].shifted
11568 && inst.operands[2].immisreg,
11569 _("shift must be constant"));
11570 inst.instruction = THUMB_OP32 (inst.instruction);
11571 inst.instruction |= Rd << 8;
11572 inst.instruction |= Rs << 16;
11573 encode_thumb32_shifted_operand (2);
11574 }
a737bd4d 11575 }
c19d1205 11576 else
b99bd4ef 11577 {
c19d1205
ZW
11578 /* On its face this is a lie - the instruction does set the
11579 flags. However, the only supported mnemonic in this mode
11580 says it doesn't. */
11581 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 11582
c19d1205
ZW
11583 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
11584 _("unshifted register required"));
11585 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
11586 constraint (Rd != Rs,
11587 _("dest and source1 must be the same register"));
a737bd4d 11588
c19d1205
ZW
11589 inst.instruction = THUMB_OP16 (inst.instruction);
11590 inst.instruction |= Rd;
11591 inst.instruction |= Rn << 3;
b99bd4ef 11592 }
a737bd4d 11593}
b99bd4ef 11594
c19d1205
ZW
11595/* Similarly, but for instructions where the arithmetic operation is
11596 commutative, so we can allow either of them to be different from
11597 the destination operand in a 16-bit instruction. For instance, all
11598 three of "adc r0,r1", "adc r0,r0,r1", and "adc r0,r1,r0" are
11599 accepted. */
11600static void
11601do_t_arit3c (void)
a737bd4d 11602{
c19d1205 11603 int Rd, Rs, Rn;
b99bd4ef 11604
c19d1205
ZW
11605 Rd = inst.operands[0].reg;
11606 Rs = (inst.operands[1].present
11607 ? inst.operands[1].reg /* Rd, Rs, foo */
11608 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11609 Rn = inst.operands[2].reg;
c921be7d 11610
fdfde340
JM
11611 reject_bad_reg (Rd);
11612 reject_bad_reg (Rs);
11613 if (inst.operands[2].isreg)
11614 reject_bad_reg (Rn);
a737bd4d 11615
c19d1205 11616 if (unified_syntax)
a737bd4d 11617 {
c19d1205 11618 if (!inst.operands[2].isreg)
b99bd4ef 11619 {
c19d1205
ZW
11620 /* For an immediate, we always generate a 32-bit opcode;
11621 section relaxation will shrink it later if possible. */
11622 inst.instruction = THUMB_OP32 (inst.instruction);
11623 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
11624 inst.instruction |= Rd << 8;
11625 inst.instruction |= Rs << 16;
e2b0ab59 11626 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 11627 }
c19d1205 11628 else
a737bd4d 11629 {
e27ec89e
PB
11630 bfd_boolean narrow;
11631
c19d1205 11632 /* See if we can do this with a 16-bit instruction. */
e27ec89e 11633 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 11634 narrow = !in_pred_block ();
e27ec89e 11635 else
5ee91343 11636 narrow = in_pred_block ();
e27ec89e
PB
11637
11638 if (Rd > 7 || Rn > 7 || Rs > 7)
11639 narrow = FALSE;
11640 if (inst.operands[2].shifted)
11641 narrow = FALSE;
11642 if (inst.size_req == 4)
11643 narrow = FALSE;
11644
11645 if (narrow)
a737bd4d 11646 {
c19d1205 11647 if (Rd == Rs)
a737bd4d 11648 {
c19d1205
ZW
11649 inst.instruction = THUMB_OP16 (inst.instruction);
11650 inst.instruction |= Rd;
11651 inst.instruction |= Rn << 3;
11652 return;
a737bd4d 11653 }
c19d1205 11654 if (Rd == Rn)
a737bd4d 11655 {
c19d1205
ZW
11656 inst.instruction = THUMB_OP16 (inst.instruction);
11657 inst.instruction |= Rd;
11658 inst.instruction |= Rs << 3;
11659 return;
a737bd4d
NC
11660 }
11661 }
c19d1205
ZW
11662
11663 /* If we get here, it can't be done in 16 bits. */
11664 constraint (inst.operands[2].shifted
11665 && inst.operands[2].immisreg,
11666 _("shift must be constant"));
11667 inst.instruction = THUMB_OP32 (inst.instruction);
11668 inst.instruction |= Rd << 8;
11669 inst.instruction |= Rs << 16;
11670 encode_thumb32_shifted_operand (2);
a737bd4d 11671 }
b99bd4ef 11672 }
c19d1205
ZW
11673 else
11674 {
11675 /* On its face this is a lie - the instruction does set the
11676 flags. However, the only supported mnemonic in this mode
11677 says it doesn't. */
11678 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 11679
c19d1205
ZW
11680 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
11681 _("unshifted register required"));
11682 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
11683
11684 inst.instruction = THUMB_OP16 (inst.instruction);
11685 inst.instruction |= Rd;
11686
11687 if (Rd == Rs)
11688 inst.instruction |= Rn << 3;
11689 else if (Rd == Rn)
11690 inst.instruction |= Rs << 3;
11691 else
11692 constraint (1, _("dest must overlap one source register"));
11693 }
a737bd4d
NC
11694}
11695
c19d1205
ZW
11696static void
11697do_t_bfc (void)
a737bd4d 11698{
fdfde340 11699 unsigned Rd;
c19d1205
ZW
11700 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
11701 constraint (msb > 32, _("bit-field extends past end of register"));
11702 /* The instruction encoding stores the LSB and MSB,
11703 not the LSB and width. */
fdfde340
JM
11704 Rd = inst.operands[0].reg;
11705 reject_bad_reg (Rd);
11706 inst.instruction |= Rd << 8;
c19d1205
ZW
11707 inst.instruction |= (inst.operands[1].imm & 0x1c) << 10;
11708 inst.instruction |= (inst.operands[1].imm & 0x03) << 6;
11709 inst.instruction |= msb - 1;
b99bd4ef
NC
11710}
11711
c19d1205
ZW
11712static void
11713do_t_bfi (void)
b99bd4ef 11714{
fdfde340 11715 int Rd, Rn;
c19d1205 11716 unsigned int msb;
b99bd4ef 11717
fdfde340
JM
11718 Rd = inst.operands[0].reg;
11719 reject_bad_reg (Rd);
11720
c19d1205
ZW
11721 /* #0 in second position is alternative syntax for bfc, which is
11722 the same instruction but with REG_PC in the Rm field. */
11723 if (!inst.operands[1].isreg)
fdfde340
JM
11724 Rn = REG_PC;
11725 else
11726 {
11727 Rn = inst.operands[1].reg;
11728 reject_bad_reg (Rn);
11729 }
b99bd4ef 11730
c19d1205
ZW
11731 msb = inst.operands[2].imm + inst.operands[3].imm;
11732 constraint (msb > 32, _("bit-field extends past end of register"));
11733 /* The instruction encoding stores the LSB and MSB,
11734 not the LSB and width. */
fdfde340
JM
11735 inst.instruction |= Rd << 8;
11736 inst.instruction |= Rn << 16;
c19d1205
ZW
11737 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
11738 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
11739 inst.instruction |= msb - 1;
b99bd4ef
NC
11740}
11741
c19d1205
ZW
11742static void
11743do_t_bfx (void)
b99bd4ef 11744{
fdfde340
JM
11745 unsigned Rd, Rn;
11746
11747 Rd = inst.operands[0].reg;
11748 Rn = inst.operands[1].reg;
11749
11750 reject_bad_reg (Rd);
11751 reject_bad_reg (Rn);
11752
c19d1205
ZW
11753 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
11754 _("bit-field extends past end of register"));
fdfde340
JM
11755 inst.instruction |= Rd << 8;
11756 inst.instruction |= Rn << 16;
c19d1205
ZW
11757 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
11758 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
11759 inst.instruction |= inst.operands[3].imm - 1;
11760}
b99bd4ef 11761
c19d1205
ZW
11762/* ARM V5 Thumb BLX (argument parse)
11763 BLX <target_addr> which is BLX(1)
11764 BLX <Rm> which is BLX(2)
11765 Unfortunately, there are two different opcodes for this mnemonic.
11766 So, the insns[].value is not used, and the code here zaps values
11767 into inst.instruction.
b99bd4ef 11768
c19d1205
ZW
11769 ??? How to take advantage of the additional two bits of displacement
11770 available in Thumb32 mode? Need new relocation? */
b99bd4ef 11771
c19d1205
ZW
11772static void
11773do_t_blx (void)
11774{
5ee91343 11775 set_pred_insn_type_last ();
e07e6e58 11776
c19d1205 11777 if (inst.operands[0].isreg)
fdfde340
JM
11778 {
11779 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
11780 /* We have a register, so this is BLX(2). */
11781 inst.instruction |= inst.operands[0].reg << 3;
11782 }
b99bd4ef
NC
11783 else
11784 {
c19d1205 11785 /* No register. This must be BLX(1). */
2fc8bdac 11786 inst.instruction = 0xf000e800;
0855e32b 11787 encode_branch (BFD_RELOC_THUMB_PCREL_BLX);
b99bd4ef
NC
11788 }
11789}
11790
c19d1205
ZW
11791static void
11792do_t_branch (void)
b99bd4ef 11793{
0110f2b8 11794 int opcode;
dfa9f0d5 11795 int cond;
2fe88214 11796 bfd_reloc_code_real_type reloc;
dfa9f0d5 11797
e07e6e58 11798 cond = inst.cond;
5ee91343 11799 set_pred_insn_type (IF_INSIDE_IT_LAST_INSN);
e07e6e58 11800
5ee91343 11801 if (in_pred_block ())
dfa9f0d5
PB
11802 {
11803 /* Conditional branches inside IT blocks are encoded as unconditional
477330fc 11804 branches. */
dfa9f0d5 11805 cond = COND_ALWAYS;
dfa9f0d5
PB
11806 }
11807 else
11808 cond = inst.cond;
11809
11810 if (cond != COND_ALWAYS)
0110f2b8
PB
11811 opcode = T_MNEM_bcond;
11812 else
11813 opcode = inst.instruction;
11814
12d6b0b7
RS
11815 if (unified_syntax
11816 && (inst.size_req == 4
10960bfb
PB
11817 || (inst.size_req != 2
11818 && (inst.operands[0].hasreloc
e2b0ab59 11819 || inst.relocs[0].exp.X_op == O_constant))))
c19d1205 11820 {
0110f2b8 11821 inst.instruction = THUMB_OP32(opcode);
dfa9f0d5 11822 if (cond == COND_ALWAYS)
9ae92b05 11823 reloc = BFD_RELOC_THUMB_PCREL_BRANCH25;
c19d1205
ZW
11824 else
11825 {
ff8646ee
TP
11826 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2),
11827 _("selected architecture does not support "
11828 "wide conditional branch instruction"));
11829
9c2799c2 11830 gas_assert (cond != 0xF);
dfa9f0d5 11831 inst.instruction |= cond << 22;
9ae92b05 11832 reloc = BFD_RELOC_THUMB_PCREL_BRANCH20;
c19d1205
ZW
11833 }
11834 }
b99bd4ef
NC
11835 else
11836 {
0110f2b8 11837 inst.instruction = THUMB_OP16(opcode);
dfa9f0d5 11838 if (cond == COND_ALWAYS)
9ae92b05 11839 reloc = BFD_RELOC_THUMB_PCREL_BRANCH12;
c19d1205 11840 else
b99bd4ef 11841 {
dfa9f0d5 11842 inst.instruction |= cond << 8;
9ae92b05 11843 reloc = BFD_RELOC_THUMB_PCREL_BRANCH9;
b99bd4ef 11844 }
0110f2b8
PB
11845 /* Allow section relaxation. */
11846 if (unified_syntax && inst.size_req != 2)
11847 inst.relax = opcode;
b99bd4ef 11848 }
e2b0ab59
AV
11849 inst.relocs[0].type = reloc;
11850 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
11851}
11852
8884b720 11853/* Actually do the work for Thumb state bkpt and hlt. The only difference
bacebabc 11854 between the two is the maximum immediate allowed - which is passed in
8884b720 11855 RANGE. */
b99bd4ef 11856static void
8884b720 11857do_t_bkpt_hlt1 (int range)
b99bd4ef 11858{
dfa9f0d5
PB
11859 constraint (inst.cond != COND_ALWAYS,
11860 _("instruction is always unconditional"));
c19d1205 11861 if (inst.operands[0].present)
b99bd4ef 11862 {
8884b720 11863 constraint (inst.operands[0].imm > range,
c19d1205
ZW
11864 _("immediate value out of range"));
11865 inst.instruction |= inst.operands[0].imm;
b99bd4ef 11866 }
8884b720 11867
5ee91343 11868 set_pred_insn_type (NEUTRAL_IT_INSN);
8884b720
MGD
11869}
11870
11871static void
11872do_t_hlt (void)
11873{
11874 do_t_bkpt_hlt1 (63);
11875}
11876
11877static void
11878do_t_bkpt (void)
11879{
11880 do_t_bkpt_hlt1 (255);
b99bd4ef
NC
11881}
11882
11883static void
c19d1205 11884do_t_branch23 (void)
b99bd4ef 11885{
5ee91343 11886 set_pred_insn_type_last ();
0855e32b 11887 encode_branch (BFD_RELOC_THUMB_PCREL_BRANCH23);
fa94de6b 11888
0855e32b
NS
11889 /* md_apply_fix blows up with 'bl foo(PLT)' where foo is defined in
11890 this file. We used to simply ignore the PLT reloc type here --
11891 the branch encoding is now needed to deal with TLSCALL relocs.
11892 So if we see a PLT reloc now, put it back to how it used to be to
11893 keep the preexisting behaviour. */
e2b0ab59
AV
11894 if (inst.relocs[0].type == BFD_RELOC_ARM_PLT32)
11895 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH23;
90e4755a 11896
4343666d 11897#if defined(OBJ_COFF)
c19d1205
ZW
11898 /* If the destination of the branch is a defined symbol which does not have
11899 the THUMB_FUNC attribute, then we must be calling a function which has
11900 the (interfacearm) attribute. We look for the Thumb entry point to that
11901 function and change the branch to refer to that function instead. */
e2b0ab59
AV
11902 if ( inst.relocs[0].exp.X_op == O_symbol
11903 && inst.relocs[0].exp.X_add_symbol != NULL
11904 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
11905 && ! THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
11906 inst.relocs[0].exp.X_add_symbol
11907 = find_real_start (inst.relocs[0].exp.X_add_symbol);
4343666d 11908#endif
90e4755a
RE
11909}
11910
11911static void
c19d1205 11912do_t_bx (void)
90e4755a 11913{
5ee91343 11914 set_pred_insn_type_last ();
c19d1205
ZW
11915 inst.instruction |= inst.operands[0].reg << 3;
11916 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
11917 should cause the alignment to be checked once it is known. This is
11918 because BX PC only works if the instruction is word aligned. */
11919}
90e4755a 11920
c19d1205
ZW
11921static void
11922do_t_bxj (void)
11923{
fdfde340 11924 int Rm;
90e4755a 11925
5ee91343 11926 set_pred_insn_type_last ();
fdfde340
JM
11927 Rm = inst.operands[0].reg;
11928 reject_bad_reg (Rm);
11929 inst.instruction |= Rm << 16;
90e4755a
RE
11930}
11931
11932static void
c19d1205 11933do_t_clz (void)
90e4755a 11934{
fdfde340
JM
11935 unsigned Rd;
11936 unsigned Rm;
11937
11938 Rd = inst.operands[0].reg;
11939 Rm = inst.operands[1].reg;
11940
11941 reject_bad_reg (Rd);
11942 reject_bad_reg (Rm);
11943
11944 inst.instruction |= Rd << 8;
11945 inst.instruction |= Rm << 16;
11946 inst.instruction |= Rm;
c19d1205 11947}
90e4755a 11948
91d8b670
JG
11949static void
11950do_t_csdb (void)
11951{
5ee91343 11952 set_pred_insn_type (OUTSIDE_PRED_INSN);
91d8b670
JG
11953}
11954
dfa9f0d5
PB
11955static void
11956do_t_cps (void)
11957{
5ee91343 11958 set_pred_insn_type (OUTSIDE_PRED_INSN);
dfa9f0d5
PB
11959 inst.instruction |= inst.operands[0].imm;
11960}
11961
c19d1205
ZW
11962static void
11963do_t_cpsi (void)
11964{
5ee91343 11965 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205 11966 if (unified_syntax
62b3e311
PB
11967 && (inst.operands[1].present || inst.size_req == 4)
11968 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6_notm))
90e4755a 11969 {
c19d1205
ZW
11970 unsigned int imod = (inst.instruction & 0x0030) >> 4;
11971 inst.instruction = 0xf3af8000;
11972 inst.instruction |= imod << 9;
11973 inst.instruction |= inst.operands[0].imm << 5;
11974 if (inst.operands[1].present)
11975 inst.instruction |= 0x100 | inst.operands[1].imm;
90e4755a 11976 }
c19d1205 11977 else
90e4755a 11978 {
62b3e311
PB
11979 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1)
11980 && (inst.operands[0].imm & 4),
11981 _("selected processor does not support 'A' form "
11982 "of this instruction"));
11983 constraint (inst.operands[1].present || inst.size_req == 4,
c19d1205
ZW
11984 _("Thumb does not support the 2-argument "
11985 "form of this instruction"));
11986 inst.instruction |= inst.operands[0].imm;
90e4755a 11987 }
90e4755a
RE
11988}
11989
c19d1205
ZW
11990/* THUMB CPY instruction (argument parse). */
11991
90e4755a 11992static void
c19d1205 11993do_t_cpy (void)
90e4755a 11994{
c19d1205 11995 if (inst.size_req == 4)
90e4755a 11996 {
c19d1205
ZW
11997 inst.instruction = THUMB_OP32 (T_MNEM_mov);
11998 inst.instruction |= inst.operands[0].reg << 8;
11999 inst.instruction |= inst.operands[1].reg;
90e4755a 12000 }
c19d1205 12001 else
90e4755a 12002 {
c19d1205
ZW
12003 inst.instruction |= (inst.operands[0].reg & 0x8) << 4;
12004 inst.instruction |= (inst.operands[0].reg & 0x7);
12005 inst.instruction |= inst.operands[1].reg << 3;
90e4755a 12006 }
90e4755a
RE
12007}
12008
90e4755a 12009static void
25fe350b 12010do_t_cbz (void)
90e4755a 12011{
5ee91343 12012 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205
ZW
12013 constraint (inst.operands[0].reg > 7, BAD_HIREG);
12014 inst.instruction |= inst.operands[0].reg;
e2b0ab59
AV
12015 inst.relocs[0].pc_rel = 1;
12016 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH7;
c19d1205 12017}
90e4755a 12018
62b3e311
PB
12019static void
12020do_t_dbg (void)
12021{
12022 inst.instruction |= inst.operands[0].imm;
12023}
12024
12025static void
12026do_t_div (void)
12027{
fdfde340
JM
12028 unsigned Rd, Rn, Rm;
12029
12030 Rd = inst.operands[0].reg;
12031 Rn = (inst.operands[1].present
12032 ? inst.operands[1].reg : Rd);
12033 Rm = inst.operands[2].reg;
12034
12035 reject_bad_reg (Rd);
12036 reject_bad_reg (Rn);
12037 reject_bad_reg (Rm);
12038
12039 inst.instruction |= Rd << 8;
12040 inst.instruction |= Rn << 16;
12041 inst.instruction |= Rm;
62b3e311
PB
12042}
12043
c19d1205
ZW
12044static void
12045do_t_hint (void)
12046{
12047 if (unified_syntax && inst.size_req == 4)
12048 inst.instruction = THUMB_OP32 (inst.instruction);
12049 else
12050 inst.instruction = THUMB_OP16 (inst.instruction);
12051}
90e4755a 12052
c19d1205
ZW
12053static void
12054do_t_it (void)
12055{
12056 unsigned int cond = inst.operands[0].imm;
e27ec89e 12057
5ee91343
AV
12058 set_pred_insn_type (IT_INSN);
12059 now_pred.mask = (inst.instruction & 0xf) | 0x10;
12060 now_pred.cc = cond;
12061 now_pred.warn_deprecated = FALSE;
12062 now_pred.type = SCALAR_PRED;
e27ec89e
PB
12063
12064 /* If the condition is a negative condition, invert the mask. */
c19d1205 12065 if ((cond & 0x1) == 0x0)
90e4755a 12066 {
c19d1205 12067 unsigned int mask = inst.instruction & 0x000f;
90e4755a 12068
c19d1205 12069 if ((mask & 0x7) == 0)
5a01bb1d
MGD
12070 {
12071 /* No conversion needed. */
5ee91343 12072 now_pred.block_length = 1;
5a01bb1d 12073 }
c19d1205 12074 else if ((mask & 0x3) == 0)
5a01bb1d
MGD
12075 {
12076 mask ^= 0x8;
5ee91343 12077 now_pred.block_length = 2;
5a01bb1d 12078 }
e27ec89e 12079 else if ((mask & 0x1) == 0)
5a01bb1d
MGD
12080 {
12081 mask ^= 0xC;
5ee91343 12082 now_pred.block_length = 3;
5a01bb1d 12083 }
c19d1205 12084 else
5a01bb1d
MGD
12085 {
12086 mask ^= 0xE;
5ee91343 12087 now_pred.block_length = 4;
5a01bb1d 12088 }
90e4755a 12089
e27ec89e
PB
12090 inst.instruction &= 0xfff0;
12091 inst.instruction |= mask;
c19d1205 12092 }
90e4755a 12093
c19d1205
ZW
12094 inst.instruction |= cond << 4;
12095}
90e4755a 12096
3c707909
PB
12097/* Helper function used for both push/pop and ldm/stm. */
12098static void
4b5a202f
AV
12099encode_thumb2_multi (bfd_boolean do_io, int base, unsigned mask,
12100 bfd_boolean writeback)
3c707909 12101{
4b5a202f 12102 bfd_boolean load, store;
3c707909 12103
4b5a202f
AV
12104 gas_assert (base != -1 || !do_io);
12105 load = do_io && ((inst.instruction & (1 << 20)) != 0);
12106 store = do_io && !load;
3c707909
PB
12107
12108 if (mask & (1 << 13))
12109 inst.error = _("SP not allowed in register list");
1e5b0379 12110
4b5a202f 12111 if (do_io && (mask & (1 << base)) != 0
1e5b0379
NC
12112 && writeback)
12113 inst.error = _("having the base register in the register list when "
12114 "using write back is UNPREDICTABLE");
12115
3c707909
PB
12116 if (load)
12117 {
e07e6e58 12118 if (mask & (1 << 15))
477330fc
RM
12119 {
12120 if (mask & (1 << 14))
12121 inst.error = _("LR and PC should not both be in register list");
12122 else
5ee91343 12123 set_pred_insn_type_last ();
477330fc 12124 }
3c707909 12125 }
4b5a202f 12126 else if (store)
3c707909
PB
12127 {
12128 if (mask & (1 << 15))
12129 inst.error = _("PC not allowed in register list");
3c707909
PB
12130 }
12131
4b5a202f 12132 if (do_io && ((mask & (mask - 1)) == 0))
3c707909
PB
12133 {
12134 /* Single register transfers implemented as str/ldr. */
12135 if (writeback)
12136 {
12137 if (inst.instruction & (1 << 23))
12138 inst.instruction = 0x00000b04; /* ia! -> [base], #4 */
12139 else
12140 inst.instruction = 0x00000d04; /* db! -> [base, #-4]! */
12141 }
12142 else
12143 {
12144 if (inst.instruction & (1 << 23))
12145 inst.instruction = 0x00800000; /* ia -> [base] */
12146 else
12147 inst.instruction = 0x00000c04; /* db -> [base, #-4] */
12148 }
12149
12150 inst.instruction |= 0xf8400000;
12151 if (load)
12152 inst.instruction |= 0x00100000;
12153
5f4273c7 12154 mask = ffs (mask) - 1;
3c707909
PB
12155 mask <<= 12;
12156 }
12157 else if (writeback)
12158 inst.instruction |= WRITE_BACK;
12159
12160 inst.instruction |= mask;
4b5a202f
AV
12161 if (do_io)
12162 inst.instruction |= base << 16;
3c707909
PB
12163}
12164
c19d1205
ZW
12165static void
12166do_t_ldmstm (void)
12167{
12168 /* This really doesn't seem worth it. */
e2b0ab59 12169 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205
ZW
12170 _("expression too complex"));
12171 constraint (inst.operands[1].writeback,
12172 _("Thumb load/store multiple does not support {reglist}^"));
90e4755a 12173
c19d1205
ZW
12174 if (unified_syntax)
12175 {
3c707909
PB
12176 bfd_boolean narrow;
12177 unsigned mask;
12178
12179 narrow = FALSE;
c19d1205
ZW
12180 /* See if we can use a 16-bit instruction. */
12181 if (inst.instruction < 0xffff /* not ldmdb/stmdb */
12182 && inst.size_req != 4
3c707909 12183 && !(inst.operands[1].imm & ~0xff))
90e4755a 12184 {
3c707909 12185 mask = 1 << inst.operands[0].reg;
90e4755a 12186
eab4f823 12187 if (inst.operands[0].reg <= 7)
90e4755a 12188 {
3c707909 12189 if (inst.instruction == T_MNEM_stmia
eab4f823
MGD
12190 ? inst.operands[0].writeback
12191 : (inst.operands[0].writeback
12192 == !(inst.operands[1].imm & mask)))
477330fc 12193 {
eab4f823
MGD
12194 if (inst.instruction == T_MNEM_stmia
12195 && (inst.operands[1].imm & mask)
12196 && (inst.operands[1].imm & (mask - 1)))
12197 as_warn (_("value stored for r%d is UNKNOWN"),
12198 inst.operands[0].reg);
3c707909 12199
eab4f823
MGD
12200 inst.instruction = THUMB_OP16 (inst.instruction);
12201 inst.instruction |= inst.operands[0].reg << 8;
12202 inst.instruction |= inst.operands[1].imm;
12203 narrow = TRUE;
12204 }
12205 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
12206 {
12207 /* This means 1 register in reg list one of 3 situations:
12208 1. Instruction is stmia, but without writeback.
12209 2. lmdia without writeback, but with Rn not in
477330fc 12210 reglist.
eab4f823
MGD
12211 3. ldmia with writeback, but with Rn in reglist.
12212 Case 3 is UNPREDICTABLE behaviour, so we handle
12213 case 1 and 2 which can be converted into a 16-bit
12214 str or ldr. The SP cases are handled below. */
12215 unsigned long opcode;
12216 /* First, record an error for Case 3. */
12217 if (inst.operands[1].imm & mask
12218 && inst.operands[0].writeback)
fa94de6b 12219 inst.error =
eab4f823
MGD
12220 _("having the base register in the register list when "
12221 "using write back is UNPREDICTABLE");
fa94de6b
RM
12222
12223 opcode = (inst.instruction == T_MNEM_stmia ? T_MNEM_str
eab4f823
MGD
12224 : T_MNEM_ldr);
12225 inst.instruction = THUMB_OP16 (opcode);
12226 inst.instruction |= inst.operands[0].reg << 3;
12227 inst.instruction |= (ffs (inst.operands[1].imm)-1);
12228 narrow = TRUE;
12229 }
90e4755a 12230 }
eab4f823 12231 else if (inst.operands[0] .reg == REG_SP)
90e4755a 12232 {
eab4f823
MGD
12233 if (inst.operands[0].writeback)
12234 {
fa94de6b 12235 inst.instruction =
eab4f823 12236 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 12237 ? T_MNEM_push : T_MNEM_pop);
eab4f823 12238 inst.instruction |= inst.operands[1].imm;
477330fc 12239 narrow = TRUE;
eab4f823
MGD
12240 }
12241 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
12242 {
fa94de6b 12243 inst.instruction =
eab4f823 12244 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 12245 ? T_MNEM_str_sp : T_MNEM_ldr_sp);
eab4f823 12246 inst.instruction |= ((ffs (inst.operands[1].imm)-1) << 8);
477330fc 12247 narrow = TRUE;
eab4f823 12248 }
90e4755a 12249 }
3c707909
PB
12250 }
12251
12252 if (!narrow)
12253 {
c19d1205
ZW
12254 if (inst.instruction < 0xffff)
12255 inst.instruction = THUMB_OP32 (inst.instruction);
3c707909 12256
4b5a202f
AV
12257 encode_thumb2_multi (TRUE /* do_io */, inst.operands[0].reg,
12258 inst.operands[1].imm,
12259 inst.operands[0].writeback);
90e4755a
RE
12260 }
12261 }
c19d1205 12262 else
90e4755a 12263 {
c19d1205
ZW
12264 constraint (inst.operands[0].reg > 7
12265 || (inst.operands[1].imm & ~0xff), BAD_HIREG);
1198ca51
PB
12266 constraint (inst.instruction != T_MNEM_ldmia
12267 && inst.instruction != T_MNEM_stmia,
12268 _("Thumb-2 instruction only valid in unified syntax"));
c19d1205 12269 if (inst.instruction == T_MNEM_stmia)
f03698e6 12270 {
c19d1205
ZW
12271 if (!inst.operands[0].writeback)
12272 as_warn (_("this instruction will write back the base register"));
12273 if ((inst.operands[1].imm & (1 << inst.operands[0].reg))
12274 && (inst.operands[1].imm & ((1 << inst.operands[0].reg) - 1)))
1e5b0379 12275 as_warn (_("value stored for r%d is UNKNOWN"),
c19d1205 12276 inst.operands[0].reg);
f03698e6 12277 }
c19d1205 12278 else
90e4755a 12279 {
c19d1205
ZW
12280 if (!inst.operands[0].writeback
12281 && !(inst.operands[1].imm & (1 << inst.operands[0].reg)))
12282 as_warn (_("this instruction will write back the base register"));
12283 else if (inst.operands[0].writeback
12284 && (inst.operands[1].imm & (1 << inst.operands[0].reg)))
12285 as_warn (_("this instruction will not write back the base register"));
90e4755a
RE
12286 }
12287
c19d1205
ZW
12288 inst.instruction = THUMB_OP16 (inst.instruction);
12289 inst.instruction |= inst.operands[0].reg << 8;
12290 inst.instruction |= inst.operands[1].imm;
12291 }
12292}
e28cd48c 12293
c19d1205
ZW
12294static void
12295do_t_ldrex (void)
12296{
12297 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
12298 || inst.operands[1].postind || inst.operands[1].writeback
12299 || inst.operands[1].immisreg || inst.operands[1].shifted
12300 || inst.operands[1].negative,
01cfc07f 12301 BAD_ADDR_MODE);
e28cd48c 12302
5be8be5d
DG
12303 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
12304
c19d1205
ZW
12305 inst.instruction |= inst.operands[0].reg << 12;
12306 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 12307 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
c19d1205 12308}
e28cd48c 12309
c19d1205
ZW
12310static void
12311do_t_ldrexd (void)
12312{
12313 if (!inst.operands[1].present)
1cac9012 12314 {
c19d1205
ZW
12315 constraint (inst.operands[0].reg == REG_LR,
12316 _("r14 not allowed as first register "
12317 "when second register is omitted"));
12318 inst.operands[1].reg = inst.operands[0].reg + 1;
b99bd4ef 12319 }
c19d1205
ZW
12320 constraint (inst.operands[0].reg == inst.operands[1].reg,
12321 BAD_OVERLAP);
b99bd4ef 12322
c19d1205
ZW
12323 inst.instruction |= inst.operands[0].reg << 12;
12324 inst.instruction |= inst.operands[1].reg << 8;
12325 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
12326}
12327
12328static void
c19d1205 12329do_t_ldst (void)
b99bd4ef 12330{
0110f2b8
PB
12331 unsigned long opcode;
12332 int Rn;
12333
e07e6e58
NC
12334 if (inst.operands[0].isreg
12335 && !inst.operands[0].preind
12336 && inst.operands[0].reg == REG_PC)
5ee91343 12337 set_pred_insn_type_last ();
e07e6e58 12338
0110f2b8 12339 opcode = inst.instruction;
c19d1205 12340 if (unified_syntax)
b99bd4ef 12341 {
53365c0d
PB
12342 if (!inst.operands[1].isreg)
12343 {
12344 if (opcode <= 0xffff)
12345 inst.instruction = THUMB_OP32 (opcode);
8335d6aa 12346 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/FALSE))
53365c0d
PB
12347 return;
12348 }
0110f2b8
PB
12349 if (inst.operands[1].isreg
12350 && !inst.operands[1].writeback
c19d1205
ZW
12351 && !inst.operands[1].shifted && !inst.operands[1].postind
12352 && !inst.operands[1].negative && inst.operands[0].reg <= 7
0110f2b8
PB
12353 && opcode <= 0xffff
12354 && inst.size_req != 4)
c19d1205 12355 {
0110f2b8
PB
12356 /* Insn may have a 16-bit form. */
12357 Rn = inst.operands[1].reg;
12358 if (inst.operands[1].immisreg)
12359 {
12360 inst.instruction = THUMB_OP16 (opcode);
5f4273c7 12361 /* [Rn, Rik] */
0110f2b8
PB
12362 if (Rn <= 7 && inst.operands[1].imm <= 7)
12363 goto op16;
5be8be5d
DG
12364 else if (opcode != T_MNEM_ldr && opcode != T_MNEM_str)
12365 reject_bad_reg (inst.operands[1].imm);
0110f2b8
PB
12366 }
12367 else if ((Rn <= 7 && opcode != T_MNEM_ldrsh
12368 && opcode != T_MNEM_ldrsb)
12369 || ((Rn == REG_PC || Rn == REG_SP) && opcode == T_MNEM_ldr)
12370 || (Rn == REG_SP && opcode == T_MNEM_str))
12371 {
12372 /* [Rn, #const] */
12373 if (Rn > 7)
12374 {
12375 if (Rn == REG_PC)
12376 {
e2b0ab59 12377 if (inst.relocs[0].pc_rel)
0110f2b8
PB
12378 opcode = T_MNEM_ldr_pc2;
12379 else
12380 opcode = T_MNEM_ldr_pc;
12381 }
12382 else
12383 {
12384 if (opcode == T_MNEM_ldr)
12385 opcode = T_MNEM_ldr_sp;
12386 else
12387 opcode = T_MNEM_str_sp;
12388 }
12389 inst.instruction = inst.operands[0].reg << 8;
12390 }
12391 else
12392 {
12393 inst.instruction = inst.operands[0].reg;
12394 inst.instruction |= inst.operands[1].reg << 3;
12395 }
12396 inst.instruction |= THUMB_OP16 (opcode);
12397 if (inst.size_req == 2)
e2b0ab59 12398 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
0110f2b8
PB
12399 else
12400 inst.relax = opcode;
12401 return;
12402 }
c19d1205 12403 }
0110f2b8 12404 /* Definitely a 32-bit variant. */
5be8be5d 12405
8d67f500
NC
12406 /* Warning for Erratum 752419. */
12407 if (opcode == T_MNEM_ldr
12408 && inst.operands[0].reg == REG_SP
12409 && inst.operands[1].writeback == 1
12410 && !inst.operands[1].immisreg)
12411 {
12412 if (no_cpu_selected ()
12413 || (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7)
477330fc
RM
12414 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a)
12415 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7r)))
8d67f500
NC
12416 as_warn (_("This instruction may be unpredictable "
12417 "if executed on M-profile cores "
12418 "with interrupts enabled."));
12419 }
12420
5be8be5d 12421 /* Do some validations regarding addressing modes. */
1be5fd2e 12422 if (inst.operands[1].immisreg)
5be8be5d
DG
12423 reject_bad_reg (inst.operands[1].imm);
12424
1be5fd2e
NC
12425 constraint (inst.operands[1].writeback == 1
12426 && inst.operands[0].reg == inst.operands[1].reg,
12427 BAD_OVERLAP);
12428
0110f2b8 12429 inst.instruction = THUMB_OP32 (opcode);
c19d1205
ZW
12430 inst.instruction |= inst.operands[0].reg << 12;
12431 encode_thumb32_addr_mode (1, /*is_t=*/FALSE, /*is_d=*/FALSE);
1be5fd2e 12432 check_ldr_r15_aligned ();
b99bd4ef
NC
12433 return;
12434 }
12435
c19d1205
ZW
12436 constraint (inst.operands[0].reg > 7, BAD_HIREG);
12437
12438 if (inst.instruction == T_MNEM_ldrsh || inst.instruction == T_MNEM_ldrsb)
b99bd4ef 12439 {
c19d1205
ZW
12440 /* Only [Rn,Rm] is acceptable. */
12441 constraint (inst.operands[1].reg > 7 || inst.operands[1].imm > 7, BAD_HIREG);
12442 constraint (!inst.operands[1].isreg || !inst.operands[1].immisreg
12443 || inst.operands[1].postind || inst.operands[1].shifted
12444 || inst.operands[1].negative,
12445 _("Thumb does not support this addressing mode"));
12446 inst.instruction = THUMB_OP16 (inst.instruction);
12447 goto op16;
b99bd4ef 12448 }
5f4273c7 12449
c19d1205
ZW
12450 inst.instruction = THUMB_OP16 (inst.instruction);
12451 if (!inst.operands[1].isreg)
8335d6aa 12452 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/FALSE))
c19d1205 12453 return;
b99bd4ef 12454
c19d1205
ZW
12455 constraint (!inst.operands[1].preind
12456 || inst.operands[1].shifted
12457 || inst.operands[1].writeback,
12458 _("Thumb does not support this addressing mode"));
12459 if (inst.operands[1].reg == REG_PC || inst.operands[1].reg == REG_SP)
90e4755a 12460 {
c19d1205
ZW
12461 constraint (inst.instruction & 0x0600,
12462 _("byte or halfword not valid for base register"));
12463 constraint (inst.operands[1].reg == REG_PC
12464 && !(inst.instruction & THUMB_LOAD_BIT),
12465 _("r15 based store not allowed"));
12466 constraint (inst.operands[1].immisreg,
12467 _("invalid base register for register offset"));
b99bd4ef 12468
c19d1205
ZW
12469 if (inst.operands[1].reg == REG_PC)
12470 inst.instruction = T_OPCODE_LDR_PC;
12471 else if (inst.instruction & THUMB_LOAD_BIT)
12472 inst.instruction = T_OPCODE_LDR_SP;
12473 else
12474 inst.instruction = T_OPCODE_STR_SP;
b99bd4ef 12475
c19d1205 12476 inst.instruction |= inst.operands[0].reg << 8;
e2b0ab59 12477 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
12478 return;
12479 }
90e4755a 12480
c19d1205
ZW
12481 constraint (inst.operands[1].reg > 7, BAD_HIREG);
12482 if (!inst.operands[1].immisreg)
12483 {
12484 /* Immediate offset. */
12485 inst.instruction |= inst.operands[0].reg;
12486 inst.instruction |= inst.operands[1].reg << 3;
e2b0ab59 12487 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
12488 return;
12489 }
90e4755a 12490
c19d1205
ZW
12491 /* Register offset. */
12492 constraint (inst.operands[1].imm > 7, BAD_HIREG);
12493 constraint (inst.operands[1].negative,
12494 _("Thumb does not support this addressing mode"));
90e4755a 12495
c19d1205
ZW
12496 op16:
12497 switch (inst.instruction)
12498 {
12499 case T_OPCODE_STR_IW: inst.instruction = T_OPCODE_STR_RW; break;
12500 case T_OPCODE_STR_IH: inst.instruction = T_OPCODE_STR_RH; break;
12501 case T_OPCODE_STR_IB: inst.instruction = T_OPCODE_STR_RB; break;
12502 case T_OPCODE_LDR_IW: inst.instruction = T_OPCODE_LDR_RW; break;
12503 case T_OPCODE_LDR_IH: inst.instruction = T_OPCODE_LDR_RH; break;
12504 case T_OPCODE_LDR_IB: inst.instruction = T_OPCODE_LDR_RB; break;
12505 case 0x5600 /* ldrsb */:
12506 case 0x5e00 /* ldrsh */: break;
12507 default: abort ();
12508 }
90e4755a 12509
c19d1205
ZW
12510 inst.instruction |= inst.operands[0].reg;
12511 inst.instruction |= inst.operands[1].reg << 3;
12512 inst.instruction |= inst.operands[1].imm << 6;
12513}
90e4755a 12514
c19d1205
ZW
12515static void
12516do_t_ldstd (void)
12517{
12518 if (!inst.operands[1].present)
b99bd4ef 12519 {
c19d1205
ZW
12520 inst.operands[1].reg = inst.operands[0].reg + 1;
12521 constraint (inst.operands[0].reg == REG_LR,
12522 _("r14 not allowed here"));
bd340a04 12523 constraint (inst.operands[0].reg == REG_R12,
477330fc 12524 _("r12 not allowed here"));
b99bd4ef 12525 }
bd340a04
MGD
12526
12527 if (inst.operands[2].writeback
12528 && (inst.operands[0].reg == inst.operands[2].reg
12529 || inst.operands[1].reg == inst.operands[2].reg))
12530 as_warn (_("base register written back, and overlaps "
477330fc 12531 "one of transfer registers"));
bd340a04 12532
c19d1205
ZW
12533 inst.instruction |= inst.operands[0].reg << 12;
12534 inst.instruction |= inst.operands[1].reg << 8;
12535 encode_thumb32_addr_mode (2, /*is_t=*/FALSE, /*is_d=*/TRUE);
b99bd4ef
NC
12536}
12537
c19d1205
ZW
12538static void
12539do_t_ldstt (void)
12540{
12541 inst.instruction |= inst.operands[0].reg << 12;
12542 encode_thumb32_addr_mode (1, /*is_t=*/TRUE, /*is_d=*/FALSE);
12543}
a737bd4d 12544
b99bd4ef 12545static void
c19d1205 12546do_t_mla (void)
b99bd4ef 12547{
fdfde340 12548 unsigned Rd, Rn, Rm, Ra;
c921be7d 12549
fdfde340
JM
12550 Rd = inst.operands[0].reg;
12551 Rn = inst.operands[1].reg;
12552 Rm = inst.operands[2].reg;
12553 Ra = inst.operands[3].reg;
12554
12555 reject_bad_reg (Rd);
12556 reject_bad_reg (Rn);
12557 reject_bad_reg (Rm);
12558 reject_bad_reg (Ra);
12559
12560 inst.instruction |= Rd << 8;
12561 inst.instruction |= Rn << 16;
12562 inst.instruction |= Rm;
12563 inst.instruction |= Ra << 12;
c19d1205 12564}
b99bd4ef 12565
c19d1205
ZW
12566static void
12567do_t_mlal (void)
12568{
fdfde340
JM
12569 unsigned RdLo, RdHi, Rn, Rm;
12570
12571 RdLo = inst.operands[0].reg;
12572 RdHi = inst.operands[1].reg;
12573 Rn = inst.operands[2].reg;
12574 Rm = inst.operands[3].reg;
12575
12576 reject_bad_reg (RdLo);
12577 reject_bad_reg (RdHi);
12578 reject_bad_reg (Rn);
12579 reject_bad_reg (Rm);
12580
12581 inst.instruction |= RdLo << 12;
12582 inst.instruction |= RdHi << 8;
12583 inst.instruction |= Rn << 16;
12584 inst.instruction |= Rm;
c19d1205 12585}
b99bd4ef 12586
c19d1205
ZW
12587static void
12588do_t_mov_cmp (void)
12589{
fdfde340
JM
12590 unsigned Rn, Rm;
12591
12592 Rn = inst.operands[0].reg;
12593 Rm = inst.operands[1].reg;
12594
e07e6e58 12595 if (Rn == REG_PC)
5ee91343 12596 set_pred_insn_type_last ();
e07e6e58 12597
c19d1205 12598 if (unified_syntax)
b99bd4ef 12599 {
c19d1205
ZW
12600 int r0off = (inst.instruction == T_MNEM_mov
12601 || inst.instruction == T_MNEM_movs) ? 8 : 16;
0110f2b8 12602 unsigned long opcode;
3d388997
PB
12603 bfd_boolean narrow;
12604 bfd_boolean low_regs;
12605
fdfde340 12606 low_regs = (Rn <= 7 && Rm <= 7);
0110f2b8 12607 opcode = inst.instruction;
5ee91343 12608 if (in_pred_block ())
0110f2b8 12609 narrow = opcode != T_MNEM_movs;
3d388997 12610 else
0110f2b8 12611 narrow = opcode != T_MNEM_movs || low_regs;
3d388997
PB
12612 if (inst.size_req == 4
12613 || inst.operands[1].shifted)
12614 narrow = FALSE;
12615
efd81785
PB
12616 /* MOVS PC, LR is encoded as SUBS PC, LR, #0. */
12617 if (opcode == T_MNEM_movs && inst.operands[1].isreg
12618 && !inst.operands[1].shifted
fdfde340
JM
12619 && Rn == REG_PC
12620 && Rm == REG_LR)
efd81785
PB
12621 {
12622 inst.instruction = T2_SUBS_PC_LR;
12623 return;
12624 }
12625
fdfde340
JM
12626 if (opcode == T_MNEM_cmp)
12627 {
12628 constraint (Rn == REG_PC, BAD_PC);
94206790
MM
12629 if (narrow)
12630 {
12631 /* In the Thumb-2 ISA, use of R13 as Rm is deprecated,
12632 but valid. */
12633 warn_deprecated_sp (Rm);
12634 /* R15 was documented as a valid choice for Rm in ARMv6,
12635 but as UNPREDICTABLE in ARMv7. ARM's proprietary
12636 tools reject R15, so we do too. */
12637 constraint (Rm == REG_PC, BAD_PC);
12638 }
12639 else
12640 reject_bad_reg (Rm);
fdfde340
JM
12641 }
12642 else if (opcode == T_MNEM_mov
12643 || opcode == T_MNEM_movs)
12644 {
12645 if (inst.operands[1].isreg)
12646 {
12647 if (opcode == T_MNEM_movs)
12648 {
12649 reject_bad_reg (Rn);
12650 reject_bad_reg (Rm);
12651 }
76fa04a4
MGD
12652 else if (narrow)
12653 {
12654 /* This is mov.n. */
12655 if ((Rn == REG_SP || Rn == REG_PC)
12656 && (Rm == REG_SP || Rm == REG_PC))
12657 {
5c3696f8 12658 as_tsktsk (_("Use of r%u as a source register is "
76fa04a4
MGD
12659 "deprecated when r%u is the destination "
12660 "register."), Rm, Rn);
12661 }
12662 }
12663 else
12664 {
12665 /* This is mov.w. */
12666 constraint (Rn == REG_PC, BAD_PC);
12667 constraint (Rm == REG_PC, BAD_PC);
5c8ed6a4
JW
12668 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
12669 constraint (Rn == REG_SP && Rm == REG_SP, BAD_SP);
76fa04a4 12670 }
fdfde340
JM
12671 }
12672 else
12673 reject_bad_reg (Rn);
12674 }
12675
c19d1205
ZW
12676 if (!inst.operands[1].isreg)
12677 {
0110f2b8 12678 /* Immediate operand. */
5ee91343 12679 if (!in_pred_block () && opcode == T_MNEM_mov)
0110f2b8
PB
12680 narrow = 0;
12681 if (low_regs && narrow)
12682 {
12683 inst.instruction = THUMB_OP16 (opcode);
fdfde340 12684 inst.instruction |= Rn << 8;
e2b0ab59
AV
12685 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
12686 || inst.relocs[0].type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
72d98d16 12687 {
a9f02af8 12688 if (inst.size_req == 2)
e2b0ab59 12689 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
a9f02af8
MG
12690 else
12691 inst.relax = opcode;
72d98d16 12692 }
0110f2b8
PB
12693 }
12694 else
12695 {
e2b0ab59
AV
12696 constraint ((inst.relocs[0].type
12697 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
12698 && (inst.relocs[0].type
12699 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8
MG
12700 THUMB1_RELOC_ONLY);
12701
0110f2b8
PB
12702 inst.instruction = THUMB_OP32 (inst.instruction);
12703 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 12704 inst.instruction |= Rn << r0off;
e2b0ab59 12705 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8 12706 }
c19d1205 12707 }
728ca7c9
PB
12708 else if (inst.operands[1].shifted && inst.operands[1].immisreg
12709 && (inst.instruction == T_MNEM_mov
12710 || inst.instruction == T_MNEM_movs))
12711 {
12712 /* Register shifts are encoded as separate shift instructions. */
12713 bfd_boolean flags = (inst.instruction == T_MNEM_movs);
12714
5ee91343 12715 if (in_pred_block ())
728ca7c9
PB
12716 narrow = !flags;
12717 else
12718 narrow = flags;
12719
12720 if (inst.size_req == 4)
12721 narrow = FALSE;
12722
12723 if (!low_regs || inst.operands[1].imm > 7)
12724 narrow = FALSE;
12725
fdfde340 12726 if (Rn != Rm)
728ca7c9
PB
12727 narrow = FALSE;
12728
12729 switch (inst.operands[1].shift_kind)
12730 {
12731 case SHIFT_LSL:
12732 opcode = narrow ? T_OPCODE_LSL_R : THUMB_OP32 (T_MNEM_lsl);
12733 break;
12734 case SHIFT_ASR:
12735 opcode = narrow ? T_OPCODE_ASR_R : THUMB_OP32 (T_MNEM_asr);
12736 break;
12737 case SHIFT_LSR:
12738 opcode = narrow ? T_OPCODE_LSR_R : THUMB_OP32 (T_MNEM_lsr);
12739 break;
12740 case SHIFT_ROR:
12741 opcode = narrow ? T_OPCODE_ROR_R : THUMB_OP32 (T_MNEM_ror);
12742 break;
12743 default:
5f4273c7 12744 abort ();
728ca7c9
PB
12745 }
12746
12747 inst.instruction = opcode;
12748 if (narrow)
12749 {
fdfde340 12750 inst.instruction |= Rn;
728ca7c9
PB
12751 inst.instruction |= inst.operands[1].imm << 3;
12752 }
12753 else
12754 {
12755 if (flags)
12756 inst.instruction |= CONDS_BIT;
12757
fdfde340
JM
12758 inst.instruction |= Rn << 8;
12759 inst.instruction |= Rm << 16;
728ca7c9
PB
12760 inst.instruction |= inst.operands[1].imm;
12761 }
12762 }
3d388997 12763 else if (!narrow)
c19d1205 12764 {
728ca7c9
PB
12765 /* Some mov with immediate shift have narrow variants.
12766 Register shifts are handled above. */
12767 if (low_regs && inst.operands[1].shifted
12768 && (inst.instruction == T_MNEM_mov
12769 || inst.instruction == T_MNEM_movs))
12770 {
5ee91343 12771 if (in_pred_block ())
728ca7c9
PB
12772 narrow = (inst.instruction == T_MNEM_mov);
12773 else
12774 narrow = (inst.instruction == T_MNEM_movs);
12775 }
12776
12777 if (narrow)
12778 {
12779 switch (inst.operands[1].shift_kind)
12780 {
12781 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
12782 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
12783 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
12784 default: narrow = FALSE; break;
12785 }
12786 }
12787
12788 if (narrow)
12789 {
fdfde340
JM
12790 inst.instruction |= Rn;
12791 inst.instruction |= Rm << 3;
e2b0ab59 12792 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
728ca7c9
PB
12793 }
12794 else
12795 {
12796 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 12797 inst.instruction |= Rn << r0off;
728ca7c9
PB
12798 encode_thumb32_shifted_operand (1);
12799 }
c19d1205
ZW
12800 }
12801 else
12802 switch (inst.instruction)
12803 {
12804 case T_MNEM_mov:
837b3435 12805 /* In v4t or v5t a move of two lowregs produces unpredictable
c6400f8a
MGD
12806 results. Don't allow this. */
12807 if (low_regs)
12808 {
12809 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6),
12810 "MOV Rd, Rs with two low registers is not "
12811 "permitted on this architecture");
fa94de6b 12812 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
c6400f8a
MGD
12813 arm_ext_v6);
12814 }
12815
c19d1205 12816 inst.instruction = T_OPCODE_MOV_HR;
fdfde340
JM
12817 inst.instruction |= (Rn & 0x8) << 4;
12818 inst.instruction |= (Rn & 0x7);
12819 inst.instruction |= Rm << 3;
c19d1205 12820 break;
b99bd4ef 12821
c19d1205
ZW
12822 case T_MNEM_movs:
12823 /* We know we have low registers at this point.
941a8a52
MGD
12824 Generate LSLS Rd, Rs, #0. */
12825 inst.instruction = T_OPCODE_LSL_I;
fdfde340
JM
12826 inst.instruction |= Rn;
12827 inst.instruction |= Rm << 3;
c19d1205
ZW
12828 break;
12829
12830 case T_MNEM_cmp:
3d388997 12831 if (low_regs)
c19d1205
ZW
12832 {
12833 inst.instruction = T_OPCODE_CMP_LR;
fdfde340
JM
12834 inst.instruction |= Rn;
12835 inst.instruction |= Rm << 3;
c19d1205
ZW
12836 }
12837 else
12838 {
12839 inst.instruction = T_OPCODE_CMP_HR;
fdfde340
JM
12840 inst.instruction |= (Rn & 0x8) << 4;
12841 inst.instruction |= (Rn & 0x7);
12842 inst.instruction |= Rm << 3;
c19d1205
ZW
12843 }
12844 break;
12845 }
b99bd4ef
NC
12846 return;
12847 }
12848
c19d1205 12849 inst.instruction = THUMB_OP16 (inst.instruction);
539d4391
NC
12850
12851 /* PR 10443: Do not silently ignore shifted operands. */
12852 constraint (inst.operands[1].shifted,
12853 _("shifts in CMP/MOV instructions are only supported in unified syntax"));
12854
c19d1205 12855 if (inst.operands[1].isreg)
b99bd4ef 12856 {
fdfde340 12857 if (Rn < 8 && Rm < 8)
b99bd4ef 12858 {
c19d1205
ZW
12859 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
12860 since a MOV instruction produces unpredictable results. */
12861 if (inst.instruction == T_OPCODE_MOV_I8)
12862 inst.instruction = T_OPCODE_ADD_I3;
b99bd4ef 12863 else
c19d1205 12864 inst.instruction = T_OPCODE_CMP_LR;
b99bd4ef 12865
fdfde340
JM
12866 inst.instruction |= Rn;
12867 inst.instruction |= Rm << 3;
b99bd4ef
NC
12868 }
12869 else
12870 {
c19d1205
ZW
12871 if (inst.instruction == T_OPCODE_MOV_I8)
12872 inst.instruction = T_OPCODE_MOV_HR;
12873 else
12874 inst.instruction = T_OPCODE_CMP_HR;
12875 do_t_cpy ();
b99bd4ef
NC
12876 }
12877 }
c19d1205 12878 else
b99bd4ef 12879 {
fdfde340 12880 constraint (Rn > 7,
c19d1205 12881 _("only lo regs allowed with immediate"));
fdfde340 12882 inst.instruction |= Rn << 8;
e2b0ab59 12883 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
c19d1205
ZW
12884 }
12885}
b99bd4ef 12886
c19d1205
ZW
12887static void
12888do_t_mov16 (void)
12889{
fdfde340 12890 unsigned Rd;
b6895b4f
PB
12891 bfd_vma imm;
12892 bfd_boolean top;
12893
12894 top = (inst.instruction & 0x00800000) != 0;
e2b0ab59 12895 if (inst.relocs[0].type == BFD_RELOC_ARM_MOVW)
b6895b4f 12896 {
33eaf5de 12897 constraint (top, _(":lower16: not allowed in this instruction"));
e2b0ab59 12898 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVW;
b6895b4f 12899 }
e2b0ab59 12900 else if (inst.relocs[0].type == BFD_RELOC_ARM_MOVT)
b6895b4f 12901 {
33eaf5de 12902 constraint (!top, _(":upper16: not allowed in this instruction"));
e2b0ab59 12903 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVT;
b6895b4f
PB
12904 }
12905
fdfde340
JM
12906 Rd = inst.operands[0].reg;
12907 reject_bad_reg (Rd);
12908
12909 inst.instruction |= Rd << 8;
e2b0ab59 12910 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 12911 {
e2b0ab59 12912 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
12913 inst.instruction |= (imm & 0xf000) << 4;
12914 inst.instruction |= (imm & 0x0800) << 15;
12915 inst.instruction |= (imm & 0x0700) << 4;
12916 inst.instruction |= (imm & 0x00ff);
12917 }
c19d1205 12918}
b99bd4ef 12919
c19d1205
ZW
12920static void
12921do_t_mvn_tst (void)
12922{
fdfde340 12923 unsigned Rn, Rm;
c921be7d 12924
fdfde340
JM
12925 Rn = inst.operands[0].reg;
12926 Rm = inst.operands[1].reg;
12927
12928 if (inst.instruction == T_MNEM_cmp
12929 || inst.instruction == T_MNEM_cmn)
12930 constraint (Rn == REG_PC, BAD_PC);
12931 else
12932 reject_bad_reg (Rn);
12933 reject_bad_reg (Rm);
12934
c19d1205
ZW
12935 if (unified_syntax)
12936 {
12937 int r0off = (inst.instruction == T_MNEM_mvn
12938 || inst.instruction == T_MNEM_mvns) ? 8 : 16;
3d388997
PB
12939 bfd_boolean narrow;
12940
12941 if (inst.size_req == 4
12942 || inst.instruction > 0xffff
12943 || inst.operands[1].shifted
fdfde340 12944 || Rn > 7 || Rm > 7)
3d388997 12945 narrow = FALSE;
fe8b4cc3
KT
12946 else if (inst.instruction == T_MNEM_cmn
12947 || inst.instruction == T_MNEM_tst)
3d388997
PB
12948 narrow = TRUE;
12949 else if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 12950 narrow = !in_pred_block ();
3d388997 12951 else
5ee91343 12952 narrow = in_pred_block ();
3d388997 12953
c19d1205 12954 if (!inst.operands[1].isreg)
b99bd4ef 12955 {
c19d1205
ZW
12956 /* For an immediate, we always generate a 32-bit opcode;
12957 section relaxation will shrink it later if possible. */
12958 if (inst.instruction < 0xffff)
12959 inst.instruction = THUMB_OP32 (inst.instruction);
12960 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 12961 inst.instruction |= Rn << r0off;
e2b0ab59 12962 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 12963 }
c19d1205 12964 else
b99bd4ef 12965 {
c19d1205 12966 /* See if we can do this with a 16-bit instruction. */
3d388997 12967 if (narrow)
b99bd4ef 12968 {
c19d1205 12969 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
12970 inst.instruction |= Rn;
12971 inst.instruction |= Rm << 3;
b99bd4ef 12972 }
c19d1205 12973 else
b99bd4ef 12974 {
c19d1205
ZW
12975 constraint (inst.operands[1].shifted
12976 && inst.operands[1].immisreg,
12977 _("shift must be constant"));
12978 if (inst.instruction < 0xffff)
12979 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 12980 inst.instruction |= Rn << r0off;
c19d1205 12981 encode_thumb32_shifted_operand (1);
b99bd4ef 12982 }
b99bd4ef
NC
12983 }
12984 }
12985 else
12986 {
c19d1205
ZW
12987 constraint (inst.instruction > 0xffff
12988 || inst.instruction == T_MNEM_mvns, BAD_THUMB32);
12989 constraint (!inst.operands[1].isreg || inst.operands[1].shifted,
12990 _("unshifted register required"));
fdfde340 12991 constraint (Rn > 7 || Rm > 7,
c19d1205 12992 BAD_HIREG);
b99bd4ef 12993
c19d1205 12994 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
12995 inst.instruction |= Rn;
12996 inst.instruction |= Rm << 3;
b99bd4ef 12997 }
b99bd4ef
NC
12998}
12999
b05fe5cf 13000static void
c19d1205 13001do_t_mrs (void)
b05fe5cf 13002{
fdfde340 13003 unsigned Rd;
037e8744
JB
13004
13005 if (do_vfp_nsyn_mrs () == SUCCESS)
13006 return;
13007
90ec0d68
MGD
13008 Rd = inst.operands[0].reg;
13009 reject_bad_reg (Rd);
13010 inst.instruction |= Rd << 8;
13011
13012 if (inst.operands[1].isreg)
62b3e311 13013 {
90ec0d68
MGD
13014 unsigned br = inst.operands[1].reg;
13015 if (((br & 0x200) == 0) && ((br & 0xf000) != 0xf000))
13016 as_bad (_("bad register for mrs"));
13017
13018 inst.instruction |= br & (0xf << 16);
13019 inst.instruction |= (br & 0x300) >> 4;
13020 inst.instruction |= (br & SPSR_BIT) >> 2;
62b3e311
PB
13021 }
13022 else
13023 {
90ec0d68 13024 int flags = inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
5f4273c7 13025
d2cd1205 13026 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
1a43faaf
NC
13027 {
13028 /* PR gas/12698: The constraint is only applied for m_profile.
13029 If the user has specified -march=all, we want to ignore it as
13030 we are building for any CPU type, including non-m variants. */
823d2571
TG
13031 bfd_boolean m_profile =
13032 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf
NC
13033 constraint ((flags != 0) && m_profile, _("selected processor does "
13034 "not support requested special purpose register"));
13035 }
90ec0d68 13036 else
d2cd1205
JB
13037 /* mrs only accepts APSR/CPSR/SPSR/CPSR_all/SPSR_all (for non-M profile
13038 devices). */
13039 constraint ((flags & ~SPSR_BIT) != (PSR_c|PSR_f),
13040 _("'APSR', 'CPSR' or 'SPSR' expected"));
fdfde340 13041
90ec0d68
MGD
13042 inst.instruction |= (flags & SPSR_BIT) >> 2;
13043 inst.instruction |= inst.operands[1].imm & 0xff;
13044 inst.instruction |= 0xf0000;
13045 }
c19d1205 13046}
b05fe5cf 13047
c19d1205
ZW
13048static void
13049do_t_msr (void)
13050{
62b3e311 13051 int flags;
fdfde340 13052 unsigned Rn;
62b3e311 13053
037e8744
JB
13054 if (do_vfp_nsyn_msr () == SUCCESS)
13055 return;
13056
c19d1205
ZW
13057 constraint (!inst.operands[1].isreg,
13058 _("Thumb encoding does not support an immediate here"));
90ec0d68
MGD
13059
13060 if (inst.operands[0].isreg)
13061 flags = (int)(inst.operands[0].reg);
13062 else
13063 flags = inst.operands[0].imm;
13064
d2cd1205 13065 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
62b3e311 13066 {
d2cd1205
JB
13067 int bits = inst.operands[0].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
13068
1a43faaf 13069 /* PR gas/12698: The constraint is only applied for m_profile.
477330fc
RM
13070 If the user has specified -march=all, we want to ignore it as
13071 we are building for any CPU type, including non-m variants. */
823d2571
TG
13072 bfd_boolean m_profile =
13073 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf 13074 constraint (((ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
477330fc
RM
13075 && (bits & ~(PSR_s | PSR_f)) != 0)
13076 || (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
13077 && bits != PSR_f)) && m_profile,
13078 _("selected processor does not support requested special "
13079 "purpose register"));
62b3e311
PB
13080 }
13081 else
d2cd1205
JB
13082 constraint ((flags & 0xff) != 0, _("selected processor does not support "
13083 "requested special purpose register"));
c921be7d 13084
fdfde340
JM
13085 Rn = inst.operands[1].reg;
13086 reject_bad_reg (Rn);
13087
62b3e311 13088 inst.instruction |= (flags & SPSR_BIT) >> 2;
90ec0d68
MGD
13089 inst.instruction |= (flags & 0xf0000) >> 8;
13090 inst.instruction |= (flags & 0x300) >> 4;
62b3e311 13091 inst.instruction |= (flags & 0xff);
fdfde340 13092 inst.instruction |= Rn << 16;
c19d1205 13093}
b05fe5cf 13094
c19d1205
ZW
13095static void
13096do_t_mul (void)
13097{
17828f45 13098 bfd_boolean narrow;
fdfde340 13099 unsigned Rd, Rn, Rm;
17828f45 13100
c19d1205
ZW
13101 if (!inst.operands[2].present)
13102 inst.operands[2].reg = inst.operands[0].reg;
b05fe5cf 13103
fdfde340
JM
13104 Rd = inst.operands[0].reg;
13105 Rn = inst.operands[1].reg;
13106 Rm = inst.operands[2].reg;
13107
17828f45 13108 if (unified_syntax)
b05fe5cf 13109 {
17828f45 13110 if (inst.size_req == 4
fdfde340
JM
13111 || (Rd != Rn
13112 && Rd != Rm)
13113 || Rn > 7
13114 || Rm > 7)
17828f45
JM
13115 narrow = FALSE;
13116 else if (inst.instruction == T_MNEM_muls)
5ee91343 13117 narrow = !in_pred_block ();
17828f45 13118 else
5ee91343 13119 narrow = in_pred_block ();
b05fe5cf 13120 }
c19d1205 13121 else
b05fe5cf 13122 {
17828f45 13123 constraint (inst.instruction == T_MNEM_muls, BAD_THUMB32);
fdfde340 13124 constraint (Rn > 7 || Rm > 7,
c19d1205 13125 BAD_HIREG);
17828f45
JM
13126 narrow = TRUE;
13127 }
b05fe5cf 13128
17828f45
JM
13129 if (narrow)
13130 {
13131 /* 16-bit MULS/Conditional MUL. */
c19d1205 13132 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 13133 inst.instruction |= Rd;
b05fe5cf 13134
fdfde340
JM
13135 if (Rd == Rn)
13136 inst.instruction |= Rm << 3;
13137 else if (Rd == Rm)
13138 inst.instruction |= Rn << 3;
c19d1205
ZW
13139 else
13140 constraint (1, _("dest must overlap one source register"));
13141 }
17828f45
JM
13142 else
13143 {
e07e6e58
NC
13144 constraint (inst.instruction != T_MNEM_mul,
13145 _("Thumb-2 MUL must not set flags"));
17828f45
JM
13146 /* 32-bit MUL. */
13147 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13148 inst.instruction |= Rd << 8;
13149 inst.instruction |= Rn << 16;
13150 inst.instruction |= Rm << 0;
13151
13152 reject_bad_reg (Rd);
13153 reject_bad_reg (Rn);
13154 reject_bad_reg (Rm);
17828f45 13155 }
c19d1205 13156}
b05fe5cf 13157
c19d1205
ZW
13158static void
13159do_t_mull (void)
13160{
fdfde340 13161 unsigned RdLo, RdHi, Rn, Rm;
b05fe5cf 13162
fdfde340
JM
13163 RdLo = inst.operands[0].reg;
13164 RdHi = inst.operands[1].reg;
13165 Rn = inst.operands[2].reg;
13166 Rm = inst.operands[3].reg;
13167
13168 reject_bad_reg (RdLo);
13169 reject_bad_reg (RdHi);
13170 reject_bad_reg (Rn);
13171 reject_bad_reg (Rm);
13172
13173 inst.instruction |= RdLo << 12;
13174 inst.instruction |= RdHi << 8;
13175 inst.instruction |= Rn << 16;
13176 inst.instruction |= Rm;
13177
13178 if (RdLo == RdHi)
c19d1205
ZW
13179 as_tsktsk (_("rdhi and rdlo must be different"));
13180}
b05fe5cf 13181
c19d1205
ZW
13182static void
13183do_t_nop (void)
13184{
5ee91343 13185 set_pred_insn_type (NEUTRAL_IT_INSN);
e07e6e58 13186
c19d1205
ZW
13187 if (unified_syntax)
13188 {
13189 if (inst.size_req == 4 || inst.operands[0].imm > 15)
b05fe5cf 13190 {
c19d1205
ZW
13191 inst.instruction = THUMB_OP32 (inst.instruction);
13192 inst.instruction |= inst.operands[0].imm;
13193 }
13194 else
13195 {
bc2d1808
NC
13196 /* PR9722: Check for Thumb2 availability before
13197 generating a thumb2 nop instruction. */
afa62d5e 13198 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2))
bc2d1808
NC
13199 {
13200 inst.instruction = THUMB_OP16 (inst.instruction);
13201 inst.instruction |= inst.operands[0].imm << 4;
13202 }
13203 else
13204 inst.instruction = 0x46c0;
c19d1205
ZW
13205 }
13206 }
13207 else
13208 {
13209 constraint (inst.operands[0].present,
13210 _("Thumb does not support NOP with hints"));
13211 inst.instruction = 0x46c0;
13212 }
13213}
b05fe5cf 13214
c19d1205
ZW
13215static void
13216do_t_neg (void)
13217{
13218 if (unified_syntax)
13219 {
3d388997
PB
13220 bfd_boolean narrow;
13221
13222 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 13223 narrow = !in_pred_block ();
3d388997 13224 else
5ee91343 13225 narrow = in_pred_block ();
3d388997
PB
13226 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
13227 narrow = FALSE;
13228 if (inst.size_req == 4)
13229 narrow = FALSE;
13230
13231 if (!narrow)
c19d1205
ZW
13232 {
13233 inst.instruction = THUMB_OP32 (inst.instruction);
13234 inst.instruction |= inst.operands[0].reg << 8;
13235 inst.instruction |= inst.operands[1].reg << 16;
b05fe5cf
ZW
13236 }
13237 else
13238 {
c19d1205
ZW
13239 inst.instruction = THUMB_OP16 (inst.instruction);
13240 inst.instruction |= inst.operands[0].reg;
13241 inst.instruction |= inst.operands[1].reg << 3;
b05fe5cf
ZW
13242 }
13243 }
13244 else
13245 {
c19d1205
ZW
13246 constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7,
13247 BAD_HIREG);
13248 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
13249
13250 inst.instruction = THUMB_OP16 (inst.instruction);
13251 inst.instruction |= inst.operands[0].reg;
13252 inst.instruction |= inst.operands[1].reg << 3;
13253 }
13254}
13255
1c444d06
JM
13256static void
13257do_t_orn (void)
13258{
13259 unsigned Rd, Rn;
13260
13261 Rd = inst.operands[0].reg;
13262 Rn = inst.operands[1].present ? inst.operands[1].reg : Rd;
13263
fdfde340
JM
13264 reject_bad_reg (Rd);
13265 /* Rn == REG_SP is unpredictable; Rn == REG_PC is MVN. */
13266 reject_bad_reg (Rn);
13267
1c444d06
JM
13268 inst.instruction |= Rd << 8;
13269 inst.instruction |= Rn << 16;
13270
13271 if (!inst.operands[2].isreg)
13272 {
13273 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 13274 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
1c444d06
JM
13275 }
13276 else
13277 {
13278 unsigned Rm;
13279
13280 Rm = inst.operands[2].reg;
fdfde340 13281 reject_bad_reg (Rm);
1c444d06
JM
13282
13283 constraint (inst.operands[2].shifted
13284 && inst.operands[2].immisreg,
13285 _("shift must be constant"));
13286 encode_thumb32_shifted_operand (2);
13287 }
13288}
13289
c19d1205
ZW
13290static void
13291do_t_pkhbt (void)
13292{
fdfde340
JM
13293 unsigned Rd, Rn, Rm;
13294
13295 Rd = inst.operands[0].reg;
13296 Rn = inst.operands[1].reg;
13297 Rm = inst.operands[2].reg;
13298
13299 reject_bad_reg (Rd);
13300 reject_bad_reg (Rn);
13301 reject_bad_reg (Rm);
13302
13303 inst.instruction |= Rd << 8;
13304 inst.instruction |= Rn << 16;
13305 inst.instruction |= Rm;
c19d1205
ZW
13306 if (inst.operands[3].present)
13307 {
e2b0ab59
AV
13308 unsigned int val = inst.relocs[0].exp.X_add_number;
13309 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
13310 _("expression too complex"));
13311 inst.instruction |= (val & 0x1c) << 10;
13312 inst.instruction |= (val & 0x03) << 6;
b05fe5cf 13313 }
c19d1205 13314}
b05fe5cf 13315
c19d1205
ZW
13316static void
13317do_t_pkhtb (void)
13318{
13319 if (!inst.operands[3].present)
1ef52f49
NC
13320 {
13321 unsigned Rtmp;
13322
13323 inst.instruction &= ~0x00000020;
13324
13325 /* PR 10168. Swap the Rm and Rn registers. */
13326 Rtmp = inst.operands[1].reg;
13327 inst.operands[1].reg = inst.operands[2].reg;
13328 inst.operands[2].reg = Rtmp;
13329 }
c19d1205 13330 do_t_pkhbt ();
b05fe5cf
ZW
13331}
13332
c19d1205
ZW
13333static void
13334do_t_pld (void)
13335{
fdfde340
JM
13336 if (inst.operands[0].immisreg)
13337 reject_bad_reg (inst.operands[0].imm);
13338
c19d1205
ZW
13339 encode_thumb32_addr_mode (0, /*is_t=*/FALSE, /*is_d=*/FALSE);
13340}
b05fe5cf 13341
c19d1205
ZW
13342static void
13343do_t_push_pop (void)
b99bd4ef 13344{
e9f89963 13345 unsigned mask;
5f4273c7 13346
c19d1205
ZW
13347 constraint (inst.operands[0].writeback,
13348 _("push/pop do not support {reglist}^"));
e2b0ab59 13349 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205 13350 _("expression too complex"));
b99bd4ef 13351
e9f89963 13352 mask = inst.operands[0].imm;
d3bfe16e 13353 if (inst.size_req != 4 && (mask & ~0xff) == 0)
3c707909 13354 inst.instruction = THUMB_OP16 (inst.instruction) | mask;
d3bfe16e 13355 else if (inst.size_req != 4
c6025a80 13356 && (mask & ~0xff) == (1U << (inst.instruction == T_MNEM_push
d3bfe16e 13357 ? REG_LR : REG_PC)))
b99bd4ef 13358 {
c19d1205
ZW
13359 inst.instruction = THUMB_OP16 (inst.instruction);
13360 inst.instruction |= THUMB_PP_PC_LR;
3c707909 13361 inst.instruction |= mask & 0xff;
c19d1205
ZW
13362 }
13363 else if (unified_syntax)
13364 {
3c707909 13365 inst.instruction = THUMB_OP32 (inst.instruction);
4b5a202f
AV
13366 encode_thumb2_multi (TRUE /* do_io */, 13, mask, TRUE);
13367 }
13368 else
13369 {
13370 inst.error = _("invalid register list to push/pop instruction");
13371 return;
c19d1205 13372 }
4b5a202f
AV
13373}
13374
13375static void
13376do_t_clrm (void)
13377{
13378 if (unified_syntax)
13379 encode_thumb2_multi (FALSE /* do_io */, -1, inst.operands[0].imm, FALSE);
c19d1205
ZW
13380 else
13381 {
13382 inst.error = _("invalid register list to push/pop instruction");
13383 return;
13384 }
c19d1205 13385}
b99bd4ef 13386
efd6b359
AV
13387static void
13388do_t_vscclrm (void)
13389{
13390 if (inst.operands[0].issingle)
13391 {
13392 inst.instruction |= (inst.operands[0].reg & 0x1) << 22;
13393 inst.instruction |= (inst.operands[0].reg & 0x1e) << 11;
13394 inst.instruction |= inst.operands[0].imm;
13395 }
13396 else
13397 {
13398 inst.instruction |= (inst.operands[0].reg & 0x10) << 18;
13399 inst.instruction |= (inst.operands[0].reg & 0xf) << 12;
13400 inst.instruction |= 1 << 8;
13401 inst.instruction |= inst.operands[0].imm << 1;
13402 }
13403}
13404
c19d1205
ZW
13405static void
13406do_t_rbit (void)
13407{
fdfde340
JM
13408 unsigned Rd, Rm;
13409
13410 Rd = inst.operands[0].reg;
13411 Rm = inst.operands[1].reg;
13412
13413 reject_bad_reg (Rd);
13414 reject_bad_reg (Rm);
13415
13416 inst.instruction |= Rd << 8;
13417 inst.instruction |= Rm << 16;
13418 inst.instruction |= Rm;
c19d1205 13419}
b99bd4ef 13420
c19d1205
ZW
13421static void
13422do_t_rev (void)
13423{
fdfde340
JM
13424 unsigned Rd, Rm;
13425
13426 Rd = inst.operands[0].reg;
13427 Rm = inst.operands[1].reg;
13428
13429 reject_bad_reg (Rd);
13430 reject_bad_reg (Rm);
13431
13432 if (Rd <= 7 && Rm <= 7
c19d1205
ZW
13433 && inst.size_req != 4)
13434 {
13435 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13436 inst.instruction |= Rd;
13437 inst.instruction |= Rm << 3;
c19d1205
ZW
13438 }
13439 else if (unified_syntax)
13440 {
13441 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13442 inst.instruction |= Rd << 8;
13443 inst.instruction |= Rm << 16;
13444 inst.instruction |= Rm;
c19d1205
ZW
13445 }
13446 else
13447 inst.error = BAD_HIREG;
13448}
b99bd4ef 13449
1c444d06
JM
13450static void
13451do_t_rrx (void)
13452{
13453 unsigned Rd, Rm;
13454
13455 Rd = inst.operands[0].reg;
13456 Rm = inst.operands[1].reg;
13457
fdfde340
JM
13458 reject_bad_reg (Rd);
13459 reject_bad_reg (Rm);
c921be7d 13460
1c444d06
JM
13461 inst.instruction |= Rd << 8;
13462 inst.instruction |= Rm;
13463}
13464
c19d1205
ZW
13465static void
13466do_t_rsb (void)
13467{
fdfde340 13468 unsigned Rd, Rs;
b99bd4ef 13469
c19d1205
ZW
13470 Rd = inst.operands[0].reg;
13471 Rs = (inst.operands[1].present
13472 ? inst.operands[1].reg /* Rd, Rs, foo */
13473 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
b99bd4ef 13474
fdfde340
JM
13475 reject_bad_reg (Rd);
13476 reject_bad_reg (Rs);
13477 if (inst.operands[2].isreg)
13478 reject_bad_reg (inst.operands[2].reg);
13479
c19d1205
ZW
13480 inst.instruction |= Rd << 8;
13481 inst.instruction |= Rs << 16;
13482 if (!inst.operands[2].isreg)
13483 {
026d3abb
PB
13484 bfd_boolean narrow;
13485
13486 if ((inst.instruction & 0x00100000) != 0)
5ee91343 13487 narrow = !in_pred_block ();
026d3abb 13488 else
5ee91343 13489 narrow = in_pred_block ();
026d3abb
PB
13490
13491 if (Rd > 7 || Rs > 7)
13492 narrow = FALSE;
13493
13494 if (inst.size_req == 4 || !unified_syntax)
13495 narrow = FALSE;
13496
e2b0ab59
AV
13497 if (inst.relocs[0].exp.X_op != O_constant
13498 || inst.relocs[0].exp.X_add_number != 0)
026d3abb
PB
13499 narrow = FALSE;
13500
13501 /* Turn rsb #0 into 16-bit neg. We should probably do this via
477330fc 13502 relaxation, but it doesn't seem worth the hassle. */
026d3abb
PB
13503 if (narrow)
13504 {
e2b0ab59 13505 inst.relocs[0].type = BFD_RELOC_UNUSED;
026d3abb
PB
13506 inst.instruction = THUMB_OP16 (T_MNEM_negs);
13507 inst.instruction |= Rs << 3;
13508 inst.instruction |= Rd;
13509 }
13510 else
13511 {
13512 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 13513 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
026d3abb 13514 }
c19d1205
ZW
13515 }
13516 else
13517 encode_thumb32_shifted_operand (2);
13518}
b99bd4ef 13519
c19d1205
ZW
13520static void
13521do_t_setend (void)
13522{
12e37cbc
MGD
13523 if (warn_on_deprecated
13524 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 13525 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 13526
5ee91343 13527 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205
ZW
13528 if (inst.operands[0].imm)
13529 inst.instruction |= 0x8;
13530}
b99bd4ef 13531
c19d1205
ZW
13532static void
13533do_t_shift (void)
13534{
13535 if (!inst.operands[1].present)
13536 inst.operands[1].reg = inst.operands[0].reg;
13537
13538 if (unified_syntax)
13539 {
3d388997
PB
13540 bfd_boolean narrow;
13541 int shift_kind;
13542
13543 switch (inst.instruction)
13544 {
13545 case T_MNEM_asr:
13546 case T_MNEM_asrs: shift_kind = SHIFT_ASR; break;
13547 case T_MNEM_lsl:
13548 case T_MNEM_lsls: shift_kind = SHIFT_LSL; break;
13549 case T_MNEM_lsr:
13550 case T_MNEM_lsrs: shift_kind = SHIFT_LSR; break;
13551 case T_MNEM_ror:
13552 case T_MNEM_rors: shift_kind = SHIFT_ROR; break;
13553 default: abort ();
13554 }
13555
13556 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 13557 narrow = !in_pred_block ();
3d388997 13558 else
5ee91343 13559 narrow = in_pred_block ();
3d388997
PB
13560 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
13561 narrow = FALSE;
13562 if (!inst.operands[2].isreg && shift_kind == SHIFT_ROR)
13563 narrow = FALSE;
13564 if (inst.operands[2].isreg
13565 && (inst.operands[1].reg != inst.operands[0].reg
13566 || inst.operands[2].reg > 7))
13567 narrow = FALSE;
13568 if (inst.size_req == 4)
13569 narrow = FALSE;
13570
fdfde340
JM
13571 reject_bad_reg (inst.operands[0].reg);
13572 reject_bad_reg (inst.operands[1].reg);
c921be7d 13573
3d388997 13574 if (!narrow)
c19d1205
ZW
13575 {
13576 if (inst.operands[2].isreg)
b99bd4ef 13577 {
fdfde340 13578 reject_bad_reg (inst.operands[2].reg);
c19d1205
ZW
13579 inst.instruction = THUMB_OP32 (inst.instruction);
13580 inst.instruction |= inst.operands[0].reg << 8;
13581 inst.instruction |= inst.operands[1].reg << 16;
13582 inst.instruction |= inst.operands[2].reg;
94342ec3
NC
13583
13584 /* PR 12854: Error on extraneous shifts. */
13585 constraint (inst.operands[2].shifted,
13586 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
13587 }
13588 else
13589 {
13590 inst.operands[1].shifted = 1;
3d388997 13591 inst.operands[1].shift_kind = shift_kind;
c19d1205
ZW
13592 inst.instruction = THUMB_OP32 (THUMB_SETS_FLAGS (inst.instruction)
13593 ? T_MNEM_movs : T_MNEM_mov);
13594 inst.instruction |= inst.operands[0].reg << 8;
13595 encode_thumb32_shifted_operand (1);
13596 /* Prevent the incorrect generation of an ARM_IMMEDIATE fixup. */
e2b0ab59 13597 inst.relocs[0].type = BFD_RELOC_UNUSED;
b99bd4ef
NC
13598 }
13599 }
13600 else
13601 {
c19d1205 13602 if (inst.operands[2].isreg)
b99bd4ef 13603 {
3d388997 13604 switch (shift_kind)
b99bd4ef 13605 {
3d388997
PB
13606 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_R; break;
13607 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_R; break;
13608 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_R; break;
13609 case SHIFT_ROR: inst.instruction = T_OPCODE_ROR_R; break;
c19d1205 13610 default: abort ();
b99bd4ef 13611 }
5f4273c7 13612
c19d1205
ZW
13613 inst.instruction |= inst.operands[0].reg;
13614 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
13615
13616 /* PR 12854: Error on extraneous shifts. */
13617 constraint (inst.operands[2].shifted,
13618 _("extraneous shift as part of operand to shift insn"));
b99bd4ef
NC
13619 }
13620 else
13621 {
3d388997 13622 switch (shift_kind)
b99bd4ef 13623 {
3d388997
PB
13624 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
13625 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
13626 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
c19d1205 13627 default: abort ();
b99bd4ef 13628 }
e2b0ab59 13629 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
13630 inst.instruction |= inst.operands[0].reg;
13631 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
13632 }
13633 }
c19d1205
ZW
13634 }
13635 else
13636 {
13637 constraint (inst.operands[0].reg > 7
13638 || inst.operands[1].reg > 7, BAD_HIREG);
13639 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
b99bd4ef 13640
c19d1205
ZW
13641 if (inst.operands[2].isreg) /* Rd, {Rs,} Rn */
13642 {
13643 constraint (inst.operands[2].reg > 7, BAD_HIREG);
13644 constraint (inst.operands[0].reg != inst.operands[1].reg,
13645 _("source1 and dest must be same register"));
b99bd4ef 13646
c19d1205
ZW
13647 switch (inst.instruction)
13648 {
13649 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_R; break;
13650 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_R; break;
13651 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_R; break;
13652 case T_MNEM_ror: inst.instruction = T_OPCODE_ROR_R; break;
13653 default: abort ();
13654 }
5f4273c7 13655
c19d1205
ZW
13656 inst.instruction |= inst.operands[0].reg;
13657 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
13658
13659 /* PR 12854: Error on extraneous shifts. */
13660 constraint (inst.operands[2].shifted,
13661 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
13662 }
13663 else
b99bd4ef 13664 {
c19d1205
ZW
13665 switch (inst.instruction)
13666 {
13667 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_I; break;
13668 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_I; break;
13669 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_I; break;
13670 case T_MNEM_ror: inst.error = _("ror #imm not supported"); return;
13671 default: abort ();
13672 }
e2b0ab59 13673 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
13674 inst.instruction |= inst.operands[0].reg;
13675 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
13676 }
13677 }
b99bd4ef
NC
13678}
13679
13680static void
c19d1205 13681do_t_simd (void)
b99bd4ef 13682{
fdfde340
JM
13683 unsigned Rd, Rn, Rm;
13684
13685 Rd = inst.operands[0].reg;
13686 Rn = inst.operands[1].reg;
13687 Rm = 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;
c19d1205 13696}
b99bd4ef 13697
03ee1b7f
NC
13698static void
13699do_t_simd2 (void)
13700{
13701 unsigned Rd, Rn, Rm;
13702
13703 Rd = inst.operands[0].reg;
13704 Rm = inst.operands[1].reg;
13705 Rn = inst.operands[2].reg;
13706
13707 reject_bad_reg (Rd);
13708 reject_bad_reg (Rn);
13709 reject_bad_reg (Rm);
13710
13711 inst.instruction |= Rd << 8;
13712 inst.instruction |= Rn << 16;
13713 inst.instruction |= Rm;
13714}
13715
c19d1205 13716static void
3eb17e6b 13717do_t_smc (void)
c19d1205 13718{
e2b0ab59 13719 unsigned int value = inst.relocs[0].exp.X_add_number;
f4c65163
MGD
13720 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a),
13721 _("SMC is not permitted on this architecture"));
e2b0ab59 13722 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 13723 _("expression too complex"));
e2b0ab59 13724 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205
ZW
13725 inst.instruction |= (value & 0xf000) >> 12;
13726 inst.instruction |= (value & 0x0ff0);
13727 inst.instruction |= (value & 0x000f) << 16;
24382199 13728 /* PR gas/15623: SMC instructions must be last in an IT block. */
5ee91343 13729 set_pred_insn_type_last ();
c19d1205 13730}
b99bd4ef 13731
90ec0d68
MGD
13732static void
13733do_t_hvc (void)
13734{
e2b0ab59 13735 unsigned int value = inst.relocs[0].exp.X_add_number;
90ec0d68 13736
e2b0ab59 13737 inst.relocs[0].type = BFD_RELOC_UNUSED;
90ec0d68
MGD
13738 inst.instruction |= (value & 0x0fff);
13739 inst.instruction |= (value & 0xf000) << 4;
13740}
13741
c19d1205 13742static void
3a21c15a 13743do_t_ssat_usat (int bias)
c19d1205 13744{
fdfde340
JM
13745 unsigned Rd, Rn;
13746
13747 Rd = inst.operands[0].reg;
13748 Rn = inst.operands[2].reg;
13749
13750 reject_bad_reg (Rd);
13751 reject_bad_reg (Rn);
13752
13753 inst.instruction |= Rd << 8;
3a21c15a 13754 inst.instruction |= inst.operands[1].imm - bias;
fdfde340 13755 inst.instruction |= Rn << 16;
b99bd4ef 13756
c19d1205 13757 if (inst.operands[3].present)
b99bd4ef 13758 {
e2b0ab59 13759 offsetT shift_amount = inst.relocs[0].exp.X_add_number;
3a21c15a 13760
e2b0ab59 13761 inst.relocs[0].type = BFD_RELOC_UNUSED;
3a21c15a 13762
e2b0ab59 13763 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 13764 _("expression too complex"));
b99bd4ef 13765
3a21c15a 13766 if (shift_amount != 0)
6189168b 13767 {
3a21c15a
NC
13768 constraint (shift_amount > 31,
13769 _("shift expression is too large"));
13770
c19d1205 13771 if (inst.operands[3].shift_kind == SHIFT_ASR)
3a21c15a
NC
13772 inst.instruction |= 0x00200000; /* sh bit. */
13773
13774 inst.instruction |= (shift_amount & 0x1c) << 10;
13775 inst.instruction |= (shift_amount & 0x03) << 6;
6189168b
NC
13776 }
13777 }
b99bd4ef 13778}
c921be7d 13779
3a21c15a
NC
13780static void
13781do_t_ssat (void)
13782{
13783 do_t_ssat_usat (1);
13784}
b99bd4ef 13785
0dd132b6 13786static void
c19d1205 13787do_t_ssat16 (void)
0dd132b6 13788{
fdfde340
JM
13789 unsigned Rd, Rn;
13790
13791 Rd = inst.operands[0].reg;
13792 Rn = inst.operands[2].reg;
13793
13794 reject_bad_reg (Rd);
13795 reject_bad_reg (Rn);
13796
13797 inst.instruction |= Rd << 8;
c19d1205 13798 inst.instruction |= inst.operands[1].imm - 1;
fdfde340 13799 inst.instruction |= Rn << 16;
c19d1205 13800}
0dd132b6 13801
c19d1205
ZW
13802static void
13803do_t_strex (void)
13804{
13805 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
13806 || inst.operands[2].postind || inst.operands[2].writeback
13807 || inst.operands[2].immisreg || inst.operands[2].shifted
13808 || inst.operands[2].negative,
01cfc07f 13809 BAD_ADDR_MODE);
0dd132b6 13810
5be8be5d
DG
13811 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
13812
c19d1205
ZW
13813 inst.instruction |= inst.operands[0].reg << 8;
13814 inst.instruction |= inst.operands[1].reg << 12;
13815 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 13816 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
0dd132b6
NC
13817}
13818
b99bd4ef 13819static void
c19d1205 13820do_t_strexd (void)
b99bd4ef 13821{
c19d1205
ZW
13822 if (!inst.operands[2].present)
13823 inst.operands[2].reg = inst.operands[1].reg + 1;
b99bd4ef 13824
c19d1205
ZW
13825 constraint (inst.operands[0].reg == inst.operands[1].reg
13826 || inst.operands[0].reg == inst.operands[2].reg
f8a8e9d6 13827 || inst.operands[0].reg == inst.operands[3].reg,
c19d1205 13828 BAD_OVERLAP);
b99bd4ef 13829
c19d1205
ZW
13830 inst.instruction |= inst.operands[0].reg;
13831 inst.instruction |= inst.operands[1].reg << 12;
13832 inst.instruction |= inst.operands[2].reg << 8;
13833 inst.instruction |= inst.operands[3].reg << 16;
b99bd4ef
NC
13834}
13835
13836static void
c19d1205 13837do_t_sxtah (void)
b99bd4ef 13838{
fdfde340
JM
13839 unsigned Rd, Rn, Rm;
13840
13841 Rd = inst.operands[0].reg;
13842 Rn = inst.operands[1].reg;
13843 Rm = inst.operands[2].reg;
13844
13845 reject_bad_reg (Rd);
13846 reject_bad_reg (Rn);
13847 reject_bad_reg (Rm);
13848
13849 inst.instruction |= Rd << 8;
13850 inst.instruction |= Rn << 16;
13851 inst.instruction |= Rm;
c19d1205
ZW
13852 inst.instruction |= inst.operands[3].imm << 4;
13853}
b99bd4ef 13854
c19d1205
ZW
13855static void
13856do_t_sxth (void)
13857{
fdfde340
JM
13858 unsigned Rd, Rm;
13859
13860 Rd = inst.operands[0].reg;
13861 Rm = inst.operands[1].reg;
13862
13863 reject_bad_reg (Rd);
13864 reject_bad_reg (Rm);
c921be7d
NC
13865
13866 if (inst.instruction <= 0xffff
13867 && inst.size_req != 4
fdfde340 13868 && Rd <= 7 && Rm <= 7
c19d1205 13869 && (!inst.operands[2].present || inst.operands[2].imm == 0))
b99bd4ef 13870 {
c19d1205 13871 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13872 inst.instruction |= Rd;
13873 inst.instruction |= Rm << 3;
b99bd4ef 13874 }
c19d1205 13875 else if (unified_syntax)
b99bd4ef 13876 {
c19d1205
ZW
13877 if (inst.instruction <= 0xffff)
13878 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13879 inst.instruction |= Rd << 8;
13880 inst.instruction |= Rm;
c19d1205 13881 inst.instruction |= inst.operands[2].imm << 4;
b99bd4ef 13882 }
c19d1205 13883 else
b99bd4ef 13884 {
c19d1205
ZW
13885 constraint (inst.operands[2].present && inst.operands[2].imm != 0,
13886 _("Thumb encoding does not support rotation"));
13887 constraint (1, BAD_HIREG);
b99bd4ef 13888 }
c19d1205 13889}
b99bd4ef 13890
c19d1205
ZW
13891static void
13892do_t_swi (void)
13893{
e2b0ab59 13894 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
c19d1205 13895}
b99bd4ef 13896
92e90b6e
PB
13897static void
13898do_t_tb (void)
13899{
fdfde340 13900 unsigned Rn, Rm;
92e90b6e
PB
13901 int half;
13902
13903 half = (inst.instruction & 0x10) != 0;
5ee91343 13904 set_pred_insn_type_last ();
dfa9f0d5
PB
13905 constraint (inst.operands[0].immisreg,
13906 _("instruction requires register index"));
fdfde340
JM
13907
13908 Rn = inst.operands[0].reg;
13909 Rm = inst.operands[0].imm;
c921be7d 13910
5c8ed6a4
JW
13911 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
13912 constraint (Rn == REG_SP, BAD_SP);
fdfde340
JM
13913 reject_bad_reg (Rm);
13914
92e90b6e
PB
13915 constraint (!half && inst.operands[0].shifted,
13916 _("instruction does not allow shifted index"));
fdfde340 13917 inst.instruction |= (Rn << 16) | Rm;
92e90b6e
PB
13918}
13919
74db7efb
NC
13920static void
13921do_t_udf (void)
13922{
13923 if (!inst.operands[0].present)
13924 inst.operands[0].imm = 0;
13925
13926 if ((unsigned int) inst.operands[0].imm > 255 || inst.size_req == 4)
13927 {
13928 constraint (inst.size_req == 2,
13929 _("immediate value out of range"));
13930 inst.instruction = THUMB_OP32 (inst.instruction);
13931 inst.instruction |= (inst.operands[0].imm & 0xf000u) << 4;
13932 inst.instruction |= (inst.operands[0].imm & 0x0fffu) << 0;
13933 }
13934 else
13935 {
13936 inst.instruction = THUMB_OP16 (inst.instruction);
13937 inst.instruction |= inst.operands[0].imm;
13938 }
13939
5ee91343 13940 set_pred_insn_type (NEUTRAL_IT_INSN);
74db7efb
NC
13941}
13942
13943
c19d1205
ZW
13944static void
13945do_t_usat (void)
13946{
3a21c15a 13947 do_t_ssat_usat (0);
b99bd4ef
NC
13948}
13949
13950static void
c19d1205 13951do_t_usat16 (void)
b99bd4ef 13952{
fdfde340
JM
13953 unsigned Rd, Rn;
13954
13955 Rd = inst.operands[0].reg;
13956 Rn = inst.operands[2].reg;
13957
13958 reject_bad_reg (Rd);
13959 reject_bad_reg (Rn);
13960
13961 inst.instruction |= Rd << 8;
c19d1205 13962 inst.instruction |= inst.operands[1].imm;
fdfde340 13963 inst.instruction |= Rn << 16;
b99bd4ef 13964}
c19d1205 13965
e12437dc
AV
13966/* Checking the range of the branch offset (VAL) with NBITS bits
13967 and IS_SIGNED signedness. Also checks the LSB to be 0. */
13968static int
13969v8_1_branch_value_check (int val, int nbits, int is_signed)
13970{
13971 gas_assert (nbits > 0 && nbits <= 32);
13972 if (is_signed)
13973 {
13974 int cmp = (1 << (nbits - 1));
13975 if ((val < -cmp) || (val >= cmp) || (val & 0x01))
13976 return FAIL;
13977 }
13978 else
13979 {
13980 if ((val <= 0) || (val >= (1 << nbits)) || (val & 0x1))
13981 return FAIL;
13982 }
13983 return SUCCESS;
13984}
13985
4389b29a
AV
13986/* For branches in Armv8.1-M Mainline. */
13987static void
13988do_t_branch_future (void)
13989{
13990 unsigned long insn = inst.instruction;
13991
13992 inst.instruction = THUMB_OP32 (inst.instruction);
13993 if (inst.operands[0].hasreloc == 0)
13994 {
13995 if (v8_1_branch_value_check (inst.operands[0].imm, 5, FALSE) == FAIL)
13996 as_bad (BAD_BRANCH_OFF);
13997
13998 inst.instruction |= ((inst.operands[0].imm & 0x1f) >> 1) << 23;
13999 }
14000 else
14001 {
14002 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH5;
14003 inst.relocs[0].pc_rel = 1;
14004 }
14005
14006 switch (insn)
14007 {
14008 case T_MNEM_bf:
14009 if (inst.operands[1].hasreloc == 0)
14010 {
14011 int val = inst.operands[1].imm;
14012 if (v8_1_branch_value_check (inst.operands[1].imm, 17, TRUE) == FAIL)
14013 as_bad (BAD_BRANCH_OFF);
14014
14015 int immA = (val & 0x0001f000) >> 12;
14016 int immB = (val & 0x00000ffc) >> 2;
14017 int immC = (val & 0x00000002) >> 1;
14018 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14019 }
14020 else
14021 {
14022 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF17;
14023 inst.relocs[1].pc_rel = 1;
14024 }
14025 break;
14026
65d1bc05
AV
14027 case T_MNEM_bfl:
14028 if (inst.operands[1].hasreloc == 0)
14029 {
14030 int val = inst.operands[1].imm;
14031 if (v8_1_branch_value_check (inst.operands[1].imm, 19, TRUE) == FAIL)
14032 as_bad (BAD_BRANCH_OFF);
14033
14034 int immA = (val & 0x0007f000) >> 12;
14035 int immB = (val & 0x00000ffc) >> 2;
14036 int immC = (val & 0x00000002) >> 1;
14037 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14038 }
14039 else
14040 {
14041 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF19;
14042 inst.relocs[1].pc_rel = 1;
14043 }
14044 break;
14045
f6b2b12d
AV
14046 case T_MNEM_bfcsel:
14047 /* Operand 1. */
14048 if (inst.operands[1].hasreloc == 0)
14049 {
14050 int val = inst.operands[1].imm;
14051 int immA = (val & 0x00001000) >> 12;
14052 int immB = (val & 0x00000ffc) >> 2;
14053 int immC = (val & 0x00000002) >> 1;
14054 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14055 }
14056 else
14057 {
14058 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF13;
14059 inst.relocs[1].pc_rel = 1;
14060 }
14061
14062 /* Operand 2. */
14063 if (inst.operands[2].hasreloc == 0)
14064 {
14065 constraint ((inst.operands[0].hasreloc != 0), BAD_ARGS);
14066 int val2 = inst.operands[2].imm;
14067 int val0 = inst.operands[0].imm & 0x1f;
14068 int diff = val2 - val0;
14069 if (diff == 4)
14070 inst.instruction |= 1 << 17; /* T bit. */
14071 else if (diff != 2)
14072 as_bad (_("out of range label-relative fixup value"));
14073 }
14074 else
14075 {
14076 constraint ((inst.operands[0].hasreloc == 0), BAD_ARGS);
14077 inst.relocs[2].type = BFD_RELOC_THUMB_PCREL_BFCSEL;
14078 inst.relocs[2].pc_rel = 1;
14079 }
14080
14081 /* Operand 3. */
14082 constraint (inst.cond != COND_ALWAYS, BAD_COND);
14083 inst.instruction |= (inst.operands[3].imm & 0xf) << 18;
14084 break;
14085
f1c7f421
AV
14086 case T_MNEM_bfx:
14087 case T_MNEM_bflx:
14088 inst.instruction |= inst.operands[1].reg << 16;
14089 break;
14090
4389b29a
AV
14091 default: abort ();
14092 }
14093}
14094
60f993ce
AV
14095/* Helper function for do_t_loloop to handle relocations. */
14096static void
14097v8_1_loop_reloc (int is_le)
14098{
14099 if (inst.relocs[0].exp.X_op == O_constant)
14100 {
14101 int value = inst.relocs[0].exp.X_add_number;
14102 value = (is_le) ? -value : value;
14103
14104 if (v8_1_branch_value_check (value, 12, FALSE) == FAIL)
14105 as_bad (BAD_BRANCH_OFF);
14106
14107 int imml, immh;
14108
14109 immh = (value & 0x00000ffc) >> 2;
14110 imml = (value & 0x00000002) >> 1;
14111
14112 inst.instruction |= (imml << 11) | (immh << 1);
14113 }
14114 else
14115 {
14116 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_LOOP12;
14117 inst.relocs[0].pc_rel = 1;
14118 }
14119}
14120
a302e574
AV
14121/* MVE instruction encoder helpers. */
14122#define M_MNEM_vabav 0xee800f01
14123#define M_MNEM_vmladav 0xeef00e00
14124#define M_MNEM_vmladava 0xeef00e20
14125#define M_MNEM_vmladavx 0xeef01e00
14126#define M_MNEM_vmladavax 0xeef01e20
14127#define M_MNEM_vmlsdav 0xeef00e01
14128#define M_MNEM_vmlsdava 0xeef00e21
14129#define M_MNEM_vmlsdavx 0xeef01e01
14130#define M_MNEM_vmlsdavax 0xeef01e21
886e1c73
AV
14131#define M_MNEM_vmullt 0xee011e00
14132#define M_MNEM_vmullb 0xee010e00
35c228db
AV
14133#define M_MNEM_vst20 0xfc801e00
14134#define M_MNEM_vst21 0xfc801e20
14135#define M_MNEM_vst40 0xfc801e01
14136#define M_MNEM_vst41 0xfc801e21
14137#define M_MNEM_vst42 0xfc801e41
14138#define M_MNEM_vst43 0xfc801e61
14139#define M_MNEM_vld20 0xfc901e00
14140#define M_MNEM_vld21 0xfc901e20
14141#define M_MNEM_vld40 0xfc901e01
14142#define M_MNEM_vld41 0xfc901e21
14143#define M_MNEM_vld42 0xfc901e41
14144#define M_MNEM_vld43 0xfc901e61
f5f10c66
AV
14145#define M_MNEM_vstrb 0xec000e00
14146#define M_MNEM_vstrh 0xec000e10
14147#define M_MNEM_vstrw 0xec000e40
14148#define M_MNEM_vstrd 0xec000e50
14149#define M_MNEM_vldrb 0xec100e00
14150#define M_MNEM_vldrh 0xec100e10
14151#define M_MNEM_vldrw 0xec100e40
14152#define M_MNEM_vldrd 0xec100e50
57785aa2
AV
14153#define M_MNEM_vmovlt 0xeea01f40
14154#define M_MNEM_vmovlb 0xeea00f40
14155#define M_MNEM_vmovnt 0xfe311e81
14156#define M_MNEM_vmovnb 0xfe310e81
c2dafc2a
AV
14157#define M_MNEM_vadc 0xee300f00
14158#define M_MNEM_vadci 0xee301f00
14159#define M_MNEM_vbrsr 0xfe011e60
26c1e780
AV
14160#define M_MNEM_vaddlv 0xee890f00
14161#define M_MNEM_vaddlva 0xee890f20
14162#define M_MNEM_vaddv 0xeef10f00
14163#define M_MNEM_vaddva 0xeef10f20
b409bdb6
AV
14164#define M_MNEM_vddup 0xee011f6e
14165#define M_MNEM_vdwdup 0xee011f60
14166#define M_MNEM_vidup 0xee010f6e
14167#define M_MNEM_viwdup 0xee010f60
13ccd4c0
AV
14168#define M_MNEM_vmaxv 0xeee20f00
14169#define M_MNEM_vmaxav 0xeee00f00
14170#define M_MNEM_vminv 0xeee20f80
14171#define M_MNEM_vminav 0xeee00f80
93925576
AV
14172#define M_MNEM_vmlaldav 0xee800e00
14173#define M_MNEM_vmlaldava 0xee800e20
14174#define M_MNEM_vmlaldavx 0xee801e00
14175#define M_MNEM_vmlaldavax 0xee801e20
14176#define M_MNEM_vmlsldav 0xee800e01
14177#define M_MNEM_vmlsldava 0xee800e21
14178#define M_MNEM_vmlsldavx 0xee801e01
14179#define M_MNEM_vmlsldavax 0xee801e21
14180#define M_MNEM_vrmlaldavhx 0xee801f00
14181#define M_MNEM_vrmlaldavhax 0xee801f20
14182#define M_MNEM_vrmlsldavh 0xfe800e01
14183#define M_MNEM_vrmlsldavha 0xfe800e21
14184#define M_MNEM_vrmlsldavhx 0xfe801e01
14185#define M_MNEM_vrmlsldavhax 0xfe801e21
1be7aba3
AV
14186#define M_MNEM_vqmovnt 0xee331e01
14187#define M_MNEM_vqmovnb 0xee330e01
14188#define M_MNEM_vqmovunt 0xee311e81
14189#define M_MNEM_vqmovunb 0xee310e81
4aa88b50
AV
14190#define M_MNEM_vshrnt 0xee801fc1
14191#define M_MNEM_vshrnb 0xee800fc1
14192#define M_MNEM_vrshrnt 0xfe801fc1
14193#define M_MNEM_vqshrnt 0xee801f40
14194#define M_MNEM_vqshrnb 0xee800f40
14195#define M_MNEM_vqshrunt 0xee801fc0
14196#define M_MNEM_vqshrunb 0xee800fc0
14197#define M_MNEM_vrshrnb 0xfe800fc1
14198#define M_MNEM_vqrshrnt 0xee801f41
14199#define M_MNEM_vqrshrnb 0xee800f41
14200#define M_MNEM_vqrshrunt 0xfe801fc0
14201#define M_MNEM_vqrshrunb 0xfe800fc0
a302e574 14202
5287ad62 14203/* Neon instruction encoder helpers. */
5f4273c7 14204
5287ad62 14205/* Encodings for the different types for various Neon opcodes. */
b99bd4ef 14206
5287ad62
JB
14207/* An "invalid" code for the following tables. */
14208#define N_INV -1u
14209
14210struct neon_tab_entry
b99bd4ef 14211{
5287ad62
JB
14212 unsigned integer;
14213 unsigned float_or_poly;
14214 unsigned scalar_or_imm;
14215};
5f4273c7 14216
5287ad62
JB
14217/* Map overloaded Neon opcodes to their respective encodings. */
14218#define NEON_ENC_TAB \
14219 X(vabd, 0x0000700, 0x1200d00, N_INV), \
5ee91343 14220 X(vabdl, 0x0800700, N_INV, N_INV), \
5287ad62
JB
14221 X(vmax, 0x0000600, 0x0000f00, N_INV), \
14222 X(vmin, 0x0000610, 0x0200f00, N_INV), \
14223 X(vpadd, 0x0000b10, 0x1000d00, N_INV), \
14224 X(vpmax, 0x0000a00, 0x1000f00, N_INV), \
14225 X(vpmin, 0x0000a10, 0x1200f00, N_INV), \
14226 X(vadd, 0x0000800, 0x0000d00, N_INV), \
5ee91343 14227 X(vaddl, 0x0800000, N_INV, N_INV), \
5287ad62 14228 X(vsub, 0x1000800, 0x0200d00, N_INV), \
5ee91343 14229 X(vsubl, 0x0800200, N_INV, N_INV), \
5287ad62
JB
14230 X(vceq, 0x1000810, 0x0000e00, 0x1b10100), \
14231 X(vcge, 0x0000310, 0x1000e00, 0x1b10080), \
14232 X(vcgt, 0x0000300, 0x1200e00, 0x1b10000), \
14233 /* Register variants of the following two instructions are encoded as
e07e6e58 14234 vcge / vcgt with the operands reversed. */ \
92559b5b
PB
14235 X(vclt, 0x0000300, 0x1200e00, 0x1b10200), \
14236 X(vcle, 0x0000310, 0x1000e00, 0x1b10180), \
62f3b8c8
PB
14237 X(vfma, N_INV, 0x0000c10, N_INV), \
14238 X(vfms, N_INV, 0x0200c10, N_INV), \
5287ad62
JB
14239 X(vmla, 0x0000900, 0x0000d10, 0x0800040), \
14240 X(vmls, 0x1000900, 0x0200d10, 0x0800440), \
14241 X(vmul, 0x0000910, 0x1000d10, 0x0800840), \
14242 X(vmull, 0x0800c00, 0x0800e00, 0x0800a40), /* polynomial not float. */ \
14243 X(vmlal, 0x0800800, N_INV, 0x0800240), \
14244 X(vmlsl, 0x0800a00, N_INV, 0x0800640), \
14245 X(vqdmlal, 0x0800900, N_INV, 0x0800340), \
14246 X(vqdmlsl, 0x0800b00, N_INV, 0x0800740), \
14247 X(vqdmull, 0x0800d00, N_INV, 0x0800b40), \
14248 X(vqdmulh, 0x0000b00, N_INV, 0x0800c40), \
14249 X(vqrdmulh, 0x1000b00, N_INV, 0x0800d40), \
d6b4b13e
MW
14250 X(vqrdmlah, 0x3000b10, N_INV, 0x0800e40), \
14251 X(vqrdmlsh, 0x3000c10, N_INV, 0x0800f40), \
5287ad62
JB
14252 X(vshl, 0x0000400, N_INV, 0x0800510), \
14253 X(vqshl, 0x0000410, N_INV, 0x0800710), \
14254 X(vand, 0x0000110, N_INV, 0x0800030), \
14255 X(vbic, 0x0100110, N_INV, 0x0800030), \
14256 X(veor, 0x1000110, N_INV, N_INV), \
14257 X(vorn, 0x0300110, N_INV, 0x0800010), \
14258 X(vorr, 0x0200110, N_INV, 0x0800010), \
14259 X(vmvn, 0x1b00580, N_INV, 0x0800030), \
14260 X(vshll, 0x1b20300, N_INV, 0x0800a10), /* max shift, immediate. */ \
14261 X(vcvt, 0x1b30600, N_INV, 0x0800e10), /* integer, fixed-point. */ \
14262 X(vdup, 0xe800b10, N_INV, 0x1b00c00), /* arm, scalar. */ \
14263 X(vld1, 0x0200000, 0x0a00000, 0x0a00c00), /* interlv, lane, dup. */ \
14264 X(vst1, 0x0000000, 0x0800000, N_INV), \
14265 X(vld2, 0x0200100, 0x0a00100, 0x0a00d00), \
14266 X(vst2, 0x0000100, 0x0800100, N_INV), \
14267 X(vld3, 0x0200200, 0x0a00200, 0x0a00e00), \
14268 X(vst3, 0x0000200, 0x0800200, N_INV), \
14269 X(vld4, 0x0200300, 0x0a00300, 0x0a00f00), \
14270 X(vst4, 0x0000300, 0x0800300, N_INV), \
14271 X(vmovn, 0x1b20200, N_INV, N_INV), \
14272 X(vtrn, 0x1b20080, N_INV, N_INV), \
14273 X(vqmovn, 0x1b20200, N_INV, N_INV), \
037e8744
JB
14274 X(vqmovun, 0x1b20240, N_INV, N_INV), \
14275 X(vnmul, 0xe200a40, 0xe200b40, N_INV), \
e6655fda
PB
14276 X(vnmla, 0xe100a40, 0xe100b40, N_INV), \
14277 X(vnmls, 0xe100a00, 0xe100b00, N_INV), \
62f3b8c8
PB
14278 X(vfnma, 0xe900a40, 0xe900b40, N_INV), \
14279 X(vfnms, 0xe900a00, 0xe900b00, N_INV), \
037e8744
JB
14280 X(vcmp, 0xeb40a40, 0xeb40b40, N_INV), \
14281 X(vcmpz, 0xeb50a40, 0xeb50b40, N_INV), \
14282 X(vcmpe, 0xeb40ac0, 0xeb40bc0, N_INV), \
33399f07
MGD
14283 X(vcmpez, 0xeb50ac0, 0xeb50bc0, N_INV), \
14284 X(vseleq, 0xe000a00, N_INV, N_INV), \
14285 X(vselvs, 0xe100a00, N_INV, N_INV), \
14286 X(vselge, 0xe200a00, N_INV, N_INV), \
73924fbc
MGD
14287 X(vselgt, 0xe300a00, N_INV, N_INV), \
14288 X(vmaxnm, 0xe800a00, 0x3000f10, N_INV), \
7e8e6784 14289 X(vminnm, 0xe800a40, 0x3200f10, N_INV), \
30bdf752
MGD
14290 X(vcvta, 0xebc0a40, 0x3bb0000, N_INV), \
14291 X(vrintr, 0xeb60a40, 0x3ba0400, N_INV), \
91ff7894 14292 X(vrinta, 0xeb80a40, 0x3ba0400, N_INV), \
48adcd8e 14293 X(aes, 0x3b00300, N_INV, N_INV), \
3c9017d2
MGD
14294 X(sha3op, 0x2000c00, N_INV, N_INV), \
14295 X(sha1h, 0x3b902c0, N_INV, N_INV), \
14296 X(sha2op, 0x3ba0380, N_INV, N_INV)
5287ad62
JB
14297
14298enum neon_opc
14299{
14300#define X(OPC,I,F,S) N_MNEM_##OPC
14301NEON_ENC_TAB
14302#undef X
14303};
b99bd4ef 14304
5287ad62
JB
14305static const struct neon_tab_entry neon_enc_tab[] =
14306{
14307#define X(OPC,I,F,S) { (I), (F), (S) }
14308NEON_ENC_TAB
14309#undef X
14310};
b99bd4ef 14311
88714cb8
DG
14312/* Do not use these macros; instead, use NEON_ENCODE defined below. */
14313#define NEON_ENC_INTEGER_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14314#define NEON_ENC_ARMREG_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14315#define NEON_ENC_POLY_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14316#define NEON_ENC_FLOAT_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14317#define NEON_ENC_SCALAR_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14318#define NEON_ENC_IMMED_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14319#define NEON_ENC_INTERLV_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14320#define NEON_ENC_LANE_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14321#define NEON_ENC_DUP_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14322#define NEON_ENC_SINGLE_(X) \
037e8744 14323 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf0000000))
88714cb8 14324#define NEON_ENC_DOUBLE_(X) \
037e8744 14325 ((neon_enc_tab[(X) & 0x0fffffff].float_or_poly) | ((X) & 0xf0000000))
33399f07
MGD
14326#define NEON_ENC_FPV8_(X) \
14327 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf000000))
5287ad62 14328
88714cb8
DG
14329#define NEON_ENCODE(type, inst) \
14330 do \
14331 { \
14332 inst.instruction = NEON_ENC_##type##_ (inst.instruction); \
14333 inst.is_neon = 1; \
14334 } \
14335 while (0)
14336
14337#define check_neon_suffixes \
14338 do \
14339 { \
14340 if (!inst.error && inst.vectype.elems > 0 && !inst.is_neon) \
14341 { \
14342 as_bad (_("invalid neon suffix for non neon instruction")); \
14343 return; \
14344 } \
14345 } \
14346 while (0)
14347
037e8744
JB
14348/* Define shapes for instruction operands. The following mnemonic characters
14349 are used in this table:
5287ad62 14350
037e8744 14351 F - VFP S<n> register
5287ad62
JB
14352 D - Neon D<n> register
14353 Q - Neon Q<n> register
14354 I - Immediate
14355 S - Scalar
14356 R - ARM register
14357 L - D<n> register list
5f4273c7 14358
037e8744
JB
14359 This table is used to generate various data:
14360 - enumerations of the form NS_DDR to be used as arguments to
14361 neon_select_shape.
14362 - a table classifying shapes into single, double, quad, mixed.
5f4273c7 14363 - a table used to drive neon_select_shape. */
b99bd4ef 14364
037e8744 14365#define NEON_SHAPE_DEF \
93925576 14366 X(4, (R, R, Q, Q), QUAD), \
b409bdb6 14367 X(4, (Q, R, R, I), QUAD), \
57785aa2
AV
14368 X(4, (R, R, S, S), QUAD), \
14369 X(4, (S, S, R, R), QUAD), \
b409bdb6 14370 X(3, (Q, R, I), QUAD), \
1b883319
AV
14371 X(3, (I, Q, Q), QUAD), \
14372 X(3, (I, Q, R), QUAD), \
a302e574 14373 X(3, (R, Q, Q), QUAD), \
037e8744
JB
14374 X(3, (D, D, D), DOUBLE), \
14375 X(3, (Q, Q, Q), QUAD), \
14376 X(3, (D, D, I), DOUBLE), \
14377 X(3, (Q, Q, I), QUAD), \
14378 X(3, (D, D, S), DOUBLE), \
14379 X(3, (Q, Q, S), QUAD), \
5ee91343 14380 X(3, (Q, Q, R), QUAD), \
26c1e780
AV
14381 X(3, (R, R, Q), QUAD), \
14382 X(2, (R, Q), QUAD), \
037e8744
JB
14383 X(2, (D, D), DOUBLE), \
14384 X(2, (Q, Q), QUAD), \
14385 X(2, (D, S), DOUBLE), \
14386 X(2, (Q, S), QUAD), \
14387 X(2, (D, R), DOUBLE), \
14388 X(2, (Q, R), QUAD), \
14389 X(2, (D, I), DOUBLE), \
14390 X(2, (Q, I), QUAD), \
14391 X(3, (D, L, D), DOUBLE), \
14392 X(2, (D, Q), MIXED), \
14393 X(2, (Q, D), MIXED), \
14394 X(3, (D, Q, I), MIXED), \
14395 X(3, (Q, D, I), MIXED), \
14396 X(3, (Q, D, D), MIXED), \
14397 X(3, (D, Q, Q), MIXED), \
14398 X(3, (Q, Q, D), MIXED), \
14399 X(3, (Q, D, S), MIXED), \
14400 X(3, (D, Q, S), MIXED), \
14401 X(4, (D, D, D, I), DOUBLE), \
14402 X(4, (Q, Q, Q, I), QUAD), \
c28eeff2
SN
14403 X(4, (D, D, S, I), DOUBLE), \
14404 X(4, (Q, Q, S, I), QUAD), \
037e8744
JB
14405 X(2, (F, F), SINGLE), \
14406 X(3, (F, F, F), SINGLE), \
14407 X(2, (F, I), SINGLE), \
14408 X(2, (F, D), MIXED), \
14409 X(2, (D, F), MIXED), \
14410 X(3, (F, F, I), MIXED), \
14411 X(4, (R, R, F, F), SINGLE), \
14412 X(4, (F, F, R, R), SINGLE), \
14413 X(3, (D, R, R), DOUBLE), \
14414 X(3, (R, R, D), DOUBLE), \
14415 X(2, (S, R), SINGLE), \
14416 X(2, (R, S), SINGLE), \
14417 X(2, (F, R), SINGLE), \
d54af2d0 14418 X(2, (R, F), SINGLE), \
1f6234a3
AV
14419/* Used for MVE tail predicated loop instructions. */\
14420 X(2, (R, R), QUAD), \
d54af2d0
RL
14421/* Half float shape supported so far. */\
14422 X (2, (H, D), MIXED), \
14423 X (2, (D, H), MIXED), \
14424 X (2, (H, F), MIXED), \
14425 X (2, (F, H), MIXED), \
14426 X (2, (H, H), HALF), \
14427 X (2, (H, R), HALF), \
14428 X (2, (R, H), HALF), \
14429 X (2, (H, I), HALF), \
14430 X (3, (H, H, H), HALF), \
14431 X (3, (H, F, I), MIXED), \
dec41383
JW
14432 X (3, (F, H, I), MIXED), \
14433 X (3, (D, H, H), MIXED), \
14434 X (3, (D, H, S), MIXED)
037e8744
JB
14435
14436#define S2(A,B) NS_##A##B
14437#define S3(A,B,C) NS_##A##B##C
14438#define S4(A,B,C,D) NS_##A##B##C##D
14439
14440#define X(N, L, C) S##N L
14441
5287ad62
JB
14442enum neon_shape
14443{
037e8744
JB
14444 NEON_SHAPE_DEF,
14445 NS_NULL
5287ad62 14446};
b99bd4ef 14447
037e8744
JB
14448#undef X
14449#undef S2
14450#undef S3
14451#undef S4
14452
14453enum neon_shape_class
14454{
d54af2d0 14455 SC_HALF,
037e8744
JB
14456 SC_SINGLE,
14457 SC_DOUBLE,
14458 SC_QUAD,
14459 SC_MIXED
14460};
14461
14462#define X(N, L, C) SC_##C
14463
14464static enum neon_shape_class neon_shape_class[] =
14465{
14466 NEON_SHAPE_DEF
14467};
14468
14469#undef X
14470
14471enum neon_shape_el
14472{
d54af2d0 14473 SE_H,
037e8744
JB
14474 SE_F,
14475 SE_D,
14476 SE_Q,
14477 SE_I,
14478 SE_S,
14479 SE_R,
14480 SE_L
14481};
14482
14483/* Register widths of above. */
14484static unsigned neon_shape_el_size[] =
14485{
d54af2d0 14486 16,
037e8744
JB
14487 32,
14488 64,
14489 128,
14490 0,
14491 32,
14492 32,
14493 0
14494};
14495
14496struct neon_shape_info
14497{
14498 unsigned els;
14499 enum neon_shape_el el[NEON_MAX_TYPE_ELS];
14500};
14501
14502#define S2(A,B) { SE_##A, SE_##B }
14503#define S3(A,B,C) { SE_##A, SE_##B, SE_##C }
14504#define S4(A,B,C,D) { SE_##A, SE_##B, SE_##C, SE_##D }
14505
14506#define X(N, L, C) { N, S##N L }
14507
14508static struct neon_shape_info neon_shape_tab[] =
14509{
14510 NEON_SHAPE_DEF
14511};
14512
14513#undef X
14514#undef S2
14515#undef S3
14516#undef S4
14517
5287ad62
JB
14518/* Bit masks used in type checking given instructions.
14519 'N_EQK' means the type must be the same as (or based on in some way) the key
14520 type, which itself is marked with the 'N_KEY' bit. If the 'N_EQK' bit is
14521 set, various other bits can be set as well in order to modify the meaning of
14522 the type constraint. */
14523
14524enum neon_type_mask
14525{
8e79c3df
CM
14526 N_S8 = 0x0000001,
14527 N_S16 = 0x0000002,
14528 N_S32 = 0x0000004,
14529 N_S64 = 0x0000008,
14530 N_U8 = 0x0000010,
14531 N_U16 = 0x0000020,
14532 N_U32 = 0x0000040,
14533 N_U64 = 0x0000080,
14534 N_I8 = 0x0000100,
14535 N_I16 = 0x0000200,
14536 N_I32 = 0x0000400,
14537 N_I64 = 0x0000800,
14538 N_8 = 0x0001000,
14539 N_16 = 0x0002000,
14540 N_32 = 0x0004000,
14541 N_64 = 0x0008000,
14542 N_P8 = 0x0010000,
14543 N_P16 = 0x0020000,
14544 N_F16 = 0x0040000,
14545 N_F32 = 0x0080000,
14546 N_F64 = 0x0100000,
4f51b4bd 14547 N_P64 = 0x0200000,
c921be7d
NC
14548 N_KEY = 0x1000000, /* Key element (main type specifier). */
14549 N_EQK = 0x2000000, /* Given operand has the same type & size as the key. */
8e79c3df 14550 N_VFP = 0x4000000, /* VFP mode: operand size must match register width. */
91ff7894 14551 N_UNT = 0x8000000, /* Must be explicitly untyped. */
c921be7d
NC
14552 N_DBL = 0x0000001, /* If N_EQK, this operand is twice the size. */
14553 N_HLF = 0x0000002, /* If N_EQK, this operand is half the size. */
14554 N_SGN = 0x0000004, /* If N_EQK, this operand is forced to be signed. */
14555 N_UNS = 0x0000008, /* If N_EQK, this operand is forced to be unsigned. */
14556 N_INT = 0x0000010, /* If N_EQK, this operand is forced to be integer. */
14557 N_FLT = 0x0000020, /* If N_EQK, this operand is forced to be float. */
14558 N_SIZ = 0x0000040, /* If N_EQK, this operand is forced to be size-only. */
5287ad62 14559 N_UTYP = 0,
4f51b4bd 14560 N_MAX_NONSPECIAL = N_P64
5287ad62
JB
14561};
14562
dcbf9037
JB
14563#define N_ALLMODS (N_DBL | N_HLF | N_SGN | N_UNS | N_INT | N_FLT | N_SIZ)
14564
5287ad62
JB
14565#define N_SU_ALL (N_S8 | N_S16 | N_S32 | N_S64 | N_U8 | N_U16 | N_U32 | N_U64)
14566#define N_SU_32 (N_S8 | N_S16 | N_S32 | N_U8 | N_U16 | N_U32)
14567#define N_SU_16_64 (N_S16 | N_S32 | N_S64 | N_U16 | N_U32 | N_U64)
cc933301
JW
14568#define N_S_32 (N_S8 | N_S16 | N_S32)
14569#define N_F_16_32 (N_F16 | N_F32)
14570#define N_SUF_32 (N_SU_32 | N_F_16_32)
5287ad62 14571#define N_I_ALL (N_I8 | N_I16 | N_I32 | N_I64)
cc933301 14572#define N_IF_32 (N_I8 | N_I16 | N_I32 | N_F16 | N_F32)
d54af2d0 14573#define N_F_ALL (N_F16 | N_F32 | N_F64)
5ee91343
AV
14574#define N_I_MVE (N_I8 | N_I16 | N_I32)
14575#define N_F_MVE (N_F16 | N_F32)
14576#define N_SU_MVE (N_S8 | N_S16 | N_S32 | N_U8 | N_U16 | N_U32)
5287ad62
JB
14577
14578/* Pass this as the first type argument to neon_check_type to ignore types
14579 altogether. */
14580#define N_IGNORE_TYPE (N_KEY | N_EQK)
14581
037e8744
JB
14582/* Select a "shape" for the current instruction (describing register types or
14583 sizes) from a list of alternatives. Return NS_NULL if the current instruction
14584 doesn't fit. For non-polymorphic shapes, checking is usually done as a
14585 function of operand parsing, so this function doesn't need to be called.
14586 Shapes should be listed in order of decreasing length. */
5287ad62
JB
14587
14588static enum neon_shape
037e8744 14589neon_select_shape (enum neon_shape shape, ...)
5287ad62 14590{
037e8744
JB
14591 va_list ap;
14592 enum neon_shape first_shape = shape;
5287ad62
JB
14593
14594 /* Fix missing optional operands. FIXME: we don't know at this point how
14595 many arguments we should have, so this makes the assumption that we have
14596 > 1. This is true of all current Neon opcodes, I think, but may not be
14597 true in the future. */
14598 if (!inst.operands[1].present)
14599 inst.operands[1] = inst.operands[0];
14600
037e8744 14601 va_start (ap, shape);
5f4273c7 14602
21d799b5 14603 for (; shape != NS_NULL; shape = (enum neon_shape) va_arg (ap, int))
037e8744
JB
14604 {
14605 unsigned j;
14606 int matches = 1;
14607
14608 for (j = 0; j < neon_shape_tab[shape].els; j++)
477330fc
RM
14609 {
14610 if (!inst.operands[j].present)
14611 {
14612 matches = 0;
14613 break;
14614 }
14615
14616 switch (neon_shape_tab[shape].el[j])
14617 {
d54af2d0
RL
14618 /* If a .f16, .16, .u16, .s16 type specifier is given over
14619 a VFP single precision register operand, it's essentially
14620 means only half of the register is used.
14621
14622 If the type specifier is given after the mnemonics, the
14623 information is stored in inst.vectype. If the type specifier
14624 is given after register operand, the information is stored
14625 in inst.operands[].vectype.
14626
14627 When there is only one type specifier, and all the register
14628 operands are the same type of hardware register, the type
14629 specifier applies to all register operands.
14630
14631 If no type specifier is given, the shape is inferred from
14632 operand information.
14633
14634 for example:
14635 vadd.f16 s0, s1, s2: NS_HHH
14636 vabs.f16 s0, s1: NS_HH
14637 vmov.f16 s0, r1: NS_HR
14638 vmov.f16 r0, s1: NS_RH
14639 vcvt.f16 r0, s1: NS_RH
14640 vcvt.f16.s32 s2, s2, #29: NS_HFI
14641 vcvt.f16.s32 s2, s2: NS_HF
14642 */
14643 case SE_H:
14644 if (!(inst.operands[j].isreg
14645 && inst.operands[j].isvec
14646 && inst.operands[j].issingle
14647 && !inst.operands[j].isquad
14648 && ((inst.vectype.elems == 1
14649 && inst.vectype.el[0].size == 16)
14650 || (inst.vectype.elems > 1
14651 && inst.vectype.el[j].size == 16)
14652 || (inst.vectype.elems == 0
14653 && inst.operands[j].vectype.type != NT_invtype
14654 && inst.operands[j].vectype.size == 16))))
14655 matches = 0;
14656 break;
14657
477330fc
RM
14658 case SE_F:
14659 if (!(inst.operands[j].isreg
14660 && inst.operands[j].isvec
14661 && inst.operands[j].issingle
d54af2d0
RL
14662 && !inst.operands[j].isquad
14663 && ((inst.vectype.elems == 1 && inst.vectype.el[0].size == 32)
14664 || (inst.vectype.elems > 1 && inst.vectype.el[j].size == 32)
14665 || (inst.vectype.elems == 0
14666 && (inst.operands[j].vectype.size == 32
14667 || inst.operands[j].vectype.type == NT_invtype)))))
477330fc
RM
14668 matches = 0;
14669 break;
14670
14671 case SE_D:
14672 if (!(inst.operands[j].isreg
14673 && inst.operands[j].isvec
14674 && !inst.operands[j].isquad
14675 && !inst.operands[j].issingle))
14676 matches = 0;
14677 break;
14678
14679 case SE_R:
14680 if (!(inst.operands[j].isreg
14681 && !inst.operands[j].isvec))
14682 matches = 0;
14683 break;
14684
14685 case SE_Q:
14686 if (!(inst.operands[j].isreg
14687 && inst.operands[j].isvec
14688 && inst.operands[j].isquad
14689 && !inst.operands[j].issingle))
14690 matches = 0;
14691 break;
14692
14693 case SE_I:
14694 if (!(!inst.operands[j].isreg
14695 && !inst.operands[j].isscalar))
14696 matches = 0;
14697 break;
14698
14699 case SE_S:
14700 if (!(!inst.operands[j].isreg
14701 && inst.operands[j].isscalar))
14702 matches = 0;
14703 break;
14704
14705 case SE_L:
14706 break;
14707 }
3fde54a2
JZ
14708 if (!matches)
14709 break;
477330fc 14710 }
ad6cec43
MGD
14711 if (matches && (j >= ARM_IT_MAX_OPERANDS || !inst.operands[j].present))
14712 /* We've matched all the entries in the shape table, and we don't
14713 have any left over operands which have not been matched. */
477330fc 14714 break;
037e8744 14715 }
5f4273c7 14716
037e8744 14717 va_end (ap);
5287ad62 14718
037e8744
JB
14719 if (shape == NS_NULL && first_shape != NS_NULL)
14720 first_error (_("invalid instruction shape"));
5287ad62 14721
037e8744
JB
14722 return shape;
14723}
5287ad62 14724
037e8744
JB
14725/* True if SHAPE is predominantly a quadword operation (most of the time, this
14726 means the Q bit should be set). */
14727
14728static int
14729neon_quad (enum neon_shape shape)
14730{
14731 return neon_shape_class[shape] == SC_QUAD;
5287ad62 14732}
037e8744 14733
5287ad62
JB
14734static void
14735neon_modify_type_size (unsigned typebits, enum neon_el_type *g_type,
477330fc 14736 unsigned *g_size)
5287ad62
JB
14737{
14738 /* Allow modification to be made to types which are constrained to be
14739 based on the key element, based on bits set alongside N_EQK. */
14740 if ((typebits & N_EQK) != 0)
14741 {
14742 if ((typebits & N_HLF) != 0)
14743 *g_size /= 2;
14744 else if ((typebits & N_DBL) != 0)
14745 *g_size *= 2;
14746 if ((typebits & N_SGN) != 0)
14747 *g_type = NT_signed;
14748 else if ((typebits & N_UNS) != 0)
477330fc 14749 *g_type = NT_unsigned;
5287ad62 14750 else if ((typebits & N_INT) != 0)
477330fc 14751 *g_type = NT_integer;
5287ad62 14752 else if ((typebits & N_FLT) != 0)
477330fc 14753 *g_type = NT_float;
dcbf9037 14754 else if ((typebits & N_SIZ) != 0)
477330fc 14755 *g_type = NT_untyped;
5287ad62
JB
14756 }
14757}
5f4273c7 14758
5287ad62
JB
14759/* Return operand OPNO promoted by bits set in THISARG. KEY should be the "key"
14760 operand type, i.e. the single type specified in a Neon instruction when it
14761 is the only one given. */
14762
14763static struct neon_type_el
14764neon_type_promote (struct neon_type_el *key, unsigned thisarg)
14765{
14766 struct neon_type_el dest = *key;
5f4273c7 14767
9c2799c2 14768 gas_assert ((thisarg & N_EQK) != 0);
5f4273c7 14769
5287ad62
JB
14770 neon_modify_type_size (thisarg, &dest.type, &dest.size);
14771
14772 return dest;
14773}
14774
14775/* Convert Neon type and size into compact bitmask representation. */
14776
14777static enum neon_type_mask
14778type_chk_of_el_type (enum neon_el_type type, unsigned size)
14779{
14780 switch (type)
14781 {
14782 case NT_untyped:
14783 switch (size)
477330fc
RM
14784 {
14785 case 8: return N_8;
14786 case 16: return N_16;
14787 case 32: return N_32;
14788 case 64: return N_64;
14789 default: ;
14790 }
5287ad62
JB
14791 break;
14792
14793 case NT_integer:
14794 switch (size)
477330fc
RM
14795 {
14796 case 8: return N_I8;
14797 case 16: return N_I16;
14798 case 32: return N_I32;
14799 case 64: return N_I64;
14800 default: ;
14801 }
5287ad62
JB
14802 break;
14803
14804 case NT_float:
037e8744 14805 switch (size)
477330fc 14806 {
8e79c3df 14807 case 16: return N_F16;
477330fc
RM
14808 case 32: return N_F32;
14809 case 64: return N_F64;
14810 default: ;
14811 }
5287ad62
JB
14812 break;
14813
14814 case NT_poly:
14815 switch (size)
477330fc
RM
14816 {
14817 case 8: return N_P8;
14818 case 16: return N_P16;
4f51b4bd 14819 case 64: return N_P64;
477330fc
RM
14820 default: ;
14821 }
5287ad62
JB
14822 break;
14823
14824 case NT_signed:
14825 switch (size)
477330fc
RM
14826 {
14827 case 8: return N_S8;
14828 case 16: return N_S16;
14829 case 32: return N_S32;
14830 case 64: return N_S64;
14831 default: ;
14832 }
5287ad62
JB
14833 break;
14834
14835 case NT_unsigned:
14836 switch (size)
477330fc
RM
14837 {
14838 case 8: return N_U8;
14839 case 16: return N_U16;
14840 case 32: return N_U32;
14841 case 64: return N_U64;
14842 default: ;
14843 }
5287ad62
JB
14844 break;
14845
14846 default: ;
14847 }
5f4273c7 14848
5287ad62
JB
14849 return N_UTYP;
14850}
14851
14852/* Convert compact Neon bitmask type representation to a type and size. Only
14853 handles the case where a single bit is set in the mask. */
14854
dcbf9037 14855static int
5287ad62 14856el_type_of_type_chk (enum neon_el_type *type, unsigned *size,
477330fc 14857 enum neon_type_mask mask)
5287ad62 14858{
dcbf9037
JB
14859 if ((mask & N_EQK) != 0)
14860 return FAIL;
14861
5287ad62
JB
14862 if ((mask & (N_S8 | N_U8 | N_I8 | N_8 | N_P8)) != 0)
14863 *size = 8;
c70a8987 14864 else if ((mask & (N_S16 | N_U16 | N_I16 | N_16 | N_F16 | N_P16)) != 0)
5287ad62 14865 *size = 16;
dcbf9037 14866 else if ((mask & (N_S32 | N_U32 | N_I32 | N_32 | N_F32)) != 0)
5287ad62 14867 *size = 32;
4f51b4bd 14868 else if ((mask & (N_S64 | N_U64 | N_I64 | N_64 | N_F64 | N_P64)) != 0)
5287ad62 14869 *size = 64;
dcbf9037
JB
14870 else
14871 return FAIL;
14872
5287ad62
JB
14873 if ((mask & (N_S8 | N_S16 | N_S32 | N_S64)) != 0)
14874 *type = NT_signed;
dcbf9037 14875 else if ((mask & (N_U8 | N_U16 | N_U32 | N_U64)) != 0)
5287ad62 14876 *type = NT_unsigned;
dcbf9037 14877 else if ((mask & (N_I8 | N_I16 | N_I32 | N_I64)) != 0)
5287ad62 14878 *type = NT_integer;
dcbf9037 14879 else if ((mask & (N_8 | N_16 | N_32 | N_64)) != 0)
5287ad62 14880 *type = NT_untyped;
4f51b4bd 14881 else if ((mask & (N_P8 | N_P16 | N_P64)) != 0)
5287ad62 14882 *type = NT_poly;
d54af2d0 14883 else if ((mask & (N_F_ALL)) != 0)
5287ad62 14884 *type = NT_float;
dcbf9037
JB
14885 else
14886 return FAIL;
5f4273c7 14887
dcbf9037 14888 return SUCCESS;
5287ad62
JB
14889}
14890
14891/* Modify a bitmask of allowed types. This is only needed for type
14892 relaxation. */
14893
14894static unsigned
14895modify_types_allowed (unsigned allowed, unsigned mods)
14896{
14897 unsigned size;
14898 enum neon_el_type type;
14899 unsigned destmask;
14900 int i;
5f4273c7 14901
5287ad62 14902 destmask = 0;
5f4273c7 14903
5287ad62
JB
14904 for (i = 1; i <= N_MAX_NONSPECIAL; i <<= 1)
14905 {
21d799b5 14906 if (el_type_of_type_chk (&type, &size,
477330fc
RM
14907 (enum neon_type_mask) (allowed & i)) == SUCCESS)
14908 {
14909 neon_modify_type_size (mods, &type, &size);
14910 destmask |= type_chk_of_el_type (type, size);
14911 }
5287ad62 14912 }
5f4273c7 14913
5287ad62
JB
14914 return destmask;
14915}
14916
14917/* Check type and return type classification.
14918 The manual states (paraphrase): If one datatype is given, it indicates the
14919 type given in:
14920 - the second operand, if there is one
14921 - the operand, if there is no second operand
14922 - the result, if there are no operands.
14923 This isn't quite good enough though, so we use a concept of a "key" datatype
14924 which is set on a per-instruction basis, which is the one which matters when
14925 only one data type is written.
14926 Note: this function has side-effects (e.g. filling in missing operands). All
037e8744 14927 Neon instructions should call it before performing bit encoding. */
5287ad62
JB
14928
14929static struct neon_type_el
14930neon_check_type (unsigned els, enum neon_shape ns, ...)
14931{
14932 va_list ap;
14933 unsigned i, pass, key_el = 0;
14934 unsigned types[NEON_MAX_TYPE_ELS];
14935 enum neon_el_type k_type = NT_invtype;
14936 unsigned k_size = -1u;
14937 struct neon_type_el badtype = {NT_invtype, -1};
14938 unsigned key_allowed = 0;
14939
14940 /* Optional registers in Neon instructions are always (not) in operand 1.
14941 Fill in the missing operand here, if it was omitted. */
14942 if (els > 1 && !inst.operands[1].present)
14943 inst.operands[1] = inst.operands[0];
14944
14945 /* Suck up all the varargs. */
14946 va_start (ap, ns);
14947 for (i = 0; i < els; i++)
14948 {
14949 unsigned thisarg = va_arg (ap, unsigned);
14950 if (thisarg == N_IGNORE_TYPE)
477330fc
RM
14951 {
14952 va_end (ap);
14953 return badtype;
14954 }
5287ad62
JB
14955 types[i] = thisarg;
14956 if ((thisarg & N_KEY) != 0)
477330fc 14957 key_el = i;
5287ad62
JB
14958 }
14959 va_end (ap);
14960
dcbf9037
JB
14961 if (inst.vectype.elems > 0)
14962 for (i = 0; i < els; i++)
14963 if (inst.operands[i].vectype.type != NT_invtype)
477330fc
RM
14964 {
14965 first_error (_("types specified in both the mnemonic and operands"));
14966 return badtype;
14967 }
dcbf9037 14968
5287ad62
JB
14969 /* Duplicate inst.vectype elements here as necessary.
14970 FIXME: No idea if this is exactly the same as the ARM assembler,
14971 particularly when an insn takes one register and one non-register
14972 operand. */
14973 if (inst.vectype.elems == 1 && els > 1)
14974 {
14975 unsigned j;
14976 inst.vectype.elems = els;
14977 inst.vectype.el[key_el] = inst.vectype.el[0];
14978 for (j = 0; j < els; j++)
477330fc
RM
14979 if (j != key_el)
14980 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
14981 types[j]);
dcbf9037
JB
14982 }
14983 else if (inst.vectype.elems == 0 && els > 0)
14984 {
14985 unsigned j;
14986 /* No types were given after the mnemonic, so look for types specified
477330fc
RM
14987 after each operand. We allow some flexibility here; as long as the
14988 "key" operand has a type, we can infer the others. */
dcbf9037 14989 for (j = 0; j < els; j++)
477330fc
RM
14990 if (inst.operands[j].vectype.type != NT_invtype)
14991 inst.vectype.el[j] = inst.operands[j].vectype;
dcbf9037
JB
14992
14993 if (inst.operands[key_el].vectype.type != NT_invtype)
477330fc
RM
14994 {
14995 for (j = 0; j < els; j++)
14996 if (inst.operands[j].vectype.type == NT_invtype)
14997 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
14998 types[j]);
14999 }
dcbf9037 15000 else
477330fc
RM
15001 {
15002 first_error (_("operand types can't be inferred"));
15003 return badtype;
15004 }
5287ad62
JB
15005 }
15006 else if (inst.vectype.elems != els)
15007 {
dcbf9037 15008 first_error (_("type specifier has the wrong number of parts"));
5287ad62
JB
15009 return badtype;
15010 }
15011
15012 for (pass = 0; pass < 2; pass++)
15013 {
15014 for (i = 0; i < els; i++)
477330fc
RM
15015 {
15016 unsigned thisarg = types[i];
15017 unsigned types_allowed = ((thisarg & N_EQK) != 0 && pass != 0)
15018 ? modify_types_allowed (key_allowed, thisarg) : thisarg;
15019 enum neon_el_type g_type = inst.vectype.el[i].type;
15020 unsigned g_size = inst.vectype.el[i].size;
15021
15022 /* Decay more-specific signed & unsigned types to sign-insensitive
5287ad62 15023 integer types if sign-specific variants are unavailable. */
477330fc 15024 if ((g_type == NT_signed || g_type == NT_unsigned)
5287ad62
JB
15025 && (types_allowed & N_SU_ALL) == 0)
15026 g_type = NT_integer;
15027
477330fc 15028 /* If only untyped args are allowed, decay any more specific types to
5287ad62
JB
15029 them. Some instructions only care about signs for some element
15030 sizes, so handle that properly. */
477330fc 15031 if (((types_allowed & N_UNT) == 0)
91ff7894
MGD
15032 && ((g_size == 8 && (types_allowed & N_8) != 0)
15033 || (g_size == 16 && (types_allowed & N_16) != 0)
15034 || (g_size == 32 && (types_allowed & N_32) != 0)
15035 || (g_size == 64 && (types_allowed & N_64) != 0)))
5287ad62
JB
15036 g_type = NT_untyped;
15037
477330fc
RM
15038 if (pass == 0)
15039 {
15040 if ((thisarg & N_KEY) != 0)
15041 {
15042 k_type = g_type;
15043 k_size = g_size;
15044 key_allowed = thisarg & ~N_KEY;
cc933301
JW
15045
15046 /* Check architecture constraint on FP16 extension. */
15047 if (k_size == 16
15048 && k_type == NT_float
15049 && ! ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
15050 {
15051 inst.error = _(BAD_FP16);
15052 return badtype;
15053 }
477330fc
RM
15054 }
15055 }
15056 else
15057 {
15058 if ((thisarg & N_VFP) != 0)
15059 {
15060 enum neon_shape_el regshape;
15061 unsigned regwidth, match;
99b253c5
NC
15062
15063 /* PR 11136: Catch the case where we are passed a shape of NS_NULL. */
15064 if (ns == NS_NULL)
15065 {
15066 first_error (_("invalid instruction shape"));
15067 return badtype;
15068 }
477330fc
RM
15069 regshape = neon_shape_tab[ns].el[i];
15070 regwidth = neon_shape_el_size[regshape];
15071
15072 /* In VFP mode, operands must match register widths. If we
15073 have a key operand, use its width, else use the width of
15074 the current operand. */
15075 if (k_size != -1u)
15076 match = k_size;
15077 else
15078 match = g_size;
15079
9db2f6b4
RL
15080 /* FP16 will use a single precision register. */
15081 if (regwidth == 32 && match == 16)
15082 {
15083 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
15084 match = regwidth;
15085 else
15086 {
15087 inst.error = _(BAD_FP16);
15088 return badtype;
15089 }
15090 }
15091
477330fc
RM
15092 if (regwidth != match)
15093 {
15094 first_error (_("operand size must match register width"));
15095 return badtype;
15096 }
15097 }
15098
15099 if ((thisarg & N_EQK) == 0)
15100 {
15101 unsigned given_type = type_chk_of_el_type (g_type, g_size);
15102
15103 if ((given_type & types_allowed) == 0)
15104 {
a302e574 15105 first_error (BAD_SIMD_TYPE);
477330fc
RM
15106 return badtype;
15107 }
15108 }
15109 else
15110 {
15111 enum neon_el_type mod_k_type = k_type;
15112 unsigned mod_k_size = k_size;
15113 neon_modify_type_size (thisarg, &mod_k_type, &mod_k_size);
15114 if (g_type != mod_k_type || g_size != mod_k_size)
15115 {
15116 first_error (_("inconsistent types in Neon instruction"));
15117 return badtype;
15118 }
15119 }
15120 }
15121 }
5287ad62
JB
15122 }
15123
15124 return inst.vectype.el[key_el];
15125}
15126
037e8744 15127/* Neon-style VFP instruction forwarding. */
5287ad62 15128
037e8744
JB
15129/* Thumb VFP instructions have 0xE in the condition field. */
15130
15131static void
15132do_vfp_cond_or_thumb (void)
5287ad62 15133{
88714cb8
DG
15134 inst.is_neon = 1;
15135
5287ad62 15136 if (thumb_mode)
037e8744 15137 inst.instruction |= 0xe0000000;
5287ad62 15138 else
037e8744 15139 inst.instruction |= inst.cond << 28;
5287ad62
JB
15140}
15141
037e8744
JB
15142/* Look up and encode a simple mnemonic, for use as a helper function for the
15143 Neon-style VFP syntax. This avoids duplication of bits of the insns table,
15144 etc. It is assumed that operand parsing has already been done, and that the
15145 operands are in the form expected by the given opcode (this isn't necessarily
15146 the same as the form in which they were parsed, hence some massaging must
15147 take place before this function is called).
15148 Checks current arch version against that in the looked-up opcode. */
5287ad62 15149
037e8744
JB
15150static void
15151do_vfp_nsyn_opcode (const char *opname)
5287ad62 15152{
037e8744 15153 const struct asm_opcode *opcode;
5f4273c7 15154
21d799b5 15155 opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, opname);
5287ad62 15156
037e8744
JB
15157 if (!opcode)
15158 abort ();
5287ad62 15159
037e8744 15160 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant,
477330fc
RM
15161 thumb_mode ? *opcode->tvariant : *opcode->avariant),
15162 _(BAD_FPU));
5287ad62 15163
88714cb8
DG
15164 inst.is_neon = 1;
15165
037e8744
JB
15166 if (thumb_mode)
15167 {
15168 inst.instruction = opcode->tvalue;
15169 opcode->tencode ();
15170 }
15171 else
15172 {
15173 inst.instruction = (inst.cond << 28) | opcode->avalue;
15174 opcode->aencode ();
15175 }
15176}
5287ad62
JB
15177
15178static void
037e8744 15179do_vfp_nsyn_add_sub (enum neon_shape rs)
5287ad62 15180{
037e8744
JB
15181 int is_add = (inst.instruction & 0x0fffffff) == N_MNEM_vadd;
15182
9db2f6b4 15183 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
15184 {
15185 if (is_add)
477330fc 15186 do_vfp_nsyn_opcode ("fadds");
037e8744 15187 else
477330fc 15188 do_vfp_nsyn_opcode ("fsubs");
9db2f6b4
RL
15189
15190 /* ARMv8.2 fp16 instruction. */
15191 if (rs == NS_HHH)
15192 do_scalar_fp16_v82_encode ();
037e8744
JB
15193 }
15194 else
15195 {
15196 if (is_add)
477330fc 15197 do_vfp_nsyn_opcode ("faddd");
037e8744 15198 else
477330fc 15199 do_vfp_nsyn_opcode ("fsubd");
037e8744
JB
15200 }
15201}
15202
15203/* Check operand types to see if this is a VFP instruction, and if so call
15204 PFN (). */
15205
15206static int
15207try_vfp_nsyn (int args, void (*pfn) (enum neon_shape))
15208{
15209 enum neon_shape rs;
15210 struct neon_type_el et;
15211
15212 switch (args)
15213 {
15214 case 2:
9db2f6b4
RL
15215 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
15216 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
037e8744 15217 break;
5f4273c7 15218
037e8744 15219 case 3:
9db2f6b4
RL
15220 rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
15221 et = neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
15222 N_F_ALL | N_KEY | N_VFP);
037e8744
JB
15223 break;
15224
15225 default:
15226 abort ();
15227 }
15228
15229 if (et.type != NT_invtype)
15230 {
15231 pfn (rs);
15232 return SUCCESS;
15233 }
037e8744 15234
99b253c5 15235 inst.error = NULL;
037e8744
JB
15236 return FAIL;
15237}
15238
15239static void
15240do_vfp_nsyn_mla_mls (enum neon_shape rs)
15241{
15242 int is_mla = (inst.instruction & 0x0fffffff) == N_MNEM_vmla;
5f4273c7 15243
9db2f6b4 15244 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
15245 {
15246 if (is_mla)
477330fc 15247 do_vfp_nsyn_opcode ("fmacs");
037e8744 15248 else
477330fc 15249 do_vfp_nsyn_opcode ("fnmacs");
9db2f6b4
RL
15250
15251 /* ARMv8.2 fp16 instruction. */
15252 if (rs == NS_HHH)
15253 do_scalar_fp16_v82_encode ();
037e8744
JB
15254 }
15255 else
15256 {
15257 if (is_mla)
477330fc 15258 do_vfp_nsyn_opcode ("fmacd");
037e8744 15259 else
477330fc 15260 do_vfp_nsyn_opcode ("fnmacd");
037e8744
JB
15261 }
15262}
15263
62f3b8c8
PB
15264static void
15265do_vfp_nsyn_fma_fms (enum neon_shape rs)
15266{
15267 int is_fma = (inst.instruction & 0x0fffffff) == N_MNEM_vfma;
15268
9db2f6b4 15269 if (rs == NS_FFF || rs == NS_HHH)
62f3b8c8
PB
15270 {
15271 if (is_fma)
477330fc 15272 do_vfp_nsyn_opcode ("ffmas");
62f3b8c8 15273 else
477330fc 15274 do_vfp_nsyn_opcode ("ffnmas");
9db2f6b4
RL
15275
15276 /* ARMv8.2 fp16 instruction. */
15277 if (rs == NS_HHH)
15278 do_scalar_fp16_v82_encode ();
62f3b8c8
PB
15279 }
15280 else
15281 {
15282 if (is_fma)
477330fc 15283 do_vfp_nsyn_opcode ("ffmad");
62f3b8c8 15284 else
477330fc 15285 do_vfp_nsyn_opcode ("ffnmad");
62f3b8c8
PB
15286 }
15287}
15288
037e8744
JB
15289static void
15290do_vfp_nsyn_mul (enum neon_shape rs)
15291{
9db2f6b4
RL
15292 if (rs == NS_FFF || rs == NS_HHH)
15293 {
15294 do_vfp_nsyn_opcode ("fmuls");
15295
15296 /* ARMv8.2 fp16 instruction. */
15297 if (rs == NS_HHH)
15298 do_scalar_fp16_v82_encode ();
15299 }
037e8744
JB
15300 else
15301 do_vfp_nsyn_opcode ("fmuld");
15302}
15303
15304static void
15305do_vfp_nsyn_abs_neg (enum neon_shape rs)
15306{
15307 int is_neg = (inst.instruction & 0x80) != 0;
9db2f6b4 15308 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_VFP | N_KEY);
037e8744 15309
9db2f6b4 15310 if (rs == NS_FF || rs == NS_HH)
037e8744
JB
15311 {
15312 if (is_neg)
477330fc 15313 do_vfp_nsyn_opcode ("fnegs");
037e8744 15314 else
477330fc 15315 do_vfp_nsyn_opcode ("fabss");
9db2f6b4
RL
15316
15317 /* ARMv8.2 fp16 instruction. */
15318 if (rs == NS_HH)
15319 do_scalar_fp16_v82_encode ();
037e8744
JB
15320 }
15321 else
15322 {
15323 if (is_neg)
477330fc 15324 do_vfp_nsyn_opcode ("fnegd");
037e8744 15325 else
477330fc 15326 do_vfp_nsyn_opcode ("fabsd");
037e8744
JB
15327 }
15328}
15329
15330/* Encode single-precision (only!) VFP fldm/fstm instructions. Double precision
15331 insns belong to Neon, and are handled elsewhere. */
15332
15333static void
15334do_vfp_nsyn_ldm_stm (int is_dbmode)
15335{
15336 int is_ldm = (inst.instruction & (1 << 20)) != 0;
15337 if (is_ldm)
15338 {
15339 if (is_dbmode)
477330fc 15340 do_vfp_nsyn_opcode ("fldmdbs");
037e8744 15341 else
477330fc 15342 do_vfp_nsyn_opcode ("fldmias");
037e8744
JB
15343 }
15344 else
15345 {
15346 if (is_dbmode)
477330fc 15347 do_vfp_nsyn_opcode ("fstmdbs");
037e8744 15348 else
477330fc 15349 do_vfp_nsyn_opcode ("fstmias");
037e8744
JB
15350 }
15351}
15352
037e8744
JB
15353static void
15354do_vfp_nsyn_sqrt (void)
15355{
9db2f6b4
RL
15356 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
15357 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 15358
9db2f6b4
RL
15359 if (rs == NS_FF || rs == NS_HH)
15360 {
15361 do_vfp_nsyn_opcode ("fsqrts");
15362
15363 /* ARMv8.2 fp16 instruction. */
15364 if (rs == NS_HH)
15365 do_scalar_fp16_v82_encode ();
15366 }
037e8744
JB
15367 else
15368 do_vfp_nsyn_opcode ("fsqrtd");
15369}
15370
15371static void
15372do_vfp_nsyn_div (void)
15373{
9db2f6b4 15374 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 15375 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 15376 N_F_ALL | N_KEY | N_VFP);
5f4273c7 15377
9db2f6b4
RL
15378 if (rs == NS_FFF || rs == NS_HHH)
15379 {
15380 do_vfp_nsyn_opcode ("fdivs");
15381
15382 /* ARMv8.2 fp16 instruction. */
15383 if (rs == NS_HHH)
15384 do_scalar_fp16_v82_encode ();
15385 }
037e8744
JB
15386 else
15387 do_vfp_nsyn_opcode ("fdivd");
15388}
15389
15390static void
15391do_vfp_nsyn_nmul (void)
15392{
9db2f6b4 15393 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 15394 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 15395 N_F_ALL | N_KEY | N_VFP);
5f4273c7 15396
9db2f6b4 15397 if (rs == NS_FFF || rs == NS_HHH)
037e8744 15398 {
88714cb8 15399 NEON_ENCODE (SINGLE, inst);
037e8744 15400 do_vfp_sp_dyadic ();
9db2f6b4
RL
15401
15402 /* ARMv8.2 fp16 instruction. */
15403 if (rs == NS_HHH)
15404 do_scalar_fp16_v82_encode ();
037e8744
JB
15405 }
15406 else
15407 {
88714cb8 15408 NEON_ENCODE (DOUBLE, inst);
037e8744
JB
15409 do_vfp_dp_rd_rn_rm ();
15410 }
15411 do_vfp_cond_or_thumb ();
9db2f6b4 15412
037e8744
JB
15413}
15414
1b883319
AV
15415/* Turn a size (8, 16, 32, 64) into the respective bit number minus 3
15416 (0, 1, 2, 3). */
15417
15418static unsigned
15419neon_logbits (unsigned x)
15420{
15421 return ffs (x) - 4;
15422}
15423
15424#define LOW4(R) ((R) & 0xf)
15425#define HI1(R) (((R) >> 4) & 1)
15426
15427static unsigned
15428mve_get_vcmp_vpt_cond (struct neon_type_el et)
15429{
15430 switch (et.type)
15431 {
15432 default:
15433 first_error (BAD_EL_TYPE);
15434 return 0;
15435 case NT_float:
15436 switch (inst.operands[0].imm)
15437 {
15438 default:
15439 first_error (_("invalid condition"));
15440 return 0;
15441 case 0x0:
15442 /* eq. */
15443 return 0;
15444 case 0x1:
15445 /* ne. */
15446 return 1;
15447 case 0xa:
15448 /* ge/ */
15449 return 4;
15450 case 0xb:
15451 /* lt. */
15452 return 5;
15453 case 0xc:
15454 /* gt. */
15455 return 6;
15456 case 0xd:
15457 /* le. */
15458 return 7;
15459 }
15460 case NT_integer:
15461 /* only accept eq and ne. */
15462 if (inst.operands[0].imm > 1)
15463 {
15464 first_error (_("invalid condition"));
15465 return 0;
15466 }
15467 return inst.operands[0].imm;
15468 case NT_unsigned:
15469 if (inst.operands[0].imm == 0x2)
15470 return 2;
15471 else if (inst.operands[0].imm == 0x8)
15472 return 3;
15473 else
15474 {
15475 first_error (_("invalid condition"));
15476 return 0;
15477 }
15478 case NT_signed:
15479 switch (inst.operands[0].imm)
15480 {
15481 default:
15482 first_error (_("invalid condition"));
15483 return 0;
15484 case 0xa:
15485 /* ge. */
15486 return 4;
15487 case 0xb:
15488 /* lt. */
15489 return 5;
15490 case 0xc:
15491 /* gt. */
15492 return 6;
15493 case 0xd:
15494 /* le. */
15495 return 7;
15496 }
15497 }
15498 /* Should be unreachable. */
15499 abort ();
15500}
15501
15502static void
15503do_mve_vpt (void)
15504{
15505 /* We are dealing with a vector predicated block. */
15506 if (inst.operands[0].present)
15507 {
15508 enum neon_shape rs = neon_select_shape (NS_IQQ, NS_IQR, NS_NULL);
15509 struct neon_type_el et
15510 = neon_check_type (3, rs, N_EQK, N_KEY | N_F_MVE | N_I_MVE | N_SU_32,
15511 N_EQK);
15512
15513 unsigned fcond = mve_get_vcmp_vpt_cond (et);
15514
15515 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
15516
15517 if (et.type == NT_invtype)
15518 return;
15519
15520 if (et.type == NT_float)
15521 {
15522 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
15523 BAD_FPU);
15524 constraint (et.size != 16 && et.size != 32, BAD_EL_TYPE);
15525 inst.instruction |= (et.size == 16) << 28;
15526 inst.instruction |= 0x3 << 20;
15527 }
15528 else
15529 {
15530 constraint (et.size != 8 && et.size != 16 && et.size != 32,
15531 BAD_EL_TYPE);
15532 inst.instruction |= 1 << 28;
15533 inst.instruction |= neon_logbits (et.size) << 20;
15534 }
15535
15536 if (inst.operands[2].isquad)
15537 {
15538 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
15539 inst.instruction |= LOW4 (inst.operands[2].reg);
15540 inst.instruction |= (fcond & 0x2) >> 1;
15541 }
15542 else
15543 {
15544 if (inst.operands[2].reg == REG_SP)
15545 as_tsktsk (MVE_BAD_SP);
15546 inst.instruction |= 1 << 6;
15547 inst.instruction |= (fcond & 0x2) << 4;
15548 inst.instruction |= inst.operands[2].reg;
15549 }
15550 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15551 inst.instruction |= (fcond & 0x4) << 10;
15552 inst.instruction |= (fcond & 0x1) << 7;
15553
15554 }
15555 set_pred_insn_type (VPT_INSN);
15556 now_pred.cc = 0;
15557 now_pred.mask = ((inst.instruction & 0x00400000) >> 19)
15558 | ((inst.instruction & 0xe000) >> 13);
15559 now_pred.warn_deprecated = FALSE;
15560 now_pred.type = VECTOR_PRED;
15561 inst.is_neon = 1;
15562}
15563
15564static void
15565do_mve_vcmp (void)
15566{
15567 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
15568 if (!inst.operands[1].isreg || !inst.operands[1].isquad)
15569 first_error (_(reg_expected_msgs[REG_TYPE_MQ]));
15570 if (!inst.operands[2].present)
15571 first_error (_("MVE vector or ARM register expected"));
15572 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
15573
15574 /* Deal with 'else' conditional MVE's vcmp, it will be parsed as vcmpe. */
15575 if ((inst.instruction & 0xffffffff) == N_MNEM_vcmpe
15576 && inst.operands[1].isquad)
15577 {
15578 inst.instruction = N_MNEM_vcmp;
15579 inst.cond = 0x10;
15580 }
15581
15582 if (inst.cond > COND_ALWAYS)
15583 inst.pred_insn_type = INSIDE_VPT_INSN;
15584 else
15585 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15586
15587 enum neon_shape rs = neon_select_shape (NS_IQQ, NS_IQR, NS_NULL);
15588 struct neon_type_el et
15589 = neon_check_type (3, rs, N_EQK, N_KEY | N_F_MVE | N_I_MVE | N_SU_32,
15590 N_EQK);
15591
15592 constraint (rs == NS_IQR && inst.operands[2].reg == REG_PC
15593 && !inst.operands[2].iszr, BAD_PC);
15594
15595 unsigned fcond = mve_get_vcmp_vpt_cond (et);
15596
15597 inst.instruction = 0xee010f00;
15598 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15599 inst.instruction |= (fcond & 0x4) << 10;
15600 inst.instruction |= (fcond & 0x1) << 7;
15601 if (et.type == NT_float)
15602 {
15603 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
15604 BAD_FPU);
15605 inst.instruction |= (et.size == 16) << 28;
15606 inst.instruction |= 0x3 << 20;
15607 }
15608 else
15609 {
15610 inst.instruction |= 1 << 28;
15611 inst.instruction |= neon_logbits (et.size) << 20;
15612 }
15613 if (inst.operands[2].isquad)
15614 {
15615 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
15616 inst.instruction |= (fcond & 0x2) >> 1;
15617 inst.instruction |= LOW4 (inst.operands[2].reg);
15618 }
15619 else
15620 {
15621 if (inst.operands[2].reg == REG_SP)
15622 as_tsktsk (MVE_BAD_SP);
15623 inst.instruction |= 1 << 6;
15624 inst.instruction |= (fcond & 0x2) << 4;
15625 inst.instruction |= inst.operands[2].reg;
15626 }
15627
15628 inst.is_neon = 1;
15629 return;
15630}
15631
935295b5
AV
15632static void
15633do_mve_vmaxa_vmina (void)
15634{
15635 if (inst.cond > COND_ALWAYS)
15636 inst.pred_insn_type = INSIDE_VPT_INSN;
15637 else
15638 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15639
15640 enum neon_shape rs = neon_select_shape (NS_QQ, NS_NULL);
15641 struct neon_type_el et
15642 = neon_check_type (2, rs, N_EQK, N_KEY | N_S8 | N_S16 | N_S32);
15643
15644 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15645 inst.instruction |= neon_logbits (et.size) << 18;
15646 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15647 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
15648 inst.instruction |= LOW4 (inst.operands[1].reg);
15649 inst.is_neon = 1;
15650}
15651
f30ee27c
AV
15652static void
15653do_mve_vfmas (void)
15654{
15655 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
15656 struct neon_type_el et
15657 = neon_check_type (3, rs, N_F_MVE | N_KEY, N_EQK, N_EQK);
15658
15659 if (inst.cond > COND_ALWAYS)
15660 inst.pred_insn_type = INSIDE_VPT_INSN;
15661 else
15662 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15663
15664 if (inst.operands[2].reg == REG_SP)
15665 as_tsktsk (MVE_BAD_SP);
15666 else if (inst.operands[2].reg == REG_PC)
15667 as_tsktsk (MVE_BAD_PC);
15668
15669 inst.instruction |= (et.size == 16) << 28;
15670 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15671 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15672 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15673 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
15674 inst.instruction |= inst.operands[2].reg;
15675 inst.is_neon = 1;
15676}
15677
b409bdb6
AV
15678static void
15679do_mve_viddup (void)
15680{
15681 if (inst.cond > COND_ALWAYS)
15682 inst.pred_insn_type = INSIDE_VPT_INSN;
15683 else
15684 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15685
15686 unsigned imm = inst.relocs[0].exp.X_add_number;
15687 constraint (imm != 1 && imm != 2 && imm != 4 && imm != 8,
15688 _("immediate must be either 1, 2, 4 or 8"));
15689
15690 enum neon_shape rs;
15691 struct neon_type_el et;
15692 unsigned Rm;
15693 if (inst.instruction == M_MNEM_vddup || inst.instruction == M_MNEM_vidup)
15694 {
15695 rs = neon_select_shape (NS_QRI, NS_NULL);
15696 et = neon_check_type (2, rs, N_KEY | N_U8 | N_U16 | N_U32, N_EQK);
15697 Rm = 7;
15698 }
15699 else
15700 {
15701 constraint ((inst.operands[2].reg % 2) != 1, BAD_EVEN);
15702 if (inst.operands[2].reg == REG_SP)
15703 as_tsktsk (MVE_BAD_SP);
15704 else if (inst.operands[2].reg == REG_PC)
15705 first_error (BAD_PC);
15706
15707 rs = neon_select_shape (NS_QRRI, NS_NULL);
15708 et = neon_check_type (3, rs, N_KEY | N_U8 | N_U16 | N_U32, N_EQK, N_EQK);
15709 Rm = inst.operands[2].reg >> 1;
15710 }
15711 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15712 inst.instruction |= neon_logbits (et.size) << 20;
15713 inst.instruction |= inst.operands[1].reg << 16;
15714 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15715 inst.instruction |= (imm > 2) << 7;
15716 inst.instruction |= Rm << 1;
15717 inst.instruction |= (imm == 2 || imm == 8);
15718 inst.is_neon = 1;
15719}
15720
2d78f95b
AV
15721static void
15722do_mve_vmlas (void)
15723{
15724 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
15725 struct neon_type_el et
15726 = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
15727
15728 if (inst.operands[2].reg == REG_PC)
15729 as_tsktsk (MVE_BAD_PC);
15730 else if (inst.operands[2].reg == REG_SP)
15731 as_tsktsk (MVE_BAD_SP);
15732
15733 if (inst.cond > COND_ALWAYS)
15734 inst.pred_insn_type = INSIDE_VPT_INSN;
15735 else
15736 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15737
15738 inst.instruction |= (et.type == NT_unsigned) << 28;
15739 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15740 inst.instruction |= neon_logbits (et.size) << 20;
15741 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15742 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15743 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
15744 inst.instruction |= inst.operands[2].reg;
15745 inst.is_neon = 1;
15746}
15747
acca5630
AV
15748static void
15749do_mve_vshll (void)
15750{
15751 struct neon_type_el et
15752 = neon_check_type (2, NS_QQI, N_EQK, N_S8 | N_U8 | N_S16 | N_U16 | N_KEY);
15753
15754 if (inst.cond > COND_ALWAYS)
15755 inst.pred_insn_type = INSIDE_VPT_INSN;
15756 else
15757 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15758
15759 int imm = inst.operands[2].imm;
15760 constraint (imm < 1 || (unsigned)imm > et.size,
15761 _("immediate value out of range"));
15762
15763 if ((unsigned)imm == et.size)
15764 {
15765 inst.instruction |= neon_logbits (et.size) << 18;
15766 inst.instruction |= 0x110001;
15767 }
15768 else
15769 {
15770 inst.instruction |= (et.size + imm) << 16;
15771 inst.instruction |= 0x800140;
15772 }
15773
15774 inst.instruction |= (et.type == NT_unsigned) << 28;
15775 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15776 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15777 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
15778 inst.instruction |= LOW4 (inst.operands[1].reg);
15779 inst.is_neon = 1;
15780}
15781
15782static void
15783do_mve_vshlc (void)
15784{
15785 if (inst.cond > COND_ALWAYS)
15786 inst.pred_insn_type = INSIDE_VPT_INSN;
15787 else
15788 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15789
15790 if (inst.operands[1].reg == REG_PC)
15791 as_tsktsk (MVE_BAD_PC);
15792 else if (inst.operands[1].reg == REG_SP)
15793 as_tsktsk (MVE_BAD_SP);
15794
15795 int imm = inst.operands[2].imm;
15796 constraint (imm < 1 || imm > 32, _("immediate value out of range"));
15797
15798 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15799 inst.instruction |= (imm & 0x1f) << 16;
15800 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15801 inst.instruction |= inst.operands[1].reg;
15802 inst.is_neon = 1;
15803}
15804
4aa88b50
AV
15805static void
15806do_mve_vshrn (void)
15807{
15808 unsigned types;
15809 switch (inst.instruction)
15810 {
15811 case M_MNEM_vshrnt:
15812 case M_MNEM_vshrnb:
15813 case M_MNEM_vrshrnt:
15814 case M_MNEM_vrshrnb:
15815 types = N_I16 | N_I32;
15816 break;
15817 case M_MNEM_vqshrnt:
15818 case M_MNEM_vqshrnb:
15819 case M_MNEM_vqrshrnt:
15820 case M_MNEM_vqrshrnb:
15821 types = N_U16 | N_U32 | N_S16 | N_S32;
15822 break;
15823 case M_MNEM_vqshrunt:
15824 case M_MNEM_vqshrunb:
15825 case M_MNEM_vqrshrunt:
15826 case M_MNEM_vqrshrunb:
15827 types = N_S16 | N_S32;
15828 break;
15829 default:
15830 abort ();
15831 }
15832
15833 struct neon_type_el et = neon_check_type (2, NS_QQI, N_EQK, types | N_KEY);
15834
15835 if (inst.cond > COND_ALWAYS)
15836 inst.pred_insn_type = INSIDE_VPT_INSN;
15837 else
15838 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15839
15840 unsigned Qd = inst.operands[0].reg;
15841 unsigned Qm = inst.operands[1].reg;
15842 unsigned imm = inst.operands[2].imm;
15843 constraint (imm < 1 || ((unsigned) imm) > (et.size / 2),
15844 et.size == 16
15845 ? _("immediate operand expected in the range [1,8]")
15846 : _("immediate operand expected in the range [1,16]"));
15847
15848 inst.instruction |= (et.type == NT_unsigned) << 28;
15849 inst.instruction |= HI1 (Qd) << 22;
15850 inst.instruction |= (et.size - imm) << 16;
15851 inst.instruction |= LOW4 (Qd) << 12;
15852 inst.instruction |= HI1 (Qm) << 5;
15853 inst.instruction |= LOW4 (Qm);
15854 inst.is_neon = 1;
15855}
15856
1be7aba3
AV
15857static void
15858do_mve_vqmovn (void)
15859{
15860 struct neon_type_el et;
15861 if (inst.instruction == M_MNEM_vqmovnt
15862 || inst.instruction == M_MNEM_vqmovnb)
15863 et = neon_check_type (2, NS_QQ, N_EQK,
15864 N_U16 | N_U32 | N_S16 | N_S32 | N_KEY);
15865 else
15866 et = neon_check_type (2, NS_QQ, N_EQK, N_S16 | N_S32 | N_KEY);
15867
15868 if (inst.cond > COND_ALWAYS)
15869 inst.pred_insn_type = INSIDE_VPT_INSN;
15870 else
15871 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15872
15873 inst.instruction |= (et.type == NT_unsigned) << 28;
15874 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15875 inst.instruction |= (et.size == 32) << 18;
15876 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15877 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
15878 inst.instruction |= LOW4 (inst.operands[1].reg);
15879 inst.is_neon = 1;
15880}
15881
3063888e
AV
15882static void
15883do_mve_vpsel (void)
15884{
15885 neon_select_shape (NS_QQQ, NS_NULL);
15886
15887 if (inst.cond > COND_ALWAYS)
15888 inst.pred_insn_type = INSIDE_VPT_INSN;
15889 else
15890 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15891
15892 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15893 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15894 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15895 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
15896 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
15897 inst.instruction |= LOW4 (inst.operands[2].reg);
15898 inst.is_neon = 1;
15899}
15900
15901static void
15902do_mve_vpnot (void)
15903{
15904 if (inst.cond > COND_ALWAYS)
15905 inst.pred_insn_type = INSIDE_VPT_INSN;
15906 else
15907 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15908}
15909
935295b5
AV
15910static void
15911do_mve_vmaxnma_vminnma (void)
15912{
15913 enum neon_shape rs = neon_select_shape (NS_QQ, NS_NULL);
15914 struct neon_type_el et
15915 = neon_check_type (2, rs, N_EQK, N_F_MVE | N_KEY);
15916
15917 if (inst.cond > COND_ALWAYS)
15918 inst.pred_insn_type = INSIDE_VPT_INSN;
15919 else
15920 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15921
15922 inst.instruction |= (et.size == 16) << 28;
15923 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15924 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15925 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
15926 inst.instruction |= LOW4 (inst.operands[1].reg);
15927 inst.is_neon = 1;
15928}
15929
5d281bf0
AV
15930static void
15931do_mve_vcmul (void)
15932{
15933 enum neon_shape rs = neon_select_shape (NS_QQQI, NS_NULL);
15934 struct neon_type_el et
15935 = neon_check_type (3, rs, N_EQK, N_EQK, N_F_MVE | N_KEY);
15936
15937 if (inst.cond > COND_ALWAYS)
15938 inst.pred_insn_type = INSIDE_VPT_INSN;
15939 else
15940 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15941
15942 unsigned rot = inst.relocs[0].exp.X_add_number;
15943 constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
15944 _("immediate out of range"));
15945
15946 if (et.size == 32 && (inst.operands[0].reg == inst.operands[1].reg
15947 || inst.operands[0].reg == inst.operands[2].reg))
15948 as_tsktsk (BAD_MVE_SRCDEST);
15949
15950 inst.instruction |= (et.size == 32) << 28;
15951 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15952 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15953 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15954 inst.instruction |= (rot > 90) << 12;
15955 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
15956 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
15957 inst.instruction |= LOW4 (inst.operands[2].reg);
15958 inst.instruction |= (rot == 90 || rot == 270);
15959 inst.is_neon = 1;
15960}
15961
1f6234a3
AV
15962/* To handle the Low Overhead Loop instructions
15963 in Armv8.1-M Mainline and MVE. */
15964static void
15965do_t_loloop (void)
15966{
15967 unsigned long insn = inst.instruction;
15968
15969 inst.instruction = THUMB_OP32 (inst.instruction);
15970
15971 if (insn == T_MNEM_lctp)
15972 return;
15973
15974 set_pred_insn_type (MVE_OUTSIDE_PRED_INSN);
15975
15976 if (insn == T_MNEM_wlstp || insn == T_MNEM_dlstp)
15977 {
15978 struct neon_type_el et
15979 = neon_check_type (2, NS_RR, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
15980 inst.instruction |= neon_logbits (et.size) << 20;
15981 inst.is_neon = 1;
15982 }
15983
15984 switch (insn)
15985 {
15986 case T_MNEM_letp:
15987 constraint (!inst.operands[0].present,
15988 _("expected LR"));
15989 /* fall through. */
15990 case T_MNEM_le:
15991 /* le <label>. */
15992 if (!inst.operands[0].present)
15993 inst.instruction |= 1 << 21;
15994
15995 v8_1_loop_reloc (TRUE);
15996 break;
15997
15998 case T_MNEM_wls:
15999 case T_MNEM_wlstp:
16000 v8_1_loop_reloc (FALSE);
16001 /* fall through. */
16002 case T_MNEM_dlstp:
16003 case T_MNEM_dls:
16004 constraint (inst.operands[1].isreg != 1, BAD_ARGS);
16005
16006 if (insn == T_MNEM_wlstp || insn == T_MNEM_dlstp)
16007 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
16008 else if (inst.operands[1].reg == REG_PC)
16009 as_tsktsk (MVE_BAD_PC);
16010 if (inst.operands[1].reg == REG_SP)
16011 as_tsktsk (MVE_BAD_SP);
16012
16013 inst.instruction |= (inst.operands[1].reg << 16);
16014 break;
16015
16016 default:
16017 abort ();
16018 }
16019}
16020
16021
037e8744
JB
16022static void
16023do_vfp_nsyn_cmp (void)
16024{
9db2f6b4 16025 enum neon_shape rs;
1b883319
AV
16026 if (!inst.operands[0].isreg)
16027 {
16028 do_mve_vcmp ();
16029 return;
16030 }
16031 else
16032 {
16033 constraint (inst.operands[2].present, BAD_SYNTAX);
16034 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd),
16035 BAD_FPU);
16036 }
16037
037e8744
JB
16038 if (inst.operands[1].isreg)
16039 {
9db2f6b4
RL
16040 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
16041 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 16042
9db2f6b4 16043 if (rs == NS_FF || rs == NS_HH)
477330fc
RM
16044 {
16045 NEON_ENCODE (SINGLE, inst);
16046 do_vfp_sp_monadic ();
16047 }
037e8744 16048 else
477330fc
RM
16049 {
16050 NEON_ENCODE (DOUBLE, inst);
16051 do_vfp_dp_rd_rm ();
16052 }
037e8744
JB
16053 }
16054 else
16055 {
9db2f6b4
RL
16056 rs = neon_select_shape (NS_HI, NS_FI, NS_DI, NS_NULL);
16057 neon_check_type (2, rs, N_F_ALL | N_KEY | N_VFP, N_EQK);
037e8744
JB
16058
16059 switch (inst.instruction & 0x0fffffff)
477330fc
RM
16060 {
16061 case N_MNEM_vcmp:
16062 inst.instruction += N_MNEM_vcmpz - N_MNEM_vcmp;
16063 break;
16064 case N_MNEM_vcmpe:
16065 inst.instruction += N_MNEM_vcmpez - N_MNEM_vcmpe;
16066 break;
16067 default:
16068 abort ();
16069 }
5f4273c7 16070
9db2f6b4 16071 if (rs == NS_FI || rs == NS_HI)
477330fc
RM
16072 {
16073 NEON_ENCODE (SINGLE, inst);
16074 do_vfp_sp_compare_z ();
16075 }
037e8744 16076 else
477330fc
RM
16077 {
16078 NEON_ENCODE (DOUBLE, inst);
16079 do_vfp_dp_rd ();
16080 }
037e8744
JB
16081 }
16082 do_vfp_cond_or_thumb ();
9db2f6b4
RL
16083
16084 /* ARMv8.2 fp16 instruction. */
16085 if (rs == NS_HI || rs == NS_HH)
16086 do_scalar_fp16_v82_encode ();
037e8744
JB
16087}
16088
16089static void
16090nsyn_insert_sp (void)
16091{
16092 inst.operands[1] = inst.operands[0];
16093 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
fdfde340 16094 inst.operands[0].reg = REG_SP;
037e8744
JB
16095 inst.operands[0].isreg = 1;
16096 inst.operands[0].writeback = 1;
16097 inst.operands[0].present = 1;
16098}
16099
16100static void
16101do_vfp_nsyn_push (void)
16102{
16103 nsyn_insert_sp ();
b126985e
NC
16104
16105 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
16106 _("register list must contain at least 1 and at most 16 "
16107 "registers"));
16108
037e8744
JB
16109 if (inst.operands[1].issingle)
16110 do_vfp_nsyn_opcode ("fstmdbs");
16111 else
16112 do_vfp_nsyn_opcode ("fstmdbd");
16113}
16114
16115static void
16116do_vfp_nsyn_pop (void)
16117{
16118 nsyn_insert_sp ();
b126985e
NC
16119
16120 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
16121 _("register list must contain at least 1 and at most 16 "
16122 "registers"));
16123
037e8744 16124 if (inst.operands[1].issingle)
22b5b651 16125 do_vfp_nsyn_opcode ("fldmias");
037e8744 16126 else
22b5b651 16127 do_vfp_nsyn_opcode ("fldmiad");
037e8744
JB
16128}
16129
16130/* Fix up Neon data-processing instructions, ORing in the correct bits for
16131 ARM mode or Thumb mode and moving the encoded bit 24 to bit 28. */
16132
88714cb8
DG
16133static void
16134neon_dp_fixup (struct arm_it* insn)
037e8744 16135{
88714cb8
DG
16136 unsigned int i = insn->instruction;
16137 insn->is_neon = 1;
16138
037e8744
JB
16139 if (thumb_mode)
16140 {
16141 /* The U bit is at bit 24 by default. Move to bit 28 in Thumb mode. */
16142 if (i & (1 << 24))
477330fc 16143 i |= 1 << 28;
5f4273c7 16144
037e8744 16145 i &= ~(1 << 24);
5f4273c7 16146
037e8744
JB
16147 i |= 0xef000000;
16148 }
16149 else
16150 i |= 0xf2000000;
5f4273c7 16151
88714cb8 16152 insn->instruction = i;
037e8744
JB
16153}
16154
5ee91343 16155static void
7df54120 16156mve_encode_qqr (int size, int U, int fp)
5ee91343
AV
16157{
16158 if (inst.operands[2].reg == REG_SP)
16159 as_tsktsk (MVE_BAD_SP);
16160 else if (inst.operands[2].reg == REG_PC)
16161 as_tsktsk (MVE_BAD_PC);
16162
16163 if (fp)
16164 {
16165 /* vadd. */
16166 if (((unsigned)inst.instruction) == 0xd00)
16167 inst.instruction = 0xee300f40;
16168 /* vsub. */
16169 else if (((unsigned)inst.instruction) == 0x200d00)
16170 inst.instruction = 0xee301f40;
a8465a06
AV
16171 /* vmul. */
16172 else if (((unsigned)inst.instruction) == 0x1000d10)
16173 inst.instruction = 0xee310e60;
5ee91343
AV
16174
16175 /* Setting size which is 1 for F16 and 0 for F32. */
16176 inst.instruction |= (size == 16) << 28;
16177 }
16178 else
16179 {
16180 /* vadd. */
16181 if (((unsigned)inst.instruction) == 0x800)
16182 inst.instruction = 0xee010f40;
16183 /* vsub. */
16184 else if (((unsigned)inst.instruction) == 0x1000800)
16185 inst.instruction = 0xee011f40;
7df54120
AV
16186 /* vhadd. */
16187 else if (((unsigned)inst.instruction) == 0)
16188 inst.instruction = 0xee000f40;
16189 /* vhsub. */
16190 else if (((unsigned)inst.instruction) == 0x200)
16191 inst.instruction = 0xee001f40;
a8465a06
AV
16192 /* vmla. */
16193 else if (((unsigned)inst.instruction) == 0x900)
16194 inst.instruction = 0xee010e40;
16195 /* vmul. */
16196 else if (((unsigned)inst.instruction) == 0x910)
16197 inst.instruction = 0xee011e60;
16198 /* vqadd. */
16199 else if (((unsigned)inst.instruction) == 0x10)
16200 inst.instruction = 0xee000f60;
16201 /* vqsub. */
16202 else if (((unsigned)inst.instruction) == 0x210)
16203 inst.instruction = 0xee001f60;
42b16635
AV
16204 /* vqrdmlah. */
16205 else if (((unsigned)inst.instruction) == 0x3000b10)
16206 inst.instruction = 0xee000e40;
16207 /* vqdmulh. */
16208 else if (((unsigned)inst.instruction) == 0x0000b00)
16209 inst.instruction = 0xee010e60;
16210 /* vqrdmulh. */
16211 else if (((unsigned)inst.instruction) == 0x1000b00)
16212 inst.instruction = 0xfe010e60;
7df54120
AV
16213
16214 /* Set U-bit. */
16215 inst.instruction |= U << 28;
16216
5ee91343
AV
16217 /* Setting bits for size. */
16218 inst.instruction |= neon_logbits (size) << 20;
16219 }
16220 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16221 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16222 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16223 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16224 inst.instruction |= inst.operands[2].reg;
16225 inst.is_neon = 1;
16226}
16227
a302e574
AV
16228static void
16229mve_encode_rqq (unsigned bit28, unsigned size)
16230{
16231 inst.instruction |= bit28 << 28;
16232 inst.instruction |= neon_logbits (size) << 20;
16233 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16234 inst.instruction |= inst.operands[0].reg << 12;
16235 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16236 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16237 inst.instruction |= LOW4 (inst.operands[2].reg);
16238 inst.is_neon = 1;
16239}
16240
886e1c73
AV
16241static void
16242mve_encode_qqq (int ubit, int size)
16243{
16244
16245 inst.instruction |= (ubit != 0) << 28;
16246 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16247 inst.instruction |= neon_logbits (size) << 20;
16248 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16249 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16250 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16251 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16252 inst.instruction |= LOW4 (inst.operands[2].reg);
16253
16254 inst.is_neon = 1;
16255}
16256
26c1e780
AV
16257static void
16258mve_encode_rq (unsigned bit28, unsigned size)
16259{
16260 inst.instruction |= bit28 << 28;
16261 inst.instruction |= neon_logbits (size) << 18;
16262 inst.instruction |= inst.operands[0].reg << 12;
16263 inst.instruction |= LOW4 (inst.operands[1].reg);
16264 inst.is_neon = 1;
16265}
886e1c73 16266
93925576
AV
16267static void
16268mve_encode_rrqq (unsigned U, unsigned size)
16269{
16270 constraint (inst.operands[3].reg > 14, MVE_BAD_QREG);
16271
16272 inst.instruction |= U << 28;
16273 inst.instruction |= (inst.operands[1].reg >> 1) << 20;
16274 inst.instruction |= LOW4 (inst.operands[2].reg) << 16;
16275 inst.instruction |= (size == 32) << 16;
16276 inst.instruction |= inst.operands[0].reg << 12;
16277 inst.instruction |= HI1 (inst.operands[2].reg) << 7;
16278 inst.instruction |= inst.operands[3].reg;
16279 inst.is_neon = 1;
16280}
16281
037e8744
JB
16282/* Encode insns with bit pattern:
16283
16284 |28/24|23|22 |21 20|19 16|15 12|11 8|7|6|5|4|3 0|
16285 | U |x |D |size | Rn | Rd |x x x x|N|Q|M|x| Rm |
5f4273c7 16286
037e8744
JB
16287 SIZE is passed in bits. -1 means size field isn't changed, in case it has a
16288 different meaning for some instruction. */
16289
16290static void
16291neon_three_same (int isquad, int ubit, int size)
16292{
16293 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16294 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16295 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16296 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16297 inst.instruction |= LOW4 (inst.operands[2].reg);
16298 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16299 inst.instruction |= (isquad != 0) << 6;
16300 inst.instruction |= (ubit != 0) << 24;
16301 if (size != -1)
16302 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 16303
88714cb8 16304 neon_dp_fixup (&inst);
037e8744
JB
16305}
16306
16307/* Encode instructions of the form:
16308
16309 |28/24|23|22|21 20|19 18|17 16|15 12|11 7|6|5|4|3 0|
16310 | U |x |D |x x |size |x x | Rd |x x x x x|Q|M|x| Rm |
5287ad62
JB
16311
16312 Don't write size if SIZE == -1. */
16313
16314static void
16315neon_two_same (int qbit, int ubit, int size)
16316{
16317 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16318 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16319 inst.instruction |= LOW4 (inst.operands[1].reg);
16320 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16321 inst.instruction |= (qbit != 0) << 6;
16322 inst.instruction |= (ubit != 0) << 24;
16323
16324 if (size != -1)
16325 inst.instruction |= neon_logbits (size) << 18;
16326
88714cb8 16327 neon_dp_fixup (&inst);
5287ad62
JB
16328}
16329
7df54120
AV
16330enum vfp_or_neon_is_neon_bits
16331{
16332NEON_CHECK_CC = 1,
16333NEON_CHECK_ARCH = 2,
16334NEON_CHECK_ARCH8 = 4
16335};
16336
16337/* Call this function if an instruction which may have belonged to the VFP or
16338 Neon instruction sets, but turned out to be a Neon instruction (due to the
16339 operand types involved, etc.). We have to check and/or fix-up a couple of
16340 things:
16341
16342 - Make sure the user hasn't attempted to make a Neon instruction
16343 conditional.
16344 - Alter the value in the condition code field if necessary.
16345 - Make sure that the arch supports Neon instructions.
16346
16347 Which of these operations take place depends on bits from enum
16348 vfp_or_neon_is_neon_bits.
16349
16350 WARNING: This function has side effects! If NEON_CHECK_CC is used and the
16351 current instruction's condition is COND_ALWAYS, the condition field is
16352 changed to inst.uncond_value. This is necessary because instructions shared
16353 between VFP and Neon may be conditional for the VFP variants only, and the
16354 unconditional Neon version must have, e.g., 0xF in the condition field. */
16355
16356static int
16357vfp_or_neon_is_neon (unsigned check)
16358{
16359/* Conditions are always legal in Thumb mode (IT blocks). */
16360if (!thumb_mode && (check & NEON_CHECK_CC))
16361 {
16362 if (inst.cond != COND_ALWAYS)
16363 {
16364 first_error (_(BAD_COND));
16365 return FAIL;
16366 }
16367 if (inst.uncond_value != -1)
16368 inst.instruction |= inst.uncond_value << 28;
16369 }
16370
16371
16372 if (((check & NEON_CHECK_ARCH) && !mark_feature_used (&fpu_neon_ext_v1))
16373 || ((check & NEON_CHECK_ARCH8)
16374 && !mark_feature_used (&fpu_neon_ext_armv8)))
16375 {
16376 first_error (_(BAD_FPU));
16377 return FAIL;
16378 }
16379
16380return SUCCESS;
16381}
16382
64c350f2
AV
16383
16384/* Return TRUE if the SIMD instruction is available for the current
16385 cpu_variant. FP is set to TRUE if this is a SIMD floating-point
16386 instruction. CHECK contains th. CHECK contains the set of bits to pass to
16387 vfp_or_neon_is_neon for the NEON specific checks. */
16388
16389static bfd_boolean
7df54120
AV
16390check_simd_pred_availability (int fp, unsigned check)
16391{
16392if (inst.cond > COND_ALWAYS)
16393 {
16394 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16395 {
16396 inst.error = BAD_FPU;
64c350f2 16397 return FALSE;
7df54120
AV
16398 }
16399 inst.pred_insn_type = INSIDE_VPT_INSN;
16400 }
16401else if (inst.cond < COND_ALWAYS)
16402 {
16403 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16404 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16405 else if (vfp_or_neon_is_neon (check) == FAIL)
64c350f2 16406 return FALSE;
7df54120
AV
16407 }
16408else
16409 {
16410 if (!ARM_CPU_HAS_FEATURE (cpu_variant, fp ? mve_fp_ext : mve_ext)
16411 && vfp_or_neon_is_neon (check) == FAIL)
64c350f2 16412 return FALSE;
7df54120
AV
16413
16414 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16415 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16416 }
64c350f2 16417return TRUE;
7df54120
AV
16418}
16419
5287ad62
JB
16420/* Neon instruction encoders, in approximate order of appearance. */
16421
16422static void
16423do_neon_dyadic_i_su (void)
16424{
64c350f2 16425 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
7df54120
AV
16426 return;
16427
16428 enum neon_shape rs;
16429 struct neon_type_el et;
16430 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16431 rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
16432 else
16433 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
16434
16435 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_32 | N_KEY);
16436
16437
16438 if (rs != NS_QQR)
16439 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
16440 else
16441 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
5287ad62
JB
16442}
16443
16444static void
16445do_neon_dyadic_i64_su (void)
16446{
64c350f2 16447 if (!check_simd_pred_availability (FALSE, NEON_CHECK_CC | NEON_CHECK_ARCH))
a8465a06
AV
16448 return;
16449 enum neon_shape rs;
16450 struct neon_type_el et;
16451 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16452 {
16453 rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
16454 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
16455 }
16456 else
16457 {
16458 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
16459 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_ALL | N_KEY);
16460 }
16461 if (rs == NS_QQR)
16462 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
16463 else
16464 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
16465}
16466
16467static void
16468neon_imm_shift (int write_ubit, int uval, int isquad, struct neon_type_el et,
477330fc 16469 unsigned immbits)
5287ad62
JB
16470{
16471 unsigned size = et.size >> 3;
16472 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16473 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16474 inst.instruction |= LOW4 (inst.operands[1].reg);
16475 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16476 inst.instruction |= (isquad != 0) << 6;
16477 inst.instruction |= immbits << 16;
16478 inst.instruction |= (size >> 3) << 7;
16479 inst.instruction |= (size & 0x7) << 19;
16480 if (write_ubit)
16481 inst.instruction |= (uval != 0) << 24;
16482
88714cb8 16483 neon_dp_fixup (&inst);
5287ad62
JB
16484}
16485
16486static void
5150f0d8 16487do_neon_shl (void)
5287ad62 16488{
64c350f2 16489 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
5150f0d8
AV
16490 return;
16491
5287ad62
JB
16492 if (!inst.operands[2].isreg)
16493 {
5150f0d8
AV
16494 enum neon_shape rs;
16495 struct neon_type_el et;
16496 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16497 {
16498 rs = neon_select_shape (NS_QQI, NS_NULL);
16499 et = neon_check_type (2, rs, N_EQK, N_KEY | N_I_MVE);
16500 }
16501 else
16502 {
16503 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
16504 et = neon_check_type (2, rs, N_EQK, N_KEY | N_I_ALL);
16505 }
cb3b1e65
JB
16506 int imm = inst.operands[2].imm;
16507
16508 constraint (imm < 0 || (unsigned)imm >= et.size,
16509 _("immediate out of range for shift"));
88714cb8 16510 NEON_ENCODE (IMMED, inst);
cb3b1e65 16511 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
16512 }
16513 else
16514 {
5150f0d8
AV
16515 enum neon_shape rs;
16516 struct neon_type_el et;
16517 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16518 {
16519 rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
16520 et = neon_check_type (3, rs, N_EQK, N_SU_MVE | N_KEY, N_EQK | N_EQK);
16521 }
16522 else
16523 {
16524 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
16525 et = neon_check_type (3, rs, N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
16526 }
16527
16528
16529 if (rs == NS_QQR)
16530 {
16531 constraint (inst.operands[0].reg != inst.operands[1].reg,
16532 _("invalid instruction shape"));
16533 if (inst.operands[2].reg == REG_SP)
16534 as_tsktsk (MVE_BAD_SP);
16535 else if (inst.operands[2].reg == REG_PC)
16536 as_tsktsk (MVE_BAD_PC);
16537
16538 inst.instruction = 0xee311e60;
16539 inst.instruction |= (et.type == NT_unsigned) << 28;
16540 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16541 inst.instruction |= neon_logbits (et.size) << 18;
16542 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16543 inst.instruction |= inst.operands[2].reg;
16544 inst.is_neon = 1;
16545 }
16546 else
16547 {
16548 unsigned int tmp;
16549
16550 /* VSHL/VQSHL 3-register variants have syntax such as:
16551 vshl.xx Dd, Dm, Dn
16552 whereas other 3-register operations encoded by neon_three_same have
16553 syntax like:
16554 vadd.xx Dd, Dn, Dm
16555 (i.e. with Dn & Dm reversed). Swap operands[1].reg and
16556 operands[2].reg here. */
16557 tmp = inst.operands[2].reg;
16558 inst.operands[2].reg = inst.operands[1].reg;
16559 inst.operands[1].reg = tmp;
16560 NEON_ENCODE (INTEGER, inst);
16561 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
16562 }
5287ad62
JB
16563 }
16564}
16565
16566static void
5150f0d8 16567do_neon_qshl (void)
5287ad62 16568{
64c350f2 16569 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
5150f0d8
AV
16570 return;
16571
5287ad62
JB
16572 if (!inst.operands[2].isreg)
16573 {
5150f0d8
AV
16574 enum neon_shape rs;
16575 struct neon_type_el et;
16576 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16577 {
16578 rs = neon_select_shape (NS_QQI, NS_NULL);
16579 et = neon_check_type (2, rs, N_EQK, N_KEY | N_SU_MVE);
16580 }
16581 else
16582 {
16583 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
16584 et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
16585 }
cb3b1e65 16586 int imm = inst.operands[2].imm;
627907b7 16587
cb3b1e65
JB
16588 constraint (imm < 0 || (unsigned)imm >= et.size,
16589 _("immediate out of range for shift"));
88714cb8 16590 NEON_ENCODE (IMMED, inst);
cb3b1e65 16591 neon_imm_shift (TRUE, et.type == NT_unsigned, neon_quad (rs), et, imm);
5287ad62
JB
16592 }
16593 else
16594 {
5150f0d8
AV
16595 enum neon_shape rs;
16596 struct neon_type_el et;
627907b7 16597
5150f0d8
AV
16598 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16599 {
16600 rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
16601 et = neon_check_type (3, rs, N_EQK, N_SU_MVE | N_KEY, N_EQK | N_EQK);
16602 }
16603 else
16604 {
16605 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
16606 et = neon_check_type (3, rs, N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
16607 }
16608
16609 if (rs == NS_QQR)
16610 {
16611 constraint (inst.operands[0].reg != inst.operands[1].reg,
16612 _("invalid instruction shape"));
16613 if (inst.operands[2].reg == REG_SP)
16614 as_tsktsk (MVE_BAD_SP);
16615 else if (inst.operands[2].reg == REG_PC)
16616 as_tsktsk (MVE_BAD_PC);
16617
16618 inst.instruction = 0xee311ee0;
16619 inst.instruction |= (et.type == NT_unsigned) << 28;
16620 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16621 inst.instruction |= neon_logbits (et.size) << 18;
16622 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16623 inst.instruction |= inst.operands[2].reg;
16624 inst.is_neon = 1;
16625 }
16626 else
16627 {
16628 unsigned int tmp;
16629
16630 /* See note in do_neon_shl. */
16631 tmp = inst.operands[2].reg;
16632 inst.operands[2].reg = inst.operands[1].reg;
16633 inst.operands[1].reg = tmp;
16634 NEON_ENCODE (INTEGER, inst);
16635 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
16636 }
5287ad62
JB
16637 }
16638}
16639
627907b7
JB
16640static void
16641do_neon_rshl (void)
16642{
64c350f2 16643 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
1be7aba3
AV
16644 return;
16645
16646 enum neon_shape rs;
16647 struct neon_type_el et;
16648 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16649 {
16650 rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
16651 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
16652 }
16653 else
16654 {
16655 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
16656 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_ALL | N_KEY);
16657 }
16658
627907b7
JB
16659 unsigned int tmp;
16660
1be7aba3
AV
16661 if (rs == NS_QQR)
16662 {
16663 if (inst.operands[2].reg == REG_PC)
16664 as_tsktsk (MVE_BAD_PC);
16665 else if (inst.operands[2].reg == REG_SP)
16666 as_tsktsk (MVE_BAD_SP);
16667
16668 constraint (inst.operands[0].reg != inst.operands[1].reg,
16669 _("invalid instruction shape"));
16670
16671 if (inst.instruction == 0x0000510)
16672 /* We are dealing with vqrshl. */
16673 inst.instruction = 0xee331ee0;
16674 else
16675 /* We are dealing with vrshl. */
16676 inst.instruction = 0xee331e60;
16677
16678 inst.instruction |= (et.type == NT_unsigned) << 28;
16679 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16680 inst.instruction |= neon_logbits (et.size) << 18;
16681 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16682 inst.instruction |= inst.operands[2].reg;
16683 inst.is_neon = 1;
16684 }
16685 else
16686 {
16687 tmp = inst.operands[2].reg;
16688 inst.operands[2].reg = inst.operands[1].reg;
16689 inst.operands[1].reg = tmp;
16690 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
16691 }
627907b7
JB
16692}
16693
5287ad62
JB
16694static int
16695neon_cmode_for_logic_imm (unsigned immediate, unsigned *immbits, int size)
16696{
036dc3f7
PB
16697 /* Handle .I8 pseudo-instructions. */
16698 if (size == 8)
5287ad62 16699 {
5287ad62 16700 /* Unfortunately, this will make everything apart from zero out-of-range.
477330fc
RM
16701 FIXME is this the intended semantics? There doesn't seem much point in
16702 accepting .I8 if so. */
5287ad62
JB
16703 immediate |= immediate << 8;
16704 size = 16;
036dc3f7
PB
16705 }
16706
16707 if (size >= 32)
16708 {
16709 if (immediate == (immediate & 0x000000ff))
16710 {
16711 *immbits = immediate;
16712 return 0x1;
16713 }
16714 else if (immediate == (immediate & 0x0000ff00))
16715 {
16716 *immbits = immediate >> 8;
16717 return 0x3;
16718 }
16719 else if (immediate == (immediate & 0x00ff0000))
16720 {
16721 *immbits = immediate >> 16;
16722 return 0x5;
16723 }
16724 else if (immediate == (immediate & 0xff000000))
16725 {
16726 *immbits = immediate >> 24;
16727 return 0x7;
16728 }
16729 if ((immediate & 0xffff) != (immediate >> 16))
16730 goto bad_immediate;
16731 immediate &= 0xffff;
5287ad62
JB
16732 }
16733
16734 if (immediate == (immediate & 0x000000ff))
16735 {
16736 *immbits = immediate;
036dc3f7 16737 return 0x9;
5287ad62
JB
16738 }
16739 else if (immediate == (immediate & 0x0000ff00))
16740 {
16741 *immbits = immediate >> 8;
036dc3f7 16742 return 0xb;
5287ad62
JB
16743 }
16744
16745 bad_immediate:
dcbf9037 16746 first_error (_("immediate value out of range"));
5287ad62
JB
16747 return FAIL;
16748}
16749
5287ad62
JB
16750static void
16751do_neon_logic (void)
16752{
16753 if (inst.operands[2].present && inst.operands[2].isreg)
16754 {
037e8744 16755 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
f601a00c 16756 if (rs == NS_QQQ
64c350f2
AV
16757 && !check_simd_pred_availability (FALSE,
16758 NEON_CHECK_ARCH | NEON_CHECK_CC))
f601a00c
AV
16759 return;
16760 else if (rs != NS_QQQ
16761 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
16762 first_error (BAD_FPU);
16763
5287ad62
JB
16764 neon_check_type (3, rs, N_IGNORE_TYPE);
16765 /* U bit and size field were set as part of the bitmask. */
88714cb8 16766 NEON_ENCODE (INTEGER, inst);
037e8744 16767 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
16768 }
16769 else
16770 {
4316f0d2
DG
16771 const int three_ops_form = (inst.operands[2].present
16772 && !inst.operands[2].isreg);
16773 const int immoperand = (three_ops_form ? 2 : 1);
16774 enum neon_shape rs = (three_ops_form
16775 ? neon_select_shape (NS_DDI, NS_QQI, NS_NULL)
16776 : neon_select_shape (NS_DI, NS_QI, NS_NULL));
f601a00c
AV
16777 /* Because neon_select_shape makes the second operand a copy of the first
16778 if the second operand is not present. */
16779 if (rs == NS_QQI
64c350f2
AV
16780 && !check_simd_pred_availability (FALSE,
16781 NEON_CHECK_ARCH | NEON_CHECK_CC))
f601a00c
AV
16782 return;
16783 else if (rs != NS_QQI
16784 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
16785 first_error (BAD_FPU);
16786
16787 struct neon_type_el et;
16788 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16789 et = neon_check_type (2, rs, N_I32 | N_I16 | N_KEY, N_EQK);
16790 else
16791 et = neon_check_type (2, rs, N_I8 | N_I16 | N_I32 | N_I64 | N_F32
16792 | N_KEY, N_EQK);
16793
16794 if (et.type == NT_invtype)
16795 return;
21d799b5 16796 enum neon_opc opcode = (enum neon_opc) inst.instruction & 0x0fffffff;
5287ad62
JB
16797 unsigned immbits;
16798 int cmode;
5f4273c7 16799
5f4273c7 16800
4316f0d2
DG
16801 if (three_ops_form)
16802 constraint (inst.operands[0].reg != inst.operands[1].reg,
16803 _("first and second operands shall be the same register"));
16804
88714cb8 16805 NEON_ENCODE (IMMED, inst);
5287ad62 16806
4316f0d2 16807 immbits = inst.operands[immoperand].imm;
036dc3f7
PB
16808 if (et.size == 64)
16809 {
16810 /* .i64 is a pseudo-op, so the immediate must be a repeating
16811 pattern. */
4316f0d2
DG
16812 if (immbits != (inst.operands[immoperand].regisimm ?
16813 inst.operands[immoperand].reg : 0))
036dc3f7
PB
16814 {
16815 /* Set immbits to an invalid constant. */
16816 immbits = 0xdeadbeef;
16817 }
16818 }
16819
5287ad62 16820 switch (opcode)
477330fc
RM
16821 {
16822 case N_MNEM_vbic:
16823 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
16824 break;
16825
16826 case N_MNEM_vorr:
16827 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
16828 break;
16829
16830 case N_MNEM_vand:
16831 /* Pseudo-instruction for VBIC. */
16832 neon_invert_size (&immbits, 0, et.size);
16833 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
16834 break;
16835
16836 case N_MNEM_vorn:
16837 /* Pseudo-instruction for VORR. */
16838 neon_invert_size (&immbits, 0, et.size);
16839 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
16840 break;
16841
16842 default:
16843 abort ();
16844 }
5287ad62
JB
16845
16846 if (cmode == FAIL)
477330fc 16847 return;
5287ad62 16848
037e8744 16849 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
16850 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16851 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16852 inst.instruction |= cmode << 8;
16853 neon_write_immbits (immbits);
5f4273c7 16854
88714cb8 16855 neon_dp_fixup (&inst);
5287ad62
JB
16856 }
16857}
16858
16859static void
16860do_neon_bitfield (void)
16861{
037e8744 16862 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
dcbf9037 16863 neon_check_type (3, rs, N_IGNORE_TYPE);
037e8744 16864 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
16865}
16866
16867static void
dcbf9037 16868neon_dyadic_misc (enum neon_el_type ubit_meaning, unsigned types,
477330fc 16869 unsigned destbits)
5287ad62 16870{
5ee91343 16871 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
dcbf9037 16872 struct neon_type_el et = neon_check_type (3, rs, N_EQK | destbits, N_EQK,
477330fc 16873 types | N_KEY);
5287ad62
JB
16874 if (et.type == NT_float)
16875 {
88714cb8 16876 NEON_ENCODE (FLOAT, inst);
5ee91343 16877 if (rs == NS_QQR)
7df54120 16878 mve_encode_qqr (et.size, 0, 1);
5ee91343
AV
16879 else
16880 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
16881 }
16882 else
16883 {
88714cb8 16884 NEON_ENCODE (INTEGER, inst);
5ee91343 16885 if (rs == NS_QQR)
a8465a06 16886 mve_encode_qqr (et.size, et.type == ubit_meaning, 0);
5ee91343
AV
16887 else
16888 neon_three_same (neon_quad (rs), et.type == ubit_meaning, et.size);
5287ad62
JB
16889 }
16890}
16891
5287ad62
JB
16892
16893static void
16894do_neon_dyadic_if_su_d (void)
16895{
16896 /* This version only allow D registers, but that constraint is enforced during
16897 operand parsing so we don't need to do anything extra here. */
dcbf9037 16898 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
5287ad62
JB
16899}
16900
5287ad62
JB
16901static void
16902do_neon_dyadic_if_i_d (void)
16903{
428e3f1f
PB
16904 /* The "untyped" case can't happen. Do this to stop the "U" bit being
16905 affected if we specify unsigned args. */
16906 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
5287ad62
JB
16907}
16908
f5f10c66
AV
16909static void
16910do_mve_vstr_vldr_QI (int size, int elsize, int load)
16911{
16912 constraint (size < 32, BAD_ADDR_MODE);
16913 constraint (size != elsize, BAD_EL_TYPE);
16914 constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
16915 constraint (!inst.operands[1].preind, BAD_ADDR_MODE);
16916 constraint (load && inst.operands[0].reg == inst.operands[1].reg,
16917 _("destination register and offset register may not be the"
16918 " same"));
16919
16920 int imm = inst.relocs[0].exp.X_add_number;
16921 int add = 1;
16922 if (imm < 0)
16923 {
16924 add = 0;
16925 imm = -imm;
16926 }
16927 constraint ((imm % (size / 8) != 0)
16928 || imm > (0x7f << neon_logbits (size)),
16929 (size == 32) ? _("immediate must be a multiple of 4 in the"
16930 " range of +/-[0,508]")
16931 : _("immediate must be a multiple of 8 in the"
16932 " range of +/-[0,1016]"));
16933 inst.instruction |= 0x11 << 24;
16934 inst.instruction |= add << 23;
16935 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16936 inst.instruction |= inst.operands[1].writeback << 21;
16937 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16938 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16939 inst.instruction |= 1 << 12;
16940 inst.instruction |= (size == 64) << 8;
16941 inst.instruction &= 0xffffff00;
16942 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16943 inst.instruction |= imm >> neon_logbits (size);
16944}
16945
16946static void
16947do_mve_vstr_vldr_RQ (int size, int elsize, int load)
16948{
16949 unsigned os = inst.operands[1].imm >> 5;
16950 constraint (os != 0 && size == 8,
16951 _("can not shift offsets when accessing less than half-word"));
16952 constraint (os && os != neon_logbits (size),
16953 _("shift immediate must be 1, 2 or 3 for half-word, word"
16954 " or double-word accesses respectively"));
16955 if (inst.operands[1].reg == REG_PC)
16956 as_tsktsk (MVE_BAD_PC);
16957
16958 switch (size)
16959 {
16960 case 8:
16961 constraint (elsize >= 64, BAD_EL_TYPE);
16962 break;
16963 case 16:
16964 constraint (elsize < 16 || elsize >= 64, BAD_EL_TYPE);
16965 break;
16966 case 32:
16967 case 64:
16968 constraint (elsize != size, BAD_EL_TYPE);
16969 break;
16970 default:
16971 break;
16972 }
16973 constraint (inst.operands[1].writeback || !inst.operands[1].preind,
16974 BAD_ADDR_MODE);
16975 if (load)
16976 {
16977 constraint (inst.operands[0].reg == (inst.operands[1].imm & 0x1f),
16978 _("destination register and offset register may not be"
16979 " the same"));
16980 constraint (size == elsize && inst.vectype.el[0].type != NT_unsigned,
16981 BAD_EL_TYPE);
16982 constraint (inst.vectype.el[0].type != NT_unsigned
16983 && inst.vectype.el[0].type != NT_signed, BAD_EL_TYPE);
16984 inst.instruction |= (inst.vectype.el[0].type == NT_unsigned) << 28;
16985 }
16986 else
16987 {
16988 constraint (inst.vectype.el[0].type != NT_untyped, BAD_EL_TYPE);
16989 }
16990
16991 inst.instruction |= 1 << 23;
16992 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16993 inst.instruction |= inst.operands[1].reg << 16;
16994 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16995 inst.instruction |= neon_logbits (elsize) << 7;
16996 inst.instruction |= HI1 (inst.operands[1].imm) << 5;
16997 inst.instruction |= LOW4 (inst.operands[1].imm);
16998 inst.instruction |= !!os;
16999}
17000
17001static void
17002do_mve_vstr_vldr_RI (int size, int elsize, int load)
17003{
17004 enum neon_el_type type = inst.vectype.el[0].type;
17005
17006 constraint (size >= 64, BAD_ADDR_MODE);
17007 switch (size)
17008 {
17009 case 16:
17010 constraint (elsize < 16 || elsize >= 64, BAD_EL_TYPE);
17011 break;
17012 case 32:
17013 constraint (elsize != size, BAD_EL_TYPE);
17014 break;
17015 default:
17016 break;
17017 }
17018 if (load)
17019 {
17020 constraint (elsize != size && type != NT_unsigned
17021 && type != NT_signed, BAD_EL_TYPE);
17022 }
17023 else
17024 {
17025 constraint (elsize != size && type != NT_untyped, BAD_EL_TYPE);
17026 }
17027
17028 int imm = inst.relocs[0].exp.X_add_number;
17029 int add = 1;
17030 if (imm < 0)
17031 {
17032 add = 0;
17033 imm = -imm;
17034 }
17035
17036 if ((imm % (size / 8) != 0) || imm > (0x7f << neon_logbits (size)))
17037 {
17038 switch (size)
17039 {
17040 case 8:
17041 constraint (1, _("immediate must be in the range of +/-[0,127]"));
17042 break;
17043 case 16:
17044 constraint (1, _("immediate must be a multiple of 2 in the"
17045 " range of +/-[0,254]"));
17046 break;
17047 case 32:
17048 constraint (1, _("immediate must be a multiple of 4 in the"
17049 " range of +/-[0,508]"));
17050 break;
17051 }
17052 }
17053
17054 if (size != elsize)
17055 {
17056 constraint (inst.operands[1].reg > 7, BAD_HIREG);
17057 constraint (inst.operands[0].reg > 14,
17058 _("MVE vector register in the range [Q0..Q7] expected"));
17059 inst.instruction |= (load && type == NT_unsigned) << 28;
17060 inst.instruction |= (size == 16) << 19;
17061 inst.instruction |= neon_logbits (elsize) << 7;
17062 }
17063 else
17064 {
17065 if (inst.operands[1].reg == REG_PC)
17066 as_tsktsk (MVE_BAD_PC);
17067 else if (inst.operands[1].reg == REG_SP && inst.operands[1].writeback)
17068 as_tsktsk (MVE_BAD_SP);
17069 inst.instruction |= 1 << 12;
17070 inst.instruction |= neon_logbits (size) << 7;
17071 }
17072 inst.instruction |= inst.operands[1].preind << 24;
17073 inst.instruction |= add << 23;
17074 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17075 inst.instruction |= inst.operands[1].writeback << 21;
17076 inst.instruction |= inst.operands[1].reg << 16;
17077 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17078 inst.instruction &= 0xffffff80;
17079 inst.instruction |= imm >> neon_logbits (size);
17080
17081}
17082
17083static void
17084do_mve_vstr_vldr (void)
17085{
17086 unsigned size;
17087 int load = 0;
17088
17089 if (inst.cond > COND_ALWAYS)
17090 inst.pred_insn_type = INSIDE_VPT_INSN;
17091 else
17092 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17093
17094 switch (inst.instruction)
17095 {
17096 default:
17097 gas_assert (0);
17098 break;
17099 case M_MNEM_vldrb:
17100 load = 1;
17101 /* fall through. */
17102 case M_MNEM_vstrb:
17103 size = 8;
17104 break;
17105 case M_MNEM_vldrh:
17106 load = 1;
17107 /* fall through. */
17108 case M_MNEM_vstrh:
17109 size = 16;
17110 break;
17111 case M_MNEM_vldrw:
17112 load = 1;
17113 /* fall through. */
17114 case M_MNEM_vstrw:
17115 size = 32;
17116 break;
17117 case M_MNEM_vldrd:
17118 load = 1;
17119 /* fall through. */
17120 case M_MNEM_vstrd:
17121 size = 64;
17122 break;
17123 }
17124 unsigned elsize = inst.vectype.el[0].size;
17125
17126 if (inst.operands[1].isquad)
17127 {
17128 /* We are dealing with [Q, imm]{!} cases. */
17129 do_mve_vstr_vldr_QI (size, elsize, load);
17130 }
17131 else
17132 {
17133 if (inst.operands[1].immisreg == 2)
17134 {
17135 /* We are dealing with [R, Q, {UXTW #os}] cases. */
17136 do_mve_vstr_vldr_RQ (size, elsize, load);
17137 }
17138 else if (!inst.operands[1].immisreg)
17139 {
17140 /* We are dealing with [R, Imm]{!}/[R], Imm cases. */
17141 do_mve_vstr_vldr_RI (size, elsize, load);
17142 }
17143 else
17144 constraint (1, BAD_ADDR_MODE);
17145 }
17146
17147 inst.is_neon = 1;
17148}
17149
35c228db
AV
17150static void
17151do_mve_vst_vld (void)
17152{
17153 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17154 return;
17155
17156 constraint (!inst.operands[1].preind || inst.relocs[0].exp.X_add_symbol != 0
17157 || inst.relocs[0].exp.X_add_number != 0
17158 || inst.operands[1].immisreg != 0,
17159 BAD_ADDR_MODE);
17160 constraint (inst.vectype.el[0].size > 32, BAD_EL_TYPE);
17161 if (inst.operands[1].reg == REG_PC)
17162 as_tsktsk (MVE_BAD_PC);
17163 else if (inst.operands[1].reg == REG_SP && inst.operands[1].writeback)
17164 as_tsktsk (MVE_BAD_SP);
17165
17166
17167 /* These instructions are one of the "exceptions" mentioned in
17168 handle_pred_state. They are MVE instructions that are not VPT compatible
17169 and do not accept a VPT code, thus appending such a code is a syntax
17170 error. */
17171 if (inst.cond > COND_ALWAYS)
17172 first_error (BAD_SYNTAX);
17173 /* If we append a scalar condition code we can set this to
17174 MVE_OUTSIDE_PRED_INSN as it will also lead to a syntax error. */
17175 else if (inst.cond < COND_ALWAYS)
17176 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17177 else
17178 inst.pred_insn_type = MVE_UNPREDICABLE_INSN;
17179
17180 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17181 inst.instruction |= inst.operands[1].writeback << 21;
17182 inst.instruction |= inst.operands[1].reg << 16;
17183 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17184 inst.instruction |= neon_logbits (inst.vectype.el[0].size) << 7;
17185 inst.is_neon = 1;
17186}
17187
26c1e780
AV
17188static void
17189do_mve_vaddlv (void)
17190{
17191 enum neon_shape rs = neon_select_shape (NS_RRQ, NS_NULL);
17192 struct neon_type_el et
17193 = neon_check_type (3, rs, N_EQK, N_EQK, N_S32 | N_U32 | N_KEY);
17194
17195 if (et.type == NT_invtype)
17196 first_error (BAD_EL_TYPE);
17197
17198 if (inst.cond > COND_ALWAYS)
17199 inst.pred_insn_type = INSIDE_VPT_INSN;
17200 else
17201 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17202
17203 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
17204
17205 inst.instruction |= (et.type == NT_unsigned) << 28;
17206 inst.instruction |= inst.operands[1].reg << 19;
17207 inst.instruction |= inst.operands[0].reg << 12;
17208 inst.instruction |= inst.operands[2].reg;
17209 inst.is_neon = 1;
17210}
17211
5287ad62 17212static void
5ee91343 17213do_neon_dyadic_if_su (void)
5287ad62 17214{
5ee91343
AV
17215 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
17216 struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
17217 N_SUF_32 | N_KEY);
17218
935295b5
AV
17219 constraint ((inst.instruction == ((unsigned) N_MNEM_vmax)
17220 || inst.instruction == ((unsigned) N_MNEM_vmin))
17221 && et.type == NT_float
17222 && !ARM_CPU_HAS_FEATURE (cpu_variant,fpu_neon_ext_v1), BAD_FPU);
17223
64c350f2
AV
17224 if (!check_simd_pred_availability (et.type == NT_float,
17225 NEON_CHECK_ARCH | NEON_CHECK_CC))
037e8744
JB
17226 return;
17227
5ee91343
AV
17228 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
17229}
17230
17231static void
17232do_neon_addsub_if_i (void)
17233{
17234 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
17235 && try_vfp_nsyn (3, do_vfp_nsyn_add_sub) == SUCCESS)
037e8744
JB
17236 return;
17237
5ee91343
AV
17238 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
17239 struct neon_type_el et = neon_check_type (3, rs, N_EQK,
17240 N_EQK, N_IF_32 | N_I64 | N_KEY);
17241
17242 constraint (rs == NS_QQR && et.size == 64, BAD_FPU);
17243 /* If we are parsing Q registers and the element types match MVE, which NEON
17244 also supports, then we must check whether this is an instruction that can
17245 be used by both MVE/NEON. This distinction can be made based on whether
17246 they are predicated or not. */
17247 if ((rs == NS_QQQ || rs == NS_QQR) && et.size != 64)
17248 {
64c350f2
AV
17249 if (!check_simd_pred_availability (et.type == NT_float,
17250 NEON_CHECK_ARCH | NEON_CHECK_CC))
5ee91343
AV
17251 return;
17252 }
17253 else
17254 {
17255 /* If they are either in a D register or are using an unsupported. */
17256 if (rs != NS_QQR
17257 && vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
17258 return;
17259 }
17260
5287ad62
JB
17261 /* The "untyped" case can't happen. Do this to stop the "U" bit being
17262 affected if we specify unsigned args. */
dcbf9037 17263 neon_dyadic_misc (NT_untyped, N_IF_32 | N_I64, 0);
5287ad62
JB
17264}
17265
17266/* Swaps operands 1 and 2. If operand 1 (optional arg) was omitted, we want the
17267 result to be:
17268 V<op> A,B (A is operand 0, B is operand 2)
17269 to mean:
17270 V<op> A,B,A
17271 not:
17272 V<op> A,B,B
17273 so handle that case specially. */
17274
17275static void
17276neon_exchange_operands (void)
17277{
5287ad62
JB
17278 if (inst.operands[1].present)
17279 {
e1fa0163
NC
17280 void *scratch = xmalloc (sizeof (inst.operands[0]));
17281
5287ad62
JB
17282 /* Swap operands[1] and operands[2]. */
17283 memcpy (scratch, &inst.operands[1], sizeof (inst.operands[0]));
17284 inst.operands[1] = inst.operands[2];
17285 memcpy (&inst.operands[2], scratch, sizeof (inst.operands[0]));
e1fa0163 17286 free (scratch);
5287ad62
JB
17287 }
17288 else
17289 {
17290 inst.operands[1] = inst.operands[2];
17291 inst.operands[2] = inst.operands[0];
17292 }
17293}
17294
17295static void
17296neon_compare (unsigned regtypes, unsigned immtypes, int invert)
17297{
17298 if (inst.operands[2].isreg)
17299 {
17300 if (invert)
477330fc 17301 neon_exchange_operands ();
dcbf9037 17302 neon_dyadic_misc (NT_unsigned, regtypes, N_SIZ);
5287ad62
JB
17303 }
17304 else
17305 {
037e8744 17306 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
dcbf9037 17307 struct neon_type_el et = neon_check_type (2, rs,
477330fc 17308 N_EQK | N_SIZ, immtypes | N_KEY);
5287ad62 17309
88714cb8 17310 NEON_ENCODE (IMMED, inst);
5287ad62
JB
17311 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17312 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17313 inst.instruction |= LOW4 (inst.operands[1].reg);
17314 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 17315 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
17316 inst.instruction |= (et.type == NT_float) << 10;
17317 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 17318
88714cb8 17319 neon_dp_fixup (&inst);
5287ad62
JB
17320 }
17321}
17322
17323static void
17324do_neon_cmp (void)
17325{
cc933301 17326 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, FALSE);
5287ad62
JB
17327}
17328
17329static void
17330do_neon_cmp_inv (void)
17331{
cc933301 17332 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, TRUE);
5287ad62
JB
17333}
17334
17335static void
17336do_neon_ceq (void)
17337{
17338 neon_compare (N_IF_32, N_IF_32, FALSE);
17339}
17340
17341/* For multiply instructions, we have the possibility of 16-bit or 32-bit
17342 scalars, which are encoded in 5 bits, M : Rm.
17343 For 16-bit scalars, the register is encoded in Rm[2:0] and the index in
17344 M:Rm[3], and for 32-bit scalars, the register is encoded in Rm[3:0] and the
c604a79a
JW
17345 index in M.
17346
17347 Dot Product instructions are similar to multiply instructions except elsize
17348 should always be 32.
17349
17350 This function translates SCALAR, which is GAS's internal encoding of indexed
17351 scalar register, to raw encoding. There is also register and index range
17352 check based on ELSIZE. */
5287ad62
JB
17353
17354static unsigned
17355neon_scalar_for_mul (unsigned scalar, unsigned elsize)
17356{
dcbf9037
JB
17357 unsigned regno = NEON_SCALAR_REG (scalar);
17358 unsigned elno = NEON_SCALAR_INDEX (scalar);
5287ad62
JB
17359
17360 switch (elsize)
17361 {
17362 case 16:
17363 if (regno > 7 || elno > 3)
477330fc 17364 goto bad_scalar;
5287ad62 17365 return regno | (elno << 3);
5f4273c7 17366
5287ad62
JB
17367 case 32:
17368 if (regno > 15 || elno > 1)
477330fc 17369 goto bad_scalar;
5287ad62
JB
17370 return regno | (elno << 4);
17371
17372 default:
17373 bad_scalar:
dcbf9037 17374 first_error (_("scalar out of range for multiply instruction"));
5287ad62
JB
17375 }
17376
17377 return 0;
17378}
17379
17380/* Encode multiply / multiply-accumulate scalar instructions. */
17381
17382static void
17383neon_mul_mac (struct neon_type_el et, int ubit)
17384{
dcbf9037
JB
17385 unsigned scalar;
17386
17387 /* Give a more helpful error message if we have an invalid type. */
17388 if (et.type == NT_invtype)
17389 return;
5f4273c7 17390
dcbf9037 17391 scalar = neon_scalar_for_mul (inst.operands[2].reg, et.size);
5287ad62
JB
17392 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17393 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17394 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17395 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
17396 inst.instruction |= LOW4 (scalar);
17397 inst.instruction |= HI1 (scalar) << 5;
17398 inst.instruction |= (et.type == NT_float) << 8;
17399 inst.instruction |= neon_logbits (et.size) << 20;
17400 inst.instruction |= (ubit != 0) << 24;
17401
88714cb8 17402 neon_dp_fixup (&inst);
5287ad62
JB
17403}
17404
17405static void
17406do_neon_mac_maybe_scalar (void)
17407{
037e8744
JB
17408 if (try_vfp_nsyn (3, do_vfp_nsyn_mla_mls) == SUCCESS)
17409 return;
17410
64c350f2 17411 if (!check_simd_pred_availability (FALSE, NEON_CHECK_CC | NEON_CHECK_ARCH))
037e8744
JB
17412 return;
17413
5287ad62
JB
17414 if (inst.operands[2].isscalar)
17415 {
a8465a06 17416 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
037e8744 17417 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 17418 struct neon_type_el et = neon_check_type (3, rs,
589a7d88 17419 N_EQK, N_EQK, N_I16 | N_I32 | N_F_16_32 | N_KEY);
88714cb8 17420 NEON_ENCODE (SCALAR, inst);
037e8744 17421 neon_mul_mac (et, neon_quad (rs));
5287ad62 17422 }
a8465a06
AV
17423 else if (!inst.operands[2].isvec)
17424 {
17425 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
17426
17427 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
17428 neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
17429
17430 neon_dyadic_misc (NT_unsigned, N_SU_MVE, 0);
17431 }
5287ad62 17432 else
428e3f1f 17433 {
a8465a06 17434 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
428e3f1f
PB
17435 /* The "untyped" case can't happen. Do this to stop the "U" bit being
17436 affected if we specify unsigned args. */
17437 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
17438 }
5287ad62
JB
17439}
17440
62f3b8c8
PB
17441static void
17442do_neon_fmac (void)
17443{
d58196e0
AV
17444 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_fma)
17445 && try_vfp_nsyn (3, do_vfp_nsyn_fma_fms) == SUCCESS)
62f3b8c8
PB
17446 return;
17447
64c350f2 17448 if (!check_simd_pred_availability (TRUE, NEON_CHECK_CC | NEON_CHECK_ARCH))
62f3b8c8
PB
17449 return;
17450
d58196e0
AV
17451 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
17452 {
17453 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
17454 struct neon_type_el et = neon_check_type (3, rs, N_F_MVE | N_KEY, N_EQK,
17455 N_EQK);
17456
17457 if (rs == NS_QQR)
17458 {
17459 if (inst.operands[2].reg == REG_SP)
17460 as_tsktsk (MVE_BAD_SP);
17461 else if (inst.operands[2].reg == REG_PC)
17462 as_tsktsk (MVE_BAD_PC);
17463
17464 inst.instruction = 0xee310e40;
17465 inst.instruction |= (et.size == 16) << 28;
17466 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17467 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17468 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17469 inst.instruction |= HI1 (inst.operands[1].reg) << 6;
17470 inst.instruction |= inst.operands[2].reg;
17471 inst.is_neon = 1;
17472 return;
17473 }
17474 }
17475 else
17476 {
17477 constraint (!inst.operands[2].isvec, BAD_FPU);
17478 }
17479
62f3b8c8
PB
17480 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
17481}
17482
5287ad62
JB
17483static void
17484do_neon_tst (void)
17485{
037e8744 17486 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
17487 struct neon_type_el et = neon_check_type (3, rs,
17488 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_KEY);
037e8744 17489 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
17490}
17491
17492/* VMUL with 3 registers allows the P8 type. The scalar version supports the
17493 same types as the MAC equivalents. The polynomial type for this instruction
17494 is encoded the same as the integer type. */
17495
17496static void
17497do_neon_mul (void)
17498{
037e8744
JB
17499 if (try_vfp_nsyn (3, do_vfp_nsyn_mul) == SUCCESS)
17500 return;
17501
64c350f2 17502 if (!check_simd_pred_availability (FALSE, NEON_CHECK_CC | NEON_CHECK_ARCH))
037e8744
JB
17503 return;
17504
5287ad62 17505 if (inst.operands[2].isscalar)
a8465a06
AV
17506 {
17507 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
17508 do_neon_mac_maybe_scalar ();
17509 }
5287ad62 17510 else
a8465a06
AV
17511 {
17512 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17513 {
17514 enum neon_shape rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
17515 struct neon_type_el et
17516 = neon_check_type (3, rs, N_EQK, N_EQK, N_I_MVE | N_F_MVE | N_KEY);
17517 if (et.type == NT_float)
17518 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
17519 BAD_FPU);
17520
17521 neon_dyadic_misc (NT_float, N_I_MVE | N_F_MVE, 0);
17522 }
17523 else
17524 {
17525 constraint (!inst.operands[2].isvec, BAD_FPU);
17526 neon_dyadic_misc (NT_poly,
17527 N_I8 | N_I16 | N_I32 | N_F16 | N_F32 | N_P8, 0);
17528 }
17529 }
5287ad62
JB
17530}
17531
17532static void
17533do_neon_qdmulh (void)
17534{
64c350f2 17535 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
42b16635
AV
17536 return;
17537
5287ad62
JB
17538 if (inst.operands[2].isscalar)
17539 {
42b16635 17540 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
037e8744 17541 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 17542 struct neon_type_el et = neon_check_type (3, rs,
477330fc 17543 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
88714cb8 17544 NEON_ENCODE (SCALAR, inst);
037e8744 17545 neon_mul_mac (et, neon_quad (rs));
5287ad62
JB
17546 }
17547 else
17548 {
42b16635
AV
17549 enum neon_shape rs;
17550 struct neon_type_el et;
17551 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17552 {
17553 rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
17554 et = neon_check_type (3, rs,
17555 N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
17556 }
17557 else
17558 {
17559 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17560 et = neon_check_type (3, rs,
17561 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
17562 }
17563
88714cb8 17564 NEON_ENCODE (INTEGER, inst);
42b16635
AV
17565 if (rs == NS_QQR)
17566 mve_encode_qqr (et.size, 0, 0);
17567 else
17568 /* The U bit (rounding) comes from bit mask. */
17569 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
17570 }
17571}
17572
26c1e780
AV
17573static void
17574do_mve_vaddv (void)
17575{
17576 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
17577 struct neon_type_el et
17578 = neon_check_type (2, rs, N_EQK, N_SU_32 | N_KEY);
17579
17580 if (et.type == NT_invtype)
17581 first_error (BAD_EL_TYPE);
17582
17583 if (inst.cond > COND_ALWAYS)
17584 inst.pred_insn_type = INSIDE_VPT_INSN;
17585 else
17586 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17587
17588 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
17589
17590 mve_encode_rq (et.type == NT_unsigned, et.size);
17591}
17592
7df54120
AV
17593static void
17594do_mve_vhcadd (void)
17595{
17596 enum neon_shape rs = neon_select_shape (NS_QQQI, NS_NULL);
17597 struct neon_type_el et
17598 = neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
17599
17600 if (inst.cond > COND_ALWAYS)
17601 inst.pred_insn_type = INSIDE_VPT_INSN;
17602 else
17603 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17604
17605 unsigned rot = inst.relocs[0].exp.X_add_number;
17606 constraint (rot != 90 && rot != 270, _("immediate out of range"));
17607
17608 if (et.size == 32 && inst.operands[0].reg == inst.operands[2].reg)
17609 as_tsktsk (_("Warning: 32-bit element size and same first and third "
17610 "operand makes instruction UNPREDICTABLE"));
17611
17612 mve_encode_qqq (0, et.size);
17613 inst.instruction |= (rot == 270) << 12;
17614 inst.is_neon = 1;
17615}
17616
35d1cfc2
AV
17617static void
17618do_mve_vqdmull (void)
17619{
17620 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
17621 struct neon_type_el et
17622 = neon_check_type (3, rs, N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
17623
17624 if (et.size == 32
17625 && (inst.operands[0].reg == inst.operands[1].reg
17626 || (rs == NS_QQQ && inst.operands[0].reg == inst.operands[2].reg)))
17627 as_tsktsk (BAD_MVE_SRCDEST);
17628
17629 if (inst.cond > COND_ALWAYS)
17630 inst.pred_insn_type = INSIDE_VPT_INSN;
17631 else
17632 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17633
17634 if (rs == NS_QQQ)
17635 {
17636 mve_encode_qqq (et.size == 32, 64);
17637 inst.instruction |= 1;
17638 }
17639 else
17640 {
17641 mve_encode_qqr (64, et.size == 32, 0);
17642 inst.instruction |= 0x3 << 5;
17643 }
17644}
17645
c2dafc2a
AV
17646static void
17647do_mve_vadc (void)
17648{
17649 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
17650 struct neon_type_el et
17651 = neon_check_type (3, rs, N_KEY | N_I32, N_EQK, N_EQK);
17652
17653 if (et.type == NT_invtype)
17654 first_error (BAD_EL_TYPE);
17655
17656 if (inst.cond > COND_ALWAYS)
17657 inst.pred_insn_type = INSIDE_VPT_INSN;
17658 else
17659 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17660
17661 mve_encode_qqq (0, 64);
17662}
17663
17664static void
17665do_mve_vbrsr (void)
17666{
17667 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
17668 struct neon_type_el et
17669 = neon_check_type (3, rs, N_EQK, N_EQK, N_8 | N_16 | N_32 | N_KEY);
17670
17671 if (inst.cond > COND_ALWAYS)
17672 inst.pred_insn_type = INSIDE_VPT_INSN;
17673 else
17674 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17675
7df54120 17676 mve_encode_qqr (et.size, 0, 0);
c2dafc2a
AV
17677}
17678
17679static void
17680do_mve_vsbc (void)
17681{
17682 neon_check_type (3, NS_QQQ, N_EQK, N_EQK, N_I32 | N_KEY);
17683
17684 if (inst.cond > COND_ALWAYS)
17685 inst.pred_insn_type = INSIDE_VPT_INSN;
17686 else
17687 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17688
17689 mve_encode_qqq (1, 64);
17690}
17691
2d78f95b
AV
17692static void
17693do_mve_vmulh (void)
17694{
17695 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
17696 struct neon_type_el et
17697 = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
17698
17699 if (inst.cond > COND_ALWAYS)
17700 inst.pred_insn_type = INSIDE_VPT_INSN;
17701 else
17702 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17703
17704 mve_encode_qqq (et.type == NT_unsigned, et.size);
17705}
17706
42b16635
AV
17707static void
17708do_mve_vqdmlah (void)
17709{
17710 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
17711 struct neon_type_el et
17712 = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
17713
17714 if (inst.cond > COND_ALWAYS)
17715 inst.pred_insn_type = INSIDE_VPT_INSN;
17716 else
17717 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17718
17719 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
17720}
8b8b22a4
AV
17721
17722static void
17723do_mve_vqdmladh (void)
17724{
17725 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
17726 struct neon_type_el et
17727 = neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
17728
17729 if (inst.cond > COND_ALWAYS)
17730 inst.pred_insn_type = INSIDE_VPT_INSN;
17731 else
17732 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17733
17734 if (et.size == 32
17735 && (inst.operands[0].reg == inst.operands[1].reg
17736 || inst.operands[0].reg == inst.operands[2].reg))
17737 as_tsktsk (BAD_MVE_SRCDEST);
17738
17739 mve_encode_qqq (0, et.size);
17740}
17741
17742
886e1c73
AV
17743static void
17744do_mve_vmull (void)
17745{
17746
17747 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_DDS,
17748 NS_QQS, NS_QQQ, NS_QQR, NS_NULL);
17749 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
17750 && inst.cond == COND_ALWAYS
17751 && ((unsigned)inst.instruction) == M_MNEM_vmullt)
17752 {
17753 if (rs == NS_QQQ)
17754 {
17755
17756 struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
17757 N_SUF_32 | N_F64 | N_P8
17758 | N_P16 | N_I_MVE | N_KEY);
17759 if (((et.type == NT_poly) && et.size == 8
17760 && ARM_CPU_IS_ANY (cpu_variant))
17761 || (et.type == NT_integer) || (et.type == NT_float))
17762 goto neon_vmul;
17763 }
17764 else
17765 goto neon_vmul;
17766 }
17767
17768 constraint (rs != NS_QQQ, BAD_FPU);
17769 struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
17770 N_SU_32 | N_P8 | N_P16 | N_KEY);
17771
17772 /* We are dealing with MVE's vmullt. */
17773 if (et.size == 32
17774 && (inst.operands[0].reg == inst.operands[1].reg
17775 || inst.operands[0].reg == inst.operands[2].reg))
17776 as_tsktsk (BAD_MVE_SRCDEST);
17777
17778 if (inst.cond > COND_ALWAYS)
17779 inst.pred_insn_type = INSIDE_VPT_INSN;
17780 else
17781 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17782
17783 if (et.type == NT_poly)
17784 mve_encode_qqq (neon_logbits (et.size), 64);
17785 else
17786 mve_encode_qqq (et.type == NT_unsigned, et.size);
17787
17788 return;
17789
17790neon_vmul:
17791 inst.instruction = N_MNEM_vmul;
17792 inst.cond = 0xb;
17793 if (thumb_mode)
17794 inst.pred_insn_type = INSIDE_IT_INSN;
17795 do_neon_mul ();
17796}
17797
a302e574
AV
17798static void
17799do_mve_vabav (void)
17800{
17801 enum neon_shape rs = neon_select_shape (NS_RQQ, NS_NULL);
17802
17803 if (rs == NS_NULL)
17804 return;
17805
17806 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17807 return;
17808
17809 struct neon_type_el et = neon_check_type (2, NS_NULL, N_EQK, N_KEY | N_S8
17810 | N_S16 | N_S32 | N_U8 | N_U16
17811 | N_U32);
17812
17813 if (inst.cond > COND_ALWAYS)
17814 inst.pred_insn_type = INSIDE_VPT_INSN;
17815 else
17816 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17817
17818 mve_encode_rqq (et.type == NT_unsigned, et.size);
17819}
17820
17821static void
17822do_mve_vmladav (void)
17823{
17824 enum neon_shape rs = neon_select_shape (NS_RQQ, NS_NULL);
17825 struct neon_type_el et = neon_check_type (3, rs,
17826 N_EQK, N_EQK, N_SU_MVE | N_KEY);
17827
17828 if (et.type == NT_unsigned
17829 && (inst.instruction == M_MNEM_vmladavx
17830 || inst.instruction == M_MNEM_vmladavax
17831 || inst.instruction == M_MNEM_vmlsdav
17832 || inst.instruction == M_MNEM_vmlsdava
17833 || inst.instruction == M_MNEM_vmlsdavx
17834 || inst.instruction == M_MNEM_vmlsdavax))
17835 first_error (BAD_SIMD_TYPE);
17836
17837 constraint (inst.operands[2].reg > 14,
17838 _("MVE vector register in the range [Q0..Q7] expected"));
17839
17840 if (inst.cond > COND_ALWAYS)
17841 inst.pred_insn_type = INSIDE_VPT_INSN;
17842 else
17843 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17844
17845 if (inst.instruction == M_MNEM_vmlsdav
17846 || inst.instruction == M_MNEM_vmlsdava
17847 || inst.instruction == M_MNEM_vmlsdavx
17848 || inst.instruction == M_MNEM_vmlsdavax)
17849 inst.instruction |= (et.size == 8) << 28;
17850 else
17851 inst.instruction |= (et.size == 8) << 8;
17852
17853 mve_encode_rqq (et.type == NT_unsigned, 64);
17854 inst.instruction |= (et.size == 32) << 16;
17855}
17856
93925576
AV
17857static void
17858do_mve_vmlaldav (void)
17859{
17860 enum neon_shape rs = neon_select_shape (NS_RRQQ, NS_NULL);
17861 struct neon_type_el et
17862 = neon_check_type (4, rs, N_EQK, N_EQK, N_EQK,
17863 N_S16 | N_S32 | N_U16 | N_U32 | N_KEY);
17864
17865 if (et.type == NT_unsigned
17866 && (inst.instruction == M_MNEM_vmlsldav
17867 || inst.instruction == M_MNEM_vmlsldava
17868 || inst.instruction == M_MNEM_vmlsldavx
17869 || inst.instruction == M_MNEM_vmlsldavax))
17870 first_error (BAD_SIMD_TYPE);
17871
17872 if (inst.cond > COND_ALWAYS)
17873 inst.pred_insn_type = INSIDE_VPT_INSN;
17874 else
17875 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17876
17877 mve_encode_rrqq (et.type == NT_unsigned, et.size);
17878}
17879
17880static void
17881do_mve_vrmlaldavh (void)
17882{
17883 struct neon_type_el et;
17884 if (inst.instruction == M_MNEM_vrmlsldavh
17885 || inst.instruction == M_MNEM_vrmlsldavha
17886 || inst.instruction == M_MNEM_vrmlsldavhx
17887 || inst.instruction == M_MNEM_vrmlsldavhax)
17888 {
17889 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK, N_S32 | N_KEY);
17890 if (inst.operands[1].reg == REG_SP)
17891 as_tsktsk (MVE_BAD_SP);
17892 }
17893 else
17894 {
17895 if (inst.instruction == M_MNEM_vrmlaldavhx
17896 || inst.instruction == M_MNEM_vrmlaldavhax)
17897 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK, N_S32 | N_KEY);
17898 else
17899 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK,
17900 N_U32 | N_S32 | N_KEY);
17901 /* vrmlaldavh's encoding with SP as the second, odd, GPR operand may alias
17902 with vmax/min instructions, making the use of SP in assembly really
17903 nonsensical, so instead of issuing a warning like we do for other uses
17904 of SP for the odd register operand we error out. */
17905 constraint (inst.operands[1].reg == REG_SP, BAD_SP);
17906 }
17907
17908 /* Make sure we still check the second operand is an odd one and that PC is
17909 disallowed. This because we are parsing for any GPR operand, to be able
17910 to distinguish between giving a warning or an error for SP as described
17911 above. */
17912 constraint ((inst.operands[1].reg % 2) != 1, BAD_EVEN);
17913 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
17914
17915 if (inst.cond > COND_ALWAYS)
17916 inst.pred_insn_type = INSIDE_VPT_INSN;
17917 else
17918 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17919
17920 mve_encode_rrqq (et.type == NT_unsigned, 0);
17921}
17922
17923
8cd78170
AV
17924static void
17925do_mve_vmaxnmv (void)
17926{
17927 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
17928 struct neon_type_el et
17929 = neon_check_type (2, rs, N_EQK, N_F_MVE | N_KEY);
17930
17931 if (inst.cond > COND_ALWAYS)
17932 inst.pred_insn_type = INSIDE_VPT_INSN;
17933 else
17934 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17935
17936 if (inst.operands[0].reg == REG_SP)
17937 as_tsktsk (MVE_BAD_SP);
17938 else if (inst.operands[0].reg == REG_PC)
17939 as_tsktsk (MVE_BAD_PC);
17940
17941 mve_encode_rq (et.size == 16, 64);
17942}
17943
13ccd4c0
AV
17944static void
17945do_mve_vmaxv (void)
17946{
17947 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
17948 struct neon_type_el et;
17949
17950 if (inst.instruction == M_MNEM_vmaxv || inst.instruction == M_MNEM_vminv)
17951 et = neon_check_type (2, rs, N_EQK, N_SU_MVE | N_KEY);
17952 else
17953 et = neon_check_type (2, rs, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
17954
17955 if (inst.cond > COND_ALWAYS)
17956 inst.pred_insn_type = INSIDE_VPT_INSN;
17957 else
17958 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17959
17960 if (inst.operands[0].reg == REG_SP)
17961 as_tsktsk (MVE_BAD_SP);
17962 else if (inst.operands[0].reg == REG_PC)
17963 as_tsktsk (MVE_BAD_PC);
17964
17965 mve_encode_rq (et.type == NT_unsigned, et.size);
17966}
17967
17968
643afb90
MW
17969static void
17970do_neon_qrdmlah (void)
17971{
64c350f2 17972 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
42b16635
AV
17973 return;
17974 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
643afb90 17975 {
42b16635
AV
17976 /* Check we're on the correct architecture. */
17977 if (!mark_feature_used (&fpu_neon_ext_armv8))
17978 inst.error
17979 = _("instruction form not available on this architecture.");
17980 else if (!mark_feature_used (&fpu_neon_ext_v8_1))
17981 {
17982 as_warn (_("this instruction implies use of ARMv8.1 AdvSIMD."));
17983 record_feature_use (&fpu_neon_ext_v8_1);
17984 }
17985 if (inst.operands[2].isscalar)
17986 {
17987 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
17988 struct neon_type_el et = neon_check_type (3, rs,
17989 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
17990 NEON_ENCODE (SCALAR, inst);
17991 neon_mul_mac (et, neon_quad (rs));
17992 }
17993 else
17994 {
17995 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17996 struct neon_type_el et = neon_check_type (3, rs,
17997 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
17998 NEON_ENCODE (INTEGER, inst);
17999 /* The U bit (rounding) comes from bit mask. */
18000 neon_three_same (neon_quad (rs), 0, et.size);
18001 }
643afb90
MW
18002 }
18003 else
18004 {
42b16635
AV
18005 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
18006 struct neon_type_el et
18007 = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
18008
643afb90 18009 NEON_ENCODE (INTEGER, inst);
42b16635 18010 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
643afb90
MW
18011 }
18012}
18013
5287ad62
JB
18014static void
18015do_neon_fcmp_absolute (void)
18016{
037e8744 18017 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
18018 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
18019 N_F_16_32 | N_KEY);
5287ad62 18020 /* Size field comes from bit mask. */
cc933301 18021 neon_three_same (neon_quad (rs), 1, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
18022}
18023
18024static void
18025do_neon_fcmp_absolute_inv (void)
18026{
18027 neon_exchange_operands ();
18028 do_neon_fcmp_absolute ();
18029}
18030
18031static void
18032do_neon_step (void)
18033{
037e8744 18034 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
18035 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
18036 N_F_16_32 | N_KEY);
18037 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
18038}
18039
18040static void
18041do_neon_abs_neg (void)
18042{
037e8744
JB
18043 enum neon_shape rs;
18044 struct neon_type_el et;
5f4273c7 18045
037e8744
JB
18046 if (try_vfp_nsyn (2, do_vfp_nsyn_abs_neg) == SUCCESS)
18047 return;
18048
037e8744 18049 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
cc933301 18050 et = neon_check_type (2, rs, N_EQK, N_S_32 | N_F_16_32 | N_KEY);
5f4273c7 18051
64c350f2
AV
18052 if (!check_simd_pred_availability (et.type == NT_float,
18053 NEON_CHECK_ARCH | NEON_CHECK_CC))
485dee97
AV
18054 return;
18055
5287ad62
JB
18056 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18057 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18058 inst.instruction |= LOW4 (inst.operands[1].reg);
18059 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 18060 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
18061 inst.instruction |= (et.type == NT_float) << 10;
18062 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 18063
88714cb8 18064 neon_dp_fixup (&inst);
5287ad62
JB
18065}
18066
18067static void
18068do_neon_sli (void)
18069{
64c350f2 18070 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
18071 return;
18072
18073 enum neon_shape rs;
18074 struct neon_type_el et;
18075 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18076 {
18077 rs = neon_select_shape (NS_QQI, NS_NULL);
18078 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_KEY);
18079 }
18080 else
18081 {
18082 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
18083 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
18084 }
18085
18086
5287ad62
JB
18087 int imm = inst.operands[2].imm;
18088 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 18089 _("immediate out of range for insert"));
037e8744 18090 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
18091}
18092
18093static void
18094do_neon_sri (void)
18095{
64c350f2 18096 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
18097 return;
18098
18099 enum neon_shape rs;
18100 struct neon_type_el et;
18101 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18102 {
18103 rs = neon_select_shape (NS_QQI, NS_NULL);
18104 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_KEY);
18105 }
18106 else
18107 {
18108 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
18109 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
18110 }
18111
5287ad62
JB
18112 int imm = inst.operands[2].imm;
18113 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18114 _("immediate out of range for insert"));
037e8744 18115 neon_imm_shift (FALSE, 0, neon_quad (rs), et, et.size - imm);
5287ad62
JB
18116}
18117
18118static void
18119do_neon_qshlu_imm (void)
18120{
64c350f2 18121 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
5150f0d8
AV
18122 return;
18123
18124 enum neon_shape rs;
18125 struct neon_type_el et;
18126 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18127 {
18128 rs = neon_select_shape (NS_QQI, NS_NULL);
18129 et = neon_check_type (2, rs, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18130 }
18131 else
18132 {
18133 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
18134 et = neon_check_type (2, rs, N_EQK | N_UNS,
18135 N_S8 | N_S16 | N_S32 | N_S64 | N_KEY);
18136 }
18137
5287ad62
JB
18138 int imm = inst.operands[2].imm;
18139 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 18140 _("immediate out of range for shift"));
5287ad62
JB
18141 /* Only encodes the 'U present' variant of the instruction.
18142 In this case, signed types have OP (bit 8) set to 0.
18143 Unsigned types have OP set to 1. */
18144 inst.instruction |= (et.type == NT_unsigned) << 8;
18145 /* The rest of the bits are the same as other immediate shifts. */
037e8744 18146 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
18147}
18148
18149static void
18150do_neon_qmovn (void)
18151{
18152 struct neon_type_el et = neon_check_type (2, NS_DQ,
18153 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
18154 /* Saturating move where operands can be signed or unsigned, and the
18155 destination has the same signedness. */
88714cb8 18156 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18157 if (et.type == NT_unsigned)
18158 inst.instruction |= 0xc0;
18159 else
18160 inst.instruction |= 0x80;
18161 neon_two_same (0, 1, et.size / 2);
18162}
18163
18164static void
18165do_neon_qmovun (void)
18166{
18167 struct neon_type_el et = neon_check_type (2, NS_DQ,
18168 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
18169 /* Saturating move with unsigned results. Operands must be signed. */
88714cb8 18170 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18171 neon_two_same (0, 1, et.size / 2);
18172}
18173
18174static void
18175do_neon_rshift_sat_narrow (void)
18176{
18177 /* FIXME: Types for narrowing. If operands are signed, results can be signed
18178 or unsigned. If operands are unsigned, results must also be unsigned. */
18179 struct neon_type_el et = neon_check_type (2, NS_DQI,
18180 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
18181 int imm = inst.operands[2].imm;
18182 /* This gets the bounds check, size encoding and immediate bits calculation
18183 right. */
18184 et.size /= 2;
5f4273c7 18185
5287ad62
JB
18186 /* VQ{R}SHRN.I<size> <Dd>, <Qm>, #0 is a synonym for
18187 VQMOVN.I<size> <Dd>, <Qm>. */
18188 if (imm == 0)
18189 {
18190 inst.operands[2].present = 0;
18191 inst.instruction = N_MNEM_vqmovn;
18192 do_neon_qmovn ();
18193 return;
18194 }
5f4273c7 18195
5287ad62 18196 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18197 _("immediate out of range"));
5287ad62
JB
18198 neon_imm_shift (TRUE, et.type == NT_unsigned, 0, et, et.size - imm);
18199}
18200
18201static void
18202do_neon_rshift_sat_narrow_u (void)
18203{
18204 /* FIXME: Types for narrowing. If operands are signed, results can be signed
18205 or unsigned. If operands are unsigned, results must also be unsigned. */
18206 struct neon_type_el et = neon_check_type (2, NS_DQI,
18207 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
18208 int imm = inst.operands[2].imm;
18209 /* This gets the bounds check, size encoding and immediate bits calculation
18210 right. */
18211 et.size /= 2;
18212
18213 /* VQSHRUN.I<size> <Dd>, <Qm>, #0 is a synonym for
18214 VQMOVUN.I<size> <Dd>, <Qm>. */
18215 if (imm == 0)
18216 {
18217 inst.operands[2].present = 0;
18218 inst.instruction = N_MNEM_vqmovun;
18219 do_neon_qmovun ();
18220 return;
18221 }
18222
18223 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18224 _("immediate out of range"));
5287ad62
JB
18225 /* FIXME: The manual is kind of unclear about what value U should have in
18226 VQ{R}SHRUN instructions, but U=0, op=0 definitely encodes VRSHR, so it
18227 must be 1. */
18228 neon_imm_shift (TRUE, 1, 0, et, et.size - imm);
18229}
18230
18231static void
18232do_neon_movn (void)
18233{
18234 struct neon_type_el et = neon_check_type (2, NS_DQ,
18235 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
88714cb8 18236 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18237 neon_two_same (0, 1, et.size / 2);
18238}
18239
18240static void
18241do_neon_rshift_narrow (void)
18242{
18243 struct neon_type_el et = neon_check_type (2, NS_DQI,
18244 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
18245 int imm = inst.operands[2].imm;
18246 /* This gets the bounds check, size encoding and immediate bits calculation
18247 right. */
18248 et.size /= 2;
5f4273c7 18249
5287ad62
JB
18250 /* If immediate is zero then we are a pseudo-instruction for
18251 VMOVN.I<size> <Dd>, <Qm> */
18252 if (imm == 0)
18253 {
18254 inst.operands[2].present = 0;
18255 inst.instruction = N_MNEM_vmovn;
18256 do_neon_movn ();
18257 return;
18258 }
5f4273c7 18259
5287ad62 18260 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18261 _("immediate out of range for narrowing operation"));
5287ad62
JB
18262 neon_imm_shift (FALSE, 0, 0, et, et.size - imm);
18263}
18264
18265static void
18266do_neon_shll (void)
18267{
18268 /* FIXME: Type checking when lengthening. */
18269 struct neon_type_el et = neon_check_type (2, NS_QDI,
18270 N_EQK | N_DBL, N_I8 | N_I16 | N_I32 | N_KEY);
18271 unsigned imm = inst.operands[2].imm;
18272
18273 if (imm == et.size)
18274 {
18275 /* Maximum shift variant. */
88714cb8 18276 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18277 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18278 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18279 inst.instruction |= LOW4 (inst.operands[1].reg);
18280 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18281 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 18282
88714cb8 18283 neon_dp_fixup (&inst);
5287ad62
JB
18284 }
18285 else
18286 {
18287 /* A more-specific type check for non-max versions. */
18288 et = neon_check_type (2, NS_QDI,
477330fc 18289 N_EQK | N_DBL, N_SU_32 | N_KEY);
88714cb8 18290 NEON_ENCODE (IMMED, inst);
5287ad62
JB
18291 neon_imm_shift (TRUE, et.type == NT_unsigned, 0, et, imm);
18292 }
18293}
18294
037e8744 18295/* Check the various types for the VCVT instruction, and return which version
5287ad62
JB
18296 the current instruction is. */
18297
6b9a8b67
MGD
18298#define CVT_FLAVOUR_VAR \
18299 CVT_VAR (s32_f32, N_S32, N_F32, whole_reg, "ftosls", "ftosis", "ftosizs") \
18300 CVT_VAR (u32_f32, N_U32, N_F32, whole_reg, "ftouls", "ftouis", "ftouizs") \
18301 CVT_VAR (f32_s32, N_F32, N_S32, whole_reg, "fsltos", "fsitos", NULL) \
18302 CVT_VAR (f32_u32, N_F32, N_U32, whole_reg, "fultos", "fuitos", NULL) \
18303 /* Half-precision conversions. */ \
cc933301
JW
18304 CVT_VAR (s16_f16, N_S16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
18305 CVT_VAR (u16_f16, N_U16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
18306 CVT_VAR (f16_s16, N_F16 | N_KEY, N_S16, whole_reg, NULL, NULL, NULL) \
18307 CVT_VAR (f16_u16, N_F16 | N_KEY, N_U16, whole_reg, NULL, NULL, NULL) \
6b9a8b67
MGD
18308 CVT_VAR (f32_f16, N_F32, N_F16, whole_reg, NULL, NULL, NULL) \
18309 CVT_VAR (f16_f32, N_F16, N_F32, whole_reg, NULL, NULL, NULL) \
9db2f6b4
RL
18310 /* New VCVT instructions introduced by ARMv8.2 fp16 extension. \
18311 Compared with single/double precision variants, only the co-processor \
18312 field is different, so the encoding flow is reused here. */ \
18313 CVT_VAR (f16_s32, N_F16 | N_KEY, N_S32, N_VFP, "fsltos", "fsitos", NULL) \
18314 CVT_VAR (f16_u32, N_F16 | N_KEY, N_U32, N_VFP, "fultos", "fuitos", NULL) \
18315 CVT_VAR (u32_f16, N_U32, N_F16 | N_KEY, N_VFP, "ftouls", "ftouis", "ftouizs")\
18316 CVT_VAR (s32_f16, N_S32, N_F16 | N_KEY, N_VFP, "ftosls", "ftosis", "ftosizs")\
6b9a8b67
MGD
18317 /* VFP instructions. */ \
18318 CVT_VAR (f32_f64, N_F32, N_F64, N_VFP, NULL, "fcvtsd", NULL) \
18319 CVT_VAR (f64_f32, N_F64, N_F32, N_VFP, NULL, "fcvtds", NULL) \
18320 CVT_VAR (s32_f64, N_S32, N_F64 | key, N_VFP, "ftosld", "ftosid", "ftosizd") \
18321 CVT_VAR (u32_f64, N_U32, N_F64 | key, N_VFP, "ftould", "ftouid", "ftouizd") \
18322 CVT_VAR (f64_s32, N_F64 | key, N_S32, N_VFP, "fsltod", "fsitod", NULL) \
18323 CVT_VAR (f64_u32, N_F64 | key, N_U32, N_VFP, "fultod", "fuitod", NULL) \
18324 /* VFP instructions with bitshift. */ \
18325 CVT_VAR (f32_s16, N_F32 | key, N_S16, N_VFP, "fshtos", NULL, NULL) \
18326 CVT_VAR (f32_u16, N_F32 | key, N_U16, N_VFP, "fuhtos", NULL, NULL) \
18327 CVT_VAR (f64_s16, N_F64 | key, N_S16, N_VFP, "fshtod", NULL, NULL) \
18328 CVT_VAR (f64_u16, N_F64 | key, N_U16, N_VFP, "fuhtod", NULL, NULL) \
18329 CVT_VAR (s16_f32, N_S16, N_F32 | key, N_VFP, "ftoshs", NULL, NULL) \
18330 CVT_VAR (u16_f32, N_U16, N_F32 | key, N_VFP, "ftouhs", NULL, NULL) \
18331 CVT_VAR (s16_f64, N_S16, N_F64 | key, N_VFP, "ftoshd", NULL, NULL) \
18332 CVT_VAR (u16_f64, N_U16, N_F64 | key, N_VFP, "ftouhd", NULL, NULL)
18333
18334#define CVT_VAR(C, X, Y, R, BSN, CN, ZN) \
18335 neon_cvt_flavour_##C,
18336
18337/* The different types of conversions we can do. */
18338enum neon_cvt_flavour
18339{
18340 CVT_FLAVOUR_VAR
18341 neon_cvt_flavour_invalid,
18342 neon_cvt_flavour_first_fp = neon_cvt_flavour_f32_f64
18343};
18344
18345#undef CVT_VAR
18346
18347static enum neon_cvt_flavour
18348get_neon_cvt_flavour (enum neon_shape rs)
5287ad62 18349{
6b9a8b67
MGD
18350#define CVT_VAR(C,X,Y,R,BSN,CN,ZN) \
18351 et = neon_check_type (2, rs, (R) | (X), (R) | (Y)); \
18352 if (et.type != NT_invtype) \
18353 { \
18354 inst.error = NULL; \
18355 return (neon_cvt_flavour_##C); \
5287ad62 18356 }
6b9a8b67 18357
5287ad62 18358 struct neon_type_el et;
037e8744 18359 unsigned whole_reg = (rs == NS_FFI || rs == NS_FD || rs == NS_DF
477330fc 18360 || rs == NS_FF) ? N_VFP : 0;
037e8744
JB
18361 /* The instruction versions which take an immediate take one register
18362 argument, which is extended to the width of the full register. Thus the
18363 "source" and "destination" registers must have the same width. Hack that
18364 here by making the size equal to the key (wider, in this case) operand. */
18365 unsigned key = (rs == NS_QQI || rs == NS_DDI || rs == NS_FFI) ? N_KEY : 0;
5f4273c7 18366
6b9a8b67
MGD
18367 CVT_FLAVOUR_VAR;
18368
18369 return neon_cvt_flavour_invalid;
5287ad62
JB
18370#undef CVT_VAR
18371}
18372
7e8e6784
MGD
18373enum neon_cvt_mode
18374{
18375 neon_cvt_mode_a,
18376 neon_cvt_mode_n,
18377 neon_cvt_mode_p,
18378 neon_cvt_mode_m,
18379 neon_cvt_mode_z,
30bdf752
MGD
18380 neon_cvt_mode_x,
18381 neon_cvt_mode_r
7e8e6784
MGD
18382};
18383
037e8744
JB
18384/* Neon-syntax VFP conversions. */
18385
5287ad62 18386static void
6b9a8b67 18387do_vfp_nsyn_cvt (enum neon_shape rs, enum neon_cvt_flavour flavour)
5287ad62 18388{
037e8744 18389 const char *opname = 0;
5f4273c7 18390
d54af2d0
RL
18391 if (rs == NS_DDI || rs == NS_QQI || rs == NS_FFI
18392 || rs == NS_FHI || rs == NS_HFI)
5287ad62 18393 {
037e8744
JB
18394 /* Conversions with immediate bitshift. */
18395 const char *enc[] =
477330fc 18396 {
6b9a8b67
MGD
18397#define CVT_VAR(C,A,B,R,BSN,CN,ZN) BSN,
18398 CVT_FLAVOUR_VAR
18399 NULL
18400#undef CVT_VAR
477330fc 18401 };
037e8744 18402
6b9a8b67 18403 if (flavour < (int) ARRAY_SIZE (enc))
477330fc
RM
18404 {
18405 opname = enc[flavour];
18406 constraint (inst.operands[0].reg != inst.operands[1].reg,
18407 _("operands 0 and 1 must be the same register"));
18408 inst.operands[1] = inst.operands[2];
18409 memset (&inst.operands[2], '\0', sizeof (inst.operands[2]));
18410 }
5287ad62
JB
18411 }
18412 else
18413 {
037e8744
JB
18414 /* Conversions without bitshift. */
18415 const char *enc[] =
477330fc 18416 {
6b9a8b67
MGD
18417#define CVT_VAR(C,A,B,R,BSN,CN,ZN) CN,
18418 CVT_FLAVOUR_VAR
18419 NULL
18420#undef CVT_VAR
477330fc 18421 };
037e8744 18422
6b9a8b67 18423 if (flavour < (int) ARRAY_SIZE (enc))
477330fc 18424 opname = enc[flavour];
037e8744
JB
18425 }
18426
18427 if (opname)
18428 do_vfp_nsyn_opcode (opname);
9db2f6b4
RL
18429
18430 /* ARMv8.2 fp16 VCVT instruction. */
18431 if (flavour == neon_cvt_flavour_s32_f16
18432 || flavour == neon_cvt_flavour_u32_f16
18433 || flavour == neon_cvt_flavour_f16_u32
18434 || flavour == neon_cvt_flavour_f16_s32)
18435 do_scalar_fp16_v82_encode ();
037e8744
JB
18436}
18437
18438static void
18439do_vfp_nsyn_cvtz (void)
18440{
d54af2d0 18441 enum neon_shape rs = neon_select_shape (NS_FH, NS_FF, NS_FD, NS_NULL);
6b9a8b67 18442 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744
JB
18443 const char *enc[] =
18444 {
6b9a8b67
MGD
18445#define CVT_VAR(C,A,B,R,BSN,CN,ZN) ZN,
18446 CVT_FLAVOUR_VAR
18447 NULL
18448#undef CVT_VAR
037e8744
JB
18449 };
18450
6b9a8b67 18451 if (flavour < (int) ARRAY_SIZE (enc) && enc[flavour])
037e8744
JB
18452 do_vfp_nsyn_opcode (enc[flavour]);
18453}
f31fef98 18454
037e8744 18455static void
bacebabc 18456do_vfp_nsyn_cvt_fpv8 (enum neon_cvt_flavour flavour,
7e8e6784
MGD
18457 enum neon_cvt_mode mode)
18458{
18459 int sz, op;
18460 int rm;
18461
a715796b
TG
18462 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
18463 D register operands. */
18464 if (flavour == neon_cvt_flavour_s32_f64
18465 || flavour == neon_cvt_flavour_u32_f64)
18466 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
18467 _(BAD_FPU));
18468
9db2f6b4
RL
18469 if (flavour == neon_cvt_flavour_s32_f16
18470 || flavour == neon_cvt_flavour_u32_f16)
18471 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
18472 _(BAD_FP16));
18473
5ee91343 18474 set_pred_insn_type (OUTSIDE_PRED_INSN);
7e8e6784
MGD
18475
18476 switch (flavour)
18477 {
18478 case neon_cvt_flavour_s32_f64:
18479 sz = 1;
827f64ff 18480 op = 1;
7e8e6784
MGD
18481 break;
18482 case neon_cvt_flavour_s32_f32:
18483 sz = 0;
18484 op = 1;
18485 break;
9db2f6b4
RL
18486 case neon_cvt_flavour_s32_f16:
18487 sz = 0;
18488 op = 1;
18489 break;
7e8e6784
MGD
18490 case neon_cvt_flavour_u32_f64:
18491 sz = 1;
18492 op = 0;
18493 break;
18494 case neon_cvt_flavour_u32_f32:
18495 sz = 0;
18496 op = 0;
18497 break;
9db2f6b4
RL
18498 case neon_cvt_flavour_u32_f16:
18499 sz = 0;
18500 op = 0;
18501 break;
7e8e6784
MGD
18502 default:
18503 first_error (_("invalid instruction shape"));
18504 return;
18505 }
18506
18507 switch (mode)
18508 {
18509 case neon_cvt_mode_a: rm = 0; break;
18510 case neon_cvt_mode_n: rm = 1; break;
18511 case neon_cvt_mode_p: rm = 2; break;
18512 case neon_cvt_mode_m: rm = 3; break;
18513 default: first_error (_("invalid rounding mode")); return;
18514 }
18515
18516 NEON_ENCODE (FPV8, inst);
18517 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
18518 encode_arm_vfp_reg (inst.operands[1].reg, sz == 1 ? VFP_REG_Dm : VFP_REG_Sm);
18519 inst.instruction |= sz << 8;
9db2f6b4
RL
18520
18521 /* ARMv8.2 fp16 VCVT instruction. */
18522 if (flavour == neon_cvt_flavour_s32_f16
18523 ||flavour == neon_cvt_flavour_u32_f16)
18524 do_scalar_fp16_v82_encode ();
7e8e6784
MGD
18525 inst.instruction |= op << 7;
18526 inst.instruction |= rm << 16;
18527 inst.instruction |= 0xf0000000;
18528 inst.is_neon = TRUE;
18529}
18530
18531static void
18532do_neon_cvt_1 (enum neon_cvt_mode mode)
037e8744
JB
18533{
18534 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_FFI, NS_DD, NS_QQ,
d54af2d0
RL
18535 NS_FD, NS_DF, NS_FF, NS_QD, NS_DQ,
18536 NS_FH, NS_HF, NS_FHI, NS_HFI,
18537 NS_NULL);
6b9a8b67 18538 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744 18539
cc933301
JW
18540 if (flavour == neon_cvt_flavour_invalid)
18541 return;
18542
e3e535bc 18543 /* PR11109: Handle round-to-zero for VCVT conversions. */
7e8e6784 18544 if (mode == neon_cvt_mode_z
e3e535bc 18545 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_vfp_v2)
cc933301
JW
18546 && (flavour == neon_cvt_flavour_s16_f16
18547 || flavour == neon_cvt_flavour_u16_f16
18548 || flavour == neon_cvt_flavour_s32_f32
bacebabc
RM
18549 || flavour == neon_cvt_flavour_u32_f32
18550 || flavour == neon_cvt_flavour_s32_f64
6b9a8b67 18551 || flavour == neon_cvt_flavour_u32_f64)
e3e535bc
NC
18552 && (rs == NS_FD || rs == NS_FF))
18553 {
18554 do_vfp_nsyn_cvtz ();
18555 return;
18556 }
18557
9db2f6b4
RL
18558 /* ARMv8.2 fp16 VCVT conversions. */
18559 if (mode == neon_cvt_mode_z
18560 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16)
18561 && (flavour == neon_cvt_flavour_s32_f16
18562 || flavour == neon_cvt_flavour_u32_f16)
18563 && (rs == NS_FH))
18564 {
18565 do_vfp_nsyn_cvtz ();
18566 do_scalar_fp16_v82_encode ();
18567 return;
18568 }
18569
037e8744 18570 /* VFP rather than Neon conversions. */
6b9a8b67 18571 if (flavour >= neon_cvt_flavour_first_fp)
037e8744 18572 {
7e8e6784
MGD
18573 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
18574 do_vfp_nsyn_cvt (rs, flavour);
18575 else
18576 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
18577
037e8744
JB
18578 return;
18579 }
18580
18581 switch (rs)
18582 {
037e8744 18583 case NS_QQI:
dd9634d9
AV
18584 if (mode == neon_cvt_mode_z
18585 && (flavour == neon_cvt_flavour_f16_s16
18586 || flavour == neon_cvt_flavour_f16_u16
18587 || flavour == neon_cvt_flavour_s16_f16
18588 || flavour == neon_cvt_flavour_u16_f16
18589 || flavour == neon_cvt_flavour_f32_u32
18590 || flavour == neon_cvt_flavour_f32_s32
18591 || flavour == neon_cvt_flavour_s32_f32
18592 || flavour == neon_cvt_flavour_u32_f32))
18593 {
64c350f2
AV
18594 if (!check_simd_pred_availability (TRUE,
18595 NEON_CHECK_CC | NEON_CHECK_ARCH))
dd9634d9
AV
18596 return;
18597 }
18598 else if (mode == neon_cvt_mode_n)
18599 {
18600 /* We are dealing with vcvt with the 'ne' condition. */
18601 inst.cond = 0x1;
18602 inst.instruction = N_MNEM_vcvt;
18603 do_neon_cvt_1 (neon_cvt_mode_z);
18604 return;
18605 }
18606 /* fall through. */
18607 case NS_DDI:
037e8744 18608 {
477330fc 18609 unsigned immbits;
cc933301
JW
18610 unsigned enctab[] = {0x0000100, 0x1000100, 0x0, 0x1000000,
18611 0x0000100, 0x1000100, 0x0, 0x1000000};
35997600 18612
dd9634d9
AV
18613 if ((rs != NS_QQI || !ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
18614 && vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
18615 return;
18616
18617 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
18618 {
18619 constraint (inst.operands[2].present && inst.operands[2].imm == 0,
18620 _("immediate value out of range"));
18621 switch (flavour)
18622 {
18623 case neon_cvt_flavour_f16_s16:
18624 case neon_cvt_flavour_f16_u16:
18625 case neon_cvt_flavour_s16_f16:
18626 case neon_cvt_flavour_u16_f16:
18627 constraint (inst.operands[2].imm > 16,
18628 _("immediate value out of range"));
18629 break;
18630 case neon_cvt_flavour_f32_u32:
18631 case neon_cvt_flavour_f32_s32:
18632 case neon_cvt_flavour_s32_f32:
18633 case neon_cvt_flavour_u32_f32:
18634 constraint (inst.operands[2].imm > 32,
18635 _("immediate value out of range"));
18636 break;
18637 default:
18638 inst.error = BAD_FPU;
18639 return;
18640 }
18641 }
037e8744 18642
477330fc
RM
18643 /* Fixed-point conversion with #0 immediate is encoded as an
18644 integer conversion. */
18645 if (inst.operands[2].present && inst.operands[2].imm == 0)
18646 goto int_encode;
477330fc
RM
18647 NEON_ENCODE (IMMED, inst);
18648 if (flavour != neon_cvt_flavour_invalid)
18649 inst.instruction |= enctab[flavour];
18650 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18651 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18652 inst.instruction |= LOW4 (inst.operands[1].reg);
18653 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18654 inst.instruction |= neon_quad (rs) << 6;
18655 inst.instruction |= 1 << 21;
cc933301
JW
18656 if (flavour < neon_cvt_flavour_s16_f16)
18657 {
18658 inst.instruction |= 1 << 21;
18659 immbits = 32 - inst.operands[2].imm;
18660 inst.instruction |= immbits << 16;
18661 }
18662 else
18663 {
18664 inst.instruction |= 3 << 20;
18665 immbits = 16 - inst.operands[2].imm;
18666 inst.instruction |= immbits << 16;
18667 inst.instruction &= ~(1 << 9);
18668 }
477330fc
RM
18669
18670 neon_dp_fixup (&inst);
037e8744
JB
18671 }
18672 break;
18673
037e8744 18674 case NS_QQ:
dd9634d9
AV
18675 if ((mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
18676 || mode == neon_cvt_mode_m || mode == neon_cvt_mode_p)
18677 && (flavour == neon_cvt_flavour_s16_f16
18678 || flavour == neon_cvt_flavour_u16_f16
18679 || flavour == neon_cvt_flavour_s32_f32
18680 || flavour == neon_cvt_flavour_u32_f32))
18681 {
64c350f2
AV
18682 if (!check_simd_pred_availability (TRUE,
18683 NEON_CHECK_CC | NEON_CHECK_ARCH8))
dd9634d9
AV
18684 return;
18685 }
18686 else if (mode == neon_cvt_mode_z
18687 && (flavour == neon_cvt_flavour_f16_s16
18688 || flavour == neon_cvt_flavour_f16_u16
18689 || flavour == neon_cvt_flavour_s16_f16
18690 || flavour == neon_cvt_flavour_u16_f16
18691 || flavour == neon_cvt_flavour_f32_u32
18692 || flavour == neon_cvt_flavour_f32_s32
18693 || flavour == neon_cvt_flavour_s32_f32
18694 || flavour == neon_cvt_flavour_u32_f32))
18695 {
64c350f2
AV
18696 if (!check_simd_pred_availability (TRUE,
18697 NEON_CHECK_CC | NEON_CHECK_ARCH))
dd9634d9
AV
18698 return;
18699 }
18700 /* fall through. */
18701 case NS_DD:
7e8e6784
MGD
18702 if (mode != neon_cvt_mode_x && mode != neon_cvt_mode_z)
18703 {
7e8e6784 18704
dd9634d9 18705 NEON_ENCODE (FLOAT, inst);
64c350f2
AV
18706 if (!check_simd_pred_availability (TRUE,
18707 NEON_CHECK_CC | NEON_CHECK_ARCH8))
7e8e6784
MGD
18708 return;
18709
18710 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18711 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18712 inst.instruction |= LOW4 (inst.operands[1].reg);
18713 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18714 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
18715 inst.instruction |= (flavour == neon_cvt_flavour_u16_f16
18716 || flavour == neon_cvt_flavour_u32_f32) << 7;
7e8e6784 18717 inst.instruction |= mode << 8;
cc933301
JW
18718 if (flavour == neon_cvt_flavour_u16_f16
18719 || flavour == neon_cvt_flavour_s16_f16)
18720 /* Mask off the original size bits and reencode them. */
18721 inst.instruction = ((inst.instruction & 0xfff3ffff) | (1 << 18));
18722
7e8e6784
MGD
18723 if (thumb_mode)
18724 inst.instruction |= 0xfc000000;
18725 else
18726 inst.instruction |= 0xf0000000;
18727 }
18728 else
18729 {
037e8744 18730 int_encode:
7e8e6784 18731 {
cc933301
JW
18732 unsigned enctab[] = { 0x100, 0x180, 0x0, 0x080,
18733 0x100, 0x180, 0x0, 0x080};
037e8744 18734
7e8e6784 18735 NEON_ENCODE (INTEGER, inst);
037e8744 18736
dd9634d9
AV
18737 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
18738 {
18739 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
18740 return;
18741 }
037e8744 18742
7e8e6784
MGD
18743 if (flavour != neon_cvt_flavour_invalid)
18744 inst.instruction |= enctab[flavour];
037e8744 18745
7e8e6784
MGD
18746 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18747 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18748 inst.instruction |= LOW4 (inst.operands[1].reg);
18749 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18750 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
18751 if (flavour >= neon_cvt_flavour_s16_f16
18752 && flavour <= neon_cvt_flavour_f16_u16)
18753 /* Half precision. */
18754 inst.instruction |= 1 << 18;
18755 else
18756 inst.instruction |= 2 << 18;
037e8744 18757
7e8e6784
MGD
18758 neon_dp_fixup (&inst);
18759 }
18760 }
18761 break;
037e8744 18762
8e79c3df
CM
18763 /* Half-precision conversions for Advanced SIMD -- neon. */
18764 case NS_QD:
18765 case NS_DQ:
bc52d49c
MM
18766 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
18767 return;
8e79c3df
CM
18768
18769 if ((rs == NS_DQ)
18770 && (inst.vectype.el[0].size != 16 || inst.vectype.el[1].size != 32))
18771 {
18772 as_bad (_("operand size must match register width"));
18773 break;
18774 }
18775
18776 if ((rs == NS_QD)
18777 && ((inst.vectype.el[0].size != 32 || inst.vectype.el[1].size != 16)))
18778 {
18779 as_bad (_("operand size must match register width"));
18780 break;
18781 }
18782
18783 if (rs == NS_DQ)
477330fc 18784 inst.instruction = 0x3b60600;
8e79c3df
CM
18785 else
18786 inst.instruction = 0x3b60700;
18787
18788 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18789 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18790 inst.instruction |= LOW4 (inst.operands[1].reg);
18791 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
88714cb8 18792 neon_dp_fixup (&inst);
8e79c3df
CM
18793 break;
18794
037e8744
JB
18795 default:
18796 /* Some VFP conversions go here (s32 <-> f32, u32 <-> f32). */
7e8e6784
MGD
18797 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
18798 do_vfp_nsyn_cvt (rs, flavour);
18799 else
18800 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
5287ad62 18801 }
5287ad62
JB
18802}
18803
e3e535bc
NC
18804static void
18805do_neon_cvtr (void)
18806{
7e8e6784 18807 do_neon_cvt_1 (neon_cvt_mode_x);
e3e535bc
NC
18808}
18809
18810static void
18811do_neon_cvt (void)
18812{
7e8e6784
MGD
18813 do_neon_cvt_1 (neon_cvt_mode_z);
18814}
18815
18816static void
18817do_neon_cvta (void)
18818{
18819 do_neon_cvt_1 (neon_cvt_mode_a);
18820}
18821
18822static void
18823do_neon_cvtn (void)
18824{
18825 do_neon_cvt_1 (neon_cvt_mode_n);
18826}
18827
18828static void
18829do_neon_cvtp (void)
18830{
18831 do_neon_cvt_1 (neon_cvt_mode_p);
18832}
18833
18834static void
18835do_neon_cvtm (void)
18836{
18837 do_neon_cvt_1 (neon_cvt_mode_m);
e3e535bc
NC
18838}
18839
8e79c3df 18840static void
c70a8987 18841do_neon_cvttb_2 (bfd_boolean t, bfd_boolean to, bfd_boolean is_double)
8e79c3df 18842{
c70a8987
MGD
18843 if (is_double)
18844 mark_feature_used (&fpu_vfp_ext_armv8);
8e79c3df 18845
c70a8987
MGD
18846 encode_arm_vfp_reg (inst.operands[0].reg,
18847 (is_double && !to) ? VFP_REG_Dd : VFP_REG_Sd);
18848 encode_arm_vfp_reg (inst.operands[1].reg,
18849 (is_double && to) ? VFP_REG_Dm : VFP_REG_Sm);
18850 inst.instruction |= to ? 0x10000 : 0;
18851 inst.instruction |= t ? 0x80 : 0;
18852 inst.instruction |= is_double ? 0x100 : 0;
18853 do_vfp_cond_or_thumb ();
18854}
8e79c3df 18855
c70a8987
MGD
18856static void
18857do_neon_cvttb_1 (bfd_boolean t)
18858{
d54af2d0 18859 enum neon_shape rs = neon_select_shape (NS_HF, NS_HD, NS_FH, NS_FF, NS_FD,
dd9634d9 18860 NS_DF, NS_DH, NS_QQ, NS_QQI, NS_NULL);
8e79c3df 18861
c70a8987
MGD
18862 if (rs == NS_NULL)
18863 return;
dd9634d9
AV
18864 else if (rs == NS_QQ || rs == NS_QQI)
18865 {
18866 int single_to_half = 0;
64c350f2 18867 if (!check_simd_pred_availability (TRUE, NEON_CHECK_ARCH))
dd9634d9
AV
18868 return;
18869
18870 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
18871
18872 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
18873 && (flavour == neon_cvt_flavour_u16_f16
18874 || flavour == neon_cvt_flavour_s16_f16
18875 || flavour == neon_cvt_flavour_f16_s16
18876 || flavour == neon_cvt_flavour_f16_u16
18877 || flavour == neon_cvt_flavour_u32_f32
18878 || flavour == neon_cvt_flavour_s32_f32
18879 || flavour == neon_cvt_flavour_f32_s32
18880 || flavour == neon_cvt_flavour_f32_u32))
18881 {
18882 inst.cond = 0xf;
18883 inst.instruction = N_MNEM_vcvt;
18884 set_pred_insn_type (INSIDE_VPT_INSN);
18885 do_neon_cvt_1 (neon_cvt_mode_z);
18886 return;
18887 }
18888 else if (rs == NS_QQ && flavour == neon_cvt_flavour_f32_f16)
18889 single_to_half = 1;
18890 else if (rs == NS_QQ && flavour != neon_cvt_flavour_f16_f32)
18891 {
18892 first_error (BAD_FPU);
18893 return;
18894 }
18895
18896 inst.instruction = 0xee3f0e01;
18897 inst.instruction |= single_to_half << 28;
18898 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18899 inst.instruction |= LOW4 (inst.operands[0].reg) << 13;
18900 inst.instruction |= t << 12;
18901 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18902 inst.instruction |= LOW4 (inst.operands[1].reg) << 1;
18903 inst.is_neon = 1;
18904 }
c70a8987
MGD
18905 else if (neon_check_type (2, rs, N_F16, N_F32 | N_VFP).type != NT_invtype)
18906 {
18907 inst.error = NULL;
18908 do_neon_cvttb_2 (t, /*to=*/TRUE, /*is_double=*/FALSE);
18909 }
18910 else if (neon_check_type (2, rs, N_F32 | N_VFP, N_F16).type != NT_invtype)
18911 {
18912 inst.error = NULL;
18913 do_neon_cvttb_2 (t, /*to=*/FALSE, /*is_double=*/FALSE);
18914 }
18915 else if (neon_check_type (2, rs, N_F16, N_F64 | N_VFP).type != NT_invtype)
18916 {
a715796b
TG
18917 /* The VCVTB and VCVTT instructions with D-register operands
18918 don't work for SP only targets. */
18919 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
18920 _(BAD_FPU));
18921
c70a8987
MGD
18922 inst.error = NULL;
18923 do_neon_cvttb_2 (t, /*to=*/TRUE, /*is_double=*/TRUE);
18924 }
18925 else if (neon_check_type (2, rs, N_F64 | N_VFP, N_F16).type != NT_invtype)
18926 {
a715796b
TG
18927 /* The VCVTB and VCVTT instructions with D-register operands
18928 don't work for SP only targets. */
18929 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
18930 _(BAD_FPU));
18931
c70a8987
MGD
18932 inst.error = NULL;
18933 do_neon_cvttb_2 (t, /*to=*/FALSE, /*is_double=*/TRUE);
18934 }
18935 else
18936 return;
18937}
18938
18939static void
18940do_neon_cvtb (void)
18941{
18942 do_neon_cvttb_1 (FALSE);
8e79c3df
CM
18943}
18944
18945
18946static void
18947do_neon_cvtt (void)
18948{
c70a8987 18949 do_neon_cvttb_1 (TRUE);
8e79c3df
CM
18950}
18951
5287ad62
JB
18952static void
18953neon_move_immediate (void)
18954{
037e8744
JB
18955 enum neon_shape rs = neon_select_shape (NS_DI, NS_QI, NS_NULL);
18956 struct neon_type_el et = neon_check_type (2, rs,
18957 N_I8 | N_I16 | N_I32 | N_I64 | N_F32 | N_KEY, N_EQK);
5287ad62 18958 unsigned immlo, immhi = 0, immbits;
c96612cc 18959 int op, cmode, float_p;
5287ad62 18960
037e8744 18961 constraint (et.type == NT_invtype,
477330fc 18962 _("operand size must be specified for immediate VMOV"));
037e8744 18963
5287ad62
JB
18964 /* We start out as an MVN instruction if OP = 1, MOV otherwise. */
18965 op = (inst.instruction & (1 << 5)) != 0;
18966
18967 immlo = inst.operands[1].imm;
18968 if (inst.operands[1].regisimm)
18969 immhi = inst.operands[1].reg;
18970
18971 constraint (et.size < 32 && (immlo & ~((1 << et.size) - 1)) != 0,
477330fc 18972 _("immediate has bits set outside the operand size"));
5287ad62 18973
c96612cc
JB
18974 float_p = inst.operands[1].immisfloat;
18975
18976 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits, &op,
477330fc 18977 et.size, et.type)) == FAIL)
5287ad62
JB
18978 {
18979 /* Invert relevant bits only. */
18980 neon_invert_size (&immlo, &immhi, et.size);
18981 /* Flip from VMOV/VMVN to VMVN/VMOV. Some immediate types are unavailable
477330fc
RM
18982 with one or the other; those cases are caught by
18983 neon_cmode_for_move_imm. */
5287ad62 18984 op = !op;
c96612cc
JB
18985 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits,
18986 &op, et.size, et.type)) == FAIL)
477330fc
RM
18987 {
18988 first_error (_("immediate out of range"));
18989 return;
18990 }
5287ad62
JB
18991 }
18992
18993 inst.instruction &= ~(1 << 5);
18994 inst.instruction |= op << 5;
18995
18996 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18997 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
037e8744 18998 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
18999 inst.instruction |= cmode << 8;
19000
19001 neon_write_immbits (immbits);
19002}
19003
19004static void
19005do_neon_mvn (void)
19006{
64c350f2 19007 if (!check_simd_pred_availability (FALSE, NEON_CHECK_CC | NEON_CHECK_ARCH))
1a186d29
AV
19008 return;
19009
5287ad62
JB
19010 if (inst.operands[1].isreg)
19011 {
1a186d29
AV
19012 enum neon_shape rs;
19013 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19014 rs = neon_select_shape (NS_QQ, NS_NULL);
19015 else
19016 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5f4273c7 19017
88714cb8 19018 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
19019 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19020 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19021 inst.instruction |= LOW4 (inst.operands[1].reg);
19022 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 19023 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
19024 }
19025 else
19026 {
88714cb8 19027 NEON_ENCODE (IMMED, inst);
5287ad62
JB
19028 neon_move_immediate ();
19029 }
19030
88714cb8 19031 neon_dp_fixup (&inst);
1a186d29
AV
19032
19033 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19034 {
19035 constraint (!inst.operands[1].isreg && !inst.operands[0].isquad, BAD_FPU);
19036 constraint ((inst.instruction & 0xd00) == 0xd00,
19037 _("immediate value out of range"));
19038 }
5287ad62
JB
19039}
19040
19041/* Encode instructions of form:
19042
19043 |28/24|23|22|21 20|19 16|15 12|11 8|7|6|5|4|3 0|
5f4273c7 19044 | U |x |D |size | Rn | Rd |x x x x|N|x|M|x| Rm | */
5287ad62
JB
19045
19046static void
19047neon_mixed_length (struct neon_type_el et, unsigned size)
19048{
19049 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19050 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19051 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
19052 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
19053 inst.instruction |= LOW4 (inst.operands[2].reg);
19054 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
19055 inst.instruction |= (et.type == NT_unsigned) << 24;
19056 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 19057
88714cb8 19058 neon_dp_fixup (&inst);
5287ad62
JB
19059}
19060
19061static void
19062do_neon_dyadic_long (void)
19063{
5ee91343
AV
19064 enum neon_shape rs = neon_select_shape (NS_QDD, NS_QQQ, NS_QQR, NS_NULL);
19065 if (rs == NS_QDD)
19066 {
19067 if (vfp_or_neon_is_neon (NEON_CHECK_ARCH | NEON_CHECK_CC) == FAIL)
19068 return;
19069
19070 NEON_ENCODE (INTEGER, inst);
19071 /* FIXME: Type checking for lengthening op. */
19072 struct neon_type_el et = neon_check_type (3, NS_QDD,
19073 N_EQK | N_DBL, N_EQK, N_SU_32 | N_KEY);
19074 neon_mixed_length (et, et.size);
19075 }
19076 else if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
19077 && (inst.cond == 0xf || inst.cond == 0x10))
19078 {
19079 /* If parsing for MVE, vaddl/vsubl/vabdl{e,t} can only be vadd/vsub/vabd
19080 in an IT block with le/lt conditions. */
19081
19082 if (inst.cond == 0xf)
19083 inst.cond = 0xb;
19084 else if (inst.cond == 0x10)
19085 inst.cond = 0xd;
19086
19087 inst.pred_insn_type = INSIDE_IT_INSN;
19088
19089 if (inst.instruction == N_MNEM_vaddl)
19090 {
19091 inst.instruction = N_MNEM_vadd;
19092 do_neon_addsub_if_i ();
19093 }
19094 else if (inst.instruction == N_MNEM_vsubl)
19095 {
19096 inst.instruction = N_MNEM_vsub;
19097 do_neon_addsub_if_i ();
19098 }
19099 else if (inst.instruction == N_MNEM_vabdl)
19100 {
19101 inst.instruction = N_MNEM_vabd;
19102 do_neon_dyadic_if_su ();
19103 }
19104 }
19105 else
19106 first_error (BAD_FPU);
5287ad62
JB
19107}
19108
19109static void
19110do_neon_abal (void)
19111{
19112 struct neon_type_el et = neon_check_type (3, NS_QDD,
19113 N_EQK | N_INT | N_DBL, N_EQK, N_SU_32 | N_KEY);
19114 neon_mixed_length (et, et.size);
19115}
19116
19117static void
19118neon_mac_reg_scalar_long (unsigned regtypes, unsigned scalartypes)
19119{
19120 if (inst.operands[2].isscalar)
19121 {
dcbf9037 19122 struct neon_type_el et = neon_check_type (3, NS_QDS,
477330fc 19123 N_EQK | N_DBL, N_EQK, regtypes | N_KEY);
88714cb8 19124 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
19125 neon_mul_mac (et, et.type == NT_unsigned);
19126 }
19127 else
19128 {
19129 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 19130 N_EQK | N_DBL, N_EQK, scalartypes | N_KEY);
88714cb8 19131 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
19132 neon_mixed_length (et, et.size);
19133 }
19134}
19135
19136static void
19137do_neon_mac_maybe_scalar_long (void)
19138{
19139 neon_mac_reg_scalar_long (N_S16 | N_S32 | N_U16 | N_U32, N_SU_32);
19140}
19141
dec41383
JW
19142/* Like neon_scalar_for_mul, this function generate Rm encoding from GAS's
19143 internal SCALAR. QUAD_P is 1 if it's for Q format, otherwise it's 0. */
19144
19145static unsigned
19146neon_scalar_for_fmac_fp16_long (unsigned scalar, unsigned quad_p)
19147{
19148 unsigned regno = NEON_SCALAR_REG (scalar);
19149 unsigned elno = NEON_SCALAR_INDEX (scalar);
19150
19151 if (quad_p)
19152 {
19153 if (regno > 7 || elno > 3)
19154 goto bad_scalar;
19155
19156 return ((regno & 0x7)
19157 | ((elno & 0x1) << 3)
19158 | (((elno >> 1) & 0x1) << 5));
19159 }
19160 else
19161 {
19162 if (regno > 15 || elno > 1)
19163 goto bad_scalar;
19164
19165 return (((regno & 0x1) << 5)
19166 | ((regno >> 1) & 0x7)
19167 | ((elno & 0x1) << 3));
19168 }
19169
19170bad_scalar:
19171 first_error (_("scalar out of range for multiply instruction"));
19172 return 0;
19173}
19174
19175static void
19176do_neon_fmac_maybe_scalar_long (int subtype)
19177{
19178 enum neon_shape rs;
19179 int high8;
19180 /* NOTE: vfmal/vfmsl use slightly different NEON three-same encoding. 'size"
19181 field (bits[21:20]) has different meaning. For scalar index variant, it's
19182 used to differentiate add and subtract, otherwise it's with fixed value
19183 0x2. */
19184 int size = -1;
19185
19186 if (inst.cond != COND_ALWAYS)
19187 as_warn (_("vfmal/vfmsl with FP16 type cannot be conditional, the "
19188 "behaviour is UNPREDICTABLE"));
19189
01f48020 19190 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16_fml),
dec41383
JW
19191 _(BAD_FP16));
19192
19193 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
19194 _(BAD_FPU));
19195
19196 /* vfmal/vfmsl are in three-same D/Q register format or the third operand can
19197 be a scalar index register. */
19198 if (inst.operands[2].isscalar)
19199 {
19200 high8 = 0xfe000000;
19201 if (subtype)
19202 size = 16;
19203 rs = neon_select_shape (NS_DHS, NS_QDS, NS_NULL);
19204 }
19205 else
19206 {
19207 high8 = 0xfc000000;
19208 size = 32;
19209 if (subtype)
19210 inst.instruction |= (0x1 << 23);
19211 rs = neon_select_shape (NS_DHH, NS_QDD, NS_NULL);
19212 }
19213
19214 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16);
19215
19216 /* "opcode" from template has included "ubit", so simply pass 0 here. Also,
19217 the "S" bit in size field has been reused to differentiate vfmal and vfmsl,
19218 so we simply pass -1 as size. */
19219 unsigned quad_p = (rs == NS_QDD || rs == NS_QDS);
19220 neon_three_same (quad_p, 0, size);
19221
19222 /* Undo neon_dp_fixup. Redo the high eight bits. */
19223 inst.instruction &= 0x00ffffff;
19224 inst.instruction |= high8;
19225
19226#define LOW1(R) ((R) & 0x1)
19227#define HI4(R) (((R) >> 1) & 0xf)
19228 /* Unlike usually NEON three-same, encoding for Vn and Vm will depend on
19229 whether the instruction is in Q form and whether Vm is a scalar indexed
19230 operand. */
19231 if (inst.operands[2].isscalar)
19232 {
19233 unsigned rm
19234 = neon_scalar_for_fmac_fp16_long (inst.operands[2].reg, quad_p);
19235 inst.instruction &= 0xffffffd0;
19236 inst.instruction |= rm;
19237
19238 if (!quad_p)
19239 {
19240 /* Redo Rn as well. */
19241 inst.instruction &= 0xfff0ff7f;
19242 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
19243 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
19244 }
19245 }
19246 else if (!quad_p)
19247 {
19248 /* Redo Rn and Rm. */
19249 inst.instruction &= 0xfff0ff50;
19250 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
19251 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
19252 inst.instruction |= HI4 (inst.operands[2].reg);
19253 inst.instruction |= LOW1 (inst.operands[2].reg) << 5;
19254 }
19255}
19256
19257static void
19258do_neon_vfmal (void)
19259{
19260 return do_neon_fmac_maybe_scalar_long (0);
19261}
19262
19263static void
19264do_neon_vfmsl (void)
19265{
19266 return do_neon_fmac_maybe_scalar_long (1);
19267}
19268
5287ad62
JB
19269static void
19270do_neon_dyadic_wide (void)
19271{
19272 struct neon_type_el et = neon_check_type (3, NS_QQD,
19273 N_EQK | N_DBL, N_EQK | N_DBL, N_SU_32 | N_KEY);
19274 neon_mixed_length (et, et.size);
19275}
19276
19277static void
19278do_neon_dyadic_narrow (void)
19279{
19280 struct neon_type_el et = neon_check_type (3, NS_QDD,
19281 N_EQK | N_DBL, N_EQK, N_I16 | N_I32 | N_I64 | N_KEY);
428e3f1f
PB
19282 /* Operand sign is unimportant, and the U bit is part of the opcode,
19283 so force the operand type to integer. */
19284 et.type = NT_integer;
5287ad62
JB
19285 neon_mixed_length (et, et.size / 2);
19286}
19287
19288static void
19289do_neon_mul_sat_scalar_long (void)
19290{
19291 neon_mac_reg_scalar_long (N_S16 | N_S32, N_S16 | N_S32);
19292}
19293
19294static void
19295do_neon_vmull (void)
19296{
19297 if (inst.operands[2].isscalar)
19298 do_neon_mac_maybe_scalar_long ();
19299 else
19300 {
19301 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 19302 N_EQK | N_DBL, N_EQK, N_SU_32 | N_P8 | N_P64 | N_KEY);
4f51b4bd 19303
5287ad62 19304 if (et.type == NT_poly)
477330fc 19305 NEON_ENCODE (POLY, inst);
5287ad62 19306 else
477330fc 19307 NEON_ENCODE (INTEGER, inst);
4f51b4bd
MGD
19308
19309 /* For polynomial encoding the U bit must be zero, and the size must
19310 be 8 (encoded as 0b00) or, on ARMv8 or later 64 (encoded, non
19311 obviously, as 0b10). */
19312 if (et.size == 64)
19313 {
19314 /* Check we're on the correct architecture. */
19315 if (!mark_feature_used (&fpu_crypto_ext_armv8))
19316 inst.error =
19317 _("Instruction form not available on this architecture.");
19318
19319 et.size = 32;
19320 }
19321
5287ad62
JB
19322 neon_mixed_length (et, et.size);
19323 }
19324}
19325
19326static void
19327do_neon_ext (void)
19328{
037e8744 19329 enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
5287ad62
JB
19330 struct neon_type_el et = neon_check_type (3, rs,
19331 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
19332 unsigned imm = (inst.operands[3].imm * et.size) / 8;
35997600
NC
19333
19334 constraint (imm >= (unsigned) (neon_quad (rs) ? 16 : 8),
19335 _("shift out of range"));
5287ad62
JB
19336 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19337 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19338 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
19339 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
19340 inst.instruction |= LOW4 (inst.operands[2].reg);
19341 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
037e8744 19342 inst.instruction |= neon_quad (rs) << 6;
5287ad62 19343 inst.instruction |= imm << 8;
5f4273c7 19344
88714cb8 19345 neon_dp_fixup (&inst);
5287ad62
JB
19346}
19347
19348static void
19349do_neon_rev (void)
19350{
64c350f2 19351 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
19352 return;
19353
19354 enum neon_shape rs;
19355 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19356 rs = neon_select_shape (NS_QQ, NS_NULL);
19357 else
19358 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
19359
5287ad62
JB
19360 struct neon_type_el et = neon_check_type (2, rs,
19361 N_EQK, N_8 | N_16 | N_32 | N_KEY);
4401c241 19362
5287ad62
JB
19363 unsigned op = (inst.instruction >> 7) & 3;
19364 /* N (width of reversed regions) is encoded as part of the bitmask. We
19365 extract it here to check the elements to be reversed are smaller.
19366 Otherwise we'd get a reserved instruction. */
19367 unsigned elsize = (op == 2) ? 16 : (op == 1) ? 32 : (op == 0) ? 64 : 0;
4401c241
AV
19368
19369 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext) && elsize == 64
19370 && inst.operands[0].reg == inst.operands[1].reg)
19371 as_tsktsk (_("Warning: 64-bit element size and same destination and source"
19372 " operands makes instruction UNPREDICTABLE"));
19373
9c2799c2 19374 gas_assert (elsize != 0);
5287ad62 19375 constraint (et.size >= elsize,
477330fc 19376 _("elements must be smaller than reversal region"));
037e8744 19377 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19378}
19379
19380static void
19381do_neon_dup (void)
19382{
19383 if (inst.operands[1].isscalar)
19384 {
b409bdb6
AV
19385 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1),
19386 BAD_FPU);
037e8744 19387 enum neon_shape rs = neon_select_shape (NS_DS, NS_QS, NS_NULL);
dcbf9037 19388 struct neon_type_el et = neon_check_type (2, rs,
477330fc 19389 N_EQK, N_8 | N_16 | N_32 | N_KEY);
5287ad62 19390 unsigned sizebits = et.size >> 3;
dcbf9037 19391 unsigned dm = NEON_SCALAR_REG (inst.operands[1].reg);
5287ad62 19392 int logsize = neon_logbits (et.size);
dcbf9037 19393 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg) << logsize;
037e8744
JB
19394
19395 if (vfp_or_neon_is_neon (NEON_CHECK_CC) == FAIL)
477330fc 19396 return;
037e8744 19397
88714cb8 19398 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
19399 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19400 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19401 inst.instruction |= LOW4 (dm);
19402 inst.instruction |= HI1 (dm) << 5;
037e8744 19403 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
19404 inst.instruction |= x << 17;
19405 inst.instruction |= sizebits << 16;
5f4273c7 19406
88714cb8 19407 neon_dp_fixup (&inst);
5287ad62
JB
19408 }
19409 else
19410 {
037e8744
JB
19411 enum neon_shape rs = neon_select_shape (NS_DR, NS_QR, NS_NULL);
19412 struct neon_type_el et = neon_check_type (2, rs,
477330fc 19413 N_8 | N_16 | N_32 | N_KEY, N_EQK);
b409bdb6
AV
19414 if (rs == NS_QR)
19415 {
64c350f2 19416 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH))
b409bdb6
AV
19417 return;
19418 }
19419 else
19420 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1),
19421 BAD_FPU);
19422
19423 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19424 {
19425 if (inst.operands[1].reg == REG_SP)
19426 as_tsktsk (MVE_BAD_SP);
19427 else if (inst.operands[1].reg == REG_PC)
19428 as_tsktsk (MVE_BAD_PC);
19429 }
19430
5287ad62 19431 /* Duplicate ARM register to lanes of vector. */
88714cb8 19432 NEON_ENCODE (ARMREG, inst);
5287ad62 19433 switch (et.size)
477330fc
RM
19434 {
19435 case 8: inst.instruction |= 0x400000; break;
19436 case 16: inst.instruction |= 0x000020; break;
19437 case 32: inst.instruction |= 0x000000; break;
19438 default: break;
19439 }
5287ad62
JB
19440 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
19441 inst.instruction |= LOW4 (inst.operands[0].reg) << 16;
19442 inst.instruction |= HI1 (inst.operands[0].reg) << 7;
037e8744 19443 inst.instruction |= neon_quad (rs) << 21;
5287ad62 19444 /* The encoding for this instruction is identical for the ARM and Thumb
477330fc 19445 variants, except for the condition field. */
037e8744 19446 do_vfp_cond_or_thumb ();
5287ad62
JB
19447 }
19448}
19449
57785aa2
AV
19450static void
19451do_mve_mov (int toQ)
19452{
19453 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19454 return;
19455 if (inst.cond > COND_ALWAYS)
19456 inst.pred_insn_type = MVE_UNPREDICABLE_INSN;
19457
19458 unsigned Rt = 0, Rt2 = 1, Q0 = 2, Q1 = 3;
19459 if (toQ)
19460 {
19461 Q0 = 0;
19462 Q1 = 1;
19463 Rt = 2;
19464 Rt2 = 3;
19465 }
19466
19467 constraint (inst.operands[Q0].reg != inst.operands[Q1].reg + 2,
19468 _("Index one must be [2,3] and index two must be two less than"
19469 " index one."));
19470 constraint (inst.operands[Rt].reg == inst.operands[Rt2].reg,
19471 _("General purpose registers may not be the same"));
19472 constraint (inst.operands[Rt].reg == REG_SP
19473 || inst.operands[Rt2].reg == REG_SP,
19474 BAD_SP);
19475 constraint (inst.operands[Rt].reg == REG_PC
19476 || inst.operands[Rt2].reg == REG_PC,
19477 BAD_PC);
19478
19479 inst.instruction = 0xec000f00;
19480 inst.instruction |= HI1 (inst.operands[Q1].reg / 32) << 23;
19481 inst.instruction |= !!toQ << 20;
19482 inst.instruction |= inst.operands[Rt2].reg << 16;
19483 inst.instruction |= LOW4 (inst.operands[Q1].reg / 32) << 13;
19484 inst.instruction |= (inst.operands[Q1].reg % 4) << 4;
19485 inst.instruction |= inst.operands[Rt].reg;
19486}
19487
19488static void
19489do_mve_movn (void)
19490{
19491 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19492 return;
19493
19494 if (inst.cond > COND_ALWAYS)
19495 inst.pred_insn_type = INSIDE_VPT_INSN;
19496 else
19497 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
19498
19499 struct neon_type_el et = neon_check_type (2, NS_QQ, N_EQK, N_I16 | N_I32
19500 | N_KEY);
19501
19502 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19503 inst.instruction |= (neon_logbits (et.size) - 1) << 18;
19504 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19505 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19506 inst.instruction |= LOW4 (inst.operands[1].reg);
19507 inst.is_neon = 1;
19508
19509}
19510
5287ad62
JB
19511/* VMOV has particularly many variations. It can be one of:
19512 0. VMOV<c><q> <Qd>, <Qm>
19513 1. VMOV<c><q> <Dd>, <Dm>
19514 (Register operations, which are VORR with Rm = Rn.)
19515 2. VMOV<c><q>.<dt> <Qd>, #<imm>
19516 3. VMOV<c><q>.<dt> <Dd>, #<imm>
19517 (Immediate loads.)
19518 4. VMOV<c><q>.<size> <Dn[x]>, <Rd>
19519 (ARM register to scalar.)
19520 5. VMOV<c><q> <Dm>, <Rd>, <Rn>
19521 (Two ARM registers to vector.)
19522 6. VMOV<c><q>.<dt> <Rd>, <Dn[x]>
19523 (Scalar to ARM register.)
19524 7. VMOV<c><q> <Rd>, <Rn>, <Dm>
19525 (Vector to two ARM registers.)
037e8744
JB
19526 8. VMOV.F32 <Sd>, <Sm>
19527 9. VMOV.F64 <Dd>, <Dm>
19528 (VFP register moves.)
19529 10. VMOV.F32 <Sd>, #imm
19530 11. VMOV.F64 <Dd>, #imm
19531 (VFP float immediate load.)
19532 12. VMOV <Rd>, <Sm>
19533 (VFP single to ARM reg.)
19534 13. VMOV <Sd>, <Rm>
19535 (ARM reg to VFP single.)
19536 14. VMOV <Rd>, <Re>, <Sn>, <Sm>
19537 (Two ARM regs to two VFP singles.)
19538 15. VMOV <Sd>, <Se>, <Rn>, <Rm>
19539 (Two VFP singles to two ARM regs.)
57785aa2
AV
19540 16. VMOV<c> <Rt>, <Rt2>, <Qd[idx]>, <Qd[idx2]>
19541 17. VMOV<c> <Qd[idx]>, <Qd[idx2]>, <Rt>, <Rt2>
19542 18. VMOV<c>.<dt> <Rt>, <Qn[idx]>
19543 19. VMOV<c>.<dt> <Qd[idx]>, <Rt>
5f4273c7 19544
037e8744
JB
19545 These cases can be disambiguated using neon_select_shape, except cases 1/9
19546 and 3/11 which depend on the operand type too.
5f4273c7 19547
5287ad62 19548 All the encoded bits are hardcoded by this function.
5f4273c7 19549
b7fc2769
JB
19550 Cases 4, 6 may be used with VFPv1 and above (only 32-bit transfers!).
19551 Cases 5, 7 may be used with VFPv2 and above.
5f4273c7 19552
5287ad62 19553 FIXME: Some of the checking may be a bit sloppy (in a couple of cases you
5f4273c7 19554 can specify a type where it doesn't make sense to, and is ignored). */
5287ad62
JB
19555
19556static void
19557do_neon_mov (void)
19558{
57785aa2
AV
19559 enum neon_shape rs = neon_select_shape (NS_RRSS, NS_SSRR, NS_RRFF, NS_FFRR,
19560 NS_DRR, NS_RRD, NS_QQ, NS_DD, NS_QI,
19561 NS_DI, NS_SR, NS_RS, NS_FF, NS_FI,
19562 NS_RF, NS_FR, NS_HR, NS_RH, NS_HI,
19563 NS_NULL);
037e8744
JB
19564 struct neon_type_el et;
19565 const char *ldconst = 0;
5287ad62 19566
037e8744 19567 switch (rs)
5287ad62 19568 {
037e8744
JB
19569 case NS_DD: /* case 1/9. */
19570 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
19571 /* It is not an error here if no type is given. */
19572 inst.error = NULL;
19573 if (et.type == NT_float && et.size == 64)
477330fc
RM
19574 {
19575 do_vfp_nsyn_opcode ("fcpyd");
19576 break;
19577 }
037e8744 19578 /* fall through. */
5287ad62 19579
037e8744
JB
19580 case NS_QQ: /* case 0/1. */
19581 {
64c350f2
AV
19582 if (!check_simd_pred_availability (FALSE,
19583 NEON_CHECK_CC | NEON_CHECK_ARCH))
477330fc
RM
19584 return;
19585 /* The architecture manual I have doesn't explicitly state which
19586 value the U bit should have for register->register moves, but
19587 the equivalent VORR instruction has U = 0, so do that. */
19588 inst.instruction = 0x0200110;
19589 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19590 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19591 inst.instruction |= LOW4 (inst.operands[1].reg);
19592 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19593 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
19594 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
19595 inst.instruction |= neon_quad (rs) << 6;
19596
19597 neon_dp_fixup (&inst);
037e8744
JB
19598 }
19599 break;
5f4273c7 19600
037e8744
JB
19601 case NS_DI: /* case 3/11. */
19602 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
19603 inst.error = NULL;
19604 if (et.type == NT_float && et.size == 64)
477330fc
RM
19605 {
19606 /* case 11 (fconstd). */
19607 ldconst = "fconstd";
19608 goto encode_fconstd;
19609 }
037e8744
JB
19610 /* fall through. */
19611
19612 case NS_QI: /* case 2/3. */
64c350f2
AV
19613 if (!check_simd_pred_availability (FALSE,
19614 NEON_CHECK_CC | NEON_CHECK_ARCH))
477330fc 19615 return;
037e8744
JB
19616 inst.instruction = 0x0800010;
19617 neon_move_immediate ();
88714cb8 19618 neon_dp_fixup (&inst);
5287ad62 19619 break;
5f4273c7 19620
037e8744
JB
19621 case NS_SR: /* case 4. */
19622 {
477330fc
RM
19623 unsigned bcdebits = 0;
19624 int logsize;
19625 unsigned dn = NEON_SCALAR_REG (inst.operands[0].reg);
19626 unsigned x = NEON_SCALAR_INDEX (inst.operands[0].reg);
037e8744 19627
05ac0ffb
JB
19628 /* .<size> is optional here, defaulting to .32. */
19629 if (inst.vectype.elems == 0
19630 && inst.operands[0].vectype.type == NT_invtype
19631 && inst.operands[1].vectype.type == NT_invtype)
19632 {
19633 inst.vectype.el[0].type = NT_untyped;
19634 inst.vectype.el[0].size = 32;
19635 inst.vectype.elems = 1;
19636 }
19637
477330fc
RM
19638 et = neon_check_type (2, NS_NULL, N_8 | N_16 | N_32 | N_KEY, N_EQK);
19639 logsize = neon_logbits (et.size);
19640
57785aa2
AV
19641 if (et.size != 32)
19642 {
19643 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
19644 && vfp_or_neon_is_neon (NEON_CHECK_ARCH) == FAIL)
19645 return;
19646 }
19647 else
19648 {
19649 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
19650 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
19651 _(BAD_FPU));
19652 }
19653
19654 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19655 {
19656 if (inst.operands[1].reg == REG_SP)
19657 as_tsktsk (MVE_BAD_SP);
19658 else if (inst.operands[1].reg == REG_PC)
19659 as_tsktsk (MVE_BAD_PC);
19660 }
19661 unsigned size = inst.operands[0].isscalar == 1 ? 64 : 128;
19662
477330fc 19663 constraint (et.type == NT_invtype, _("bad type for scalar"));
57785aa2
AV
19664 constraint (x >= size / et.size, _("scalar index out of range"));
19665
477330fc
RM
19666
19667 switch (et.size)
19668 {
19669 case 8: bcdebits = 0x8; break;
19670 case 16: bcdebits = 0x1; break;
19671 case 32: bcdebits = 0x0; break;
19672 default: ;
19673 }
19674
57785aa2 19675 bcdebits |= (x & ((1 << (3-logsize)) - 1)) << logsize;
477330fc
RM
19676
19677 inst.instruction = 0xe000b10;
19678 do_vfp_cond_or_thumb ();
19679 inst.instruction |= LOW4 (dn) << 16;
19680 inst.instruction |= HI1 (dn) << 7;
19681 inst.instruction |= inst.operands[1].reg << 12;
19682 inst.instruction |= (bcdebits & 3) << 5;
57785aa2
AV
19683 inst.instruction |= ((bcdebits >> 2) & 3) << 21;
19684 inst.instruction |= (x >> (3-logsize)) << 16;
037e8744
JB
19685 }
19686 break;
5f4273c7 19687
037e8744 19688 case NS_DRR: /* case 5 (fmdrr). */
57785aa2
AV
19689 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
19690 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
477330fc 19691 _(BAD_FPU));
b7fc2769 19692
037e8744
JB
19693 inst.instruction = 0xc400b10;
19694 do_vfp_cond_or_thumb ();
19695 inst.instruction |= LOW4 (inst.operands[0].reg);
19696 inst.instruction |= HI1 (inst.operands[0].reg) << 5;
19697 inst.instruction |= inst.operands[1].reg << 12;
19698 inst.instruction |= inst.operands[2].reg << 16;
19699 break;
5f4273c7 19700
037e8744
JB
19701 case NS_RS: /* case 6. */
19702 {
477330fc
RM
19703 unsigned logsize;
19704 unsigned dn = NEON_SCALAR_REG (inst.operands[1].reg);
19705 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg);
19706 unsigned abcdebits = 0;
037e8744 19707
05ac0ffb
JB
19708 /* .<dt> is optional here, defaulting to .32. */
19709 if (inst.vectype.elems == 0
19710 && inst.operands[0].vectype.type == NT_invtype
19711 && inst.operands[1].vectype.type == NT_invtype)
19712 {
19713 inst.vectype.el[0].type = NT_untyped;
19714 inst.vectype.el[0].size = 32;
19715 inst.vectype.elems = 1;
19716 }
19717
91d6fa6a
NC
19718 et = neon_check_type (2, NS_NULL,
19719 N_EQK, N_S8 | N_S16 | N_U8 | N_U16 | N_32 | N_KEY);
477330fc
RM
19720 logsize = neon_logbits (et.size);
19721
57785aa2
AV
19722 if (et.size != 32)
19723 {
19724 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
19725 && vfp_or_neon_is_neon (NEON_CHECK_CC
19726 | NEON_CHECK_ARCH) == FAIL)
19727 return;
19728 }
19729 else
19730 {
19731 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
19732 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
19733 _(BAD_FPU));
19734 }
19735
19736 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19737 {
19738 if (inst.operands[0].reg == REG_SP)
19739 as_tsktsk (MVE_BAD_SP);
19740 else if (inst.operands[0].reg == REG_PC)
19741 as_tsktsk (MVE_BAD_PC);
19742 }
19743
19744 unsigned size = inst.operands[1].isscalar == 1 ? 64 : 128;
19745
477330fc 19746 constraint (et.type == NT_invtype, _("bad type for scalar"));
57785aa2 19747 constraint (x >= size / et.size, _("scalar index out of range"));
477330fc
RM
19748
19749 switch (et.size)
19750 {
19751 case 8: abcdebits = (et.type == NT_signed) ? 0x08 : 0x18; break;
19752 case 16: abcdebits = (et.type == NT_signed) ? 0x01 : 0x11; break;
19753 case 32: abcdebits = 0x00; break;
19754 default: ;
19755 }
19756
57785aa2 19757 abcdebits |= (x & ((1 << (3-logsize)) - 1)) << logsize;
477330fc
RM
19758 inst.instruction = 0xe100b10;
19759 do_vfp_cond_or_thumb ();
19760 inst.instruction |= LOW4 (dn) << 16;
19761 inst.instruction |= HI1 (dn) << 7;
19762 inst.instruction |= inst.operands[0].reg << 12;
19763 inst.instruction |= (abcdebits & 3) << 5;
19764 inst.instruction |= (abcdebits >> 2) << 21;
57785aa2 19765 inst.instruction |= (x >> (3-logsize)) << 16;
037e8744
JB
19766 }
19767 break;
5f4273c7 19768
037e8744 19769 case NS_RRD: /* case 7 (fmrrd). */
57785aa2
AV
19770 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
19771 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
477330fc 19772 _(BAD_FPU));
037e8744
JB
19773
19774 inst.instruction = 0xc500b10;
19775 do_vfp_cond_or_thumb ();
19776 inst.instruction |= inst.operands[0].reg << 12;
19777 inst.instruction |= inst.operands[1].reg << 16;
19778 inst.instruction |= LOW4 (inst.operands[2].reg);
19779 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
19780 break;
5f4273c7 19781
037e8744
JB
19782 case NS_FF: /* case 8 (fcpys). */
19783 do_vfp_nsyn_opcode ("fcpys");
19784 break;
5f4273c7 19785
9db2f6b4 19786 case NS_HI:
037e8744
JB
19787 case NS_FI: /* case 10 (fconsts). */
19788 ldconst = "fconsts";
4ef4710f 19789 encode_fconstd:
58ed5c38
TC
19790 if (!inst.operands[1].immisfloat)
19791 {
4ef4710f 19792 unsigned new_imm;
58ed5c38 19793 /* Immediate has to fit in 8 bits so float is enough. */
4ef4710f
NC
19794 float imm = (float) inst.operands[1].imm;
19795 memcpy (&new_imm, &imm, sizeof (float));
19796 /* But the assembly may have been written to provide an integer
19797 bit pattern that equates to a float, so check that the
19798 conversion has worked. */
19799 if (is_quarter_float (new_imm))
19800 {
19801 if (is_quarter_float (inst.operands[1].imm))
19802 as_warn (_("immediate constant is valid both as a bit-pattern and a floating point value (using the fp value)"));
19803
19804 inst.operands[1].imm = new_imm;
19805 inst.operands[1].immisfloat = 1;
19806 }
58ed5c38
TC
19807 }
19808
037e8744 19809 if (is_quarter_float (inst.operands[1].imm))
477330fc
RM
19810 {
19811 inst.operands[1].imm = neon_qfloat_bits (inst.operands[1].imm);
19812 do_vfp_nsyn_opcode (ldconst);
9db2f6b4
RL
19813
19814 /* ARMv8.2 fp16 vmov.f16 instruction. */
19815 if (rs == NS_HI)
19816 do_scalar_fp16_v82_encode ();
477330fc 19817 }
5287ad62 19818 else
477330fc 19819 first_error (_("immediate out of range"));
037e8744 19820 break;
5f4273c7 19821
9db2f6b4 19822 case NS_RH:
037e8744
JB
19823 case NS_RF: /* case 12 (fmrs). */
19824 do_vfp_nsyn_opcode ("fmrs");
9db2f6b4
RL
19825 /* ARMv8.2 fp16 vmov.f16 instruction. */
19826 if (rs == NS_RH)
19827 do_scalar_fp16_v82_encode ();
037e8744 19828 break;
5f4273c7 19829
9db2f6b4 19830 case NS_HR:
037e8744
JB
19831 case NS_FR: /* case 13 (fmsr). */
19832 do_vfp_nsyn_opcode ("fmsr");
9db2f6b4
RL
19833 /* ARMv8.2 fp16 vmov.f16 instruction. */
19834 if (rs == NS_HR)
19835 do_scalar_fp16_v82_encode ();
037e8744 19836 break;
5f4273c7 19837
57785aa2
AV
19838 case NS_RRSS:
19839 do_mve_mov (0);
19840 break;
19841 case NS_SSRR:
19842 do_mve_mov (1);
19843 break;
19844
037e8744
JB
19845 /* The encoders for the fmrrs and fmsrr instructions expect three operands
19846 (one of which is a list), but we have parsed four. Do some fiddling to
19847 make the operands what do_vfp_reg2_from_sp2 and do_vfp_sp2_from_reg2
19848 expect. */
19849 case NS_RRFF: /* case 14 (fmrrs). */
57785aa2
AV
19850 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
19851 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
19852 _(BAD_FPU));
037e8744 19853 constraint (inst.operands[3].reg != inst.operands[2].reg + 1,
477330fc 19854 _("VFP registers must be adjacent"));
037e8744
JB
19855 inst.operands[2].imm = 2;
19856 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
19857 do_vfp_nsyn_opcode ("fmrrs");
19858 break;
5f4273c7 19859
037e8744 19860 case NS_FFRR: /* case 15 (fmsrr). */
57785aa2
AV
19861 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
19862 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
19863 _(BAD_FPU));
037e8744 19864 constraint (inst.operands[1].reg != inst.operands[0].reg + 1,
477330fc 19865 _("VFP registers must be adjacent"));
037e8744
JB
19866 inst.operands[1] = inst.operands[2];
19867 inst.operands[2] = inst.operands[3];
19868 inst.operands[0].imm = 2;
19869 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
19870 do_vfp_nsyn_opcode ("fmsrr");
5287ad62 19871 break;
5f4273c7 19872
4c261dff
NC
19873 case NS_NULL:
19874 /* neon_select_shape has determined that the instruction
19875 shape is wrong and has already set the error message. */
19876 break;
19877
5287ad62
JB
19878 default:
19879 abort ();
19880 }
19881}
19882
57785aa2
AV
19883static void
19884do_mve_movl (void)
19885{
19886 if (!(inst.operands[0].present && inst.operands[0].isquad
19887 && inst.operands[1].present && inst.operands[1].isquad
19888 && !inst.operands[2].present))
19889 {
19890 inst.instruction = 0;
19891 inst.cond = 0xb;
19892 if (thumb_mode)
19893 set_pred_insn_type (INSIDE_IT_INSN);
19894 do_neon_mov ();
19895 return;
19896 }
19897
19898 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19899 return;
19900
19901 if (inst.cond != COND_ALWAYS)
19902 inst.pred_insn_type = INSIDE_VPT_INSN;
19903
19904 struct neon_type_el et = neon_check_type (2, NS_QQ, N_EQK, N_S8 | N_U8
19905 | N_S16 | N_U16 | N_KEY);
19906
19907 inst.instruction |= (et.type == NT_unsigned) << 28;
19908 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19909 inst.instruction |= (neon_logbits (et.size) + 1) << 19;
19910 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19911 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19912 inst.instruction |= LOW4 (inst.operands[1].reg);
19913 inst.is_neon = 1;
19914}
19915
5287ad62
JB
19916static void
19917do_neon_rshift_round_imm (void)
19918{
64c350f2 19919 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
19920 return;
19921
19922 enum neon_shape rs;
19923 struct neon_type_el et;
19924
19925 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19926 {
19927 rs = neon_select_shape (NS_QQI, NS_NULL);
19928 et = neon_check_type (2, rs, N_EQK, N_SU_MVE | N_KEY);
19929 }
19930 else
19931 {
19932 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
19933 et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
19934 }
5287ad62
JB
19935 int imm = inst.operands[2].imm;
19936
19937 /* imm == 0 case is encoded as VMOV for V{R}SHR. */
19938 if (imm == 0)
19939 {
19940 inst.operands[2].present = 0;
19941 do_neon_mov ();
19942 return;
19943 }
19944
19945 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 19946 _("immediate out of range for shift"));
037e8744 19947 neon_imm_shift (TRUE, et.type == NT_unsigned, neon_quad (rs), et,
477330fc 19948 et.size - imm);
5287ad62
JB
19949}
19950
9db2f6b4
RL
19951static void
19952do_neon_movhf (void)
19953{
19954 enum neon_shape rs = neon_select_shape (NS_HH, NS_NULL);
19955 constraint (rs != NS_HH, _("invalid suffix"));
19956
7bdf778b
ASDV
19957 if (inst.cond != COND_ALWAYS)
19958 {
19959 if (thumb_mode)
19960 {
19961 as_warn (_("ARMv8.2 scalar fp16 instruction cannot be conditional,"
19962 " the behaviour is UNPREDICTABLE"));
19963 }
19964 else
19965 {
19966 inst.error = BAD_COND;
19967 return;
19968 }
19969 }
19970
9db2f6b4
RL
19971 do_vfp_sp_monadic ();
19972
19973 inst.is_neon = 1;
19974 inst.instruction |= 0xf0000000;
19975}
19976
5287ad62
JB
19977static void
19978do_neon_movl (void)
19979{
19980 struct neon_type_el et = neon_check_type (2, NS_QD,
19981 N_EQK | N_DBL, N_SU_32 | N_KEY);
19982 unsigned sizebits = et.size >> 3;
19983 inst.instruction |= sizebits << 19;
19984 neon_two_same (0, et.type == NT_unsigned, -1);
19985}
19986
19987static void
19988do_neon_trn (void)
19989{
037e8744 19990 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
19991 struct neon_type_el et = neon_check_type (2, rs,
19992 N_EQK, N_8 | N_16 | N_32 | N_KEY);
88714cb8 19993 NEON_ENCODE (INTEGER, inst);
037e8744 19994 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19995}
19996
19997static void
19998do_neon_zip_uzp (void)
19999{
037e8744 20000 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20001 struct neon_type_el et = neon_check_type (2, rs,
20002 N_EQK, N_8 | N_16 | N_32 | N_KEY);
20003 if (rs == NS_DD && et.size == 32)
20004 {
20005 /* Special case: encode as VTRN.32 <Dd>, <Dm>. */
20006 inst.instruction = N_MNEM_vtrn;
20007 do_neon_trn ();
20008 return;
20009 }
037e8744 20010 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20011}
20012
20013static void
20014do_neon_sat_abs_neg (void)
20015{
64c350f2 20016 if (!check_simd_pred_availability (FALSE, NEON_CHECK_CC | NEON_CHECK_ARCH))
1a186d29
AV
20017 return;
20018
20019 enum neon_shape rs;
20020 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20021 rs = neon_select_shape (NS_QQ, NS_NULL);
20022 else
20023 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20024 struct neon_type_el et = neon_check_type (2, rs,
20025 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 20026 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20027}
20028
20029static void
20030do_neon_pair_long (void)
20031{
037e8744 20032 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20033 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_32 | N_KEY);
20034 /* Unsigned is encoded in OP field (bit 7) for these instruction. */
20035 inst.instruction |= (et.type == NT_unsigned) << 7;
037e8744 20036 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20037}
20038
20039static void
20040do_neon_recip_est (void)
20041{
037e8744 20042 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62 20043 struct neon_type_el et = neon_check_type (2, rs,
cc933301 20044 N_EQK | N_FLT, N_F_16_32 | N_U32 | N_KEY);
5287ad62 20045 inst.instruction |= (et.type == NT_float) << 8;
037e8744 20046 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20047}
20048
20049static void
20050do_neon_cls (void)
20051{
64c350f2 20052 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
f30ee27c
AV
20053 return;
20054
20055 enum neon_shape rs;
20056 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20057 rs = neon_select_shape (NS_QQ, NS_NULL);
20058 else
20059 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
20060
5287ad62
JB
20061 struct neon_type_el et = neon_check_type (2, rs,
20062 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 20063 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20064}
20065
20066static void
20067do_neon_clz (void)
20068{
64c350f2 20069 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
f30ee27c
AV
20070 return;
20071
20072 enum neon_shape rs;
20073 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20074 rs = neon_select_shape (NS_QQ, NS_NULL);
20075 else
20076 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
20077
5287ad62
JB
20078 struct neon_type_el et = neon_check_type (2, rs,
20079 N_EQK, N_I8 | N_I16 | N_I32 | N_KEY);
037e8744 20080 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20081}
20082
20083static void
20084do_neon_cnt (void)
20085{
037e8744 20086 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20087 struct neon_type_el et = neon_check_type (2, rs,
20088 N_EQK | N_INT, N_8 | N_KEY);
037e8744 20089 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20090}
20091
20092static void
20093do_neon_swp (void)
20094{
037e8744
JB
20095 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
20096 neon_two_same (neon_quad (rs), 1, -1);
5287ad62
JB
20097}
20098
20099static void
20100do_neon_tbl_tbx (void)
20101{
20102 unsigned listlenbits;
dcbf9037 20103 neon_check_type (3, NS_DLD, N_EQK, N_EQK, N_8 | N_KEY);
5f4273c7 20104
5287ad62
JB
20105 if (inst.operands[1].imm < 1 || inst.operands[1].imm > 4)
20106 {
dcbf9037 20107 first_error (_("bad list length for table lookup"));
5287ad62
JB
20108 return;
20109 }
5f4273c7 20110
5287ad62
JB
20111 listlenbits = inst.operands[1].imm - 1;
20112 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20113 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20114 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
20115 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
20116 inst.instruction |= LOW4 (inst.operands[2].reg);
20117 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
20118 inst.instruction |= listlenbits << 8;
5f4273c7 20119
88714cb8 20120 neon_dp_fixup (&inst);
5287ad62
JB
20121}
20122
20123static void
20124do_neon_ldm_stm (void)
20125{
20126 /* P, U and L bits are part of bitmask. */
20127 int is_dbmode = (inst.instruction & (1 << 24)) != 0;
20128 unsigned offsetbits = inst.operands[1].imm * 2;
20129
037e8744
JB
20130 if (inst.operands[1].issingle)
20131 {
20132 do_vfp_nsyn_ldm_stm (is_dbmode);
20133 return;
20134 }
20135
5287ad62 20136 constraint (is_dbmode && !inst.operands[0].writeback,
477330fc 20137 _("writeback (!) must be used for VLDMDB and VSTMDB"));
5287ad62
JB
20138
20139 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
477330fc
RM
20140 _("register list must contain at least 1 and at most 16 "
20141 "registers"));
5287ad62
JB
20142
20143 inst.instruction |= inst.operands[0].reg << 16;
20144 inst.instruction |= inst.operands[0].writeback << 21;
20145 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
20146 inst.instruction |= HI1 (inst.operands[1].reg) << 22;
20147
20148 inst.instruction |= offsetbits;
5f4273c7 20149
037e8744 20150 do_vfp_cond_or_thumb ();
5287ad62
JB
20151}
20152
20153static void
20154do_neon_ldr_str (void)
20155{
5287ad62 20156 int is_ldr = (inst.instruction & (1 << 20)) != 0;
5f4273c7 20157
6844b2c2
MGD
20158 /* Use of PC in vstr in ARM mode is deprecated in ARMv7.
20159 And is UNPREDICTABLE in thumb mode. */
fa94de6b 20160 if (!is_ldr
6844b2c2 20161 && inst.operands[1].reg == REG_PC
ba86b375 20162 && (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7) || thumb_mode))
6844b2c2 20163 {
94dcf8bf 20164 if (thumb_mode)
6844b2c2 20165 inst.error = _("Use of PC here is UNPREDICTABLE");
94dcf8bf 20166 else if (warn_on_deprecated)
5c3696f8 20167 as_tsktsk (_("Use of PC here is deprecated"));
6844b2c2
MGD
20168 }
20169
037e8744
JB
20170 if (inst.operands[0].issingle)
20171 {
cd2f129f 20172 if (is_ldr)
477330fc 20173 do_vfp_nsyn_opcode ("flds");
cd2f129f 20174 else
477330fc 20175 do_vfp_nsyn_opcode ("fsts");
9db2f6b4
RL
20176
20177 /* ARMv8.2 vldr.16/vstr.16 instruction. */
20178 if (inst.vectype.el[0].size == 16)
20179 do_scalar_fp16_v82_encode ();
5287ad62
JB
20180 }
20181 else
5287ad62 20182 {
cd2f129f 20183 if (is_ldr)
477330fc 20184 do_vfp_nsyn_opcode ("fldd");
5287ad62 20185 else
477330fc 20186 do_vfp_nsyn_opcode ("fstd");
5287ad62 20187 }
5287ad62
JB
20188}
20189
32c36c3c
AV
20190static void
20191do_t_vldr_vstr_sysreg (void)
20192{
20193 int fp_vldr_bitno = 20, sysreg_vldr_bitno = 20;
20194 bfd_boolean is_vldr = ((inst.instruction & (1 << fp_vldr_bitno)) != 0);
20195
20196 /* Use of PC is UNPREDICTABLE. */
20197 if (inst.operands[1].reg == REG_PC)
20198 inst.error = _("Use of PC here is UNPREDICTABLE");
20199
20200 if (inst.operands[1].immisreg)
20201 inst.error = _("instruction does not accept register index");
20202
20203 if (!inst.operands[1].isreg)
20204 inst.error = _("instruction does not accept PC-relative addressing");
20205
20206 if (abs (inst.operands[1].imm) >= (1 << 7))
20207 inst.error = _("immediate value out of range");
20208
20209 inst.instruction = 0xec000f80;
20210 if (is_vldr)
20211 inst.instruction |= 1 << sysreg_vldr_bitno;
20212 encode_arm_cp_address (1, TRUE, FALSE, BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM);
20213 inst.instruction |= (inst.operands[0].imm & 0x7) << 13;
20214 inst.instruction |= (inst.operands[0].imm & 0x8) << 19;
20215}
20216
20217static void
20218do_vldr_vstr (void)
20219{
20220 bfd_boolean sysreg_op = !inst.operands[0].isreg;
20221
20222 /* VLDR/VSTR (System Register). */
20223 if (sysreg_op)
20224 {
20225 if (!mark_feature_used (&arm_ext_v8_1m_main))
20226 as_bad (_("Instruction not permitted on this architecture"));
20227
20228 do_t_vldr_vstr_sysreg ();
20229 }
20230 /* VLDR/VSTR. */
20231 else
20232 {
20233 if (!mark_feature_used (&fpu_vfp_ext_v1xd))
20234 as_bad (_("Instruction not permitted on this architecture"));
20235 do_neon_ldr_str ();
20236 }
20237}
20238
5287ad62
JB
20239/* "interleave" version also handles non-interleaving register VLD1/VST1
20240 instructions. */
20241
20242static void
20243do_neon_ld_st_interleave (void)
20244{
037e8744 20245 struct neon_type_el et = neon_check_type (1, NS_NULL,
477330fc 20246 N_8 | N_16 | N_32 | N_64);
5287ad62
JB
20247 unsigned alignbits = 0;
20248 unsigned idx;
20249 /* The bits in this table go:
20250 0: register stride of one (0) or two (1)
20251 1,2: register list length, minus one (1, 2, 3, 4).
20252 3,4: <n> in instruction type, minus one (VLD<n> / VST<n>).
20253 We use -1 for invalid entries. */
20254 const int typetable[] =
20255 {
20256 0x7, -1, 0xa, -1, 0x6, -1, 0x2, -1, /* VLD1 / VST1. */
20257 -1, -1, 0x8, 0x9, -1, -1, 0x3, -1, /* VLD2 / VST2. */
20258 -1, -1, -1, -1, 0x4, 0x5, -1, -1, /* VLD3 / VST3. */
20259 -1, -1, -1, -1, -1, -1, 0x0, 0x1 /* VLD4 / VST4. */
20260 };
20261 int typebits;
20262
dcbf9037
JB
20263 if (et.type == NT_invtype)
20264 return;
20265
5287ad62
JB
20266 if (inst.operands[1].immisalign)
20267 switch (inst.operands[1].imm >> 8)
20268 {
20269 case 64: alignbits = 1; break;
20270 case 128:
477330fc 20271 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2
e23c0ad8 20272 && NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
477330fc
RM
20273 goto bad_alignment;
20274 alignbits = 2;
20275 break;
5287ad62 20276 case 256:
477330fc
RM
20277 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
20278 goto bad_alignment;
20279 alignbits = 3;
20280 break;
5287ad62
JB
20281 default:
20282 bad_alignment:
477330fc
RM
20283 first_error (_("bad alignment"));
20284 return;
5287ad62
JB
20285 }
20286
20287 inst.instruction |= alignbits << 4;
20288 inst.instruction |= neon_logbits (et.size) << 6;
20289
20290 /* Bits [4:6] of the immediate in a list specifier encode register stride
20291 (minus 1) in bit 4, and list length in bits [5:6]. We put the <n> of
20292 VLD<n>/VST<n> in bits [9:8] of the initial bitmask. Suck it out here, look
20293 up the right value for "type" in a table based on this value and the given
20294 list style, then stick it back. */
20295 idx = ((inst.operands[0].imm >> 4) & 7)
477330fc 20296 | (((inst.instruction >> 8) & 3) << 3);
5287ad62
JB
20297
20298 typebits = typetable[idx];
5f4273c7 20299
5287ad62 20300 constraint (typebits == -1, _("bad list type for instruction"));
1d50d57c 20301 constraint (((inst.instruction >> 8) & 3) && et.size == 64,
35c228db 20302 BAD_EL_TYPE);
5287ad62
JB
20303
20304 inst.instruction &= ~0xf00;
20305 inst.instruction |= typebits << 8;
20306}
20307
20308/* Check alignment is valid for do_neon_ld_st_lane and do_neon_ld_dup.
20309 *DO_ALIGN is set to 1 if the relevant alignment bit should be set, 0
20310 otherwise. The variable arguments are a list of pairs of legal (size, align)
20311 values, terminated with -1. */
20312
20313static int
aa8a0863 20314neon_alignment_bit (int size, int align, int *do_alignment, ...)
5287ad62
JB
20315{
20316 va_list ap;
20317 int result = FAIL, thissize, thisalign;
5f4273c7 20318
5287ad62
JB
20319 if (!inst.operands[1].immisalign)
20320 {
aa8a0863 20321 *do_alignment = 0;
5287ad62
JB
20322 return SUCCESS;
20323 }
5f4273c7 20324
aa8a0863 20325 va_start (ap, do_alignment);
5287ad62
JB
20326
20327 do
20328 {
20329 thissize = va_arg (ap, int);
20330 if (thissize == -1)
477330fc 20331 break;
5287ad62
JB
20332 thisalign = va_arg (ap, int);
20333
20334 if (size == thissize && align == thisalign)
477330fc 20335 result = SUCCESS;
5287ad62
JB
20336 }
20337 while (result != SUCCESS);
20338
20339 va_end (ap);
20340
20341 if (result == SUCCESS)
aa8a0863 20342 *do_alignment = 1;
5287ad62 20343 else
dcbf9037 20344 first_error (_("unsupported alignment for instruction"));
5f4273c7 20345
5287ad62
JB
20346 return result;
20347}
20348
20349static void
20350do_neon_ld_st_lane (void)
20351{
037e8744 20352 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 20353 int align_good, do_alignment = 0;
5287ad62
JB
20354 int logsize = neon_logbits (et.size);
20355 int align = inst.operands[1].imm >> 8;
20356 int n = (inst.instruction >> 8) & 3;
20357 int max_el = 64 / et.size;
5f4273c7 20358
dcbf9037
JB
20359 if (et.type == NT_invtype)
20360 return;
5f4273c7 20361
5287ad62 20362 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != n + 1,
477330fc 20363 _("bad list length"));
5287ad62 20364 constraint (NEON_LANE (inst.operands[0].imm) >= max_el,
477330fc 20365 _("scalar index out of range"));
5287ad62 20366 constraint (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2
477330fc
RM
20367 && et.size == 8,
20368 _("stride of 2 unavailable when element size is 8"));
5f4273c7 20369
5287ad62
JB
20370 switch (n)
20371 {
20372 case 0: /* VLD1 / VST1. */
aa8a0863 20373 align_good = neon_alignment_bit (et.size, align, &do_alignment, 16, 16,
477330fc 20374 32, 32, -1);
5287ad62 20375 if (align_good == FAIL)
477330fc 20376 return;
aa8a0863 20377 if (do_alignment)
477330fc
RM
20378 {
20379 unsigned alignbits = 0;
20380 switch (et.size)
20381 {
20382 case 16: alignbits = 0x1; break;
20383 case 32: alignbits = 0x3; break;
20384 default: ;
20385 }
20386 inst.instruction |= alignbits << 4;
20387 }
5287ad62
JB
20388 break;
20389
20390 case 1: /* VLD2 / VST2. */
aa8a0863
TS
20391 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 16,
20392 16, 32, 32, 64, -1);
5287ad62 20393 if (align_good == FAIL)
477330fc 20394 return;
aa8a0863 20395 if (do_alignment)
477330fc 20396 inst.instruction |= 1 << 4;
5287ad62
JB
20397 break;
20398
20399 case 2: /* VLD3 / VST3. */
20400 constraint (inst.operands[1].immisalign,
477330fc 20401 _("can't use alignment with this instruction"));
5287ad62
JB
20402 break;
20403
20404 case 3: /* VLD4 / VST4. */
aa8a0863 20405 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc 20406 16, 64, 32, 64, 32, 128, -1);
5287ad62 20407 if (align_good == FAIL)
477330fc 20408 return;
aa8a0863 20409 if (do_alignment)
477330fc
RM
20410 {
20411 unsigned alignbits = 0;
20412 switch (et.size)
20413 {
20414 case 8: alignbits = 0x1; break;
20415 case 16: alignbits = 0x1; break;
20416 case 32: alignbits = (align == 64) ? 0x1 : 0x2; break;
20417 default: ;
20418 }
20419 inst.instruction |= alignbits << 4;
20420 }
5287ad62
JB
20421 break;
20422
20423 default: ;
20424 }
20425
20426 /* Reg stride of 2 is encoded in bit 5 when size==16, bit 6 when size==32. */
20427 if (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2)
20428 inst.instruction |= 1 << (4 + logsize);
5f4273c7 20429
5287ad62
JB
20430 inst.instruction |= NEON_LANE (inst.operands[0].imm) << (logsize + 5);
20431 inst.instruction |= logsize << 10;
20432}
20433
20434/* Encode single n-element structure to all lanes VLD<n> instructions. */
20435
20436static void
20437do_neon_ld_dup (void)
20438{
037e8744 20439 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 20440 int align_good, do_alignment = 0;
5287ad62 20441
dcbf9037
JB
20442 if (et.type == NT_invtype)
20443 return;
20444
5287ad62
JB
20445 switch ((inst.instruction >> 8) & 3)
20446 {
20447 case 0: /* VLD1. */
9c2799c2 20448 gas_assert (NEON_REG_STRIDE (inst.operands[0].imm) != 2);
5287ad62 20449 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863 20450 &do_alignment, 16, 16, 32, 32, -1);
5287ad62 20451 if (align_good == FAIL)
477330fc 20452 return;
5287ad62 20453 switch (NEON_REGLIST_LENGTH (inst.operands[0].imm))
477330fc
RM
20454 {
20455 case 1: break;
20456 case 2: inst.instruction |= 1 << 5; break;
20457 default: first_error (_("bad list length")); return;
20458 }
5287ad62
JB
20459 inst.instruction |= neon_logbits (et.size) << 6;
20460 break;
20461
20462 case 1: /* VLD2. */
20463 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863
TS
20464 &do_alignment, 8, 16, 16, 32, 32, 64,
20465 -1);
5287ad62 20466 if (align_good == FAIL)
477330fc 20467 return;
5287ad62 20468 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2,
477330fc 20469 _("bad list length"));
5287ad62 20470 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 20471 inst.instruction |= 1 << 5;
5287ad62
JB
20472 inst.instruction |= neon_logbits (et.size) << 6;
20473 break;
20474
20475 case 2: /* VLD3. */
20476 constraint (inst.operands[1].immisalign,
477330fc 20477 _("can't use alignment with this instruction"));
5287ad62 20478 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 3,
477330fc 20479 _("bad list length"));
5287ad62 20480 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 20481 inst.instruction |= 1 << 5;
5287ad62
JB
20482 inst.instruction |= neon_logbits (et.size) << 6;
20483 break;
20484
20485 case 3: /* VLD4. */
20486 {
477330fc 20487 int align = inst.operands[1].imm >> 8;
aa8a0863 20488 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc
RM
20489 16, 64, 32, 64, 32, 128, -1);
20490 if (align_good == FAIL)
20491 return;
20492 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4,
20493 _("bad list length"));
20494 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
20495 inst.instruction |= 1 << 5;
20496 if (et.size == 32 && align == 128)
20497 inst.instruction |= 0x3 << 6;
20498 else
20499 inst.instruction |= neon_logbits (et.size) << 6;
5287ad62
JB
20500 }
20501 break;
20502
20503 default: ;
20504 }
20505
aa8a0863 20506 inst.instruction |= do_alignment << 4;
5287ad62
JB
20507}
20508
20509/* Disambiguate VLD<n> and VST<n> instructions, and fill in common bits (those
20510 apart from bits [11:4]. */
20511
20512static void
20513do_neon_ldx_stx (void)
20514{
b1a769ed
DG
20515 if (inst.operands[1].isreg)
20516 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
20517
5287ad62
JB
20518 switch (NEON_LANE (inst.operands[0].imm))
20519 {
20520 case NEON_INTERLEAVE_LANES:
88714cb8 20521 NEON_ENCODE (INTERLV, inst);
5287ad62
JB
20522 do_neon_ld_st_interleave ();
20523 break;
5f4273c7 20524
5287ad62 20525 case NEON_ALL_LANES:
88714cb8 20526 NEON_ENCODE (DUP, inst);
2d51fb74
JB
20527 if (inst.instruction == N_INV)
20528 {
20529 first_error ("only loads support such operands");
20530 break;
20531 }
5287ad62
JB
20532 do_neon_ld_dup ();
20533 break;
5f4273c7 20534
5287ad62 20535 default:
88714cb8 20536 NEON_ENCODE (LANE, inst);
5287ad62
JB
20537 do_neon_ld_st_lane ();
20538 }
20539
20540 /* L bit comes from bit mask. */
20541 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20542 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20543 inst.instruction |= inst.operands[1].reg << 16;
5f4273c7 20544
5287ad62
JB
20545 if (inst.operands[1].postind)
20546 {
20547 int postreg = inst.operands[1].imm & 0xf;
20548 constraint (!inst.operands[1].immisreg,
477330fc 20549 _("post-index must be a register"));
5287ad62 20550 constraint (postreg == 0xd || postreg == 0xf,
477330fc 20551 _("bad register for post-index"));
5287ad62
JB
20552 inst.instruction |= postreg;
20553 }
4f2374c7 20554 else
5287ad62 20555 {
4f2374c7 20556 constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
e2b0ab59
AV
20557 constraint (inst.relocs[0].exp.X_op != O_constant
20558 || inst.relocs[0].exp.X_add_number != 0,
4f2374c7
WN
20559 BAD_ADDR_MODE);
20560
20561 if (inst.operands[1].writeback)
20562 {
20563 inst.instruction |= 0xd;
20564 }
20565 else
20566 inst.instruction |= 0xf;
5287ad62 20567 }
5f4273c7 20568
5287ad62
JB
20569 if (thumb_mode)
20570 inst.instruction |= 0xf9000000;
20571 else
20572 inst.instruction |= 0xf4000000;
20573}
33399f07
MGD
20574
20575/* FP v8. */
20576static void
20577do_vfp_nsyn_fpv8 (enum neon_shape rs)
20578{
a715796b
TG
20579 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
20580 D register operands. */
20581 if (neon_shape_class[rs] == SC_DOUBLE)
20582 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
20583 _(BAD_FPU));
20584
33399f07
MGD
20585 NEON_ENCODE (FPV8, inst);
20586
9db2f6b4
RL
20587 if (rs == NS_FFF || rs == NS_HHH)
20588 {
20589 do_vfp_sp_dyadic ();
20590
20591 /* ARMv8.2 fp16 instruction. */
20592 if (rs == NS_HHH)
20593 do_scalar_fp16_v82_encode ();
20594 }
33399f07
MGD
20595 else
20596 do_vfp_dp_rd_rn_rm ();
20597
20598 if (rs == NS_DDD)
20599 inst.instruction |= 0x100;
20600
20601 inst.instruction |= 0xf0000000;
20602}
20603
20604static void
20605do_vsel (void)
20606{
5ee91343 20607 set_pred_insn_type (OUTSIDE_PRED_INSN);
33399f07
MGD
20608
20609 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) != SUCCESS)
20610 first_error (_("invalid instruction shape"));
20611}
20612
73924fbc
MGD
20613static void
20614do_vmaxnm (void)
20615{
935295b5
AV
20616 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20617 set_pred_insn_type (OUTSIDE_PRED_INSN);
73924fbc
MGD
20618
20619 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) == SUCCESS)
20620 return;
20621
64c350f2 20622 if (!check_simd_pred_availability (TRUE, NEON_CHECK_CC | NEON_CHECK_ARCH8))
73924fbc
MGD
20623 return;
20624
cc933301 20625 neon_dyadic_misc (NT_untyped, N_F_16_32, 0);
73924fbc
MGD
20626}
20627
30bdf752
MGD
20628static void
20629do_vrint_1 (enum neon_cvt_mode mode)
20630{
9db2f6b4 20631 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_QQ, NS_NULL);
30bdf752
MGD
20632 struct neon_type_el et;
20633
20634 if (rs == NS_NULL)
20635 return;
20636
a715796b
TG
20637 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
20638 D register operands. */
20639 if (neon_shape_class[rs] == SC_DOUBLE)
20640 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
20641 _(BAD_FPU));
20642
9db2f6b4
RL
20643 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY
20644 | N_VFP);
30bdf752
MGD
20645 if (et.type != NT_invtype)
20646 {
20647 /* VFP encodings. */
20648 if (mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
20649 || mode == neon_cvt_mode_p || mode == neon_cvt_mode_m)
5ee91343 20650 set_pred_insn_type (OUTSIDE_PRED_INSN);
30bdf752
MGD
20651
20652 NEON_ENCODE (FPV8, inst);
9db2f6b4 20653 if (rs == NS_FF || rs == NS_HH)
30bdf752
MGD
20654 do_vfp_sp_monadic ();
20655 else
20656 do_vfp_dp_rd_rm ();
20657
20658 switch (mode)
20659 {
20660 case neon_cvt_mode_r: inst.instruction |= 0x00000000; break;
20661 case neon_cvt_mode_z: inst.instruction |= 0x00000080; break;
20662 case neon_cvt_mode_x: inst.instruction |= 0x00010000; break;
20663 case neon_cvt_mode_a: inst.instruction |= 0xf0000000; break;
20664 case neon_cvt_mode_n: inst.instruction |= 0xf0010000; break;
20665 case neon_cvt_mode_p: inst.instruction |= 0xf0020000; break;
20666 case neon_cvt_mode_m: inst.instruction |= 0xf0030000; break;
20667 default: abort ();
20668 }
20669
20670 inst.instruction |= (rs == NS_DD) << 8;
20671 do_vfp_cond_or_thumb ();
9db2f6b4
RL
20672
20673 /* ARMv8.2 fp16 vrint instruction. */
20674 if (rs == NS_HH)
20675 do_scalar_fp16_v82_encode ();
30bdf752
MGD
20676 }
20677 else
20678 {
20679 /* Neon encodings (or something broken...). */
20680 inst.error = NULL;
cc933301 20681 et = neon_check_type (2, rs, N_EQK, N_F_16_32 | N_KEY);
30bdf752
MGD
20682
20683 if (et.type == NT_invtype)
20684 return;
20685
64c350f2
AV
20686 if (!check_simd_pred_availability (TRUE,
20687 NEON_CHECK_CC | NEON_CHECK_ARCH8))
30bdf752
MGD
20688 return;
20689
a710b305
AV
20690 NEON_ENCODE (FLOAT, inst);
20691
30bdf752
MGD
20692 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20693 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20694 inst.instruction |= LOW4 (inst.operands[1].reg);
20695 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
20696 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
20697 /* Mask off the original size bits and reencode them. */
20698 inst.instruction = ((inst.instruction & 0xfff3ffff)
20699 | neon_logbits (et.size) << 18);
20700
30bdf752
MGD
20701 switch (mode)
20702 {
20703 case neon_cvt_mode_z: inst.instruction |= 3 << 7; break;
20704 case neon_cvt_mode_x: inst.instruction |= 1 << 7; break;
20705 case neon_cvt_mode_a: inst.instruction |= 2 << 7; break;
20706 case neon_cvt_mode_n: inst.instruction |= 0 << 7; break;
20707 case neon_cvt_mode_p: inst.instruction |= 7 << 7; break;
20708 case neon_cvt_mode_m: inst.instruction |= 5 << 7; break;
20709 case neon_cvt_mode_r: inst.error = _("invalid rounding mode"); break;
20710 default: abort ();
20711 }
20712
20713 if (thumb_mode)
20714 inst.instruction |= 0xfc000000;
20715 else
20716 inst.instruction |= 0xf0000000;
20717 }
20718}
20719
20720static void
20721do_vrintx (void)
20722{
20723 do_vrint_1 (neon_cvt_mode_x);
20724}
20725
20726static void
20727do_vrintz (void)
20728{
20729 do_vrint_1 (neon_cvt_mode_z);
20730}
20731
20732static void
20733do_vrintr (void)
20734{
20735 do_vrint_1 (neon_cvt_mode_r);
20736}
20737
20738static void
20739do_vrinta (void)
20740{
20741 do_vrint_1 (neon_cvt_mode_a);
20742}
20743
20744static void
20745do_vrintn (void)
20746{
20747 do_vrint_1 (neon_cvt_mode_n);
20748}
20749
20750static void
20751do_vrintp (void)
20752{
20753 do_vrint_1 (neon_cvt_mode_p);
20754}
20755
20756static void
20757do_vrintm (void)
20758{
20759 do_vrint_1 (neon_cvt_mode_m);
20760}
20761
c28eeff2
SN
20762static unsigned
20763neon_scalar_for_vcmla (unsigned opnd, unsigned elsize)
20764{
20765 unsigned regno = NEON_SCALAR_REG (opnd);
20766 unsigned elno = NEON_SCALAR_INDEX (opnd);
20767
20768 if (elsize == 16 && elno < 2 && regno < 16)
20769 return regno | (elno << 4);
20770 else if (elsize == 32 && elno == 0)
20771 return regno;
20772
20773 first_error (_("scalar out of range"));
20774 return 0;
20775}
20776
20777static void
20778do_vcmla (void)
20779{
5d281bf0
AV
20780 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext)
20781 && (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8)
20782 || !mark_feature_used (&arm_ext_v8_3)), (BAD_FPU));
e2b0ab59
AV
20783 constraint (inst.relocs[0].exp.X_op != O_constant,
20784 _("expression too complex"));
20785 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2
SN
20786 constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
20787 _("immediate out of range"));
20788 rot /= 90;
5d281bf0 20789
64c350f2
AV
20790 if (!check_simd_pred_availability (TRUE,
20791 NEON_CHECK_ARCH8 | NEON_CHECK_CC))
5d281bf0
AV
20792 return;
20793
c28eeff2
SN
20794 if (inst.operands[2].isscalar)
20795 {
5d281bf0
AV
20796 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
20797 first_error (_("invalid instruction shape"));
c28eeff2
SN
20798 enum neon_shape rs = neon_select_shape (NS_DDSI, NS_QQSI, NS_NULL);
20799 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
20800 N_KEY | N_F16 | N_F32).size;
20801 unsigned m = neon_scalar_for_vcmla (inst.operands[2].reg, size);
20802 inst.is_neon = 1;
20803 inst.instruction = 0xfe000800;
20804 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20805 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20806 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
20807 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
20808 inst.instruction |= LOW4 (m);
20809 inst.instruction |= HI1 (m) << 5;
20810 inst.instruction |= neon_quad (rs) << 6;
20811 inst.instruction |= rot << 20;
20812 inst.instruction |= (size == 32) << 23;
20813 }
20814 else
20815 {
5d281bf0
AV
20816 enum neon_shape rs;
20817 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
20818 rs = neon_select_shape (NS_QQQI, NS_NULL);
20819 else
20820 rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
20821
c28eeff2
SN
20822 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
20823 N_KEY | N_F16 | N_F32).size;
5d281bf0
AV
20824 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext) && size == 32
20825 && (inst.operands[0].reg == inst.operands[1].reg
20826 || inst.operands[0].reg == inst.operands[2].reg))
20827 as_tsktsk (BAD_MVE_SRCDEST);
20828
c28eeff2
SN
20829 neon_three_same (neon_quad (rs), 0, -1);
20830 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
20831 inst.instruction |= 0xfc200800;
20832 inst.instruction |= rot << 23;
20833 inst.instruction |= (size == 32) << 20;
20834 }
20835}
20836
20837static void
20838do_vcadd (void)
20839{
5d281bf0
AV
20840 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
20841 && (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8)
20842 || !mark_feature_used (&arm_ext_v8_3)), (BAD_FPU));
e2b0ab59
AV
20843 constraint (inst.relocs[0].exp.X_op != O_constant,
20844 _("expression too complex"));
5d281bf0 20845
e2b0ab59 20846 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2 20847 constraint (rot != 90 && rot != 270, _("immediate out of range"));
5d281bf0
AV
20848 enum neon_shape rs;
20849 struct neon_type_el et;
20850 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20851 {
20852 rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
20853 et = neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16 | N_F32);
20854 }
20855 else
20856 {
20857 rs = neon_select_shape (NS_QQQI, NS_NULL);
20858 et = neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16 | N_F32 | N_I8
20859 | N_I16 | N_I32);
20860 if (et.size == 32 && inst.operands[0].reg == inst.operands[2].reg)
20861 as_tsktsk (_("Warning: 32-bit element size and same first and third "
20862 "operand makes instruction UNPREDICTABLE"));
20863 }
20864
20865 if (et.type == NT_invtype)
20866 return;
20867
64c350f2
AV
20868 if (!check_simd_pred_availability (et.type == NT_float,
20869 NEON_CHECK_ARCH8 | NEON_CHECK_CC))
5d281bf0
AV
20870 return;
20871
20872 if (et.type == NT_float)
20873 {
20874 neon_three_same (neon_quad (rs), 0, -1);
20875 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
20876 inst.instruction |= 0xfc800800;
20877 inst.instruction |= (rot == 270) << 24;
20878 inst.instruction |= (et.size == 32) << 20;
20879 }
20880 else
20881 {
20882 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
20883 inst.instruction = 0xfe000f00;
20884 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20885 inst.instruction |= neon_logbits (et.size) << 20;
20886 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
20887 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20888 inst.instruction |= (rot == 270) << 12;
20889 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
20890 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
20891 inst.instruction |= LOW4 (inst.operands[2].reg);
20892 inst.is_neon = 1;
20893 }
c28eeff2
SN
20894}
20895
c604a79a
JW
20896/* Dot Product instructions encoding support. */
20897
20898static void
20899do_neon_dotproduct (int unsigned_p)
20900{
20901 enum neon_shape rs;
20902 unsigned scalar_oprd2 = 0;
20903 int high8;
20904
20905 if (inst.cond != COND_ALWAYS)
20906 as_warn (_("Dot Product instructions cannot be conditional, the behaviour "
20907 "is UNPREDICTABLE"));
20908
20909 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
20910 _(BAD_FPU));
20911
20912 /* Dot Product instructions are in three-same D/Q register format or the third
20913 operand can be a scalar index register. */
20914 if (inst.operands[2].isscalar)
20915 {
20916 scalar_oprd2 = neon_scalar_for_mul (inst.operands[2].reg, 32);
20917 high8 = 0xfe000000;
20918 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
20919 }
20920 else
20921 {
20922 high8 = 0xfc000000;
20923 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
20924 }
20925
20926 if (unsigned_p)
20927 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_U8);
20928 else
20929 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_S8);
20930
20931 /* The "U" bit in traditional Three Same encoding is fixed to 0 for Dot
20932 Product instruction, so we pass 0 as the "ubit" parameter. And the
20933 "Size" field are fixed to 0x2, so we pass 32 as the "size" parameter. */
20934 neon_three_same (neon_quad (rs), 0, 32);
20935
20936 /* Undo neon_dp_fixup. Dot Product instructions are using a slightly
20937 different NEON three-same encoding. */
20938 inst.instruction &= 0x00ffffff;
20939 inst.instruction |= high8;
20940 /* Encode 'U' bit which indicates signedness. */
20941 inst.instruction |= (unsigned_p ? 1 : 0) << 4;
20942 /* Re-encode operand2 if it's indexed scalar operand. What has been encoded
20943 from inst.operand[2].reg in neon_three_same is GAS's internal encoding, not
20944 the instruction encoding. */
20945 if (inst.operands[2].isscalar)
20946 {
20947 inst.instruction &= 0xffffffd0;
20948 inst.instruction |= LOW4 (scalar_oprd2);
20949 inst.instruction |= HI1 (scalar_oprd2) << 5;
20950 }
20951}
20952
20953/* Dot Product instructions for signed integer. */
20954
20955static void
20956do_neon_dotproduct_s (void)
20957{
20958 return do_neon_dotproduct (0);
20959}
20960
20961/* Dot Product instructions for unsigned integer. */
20962
20963static void
20964do_neon_dotproduct_u (void)
20965{
20966 return do_neon_dotproduct (1);
20967}
20968
91ff7894
MGD
20969/* Crypto v1 instructions. */
20970static void
20971do_crypto_2op_1 (unsigned elttype, int op)
20972{
5ee91343 20973 set_pred_insn_type (OUTSIDE_PRED_INSN);
91ff7894
MGD
20974
20975 if (neon_check_type (2, NS_QQ, N_EQK | N_UNT, elttype | N_UNT | N_KEY).type
20976 == NT_invtype)
20977 return;
20978
20979 inst.error = NULL;
20980
20981 NEON_ENCODE (INTEGER, inst);
20982 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20983 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20984 inst.instruction |= LOW4 (inst.operands[1].reg);
20985 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
20986 if (op != -1)
20987 inst.instruction |= op << 6;
20988
20989 if (thumb_mode)
20990 inst.instruction |= 0xfc000000;
20991 else
20992 inst.instruction |= 0xf0000000;
20993}
20994
48adcd8e
MGD
20995static void
20996do_crypto_3op_1 (int u, int op)
20997{
5ee91343 20998 set_pred_insn_type (OUTSIDE_PRED_INSN);
48adcd8e
MGD
20999
21000 if (neon_check_type (3, NS_QQQ, N_EQK | N_UNT, N_EQK | N_UNT,
21001 N_32 | N_UNT | N_KEY).type == NT_invtype)
21002 return;
21003
21004 inst.error = NULL;
21005
21006 NEON_ENCODE (INTEGER, inst);
21007 neon_three_same (1, u, 8 << op);
21008}
21009
91ff7894
MGD
21010static void
21011do_aese (void)
21012{
21013 do_crypto_2op_1 (N_8, 0);
21014}
21015
21016static void
21017do_aesd (void)
21018{
21019 do_crypto_2op_1 (N_8, 1);
21020}
21021
21022static void
21023do_aesmc (void)
21024{
21025 do_crypto_2op_1 (N_8, 2);
21026}
21027
21028static void
21029do_aesimc (void)
21030{
21031 do_crypto_2op_1 (N_8, 3);
21032}
21033
48adcd8e
MGD
21034static void
21035do_sha1c (void)
21036{
21037 do_crypto_3op_1 (0, 0);
21038}
21039
21040static void
21041do_sha1p (void)
21042{
21043 do_crypto_3op_1 (0, 1);
21044}
21045
21046static void
21047do_sha1m (void)
21048{
21049 do_crypto_3op_1 (0, 2);
21050}
21051
21052static void
21053do_sha1su0 (void)
21054{
21055 do_crypto_3op_1 (0, 3);
21056}
91ff7894 21057
48adcd8e
MGD
21058static void
21059do_sha256h (void)
21060{
21061 do_crypto_3op_1 (1, 0);
21062}
21063
21064static void
21065do_sha256h2 (void)
21066{
21067 do_crypto_3op_1 (1, 1);
21068}
21069
21070static void
21071do_sha256su1 (void)
21072{
21073 do_crypto_3op_1 (1, 2);
21074}
3c9017d2
MGD
21075
21076static void
21077do_sha1h (void)
21078{
21079 do_crypto_2op_1 (N_32, -1);
21080}
21081
21082static void
21083do_sha1su1 (void)
21084{
21085 do_crypto_2op_1 (N_32, 0);
21086}
21087
21088static void
21089do_sha256su0 (void)
21090{
21091 do_crypto_2op_1 (N_32, 1);
21092}
dd5181d5
KT
21093
21094static void
21095do_crc32_1 (unsigned int poly, unsigned int sz)
21096{
21097 unsigned int Rd = inst.operands[0].reg;
21098 unsigned int Rn = inst.operands[1].reg;
21099 unsigned int Rm = inst.operands[2].reg;
21100
5ee91343 21101 set_pred_insn_type (OUTSIDE_PRED_INSN);
dd5181d5
KT
21102 inst.instruction |= LOW4 (Rd) << (thumb_mode ? 8 : 12);
21103 inst.instruction |= LOW4 (Rn) << 16;
21104 inst.instruction |= LOW4 (Rm);
21105 inst.instruction |= sz << (thumb_mode ? 4 : 21);
21106 inst.instruction |= poly << (thumb_mode ? 20 : 9);
21107
21108 if (Rd == REG_PC || Rn == REG_PC || Rm == REG_PC)
21109 as_warn (UNPRED_REG ("r15"));
dd5181d5
KT
21110}
21111
21112static void
21113do_crc32b (void)
21114{
21115 do_crc32_1 (0, 0);
21116}
21117
21118static void
21119do_crc32h (void)
21120{
21121 do_crc32_1 (0, 1);
21122}
21123
21124static void
21125do_crc32w (void)
21126{
21127 do_crc32_1 (0, 2);
21128}
21129
21130static void
21131do_crc32cb (void)
21132{
21133 do_crc32_1 (1, 0);
21134}
21135
21136static void
21137do_crc32ch (void)
21138{
21139 do_crc32_1 (1, 1);
21140}
21141
21142static void
21143do_crc32cw (void)
21144{
21145 do_crc32_1 (1, 2);
21146}
21147
49e8a725
SN
21148static void
21149do_vjcvt (void)
21150{
21151 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
21152 _(BAD_FPU));
21153 neon_check_type (2, NS_FD, N_S32, N_F64);
21154 do_vfp_sp_dp_cvt ();
21155 do_vfp_cond_or_thumb ();
21156}
21157
5287ad62
JB
21158\f
21159/* Overall per-instruction processing. */
21160
21161/* We need to be able to fix up arbitrary expressions in some statements.
21162 This is so that we can handle symbols that are an arbitrary distance from
21163 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
21164 which returns part of an address in a form which will be valid for
21165 a data instruction. We do this by pushing the expression into a symbol
21166 in the expr_section, and creating a fix for that. */
21167
21168static void
21169fix_new_arm (fragS * frag,
21170 int where,
21171 short int size,
21172 expressionS * exp,
21173 int pc_rel,
21174 int reloc)
21175{
21176 fixS * new_fix;
21177
21178 switch (exp->X_op)
21179 {
21180 case O_constant:
6e7ce2cd
PB
21181 if (pc_rel)
21182 {
21183 /* Create an absolute valued symbol, so we have something to
477330fc
RM
21184 refer to in the object file. Unfortunately for us, gas's
21185 generic expression parsing will already have folded out
21186 any use of .set foo/.type foo %function that may have
21187 been used to set type information of the target location,
21188 that's being specified symbolically. We have to presume
21189 the user knows what they are doing. */
6e7ce2cd
PB
21190 char name[16 + 8];
21191 symbolS *symbol;
21192
21193 sprintf (name, "*ABS*0x%lx", (unsigned long)exp->X_add_number);
21194
21195 symbol = symbol_find_or_make (name);
21196 S_SET_SEGMENT (symbol, absolute_section);
21197 symbol_set_frag (symbol, &zero_address_frag);
21198 S_SET_VALUE (symbol, exp->X_add_number);
21199 exp->X_op = O_symbol;
21200 exp->X_add_symbol = symbol;
21201 exp->X_add_number = 0;
21202 }
21203 /* FALLTHROUGH */
5287ad62
JB
21204 case O_symbol:
21205 case O_add:
21206 case O_subtract:
21d799b5 21207 new_fix = fix_new_exp (frag, where, size, exp, pc_rel,
477330fc 21208 (enum bfd_reloc_code_real) reloc);
5287ad62
JB
21209 break;
21210
21211 default:
21d799b5 21212 new_fix = (fixS *) fix_new (frag, where, size, make_expr_symbol (exp), 0,
477330fc 21213 pc_rel, (enum bfd_reloc_code_real) reloc);
5287ad62
JB
21214 break;
21215 }
21216
21217 /* Mark whether the fix is to a THUMB instruction, or an ARM
21218 instruction. */
21219 new_fix->tc_fix_data = thumb_mode;
21220}
21221
21222/* Create a frg for an instruction requiring relaxation. */
21223static void
21224output_relax_insn (void)
21225{
21226 char * to;
21227 symbolS *sym;
0110f2b8
PB
21228 int offset;
21229
6e1cb1a6
PB
21230 /* The size of the instruction is unknown, so tie the debug info to the
21231 start of the instruction. */
21232 dwarf2_emit_insn (0);
6e1cb1a6 21233
e2b0ab59 21234 switch (inst.relocs[0].exp.X_op)
0110f2b8
PB
21235 {
21236 case O_symbol:
e2b0ab59
AV
21237 sym = inst.relocs[0].exp.X_add_symbol;
21238 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
21239 break;
21240 case O_constant:
21241 sym = NULL;
e2b0ab59 21242 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
21243 break;
21244 default:
e2b0ab59 21245 sym = make_expr_symbol (&inst.relocs[0].exp);
0110f2b8
PB
21246 offset = 0;
21247 break;
21248 }
21249 to = frag_var (rs_machine_dependent, INSN_SIZE, THUMB_SIZE,
21250 inst.relax, sym, offset, NULL/*offset, opcode*/);
21251 md_number_to_chars (to, inst.instruction, THUMB_SIZE);
0110f2b8
PB
21252}
21253
21254/* Write a 32-bit thumb instruction to buf. */
21255static void
21256put_thumb32_insn (char * buf, unsigned long insn)
21257{
21258 md_number_to_chars (buf, insn >> 16, THUMB_SIZE);
21259 md_number_to_chars (buf + THUMB_SIZE, insn, THUMB_SIZE);
21260}
21261
b99bd4ef 21262static void
c19d1205 21263output_inst (const char * str)
b99bd4ef 21264{
c19d1205 21265 char * to = NULL;
b99bd4ef 21266
c19d1205 21267 if (inst.error)
b99bd4ef 21268 {
c19d1205 21269 as_bad ("%s -- `%s'", inst.error, str);
b99bd4ef
NC
21270 return;
21271 }
5f4273c7
NC
21272 if (inst.relax)
21273 {
21274 output_relax_insn ();
0110f2b8 21275 return;
5f4273c7 21276 }
c19d1205
ZW
21277 if (inst.size == 0)
21278 return;
b99bd4ef 21279
c19d1205 21280 to = frag_more (inst.size);
8dc2430f
NC
21281 /* PR 9814: Record the thumb mode into the current frag so that we know
21282 what type of NOP padding to use, if necessary. We override any previous
21283 setting so that if the mode has changed then the NOPS that we use will
21284 match the encoding of the last instruction in the frag. */
cd000bff 21285 frag_now->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
c19d1205
ZW
21286
21287 if (thumb_mode && (inst.size > THUMB_SIZE))
b99bd4ef 21288 {
9c2799c2 21289 gas_assert (inst.size == (2 * THUMB_SIZE));
0110f2b8 21290 put_thumb32_insn (to, inst.instruction);
b99bd4ef 21291 }
c19d1205 21292 else if (inst.size > INSN_SIZE)
b99bd4ef 21293 {
9c2799c2 21294 gas_assert (inst.size == (2 * INSN_SIZE));
c19d1205
ZW
21295 md_number_to_chars (to, inst.instruction, INSN_SIZE);
21296 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
b99bd4ef 21297 }
c19d1205
ZW
21298 else
21299 md_number_to_chars (to, inst.instruction, inst.size);
b99bd4ef 21300
e2b0ab59
AV
21301 int r;
21302 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
21303 {
21304 if (inst.relocs[r].type != BFD_RELOC_UNUSED)
21305 fix_new_arm (frag_now, to - frag_now->fr_literal,
21306 inst.size, & inst.relocs[r].exp, inst.relocs[r].pc_rel,
21307 inst.relocs[r].type);
21308 }
b99bd4ef 21309
c19d1205 21310 dwarf2_emit_insn (inst.size);
c19d1205 21311}
b99bd4ef 21312
e07e6e58
NC
21313static char *
21314output_it_inst (int cond, int mask, char * to)
21315{
21316 unsigned long instruction = 0xbf00;
21317
21318 mask &= 0xf;
21319 instruction |= mask;
21320 instruction |= cond << 4;
21321
21322 if (to == NULL)
21323 {
21324 to = frag_more (2);
21325#ifdef OBJ_ELF
21326 dwarf2_emit_insn (2);
21327#endif
21328 }
21329
21330 md_number_to_chars (to, instruction, 2);
21331
21332 return to;
21333}
21334
c19d1205
ZW
21335/* Tag values used in struct asm_opcode's tag field. */
21336enum opcode_tag
21337{
21338 OT_unconditional, /* Instruction cannot be conditionalized.
21339 The ARM condition field is still 0xE. */
21340 OT_unconditionalF, /* Instruction cannot be conditionalized
21341 and carries 0xF in its ARM condition field. */
21342 OT_csuffix, /* Instruction takes a conditional suffix. */
5ee91343
AV
21343 OT_csuffixF, /* Some forms of the instruction take a scalar
21344 conditional suffix, others place 0xF where the
21345 condition field would be, others take a vector
21346 conditional suffix. */
c19d1205
ZW
21347 OT_cinfix3, /* Instruction takes a conditional infix,
21348 beginning at character index 3. (In
21349 unified mode, it becomes a suffix.) */
088fa78e
KH
21350 OT_cinfix3_deprecated, /* The same as OT_cinfix3. This is used for
21351 tsts, cmps, cmns, and teqs. */
e3cb604e
PB
21352 OT_cinfix3_legacy, /* Legacy instruction takes a conditional infix at
21353 character index 3, even in unified mode. Used for
21354 legacy instructions where suffix and infix forms
21355 may be ambiguous. */
c19d1205 21356 OT_csuf_or_in3, /* Instruction takes either a conditional
e3cb604e 21357 suffix or an infix at character index 3. */
c19d1205
ZW
21358 OT_odd_infix_unc, /* This is the unconditional variant of an
21359 instruction that takes a conditional infix
21360 at an unusual position. In unified mode,
21361 this variant will accept a suffix. */
21362 OT_odd_infix_0 /* Values greater than or equal to OT_odd_infix_0
21363 are the conditional variants of instructions that
21364 take conditional infixes in unusual positions.
21365 The infix appears at character index
21366 (tag - OT_odd_infix_0). These are not accepted
21367 in unified mode. */
21368};
b99bd4ef 21369
c19d1205
ZW
21370/* Subroutine of md_assemble, responsible for looking up the primary
21371 opcode from the mnemonic the user wrote. STR points to the
21372 beginning of the mnemonic.
21373
21374 This is not simply a hash table lookup, because of conditional
21375 variants. Most instructions have conditional variants, which are
21376 expressed with a _conditional affix_ to the mnemonic. If we were
21377 to encode each conditional variant as a literal string in the opcode
21378 table, it would have approximately 20,000 entries.
21379
21380 Most mnemonics take this affix as a suffix, and in unified syntax,
21381 'most' is upgraded to 'all'. However, in the divided syntax, some
21382 instructions take the affix as an infix, notably the s-variants of
21383 the arithmetic instructions. Of those instructions, all but six
21384 have the infix appear after the third character of the mnemonic.
21385
21386 Accordingly, the algorithm for looking up primary opcodes given
21387 an identifier is:
21388
21389 1. Look up the identifier in the opcode table.
21390 If we find a match, go to step U.
21391
21392 2. Look up the last two characters of the identifier in the
21393 conditions table. If we find a match, look up the first N-2
21394 characters of the identifier in the opcode table. If we
21395 find a match, go to step CE.
21396
21397 3. Look up the fourth and fifth characters of the identifier in
21398 the conditions table. If we find a match, extract those
21399 characters from the identifier, and look up the remaining
21400 characters in the opcode table. If we find a match, go
21401 to step CM.
21402
21403 4. Fail.
21404
21405 U. Examine the tag field of the opcode structure, in case this is
21406 one of the six instructions with its conditional infix in an
21407 unusual place. If it is, the tag tells us where to find the
21408 infix; look it up in the conditions table and set inst.cond
21409 accordingly. Otherwise, this is an unconditional instruction.
21410 Again set inst.cond accordingly. Return the opcode structure.
21411
21412 CE. Examine the tag field to make sure this is an instruction that
21413 should receive a conditional suffix. If it is not, fail.
21414 Otherwise, set inst.cond from the suffix we already looked up,
21415 and return the opcode structure.
21416
21417 CM. Examine the tag field to make sure this is an instruction that
21418 should receive a conditional infix after the third character.
21419 If it is not, fail. Otherwise, undo the edits to the current
21420 line of input and proceed as for case CE. */
21421
21422static const struct asm_opcode *
21423opcode_lookup (char **str)
21424{
21425 char *end, *base;
21426 char *affix;
21427 const struct asm_opcode *opcode;
21428 const struct asm_cond *cond;
e3cb604e 21429 char save[2];
c19d1205
ZW
21430
21431 /* Scan up to the end of the mnemonic, which must end in white space,
721a8186 21432 '.' (in unified mode, or for Neon/VFP instructions), or end of string. */
c19d1205 21433 for (base = end = *str; *end != '\0'; end++)
721a8186 21434 if (*end == ' ' || *end == '.')
c19d1205 21435 break;
b99bd4ef 21436
c19d1205 21437 if (end == base)
c921be7d 21438 return NULL;
b99bd4ef 21439
5287ad62 21440 /* Handle a possible width suffix and/or Neon type suffix. */
c19d1205 21441 if (end[0] == '.')
b99bd4ef 21442 {
5287ad62 21443 int offset = 2;
5f4273c7 21444
267d2029 21445 /* The .w and .n suffixes are only valid if the unified syntax is in
477330fc 21446 use. */
267d2029 21447 if (unified_syntax && end[1] == 'w')
c19d1205 21448 inst.size_req = 4;
267d2029 21449 else if (unified_syntax && end[1] == 'n')
c19d1205
ZW
21450 inst.size_req = 2;
21451 else
477330fc 21452 offset = 0;
5287ad62
JB
21453
21454 inst.vectype.elems = 0;
21455
21456 *str = end + offset;
b99bd4ef 21457
5f4273c7 21458 if (end[offset] == '.')
5287ad62 21459 {
267d2029 21460 /* See if we have a Neon type suffix (possible in either unified or
477330fc
RM
21461 non-unified ARM syntax mode). */
21462 if (parse_neon_type (&inst.vectype, str) == FAIL)
c921be7d 21463 return NULL;
477330fc 21464 }
5287ad62 21465 else if (end[offset] != '\0' && end[offset] != ' ')
477330fc 21466 return NULL;
b99bd4ef 21467 }
c19d1205
ZW
21468 else
21469 *str = end;
b99bd4ef 21470
c19d1205 21471 /* Look for unaffixed or special-case affixed mnemonic. */
21d799b5 21472 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
477330fc 21473 end - base);
c19d1205 21474 if (opcode)
b99bd4ef 21475 {
c19d1205
ZW
21476 /* step U */
21477 if (opcode->tag < OT_odd_infix_0)
b99bd4ef 21478 {
c19d1205
ZW
21479 inst.cond = COND_ALWAYS;
21480 return opcode;
b99bd4ef 21481 }
b99bd4ef 21482
278df34e 21483 if (warn_on_deprecated && unified_syntax)
5c3696f8 21484 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205 21485 affix = base + (opcode->tag - OT_odd_infix_0);
21d799b5 21486 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
9c2799c2 21487 gas_assert (cond);
b99bd4ef 21488
c19d1205
ZW
21489 inst.cond = cond->value;
21490 return opcode;
21491 }
5ee91343
AV
21492 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
21493 {
21494 /* Cannot have a conditional suffix on a mnemonic of less than a character.
21495 */
21496 if (end - base < 2)
21497 return NULL;
21498 affix = end - 1;
21499 cond = (const struct asm_cond *) hash_find_n (arm_vcond_hsh, affix, 1);
21500 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
21501 affix - base);
21502 /* If this opcode can not be vector predicated then don't accept it with a
21503 vector predication code. */
21504 if (opcode && !opcode->mayBeVecPred)
21505 opcode = NULL;
21506 }
21507 if (!opcode || !cond)
21508 {
21509 /* Cannot have a conditional suffix on a mnemonic of less than two
21510 characters. */
21511 if (end - base < 3)
21512 return NULL;
b99bd4ef 21513
5ee91343
AV
21514 /* Look for suffixed mnemonic. */
21515 affix = end - 2;
21516 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
21517 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
21518 affix - base);
21519 }
b99bd4ef 21520
c19d1205
ZW
21521 if (opcode && cond)
21522 {
21523 /* step CE */
21524 switch (opcode->tag)
21525 {
e3cb604e
PB
21526 case OT_cinfix3_legacy:
21527 /* Ignore conditional suffixes matched on infix only mnemonics. */
21528 break;
21529
c19d1205 21530 case OT_cinfix3:
088fa78e 21531 case OT_cinfix3_deprecated:
c19d1205
ZW
21532 case OT_odd_infix_unc:
21533 if (!unified_syntax)
0198d5e6 21534 return NULL;
1a0670f3 21535 /* Fall through. */
c19d1205
ZW
21536
21537 case OT_csuffix:
477330fc 21538 case OT_csuffixF:
c19d1205
ZW
21539 case OT_csuf_or_in3:
21540 inst.cond = cond->value;
21541 return opcode;
21542
21543 case OT_unconditional:
21544 case OT_unconditionalF:
dfa9f0d5 21545 if (thumb_mode)
c921be7d 21546 inst.cond = cond->value;
dfa9f0d5
PB
21547 else
21548 {
c921be7d 21549 /* Delayed diagnostic. */
dfa9f0d5
PB
21550 inst.error = BAD_COND;
21551 inst.cond = COND_ALWAYS;
21552 }
c19d1205 21553 return opcode;
b99bd4ef 21554
c19d1205 21555 default:
c921be7d 21556 return NULL;
c19d1205
ZW
21557 }
21558 }
b99bd4ef 21559
c19d1205
ZW
21560 /* Cannot have a usual-position infix on a mnemonic of less than
21561 six characters (five would be a suffix). */
21562 if (end - base < 6)
c921be7d 21563 return NULL;
b99bd4ef 21564
c19d1205
ZW
21565 /* Look for infixed mnemonic in the usual position. */
21566 affix = base + 3;
21d799b5 21567 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
e3cb604e 21568 if (!cond)
c921be7d 21569 return NULL;
e3cb604e
PB
21570
21571 memcpy (save, affix, 2);
21572 memmove (affix, affix + 2, (end - affix) - 2);
21d799b5 21573 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
477330fc 21574 (end - base) - 2);
e3cb604e
PB
21575 memmove (affix + 2, affix, (end - affix) - 2);
21576 memcpy (affix, save, 2);
21577
088fa78e
KH
21578 if (opcode
21579 && (opcode->tag == OT_cinfix3
21580 || opcode->tag == OT_cinfix3_deprecated
21581 || opcode->tag == OT_csuf_or_in3
21582 || opcode->tag == OT_cinfix3_legacy))
b99bd4ef 21583 {
c921be7d 21584 /* Step CM. */
278df34e 21585 if (warn_on_deprecated && unified_syntax
088fa78e
KH
21586 && (opcode->tag == OT_cinfix3
21587 || opcode->tag == OT_cinfix3_deprecated))
5c3696f8 21588 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205
ZW
21589
21590 inst.cond = cond->value;
21591 return opcode;
b99bd4ef
NC
21592 }
21593
c921be7d 21594 return NULL;
b99bd4ef
NC
21595}
21596
e07e6e58
NC
21597/* This function generates an initial IT instruction, leaving its block
21598 virtually open for the new instructions. Eventually,
5ee91343 21599 the mask will be updated by now_pred_add_mask () each time
e07e6e58
NC
21600 a new instruction needs to be included in the IT block.
21601 Finally, the block is closed with close_automatic_it_block ().
21602 The block closure can be requested either from md_assemble (),
21603 a tencode (), or due to a label hook. */
21604
21605static void
21606new_automatic_it_block (int cond)
21607{
5ee91343
AV
21608 now_pred.state = AUTOMATIC_PRED_BLOCK;
21609 now_pred.mask = 0x18;
21610 now_pred.cc = cond;
21611 now_pred.block_length = 1;
cd000bff 21612 mapping_state (MAP_THUMB);
5ee91343
AV
21613 now_pred.insn = output_it_inst (cond, now_pred.mask, NULL);
21614 now_pred.warn_deprecated = FALSE;
21615 now_pred.insn_cond = TRUE;
e07e6e58
NC
21616}
21617
21618/* Close an automatic IT block.
21619 See comments in new_automatic_it_block (). */
21620
21621static void
21622close_automatic_it_block (void)
21623{
5ee91343
AV
21624 now_pred.mask = 0x10;
21625 now_pred.block_length = 0;
e07e6e58
NC
21626}
21627
21628/* Update the mask of the current automatically-generated IT
21629 instruction. See comments in new_automatic_it_block (). */
21630
21631static void
5ee91343 21632now_pred_add_mask (int cond)
e07e6e58
NC
21633{
21634#define CLEAR_BIT(value, nbit) ((value) & ~(1 << (nbit)))
21635#define SET_BIT_VALUE(value, bitvalue, nbit) (CLEAR_BIT (value, nbit) \
477330fc 21636 | ((bitvalue) << (nbit)))
e07e6e58 21637 const int resulting_bit = (cond & 1);
c921be7d 21638
5ee91343
AV
21639 now_pred.mask &= 0xf;
21640 now_pred.mask = SET_BIT_VALUE (now_pred.mask,
477330fc 21641 resulting_bit,
5ee91343
AV
21642 (5 - now_pred.block_length));
21643 now_pred.mask = SET_BIT_VALUE (now_pred.mask,
477330fc 21644 1,
5ee91343
AV
21645 ((5 - now_pred.block_length) - 1));
21646 output_it_inst (now_pred.cc, now_pred.mask, now_pred.insn);
e07e6e58
NC
21647
21648#undef CLEAR_BIT
21649#undef SET_BIT_VALUE
e07e6e58
NC
21650}
21651
21652/* The IT blocks handling machinery is accessed through the these functions:
21653 it_fsm_pre_encode () from md_assemble ()
5ee91343
AV
21654 set_pred_insn_type () optional, from the tencode functions
21655 set_pred_insn_type_last () ditto
21656 in_pred_block () ditto
e07e6e58 21657 it_fsm_post_encode () from md_assemble ()
33eaf5de 21658 force_automatic_it_block_close () from label handling functions
e07e6e58
NC
21659
21660 Rationale:
21661 1) md_assemble () calls it_fsm_pre_encode () before calling tencode (),
477330fc
RM
21662 initializing the IT insn type with a generic initial value depending
21663 on the inst.condition.
e07e6e58 21664 2) During the tencode function, two things may happen:
477330fc 21665 a) The tencode function overrides the IT insn type by
5ee91343
AV
21666 calling either set_pred_insn_type (type) or
21667 set_pred_insn_type_last ().
477330fc 21668 b) The tencode function queries the IT block state by
5ee91343 21669 calling in_pred_block () (i.e. to determine narrow/not narrow mode).
477330fc 21670
5ee91343
AV
21671 Both set_pred_insn_type and in_pred_block run the internal FSM state
21672 handling function (handle_pred_state), because: a) setting the IT insn
477330fc
RM
21673 type may incur in an invalid state (exiting the function),
21674 and b) querying the state requires the FSM to be updated.
21675 Specifically we want to avoid creating an IT block for conditional
21676 branches, so it_fsm_pre_encode is actually a guess and we can't
21677 determine whether an IT block is required until the tencode () routine
21678 has decided what type of instruction this actually it.
5ee91343
AV
21679 Because of this, if set_pred_insn_type and in_pred_block have to be
21680 used, set_pred_insn_type has to be called first.
477330fc 21681
5ee91343
AV
21682 set_pred_insn_type_last () is a wrapper of set_pred_insn_type (type),
21683 that determines the insn IT type depending on the inst.cond code.
477330fc
RM
21684 When a tencode () routine encodes an instruction that can be
21685 either outside an IT block, or, in the case of being inside, has to be
5ee91343 21686 the last one, set_pred_insn_type_last () will determine the proper
477330fc 21687 IT instruction type based on the inst.cond code. Otherwise,
5ee91343 21688 set_pred_insn_type can be called for overriding that logic or
477330fc
RM
21689 for covering other cases.
21690
5ee91343
AV
21691 Calling handle_pred_state () may not transition the IT block state to
21692 OUTSIDE_PRED_BLOCK immediately, since the (current) state could be
477330fc 21693 still queried. Instead, if the FSM determines that the state should
5ee91343 21694 be transitioned to OUTSIDE_PRED_BLOCK, a flag is marked to be closed
477330fc
RM
21695 after the tencode () function: that's what it_fsm_post_encode () does.
21696
5ee91343 21697 Since in_pred_block () calls the state handling function to get an
477330fc
RM
21698 updated state, an error may occur (due to invalid insns combination).
21699 In that case, inst.error is set.
21700 Therefore, inst.error has to be checked after the execution of
21701 the tencode () routine.
e07e6e58
NC
21702
21703 3) Back in md_assemble(), it_fsm_post_encode () is called to commit
477330fc 21704 any pending state change (if any) that didn't take place in
5ee91343 21705 handle_pred_state () as explained above. */
e07e6e58
NC
21706
21707static void
21708it_fsm_pre_encode (void)
21709{
21710 if (inst.cond != COND_ALWAYS)
5ee91343 21711 inst.pred_insn_type = INSIDE_IT_INSN;
e07e6e58 21712 else
5ee91343 21713 inst.pred_insn_type = OUTSIDE_PRED_INSN;
e07e6e58 21714
5ee91343 21715 now_pred.state_handled = 0;
e07e6e58
NC
21716}
21717
21718/* IT state FSM handling function. */
5ee91343
AV
21719/* MVE instructions and non-MVE instructions are handled differently because of
21720 the introduction of VPT blocks.
21721 Specifications say that any non-MVE instruction inside a VPT block is
21722 UNPREDICTABLE, with the exception of the BKPT instruction. Whereas most MVE
21723 instructions are deemed to be UNPREDICTABLE if inside an IT block. For the
35c228db 21724 few exceptions we have MVE_UNPREDICABLE_INSN.
5ee91343
AV
21725 The error messages provided depending on the different combinations possible
21726 are described in the cases below:
21727 For 'most' MVE instructions:
21728 1) In an IT block, with an IT code: syntax error
21729 2) In an IT block, with a VPT code: error: must be in a VPT block
21730 3) In an IT block, with no code: warning: UNPREDICTABLE
21731 4) In a VPT block, with an IT code: syntax error
21732 5) In a VPT block, with a VPT code: OK!
21733 6) In a VPT block, with no code: error: missing code
21734 7) Outside a pred block, with an IT code: error: syntax error
21735 8) Outside a pred block, with a VPT code: error: should be in a VPT block
21736 9) Outside a pred block, with no code: OK!
21737 For non-MVE instructions:
21738 10) In an IT block, with an IT code: OK!
21739 11) In an IT block, with a VPT code: syntax error
21740 12) In an IT block, with no code: error: missing code
21741 13) In a VPT block, with an IT code: error: should be in an IT block
21742 14) In a VPT block, with a VPT code: syntax error
21743 15) In a VPT block, with no code: UNPREDICTABLE
21744 16) Outside a pred block, with an IT code: error: should be in an IT block
21745 17) Outside a pred block, with a VPT code: syntax error
21746 18) Outside a pred block, with no code: OK!
21747 */
21748
e07e6e58
NC
21749
21750static int
5ee91343 21751handle_pred_state (void)
e07e6e58 21752{
5ee91343
AV
21753 now_pred.state_handled = 1;
21754 now_pred.insn_cond = FALSE;
e07e6e58 21755
5ee91343 21756 switch (now_pred.state)
e07e6e58 21757 {
5ee91343
AV
21758 case OUTSIDE_PRED_BLOCK:
21759 switch (inst.pred_insn_type)
e07e6e58 21760 {
35c228db 21761 case MVE_UNPREDICABLE_INSN:
5ee91343
AV
21762 case MVE_OUTSIDE_PRED_INSN:
21763 if (inst.cond < COND_ALWAYS)
21764 {
21765 /* Case 7: Outside a pred block, with an IT code: error: syntax
21766 error. */
21767 inst.error = BAD_SYNTAX;
21768 return FAIL;
21769 }
21770 /* Case 9: Outside a pred block, with no code: OK! */
21771 break;
21772 case OUTSIDE_PRED_INSN:
21773 if (inst.cond > COND_ALWAYS)
21774 {
21775 /* Case 17: Outside a pred block, with a VPT code: syntax error.
21776 */
21777 inst.error = BAD_SYNTAX;
21778 return FAIL;
21779 }
21780 /* Case 18: Outside a pred block, with no code: OK! */
e07e6e58
NC
21781 break;
21782
5ee91343
AV
21783 case INSIDE_VPT_INSN:
21784 /* Case 8: Outside a pred block, with a VPT code: error: should be in
21785 a VPT block. */
21786 inst.error = BAD_OUT_VPT;
21787 return FAIL;
21788
e07e6e58
NC
21789 case INSIDE_IT_INSN:
21790 case INSIDE_IT_LAST_INSN:
5ee91343 21791 if (inst.cond < COND_ALWAYS)
e07e6e58 21792 {
5ee91343
AV
21793 /* Case 16: Outside a pred block, with an IT code: error: should
21794 be in an IT block. */
21795 if (thumb_mode == 0)
e07e6e58 21796 {
5ee91343
AV
21797 if (unified_syntax
21798 && !(implicit_it_mode & IMPLICIT_IT_MODE_ARM))
21799 as_tsktsk (_("Warning: conditional outside an IT block"\
21800 " for Thumb."));
e07e6e58
NC
21801 }
21802 else
21803 {
5ee91343
AV
21804 if ((implicit_it_mode & IMPLICIT_IT_MODE_THUMB)
21805 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
21806 {
21807 /* Automatically generate the IT instruction. */
21808 new_automatic_it_block (inst.cond);
21809 if (inst.pred_insn_type == INSIDE_IT_LAST_INSN)
21810 close_automatic_it_block ();
21811 }
21812 else
21813 {
21814 inst.error = BAD_OUT_IT;
21815 return FAIL;
21816 }
e07e6e58 21817 }
5ee91343 21818 break;
e07e6e58 21819 }
5ee91343
AV
21820 else if (inst.cond > COND_ALWAYS)
21821 {
21822 /* Case 17: Outside a pred block, with a VPT code: syntax error.
21823 */
21824 inst.error = BAD_SYNTAX;
21825 return FAIL;
21826 }
21827 else
21828 gas_assert (0);
e07e6e58
NC
21829 case IF_INSIDE_IT_LAST_INSN:
21830 case NEUTRAL_IT_INSN:
21831 break;
21832
5ee91343
AV
21833 case VPT_INSN:
21834 if (inst.cond != COND_ALWAYS)
21835 first_error (BAD_SYNTAX);
21836 now_pred.state = MANUAL_PRED_BLOCK;
21837 now_pred.block_length = 0;
21838 now_pred.type = VECTOR_PRED;
21839 now_pred.cc = 0;
21840 break;
e07e6e58 21841 case IT_INSN:
5ee91343
AV
21842 now_pred.state = MANUAL_PRED_BLOCK;
21843 now_pred.block_length = 0;
21844 now_pred.type = SCALAR_PRED;
e07e6e58
NC
21845 break;
21846 }
21847 break;
21848
5ee91343 21849 case AUTOMATIC_PRED_BLOCK:
e07e6e58
NC
21850 /* Three things may happen now:
21851 a) We should increment current it block size;
21852 b) We should close current it block (closing insn or 4 insns);
21853 c) We should close current it block and start a new one (due
21854 to incompatible conditions or
21855 4 insns-length block reached). */
21856
5ee91343 21857 switch (inst.pred_insn_type)
e07e6e58 21858 {
5ee91343
AV
21859 case INSIDE_VPT_INSN:
21860 case VPT_INSN:
35c228db 21861 case MVE_UNPREDICABLE_INSN:
5ee91343
AV
21862 case MVE_OUTSIDE_PRED_INSN:
21863 gas_assert (0);
21864 case OUTSIDE_PRED_INSN:
2b0f3761 21865 /* The closure of the block shall happen immediately,
5ee91343 21866 so any in_pred_block () call reports the block as closed. */
e07e6e58
NC
21867 force_automatic_it_block_close ();
21868 break;
21869
21870 case INSIDE_IT_INSN:
21871 case INSIDE_IT_LAST_INSN:
21872 case IF_INSIDE_IT_LAST_INSN:
5ee91343 21873 now_pred.block_length++;
e07e6e58 21874
5ee91343
AV
21875 if (now_pred.block_length > 4
21876 || !now_pred_compatible (inst.cond))
e07e6e58
NC
21877 {
21878 force_automatic_it_block_close ();
5ee91343 21879 if (inst.pred_insn_type != IF_INSIDE_IT_LAST_INSN)
e07e6e58
NC
21880 new_automatic_it_block (inst.cond);
21881 }
21882 else
21883 {
5ee91343
AV
21884 now_pred.insn_cond = TRUE;
21885 now_pred_add_mask (inst.cond);
e07e6e58
NC
21886 }
21887
5ee91343
AV
21888 if (now_pred.state == AUTOMATIC_PRED_BLOCK
21889 && (inst.pred_insn_type == INSIDE_IT_LAST_INSN
21890 || inst.pred_insn_type == IF_INSIDE_IT_LAST_INSN))
e07e6e58
NC
21891 close_automatic_it_block ();
21892 break;
21893
21894 case NEUTRAL_IT_INSN:
5ee91343
AV
21895 now_pred.block_length++;
21896 now_pred.insn_cond = TRUE;
e07e6e58 21897
5ee91343 21898 if (now_pred.block_length > 4)
e07e6e58
NC
21899 force_automatic_it_block_close ();
21900 else
5ee91343 21901 now_pred_add_mask (now_pred.cc & 1);
e07e6e58
NC
21902 break;
21903
21904 case IT_INSN:
21905 close_automatic_it_block ();
5ee91343 21906 now_pred.state = MANUAL_PRED_BLOCK;
e07e6e58
NC
21907 break;
21908 }
21909 break;
21910
5ee91343 21911 case MANUAL_PRED_BLOCK:
e07e6e58 21912 {
5ee91343
AV
21913 int cond, is_last;
21914 if (now_pred.type == SCALAR_PRED)
e07e6e58 21915 {
5ee91343
AV
21916 /* Check conditional suffixes. */
21917 cond = now_pred.cc ^ ((now_pred.mask >> 4) & 1) ^ 1;
21918 now_pred.mask <<= 1;
21919 now_pred.mask &= 0x1f;
21920 is_last = (now_pred.mask == 0x10);
21921 }
21922 else
21923 {
21924 now_pred.cc ^= (now_pred.mask >> 4);
21925 cond = now_pred.cc + 0xf;
21926 now_pred.mask <<= 1;
21927 now_pred.mask &= 0x1f;
21928 is_last = now_pred.mask == 0x10;
21929 }
21930 now_pred.insn_cond = TRUE;
e07e6e58 21931
5ee91343
AV
21932 switch (inst.pred_insn_type)
21933 {
21934 case OUTSIDE_PRED_INSN:
21935 if (now_pred.type == SCALAR_PRED)
21936 {
21937 if (inst.cond == COND_ALWAYS)
21938 {
21939 /* Case 12: In an IT block, with no code: error: missing
21940 code. */
21941 inst.error = BAD_NOT_IT;
21942 return FAIL;
21943 }
21944 else if (inst.cond > COND_ALWAYS)
21945 {
21946 /* Case 11: In an IT block, with a VPT code: syntax error.
21947 */
21948 inst.error = BAD_SYNTAX;
21949 return FAIL;
21950 }
21951 else if (thumb_mode)
21952 {
21953 /* This is for some special cases where a non-MVE
21954 instruction is not allowed in an IT block, such as cbz,
21955 but are put into one with a condition code.
21956 You could argue this should be a syntax error, but we
21957 gave the 'not allowed in IT block' diagnostic in the
21958 past so we will keep doing so. */
21959 inst.error = BAD_NOT_IT;
21960 return FAIL;
21961 }
21962 break;
21963 }
21964 else
21965 {
21966 /* Case 15: In a VPT block, with no code: UNPREDICTABLE. */
21967 as_tsktsk (MVE_NOT_VPT);
21968 return SUCCESS;
21969 }
21970 case MVE_OUTSIDE_PRED_INSN:
21971 if (now_pred.type == SCALAR_PRED)
21972 {
21973 if (inst.cond == COND_ALWAYS)
21974 {
21975 /* Case 3: In an IT block, with no code: warning:
21976 UNPREDICTABLE. */
21977 as_tsktsk (MVE_NOT_IT);
21978 return SUCCESS;
21979 }
21980 else if (inst.cond < COND_ALWAYS)
21981 {
21982 /* Case 1: In an IT block, with an IT code: syntax error.
21983 */
21984 inst.error = BAD_SYNTAX;
21985 return FAIL;
21986 }
21987 else
21988 gas_assert (0);
21989 }
21990 else
21991 {
21992 if (inst.cond < COND_ALWAYS)
21993 {
21994 /* Case 4: In a VPT block, with an IT code: syntax error.
21995 */
21996 inst.error = BAD_SYNTAX;
21997 return FAIL;
21998 }
21999 else if (inst.cond == COND_ALWAYS)
22000 {
22001 /* Case 6: In a VPT block, with no code: error: missing
22002 code. */
22003 inst.error = BAD_NOT_VPT;
22004 return FAIL;
22005 }
22006 else
22007 {
22008 gas_assert (0);
22009 }
22010 }
35c228db
AV
22011 case MVE_UNPREDICABLE_INSN:
22012 as_tsktsk (now_pred.type == SCALAR_PRED ? MVE_NOT_IT : MVE_NOT_VPT);
22013 return SUCCESS;
e07e6e58 22014 case INSIDE_IT_INSN:
5ee91343 22015 if (inst.cond > COND_ALWAYS)
e07e6e58 22016 {
5ee91343
AV
22017 /* Case 11: In an IT block, with a VPT code: syntax error. */
22018 /* Case 14: In a VPT block, with a VPT code: syntax error. */
22019 inst.error = BAD_SYNTAX;
22020 return FAIL;
22021 }
22022 else if (now_pred.type == SCALAR_PRED)
22023 {
22024 /* Case 10: In an IT block, with an IT code: OK! */
22025 if (cond != inst.cond)
22026 {
22027 inst.error = now_pred.type == SCALAR_PRED ? BAD_IT_COND :
22028 BAD_VPT_COND;
22029 return FAIL;
22030 }
22031 }
22032 else
22033 {
22034 /* Case 13: In a VPT block, with an IT code: error: should be
22035 in an IT block. */
22036 inst.error = BAD_OUT_IT;
e07e6e58
NC
22037 return FAIL;
22038 }
22039 break;
22040
5ee91343
AV
22041 case INSIDE_VPT_INSN:
22042 if (now_pred.type == SCALAR_PRED)
22043 {
22044 /* Case 2: In an IT block, with a VPT code: error: must be in a
22045 VPT block. */
22046 inst.error = BAD_OUT_VPT;
22047 return FAIL;
22048 }
22049 /* Case 5: In a VPT block, with a VPT code: OK! */
22050 else if (cond != inst.cond)
22051 {
22052 inst.error = BAD_VPT_COND;
22053 return FAIL;
22054 }
22055 break;
e07e6e58
NC
22056 case INSIDE_IT_LAST_INSN:
22057 case IF_INSIDE_IT_LAST_INSN:
5ee91343
AV
22058 if (now_pred.type == VECTOR_PRED || inst.cond > COND_ALWAYS)
22059 {
22060 /* Case 4: In a VPT block, with an IT code: syntax error. */
22061 /* Case 11: In an IT block, with a VPT code: syntax error. */
22062 inst.error = BAD_SYNTAX;
22063 return FAIL;
22064 }
22065 else if (cond != inst.cond)
e07e6e58
NC
22066 {
22067 inst.error = BAD_IT_COND;
22068 return FAIL;
22069 }
22070 if (!is_last)
22071 {
22072 inst.error = BAD_BRANCH;
22073 return FAIL;
22074 }
22075 break;
22076
22077 case NEUTRAL_IT_INSN:
5ee91343
AV
22078 /* The BKPT instruction is unconditional even in a IT or VPT
22079 block. */
e07e6e58
NC
22080 break;
22081
22082 case IT_INSN:
5ee91343
AV
22083 if (now_pred.type == SCALAR_PRED)
22084 {
22085 inst.error = BAD_IT_IT;
22086 return FAIL;
22087 }
22088 /* fall through. */
22089 case VPT_INSN:
22090 if (inst.cond == COND_ALWAYS)
22091 {
22092 /* Executing a VPT/VPST instruction inside an IT block or a
22093 VPT/VPST/IT instruction inside a VPT block is UNPREDICTABLE.
22094 */
22095 if (now_pred.type == SCALAR_PRED)
22096 as_tsktsk (MVE_NOT_IT);
22097 else
22098 as_tsktsk (MVE_NOT_VPT);
22099 return SUCCESS;
22100 }
22101 else
22102 {
22103 /* VPT/VPST do not accept condition codes. */
22104 inst.error = BAD_SYNTAX;
22105 return FAIL;
22106 }
e07e6e58 22107 }
5ee91343 22108 }
e07e6e58
NC
22109 break;
22110 }
22111
22112 return SUCCESS;
22113}
22114
5a01bb1d
MGD
22115struct depr_insn_mask
22116{
22117 unsigned long pattern;
22118 unsigned long mask;
22119 const char* description;
22120};
22121
22122/* List of 16-bit instruction patterns deprecated in an IT block in
22123 ARMv8. */
22124static const struct depr_insn_mask depr_it_insns[] = {
22125 { 0xc000, 0xc000, N_("Short branches, Undefined, SVC, LDM/STM") },
22126 { 0xb000, 0xb000, N_("Miscellaneous 16-bit instructions") },
22127 { 0xa000, 0xb800, N_("ADR") },
22128 { 0x4800, 0xf800, N_("Literal loads") },
22129 { 0x4478, 0xf478, N_("Hi-register ADD, MOV, CMP, BX, BLX using pc") },
22130 { 0x4487, 0xfc87, N_("Hi-register ADD, MOV, CMP using pc") },
c8de034b
JW
22131 /* NOTE: 0x00dd is not the real encoding, instead, it is the 'tvalue'
22132 field in asm_opcode. 'tvalue' is used at the stage this check happen. */
22133 { 0x00dd, 0x7fff, N_("ADD/SUB sp, sp #imm") },
5a01bb1d
MGD
22134 { 0, 0, NULL }
22135};
22136
e07e6e58
NC
22137static void
22138it_fsm_post_encode (void)
22139{
22140 int is_last;
22141
5ee91343
AV
22142 if (!now_pred.state_handled)
22143 handle_pred_state ();
e07e6e58 22144
5ee91343
AV
22145 if (now_pred.insn_cond
22146 && !now_pred.warn_deprecated
5a01bb1d 22147 && warn_on_deprecated
df9909b8
TP
22148 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)
22149 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_m))
5a01bb1d
MGD
22150 {
22151 if (inst.instruction >= 0x10000)
22152 {
5c3696f8 22153 as_tsktsk (_("IT blocks containing 32-bit Thumb instructions are "
df9909b8 22154 "performance deprecated in ARMv8-A and ARMv8-R"));
5ee91343 22155 now_pred.warn_deprecated = TRUE;
5a01bb1d
MGD
22156 }
22157 else
22158 {
22159 const struct depr_insn_mask *p = depr_it_insns;
22160
22161 while (p->mask != 0)
22162 {
22163 if ((inst.instruction & p->mask) == p->pattern)
22164 {
df9909b8
TP
22165 as_tsktsk (_("IT blocks containing 16-bit Thumb "
22166 "instructions of the following class are "
22167 "performance deprecated in ARMv8-A and "
22168 "ARMv8-R: %s"), p->description);
5ee91343 22169 now_pred.warn_deprecated = TRUE;
5a01bb1d
MGD
22170 break;
22171 }
22172
22173 ++p;
22174 }
22175 }
22176
5ee91343 22177 if (now_pred.block_length > 1)
5a01bb1d 22178 {
5c3696f8 22179 as_tsktsk (_("IT blocks containing more than one conditional "
df9909b8
TP
22180 "instruction are performance deprecated in ARMv8-A and "
22181 "ARMv8-R"));
5ee91343 22182 now_pred.warn_deprecated = TRUE;
5a01bb1d
MGD
22183 }
22184 }
22185
5ee91343
AV
22186 is_last = (now_pred.mask == 0x10);
22187 if (is_last)
22188 {
22189 now_pred.state = OUTSIDE_PRED_BLOCK;
22190 now_pred.mask = 0;
22191 }
e07e6e58
NC
22192}
22193
22194static void
22195force_automatic_it_block_close (void)
22196{
5ee91343 22197 if (now_pred.state == AUTOMATIC_PRED_BLOCK)
e07e6e58
NC
22198 {
22199 close_automatic_it_block ();
5ee91343
AV
22200 now_pred.state = OUTSIDE_PRED_BLOCK;
22201 now_pred.mask = 0;
e07e6e58
NC
22202 }
22203}
22204
22205static int
5ee91343 22206in_pred_block (void)
e07e6e58 22207{
5ee91343
AV
22208 if (!now_pred.state_handled)
22209 handle_pred_state ();
e07e6e58 22210
5ee91343 22211 return now_pred.state != OUTSIDE_PRED_BLOCK;
e07e6e58
NC
22212}
22213
ff8646ee
TP
22214/* Whether OPCODE only has T32 encoding. Since this function is only used by
22215 t32_insn_ok, OPCODE enabled by v6t2 extension bit do not need to be listed
22216 here, hence the "known" in the function name. */
fc289b0a
TP
22217
22218static bfd_boolean
ff8646ee 22219known_t32_only_insn (const struct asm_opcode *opcode)
fc289b0a
TP
22220{
22221 /* Original Thumb-1 wide instruction. */
22222 if (opcode->tencode == do_t_blx
22223 || opcode->tencode == do_t_branch23
22224 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_msr)
22225 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_barrier))
22226 return TRUE;
22227
16a1fa25
TP
22228 /* Wide-only instruction added to ARMv8-M Baseline. */
22229 if (ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v8m_m_only)
ff8646ee
TP
22230 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_atomics)
22231 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v6t2_v8m)
22232 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_div))
22233 return TRUE;
22234
22235 return FALSE;
22236}
22237
22238/* Whether wide instruction variant can be used if available for a valid OPCODE
22239 in ARCH. */
22240
22241static bfd_boolean
22242t32_insn_ok (arm_feature_set arch, const struct asm_opcode *opcode)
22243{
22244 if (known_t32_only_insn (opcode))
22245 return TRUE;
22246
22247 /* Instruction with narrow and wide encoding added to ARMv8-M. Availability
22248 of variant T3 of B.W is checked in do_t_branch. */
22249 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
22250 && opcode->tencode == do_t_branch)
22251 return TRUE;
22252
bada4342
JW
22253 /* MOV accepts T1/T3 encodings under Baseline, T3 encoding is 32bit. */
22254 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
22255 && opcode->tencode == do_t_mov_cmp
22256 /* Make sure CMP instruction is not affected. */
22257 && opcode->aencode == do_mov)
22258 return TRUE;
22259
ff8646ee
TP
22260 /* Wide instruction variants of all instructions with narrow *and* wide
22261 variants become available with ARMv6t2. Other opcodes are either
22262 narrow-only or wide-only and are thus available if OPCODE is valid. */
22263 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v6t2))
22264 return TRUE;
22265
22266 /* OPCODE with narrow only instruction variant or wide variant not
22267 available. */
fc289b0a
TP
22268 return FALSE;
22269}
22270
c19d1205
ZW
22271void
22272md_assemble (char *str)
b99bd4ef 22273{
c19d1205
ZW
22274 char *p = str;
22275 const struct asm_opcode * opcode;
b99bd4ef 22276
c19d1205
ZW
22277 /* Align the previous label if needed. */
22278 if (last_label_seen != NULL)
b99bd4ef 22279 {
c19d1205
ZW
22280 symbol_set_frag (last_label_seen, frag_now);
22281 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
22282 S_SET_SEGMENT (last_label_seen, now_seg);
b99bd4ef
NC
22283 }
22284
c19d1205 22285 memset (&inst, '\0', sizeof (inst));
e2b0ab59
AV
22286 int r;
22287 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
22288 inst.relocs[r].type = BFD_RELOC_UNUSED;
b99bd4ef 22289
c19d1205
ZW
22290 opcode = opcode_lookup (&p);
22291 if (!opcode)
b99bd4ef 22292 {
c19d1205 22293 /* It wasn't an instruction, but it might be a register alias of
dcbf9037 22294 the form alias .req reg, or a Neon .dn/.qn directive. */
c921be7d 22295 if (! create_register_alias (str, p)
477330fc 22296 && ! create_neon_reg_alias (str, p))
c19d1205 22297 as_bad (_("bad instruction `%s'"), str);
b99bd4ef 22298
b99bd4ef
NC
22299 return;
22300 }
22301
278df34e 22302 if (warn_on_deprecated && opcode->tag == OT_cinfix3_deprecated)
5c3696f8 22303 as_tsktsk (_("s suffix on comparison instruction is deprecated"));
088fa78e 22304
037e8744
JB
22305 /* The value which unconditional instructions should have in place of the
22306 condition field. */
22307 inst.uncond_value = (opcode->tag == OT_csuffixF) ? 0xf : -1;
22308
c19d1205 22309 if (thumb_mode)
b99bd4ef 22310 {
e74cfd16 22311 arm_feature_set variant;
8f06b2d8
PB
22312
22313 variant = cpu_variant;
22314 /* Only allow coprocessor instructions on Thumb-2 capable devices. */
e74cfd16
PB
22315 if (!ARM_CPU_HAS_FEATURE (variant, arm_arch_t2))
22316 ARM_CLEAR_FEATURE (variant, variant, fpu_any_hard);
c19d1205 22317 /* Check that this instruction is supported for this CPU. */
62b3e311
PB
22318 if (!opcode->tvariant
22319 || (thumb_mode == 1
22320 && !ARM_CPU_HAS_FEATURE (variant, *opcode->tvariant)))
b99bd4ef 22321 {
173205ca
TP
22322 if (opcode->tencode == do_t_swi)
22323 as_bad (_("SVC is not permitted on this architecture"));
22324 else
22325 as_bad (_("selected processor does not support `%s' in Thumb mode"), str);
b99bd4ef
NC
22326 return;
22327 }
c19d1205
ZW
22328 if (inst.cond != COND_ALWAYS && !unified_syntax
22329 && opcode->tencode != do_t_branch)
b99bd4ef 22330 {
c19d1205 22331 as_bad (_("Thumb does not support conditional execution"));
b99bd4ef
NC
22332 return;
22333 }
22334
fc289b0a
TP
22335 /* Two things are addressed here:
22336 1) Implicit require narrow instructions on Thumb-1.
22337 This avoids relaxation accidentally introducing Thumb-2
22338 instructions.
22339 2) Reject wide instructions in non Thumb-2 cores.
22340
22341 Only instructions with narrow and wide variants need to be handled
22342 but selecting all non wide-only instructions is easier. */
22343 if (!ARM_CPU_HAS_FEATURE (variant, arm_ext_v6t2)
ff8646ee 22344 && !t32_insn_ok (variant, opcode))
076d447c 22345 {
fc289b0a
TP
22346 if (inst.size_req == 0)
22347 inst.size_req = 2;
22348 else if (inst.size_req == 4)
752d5da4 22349 {
ff8646ee
TP
22350 if (ARM_CPU_HAS_FEATURE (variant, arm_ext_v8m))
22351 as_bad (_("selected processor does not support 32bit wide "
22352 "variant of instruction `%s'"), str);
22353 else
22354 as_bad (_("selected processor does not support `%s' in "
22355 "Thumb-2 mode"), str);
fc289b0a 22356 return;
752d5da4 22357 }
076d447c
PB
22358 }
22359
c19d1205
ZW
22360 inst.instruction = opcode->tvalue;
22361
5be8be5d 22362 if (!parse_operands (p, opcode->operands, /*thumb=*/TRUE))
477330fc 22363 {
5ee91343 22364 /* Prepare the pred_insn_type for those encodings that don't set
477330fc
RM
22365 it. */
22366 it_fsm_pre_encode ();
c19d1205 22367
477330fc 22368 opcode->tencode ();
e07e6e58 22369
477330fc
RM
22370 it_fsm_post_encode ();
22371 }
e27ec89e 22372
0110f2b8 22373 if (!(inst.error || inst.relax))
b99bd4ef 22374 {
9c2799c2 22375 gas_assert (inst.instruction < 0xe800 || inst.instruction > 0xffff);
c19d1205
ZW
22376 inst.size = (inst.instruction > 0xffff ? 4 : 2);
22377 if (inst.size_req && inst.size_req != inst.size)
b99bd4ef 22378 {
c19d1205 22379 as_bad (_("cannot honor width suffix -- `%s'"), str);
b99bd4ef
NC
22380 return;
22381 }
22382 }
076d447c
PB
22383
22384 /* Something has gone badly wrong if we try to relax a fixed size
477330fc 22385 instruction. */
9c2799c2 22386 gas_assert (inst.size_req == 0 || !inst.relax);
076d447c 22387
e74cfd16
PB
22388 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
22389 *opcode->tvariant);
ee065d83 22390 /* Many Thumb-2 instructions also have Thumb-1 variants, so explicitly
fc289b0a
TP
22391 set those bits when Thumb-2 32-bit instructions are seen. The impact
22392 of relaxable instructions will be considered later after we finish all
22393 relaxation. */
ff8646ee
TP
22394 if (ARM_FEATURE_CORE_EQUAL (cpu_variant, arm_arch_any))
22395 variant = arm_arch_none;
22396 else
22397 variant = cpu_variant;
22398 if (inst.size == 4 && !t32_insn_ok (variant, opcode))
e74cfd16
PB
22399 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
22400 arm_ext_v6t2);
cd000bff 22401
88714cb8
DG
22402 check_neon_suffixes;
22403
cd000bff 22404 if (!inst.error)
c877a2f2
NC
22405 {
22406 mapping_state (MAP_THUMB);
22407 }
c19d1205 22408 }
3e9e4fcf 22409 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
c19d1205 22410 {
845b51d6
PB
22411 bfd_boolean is_bx;
22412
22413 /* bx is allowed on v5 cores, and sometimes on v4 cores. */
22414 is_bx = (opcode->aencode == do_bx);
22415
c19d1205 22416 /* Check that this instruction is supported for this CPU. */
845b51d6
PB
22417 if (!(is_bx && fix_v4bx)
22418 && !(opcode->avariant &&
22419 ARM_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant)))
b99bd4ef 22420 {
84b52b66 22421 as_bad (_("selected processor does not support `%s' in ARM mode"), str);
c19d1205 22422 return;
b99bd4ef 22423 }
c19d1205 22424 if (inst.size_req)
b99bd4ef 22425 {
c19d1205
ZW
22426 as_bad (_("width suffixes are invalid in ARM mode -- `%s'"), str);
22427 return;
b99bd4ef
NC
22428 }
22429
c19d1205
ZW
22430 inst.instruction = opcode->avalue;
22431 if (opcode->tag == OT_unconditionalF)
eff0bc54 22432 inst.instruction |= 0xFU << 28;
c19d1205
ZW
22433 else
22434 inst.instruction |= inst.cond << 28;
22435 inst.size = INSN_SIZE;
5be8be5d 22436 if (!parse_operands (p, opcode->operands, /*thumb=*/FALSE))
477330fc
RM
22437 {
22438 it_fsm_pre_encode ();
22439 opcode->aencode ();
22440 it_fsm_post_encode ();
22441 }
ee065d83 22442 /* Arm mode bx is marked as both v4T and v5 because it's still required
477330fc 22443 on a hypothetical non-thumb v5 core. */
845b51d6 22444 if (is_bx)
e74cfd16 22445 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, arm_ext_v4t);
ee065d83 22446 else
e74cfd16
PB
22447 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
22448 *opcode->avariant);
88714cb8
DG
22449
22450 check_neon_suffixes;
22451
cd000bff 22452 if (!inst.error)
c877a2f2
NC
22453 {
22454 mapping_state (MAP_ARM);
22455 }
b99bd4ef 22456 }
3e9e4fcf
JB
22457 else
22458 {
22459 as_bad (_("attempt to use an ARM instruction on a Thumb-only processor "
22460 "-- `%s'"), str);
22461 return;
22462 }
c19d1205
ZW
22463 output_inst (str);
22464}
b99bd4ef 22465
e07e6e58 22466static void
5ee91343 22467check_pred_blocks_finished (void)
e07e6e58
NC
22468{
22469#ifdef OBJ_ELF
22470 asection *sect;
22471
22472 for (sect = stdoutput->sections; sect != NULL; sect = sect->next)
5ee91343
AV
22473 if (seg_info (sect)->tc_segment_info_data.current_pred.state
22474 == MANUAL_PRED_BLOCK)
e07e6e58 22475 {
5ee91343
AV
22476 if (now_pred.type == SCALAR_PRED)
22477 as_warn (_("section '%s' finished with an open IT block."),
22478 sect->name);
22479 else
22480 as_warn (_("section '%s' finished with an open VPT/VPST block."),
22481 sect->name);
e07e6e58
NC
22482 }
22483#else
5ee91343
AV
22484 if (now_pred.state == MANUAL_PRED_BLOCK)
22485 {
22486 if (now_pred.type == SCALAR_PRED)
22487 as_warn (_("file finished with an open IT block."));
22488 else
22489 as_warn (_("file finished with an open VPT/VPST block."));
22490 }
e07e6e58
NC
22491#endif
22492}
22493
c19d1205
ZW
22494/* Various frobbings of labels and their addresses. */
22495
22496void
22497arm_start_line_hook (void)
22498{
22499 last_label_seen = NULL;
b99bd4ef
NC
22500}
22501
c19d1205
ZW
22502void
22503arm_frob_label (symbolS * sym)
b99bd4ef 22504{
c19d1205 22505 last_label_seen = sym;
b99bd4ef 22506
c19d1205 22507 ARM_SET_THUMB (sym, thumb_mode);
b99bd4ef 22508
c19d1205
ZW
22509#if defined OBJ_COFF || defined OBJ_ELF
22510 ARM_SET_INTERWORK (sym, support_interwork);
22511#endif
b99bd4ef 22512
e07e6e58
NC
22513 force_automatic_it_block_close ();
22514
5f4273c7 22515 /* Note - do not allow local symbols (.Lxxx) to be labelled
c19d1205
ZW
22516 as Thumb functions. This is because these labels, whilst
22517 they exist inside Thumb code, are not the entry points for
22518 possible ARM->Thumb calls. Also, these labels can be used
22519 as part of a computed goto or switch statement. eg gcc
22520 can generate code that looks like this:
b99bd4ef 22521
c19d1205
ZW
22522 ldr r2, [pc, .Laaa]
22523 lsl r3, r3, #2
22524 ldr r2, [r3, r2]
22525 mov pc, r2
b99bd4ef 22526
c19d1205
ZW
22527 .Lbbb: .word .Lxxx
22528 .Lccc: .word .Lyyy
22529 ..etc...
22530 .Laaa: .word Lbbb
b99bd4ef 22531
c19d1205
ZW
22532 The first instruction loads the address of the jump table.
22533 The second instruction converts a table index into a byte offset.
22534 The third instruction gets the jump address out of the table.
22535 The fourth instruction performs the jump.
b99bd4ef 22536
c19d1205
ZW
22537 If the address stored at .Laaa is that of a symbol which has the
22538 Thumb_Func bit set, then the linker will arrange for this address
22539 to have the bottom bit set, which in turn would mean that the
22540 address computation performed by the third instruction would end
22541 up with the bottom bit set. Since the ARM is capable of unaligned
22542 word loads, the instruction would then load the incorrect address
22543 out of the jump table, and chaos would ensue. */
22544 if (label_is_thumb_function_name
22545 && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
22546 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
b99bd4ef 22547 {
c19d1205
ZW
22548 /* When the address of a Thumb function is taken the bottom
22549 bit of that address should be set. This will allow
22550 interworking between Arm and Thumb functions to work
22551 correctly. */
b99bd4ef 22552
c19d1205 22553 THUMB_SET_FUNC (sym, 1);
b99bd4ef 22554
c19d1205 22555 label_is_thumb_function_name = FALSE;
b99bd4ef 22556 }
07a53e5c 22557
07a53e5c 22558 dwarf2_emit_label (sym);
b99bd4ef
NC
22559}
22560
c921be7d 22561bfd_boolean
c19d1205 22562arm_data_in_code (void)
b99bd4ef 22563{
c19d1205 22564 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
b99bd4ef 22565 {
c19d1205
ZW
22566 *input_line_pointer = '/';
22567 input_line_pointer += 5;
22568 *input_line_pointer = 0;
c921be7d 22569 return TRUE;
b99bd4ef
NC
22570 }
22571
c921be7d 22572 return FALSE;
b99bd4ef
NC
22573}
22574
c19d1205
ZW
22575char *
22576arm_canonicalize_symbol_name (char * name)
b99bd4ef 22577{
c19d1205 22578 int len;
b99bd4ef 22579
c19d1205
ZW
22580 if (thumb_mode && (len = strlen (name)) > 5
22581 && streq (name + len - 5, "/data"))
22582 *(name + len - 5) = 0;
b99bd4ef 22583
c19d1205 22584 return name;
b99bd4ef 22585}
c19d1205
ZW
22586\f
22587/* Table of all register names defined by default. The user can
22588 define additional names with .req. Note that all register names
22589 should appear in both upper and lowercase variants. Some registers
22590 also have mixed-case names. */
b99bd4ef 22591
dcbf9037 22592#define REGDEF(s,n,t) { #s, n, REG_TYPE_##t, TRUE, 0 }
c19d1205 22593#define REGNUM(p,n,t) REGDEF(p##n, n, t)
5287ad62 22594#define REGNUM2(p,n,t) REGDEF(p##n, 2 * n, t)
c19d1205
ZW
22595#define REGSET(p,t) \
22596 REGNUM(p, 0,t), REGNUM(p, 1,t), REGNUM(p, 2,t), REGNUM(p, 3,t), \
22597 REGNUM(p, 4,t), REGNUM(p, 5,t), REGNUM(p, 6,t), REGNUM(p, 7,t), \
22598 REGNUM(p, 8,t), REGNUM(p, 9,t), REGNUM(p,10,t), REGNUM(p,11,t), \
22599 REGNUM(p,12,t), REGNUM(p,13,t), REGNUM(p,14,t), REGNUM(p,15,t)
5287ad62
JB
22600#define REGSETH(p,t) \
22601 REGNUM(p,16,t), REGNUM(p,17,t), REGNUM(p,18,t), REGNUM(p,19,t), \
22602 REGNUM(p,20,t), REGNUM(p,21,t), REGNUM(p,22,t), REGNUM(p,23,t), \
22603 REGNUM(p,24,t), REGNUM(p,25,t), REGNUM(p,26,t), REGNUM(p,27,t), \
22604 REGNUM(p,28,t), REGNUM(p,29,t), REGNUM(p,30,t), REGNUM(p,31,t)
22605#define REGSET2(p,t) \
22606 REGNUM2(p, 0,t), REGNUM2(p, 1,t), REGNUM2(p, 2,t), REGNUM2(p, 3,t), \
22607 REGNUM2(p, 4,t), REGNUM2(p, 5,t), REGNUM2(p, 6,t), REGNUM2(p, 7,t), \
22608 REGNUM2(p, 8,t), REGNUM2(p, 9,t), REGNUM2(p,10,t), REGNUM2(p,11,t), \
22609 REGNUM2(p,12,t), REGNUM2(p,13,t), REGNUM2(p,14,t), REGNUM2(p,15,t)
90ec0d68
MGD
22610#define SPLRBANK(base,bank,t) \
22611 REGDEF(lr_##bank, 768|((base+0)<<16), t), \
22612 REGDEF(sp_##bank, 768|((base+1)<<16), t), \
22613 REGDEF(spsr_##bank, 768|(base<<16)|SPSR_BIT, t), \
22614 REGDEF(LR_##bank, 768|((base+0)<<16), t), \
22615 REGDEF(SP_##bank, 768|((base+1)<<16), t), \
22616 REGDEF(SPSR_##bank, 768|(base<<16)|SPSR_BIT, t)
7ed4c4c5 22617
c19d1205 22618static const struct reg_entry reg_names[] =
7ed4c4c5 22619{
c19d1205
ZW
22620 /* ARM integer registers. */
22621 REGSET(r, RN), REGSET(R, RN),
7ed4c4c5 22622
c19d1205
ZW
22623 /* ATPCS synonyms. */
22624 REGDEF(a1,0,RN), REGDEF(a2,1,RN), REGDEF(a3, 2,RN), REGDEF(a4, 3,RN),
22625 REGDEF(v1,4,RN), REGDEF(v2,5,RN), REGDEF(v3, 6,RN), REGDEF(v4, 7,RN),
22626 REGDEF(v5,8,RN), REGDEF(v6,9,RN), REGDEF(v7,10,RN), REGDEF(v8,11,RN),
7ed4c4c5 22627
c19d1205
ZW
22628 REGDEF(A1,0,RN), REGDEF(A2,1,RN), REGDEF(A3, 2,RN), REGDEF(A4, 3,RN),
22629 REGDEF(V1,4,RN), REGDEF(V2,5,RN), REGDEF(V3, 6,RN), REGDEF(V4, 7,RN),
22630 REGDEF(V5,8,RN), REGDEF(V6,9,RN), REGDEF(V7,10,RN), REGDEF(V8,11,RN),
7ed4c4c5 22631
c19d1205
ZW
22632 /* Well-known aliases. */
22633 REGDEF(wr, 7,RN), REGDEF(sb, 9,RN), REGDEF(sl,10,RN), REGDEF(fp,11,RN),
22634 REGDEF(ip,12,RN), REGDEF(sp,13,RN), REGDEF(lr,14,RN), REGDEF(pc,15,RN),
22635
22636 REGDEF(WR, 7,RN), REGDEF(SB, 9,RN), REGDEF(SL,10,RN), REGDEF(FP,11,RN),
22637 REGDEF(IP,12,RN), REGDEF(SP,13,RN), REGDEF(LR,14,RN), REGDEF(PC,15,RN),
22638
1b883319
AV
22639 /* Defining the new Zero register from ARMv8.1-M. */
22640 REGDEF(zr,15,ZR),
22641 REGDEF(ZR,15,ZR),
22642
c19d1205
ZW
22643 /* Coprocessor numbers. */
22644 REGSET(p, CP), REGSET(P, CP),
22645
22646 /* Coprocessor register numbers. The "cr" variants are for backward
22647 compatibility. */
22648 REGSET(c, CN), REGSET(C, CN),
22649 REGSET(cr, CN), REGSET(CR, CN),
22650
90ec0d68
MGD
22651 /* ARM banked registers. */
22652 REGDEF(R8_usr,512|(0<<16),RNB), REGDEF(r8_usr,512|(0<<16),RNB),
22653 REGDEF(R9_usr,512|(1<<16),RNB), REGDEF(r9_usr,512|(1<<16),RNB),
22654 REGDEF(R10_usr,512|(2<<16),RNB), REGDEF(r10_usr,512|(2<<16),RNB),
22655 REGDEF(R11_usr,512|(3<<16),RNB), REGDEF(r11_usr,512|(3<<16),RNB),
22656 REGDEF(R12_usr,512|(4<<16),RNB), REGDEF(r12_usr,512|(4<<16),RNB),
22657 REGDEF(SP_usr,512|(5<<16),RNB), REGDEF(sp_usr,512|(5<<16),RNB),
22658 REGDEF(LR_usr,512|(6<<16),RNB), REGDEF(lr_usr,512|(6<<16),RNB),
22659
22660 REGDEF(R8_fiq,512|(8<<16),RNB), REGDEF(r8_fiq,512|(8<<16),RNB),
22661 REGDEF(R9_fiq,512|(9<<16),RNB), REGDEF(r9_fiq,512|(9<<16),RNB),
22662 REGDEF(R10_fiq,512|(10<<16),RNB), REGDEF(r10_fiq,512|(10<<16),RNB),
22663 REGDEF(R11_fiq,512|(11<<16),RNB), REGDEF(r11_fiq,512|(11<<16),RNB),
22664 REGDEF(R12_fiq,512|(12<<16),RNB), REGDEF(r12_fiq,512|(12<<16),RNB),
1472d06f 22665 REGDEF(SP_fiq,512|(13<<16),RNB), REGDEF(sp_fiq,512|(13<<16),RNB),
90ec0d68
MGD
22666 REGDEF(LR_fiq,512|(14<<16),RNB), REGDEF(lr_fiq,512|(14<<16),RNB),
22667 REGDEF(SPSR_fiq,512|(14<<16)|SPSR_BIT,RNB), REGDEF(spsr_fiq,512|(14<<16)|SPSR_BIT,RNB),
22668
22669 SPLRBANK(0,IRQ,RNB), SPLRBANK(0,irq,RNB),
22670 SPLRBANK(2,SVC,RNB), SPLRBANK(2,svc,RNB),
22671 SPLRBANK(4,ABT,RNB), SPLRBANK(4,abt,RNB),
22672 SPLRBANK(6,UND,RNB), SPLRBANK(6,und,RNB),
22673 SPLRBANK(12,MON,RNB), SPLRBANK(12,mon,RNB),
22674 REGDEF(elr_hyp,768|(14<<16),RNB), REGDEF(ELR_hyp,768|(14<<16),RNB),
22675 REGDEF(sp_hyp,768|(15<<16),RNB), REGDEF(SP_hyp,768|(15<<16),RNB),
fa94de6b 22676 REGDEF(spsr_hyp,768|(14<<16)|SPSR_BIT,RNB),
90ec0d68
MGD
22677 REGDEF(SPSR_hyp,768|(14<<16)|SPSR_BIT,RNB),
22678
c19d1205
ZW
22679 /* FPA registers. */
22680 REGNUM(f,0,FN), REGNUM(f,1,FN), REGNUM(f,2,FN), REGNUM(f,3,FN),
22681 REGNUM(f,4,FN), REGNUM(f,5,FN), REGNUM(f,6,FN), REGNUM(f,7, FN),
22682
22683 REGNUM(F,0,FN), REGNUM(F,1,FN), REGNUM(F,2,FN), REGNUM(F,3,FN),
22684 REGNUM(F,4,FN), REGNUM(F,5,FN), REGNUM(F,6,FN), REGNUM(F,7, FN),
22685
22686 /* VFP SP registers. */
5287ad62
JB
22687 REGSET(s,VFS), REGSET(S,VFS),
22688 REGSETH(s,VFS), REGSETH(S,VFS),
c19d1205
ZW
22689
22690 /* VFP DP Registers. */
5287ad62
JB
22691 REGSET(d,VFD), REGSET(D,VFD),
22692 /* Extra Neon DP registers. */
22693 REGSETH(d,VFD), REGSETH(D,VFD),
22694
22695 /* Neon QP registers. */
22696 REGSET2(q,NQ), REGSET2(Q,NQ),
c19d1205
ZW
22697
22698 /* VFP control registers. */
22699 REGDEF(fpsid,0,VFC), REGDEF(fpscr,1,VFC), REGDEF(fpexc,8,VFC),
22700 REGDEF(FPSID,0,VFC), REGDEF(FPSCR,1,VFC), REGDEF(FPEXC,8,VFC),
cd2cf30b
PB
22701 REGDEF(fpinst,9,VFC), REGDEF(fpinst2,10,VFC),
22702 REGDEF(FPINST,9,VFC), REGDEF(FPINST2,10,VFC),
22703 REGDEF(mvfr0,7,VFC), REGDEF(mvfr1,6,VFC),
22704 REGDEF(MVFR0,7,VFC), REGDEF(MVFR1,6,VFC),
40c7d507 22705 REGDEF(mvfr2,5,VFC), REGDEF(MVFR2,5,VFC),
c19d1205
ZW
22706
22707 /* Maverick DSP coprocessor registers. */
22708 REGSET(mvf,MVF), REGSET(mvd,MVD), REGSET(mvfx,MVFX), REGSET(mvdx,MVDX),
22709 REGSET(MVF,MVF), REGSET(MVD,MVD), REGSET(MVFX,MVFX), REGSET(MVDX,MVDX),
22710
22711 REGNUM(mvax,0,MVAX), REGNUM(mvax,1,MVAX),
22712 REGNUM(mvax,2,MVAX), REGNUM(mvax,3,MVAX),
22713 REGDEF(dspsc,0,DSPSC),
22714
22715 REGNUM(MVAX,0,MVAX), REGNUM(MVAX,1,MVAX),
22716 REGNUM(MVAX,2,MVAX), REGNUM(MVAX,3,MVAX),
22717 REGDEF(DSPSC,0,DSPSC),
22718
22719 /* iWMMXt data registers - p0, c0-15. */
22720 REGSET(wr,MMXWR), REGSET(wR,MMXWR), REGSET(WR, MMXWR),
22721
22722 /* iWMMXt control registers - p1, c0-3. */
22723 REGDEF(wcid, 0,MMXWC), REGDEF(wCID, 0,MMXWC), REGDEF(WCID, 0,MMXWC),
22724 REGDEF(wcon, 1,MMXWC), REGDEF(wCon, 1,MMXWC), REGDEF(WCON, 1,MMXWC),
22725 REGDEF(wcssf, 2,MMXWC), REGDEF(wCSSF, 2,MMXWC), REGDEF(WCSSF, 2,MMXWC),
22726 REGDEF(wcasf, 3,MMXWC), REGDEF(wCASF, 3,MMXWC), REGDEF(WCASF, 3,MMXWC),
22727
22728 /* iWMMXt scalar (constant/offset) registers - p1, c8-11. */
22729 REGDEF(wcgr0, 8,MMXWCG), REGDEF(wCGR0, 8,MMXWCG), REGDEF(WCGR0, 8,MMXWCG),
22730 REGDEF(wcgr1, 9,MMXWCG), REGDEF(wCGR1, 9,MMXWCG), REGDEF(WCGR1, 9,MMXWCG),
22731 REGDEF(wcgr2,10,MMXWCG), REGDEF(wCGR2,10,MMXWCG), REGDEF(WCGR2,10,MMXWCG),
22732 REGDEF(wcgr3,11,MMXWCG), REGDEF(wCGR3,11,MMXWCG), REGDEF(WCGR3,11,MMXWCG),
22733
22734 /* XScale accumulator registers. */
22735 REGNUM(acc,0,XSCALE), REGNUM(ACC,0,XSCALE),
22736};
22737#undef REGDEF
22738#undef REGNUM
22739#undef REGSET
7ed4c4c5 22740
c19d1205
ZW
22741/* Table of all PSR suffixes. Bare "CPSR" and "SPSR" are handled
22742 within psr_required_here. */
22743static const struct asm_psr psrs[] =
22744{
22745 /* Backward compatibility notation. Note that "all" is no longer
22746 truly all possible PSR bits. */
22747 {"all", PSR_c | PSR_f},
22748 {"flg", PSR_f},
22749 {"ctl", PSR_c},
22750
22751 /* Individual flags. */
22752 {"f", PSR_f},
22753 {"c", PSR_c},
22754 {"x", PSR_x},
22755 {"s", PSR_s},
59b42a0d 22756
c19d1205
ZW
22757 /* Combinations of flags. */
22758 {"fs", PSR_f | PSR_s},
22759 {"fx", PSR_f | PSR_x},
22760 {"fc", PSR_f | PSR_c},
22761 {"sf", PSR_s | PSR_f},
22762 {"sx", PSR_s | PSR_x},
22763 {"sc", PSR_s | PSR_c},
22764 {"xf", PSR_x | PSR_f},
22765 {"xs", PSR_x | PSR_s},
22766 {"xc", PSR_x | PSR_c},
22767 {"cf", PSR_c | PSR_f},
22768 {"cs", PSR_c | PSR_s},
22769 {"cx", PSR_c | PSR_x},
22770 {"fsx", PSR_f | PSR_s | PSR_x},
22771 {"fsc", PSR_f | PSR_s | PSR_c},
22772 {"fxs", PSR_f | PSR_x | PSR_s},
22773 {"fxc", PSR_f | PSR_x | PSR_c},
22774 {"fcs", PSR_f | PSR_c | PSR_s},
22775 {"fcx", PSR_f | PSR_c | PSR_x},
22776 {"sfx", PSR_s | PSR_f | PSR_x},
22777 {"sfc", PSR_s | PSR_f | PSR_c},
22778 {"sxf", PSR_s | PSR_x | PSR_f},
22779 {"sxc", PSR_s | PSR_x | PSR_c},
22780 {"scf", PSR_s | PSR_c | PSR_f},
22781 {"scx", PSR_s | PSR_c | PSR_x},
22782 {"xfs", PSR_x | PSR_f | PSR_s},
22783 {"xfc", PSR_x | PSR_f | PSR_c},
22784 {"xsf", PSR_x | PSR_s | PSR_f},
22785 {"xsc", PSR_x | PSR_s | PSR_c},
22786 {"xcf", PSR_x | PSR_c | PSR_f},
22787 {"xcs", PSR_x | PSR_c | PSR_s},
22788 {"cfs", PSR_c | PSR_f | PSR_s},
22789 {"cfx", PSR_c | PSR_f | PSR_x},
22790 {"csf", PSR_c | PSR_s | PSR_f},
22791 {"csx", PSR_c | PSR_s | PSR_x},
22792 {"cxf", PSR_c | PSR_x | PSR_f},
22793 {"cxs", PSR_c | PSR_x | PSR_s},
22794 {"fsxc", PSR_f | PSR_s | PSR_x | PSR_c},
22795 {"fscx", PSR_f | PSR_s | PSR_c | PSR_x},
22796 {"fxsc", PSR_f | PSR_x | PSR_s | PSR_c},
22797 {"fxcs", PSR_f | PSR_x | PSR_c | PSR_s},
22798 {"fcsx", PSR_f | PSR_c | PSR_s | PSR_x},
22799 {"fcxs", PSR_f | PSR_c | PSR_x | PSR_s},
22800 {"sfxc", PSR_s | PSR_f | PSR_x | PSR_c},
22801 {"sfcx", PSR_s | PSR_f | PSR_c | PSR_x},
22802 {"sxfc", PSR_s | PSR_x | PSR_f | PSR_c},
22803 {"sxcf", PSR_s | PSR_x | PSR_c | PSR_f},
22804 {"scfx", PSR_s | PSR_c | PSR_f | PSR_x},
22805 {"scxf", PSR_s | PSR_c | PSR_x | PSR_f},
22806 {"xfsc", PSR_x | PSR_f | PSR_s | PSR_c},
22807 {"xfcs", PSR_x | PSR_f | PSR_c | PSR_s},
22808 {"xsfc", PSR_x | PSR_s | PSR_f | PSR_c},
22809 {"xscf", PSR_x | PSR_s | PSR_c | PSR_f},
22810 {"xcfs", PSR_x | PSR_c | PSR_f | PSR_s},
22811 {"xcsf", PSR_x | PSR_c | PSR_s | PSR_f},
22812 {"cfsx", PSR_c | PSR_f | PSR_s | PSR_x},
22813 {"cfxs", PSR_c | PSR_f | PSR_x | PSR_s},
22814 {"csfx", PSR_c | PSR_s | PSR_f | PSR_x},
22815 {"csxf", PSR_c | PSR_s | PSR_x | PSR_f},
22816 {"cxfs", PSR_c | PSR_x | PSR_f | PSR_s},
22817 {"cxsf", PSR_c | PSR_x | PSR_s | PSR_f},
22818};
22819
62b3e311
PB
22820/* Table of V7M psr names. */
22821static const struct asm_psr v7m_psrs[] =
22822{
1a336194
TP
22823 {"apsr", 0x0 }, {"APSR", 0x0 },
22824 {"iapsr", 0x1 }, {"IAPSR", 0x1 },
22825 {"eapsr", 0x2 }, {"EAPSR", 0x2 },
22826 {"psr", 0x3 }, {"PSR", 0x3 },
22827 {"xpsr", 0x3 }, {"XPSR", 0x3 }, {"xPSR", 3 },
22828 {"ipsr", 0x5 }, {"IPSR", 0x5 },
22829 {"epsr", 0x6 }, {"EPSR", 0x6 },
22830 {"iepsr", 0x7 }, {"IEPSR", 0x7 },
22831 {"msp", 0x8 }, {"MSP", 0x8 },
22832 {"psp", 0x9 }, {"PSP", 0x9 },
22833 {"msplim", 0xa }, {"MSPLIM", 0xa },
22834 {"psplim", 0xb }, {"PSPLIM", 0xb },
22835 {"primask", 0x10}, {"PRIMASK", 0x10},
22836 {"basepri", 0x11}, {"BASEPRI", 0x11},
22837 {"basepri_max", 0x12}, {"BASEPRI_MAX", 0x12},
1a336194
TP
22838 {"faultmask", 0x13}, {"FAULTMASK", 0x13},
22839 {"control", 0x14}, {"CONTROL", 0x14},
22840 {"msp_ns", 0x88}, {"MSP_NS", 0x88},
22841 {"psp_ns", 0x89}, {"PSP_NS", 0x89},
22842 {"msplim_ns", 0x8a}, {"MSPLIM_NS", 0x8a},
22843 {"psplim_ns", 0x8b}, {"PSPLIM_NS", 0x8b},
22844 {"primask_ns", 0x90}, {"PRIMASK_NS", 0x90},
22845 {"basepri_ns", 0x91}, {"BASEPRI_NS", 0x91},
22846 {"faultmask_ns", 0x93}, {"FAULTMASK_NS", 0x93},
22847 {"control_ns", 0x94}, {"CONTROL_NS", 0x94},
22848 {"sp_ns", 0x98}, {"SP_NS", 0x98 }
62b3e311
PB
22849};
22850
c19d1205
ZW
22851/* Table of all shift-in-operand names. */
22852static const struct asm_shift_name shift_names [] =
b99bd4ef 22853{
c19d1205
ZW
22854 { "asl", SHIFT_LSL }, { "ASL", SHIFT_LSL },
22855 { "lsl", SHIFT_LSL }, { "LSL", SHIFT_LSL },
22856 { "lsr", SHIFT_LSR }, { "LSR", SHIFT_LSR },
22857 { "asr", SHIFT_ASR }, { "ASR", SHIFT_ASR },
22858 { "ror", SHIFT_ROR }, { "ROR", SHIFT_ROR },
f5f10c66
AV
22859 { "rrx", SHIFT_RRX }, { "RRX", SHIFT_RRX },
22860 { "uxtw", SHIFT_UXTW}, { "UXTW", SHIFT_UXTW}
c19d1205 22861};
b99bd4ef 22862
c19d1205
ZW
22863/* Table of all explicit relocation names. */
22864#ifdef OBJ_ELF
22865static struct reloc_entry reloc_names[] =
22866{
22867 { "got", BFD_RELOC_ARM_GOT32 }, { "GOT", BFD_RELOC_ARM_GOT32 },
22868 { "gotoff", BFD_RELOC_ARM_GOTOFF }, { "GOTOFF", BFD_RELOC_ARM_GOTOFF },
22869 { "plt", BFD_RELOC_ARM_PLT32 }, { "PLT", BFD_RELOC_ARM_PLT32 },
22870 { "target1", BFD_RELOC_ARM_TARGET1 }, { "TARGET1", BFD_RELOC_ARM_TARGET1 },
22871 { "target2", BFD_RELOC_ARM_TARGET2 }, { "TARGET2", BFD_RELOC_ARM_TARGET2 },
22872 { "sbrel", BFD_RELOC_ARM_SBREL32 }, { "SBREL", BFD_RELOC_ARM_SBREL32 },
22873 { "tlsgd", BFD_RELOC_ARM_TLS_GD32}, { "TLSGD", BFD_RELOC_ARM_TLS_GD32},
22874 { "tlsldm", BFD_RELOC_ARM_TLS_LDM32}, { "TLSLDM", BFD_RELOC_ARM_TLS_LDM32},
22875 { "tlsldo", BFD_RELOC_ARM_TLS_LDO32}, { "TLSLDO", BFD_RELOC_ARM_TLS_LDO32},
22876 { "gottpoff",BFD_RELOC_ARM_TLS_IE32}, { "GOTTPOFF",BFD_RELOC_ARM_TLS_IE32},
b43420e6 22877 { "tpoff", BFD_RELOC_ARM_TLS_LE32}, { "TPOFF", BFD_RELOC_ARM_TLS_LE32},
0855e32b
NS
22878 { "got_prel", BFD_RELOC_ARM_GOT_PREL}, { "GOT_PREL", BFD_RELOC_ARM_GOT_PREL},
22879 { "tlsdesc", BFD_RELOC_ARM_TLS_GOTDESC},
477330fc 22880 { "TLSDESC", BFD_RELOC_ARM_TLS_GOTDESC},
0855e32b 22881 { "tlscall", BFD_RELOC_ARM_TLS_CALL},
477330fc 22882 { "TLSCALL", BFD_RELOC_ARM_TLS_CALL},
0855e32b 22883 { "tlsdescseq", BFD_RELOC_ARM_TLS_DESCSEQ},
188fd7ae
CL
22884 { "TLSDESCSEQ", BFD_RELOC_ARM_TLS_DESCSEQ},
22885 { "gotfuncdesc", BFD_RELOC_ARM_GOTFUNCDESC },
22886 { "GOTFUNCDESC", BFD_RELOC_ARM_GOTFUNCDESC },
22887 { "gotofffuncdesc", BFD_RELOC_ARM_GOTOFFFUNCDESC },
22888 { "GOTOFFFUNCDESC", BFD_RELOC_ARM_GOTOFFFUNCDESC },
22889 { "funcdesc", BFD_RELOC_ARM_FUNCDESC },
5c5a4843
CL
22890 { "FUNCDESC", BFD_RELOC_ARM_FUNCDESC },
22891 { "tlsgd_fdpic", BFD_RELOC_ARM_TLS_GD32_FDPIC }, { "TLSGD_FDPIC", BFD_RELOC_ARM_TLS_GD32_FDPIC },
22892 { "tlsldm_fdpic", BFD_RELOC_ARM_TLS_LDM32_FDPIC }, { "TLSLDM_FDPIC", BFD_RELOC_ARM_TLS_LDM32_FDPIC },
22893 { "gottpoff_fdpic", BFD_RELOC_ARM_TLS_IE32_FDPIC }, { "GOTTPOFF_FDIC", BFD_RELOC_ARM_TLS_IE32_FDPIC },
c19d1205
ZW
22894};
22895#endif
b99bd4ef 22896
5ee91343 22897/* Table of all conditional affixes. */
c19d1205
ZW
22898static const struct asm_cond conds[] =
22899{
22900 {"eq", 0x0},
22901 {"ne", 0x1},
22902 {"cs", 0x2}, {"hs", 0x2},
22903 {"cc", 0x3}, {"ul", 0x3}, {"lo", 0x3},
22904 {"mi", 0x4},
22905 {"pl", 0x5},
22906 {"vs", 0x6},
22907 {"vc", 0x7},
22908 {"hi", 0x8},
22909 {"ls", 0x9},
22910 {"ge", 0xa},
22911 {"lt", 0xb},
22912 {"gt", 0xc},
22913 {"le", 0xd},
22914 {"al", 0xe}
22915};
5ee91343
AV
22916static const struct asm_cond vconds[] =
22917{
22918 {"t", 0xf},
22919 {"e", 0x10}
22920};
bfae80f2 22921
e797f7e0 22922#define UL_BARRIER(L,U,CODE,FEAT) \
823d2571
TG
22923 { L, CODE, ARM_FEATURE_CORE_LOW (FEAT) }, \
22924 { U, CODE, ARM_FEATURE_CORE_LOW (FEAT) }
e797f7e0 22925
62b3e311
PB
22926static struct asm_barrier_opt barrier_opt_names[] =
22927{
e797f7e0
MGD
22928 UL_BARRIER ("sy", "SY", 0xf, ARM_EXT_BARRIER),
22929 UL_BARRIER ("st", "ST", 0xe, ARM_EXT_BARRIER),
22930 UL_BARRIER ("ld", "LD", 0xd, ARM_EXT_V8),
22931 UL_BARRIER ("ish", "ISH", 0xb, ARM_EXT_BARRIER),
22932 UL_BARRIER ("sh", "SH", 0xb, ARM_EXT_BARRIER),
22933 UL_BARRIER ("ishst", "ISHST", 0xa, ARM_EXT_BARRIER),
22934 UL_BARRIER ("shst", "SHST", 0xa, ARM_EXT_BARRIER),
22935 UL_BARRIER ("ishld", "ISHLD", 0x9, ARM_EXT_V8),
22936 UL_BARRIER ("un", "UN", 0x7, ARM_EXT_BARRIER),
22937 UL_BARRIER ("nsh", "NSH", 0x7, ARM_EXT_BARRIER),
22938 UL_BARRIER ("unst", "UNST", 0x6, ARM_EXT_BARRIER),
22939 UL_BARRIER ("nshst", "NSHST", 0x6, ARM_EXT_BARRIER),
22940 UL_BARRIER ("nshld", "NSHLD", 0x5, ARM_EXT_V8),
22941 UL_BARRIER ("osh", "OSH", 0x3, ARM_EXT_BARRIER),
22942 UL_BARRIER ("oshst", "OSHST", 0x2, ARM_EXT_BARRIER),
22943 UL_BARRIER ("oshld", "OSHLD", 0x1, ARM_EXT_V8)
62b3e311
PB
22944};
22945
e797f7e0
MGD
22946#undef UL_BARRIER
22947
c19d1205
ZW
22948/* Table of ARM-format instructions. */
22949
22950/* Macros for gluing together operand strings. N.B. In all cases
22951 other than OPS0, the trailing OP_stop comes from default
22952 zero-initialization of the unspecified elements of the array. */
22953#define OPS0() { OP_stop, }
22954#define OPS1(a) { OP_##a, }
22955#define OPS2(a,b) { OP_##a,OP_##b, }
22956#define OPS3(a,b,c) { OP_##a,OP_##b,OP_##c, }
22957#define OPS4(a,b,c,d) { OP_##a,OP_##b,OP_##c,OP_##d, }
22958#define OPS5(a,b,c,d,e) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e, }
22959#define OPS6(a,b,c,d,e,f) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e,OP_##f, }
22960
5be8be5d
DG
22961/* These macros are similar to the OPSn, but do not prepend the OP_ prefix.
22962 This is useful when mixing operands for ARM and THUMB, i.e. using the
22963 MIX_ARM_THUMB_OPERANDS macro.
22964 In order to use these macros, prefix the number of operands with _
22965 e.g. _3. */
22966#define OPS_1(a) { a, }
22967#define OPS_2(a,b) { a,b, }
22968#define OPS_3(a,b,c) { a,b,c, }
22969#define OPS_4(a,b,c,d) { a,b,c,d, }
22970#define OPS_5(a,b,c,d,e) { a,b,c,d,e, }
22971#define OPS_6(a,b,c,d,e,f) { a,b,c,d,e,f, }
22972
c19d1205
ZW
22973/* These macros abstract out the exact format of the mnemonic table and
22974 save some repeated characters. */
22975
22976/* The normal sort of mnemonic; has a Thumb variant; takes a conditional suffix. */
22977#define TxCE(mnem, op, top, nops, ops, ae, te) \
21d799b5 22978 { mnem, OPS##nops ops, OT_csuffix, 0x##op, top, ARM_VARIANT, \
5ee91343 22979 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205
ZW
22980
22981/* Two variants of the above - TCE for a numeric Thumb opcode, tCE for
22982 a T_MNEM_xyz enumerator. */
22983#define TCE(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 22984 TxCE (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 22985#define tCE(mnem, aop, top, nops, ops, ae, te) \
21d799b5 22986 TxCE (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205
ZW
22987
22988/* Second most common sort of mnemonic: has a Thumb variant, takes a conditional
22989 infix after the third character. */
22990#define TxC3(mnem, op, top, nops, ops, ae, te) \
21d799b5 22991 { mnem, OPS##nops ops, OT_cinfix3, 0x##op, top, ARM_VARIANT, \
5ee91343 22992 THUMB_VARIANT, do_##ae, do_##te, 0 }
088fa78e 22993#define TxC3w(mnem, op, top, nops, ops, ae, te) \
21d799b5 22994 { mnem, OPS##nops ops, OT_cinfix3_deprecated, 0x##op, top, ARM_VARIANT, \
5ee91343 22995 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205 22996#define TC3(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 22997 TxC3 (mnem, aop, 0x##top, nops, ops, ae, te)
088fa78e 22998#define TC3w(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 22999 TxC3w (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 23000#define tC3(mnem, aop, top, nops, ops, ae, te) \
21d799b5 23001 TxC3 (mnem, aop, T_MNEM##top, nops, ops, ae, te)
088fa78e 23002#define tC3w(mnem, aop, top, nops, ops, ae, te) \
21d799b5 23003 TxC3w (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205 23004
c19d1205 23005/* Mnemonic that cannot be conditionalized. The ARM condition-code
dfa9f0d5
PB
23006 field is still 0xE. Many of the Thumb variants can be executed
23007 conditionally, so this is checked separately. */
c19d1205 23008#define TUE(mnem, op, top, nops, ops, ae, te) \
21d799b5 23009 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 23010 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205 23011
dd5181d5
KT
23012/* Same as TUE but the encoding function for ARM and Thumb modes is the same.
23013 Used by mnemonics that have very minimal differences in the encoding for
23014 ARM and Thumb variants and can be handled in a common function. */
23015#define TUEc(mnem, op, top, nops, ops, en) \
23016 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 23017 THUMB_VARIANT, do_##en, do_##en, 0 }
dd5181d5 23018
c19d1205
ZW
23019/* Mnemonic that cannot be conditionalized, and bears 0xF in its ARM
23020 condition code field. */
23021#define TUF(mnem, op, top, nops, ops, ae, te) \
21d799b5 23022 { mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 23023 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205
ZW
23024
23025/* ARM-only variants of all the above. */
6a86118a 23026#define CE(mnem, op, nops, ops, ae) \
5ee91343 23027 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
23028
23029#define C3(mnem, op, nops, ops, ae) \
5ee91343 23030 { #mnem, OPS##nops ops, OT_cinfix3, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a 23031
cf3cf39d
TP
23032/* Thumb-only variants of TCE and TUE. */
23033#define ToC(mnem, top, nops, ops, te) \
23034 { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
5ee91343 23035 do_##te, 0 }
cf3cf39d
TP
23036
23037#define ToU(mnem, top, nops, ops, te) \
23038 { mnem, OPS##nops ops, OT_unconditional, 0x0, 0x##top, 0, THUMB_VARIANT, \
5ee91343 23039 NULL, do_##te, 0 }
cf3cf39d 23040
4389b29a
AV
23041/* T_MNEM_xyz enumerator variants of ToC. */
23042#define toC(mnem, top, nops, ops, te) \
23043 { mnem, OPS##nops ops, OT_csuffix, 0x0, T_MNEM##top, 0, THUMB_VARIANT, NULL, \
5ee91343 23044 do_##te, 0 }
4389b29a 23045
f6b2b12d
AV
23046/* T_MNEM_xyz enumerator variants of ToU. */
23047#define toU(mnem, top, nops, ops, te) \
23048 { mnem, OPS##nops ops, OT_unconditional, 0x0, T_MNEM##top, 0, THUMB_VARIANT, \
5ee91343 23049 NULL, do_##te, 0 }
f6b2b12d 23050
e3cb604e
PB
23051/* Legacy mnemonics that always have conditional infix after the third
23052 character. */
23053#define CL(mnem, op, nops, ops, ae) \
21d799b5 23054 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
5ee91343 23055 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
e3cb604e 23056
8f06b2d8
PB
23057/* Coprocessor instructions. Isomorphic between Arm and Thumb-2. */
23058#define cCE(mnem, op, nops, ops, ae) \
5ee91343 23059 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
8f06b2d8 23060
57785aa2
AV
23061/* mov instructions that are shared between coprocessor and MVE. */
23062#define mcCE(mnem, op, nops, ops, ae) \
23063 { #mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, THUMB_VARIANT, do_##ae, do_##ae, 0 }
23064
e3cb604e
PB
23065/* Legacy coprocessor instructions where conditional infix and conditional
23066 suffix are ambiguous. For consistency this includes all FPA instructions,
23067 not just the potentially ambiguous ones. */
23068#define cCL(mnem, op, nops, ops, ae) \
21d799b5 23069 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
5ee91343 23070 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
e3cb604e
PB
23071
23072/* Coprocessor, takes either a suffix or a position-3 infix
23073 (for an FPA corner case). */
23074#define C3E(mnem, op, nops, ops, ae) \
21d799b5 23075 { mnem, OPS##nops ops, OT_csuf_or_in3, \
5ee91343 23076 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
8f06b2d8 23077
6a86118a 23078#define xCM_(m1, m2, m3, op, nops, ops, ae) \
21d799b5
NC
23079 { m1 #m2 m3, OPS##nops ops, \
23080 sizeof (#m2) == 1 ? OT_odd_infix_unc : OT_odd_infix_0 + sizeof (m1) - 1, \
5ee91343 23081 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
23082
23083#define CM(m1, m2, op, nops, ops, ae) \
e07e6e58
NC
23084 xCM_ (m1, , m2, op, nops, ops, ae), \
23085 xCM_ (m1, eq, m2, op, nops, ops, ae), \
23086 xCM_ (m1, ne, m2, op, nops, ops, ae), \
23087 xCM_ (m1, cs, m2, op, nops, ops, ae), \
23088 xCM_ (m1, hs, m2, op, nops, ops, ae), \
23089 xCM_ (m1, cc, m2, op, nops, ops, ae), \
23090 xCM_ (m1, ul, m2, op, nops, ops, ae), \
23091 xCM_ (m1, lo, m2, op, nops, ops, ae), \
23092 xCM_ (m1, mi, m2, op, nops, ops, ae), \
23093 xCM_ (m1, pl, m2, op, nops, ops, ae), \
23094 xCM_ (m1, vs, m2, op, nops, ops, ae), \
23095 xCM_ (m1, vc, m2, op, nops, ops, ae), \
23096 xCM_ (m1, hi, m2, op, nops, ops, ae), \
23097 xCM_ (m1, ls, m2, op, nops, ops, ae), \
23098 xCM_ (m1, ge, m2, op, nops, ops, ae), \
23099 xCM_ (m1, lt, m2, op, nops, ops, ae), \
23100 xCM_ (m1, gt, m2, op, nops, ops, ae), \
23101 xCM_ (m1, le, m2, op, nops, ops, ae), \
23102 xCM_ (m1, al, m2, op, nops, ops, ae)
6a86118a
NC
23103
23104#define UE(mnem, op, nops, ops, ae) \
5ee91343 23105 { #mnem, OPS##nops ops, OT_unconditional, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
23106
23107#define UF(mnem, op, nops, ops, ae) \
5ee91343 23108 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a 23109
5287ad62
JB
23110/* Neon data-processing. ARM versions are unconditional with cond=0xf.
23111 The Thumb and ARM variants are mostly the same (bits 0-23 and 24/28), so we
23112 use the same encoding function for each. */
23113#define NUF(mnem, op, nops, ops, enc) \
23114 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op, \
5ee91343 23115 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 0 }
5287ad62
JB
23116
23117/* Neon data processing, version which indirects through neon_enc_tab for
23118 the various overloaded versions of opcodes. */
23119#define nUF(mnem, op, nops, ops, enc) \
21d799b5 23120 { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op, \
5ee91343 23121 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 0 }
5287ad62
JB
23122
23123/* Neon insn with conditional suffix for the ARM version, non-overloaded
23124 version. */
5ee91343 23125#define NCE_tag(mnem, op, nops, ops, enc, tag, mve_p) \
037e8744 23126 { #mnem, OPS##nops ops, tag, 0x##op, 0x##op, ARM_VARIANT, \
5ee91343 23127 THUMB_VARIANT, do_##enc, do_##enc, mve_p }
5287ad62 23128
037e8744 23129#define NCE(mnem, op, nops, ops, enc) \
5ee91343 23130 NCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 0)
037e8744
JB
23131
23132#define NCEF(mnem, op, nops, ops, enc) \
5ee91343 23133 NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 0)
037e8744 23134
5287ad62 23135/* Neon insn with conditional suffix for the ARM version, overloaded types. */
5ee91343 23136#define nCE_tag(mnem, op, nops, ops, enc, tag, mve_p) \
21d799b5 23137 { #mnem, OPS##nops ops, tag, N_MNEM##op, N_MNEM##op, \
5ee91343 23138 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, mve_p }
5287ad62 23139
037e8744 23140#define nCE(mnem, op, nops, ops, enc) \
5ee91343 23141 nCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 0)
037e8744
JB
23142
23143#define nCEF(mnem, op, nops, ops, enc) \
5ee91343
AV
23144 nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 0)
23145
23146/* */
23147#define mCEF(mnem, op, nops, ops, enc) \
a302e574 23148 { #mnem, OPS##nops ops, OT_csuffixF, M_MNEM##op, M_MNEM##op, \
5ee91343
AV
23149 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
23150
23151
23152/* nCEF but for MVE predicated instructions. */
23153#define mnCEF(mnem, op, nops, ops, enc) \
23154 nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 1)
23155
23156/* nCE but for MVE predicated instructions. */
23157#define mnCE(mnem, op, nops, ops, enc) \
23158 nCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 1)
037e8744 23159
5ee91343
AV
23160/* NUF but for potentially MVE predicated instructions. */
23161#define MNUF(mnem, op, nops, ops, enc) \
23162 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op, \
23163 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
23164
23165/* nUF but for potentially MVE predicated instructions. */
23166#define mnUF(mnem, op, nops, ops, enc) \
23167 { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op, \
23168 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
23169
23170/* ToC but for potentially MVE predicated instructions. */
23171#define mToC(mnem, top, nops, ops, te) \
23172 { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
23173 do_##te, 1 }
23174
23175/* NCE but for MVE predicated instructions. */
23176#define MNCE(mnem, op, nops, ops, enc) \
23177 NCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 1)
23178
23179/* NCEF but for MVE predicated instructions. */
23180#define MNCEF(mnem, op, nops, ops, enc) \
23181 NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 1)
c19d1205
ZW
23182#define do_0 0
23183
c19d1205 23184static const struct asm_opcode insns[] =
bfae80f2 23185{
74db7efb
NC
23186#define ARM_VARIANT & arm_ext_v1 /* Core ARM Instructions. */
23187#define THUMB_VARIANT & arm_ext_v4t
21d799b5
NC
23188 tCE("and", 0000000, _and, 3, (RR, oRR, SH), arit, t_arit3c),
23189 tC3("ands", 0100000, _ands, 3, (RR, oRR, SH), arit, t_arit3c),
23190 tCE("eor", 0200000, _eor, 3, (RR, oRR, SH), arit, t_arit3c),
23191 tC3("eors", 0300000, _eors, 3, (RR, oRR, SH), arit, t_arit3c),
23192 tCE("sub", 0400000, _sub, 3, (RR, oRR, SH), arit, t_add_sub),
23193 tC3("subs", 0500000, _subs, 3, (RR, oRR, SH), arit, t_add_sub),
23194 tCE("add", 0800000, _add, 3, (RR, oRR, SHG), arit, t_add_sub),
23195 tC3("adds", 0900000, _adds, 3, (RR, oRR, SHG), arit, t_add_sub),
23196 tCE("adc", 0a00000, _adc, 3, (RR, oRR, SH), arit, t_arit3c),
23197 tC3("adcs", 0b00000, _adcs, 3, (RR, oRR, SH), arit, t_arit3c),
23198 tCE("sbc", 0c00000, _sbc, 3, (RR, oRR, SH), arit, t_arit3),
23199 tC3("sbcs", 0d00000, _sbcs, 3, (RR, oRR, SH), arit, t_arit3),
23200 tCE("orr", 1800000, _orr, 3, (RR, oRR, SH), arit, t_arit3c),
23201 tC3("orrs", 1900000, _orrs, 3, (RR, oRR, SH), arit, t_arit3c),
23202 tCE("bic", 1c00000, _bic, 3, (RR, oRR, SH), arit, t_arit3),
23203 tC3("bics", 1d00000, _bics, 3, (RR, oRR, SH), arit, t_arit3),
c19d1205
ZW
23204
23205 /* The p-variants of tst/cmp/cmn/teq (below) are the pre-V6 mechanism
23206 for setting PSR flag bits. They are obsolete in V6 and do not
23207 have Thumb equivalents. */
21d799b5
NC
23208 tCE("tst", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
23209 tC3w("tsts", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
23210 CL("tstp", 110f000, 2, (RR, SH), cmp),
23211 tCE("cmp", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
23212 tC3w("cmps", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
23213 CL("cmpp", 150f000, 2, (RR, SH), cmp),
23214 tCE("cmn", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
23215 tC3w("cmns", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
23216 CL("cmnp", 170f000, 2, (RR, SH), cmp),
23217
23218 tCE("mov", 1a00000, _mov, 2, (RR, SH), mov, t_mov_cmp),
72d98d16 23219 tC3("movs", 1b00000, _movs, 2, (RR, SHG), mov, t_mov_cmp),
21d799b5
NC
23220 tCE("mvn", 1e00000, _mvn, 2, (RR, SH), mov, t_mvn_tst),
23221 tC3("mvns", 1f00000, _mvns, 2, (RR, SH), mov, t_mvn_tst),
23222
23223 tCE("ldr", 4100000, _ldr, 2, (RR, ADDRGLDR),ldst, t_ldst),
5be8be5d
DG
23224 tC3("ldrb", 4500000, _ldrb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
23225 tCE("str", 4000000, _str, _2, (MIX_ARM_THUMB_OPERANDS (OP_RR,
23226 OP_RRnpc),
23227 OP_ADDRGLDR),ldst, t_ldst),
23228 tC3("strb", 4400000, _strb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
21d799b5
NC
23229
23230 tCE("stm", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
23231 tC3("stmia", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
23232 tC3("stmea", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
23233 tCE("ldm", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
23234 tC3("ldmia", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
23235 tC3("ldmfd", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
23236
21d799b5
NC
23237 tCE("b", a000000, _b, 1, (EXPr), branch, t_branch),
23238 TCE("bl", b000000, f000f800, 1, (EXPr), bl, t_branch23),
bfae80f2 23239
c19d1205 23240 /* Pseudo ops. */
21d799b5 23241 tCE("adr", 28f0000, _adr, 2, (RR, EXP), adr, t_adr),
2fc8bdac 23242 C3(adrl, 28f0000, 2, (RR, EXP), adrl),
21d799b5 23243 tCE("nop", 1a00000, _nop, 1, (oI255c), nop, t_nop),
74db7efb 23244 tCE("udf", 7f000f0, _udf, 1, (oIffffb), bkpt, t_udf),
c19d1205
ZW
23245
23246 /* Thumb-compatibility pseudo ops. */
21d799b5
NC
23247 tCE("lsl", 1a00000, _lsl, 3, (RR, oRR, SH), shift, t_shift),
23248 tC3("lsls", 1b00000, _lsls, 3, (RR, oRR, SH), shift, t_shift),
23249 tCE("lsr", 1a00020, _lsr, 3, (RR, oRR, SH), shift, t_shift),
23250 tC3("lsrs", 1b00020, _lsrs, 3, (RR, oRR, SH), shift, t_shift),
23251 tCE("asr", 1a00040, _asr, 3, (RR, oRR, SH), shift, t_shift),
23252 tC3("asrs", 1b00040, _asrs, 3, (RR, oRR, SH), shift, t_shift),
23253 tCE("ror", 1a00060, _ror, 3, (RR, oRR, SH), shift, t_shift),
23254 tC3("rors", 1b00060, _rors, 3, (RR, oRR, SH), shift, t_shift),
23255 tCE("neg", 2600000, _neg, 2, (RR, RR), rd_rn, t_neg),
23256 tC3("negs", 2700000, _negs, 2, (RR, RR), rd_rn, t_neg),
23257 tCE("push", 92d0000, _push, 1, (REGLST), push_pop, t_push_pop),
23258 tCE("pop", 8bd0000, _pop, 1, (REGLST), push_pop, t_push_pop),
c19d1205 23259
16a4cf17 23260 /* These may simplify to neg. */
21d799b5
NC
23261 TCE("rsb", 0600000, ebc00000, 3, (RR, oRR, SH), arit, t_rsb),
23262 TC3("rsbs", 0700000, ebd00000, 3, (RR, oRR, SH), arit, t_rsb),
16a4cf17 23263
173205ca
TP
23264#undef THUMB_VARIANT
23265#define THUMB_VARIANT & arm_ext_os
23266
23267 TCE("swi", f000000, df00, 1, (EXPi), swi, t_swi),
23268 TCE("svc", f000000, df00, 1, (EXPi), swi, t_swi),
23269
c921be7d
NC
23270#undef THUMB_VARIANT
23271#define THUMB_VARIANT & arm_ext_v6
23272
21d799b5 23273 TCE("cpy", 1a00000, 4600, 2, (RR, RR), rd_rm, t_cpy),
c19d1205
ZW
23274
23275 /* V1 instructions with no Thumb analogue prior to V6T2. */
c921be7d
NC
23276#undef THUMB_VARIANT
23277#define THUMB_VARIANT & arm_ext_v6t2
23278
21d799b5
NC
23279 TCE("teq", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
23280 TC3w("teqs", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
23281 CL("teqp", 130f000, 2, (RR, SH), cmp),
c19d1205 23282
5be8be5d
DG
23283 TC3("ldrt", 4300000, f8500e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
23284 TC3("ldrbt", 4700000, f8100e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
23285 TC3("strt", 4200000, f8400e00, 2, (RR_npcsp, ADDR), ldstt, t_ldstt),
23286 TC3("strbt", 4600000, f8000e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
c19d1205 23287
21d799b5
NC
23288 TC3("stmdb", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
23289 TC3("stmfd", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205 23290
21d799b5
NC
23291 TC3("ldmdb", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
23292 TC3("ldmea", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205
ZW
23293
23294 /* V1 instructions with no Thumb analogue at all. */
21d799b5 23295 CE("rsc", 0e00000, 3, (RR, oRR, SH), arit),
c19d1205
ZW
23296 C3(rscs, 0f00000, 3, (RR, oRR, SH), arit),
23297
23298 C3(stmib, 9800000, 2, (RRw, REGLST), ldmstm),
23299 C3(stmfa, 9800000, 2, (RRw, REGLST), ldmstm),
23300 C3(stmda, 8000000, 2, (RRw, REGLST), ldmstm),
23301 C3(stmed, 8000000, 2, (RRw, REGLST), ldmstm),
23302 C3(ldmib, 9900000, 2, (RRw, REGLST), ldmstm),
23303 C3(ldmed, 9900000, 2, (RRw, REGLST), ldmstm),
23304 C3(ldmda, 8100000, 2, (RRw, REGLST), ldmstm),
23305 C3(ldmfa, 8100000, 2, (RRw, REGLST), ldmstm),
23306
c921be7d
NC
23307#undef ARM_VARIANT
23308#define ARM_VARIANT & arm_ext_v2 /* ARM 2 - multiplies. */
23309#undef THUMB_VARIANT
23310#define THUMB_VARIANT & arm_ext_v4t
23311
21d799b5
NC
23312 tCE("mul", 0000090, _mul, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
23313 tC3("muls", 0100090, _muls, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
c19d1205 23314
c921be7d
NC
23315#undef THUMB_VARIANT
23316#define THUMB_VARIANT & arm_ext_v6t2
23317
21d799b5 23318 TCE("mla", 0200090, fb000000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
c19d1205
ZW
23319 C3(mlas, 0300090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas),
23320
23321 /* Generic coprocessor instructions. */
21d799b5
NC
23322 TCE("cdp", e000000, ee000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
23323 TCE("ldc", c100000, ec100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
23324 TC3("ldcl", c500000, ec500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
23325 TCE("stc", c000000, ec000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
23326 TC3("stcl", c400000, ec400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
23327 TCE("mcr", e000010, ee000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
db472d6f 23328 TCE("mrc", e100010, ee100010, 6, (RCP, I7b, APSR_RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 23329
c921be7d
NC
23330#undef ARM_VARIANT
23331#define ARM_VARIANT & arm_ext_v2s /* ARM 3 - swp instructions. */
23332
21d799b5 23333 CE("swp", 1000090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
c19d1205
ZW
23334 C3(swpb, 1400090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
23335
c921be7d
NC
23336#undef ARM_VARIANT
23337#define ARM_VARIANT & arm_ext_v3 /* ARM 6 Status register instructions. */
23338#undef THUMB_VARIANT
23339#define THUMB_VARIANT & arm_ext_msr
23340
d2cd1205
JB
23341 TCE("mrs", 1000000, f3e08000, 2, (RRnpc, rPSR), mrs, t_mrs),
23342 TCE("msr", 120f000, f3808000, 2, (wPSR, RR_EXi), msr, t_msr),
c19d1205 23343
c921be7d
NC
23344#undef ARM_VARIANT
23345#define ARM_VARIANT & arm_ext_v3m /* ARM 7M long multiplies. */
23346#undef THUMB_VARIANT
23347#define THUMB_VARIANT & arm_ext_v6t2
23348
21d799b5
NC
23349 TCE("smull", 0c00090, fb800000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
23350 CM("smull","s", 0d00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
23351 TCE("umull", 0800090, fba00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
23352 CM("umull","s", 0900090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
23353 TCE("smlal", 0e00090, fbc00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
23354 CM("smlal","s", 0f00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
23355 TCE("umlal", 0a00090, fbe00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
23356 CM("umlal","s", 0b00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
c19d1205 23357
c921be7d
NC
23358#undef ARM_VARIANT
23359#define ARM_VARIANT & arm_ext_v4 /* ARM Architecture 4. */
23360#undef THUMB_VARIANT
23361#define THUMB_VARIANT & arm_ext_v4t
23362
5be8be5d
DG
23363 tC3("ldrh", 01000b0, _ldrh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
23364 tC3("strh", 00000b0, _strh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
23365 tC3("ldrsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
23366 tC3("ldrsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
56c0a61f
RE
23367 tC3("ldsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
23368 tC3("ldsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
c19d1205 23369
c921be7d
NC
23370#undef ARM_VARIANT
23371#define ARM_VARIANT & arm_ext_v4t_5
23372
c19d1205
ZW
23373 /* ARM Architecture 4T. */
23374 /* Note: bx (and blx) are required on V5, even if the processor does
23375 not support Thumb. */
21d799b5 23376 TCE("bx", 12fff10, 4700, 1, (RR), bx, t_bx),
c19d1205 23377
c921be7d
NC
23378#undef ARM_VARIANT
23379#define ARM_VARIANT & arm_ext_v5 /* ARM Architecture 5T. */
23380#undef THUMB_VARIANT
23381#define THUMB_VARIANT & arm_ext_v5t
23382
c19d1205
ZW
23383 /* Note: blx has 2 variants; the .value coded here is for
23384 BLX(2). Only this variant has conditional execution. */
21d799b5
NC
23385 TCE("blx", 12fff30, 4780, 1, (RR_EXr), blx, t_blx),
23386 TUE("bkpt", 1200070, be00, 1, (oIffffb), bkpt, t_bkpt),
c19d1205 23387
c921be7d
NC
23388#undef THUMB_VARIANT
23389#define THUMB_VARIANT & arm_ext_v6t2
23390
21d799b5
NC
23391 TCE("clz", 16f0f10, fab0f080, 2, (RRnpc, RRnpc), rd_rm, t_clz),
23392 TUF("ldc2", c100000, fc100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
23393 TUF("ldc2l", c500000, fc500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
23394 TUF("stc2", c000000, fc000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
23395 TUF("stc2l", c400000, fc400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
23396 TUF("cdp2", e000000, fe000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
23397 TUF("mcr2", e000010, fe000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
23398 TUF("mrc2", e100010, fe100010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 23399
c921be7d 23400#undef ARM_VARIANT
74db7efb
NC
23401#define ARM_VARIANT & arm_ext_v5exp /* ARM Architecture 5TExP. */
23402#undef THUMB_VARIANT
23403#define THUMB_VARIANT & arm_ext_v5exp
c921be7d 23404
21d799b5
NC
23405 TCE("smlabb", 1000080, fb100000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
23406 TCE("smlatb", 10000a0, fb100020, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
23407 TCE("smlabt", 10000c0, fb100010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
23408 TCE("smlatt", 10000e0, fb100030, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 23409
21d799b5
NC
23410 TCE("smlawb", 1200080, fb300000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
23411 TCE("smlawt", 12000c0, fb300010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 23412
21d799b5
NC
23413 TCE("smlalbb", 1400080, fbc00080, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
23414 TCE("smlaltb", 14000a0, fbc000a0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
23415 TCE("smlalbt", 14000c0, fbc00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
23416 TCE("smlaltt", 14000e0, fbc000b0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
c19d1205 23417
21d799b5
NC
23418 TCE("smulbb", 1600080, fb10f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
23419 TCE("smultb", 16000a0, fb10f020, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
23420 TCE("smulbt", 16000c0, fb10f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
23421 TCE("smultt", 16000e0, fb10f030, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 23422
21d799b5
NC
23423 TCE("smulwb", 12000a0, fb30f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
23424 TCE("smulwt", 12000e0, fb30f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 23425
03ee1b7f
NC
23426 TCE("qadd", 1000050, fa80f080, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
23427 TCE("qdadd", 1400050, fa80f090, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
23428 TCE("qsub", 1200050, fa80f0a0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
23429 TCE("qdsub", 1600050, fa80f0b0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
c19d1205 23430
c921be7d 23431#undef ARM_VARIANT
74db7efb
NC
23432#define ARM_VARIANT & arm_ext_v5e /* ARM Architecture 5TE. */
23433#undef THUMB_VARIANT
23434#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 23435
21d799b5 23436 TUF("pld", 450f000, f810f000, 1, (ADDR), pld, t_pld),
5be8be5d
DG
23437 TC3("ldrd", 00000d0, e8500000, 3, (RRnpc_npcsp, oRRnpc_npcsp, ADDRGLDRS),
23438 ldrd, t_ldstd),
23439 TC3("strd", 00000f0, e8400000, 3, (RRnpc_npcsp, oRRnpc_npcsp,
23440 ADDRGLDRS), ldrd, t_ldstd),
c19d1205 23441
21d799b5
NC
23442 TCE("mcrr", c400000, ec400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
23443 TCE("mrrc", c500000, ec500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
c19d1205 23444
c921be7d
NC
23445#undef ARM_VARIANT
23446#define ARM_VARIANT & arm_ext_v5j /* ARM Architecture 5TEJ. */
23447
21d799b5 23448 TCE("bxj", 12fff20, f3c08f00, 1, (RR), bxj, t_bxj),
c19d1205 23449
c921be7d
NC
23450#undef ARM_VARIANT
23451#define ARM_VARIANT & arm_ext_v6 /* ARM V6. */
23452#undef THUMB_VARIANT
23453#define THUMB_VARIANT & arm_ext_v6
23454
21d799b5
NC
23455 TUF("cpsie", 1080000, b660, 2, (CPSF, oI31b), cpsi, t_cpsi),
23456 TUF("cpsid", 10c0000, b670, 2, (CPSF, oI31b), cpsi, t_cpsi),
23457 tCE("rev", 6bf0f30, _rev, 2, (RRnpc, RRnpc), rd_rm, t_rev),
23458 tCE("rev16", 6bf0fb0, _rev16, 2, (RRnpc, RRnpc), rd_rm, t_rev),
23459 tCE("revsh", 6ff0fb0, _revsh, 2, (RRnpc, RRnpc), rd_rm, t_rev),
23460 tCE("sxth", 6bf0070, _sxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
23461 tCE("uxth", 6ff0070, _uxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
23462 tCE("sxtb", 6af0070, _sxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
23463 tCE("uxtb", 6ef0070, _uxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
23464 TUF("setend", 1010000, b650, 1, (ENDI), setend, t_setend),
c19d1205 23465
c921be7d 23466#undef THUMB_VARIANT
ff8646ee 23467#define THUMB_VARIANT & arm_ext_v6t2_v8m
c921be7d 23468
5be8be5d
DG
23469 TCE("ldrex", 1900f9f, e8500f00, 2, (RRnpc_npcsp, ADDR), ldrex, t_ldrex),
23470 TCE("strex", 1800f90, e8400000, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
23471 strex, t_strex),
ff8646ee
TP
23472#undef THUMB_VARIANT
23473#define THUMB_VARIANT & arm_ext_v6t2
23474
21d799b5
NC
23475 TUF("mcrr2", c400000, fc400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
23476 TUF("mrrc2", c500000, fc500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
62b3e311 23477
21d799b5
NC
23478 TCE("ssat", 6a00010, f3000000, 4, (RRnpc, I32, RRnpc, oSHllar),ssat, t_ssat),
23479 TCE("usat", 6e00010, f3800000, 4, (RRnpc, I31, RRnpc, oSHllar),usat, t_usat),
62b3e311 23480
9e3c6df6 23481/* ARM V6 not included in V7M. */
c921be7d
NC
23482#undef THUMB_VARIANT
23483#define THUMB_VARIANT & arm_ext_v6_notm
9e3c6df6 23484 TUF("rfeia", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6 23485 TUF("rfe", 8900a00, e990c000, 1, (RRw), rfe, rfe),
9e3c6df6
PB
23486 UF(rfeib, 9900a00, 1, (RRw), rfe),
23487 UF(rfeda, 8100a00, 1, (RRw), rfe),
23488 TUF("rfedb", 9100a00, e810c000, 1, (RRw), rfe, rfe),
23489 TUF("rfefd", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6
RE
23490 UF(rfefa, 8100a00, 1, (RRw), rfe),
23491 TUF("rfeea", 9100a00, e810c000, 1, (RRw), rfe, rfe),
23492 UF(rfeed, 9900a00, 1, (RRw), rfe),
9e3c6df6 23493 TUF("srsia", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
d709e4e6
RE
23494 TUF("srs", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
23495 TUF("srsea", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
9e3c6df6 23496 UF(srsib, 9c00500, 2, (oRRw, I31w), srs),
d709e4e6 23497 UF(srsfa, 9c00500, 2, (oRRw, I31w), srs),
9e3c6df6 23498 UF(srsda, 8400500, 2, (oRRw, I31w), srs),
d709e4e6 23499 UF(srsed, 8400500, 2, (oRRw, I31w), srs),
9e3c6df6 23500 TUF("srsdb", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
d709e4e6 23501 TUF("srsfd", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
941c9cad 23502 TUF("cps", 1020000, f3af8100, 1, (I31b), imm0, t_cps),
c921be7d 23503
9e3c6df6
PB
23504/* ARM V6 not included in V7M (eg. integer SIMD). */
23505#undef THUMB_VARIANT
23506#define THUMB_VARIANT & arm_ext_v6_dsp
21d799b5
NC
23507 TCE("pkhbt", 6800010, eac00000, 4, (RRnpc, RRnpc, RRnpc, oSHll), pkhbt, t_pkhbt),
23508 TCE("pkhtb", 6800050, eac00020, 4, (RRnpc, RRnpc, RRnpc, oSHar), pkhtb, t_pkhtb),
23509 TCE("qadd16", 6200f10, fa90f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23510 TCE("qadd8", 6200f90, fa80f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23511 TCE("qasx", 6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23512 /* Old name for QASX. */
74db7efb 23513 TCE("qaddsubx",6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 23514 TCE("qsax", 6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23515 /* Old name for QSAX. */
74db7efb 23516 TCE("qsubaddx",6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
23517 TCE("qsub16", 6200f70, fad0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23518 TCE("qsub8", 6200ff0, fac0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23519 TCE("sadd16", 6100f10, fa90f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23520 TCE("sadd8", 6100f90, fa80f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23521 TCE("sasx", 6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23522 /* Old name for SASX. */
74db7efb 23523 TCE("saddsubx",6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
23524 TCE("shadd16", 6300f10, fa90f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23525 TCE("shadd8", 6300f90, fa80f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 23526 TCE("shasx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23527 /* Old name for SHASX. */
21d799b5 23528 TCE("shaddsubx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 23529 TCE("shsax", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23530 /* Old name for SHSAX. */
21d799b5
NC
23531 TCE("shsubaddx", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23532 TCE("shsub16", 6300f70, fad0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23533 TCE("shsub8", 6300ff0, fac0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23534 TCE("ssax", 6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23535 /* Old name for SSAX. */
74db7efb 23536 TCE("ssubaddx",6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
23537 TCE("ssub16", 6100f70, fad0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23538 TCE("ssub8", 6100ff0, fac0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23539 TCE("uadd16", 6500f10, fa90f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23540 TCE("uadd8", 6500f90, fa80f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23541 TCE("uasx", 6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23542 /* Old name for UASX. */
74db7efb 23543 TCE("uaddsubx",6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
23544 TCE("uhadd16", 6700f10, fa90f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23545 TCE("uhadd8", 6700f90, fa80f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 23546 TCE("uhasx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23547 /* Old name for UHASX. */
21d799b5
NC
23548 TCE("uhaddsubx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23549 TCE("uhsax", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23550 /* Old name for UHSAX. */
21d799b5
NC
23551 TCE("uhsubaddx", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23552 TCE("uhsub16", 6700f70, fad0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23553 TCE("uhsub8", 6700ff0, fac0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23554 TCE("uqadd16", 6600f10, fa90f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23555 TCE("uqadd8", 6600f90, fa80f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 23556 TCE("uqasx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23557 /* Old name for UQASX. */
21d799b5
NC
23558 TCE("uqaddsubx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23559 TCE("uqsax", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23560 /* Old name for UQSAX. */
21d799b5
NC
23561 TCE("uqsubaddx", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23562 TCE("uqsub16", 6600f70, fad0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23563 TCE("uqsub8", 6600ff0, fac0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23564 TCE("usub16", 6500f70, fad0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23565 TCE("usax", 6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 23566 /* Old name for USAX. */
74db7efb 23567 TCE("usubaddx",6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 23568 TCE("usub8", 6500ff0, fac0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
23569 TCE("sxtah", 6b00070, fa00f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
23570 TCE("sxtab16", 6800070, fa20f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
23571 TCE("sxtab", 6a00070, fa40f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
23572 TCE("sxtb16", 68f0070, fa2ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
23573 TCE("uxtah", 6f00070, fa10f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
23574 TCE("uxtab16", 6c00070, fa30f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
23575 TCE("uxtab", 6e00070, fa50f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
23576 TCE("uxtb16", 6cf0070, fa3ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
23577 TCE("sel", 6800fb0, faa0f080, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
23578 TCE("smlad", 7000010, fb200000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
23579 TCE("smladx", 7000030, fb200010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
23580 TCE("smlald", 7400010, fbc000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
23581 TCE("smlaldx", 7400030, fbc000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
23582 TCE("smlsd", 7000050, fb400000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
23583 TCE("smlsdx", 7000070, fb400010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
23584 TCE("smlsld", 7400050, fbd000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
23585 TCE("smlsldx", 7400070, fbd000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
23586 TCE("smmla", 7500010, fb500000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
23587 TCE("smmlar", 7500030, fb500010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
23588 TCE("smmls", 75000d0, fb600000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
23589 TCE("smmlsr", 75000f0, fb600010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
23590 TCE("smmul", 750f010, fb50f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
23591 TCE("smmulr", 750f030, fb50f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
23592 TCE("smuad", 700f010, fb20f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
23593 TCE("smuadx", 700f030, fb20f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
23594 TCE("smusd", 700f050, fb40f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
23595 TCE("smusdx", 700f070, fb40f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
21d799b5
NC
23596 TCE("ssat16", 6a00f30, f3200000, 3, (RRnpc, I16, RRnpc), ssat16, t_ssat16),
23597 TCE("umaal", 0400090, fbe00060, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal, t_mlal),
23598 TCE("usad8", 780f010, fb70f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
23599 TCE("usada8", 7800010, fb700000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
23600 TCE("usat16", 6e00f30, f3a00000, 3, (RRnpc, I15, RRnpc), usat16, t_usat16),
c19d1205 23601
c921be7d 23602#undef ARM_VARIANT
55e8aae7 23603#define ARM_VARIANT & arm_ext_v6k_v6t2
c921be7d 23604#undef THUMB_VARIANT
55e8aae7 23605#define THUMB_VARIANT & arm_ext_v6k_v6t2
c921be7d 23606
21d799b5
NC
23607 tCE("yield", 320f001, _yield, 0, (), noargs, t_hint),
23608 tCE("wfe", 320f002, _wfe, 0, (), noargs, t_hint),
23609 tCE("wfi", 320f003, _wfi, 0, (), noargs, t_hint),
23610 tCE("sev", 320f004, _sev, 0, (), noargs, t_hint),
c19d1205 23611
c921be7d
NC
23612#undef THUMB_VARIANT
23613#define THUMB_VARIANT & arm_ext_v6_notm
5be8be5d
DG
23614 TCE("ldrexd", 1b00f9f, e8d0007f, 3, (RRnpc_npcsp, oRRnpc_npcsp, RRnpcb),
23615 ldrexd, t_ldrexd),
23616 TCE("strexd", 1a00f90, e8c00070, 4, (RRnpc_npcsp, RRnpc_npcsp, oRRnpc_npcsp,
23617 RRnpcb), strexd, t_strexd),
ebdca51a 23618
c921be7d 23619#undef THUMB_VARIANT
ff8646ee 23620#define THUMB_VARIANT & arm_ext_v6t2_v8m
5be8be5d
DG
23621 TCE("ldrexb", 1d00f9f, e8d00f4f, 2, (RRnpc_npcsp,RRnpcb),
23622 rd_rn, rd_rn),
23623 TCE("ldrexh", 1f00f9f, e8d00f5f, 2, (RRnpc_npcsp, RRnpcb),
23624 rd_rn, rd_rn),
23625 TCE("strexb", 1c00f90, e8c00f40, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 23626 strex, t_strexbh),
5be8be5d 23627 TCE("strexh", 1e00f90, e8c00f50, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 23628 strex, t_strexbh),
21d799b5 23629 TUF("clrex", 57ff01f, f3bf8f2f, 0, (), noargs, noargs),
c19d1205 23630
c921be7d 23631#undef ARM_VARIANT
f4c65163 23632#define ARM_VARIANT & arm_ext_sec
74db7efb 23633#undef THUMB_VARIANT
f4c65163 23634#define THUMB_VARIANT & arm_ext_sec
c921be7d 23635
21d799b5 23636 TCE("smc", 1600070, f7f08000, 1, (EXPi), smc, t_smc),
c19d1205 23637
90ec0d68
MGD
23638#undef ARM_VARIANT
23639#define ARM_VARIANT & arm_ext_virt
23640#undef THUMB_VARIANT
23641#define THUMB_VARIANT & arm_ext_virt
23642
23643 TCE("hvc", 1400070, f7e08000, 1, (EXPi), hvc, t_hvc),
23644 TCE("eret", 160006e, f3de8f00, 0, (), noargs, noargs),
23645
ddfded2f
MW
23646#undef ARM_VARIANT
23647#define ARM_VARIANT & arm_ext_pan
23648#undef THUMB_VARIANT
23649#define THUMB_VARIANT & arm_ext_pan
23650
23651 TUF("setpan", 1100000, b610, 1, (I7), setpan, t_setpan),
23652
c921be7d 23653#undef ARM_VARIANT
74db7efb 23654#define ARM_VARIANT & arm_ext_v6t2
f4c65163
MGD
23655#undef THUMB_VARIANT
23656#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 23657
21d799b5
NC
23658 TCE("bfc", 7c0001f, f36f0000, 3, (RRnpc, I31, I32), bfc, t_bfc),
23659 TCE("bfi", 7c00010, f3600000, 4, (RRnpc, RRnpc_I0, I31, I32), bfi, t_bfi),
23660 TCE("sbfx", 7a00050, f3400000, 4, (RR, RR, I31, I32), bfx, t_bfx),
23661 TCE("ubfx", 7e00050, f3c00000, 4, (RR, RR, I31, I32), bfx, t_bfx),
c19d1205 23662
21d799b5 23663 TCE("mls", 0600090, fb000010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
21d799b5 23664 TCE("rbit", 6ff0f30, fa90f0a0, 2, (RR, RR), rd_rm, t_rbit),
c19d1205 23665
5be8be5d
DG
23666 TC3("ldrht", 03000b0, f8300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
23667 TC3("ldrsht", 03000f0, f9300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
23668 TC3("ldrsbt", 03000d0, f9100e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
23669 TC3("strht", 02000b0, f8200e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
c19d1205 23670
91d8b670
JG
23671#undef ARM_VARIANT
23672#define ARM_VARIANT & arm_ext_v3
23673#undef THUMB_VARIANT
23674#define THUMB_VARIANT & arm_ext_v6t2
23675
23676 TUE("csdb", 320f014, f3af8014, 0, (), noargs, t_csdb),
c597cc3d
SD
23677 TUF("ssbb", 57ff040, f3bf8f40, 0, (), noargs, t_csdb),
23678 TUF("pssbb", 57ff044, f3bf8f44, 0, (), noargs, t_csdb),
91d8b670
JG
23679
23680#undef ARM_VARIANT
23681#define ARM_VARIANT & arm_ext_v6t2
ff8646ee
TP
23682#undef THUMB_VARIANT
23683#define THUMB_VARIANT & arm_ext_v6t2_v8m
23684 TCE("movw", 3000000, f2400000, 2, (RRnpc, HALF), mov16, t_mov16),
23685 TCE("movt", 3400000, f2c00000, 2, (RRnpc, HALF), mov16, t_mov16),
23686
bf3eeda7 23687 /* Thumb-only instructions. */
74db7efb 23688#undef ARM_VARIANT
bf3eeda7
NS
23689#define ARM_VARIANT NULL
23690 TUE("cbnz", 0, b900, 2, (RR, EXP), 0, t_cbz),
23691 TUE("cbz", 0, b100, 2, (RR, EXP), 0, t_cbz),
c921be7d
NC
23692
23693 /* ARM does not really have an IT instruction, so always allow it.
23694 The opcode is copied from Thumb in order to allow warnings in
23695 -mimplicit-it=[never | arm] modes. */
23696#undef ARM_VARIANT
23697#define ARM_VARIANT & arm_ext_v1
ff8646ee
TP
23698#undef THUMB_VARIANT
23699#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 23700
21d799b5
NC
23701 TUE("it", bf08, bf08, 1, (COND), it, t_it),
23702 TUE("itt", bf0c, bf0c, 1, (COND), it, t_it),
23703 TUE("ite", bf04, bf04, 1, (COND), it, t_it),
23704 TUE("ittt", bf0e, bf0e, 1, (COND), it, t_it),
23705 TUE("itet", bf06, bf06, 1, (COND), it, t_it),
23706 TUE("itte", bf0a, bf0a, 1, (COND), it, t_it),
23707 TUE("itee", bf02, bf02, 1, (COND), it, t_it),
23708 TUE("itttt", bf0f, bf0f, 1, (COND), it, t_it),
23709 TUE("itett", bf07, bf07, 1, (COND), it, t_it),
23710 TUE("ittet", bf0b, bf0b, 1, (COND), it, t_it),
23711 TUE("iteet", bf03, bf03, 1, (COND), it, t_it),
23712 TUE("ittte", bf0d, bf0d, 1, (COND), it, t_it),
23713 TUE("itete", bf05, bf05, 1, (COND), it, t_it),
23714 TUE("ittee", bf09, bf09, 1, (COND), it, t_it),
23715 TUE("iteee", bf01, bf01, 1, (COND), it, t_it),
1c444d06 23716 /* ARM/Thumb-2 instructions with no Thumb-1 equivalent. */
21d799b5
NC
23717 TC3("rrx", 01a00060, ea4f0030, 2, (RR, RR), rd_rm, t_rrx),
23718 TC3("rrxs", 01b00060, ea5f0030, 2, (RR, RR), rd_rm, t_rrx),
c19d1205 23719
92e90b6e 23720 /* Thumb2 only instructions. */
c921be7d
NC
23721#undef ARM_VARIANT
23722#define ARM_VARIANT NULL
92e90b6e 23723
21d799b5
NC
23724 TCE("addw", 0, f2000000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
23725 TCE("subw", 0, f2a00000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
23726 TCE("orn", 0, ea600000, 3, (RR, oRR, SH), 0, t_orn),
23727 TCE("orns", 0, ea700000, 3, (RR, oRR, SH), 0, t_orn),
23728 TCE("tbb", 0, e8d0f000, 1, (TB), 0, t_tb),
23729 TCE("tbh", 0, e8d0f010, 1, (TB), 0, t_tb),
92e90b6e 23730
eea54501
MGD
23731 /* Hardware division instructions. */
23732#undef ARM_VARIANT
23733#define ARM_VARIANT & arm_ext_adiv
c921be7d
NC
23734#undef THUMB_VARIANT
23735#define THUMB_VARIANT & arm_ext_div
23736
eea54501
MGD
23737 TCE("sdiv", 710f010, fb90f0f0, 3, (RR, oRR, RR), div, t_div),
23738 TCE("udiv", 730f010, fbb0f0f0, 3, (RR, oRR, RR), div, t_div),
62b3e311 23739
7e806470 23740 /* ARM V6M/V7 instructions. */
c921be7d
NC
23741#undef ARM_VARIANT
23742#define ARM_VARIANT & arm_ext_barrier
23743#undef THUMB_VARIANT
23744#define THUMB_VARIANT & arm_ext_barrier
23745
ccb84d65
JB
23746 TUF("dmb", 57ff050, f3bf8f50, 1, (oBARRIER_I15), barrier, barrier),
23747 TUF("dsb", 57ff040, f3bf8f40, 1, (oBARRIER_I15), barrier, barrier),
23748 TUF("isb", 57ff060, f3bf8f60, 1, (oBARRIER_I15), barrier, barrier),
7e806470 23749
62b3e311 23750 /* ARM V7 instructions. */
c921be7d
NC
23751#undef ARM_VARIANT
23752#define ARM_VARIANT & arm_ext_v7
23753#undef THUMB_VARIANT
23754#define THUMB_VARIANT & arm_ext_v7
23755
21d799b5
NC
23756 TUF("pli", 450f000, f910f000, 1, (ADDR), pli, t_pld),
23757 TCE("dbg", 320f0f0, f3af80f0, 1, (I15), dbg, t_dbg),
62b3e311 23758
74db7efb 23759#undef ARM_VARIANT
60e5ef9f 23760#define ARM_VARIANT & arm_ext_mp
74db7efb 23761#undef THUMB_VARIANT
60e5ef9f
MGD
23762#define THUMB_VARIANT & arm_ext_mp
23763
23764 TUF("pldw", 410f000, f830f000, 1, (ADDR), pld, t_pld),
23765
53c4b28b
MGD
23766 /* AArchv8 instructions. */
23767#undef ARM_VARIANT
23768#define ARM_VARIANT & arm_ext_v8
4ed7ed8d
TP
23769
23770/* Instructions shared between armv8-a and armv8-m. */
53c4b28b 23771#undef THUMB_VARIANT
4ed7ed8d 23772#define THUMB_VARIANT & arm_ext_atomics
53c4b28b 23773
4ed7ed8d
TP
23774 TCE("lda", 1900c9f, e8d00faf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
23775 TCE("ldab", 1d00c9f, e8d00f8f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
23776 TCE("ldah", 1f00c9f, e8d00f9f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
23777 TCE("stl", 180fc90, e8c00faf, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
23778 TCE("stlb", 1c0fc90, e8c00f8f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
23779 TCE("stlh", 1e0fc90, e8c00f9f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
4b8c8c02 23780 TCE("ldaex", 1900e9f, e8d00fef, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
4b8c8c02
RE
23781 TCE("ldaexb", 1d00e9f, e8d00fcf, 2, (RRnpc,RRnpcb), rd_rn, rd_rn),
23782 TCE("ldaexh", 1f00e9f, e8d00fdf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
23783 TCE("stlex", 1800e90, e8c00fe0, 3, (RRnpc, RRnpc, RRnpcb),
23784 stlex, t_stlex),
4b8c8c02
RE
23785 TCE("stlexb", 1c00e90, e8c00fc0, 3, (RRnpc, RRnpc, RRnpcb),
23786 stlex, t_stlex),
23787 TCE("stlexh", 1e00e90, e8c00fd0, 3, (RRnpc, RRnpc, RRnpcb),
23788 stlex, t_stlex),
4ed7ed8d
TP
23789#undef THUMB_VARIANT
23790#define THUMB_VARIANT & arm_ext_v8
53c4b28b 23791
4ed7ed8d 23792 tCE("sevl", 320f005, _sevl, 0, (), noargs, t_hint),
4ed7ed8d
TP
23793 TCE("ldaexd", 1b00e9f, e8d000ff, 3, (RRnpc, oRRnpc, RRnpcb),
23794 ldrexd, t_ldrexd),
23795 TCE("stlexd", 1a00e90, e8c000f0, 4, (RRnpc, RRnpc, oRRnpc, RRnpcb),
23796 strexd, t_strexd),
f7dd2fb2
TC
23797
23798/* Defined in V8 but is in undefined encoding space for earlier
23799 architectures. However earlier architectures are required to treat
23800 this instuction as a semihosting trap as well. Hence while not explicitly
23801 defined as such, it is in fact correct to define the instruction for all
23802 architectures. */
23803#undef THUMB_VARIANT
23804#define THUMB_VARIANT & arm_ext_v1
23805#undef ARM_VARIANT
23806#define ARM_VARIANT & arm_ext_v1
23807 TUE("hlt", 1000070, ba80, 1, (oIffffb), bkpt, t_hlt),
23808
8884b720 23809 /* ARMv8 T32 only. */
74db7efb 23810#undef ARM_VARIANT
b79f7053
MGD
23811#define ARM_VARIANT NULL
23812 TUF("dcps1", 0, f78f8001, 0, (), noargs, noargs),
23813 TUF("dcps2", 0, f78f8002, 0, (), noargs, noargs),
23814 TUF("dcps3", 0, f78f8003, 0, (), noargs, noargs),
23815
33399f07
MGD
23816 /* FP for ARMv8. */
23817#undef ARM_VARIANT
a715796b 23818#define ARM_VARIANT & fpu_vfp_ext_armv8xd
33399f07 23819#undef THUMB_VARIANT
a715796b 23820#define THUMB_VARIANT & fpu_vfp_ext_armv8xd
33399f07
MGD
23821
23822 nUF(vseleq, _vseleq, 3, (RVSD, RVSD, RVSD), vsel),
23823 nUF(vselvs, _vselvs, 3, (RVSD, RVSD, RVSD), vsel),
23824 nUF(vselge, _vselge, 3, (RVSD, RVSD, RVSD), vsel),
23825 nUF(vselgt, _vselgt, 3, (RVSD, RVSD, RVSD), vsel),
30bdf752 23826 nCE(vrintr, _vrintr, 2, (RNSDQ, oRNSDQ), vrintr),
a710b305
AV
23827 mnCE(vrintz, _vrintr, 2, (RNSDQMQ, oRNSDQMQ), vrintz),
23828 mnCE(vrintx, _vrintr, 2, (RNSDQMQ, oRNSDQMQ), vrintx),
23829 mnUF(vrinta, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrinta),
23830 mnUF(vrintn, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrintn),
23831 mnUF(vrintp, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrintp),
23832 mnUF(vrintm, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrintm),
33399f07 23833
91ff7894
MGD
23834 /* Crypto v1 extensions. */
23835#undef ARM_VARIANT
23836#define ARM_VARIANT & fpu_crypto_ext_armv8
23837#undef THUMB_VARIANT
23838#define THUMB_VARIANT & fpu_crypto_ext_armv8
23839
23840 nUF(aese, _aes, 2, (RNQ, RNQ), aese),
23841 nUF(aesd, _aes, 2, (RNQ, RNQ), aesd),
23842 nUF(aesmc, _aes, 2, (RNQ, RNQ), aesmc),
23843 nUF(aesimc, _aes, 2, (RNQ, RNQ), aesimc),
48adcd8e
MGD
23844 nUF(sha1c, _sha3op, 3, (RNQ, RNQ, RNQ), sha1c),
23845 nUF(sha1p, _sha3op, 3, (RNQ, RNQ, RNQ), sha1p),
23846 nUF(sha1m, _sha3op, 3, (RNQ, RNQ, RNQ), sha1m),
23847 nUF(sha1su0, _sha3op, 3, (RNQ, RNQ, RNQ), sha1su0),
23848 nUF(sha256h, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h),
23849 nUF(sha256h2, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h2),
23850 nUF(sha256su1, _sha3op, 3, (RNQ, RNQ, RNQ), sha256su1),
3c9017d2
MGD
23851 nUF(sha1h, _sha1h, 2, (RNQ, RNQ), sha1h),
23852 nUF(sha1su1, _sha2op, 2, (RNQ, RNQ), sha1su1),
23853 nUF(sha256su0, _sha2op, 2, (RNQ, RNQ), sha256su0),
91ff7894 23854
dd5181d5 23855#undef ARM_VARIANT
74db7efb 23856#define ARM_VARIANT & crc_ext_armv8
dd5181d5
KT
23857#undef THUMB_VARIANT
23858#define THUMB_VARIANT & crc_ext_armv8
23859 TUEc("crc32b", 1000040, fac0f080, 3, (RR, oRR, RR), crc32b),
23860 TUEc("crc32h", 1200040, fac0f090, 3, (RR, oRR, RR), crc32h),
23861 TUEc("crc32w", 1400040, fac0f0a0, 3, (RR, oRR, RR), crc32w),
23862 TUEc("crc32cb",1000240, fad0f080, 3, (RR, oRR, RR), crc32cb),
23863 TUEc("crc32ch",1200240, fad0f090, 3, (RR, oRR, RR), crc32ch),
23864 TUEc("crc32cw",1400240, fad0f0a0, 3, (RR, oRR, RR), crc32cw),
23865
105bde57
MW
23866 /* ARMv8.2 RAS extension. */
23867#undef ARM_VARIANT
4d1464f2 23868#define ARM_VARIANT & arm_ext_ras
105bde57 23869#undef THUMB_VARIANT
4d1464f2 23870#define THUMB_VARIANT & arm_ext_ras
105bde57
MW
23871 TUE ("esb", 320f010, f3af8010, 0, (), noargs, noargs),
23872
49e8a725
SN
23873#undef ARM_VARIANT
23874#define ARM_VARIANT & arm_ext_v8_3
23875#undef THUMB_VARIANT
23876#define THUMB_VARIANT & arm_ext_v8_3
23877 NCE (vjcvt, eb90bc0, 2, (RVS, RVD), vjcvt),
23878
c604a79a
JW
23879#undef ARM_VARIANT
23880#define ARM_VARIANT & fpu_neon_ext_dotprod
23881#undef THUMB_VARIANT
23882#define THUMB_VARIANT & fpu_neon_ext_dotprod
23883 NUF (vsdot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_s),
23884 NUF (vudot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_u),
23885
c921be7d
NC
23886#undef ARM_VARIANT
23887#define ARM_VARIANT & fpu_fpa_ext_v1 /* Core FPA instruction set (V1). */
53c4b28b
MGD
23888#undef THUMB_VARIANT
23889#define THUMB_VARIANT NULL
c921be7d 23890
21d799b5
NC
23891 cCE("wfs", e200110, 1, (RR), rd),
23892 cCE("rfs", e300110, 1, (RR), rd),
23893 cCE("wfc", e400110, 1, (RR), rd),
23894 cCE("rfc", e500110, 1, (RR), rd),
23895
23896 cCL("ldfs", c100100, 2, (RF, ADDRGLDC), rd_cpaddr),
23897 cCL("ldfd", c108100, 2, (RF, ADDRGLDC), rd_cpaddr),
23898 cCL("ldfe", c500100, 2, (RF, ADDRGLDC), rd_cpaddr),
23899 cCL("ldfp", c508100, 2, (RF, ADDRGLDC), rd_cpaddr),
23900
23901 cCL("stfs", c000100, 2, (RF, ADDRGLDC), rd_cpaddr),
23902 cCL("stfd", c008100, 2, (RF, ADDRGLDC), rd_cpaddr),
23903 cCL("stfe", c400100, 2, (RF, ADDRGLDC), rd_cpaddr),
23904 cCL("stfp", c408100, 2, (RF, ADDRGLDC), rd_cpaddr),
23905
23906 cCL("mvfs", e008100, 2, (RF, RF_IF), rd_rm),
23907 cCL("mvfsp", e008120, 2, (RF, RF_IF), rd_rm),
23908 cCL("mvfsm", e008140, 2, (RF, RF_IF), rd_rm),
23909 cCL("mvfsz", e008160, 2, (RF, RF_IF), rd_rm),
23910 cCL("mvfd", e008180, 2, (RF, RF_IF), rd_rm),
23911 cCL("mvfdp", e0081a0, 2, (RF, RF_IF), rd_rm),
23912 cCL("mvfdm", e0081c0, 2, (RF, RF_IF), rd_rm),
23913 cCL("mvfdz", e0081e0, 2, (RF, RF_IF), rd_rm),
23914 cCL("mvfe", e088100, 2, (RF, RF_IF), rd_rm),
23915 cCL("mvfep", e088120, 2, (RF, RF_IF), rd_rm),
23916 cCL("mvfem", e088140, 2, (RF, RF_IF), rd_rm),
23917 cCL("mvfez", e088160, 2, (RF, RF_IF), rd_rm),
23918
23919 cCL("mnfs", e108100, 2, (RF, RF_IF), rd_rm),
23920 cCL("mnfsp", e108120, 2, (RF, RF_IF), rd_rm),
23921 cCL("mnfsm", e108140, 2, (RF, RF_IF), rd_rm),
23922 cCL("mnfsz", e108160, 2, (RF, RF_IF), rd_rm),
23923 cCL("mnfd", e108180, 2, (RF, RF_IF), rd_rm),
23924 cCL("mnfdp", e1081a0, 2, (RF, RF_IF), rd_rm),
23925 cCL("mnfdm", e1081c0, 2, (RF, RF_IF), rd_rm),
23926 cCL("mnfdz", e1081e0, 2, (RF, RF_IF), rd_rm),
23927 cCL("mnfe", e188100, 2, (RF, RF_IF), rd_rm),
23928 cCL("mnfep", e188120, 2, (RF, RF_IF), rd_rm),
23929 cCL("mnfem", e188140, 2, (RF, RF_IF), rd_rm),
23930 cCL("mnfez", e188160, 2, (RF, RF_IF), rd_rm),
23931
23932 cCL("abss", e208100, 2, (RF, RF_IF), rd_rm),
23933 cCL("abssp", e208120, 2, (RF, RF_IF), rd_rm),
23934 cCL("abssm", e208140, 2, (RF, RF_IF), rd_rm),
23935 cCL("abssz", e208160, 2, (RF, RF_IF), rd_rm),
23936 cCL("absd", e208180, 2, (RF, RF_IF), rd_rm),
23937 cCL("absdp", e2081a0, 2, (RF, RF_IF), rd_rm),
23938 cCL("absdm", e2081c0, 2, (RF, RF_IF), rd_rm),
23939 cCL("absdz", e2081e0, 2, (RF, RF_IF), rd_rm),
23940 cCL("abse", e288100, 2, (RF, RF_IF), rd_rm),
23941 cCL("absep", e288120, 2, (RF, RF_IF), rd_rm),
23942 cCL("absem", e288140, 2, (RF, RF_IF), rd_rm),
23943 cCL("absez", e288160, 2, (RF, RF_IF), rd_rm),
23944
23945 cCL("rnds", e308100, 2, (RF, RF_IF), rd_rm),
23946 cCL("rndsp", e308120, 2, (RF, RF_IF), rd_rm),
23947 cCL("rndsm", e308140, 2, (RF, RF_IF), rd_rm),
23948 cCL("rndsz", e308160, 2, (RF, RF_IF), rd_rm),
23949 cCL("rndd", e308180, 2, (RF, RF_IF), rd_rm),
23950 cCL("rnddp", e3081a0, 2, (RF, RF_IF), rd_rm),
23951 cCL("rnddm", e3081c0, 2, (RF, RF_IF), rd_rm),
23952 cCL("rnddz", e3081e0, 2, (RF, RF_IF), rd_rm),
23953 cCL("rnde", e388100, 2, (RF, RF_IF), rd_rm),
23954 cCL("rndep", e388120, 2, (RF, RF_IF), rd_rm),
23955 cCL("rndem", e388140, 2, (RF, RF_IF), rd_rm),
23956 cCL("rndez", e388160, 2, (RF, RF_IF), rd_rm),
23957
23958 cCL("sqts", e408100, 2, (RF, RF_IF), rd_rm),
23959 cCL("sqtsp", e408120, 2, (RF, RF_IF), rd_rm),
23960 cCL("sqtsm", e408140, 2, (RF, RF_IF), rd_rm),
23961 cCL("sqtsz", e408160, 2, (RF, RF_IF), rd_rm),
23962 cCL("sqtd", e408180, 2, (RF, RF_IF), rd_rm),
23963 cCL("sqtdp", e4081a0, 2, (RF, RF_IF), rd_rm),
23964 cCL("sqtdm", e4081c0, 2, (RF, RF_IF), rd_rm),
23965 cCL("sqtdz", e4081e0, 2, (RF, RF_IF), rd_rm),
23966 cCL("sqte", e488100, 2, (RF, RF_IF), rd_rm),
23967 cCL("sqtep", e488120, 2, (RF, RF_IF), rd_rm),
23968 cCL("sqtem", e488140, 2, (RF, RF_IF), rd_rm),
23969 cCL("sqtez", e488160, 2, (RF, RF_IF), rd_rm),
23970
23971 cCL("logs", e508100, 2, (RF, RF_IF), rd_rm),
23972 cCL("logsp", e508120, 2, (RF, RF_IF), rd_rm),
23973 cCL("logsm", e508140, 2, (RF, RF_IF), rd_rm),
23974 cCL("logsz", e508160, 2, (RF, RF_IF), rd_rm),
23975 cCL("logd", e508180, 2, (RF, RF_IF), rd_rm),
23976 cCL("logdp", e5081a0, 2, (RF, RF_IF), rd_rm),
23977 cCL("logdm", e5081c0, 2, (RF, RF_IF), rd_rm),
23978 cCL("logdz", e5081e0, 2, (RF, RF_IF), rd_rm),
23979 cCL("loge", e588100, 2, (RF, RF_IF), rd_rm),
23980 cCL("logep", e588120, 2, (RF, RF_IF), rd_rm),
23981 cCL("logem", e588140, 2, (RF, RF_IF), rd_rm),
23982 cCL("logez", e588160, 2, (RF, RF_IF), rd_rm),
23983
23984 cCL("lgns", e608100, 2, (RF, RF_IF), rd_rm),
23985 cCL("lgnsp", e608120, 2, (RF, RF_IF), rd_rm),
23986 cCL("lgnsm", e608140, 2, (RF, RF_IF), rd_rm),
23987 cCL("lgnsz", e608160, 2, (RF, RF_IF), rd_rm),
23988 cCL("lgnd", e608180, 2, (RF, RF_IF), rd_rm),
23989 cCL("lgndp", e6081a0, 2, (RF, RF_IF), rd_rm),
23990 cCL("lgndm", e6081c0, 2, (RF, RF_IF), rd_rm),
23991 cCL("lgndz", e6081e0, 2, (RF, RF_IF), rd_rm),
23992 cCL("lgne", e688100, 2, (RF, RF_IF), rd_rm),
23993 cCL("lgnep", e688120, 2, (RF, RF_IF), rd_rm),
23994 cCL("lgnem", e688140, 2, (RF, RF_IF), rd_rm),
23995 cCL("lgnez", e688160, 2, (RF, RF_IF), rd_rm),
23996
23997 cCL("exps", e708100, 2, (RF, RF_IF), rd_rm),
23998 cCL("expsp", e708120, 2, (RF, RF_IF), rd_rm),
23999 cCL("expsm", e708140, 2, (RF, RF_IF), rd_rm),
24000 cCL("expsz", e708160, 2, (RF, RF_IF), rd_rm),
24001 cCL("expd", e708180, 2, (RF, RF_IF), rd_rm),
24002 cCL("expdp", e7081a0, 2, (RF, RF_IF), rd_rm),
24003 cCL("expdm", e7081c0, 2, (RF, RF_IF), rd_rm),
24004 cCL("expdz", e7081e0, 2, (RF, RF_IF), rd_rm),
24005 cCL("expe", e788100, 2, (RF, RF_IF), rd_rm),
24006 cCL("expep", e788120, 2, (RF, RF_IF), rd_rm),
24007 cCL("expem", e788140, 2, (RF, RF_IF), rd_rm),
24008 cCL("expdz", e788160, 2, (RF, RF_IF), rd_rm),
24009
24010 cCL("sins", e808100, 2, (RF, RF_IF), rd_rm),
24011 cCL("sinsp", e808120, 2, (RF, RF_IF), rd_rm),
24012 cCL("sinsm", e808140, 2, (RF, RF_IF), rd_rm),
24013 cCL("sinsz", e808160, 2, (RF, RF_IF), rd_rm),
24014 cCL("sind", e808180, 2, (RF, RF_IF), rd_rm),
24015 cCL("sindp", e8081a0, 2, (RF, RF_IF), rd_rm),
24016 cCL("sindm", e8081c0, 2, (RF, RF_IF), rd_rm),
24017 cCL("sindz", e8081e0, 2, (RF, RF_IF), rd_rm),
24018 cCL("sine", e888100, 2, (RF, RF_IF), rd_rm),
24019 cCL("sinep", e888120, 2, (RF, RF_IF), rd_rm),
24020 cCL("sinem", e888140, 2, (RF, RF_IF), rd_rm),
24021 cCL("sinez", e888160, 2, (RF, RF_IF), rd_rm),
24022
24023 cCL("coss", e908100, 2, (RF, RF_IF), rd_rm),
24024 cCL("cossp", e908120, 2, (RF, RF_IF), rd_rm),
24025 cCL("cossm", e908140, 2, (RF, RF_IF), rd_rm),
24026 cCL("cossz", e908160, 2, (RF, RF_IF), rd_rm),
24027 cCL("cosd", e908180, 2, (RF, RF_IF), rd_rm),
24028 cCL("cosdp", e9081a0, 2, (RF, RF_IF), rd_rm),
24029 cCL("cosdm", e9081c0, 2, (RF, RF_IF), rd_rm),
24030 cCL("cosdz", e9081e0, 2, (RF, RF_IF), rd_rm),
24031 cCL("cose", e988100, 2, (RF, RF_IF), rd_rm),
24032 cCL("cosep", e988120, 2, (RF, RF_IF), rd_rm),
24033 cCL("cosem", e988140, 2, (RF, RF_IF), rd_rm),
24034 cCL("cosez", e988160, 2, (RF, RF_IF), rd_rm),
24035
24036 cCL("tans", ea08100, 2, (RF, RF_IF), rd_rm),
24037 cCL("tansp", ea08120, 2, (RF, RF_IF), rd_rm),
24038 cCL("tansm", ea08140, 2, (RF, RF_IF), rd_rm),
24039 cCL("tansz", ea08160, 2, (RF, RF_IF), rd_rm),
24040 cCL("tand", ea08180, 2, (RF, RF_IF), rd_rm),
24041 cCL("tandp", ea081a0, 2, (RF, RF_IF), rd_rm),
24042 cCL("tandm", ea081c0, 2, (RF, RF_IF), rd_rm),
24043 cCL("tandz", ea081e0, 2, (RF, RF_IF), rd_rm),
24044 cCL("tane", ea88100, 2, (RF, RF_IF), rd_rm),
24045 cCL("tanep", ea88120, 2, (RF, RF_IF), rd_rm),
24046 cCL("tanem", ea88140, 2, (RF, RF_IF), rd_rm),
24047 cCL("tanez", ea88160, 2, (RF, RF_IF), rd_rm),
24048
24049 cCL("asns", eb08100, 2, (RF, RF_IF), rd_rm),
24050 cCL("asnsp", eb08120, 2, (RF, RF_IF), rd_rm),
24051 cCL("asnsm", eb08140, 2, (RF, RF_IF), rd_rm),
24052 cCL("asnsz", eb08160, 2, (RF, RF_IF), rd_rm),
24053 cCL("asnd", eb08180, 2, (RF, RF_IF), rd_rm),
24054 cCL("asndp", eb081a0, 2, (RF, RF_IF), rd_rm),
24055 cCL("asndm", eb081c0, 2, (RF, RF_IF), rd_rm),
24056 cCL("asndz", eb081e0, 2, (RF, RF_IF), rd_rm),
24057 cCL("asne", eb88100, 2, (RF, RF_IF), rd_rm),
24058 cCL("asnep", eb88120, 2, (RF, RF_IF), rd_rm),
24059 cCL("asnem", eb88140, 2, (RF, RF_IF), rd_rm),
24060 cCL("asnez", eb88160, 2, (RF, RF_IF), rd_rm),
24061
24062 cCL("acss", ec08100, 2, (RF, RF_IF), rd_rm),
24063 cCL("acssp", ec08120, 2, (RF, RF_IF), rd_rm),
24064 cCL("acssm", ec08140, 2, (RF, RF_IF), rd_rm),
24065 cCL("acssz", ec08160, 2, (RF, RF_IF), rd_rm),
24066 cCL("acsd", ec08180, 2, (RF, RF_IF), rd_rm),
24067 cCL("acsdp", ec081a0, 2, (RF, RF_IF), rd_rm),
24068 cCL("acsdm", ec081c0, 2, (RF, RF_IF), rd_rm),
24069 cCL("acsdz", ec081e0, 2, (RF, RF_IF), rd_rm),
24070 cCL("acse", ec88100, 2, (RF, RF_IF), rd_rm),
24071 cCL("acsep", ec88120, 2, (RF, RF_IF), rd_rm),
24072 cCL("acsem", ec88140, 2, (RF, RF_IF), rd_rm),
24073 cCL("acsez", ec88160, 2, (RF, RF_IF), rd_rm),
24074
24075 cCL("atns", ed08100, 2, (RF, RF_IF), rd_rm),
24076 cCL("atnsp", ed08120, 2, (RF, RF_IF), rd_rm),
24077 cCL("atnsm", ed08140, 2, (RF, RF_IF), rd_rm),
24078 cCL("atnsz", ed08160, 2, (RF, RF_IF), rd_rm),
24079 cCL("atnd", ed08180, 2, (RF, RF_IF), rd_rm),
24080 cCL("atndp", ed081a0, 2, (RF, RF_IF), rd_rm),
24081 cCL("atndm", ed081c0, 2, (RF, RF_IF), rd_rm),
24082 cCL("atndz", ed081e0, 2, (RF, RF_IF), rd_rm),
24083 cCL("atne", ed88100, 2, (RF, RF_IF), rd_rm),
24084 cCL("atnep", ed88120, 2, (RF, RF_IF), rd_rm),
24085 cCL("atnem", ed88140, 2, (RF, RF_IF), rd_rm),
24086 cCL("atnez", ed88160, 2, (RF, RF_IF), rd_rm),
24087
24088 cCL("urds", ee08100, 2, (RF, RF_IF), rd_rm),
24089 cCL("urdsp", ee08120, 2, (RF, RF_IF), rd_rm),
24090 cCL("urdsm", ee08140, 2, (RF, RF_IF), rd_rm),
24091 cCL("urdsz", ee08160, 2, (RF, RF_IF), rd_rm),
24092 cCL("urdd", ee08180, 2, (RF, RF_IF), rd_rm),
24093 cCL("urddp", ee081a0, 2, (RF, RF_IF), rd_rm),
24094 cCL("urddm", ee081c0, 2, (RF, RF_IF), rd_rm),
24095 cCL("urddz", ee081e0, 2, (RF, RF_IF), rd_rm),
24096 cCL("urde", ee88100, 2, (RF, RF_IF), rd_rm),
24097 cCL("urdep", ee88120, 2, (RF, RF_IF), rd_rm),
24098 cCL("urdem", ee88140, 2, (RF, RF_IF), rd_rm),
24099 cCL("urdez", ee88160, 2, (RF, RF_IF), rd_rm),
24100
24101 cCL("nrms", ef08100, 2, (RF, RF_IF), rd_rm),
24102 cCL("nrmsp", ef08120, 2, (RF, RF_IF), rd_rm),
24103 cCL("nrmsm", ef08140, 2, (RF, RF_IF), rd_rm),
24104 cCL("nrmsz", ef08160, 2, (RF, RF_IF), rd_rm),
24105 cCL("nrmd", ef08180, 2, (RF, RF_IF), rd_rm),
24106 cCL("nrmdp", ef081a0, 2, (RF, RF_IF), rd_rm),
24107 cCL("nrmdm", ef081c0, 2, (RF, RF_IF), rd_rm),
24108 cCL("nrmdz", ef081e0, 2, (RF, RF_IF), rd_rm),
24109 cCL("nrme", ef88100, 2, (RF, RF_IF), rd_rm),
24110 cCL("nrmep", ef88120, 2, (RF, RF_IF), rd_rm),
24111 cCL("nrmem", ef88140, 2, (RF, RF_IF), rd_rm),
24112 cCL("nrmez", ef88160, 2, (RF, RF_IF), rd_rm),
24113
24114 cCL("adfs", e000100, 3, (RF, RF, RF_IF), rd_rn_rm),
24115 cCL("adfsp", e000120, 3, (RF, RF, RF_IF), rd_rn_rm),
24116 cCL("adfsm", e000140, 3, (RF, RF, RF_IF), rd_rn_rm),
24117 cCL("adfsz", e000160, 3, (RF, RF, RF_IF), rd_rn_rm),
24118 cCL("adfd", e000180, 3, (RF, RF, RF_IF), rd_rn_rm),
24119 cCL("adfdp", e0001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
24120 cCL("adfdm", e0001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
24121 cCL("adfdz", e0001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
24122 cCL("adfe", e080100, 3, (RF, RF, RF_IF), rd_rn_rm),
24123 cCL("adfep", e080120, 3, (RF, RF, RF_IF), rd_rn_rm),
24124 cCL("adfem", e080140, 3, (RF, RF, RF_IF), rd_rn_rm),
24125 cCL("adfez", e080160, 3, (RF, RF, RF_IF), rd_rn_rm),
24126
24127 cCL("sufs", e200100, 3, (RF, RF, RF_IF), rd_rn_rm),
24128 cCL("sufsp", e200120, 3, (RF, RF, RF_IF), rd_rn_rm),
24129 cCL("sufsm", e200140, 3, (RF, RF, RF_IF), rd_rn_rm),
24130 cCL("sufsz", e200160, 3, (RF, RF, RF_IF), rd_rn_rm),
24131 cCL("sufd", e200180, 3, (RF, RF, RF_IF), rd_rn_rm),
24132 cCL("sufdp", e2001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
24133 cCL("sufdm", e2001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
24134 cCL("sufdz", e2001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
24135 cCL("sufe", e280100, 3, (RF, RF, RF_IF), rd_rn_rm),
24136 cCL("sufep", e280120, 3, (RF, RF, RF_IF), rd_rn_rm),
24137 cCL("sufem", e280140, 3, (RF, RF, RF_IF), rd_rn_rm),
24138 cCL("sufez", e280160, 3, (RF, RF, RF_IF), rd_rn_rm),
24139
24140 cCL("rsfs", e300100, 3, (RF, RF, RF_IF), rd_rn_rm),
24141 cCL("rsfsp", e300120, 3, (RF, RF, RF_IF), rd_rn_rm),
24142 cCL("rsfsm", e300140, 3, (RF, RF, RF_IF), rd_rn_rm),
24143 cCL("rsfsz", e300160, 3, (RF, RF, RF_IF), rd_rn_rm),
24144 cCL("rsfd", e300180, 3, (RF, RF, RF_IF), rd_rn_rm),
24145 cCL("rsfdp", e3001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
24146 cCL("rsfdm", e3001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
24147 cCL("rsfdz", e3001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
24148 cCL("rsfe", e380100, 3, (RF, RF, RF_IF), rd_rn_rm),
24149 cCL("rsfep", e380120, 3, (RF, RF, RF_IF), rd_rn_rm),
24150 cCL("rsfem", e380140, 3, (RF, RF, RF_IF), rd_rn_rm),
24151 cCL("rsfez", e380160, 3, (RF, RF, RF_IF), rd_rn_rm),
24152
24153 cCL("mufs", e100100, 3, (RF, RF, RF_IF), rd_rn_rm),
24154 cCL("mufsp", e100120, 3, (RF, RF, RF_IF), rd_rn_rm),
24155 cCL("mufsm", e100140, 3, (RF, RF, RF_IF), rd_rn_rm),
24156 cCL("mufsz", e100160, 3, (RF, RF, RF_IF), rd_rn_rm),
24157 cCL("mufd", e100180, 3, (RF, RF, RF_IF), rd_rn_rm),
24158 cCL("mufdp", e1001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
24159 cCL("mufdm", e1001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
24160 cCL("mufdz", e1001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
24161 cCL("mufe", e180100, 3, (RF, RF, RF_IF), rd_rn_rm),
24162 cCL("mufep", e180120, 3, (RF, RF, RF_IF), rd_rn_rm),
24163 cCL("mufem", e180140, 3, (RF, RF, RF_IF), rd_rn_rm),
24164 cCL("mufez", e180160, 3, (RF, RF, RF_IF), rd_rn_rm),
24165
24166 cCL("dvfs", e400100, 3, (RF, RF, RF_IF), rd_rn_rm),
24167 cCL("dvfsp", e400120, 3, (RF, RF, RF_IF), rd_rn_rm),
24168 cCL("dvfsm", e400140, 3, (RF, RF, RF_IF), rd_rn_rm),
24169 cCL("dvfsz", e400160, 3, (RF, RF, RF_IF), rd_rn_rm),
24170 cCL("dvfd", e400180, 3, (RF, RF, RF_IF), rd_rn_rm),
24171 cCL("dvfdp", e4001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
24172 cCL("dvfdm", e4001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
24173 cCL("dvfdz", e4001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
24174 cCL("dvfe", e480100, 3, (RF, RF, RF_IF), rd_rn_rm),
24175 cCL("dvfep", e480120, 3, (RF, RF, RF_IF), rd_rn_rm),
24176 cCL("dvfem", e480140, 3, (RF, RF, RF_IF), rd_rn_rm),
24177 cCL("dvfez", e480160, 3, (RF, RF, RF_IF), rd_rn_rm),
24178
24179 cCL("rdfs", e500100, 3, (RF, RF, RF_IF), rd_rn_rm),
24180 cCL("rdfsp", e500120, 3, (RF, RF, RF_IF), rd_rn_rm),
24181 cCL("rdfsm", e500140, 3, (RF, RF, RF_IF), rd_rn_rm),
24182 cCL("rdfsz", e500160, 3, (RF, RF, RF_IF), rd_rn_rm),
24183 cCL("rdfd", e500180, 3, (RF, RF, RF_IF), rd_rn_rm),
24184 cCL("rdfdp", e5001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
24185 cCL("rdfdm", e5001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
24186 cCL("rdfdz", e5001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
24187 cCL("rdfe", e580100, 3, (RF, RF, RF_IF), rd_rn_rm),
24188 cCL("rdfep", e580120, 3, (RF, RF, RF_IF), rd_rn_rm),
24189 cCL("rdfem", e580140, 3, (RF, RF, RF_IF), rd_rn_rm),
24190 cCL("rdfez", e580160, 3, (RF, RF, RF_IF), rd_rn_rm),
24191
24192 cCL("pows", e600100, 3, (RF, RF, RF_IF), rd_rn_rm),
24193 cCL("powsp", e600120, 3, (RF, RF, RF_IF), rd_rn_rm),
24194 cCL("powsm", e600140, 3, (RF, RF, RF_IF), rd_rn_rm),
24195 cCL("powsz", e600160, 3, (RF, RF, RF_IF), rd_rn_rm),
24196 cCL("powd", e600180, 3, (RF, RF, RF_IF), rd_rn_rm),
24197 cCL("powdp", e6001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
24198 cCL("powdm", e6001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
24199 cCL("powdz", e6001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
24200 cCL("powe", e680100, 3, (RF, RF, RF_IF), rd_rn_rm),
24201 cCL("powep", e680120, 3, (RF, RF, RF_IF), rd_rn_rm),
24202 cCL("powem", e680140, 3, (RF, RF, RF_IF), rd_rn_rm),
24203 cCL("powez", e680160, 3, (RF, RF, RF_IF), rd_rn_rm),
24204
24205 cCL("rpws", e700100, 3, (RF, RF, RF_IF), rd_rn_rm),
24206 cCL("rpwsp", e700120, 3, (RF, RF, RF_IF), rd_rn_rm),
24207 cCL("rpwsm", e700140, 3, (RF, RF, RF_IF), rd_rn_rm),
24208 cCL("rpwsz", e700160, 3, (RF, RF, RF_IF), rd_rn_rm),
24209 cCL("rpwd", e700180, 3, (RF, RF, RF_IF), rd_rn_rm),
24210 cCL("rpwdp", e7001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
24211 cCL("rpwdm", e7001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
24212 cCL("rpwdz", e7001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
24213 cCL("rpwe", e780100, 3, (RF, RF, RF_IF), rd_rn_rm),
24214 cCL("rpwep", e780120, 3, (RF, RF, RF_IF), rd_rn_rm),
24215 cCL("rpwem", e780140, 3, (RF, RF, RF_IF), rd_rn_rm),
24216 cCL("rpwez", e780160, 3, (RF, RF, RF_IF), rd_rn_rm),
24217
24218 cCL("rmfs", e800100, 3, (RF, RF, RF_IF), rd_rn_rm),
24219 cCL("rmfsp", e800120, 3, (RF, RF, RF_IF), rd_rn_rm),
24220 cCL("rmfsm", e800140, 3, (RF, RF, RF_IF), rd_rn_rm),
24221 cCL("rmfsz", e800160, 3, (RF, RF, RF_IF), rd_rn_rm),
24222 cCL("rmfd", e800180, 3, (RF, RF, RF_IF), rd_rn_rm),
24223 cCL("rmfdp", e8001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
24224 cCL("rmfdm", e8001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
24225 cCL("rmfdz", e8001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
24226 cCL("rmfe", e880100, 3, (RF, RF, RF_IF), rd_rn_rm),
24227 cCL("rmfep", e880120, 3, (RF, RF, RF_IF), rd_rn_rm),
24228 cCL("rmfem", e880140, 3, (RF, RF, RF_IF), rd_rn_rm),
24229 cCL("rmfez", e880160, 3, (RF, RF, RF_IF), rd_rn_rm),
24230
24231 cCL("fmls", e900100, 3, (RF, RF, RF_IF), rd_rn_rm),
24232 cCL("fmlsp", e900120, 3, (RF, RF, RF_IF), rd_rn_rm),
24233 cCL("fmlsm", e900140, 3, (RF, RF, RF_IF), rd_rn_rm),
24234 cCL("fmlsz", e900160, 3, (RF, RF, RF_IF), rd_rn_rm),
24235 cCL("fmld", e900180, 3, (RF, RF, RF_IF), rd_rn_rm),
24236 cCL("fmldp", e9001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
24237 cCL("fmldm", e9001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
24238 cCL("fmldz", e9001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
24239 cCL("fmle", e980100, 3, (RF, RF, RF_IF), rd_rn_rm),
24240 cCL("fmlep", e980120, 3, (RF, RF, RF_IF), rd_rn_rm),
24241 cCL("fmlem", e980140, 3, (RF, RF, RF_IF), rd_rn_rm),
24242 cCL("fmlez", e980160, 3, (RF, RF, RF_IF), rd_rn_rm),
24243
24244 cCL("fdvs", ea00100, 3, (RF, RF, RF_IF), rd_rn_rm),
24245 cCL("fdvsp", ea00120, 3, (RF, RF, RF_IF), rd_rn_rm),
24246 cCL("fdvsm", ea00140, 3, (RF, RF, RF_IF), rd_rn_rm),
24247 cCL("fdvsz", ea00160, 3, (RF, RF, RF_IF), rd_rn_rm),
24248 cCL("fdvd", ea00180, 3, (RF, RF, RF_IF), rd_rn_rm),
24249 cCL("fdvdp", ea001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
24250 cCL("fdvdm", ea001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
24251 cCL("fdvdz", ea001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
24252 cCL("fdve", ea80100, 3, (RF, RF, RF_IF), rd_rn_rm),
24253 cCL("fdvep", ea80120, 3, (RF, RF, RF_IF), rd_rn_rm),
24254 cCL("fdvem", ea80140, 3, (RF, RF, RF_IF), rd_rn_rm),
24255 cCL("fdvez", ea80160, 3, (RF, RF, RF_IF), rd_rn_rm),
24256
24257 cCL("frds", eb00100, 3, (RF, RF, RF_IF), rd_rn_rm),
24258 cCL("frdsp", eb00120, 3, (RF, RF, RF_IF), rd_rn_rm),
24259 cCL("frdsm", eb00140, 3, (RF, RF, RF_IF), rd_rn_rm),
24260 cCL("frdsz", eb00160, 3, (RF, RF, RF_IF), rd_rn_rm),
24261 cCL("frdd", eb00180, 3, (RF, RF, RF_IF), rd_rn_rm),
24262 cCL("frddp", eb001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
24263 cCL("frddm", eb001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
24264 cCL("frddz", eb001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
24265 cCL("frde", eb80100, 3, (RF, RF, RF_IF), rd_rn_rm),
24266 cCL("frdep", eb80120, 3, (RF, RF, RF_IF), rd_rn_rm),
24267 cCL("frdem", eb80140, 3, (RF, RF, RF_IF), rd_rn_rm),
24268 cCL("frdez", eb80160, 3, (RF, RF, RF_IF), rd_rn_rm),
24269
24270 cCL("pols", ec00100, 3, (RF, RF, RF_IF), rd_rn_rm),
24271 cCL("polsp", ec00120, 3, (RF, RF, RF_IF), rd_rn_rm),
24272 cCL("polsm", ec00140, 3, (RF, RF, RF_IF), rd_rn_rm),
24273 cCL("polsz", ec00160, 3, (RF, RF, RF_IF), rd_rn_rm),
24274 cCL("pold", ec00180, 3, (RF, RF, RF_IF), rd_rn_rm),
24275 cCL("poldp", ec001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
24276 cCL("poldm", ec001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
24277 cCL("poldz", ec001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
24278 cCL("pole", ec80100, 3, (RF, RF, RF_IF), rd_rn_rm),
24279 cCL("polep", ec80120, 3, (RF, RF, RF_IF), rd_rn_rm),
24280 cCL("polem", ec80140, 3, (RF, RF, RF_IF), rd_rn_rm),
24281 cCL("polez", ec80160, 3, (RF, RF, RF_IF), rd_rn_rm),
24282
24283 cCE("cmf", e90f110, 2, (RF, RF_IF), fpa_cmp),
24284 C3E("cmfe", ed0f110, 2, (RF, RF_IF), fpa_cmp),
24285 cCE("cnf", eb0f110, 2, (RF, RF_IF), fpa_cmp),
24286 C3E("cnfe", ef0f110, 2, (RF, RF_IF), fpa_cmp),
24287
24288 cCL("flts", e000110, 2, (RF, RR), rn_rd),
24289 cCL("fltsp", e000130, 2, (RF, RR), rn_rd),
24290 cCL("fltsm", e000150, 2, (RF, RR), rn_rd),
24291 cCL("fltsz", e000170, 2, (RF, RR), rn_rd),
24292 cCL("fltd", e000190, 2, (RF, RR), rn_rd),
24293 cCL("fltdp", e0001b0, 2, (RF, RR), rn_rd),
24294 cCL("fltdm", e0001d0, 2, (RF, RR), rn_rd),
24295 cCL("fltdz", e0001f0, 2, (RF, RR), rn_rd),
24296 cCL("flte", e080110, 2, (RF, RR), rn_rd),
24297 cCL("fltep", e080130, 2, (RF, RR), rn_rd),
24298 cCL("fltem", e080150, 2, (RF, RR), rn_rd),
24299 cCL("fltez", e080170, 2, (RF, RR), rn_rd),
b99bd4ef 24300
c19d1205
ZW
24301 /* The implementation of the FIX instruction is broken on some
24302 assemblers, in that it accepts a precision specifier as well as a
24303 rounding specifier, despite the fact that this is meaningless.
24304 To be more compatible, we accept it as well, though of course it
24305 does not set any bits. */
21d799b5
NC
24306 cCE("fix", e100110, 2, (RR, RF), rd_rm),
24307 cCL("fixp", e100130, 2, (RR, RF), rd_rm),
24308 cCL("fixm", e100150, 2, (RR, RF), rd_rm),
24309 cCL("fixz", e100170, 2, (RR, RF), rd_rm),
24310 cCL("fixsp", e100130, 2, (RR, RF), rd_rm),
24311 cCL("fixsm", e100150, 2, (RR, RF), rd_rm),
24312 cCL("fixsz", e100170, 2, (RR, RF), rd_rm),
24313 cCL("fixdp", e100130, 2, (RR, RF), rd_rm),
24314 cCL("fixdm", e100150, 2, (RR, RF), rd_rm),
24315 cCL("fixdz", e100170, 2, (RR, RF), rd_rm),
24316 cCL("fixep", e100130, 2, (RR, RF), rd_rm),
24317 cCL("fixem", e100150, 2, (RR, RF), rd_rm),
24318 cCL("fixez", e100170, 2, (RR, RF), rd_rm),
bfae80f2 24319
c19d1205 24320 /* Instructions that were new with the real FPA, call them V2. */
c921be7d
NC
24321#undef ARM_VARIANT
24322#define ARM_VARIANT & fpu_fpa_ext_v2
24323
21d799b5
NC
24324 cCE("lfm", c100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
24325 cCL("lfmfd", c900200, 3, (RF, I4b, ADDR), fpa_ldmstm),
24326 cCL("lfmea", d100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
24327 cCE("sfm", c000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
24328 cCL("sfmfd", d000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
24329 cCL("sfmea", c800200, 3, (RF, I4b, ADDR), fpa_ldmstm),
c19d1205 24330
c921be7d
NC
24331#undef ARM_VARIANT
24332#define ARM_VARIANT & fpu_vfp_ext_v1xd /* VFP V1xD (single precision). */
24333
c19d1205 24334 /* Moves and type conversions. */
21d799b5 24335 cCE("fmstat", ef1fa10, 0, (), noargs),
7465e07a
NC
24336 cCE("vmrs", ef00a10, 2, (APSR_RR, RVC), vmrs),
24337 cCE("vmsr", ee00a10, 2, (RVC, RR), vmsr),
21d799b5
NC
24338 cCE("fsitos", eb80ac0, 2, (RVS, RVS), vfp_sp_monadic),
24339 cCE("fuitos", eb80a40, 2, (RVS, RVS), vfp_sp_monadic),
24340 cCE("ftosis", ebd0a40, 2, (RVS, RVS), vfp_sp_monadic),
24341 cCE("ftosizs", ebd0ac0, 2, (RVS, RVS), vfp_sp_monadic),
24342 cCE("ftouis", ebc0a40, 2, (RVS, RVS), vfp_sp_monadic),
24343 cCE("ftouizs", ebc0ac0, 2, (RVS, RVS), vfp_sp_monadic),
24344 cCE("fmrx", ef00a10, 2, (RR, RVC), rd_rn),
24345 cCE("fmxr", ee00a10, 2, (RVC, RR), rn_rd),
c19d1205
ZW
24346
24347 /* Memory operations. */
21d799b5
NC
24348 cCE("flds", d100a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
24349 cCE("fsts", d000a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
55881a11
MGD
24350 cCE("fldmias", c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
24351 cCE("fldmfds", c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
24352 cCE("fldmdbs", d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
24353 cCE("fldmeas", d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
24354 cCE("fldmiax", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
24355 cCE("fldmfdx", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
24356 cCE("fldmdbx", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
24357 cCE("fldmeax", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
24358 cCE("fstmias", c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
24359 cCE("fstmeas", c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
24360 cCE("fstmdbs", d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
24361 cCE("fstmfds", d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
24362 cCE("fstmiax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
24363 cCE("fstmeax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
24364 cCE("fstmdbx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
24365 cCE("fstmfdx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
bfae80f2 24366
c19d1205 24367 /* Monadic operations. */
21d799b5
NC
24368 cCE("fabss", eb00ac0, 2, (RVS, RVS), vfp_sp_monadic),
24369 cCE("fnegs", eb10a40, 2, (RVS, RVS), vfp_sp_monadic),
24370 cCE("fsqrts", eb10ac0, 2, (RVS, RVS), vfp_sp_monadic),
c19d1205
ZW
24371
24372 /* Dyadic operations. */
21d799b5
NC
24373 cCE("fadds", e300a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
24374 cCE("fsubs", e300a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
24375 cCE("fmuls", e200a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
24376 cCE("fdivs", e800a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
24377 cCE("fmacs", e000a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
24378 cCE("fmscs", e100a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
24379 cCE("fnmuls", e200a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
24380 cCE("fnmacs", e000a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
24381 cCE("fnmscs", e100a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
b99bd4ef 24382
c19d1205 24383 /* Comparisons. */
21d799b5
NC
24384 cCE("fcmps", eb40a40, 2, (RVS, RVS), vfp_sp_monadic),
24385 cCE("fcmpzs", eb50a40, 1, (RVS), vfp_sp_compare_z),
24386 cCE("fcmpes", eb40ac0, 2, (RVS, RVS), vfp_sp_monadic),
24387 cCE("fcmpezs", eb50ac0, 1, (RVS), vfp_sp_compare_z),
b99bd4ef 24388
62f3b8c8
PB
24389 /* Double precision load/store are still present on single precision
24390 implementations. */
24391 cCE("fldd", d100b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
24392 cCE("fstd", d000b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
55881a11
MGD
24393 cCE("fldmiad", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
24394 cCE("fldmfdd", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
24395 cCE("fldmdbd", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
24396 cCE("fldmead", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
24397 cCE("fstmiad", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
24398 cCE("fstmead", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
24399 cCE("fstmdbd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
24400 cCE("fstmfdd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
62f3b8c8 24401
c921be7d
NC
24402#undef ARM_VARIANT
24403#define ARM_VARIANT & fpu_vfp_ext_v1 /* VFP V1 (Double precision). */
24404
c19d1205 24405 /* Moves and type conversions. */
21d799b5
NC
24406 cCE("fcvtds", eb70ac0, 2, (RVD, RVS), vfp_dp_sp_cvt),
24407 cCE("fcvtsd", eb70bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
24408 cCE("fmdhr", e200b10, 2, (RVD, RR), vfp_dp_rn_rd),
24409 cCE("fmdlr", e000b10, 2, (RVD, RR), vfp_dp_rn_rd),
24410 cCE("fmrdh", e300b10, 2, (RR, RVD), vfp_dp_rd_rn),
24411 cCE("fmrdl", e100b10, 2, (RR, RVD), vfp_dp_rd_rn),
24412 cCE("fsitod", eb80bc0, 2, (RVD, RVS), vfp_dp_sp_cvt),
24413 cCE("fuitod", eb80b40, 2, (RVD, RVS), vfp_dp_sp_cvt),
24414 cCE("ftosid", ebd0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
24415 cCE("ftosizd", ebd0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
24416 cCE("ftouid", ebc0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
24417 cCE("ftouizd", ebc0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
c19d1205 24418
c19d1205 24419 /* Monadic operations. */
21d799b5
NC
24420 cCE("fabsd", eb00bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
24421 cCE("fnegd", eb10b40, 2, (RVD, RVD), vfp_dp_rd_rm),
24422 cCE("fsqrtd", eb10bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
c19d1205
ZW
24423
24424 /* Dyadic operations. */
21d799b5
NC
24425 cCE("faddd", e300b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
24426 cCE("fsubd", e300b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
24427 cCE("fmuld", e200b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
24428 cCE("fdivd", e800b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
24429 cCE("fmacd", e000b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
24430 cCE("fmscd", e100b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
24431 cCE("fnmuld", e200b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
24432 cCE("fnmacd", e000b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
24433 cCE("fnmscd", e100b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
b99bd4ef 24434
c19d1205 24435 /* Comparisons. */
21d799b5
NC
24436 cCE("fcmpd", eb40b40, 2, (RVD, RVD), vfp_dp_rd_rm),
24437 cCE("fcmpzd", eb50b40, 1, (RVD), vfp_dp_rd),
24438 cCE("fcmped", eb40bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
24439 cCE("fcmpezd", eb50bc0, 1, (RVD), vfp_dp_rd),
c19d1205 24440
037e8744
JB
24441/* Instructions which may belong to either the Neon or VFP instruction sets.
24442 Individual encoder functions perform additional architecture checks. */
c921be7d
NC
24443#undef ARM_VARIANT
24444#define ARM_VARIANT & fpu_vfp_ext_v1xd
24445#undef THUMB_VARIANT
24446#define THUMB_VARIANT & fpu_vfp_ext_v1xd
24447
037e8744
JB
24448 /* These mnemonics are unique to VFP. */
24449 NCE(vsqrt, 0, 2, (RVSD, RVSD), vfp_nsyn_sqrt),
24450 NCE(vdiv, 0, 3, (RVSD, RVSD, RVSD), vfp_nsyn_div),
21d799b5
NC
24451 nCE(vnmul, _vnmul, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
24452 nCE(vnmla, _vnmla, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
24453 nCE(vnmls, _vnmls, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
037e8744
JB
24454 NCE(vpush, 0, 1, (VRSDLST), vfp_nsyn_push),
24455 NCE(vpop, 0, 1, (VRSDLST), vfp_nsyn_pop),
24456 NCE(vcvtz, 0, 2, (RVSD, RVSD), vfp_nsyn_cvtz),
24457
24458 /* Mnemonics shared by Neon and VFP. */
21d799b5 24459 nCEF(vmls, _vmls, 3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
037e8744 24460
55881a11
MGD
24461 NCE(vldm, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
24462 NCE(vldmia, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
24463 NCE(vldmdb, d100b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
24464 NCE(vstm, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
24465 NCE(vstmia, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
24466 NCE(vstmdb, d000b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
037e8744 24467
dd9634d9 24468 mnCEF(vcvt, _vcvt, 3, (RNSDQMQ, RNSDQMQ, oI32z), neon_cvt),
e3e535bc 24469 nCEF(vcvtr, _vcvt, 2, (RNSDQ, RNSDQ), neon_cvtr),
dd9634d9
AV
24470 MNCEF(vcvtb, eb20a40, 3, (RVSDMQ, RVSDMQ, oI32b), neon_cvtb),
24471 MNCEF(vcvtt, eb20a40, 3, (RVSDMQ, RVSDMQ, oI32b), neon_cvtt),
f31fef98 24472
037e8744
JB
24473
24474 /* NOTE: All VMOV encoding is special-cased! */
037e8744
JB
24475 NCE(vmovq, 0, 1, (VMOV), neon_mov),
24476
32c36c3c
AV
24477#undef THUMB_VARIANT
24478/* Could be either VLDR/VSTR or VLDR/VSTR (system register) which are guarded
24479 by different feature bits. Since we are setting the Thumb guard, we can
24480 require Thumb-1 which makes it a nop guard and set the right feature bit in
24481 do_vldr_vstr (). */
24482#define THUMB_VARIANT & arm_ext_v4t
24483 NCE(vldr, d100b00, 2, (VLDR, ADDRGLDC), vldr_vstr),
24484 NCE(vstr, d000b00, 2, (VLDR, ADDRGLDC), vldr_vstr),
24485
9db2f6b4
RL
24486#undef ARM_VARIANT
24487#define ARM_VARIANT & arm_ext_fp16
24488#undef THUMB_VARIANT
24489#define THUMB_VARIANT & arm_ext_fp16
24490 /* New instructions added from v8.2, allowing the extraction and insertion of
24491 the upper 16 bits of a 32-bit vector register. */
24492 NCE (vmovx, eb00a40, 2, (RVS, RVS), neon_movhf),
24493 NCE (vins, eb00ac0, 2, (RVS, RVS), neon_movhf),
24494
dec41383
JW
24495 /* New backported fma/fms instructions optional in v8.2. */
24496 NCE (vfmal, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmal),
24497 NCE (vfmsl, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmsl),
24498
c921be7d
NC
24499#undef THUMB_VARIANT
24500#define THUMB_VARIANT & fpu_neon_ext_v1
24501#undef ARM_VARIANT
24502#define ARM_VARIANT & fpu_neon_ext_v1
24503
5287ad62
JB
24504 /* Data processing with three registers of the same length. */
24505 /* integer ops, valid types S8 S16 S32 U8 U16 U32. */
24506 NUF(vaba, 0000710, 3, (RNDQ, RNDQ, RNDQ), neon_dyadic_i_su),
24507 NUF(vabaq, 0000710, 3, (RNQ, RNQ, RNQ), neon_dyadic_i_su),
5287ad62 24508 NUF(vhaddq, 0000000, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
5287ad62 24509 NUF(vrhaddq, 0000100, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
5287ad62
JB
24510 NUF(vhsubq, 0000200, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
24511 /* integer ops, valid types S8 S16 S32 S64 U8 U16 U32 U64. */
5287ad62 24512 NUF(vqaddq, 0000010, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
5287ad62 24513 NUF(vqsubq, 0000210, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
627907b7 24514 NUF(vrshlq, 0000500, 3, (RNQ, oRNQ, RNQ), neon_rshl),
627907b7 24515 NUF(vqrshlq, 0000510, 3, (RNQ, oRNQ, RNQ), neon_rshl),
5287ad62 24516 /* If not immediate, fall back to neon_dyadic_i64_su.
5150f0d8
AV
24517 shl should accept I8 I16 I32 I64,
24518 qshl should accept S8 S16 S32 S64 U8 U16 U32 U64. */
24519 nUF(vshlq, _vshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_shl),
24520 nUF(vqshlq, _vqshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_qshl),
5287ad62 24521 /* Logic ops, types optional & ignored. */
4316f0d2 24522 nUF(vandq, _vand, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 24523 nUF(vbicq, _vbic, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 24524 nUF(vorrq, _vorr, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 24525 nUF(vornq, _vorn, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 24526 nUF(veorq, _veor, 3, (RNQ, oRNQ, RNQ), neon_logic),
5287ad62
JB
24527 /* Bitfield ops, untyped. */
24528 NUF(vbsl, 1100110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
24529 NUF(vbslq, 1100110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
24530 NUF(vbit, 1200110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
24531 NUF(vbitq, 1200110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
24532 NUF(vbif, 1300110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
24533 NUF(vbifq, 1300110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
cc933301 24534 /* Int and float variants, types S8 S16 S32 U8 U16 U32 F16 F32. */
21d799b5 24535 nUF(vabdq, _vabd, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21d799b5 24536 nUF(vmaxq, _vmax, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21d799b5 24537 nUF(vminq, _vmin, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
5287ad62
JB
24538 /* Comparisons. Types S8 S16 S32 U8 U16 U32 F32. Non-immediate versions fall
24539 back to neon_dyadic_if_su. */
21d799b5
NC
24540 nUF(vcge, _vcge, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
24541 nUF(vcgeq, _vcge, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
24542 nUF(vcgt, _vcgt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
24543 nUF(vcgtq, _vcgt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
24544 nUF(vclt, _vclt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
24545 nUF(vcltq, _vclt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
24546 nUF(vcle, _vcle, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
24547 nUF(vcleq, _vcle, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
428e3f1f 24548 /* Comparison. Type I8 I16 I32 F32. */
21d799b5
NC
24549 nUF(vceq, _vceq, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_ceq),
24550 nUF(vceqq, _vceq, 3, (RNQ, oRNQ, RNDQ_I0), neon_ceq),
5287ad62 24551 /* As above, D registers only. */
21d799b5
NC
24552 nUF(vpmax, _vpmax, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
24553 nUF(vpmin, _vpmin, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
5287ad62 24554 /* Int and float variants, signedness unimportant. */
21d799b5
NC
24555 nUF(vmlaq, _vmla, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
24556 nUF(vmlsq, _vmls, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
24557 nUF(vpadd, _vpadd, 3, (RND, oRND, RND), neon_dyadic_if_i_d),
5287ad62 24558 /* Add/sub take types I8 I16 I32 I64 F32. */
21d799b5
NC
24559 nUF(vaddq, _vadd, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
24560 nUF(vsubq, _vsub, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
5287ad62
JB
24561 /* vtst takes sizes 8, 16, 32. */
24562 NUF(vtst, 0000810, 3, (RNDQ, oRNDQ, RNDQ), neon_tst),
24563 NUF(vtstq, 0000810, 3, (RNQ, oRNQ, RNQ), neon_tst),
24564 /* VMUL takes I8 I16 I32 F32 P8. */
21d799b5 24565 nUF(vmulq, _vmul, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mul),
5287ad62 24566 /* VQD{R}MULH takes S16 S32. */
21d799b5 24567 nUF(vqdmulhq, _vqdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
21d799b5 24568 nUF(vqrdmulhq, _vqrdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
5287ad62
JB
24569 NUF(vacge, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
24570 NUF(vacgeq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
24571 NUF(vacgt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
24572 NUF(vacgtq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
92559b5b
PB
24573 NUF(vaclt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
24574 NUF(vacltq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
24575 NUF(vacle, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
24576 NUF(vacleq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
5287ad62
JB
24577 NUF(vrecps, 0000f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
24578 NUF(vrecpsq, 0000f10, 3, (RNQ, oRNQ, RNQ), neon_step),
24579 NUF(vrsqrts, 0200f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
24580 NUF(vrsqrtsq, 0200f10, 3, (RNQ, oRNQ, RNQ), neon_step),
d6b4b13e 24581 /* ARM v8.1 extension. */
643afb90
MW
24582 nUF (vqrdmlahq, _vqrdmlah, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
24583 nUF (vqrdmlsh, _vqrdmlsh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qrdmlah),
24584 nUF (vqrdmlshq, _vqrdmlsh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
5287ad62
JB
24585
24586 /* Two address, int/float. Types S8 S16 S32 F32. */
5287ad62 24587 NUF(vabsq, 1b10300, 2, (RNQ, RNQ), neon_abs_neg),
5287ad62
JB
24588 NUF(vnegq, 1b10380, 2, (RNQ, RNQ), neon_abs_neg),
24589
24590 /* Data processing with two registers and a shift amount. */
24591 /* Right shifts, and variants with rounding.
24592 Types accepted S8 S16 S32 S64 U8 U16 U32 U64. */
5287ad62 24593 NUF(vshrq, 0800010, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
5287ad62
JB
24594 NUF(vrshrq, 0800210, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
24595 NUF(vsra, 0800110, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
24596 NUF(vsraq, 0800110, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
24597 NUF(vrsra, 0800310, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
24598 NUF(vrsraq, 0800310, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
24599 /* Shift and insert. Sizes accepted 8 16 32 64. */
5287ad62 24600 NUF(vsliq, 1800510, 3, (RNQ, oRNQ, I63), neon_sli),
5287ad62
JB
24601 NUF(vsriq, 1800410, 3, (RNQ, oRNQ, I64), neon_sri),
24602 /* QSHL{U} immediate accepts S8 S16 S32 S64 U8 U16 U32 U64. */
5287ad62
JB
24603 NUF(vqshluq, 1800610, 3, (RNQ, oRNQ, I63), neon_qshlu_imm),
24604 /* Right shift immediate, saturating & narrowing, with rounding variants.
24605 Types accepted S16 S32 S64 U16 U32 U64. */
24606 NUF(vqshrn, 0800910, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
24607 NUF(vqrshrn, 0800950, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
24608 /* As above, unsigned. Types accepted S16 S32 S64. */
24609 NUF(vqshrun, 0800810, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
24610 NUF(vqrshrun, 0800850, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
24611 /* Right shift narrowing. Types accepted I16 I32 I64. */
24612 NUF(vshrn, 0800810, 3, (RND, RNQ, I32z), neon_rshift_narrow),
24613 NUF(vrshrn, 0800850, 3, (RND, RNQ, I32z), neon_rshift_narrow),
24614 /* Special case. Types S8 S16 S32 U8 U16 U32. Handles max shift variant. */
21d799b5 24615 nUF(vshll, _vshll, 3, (RNQ, RND, I32), neon_shll),
5287ad62 24616 /* CVT with optional immediate for fixed-point variant. */
21d799b5 24617 nUF(vcvtq, _vcvt, 3, (RNQ, RNQ, oI32b), neon_cvt),
b7fc2769 24618
4316f0d2 24619 nUF(vmvnq, _vmvn, 2, (RNQ, RNDQ_Ibig), neon_mvn),
5287ad62
JB
24620
24621 /* Data processing, three registers of different lengths. */
24622 /* Dyadic, long insns. Types S8 S16 S32 U8 U16 U32. */
24623 NUF(vabal, 0800500, 3, (RNQ, RND, RND), neon_abal),
5287ad62
JB
24624 /* If not scalar, fall back to neon_dyadic_long.
24625 Vector types as above, scalar types S16 S32 U16 U32. */
21d799b5
NC
24626 nUF(vmlal, _vmlal, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
24627 nUF(vmlsl, _vmlsl, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
5287ad62
JB
24628 /* Dyadic, widening insns. Types S8 S16 S32 U8 U16 U32. */
24629 NUF(vaddw, 0800100, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
24630 NUF(vsubw, 0800300, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
24631 /* Dyadic, narrowing insns. Types I16 I32 I64. */
24632 NUF(vaddhn, 0800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
24633 NUF(vraddhn, 1800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
24634 NUF(vsubhn, 0800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
24635 NUF(vrsubhn, 1800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
24636 /* Saturating doubling multiplies. Types S16 S32. */
21d799b5
NC
24637 nUF(vqdmlal, _vqdmlal, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
24638 nUF(vqdmlsl, _vqdmlsl, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
24639 nUF(vqdmull, _vqdmull, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
5287ad62
JB
24640 /* VMULL. Vector types S8 S16 S32 U8 U16 U32 P8, scalar types
24641 S16 S32 U16 U32. */
21d799b5 24642 nUF(vmull, _vmull, 3, (RNQ, RND, RND_RNSC), neon_vmull),
5287ad62
JB
24643
24644 /* Extract. Size 8. */
3b8d421e
PB
24645 NUF(vext, 0b00000, 4, (RNDQ, oRNDQ, RNDQ, I15), neon_ext),
24646 NUF(vextq, 0b00000, 4, (RNQ, oRNQ, RNQ, I15), neon_ext),
5287ad62
JB
24647
24648 /* Two registers, miscellaneous. */
24649 /* Reverse. Sizes 8 16 32 (must be < size in opcode). */
5287ad62 24650 NUF(vrev64q, 1b00000, 2, (RNQ, RNQ), neon_rev),
5287ad62 24651 NUF(vrev32q, 1b00080, 2, (RNQ, RNQ), neon_rev),
5287ad62
JB
24652 NUF(vrev16q, 1b00100, 2, (RNQ, RNQ), neon_rev),
24653 /* Vector replicate. Sizes 8 16 32. */
21d799b5 24654 nCE(vdupq, _vdup, 2, (RNQ, RR_RNSC), neon_dup),
5287ad62
JB
24655 /* VMOVL. Types S8 S16 S32 U8 U16 U32. */
24656 NUF(vmovl, 0800a10, 2, (RNQ, RND), neon_movl),
24657 /* VMOVN. Types I16 I32 I64. */
21d799b5 24658 nUF(vmovn, _vmovn, 2, (RND, RNQ), neon_movn),
5287ad62 24659 /* VQMOVN. Types S16 S32 S64 U16 U32 U64. */
21d799b5 24660 nUF(vqmovn, _vqmovn, 2, (RND, RNQ), neon_qmovn),
5287ad62 24661 /* VQMOVUN. Types S16 S32 S64. */
21d799b5 24662 nUF(vqmovun, _vqmovun, 2, (RND, RNQ), neon_qmovun),
5287ad62
JB
24663 /* VZIP / VUZP. Sizes 8 16 32. */
24664 NUF(vzip, 1b20180, 2, (RNDQ, RNDQ), neon_zip_uzp),
24665 NUF(vzipq, 1b20180, 2, (RNQ, RNQ), neon_zip_uzp),
24666 NUF(vuzp, 1b20100, 2, (RNDQ, RNDQ), neon_zip_uzp),
24667 NUF(vuzpq, 1b20100, 2, (RNQ, RNQ), neon_zip_uzp),
24668 /* VQABS / VQNEG. Types S8 S16 S32. */
5287ad62 24669 NUF(vqabsq, 1b00700, 2, (RNQ, RNQ), neon_sat_abs_neg),
5287ad62
JB
24670 NUF(vqnegq, 1b00780, 2, (RNQ, RNQ), neon_sat_abs_neg),
24671 /* Pairwise, lengthening. Types S8 S16 S32 U8 U16 U32. */
24672 NUF(vpadal, 1b00600, 2, (RNDQ, RNDQ), neon_pair_long),
24673 NUF(vpadalq, 1b00600, 2, (RNQ, RNQ), neon_pair_long),
24674 NUF(vpaddl, 1b00200, 2, (RNDQ, RNDQ), neon_pair_long),
24675 NUF(vpaddlq, 1b00200, 2, (RNQ, RNQ), neon_pair_long),
cc933301 24676 /* Reciprocal estimates. Types U32 F16 F32. */
5287ad62
JB
24677 NUF(vrecpe, 1b30400, 2, (RNDQ, RNDQ), neon_recip_est),
24678 NUF(vrecpeq, 1b30400, 2, (RNQ, RNQ), neon_recip_est),
24679 NUF(vrsqrte, 1b30480, 2, (RNDQ, RNDQ), neon_recip_est),
24680 NUF(vrsqrteq, 1b30480, 2, (RNQ, RNQ), neon_recip_est),
24681 /* VCLS. Types S8 S16 S32. */
5287ad62
JB
24682 NUF(vclsq, 1b00400, 2, (RNQ, RNQ), neon_cls),
24683 /* VCLZ. Types I8 I16 I32. */
5287ad62
JB
24684 NUF(vclzq, 1b00480, 2, (RNQ, RNQ), neon_clz),
24685 /* VCNT. Size 8. */
24686 NUF(vcnt, 1b00500, 2, (RNDQ, RNDQ), neon_cnt),
24687 NUF(vcntq, 1b00500, 2, (RNQ, RNQ), neon_cnt),
24688 /* Two address, untyped. */
24689 NUF(vswp, 1b20000, 2, (RNDQ, RNDQ), neon_swp),
24690 NUF(vswpq, 1b20000, 2, (RNQ, RNQ), neon_swp),
24691 /* VTRN. Sizes 8 16 32. */
21d799b5
NC
24692 nUF(vtrn, _vtrn, 2, (RNDQ, RNDQ), neon_trn),
24693 nUF(vtrnq, _vtrn, 2, (RNQ, RNQ), neon_trn),
5287ad62
JB
24694
24695 /* Table lookup. Size 8. */
24696 NUF(vtbl, 1b00800, 3, (RND, NRDLST, RND), neon_tbl_tbx),
24697 NUF(vtbx, 1b00840, 3, (RND, NRDLST, RND), neon_tbl_tbx),
24698
c921be7d
NC
24699#undef THUMB_VARIANT
24700#define THUMB_VARIANT & fpu_vfp_v3_or_neon_ext
24701#undef ARM_VARIANT
24702#define ARM_VARIANT & fpu_vfp_v3_or_neon_ext
24703
5287ad62 24704 /* Neon element/structure load/store. */
21d799b5
NC
24705 nUF(vld1, _vld1, 2, (NSTRLST, ADDR), neon_ldx_stx),
24706 nUF(vst1, _vst1, 2, (NSTRLST, ADDR), neon_ldx_stx),
24707 nUF(vld2, _vld2, 2, (NSTRLST, ADDR), neon_ldx_stx),
24708 nUF(vst2, _vst2, 2, (NSTRLST, ADDR), neon_ldx_stx),
24709 nUF(vld3, _vld3, 2, (NSTRLST, ADDR), neon_ldx_stx),
24710 nUF(vst3, _vst3, 2, (NSTRLST, ADDR), neon_ldx_stx),
24711 nUF(vld4, _vld4, 2, (NSTRLST, ADDR), neon_ldx_stx),
24712 nUF(vst4, _vst4, 2, (NSTRLST, ADDR), neon_ldx_stx),
5287ad62 24713
c921be7d 24714#undef THUMB_VARIANT
74db7efb
NC
24715#define THUMB_VARIANT & fpu_vfp_ext_v3xd
24716#undef ARM_VARIANT
24717#define ARM_VARIANT & fpu_vfp_ext_v3xd
62f3b8c8
PB
24718 cCE("fconsts", eb00a00, 2, (RVS, I255), vfp_sp_const),
24719 cCE("fshtos", eba0a40, 2, (RVS, I16z), vfp_sp_conv_16),
24720 cCE("fsltos", eba0ac0, 2, (RVS, I32), vfp_sp_conv_32),
24721 cCE("fuhtos", ebb0a40, 2, (RVS, I16z), vfp_sp_conv_16),
24722 cCE("fultos", ebb0ac0, 2, (RVS, I32), vfp_sp_conv_32),
24723 cCE("ftoshs", ebe0a40, 2, (RVS, I16z), vfp_sp_conv_16),
24724 cCE("ftosls", ebe0ac0, 2, (RVS, I32), vfp_sp_conv_32),
24725 cCE("ftouhs", ebf0a40, 2, (RVS, I16z), vfp_sp_conv_16),
24726 cCE("ftouls", ebf0ac0, 2, (RVS, I32), vfp_sp_conv_32),
24727
74db7efb 24728#undef THUMB_VARIANT
c921be7d
NC
24729#define THUMB_VARIANT & fpu_vfp_ext_v3
24730#undef ARM_VARIANT
24731#define ARM_VARIANT & fpu_vfp_ext_v3
24732
21d799b5 24733 cCE("fconstd", eb00b00, 2, (RVD, I255), vfp_dp_const),
21d799b5 24734 cCE("fshtod", eba0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 24735 cCE("fsltod", eba0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 24736 cCE("fuhtod", ebb0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 24737 cCE("fultod", ebb0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 24738 cCE("ftoshd", ebe0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 24739 cCE("ftosld", ebe0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 24740 cCE("ftouhd", ebf0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 24741 cCE("ftould", ebf0bc0, 2, (RVD, I32), vfp_dp_conv_32),
c19d1205 24742
74db7efb
NC
24743#undef ARM_VARIANT
24744#define ARM_VARIANT & fpu_vfp_ext_fma
24745#undef THUMB_VARIANT
24746#define THUMB_VARIANT & fpu_vfp_ext_fma
d58196e0 24747 /* Mnemonics shared by Neon, VFP and MVE. These are included in the
62f3b8c8
PB
24748 VFP FMA variant; NEON and VFP FMA always includes the NEON
24749 FMA instructions. */
d58196e0
AV
24750 mnCEF(vfma, _vfma, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_fmac),
24751 mnCEF(vfms, _vfms, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), neon_fmac),
24752
62f3b8c8
PB
24753 /* ffmas/ffmad/ffmss/ffmsd are dummy mnemonics to satisfy gas;
24754 the v form should always be used. */
24755 cCE("ffmas", ea00a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
24756 cCE("ffnmas", ea00a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
24757 cCE("ffmad", ea00b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
24758 cCE("ffnmad", ea00b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
24759 nCE(vfnma, _vfnma, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
24760 nCE(vfnms, _vfnms, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
24761
5287ad62 24762#undef THUMB_VARIANT
c921be7d
NC
24763#undef ARM_VARIANT
24764#define ARM_VARIANT & arm_cext_xscale /* Intel XScale extensions. */
24765
21d799b5
NC
24766 cCE("mia", e200010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
24767 cCE("miaph", e280010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
24768 cCE("miabb", e2c0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
24769 cCE("miabt", e2d0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
24770 cCE("miatb", e2e0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
24771 cCE("miatt", e2f0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
24772 cCE("mar", c400000, 3, (RXA, RRnpc, RRnpc), xsc_mar),
24773 cCE("mra", c500000, 3, (RRnpc, RRnpc, RXA), xsc_mra),
c19d1205 24774
c921be7d
NC
24775#undef ARM_VARIANT
24776#define ARM_VARIANT & arm_cext_iwmmxt /* Intel Wireless MMX technology. */
24777
21d799b5
NC
24778 cCE("tandcb", e13f130, 1, (RR), iwmmxt_tandorc),
24779 cCE("tandch", e53f130, 1, (RR), iwmmxt_tandorc),
24780 cCE("tandcw", e93f130, 1, (RR), iwmmxt_tandorc),
24781 cCE("tbcstb", e400010, 2, (RIWR, RR), rn_rd),
24782 cCE("tbcsth", e400050, 2, (RIWR, RR), rn_rd),
24783 cCE("tbcstw", e400090, 2, (RIWR, RR), rn_rd),
24784 cCE("textrcb", e130170, 2, (RR, I7), iwmmxt_textrc),
24785 cCE("textrch", e530170, 2, (RR, I7), iwmmxt_textrc),
24786 cCE("textrcw", e930170, 2, (RR, I7), iwmmxt_textrc),
74db7efb
NC
24787 cCE("textrmub",e100070, 3, (RR, RIWR, I7), iwmmxt_textrm),
24788 cCE("textrmuh",e500070, 3, (RR, RIWR, I7), iwmmxt_textrm),
24789 cCE("textrmuw",e900070, 3, (RR, RIWR, I7), iwmmxt_textrm),
24790 cCE("textrmsb",e100078, 3, (RR, RIWR, I7), iwmmxt_textrm),
24791 cCE("textrmsh",e500078, 3, (RR, RIWR, I7), iwmmxt_textrm),
24792 cCE("textrmsw",e900078, 3, (RR, RIWR, I7), iwmmxt_textrm),
21d799b5
NC
24793 cCE("tinsrb", e600010, 3, (RIWR, RR, I7), iwmmxt_tinsr),
24794 cCE("tinsrh", e600050, 3, (RIWR, RR, I7), iwmmxt_tinsr),
24795 cCE("tinsrw", e600090, 3, (RIWR, RR, I7), iwmmxt_tinsr),
24796 cCE("tmcr", e000110, 2, (RIWC_RIWG, RR), rn_rd),
24797 cCE("tmcrr", c400000, 3, (RIWR, RR, RR), rm_rd_rn),
24798 cCE("tmia", e200010, 3, (RIWR, RR, RR), iwmmxt_tmia),
24799 cCE("tmiaph", e280010, 3, (RIWR, RR, RR), iwmmxt_tmia),
24800 cCE("tmiabb", e2c0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
24801 cCE("tmiabt", e2d0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
24802 cCE("tmiatb", e2e0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
24803 cCE("tmiatt", e2f0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
74db7efb
NC
24804 cCE("tmovmskb",e100030, 2, (RR, RIWR), rd_rn),
24805 cCE("tmovmskh",e500030, 2, (RR, RIWR), rd_rn),
24806 cCE("tmovmskw",e900030, 2, (RR, RIWR), rd_rn),
21d799b5
NC
24807 cCE("tmrc", e100110, 2, (RR, RIWC_RIWG), rd_rn),
24808 cCE("tmrrc", c500000, 3, (RR, RR, RIWR), rd_rn_rm),
24809 cCE("torcb", e13f150, 1, (RR), iwmmxt_tandorc),
24810 cCE("torch", e53f150, 1, (RR), iwmmxt_tandorc),
24811 cCE("torcw", e93f150, 1, (RR), iwmmxt_tandorc),
24812 cCE("waccb", e0001c0, 2, (RIWR, RIWR), rd_rn),
24813 cCE("wacch", e4001c0, 2, (RIWR, RIWR), rd_rn),
24814 cCE("waccw", e8001c0, 2, (RIWR, RIWR), rd_rn),
24815 cCE("waddbss", e300180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24816 cCE("waddb", e000180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24817 cCE("waddbus", e100180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24818 cCE("waddhss", e700180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24819 cCE("waddh", e400180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24820 cCE("waddhus", e500180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24821 cCE("waddwss", eb00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24822 cCE("waddw", e800180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24823 cCE("waddwus", e900180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24824 cCE("waligni", e000020, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_waligni),
74db7efb
NC
24825 cCE("walignr0",e800020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24826 cCE("walignr1",e900020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24827 cCE("walignr2",ea00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24828 cCE("walignr3",eb00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
24829 cCE("wand", e200000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24830 cCE("wandn", e300000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24831 cCE("wavg2b", e800000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24832 cCE("wavg2br", e900000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24833 cCE("wavg2h", ec00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24834 cCE("wavg2hr", ed00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24835 cCE("wcmpeqb", e000060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24836 cCE("wcmpeqh", e400060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24837 cCE("wcmpeqw", e800060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
24838 cCE("wcmpgtub",e100060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24839 cCE("wcmpgtuh",e500060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24840 cCE("wcmpgtuw",e900060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24841 cCE("wcmpgtsb",e300060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24842 cCE("wcmpgtsh",e700060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24843 cCE("wcmpgtsw",eb00060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
24844 cCE("wldrb", c100000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
24845 cCE("wldrh", c500000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
24846 cCE("wldrw", c100100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
24847 cCE("wldrd", c500100, 2, (RIWR, ADDR), iwmmxt_wldstd),
24848 cCE("wmacs", e600100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24849 cCE("wmacsz", e700100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24850 cCE("wmacu", e400100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24851 cCE("wmacuz", e500100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24852 cCE("wmadds", ea00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24853 cCE("wmaddu", e800100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24854 cCE("wmaxsb", e200160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24855 cCE("wmaxsh", e600160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24856 cCE("wmaxsw", ea00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24857 cCE("wmaxub", e000160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24858 cCE("wmaxuh", e400160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24859 cCE("wmaxuw", e800160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24860 cCE("wminsb", e300160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24861 cCE("wminsh", e700160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24862 cCE("wminsw", eb00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24863 cCE("wminub", e100160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24864 cCE("wminuh", e500160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24865 cCE("wminuw", e900160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24866 cCE("wmov", e000000, 2, (RIWR, RIWR), iwmmxt_wmov),
24867 cCE("wmulsm", e300100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24868 cCE("wmulsl", e200100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24869 cCE("wmulum", e100100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24870 cCE("wmulul", e000100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24871 cCE("wor", e000000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
24872 cCE("wpackhss",e700080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24873 cCE("wpackhus",e500080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24874 cCE("wpackwss",eb00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24875 cCE("wpackwus",e900080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24876 cCE("wpackdss",ef00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24877 cCE("wpackdus",ed00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
24878 cCE("wrorh", e700040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24879 cCE("wrorhg", e700148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24880 cCE("wrorw", eb00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24881 cCE("wrorwg", eb00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24882 cCE("wrord", ef00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24883 cCE("wrordg", ef00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24884 cCE("wsadb", e000120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24885 cCE("wsadbz", e100120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24886 cCE("wsadh", e400120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24887 cCE("wsadhz", e500120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24888 cCE("wshufh", e0001e0, 3, (RIWR, RIWR, I255), iwmmxt_wshufh),
24889 cCE("wsllh", e500040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24890 cCE("wsllhg", e500148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24891 cCE("wsllw", e900040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24892 cCE("wsllwg", e900148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24893 cCE("wslld", ed00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24894 cCE("wslldg", ed00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24895 cCE("wsrah", e400040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24896 cCE("wsrahg", e400148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24897 cCE("wsraw", e800040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24898 cCE("wsrawg", e800148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24899 cCE("wsrad", ec00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24900 cCE("wsradg", ec00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24901 cCE("wsrlh", e600040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24902 cCE("wsrlhg", e600148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24903 cCE("wsrlw", ea00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24904 cCE("wsrlwg", ea00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24905 cCE("wsrld", ee00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24906 cCE("wsrldg", ee00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24907 cCE("wstrb", c000000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
24908 cCE("wstrh", c400000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
24909 cCE("wstrw", c000100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
24910 cCE("wstrd", c400100, 2, (RIWR, ADDR), iwmmxt_wldstd),
24911 cCE("wsubbss", e3001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24912 cCE("wsubb", e0001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24913 cCE("wsubbus", e1001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24914 cCE("wsubhss", e7001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24915 cCE("wsubh", e4001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24916 cCE("wsubhus", e5001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24917 cCE("wsubwss", eb001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24918 cCE("wsubw", e8001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24919 cCE("wsubwus", e9001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24920 cCE("wunpckehub",e0000c0, 2, (RIWR, RIWR), rd_rn),
24921 cCE("wunpckehuh",e4000c0, 2, (RIWR, RIWR), rd_rn),
24922 cCE("wunpckehuw",e8000c0, 2, (RIWR, RIWR), rd_rn),
24923 cCE("wunpckehsb",e2000c0, 2, (RIWR, RIWR), rd_rn),
24924 cCE("wunpckehsh",e6000c0, 2, (RIWR, RIWR), rd_rn),
24925 cCE("wunpckehsw",ea000c0, 2, (RIWR, RIWR), rd_rn),
24926 cCE("wunpckihb", e1000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24927 cCE("wunpckihh", e5000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24928 cCE("wunpckihw", e9000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24929 cCE("wunpckelub",e0000e0, 2, (RIWR, RIWR), rd_rn),
24930 cCE("wunpckeluh",e4000e0, 2, (RIWR, RIWR), rd_rn),
24931 cCE("wunpckeluw",e8000e0, 2, (RIWR, RIWR), rd_rn),
24932 cCE("wunpckelsb",e2000e0, 2, (RIWR, RIWR), rd_rn),
24933 cCE("wunpckelsh",e6000e0, 2, (RIWR, RIWR), rd_rn),
24934 cCE("wunpckelsw",ea000e0, 2, (RIWR, RIWR), rd_rn),
24935 cCE("wunpckilb", e1000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24936 cCE("wunpckilh", e5000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24937 cCE("wunpckilw", e9000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24938 cCE("wxor", e100000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24939 cCE("wzero", e300000, 1, (RIWR), iwmmxt_wzero),
c19d1205 24940
c921be7d
NC
24941#undef ARM_VARIANT
24942#define ARM_VARIANT & arm_cext_iwmmxt2 /* Intel Wireless MMX technology, version 2. */
24943
21d799b5
NC
24944 cCE("torvscb", e12f190, 1, (RR), iwmmxt_tandorc),
24945 cCE("torvsch", e52f190, 1, (RR), iwmmxt_tandorc),
24946 cCE("torvscw", e92f190, 1, (RR), iwmmxt_tandorc),
24947 cCE("wabsb", e2001c0, 2, (RIWR, RIWR), rd_rn),
24948 cCE("wabsh", e6001c0, 2, (RIWR, RIWR), rd_rn),
24949 cCE("wabsw", ea001c0, 2, (RIWR, RIWR), rd_rn),
24950 cCE("wabsdiffb", e1001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24951 cCE("wabsdiffh", e5001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24952 cCE("wabsdiffw", e9001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24953 cCE("waddbhusl", e2001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24954 cCE("waddbhusm", e6001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24955 cCE("waddhc", e600180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24956 cCE("waddwc", ea00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24957 cCE("waddsubhx", ea001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24958 cCE("wavg4", e400000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24959 cCE("wavg4r", e500000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24960 cCE("wmaddsn", ee00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24961 cCE("wmaddsx", eb00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24962 cCE("wmaddun", ec00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24963 cCE("wmaddux", e900100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24964 cCE("wmerge", e000080, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_wmerge),
24965 cCE("wmiabb", e0000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24966 cCE("wmiabt", e1000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24967 cCE("wmiatb", e2000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24968 cCE("wmiatt", e3000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24969 cCE("wmiabbn", e4000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24970 cCE("wmiabtn", e5000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24971 cCE("wmiatbn", e6000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24972 cCE("wmiattn", e7000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24973 cCE("wmiawbb", e800120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24974 cCE("wmiawbt", e900120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24975 cCE("wmiawtb", ea00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24976 cCE("wmiawtt", eb00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24977 cCE("wmiawbbn", ec00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24978 cCE("wmiawbtn", ed00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24979 cCE("wmiawtbn", ee00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24980 cCE("wmiawttn", ef00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24981 cCE("wmulsmr", ef00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24982 cCE("wmulumr", ed00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24983 cCE("wmulwumr", ec000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24984 cCE("wmulwsmr", ee000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24985 cCE("wmulwum", ed000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24986 cCE("wmulwsm", ef000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24987 cCE("wmulwl", eb000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24988 cCE("wqmiabb", e8000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24989 cCE("wqmiabt", e9000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24990 cCE("wqmiatb", ea000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24991 cCE("wqmiatt", eb000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24992 cCE("wqmiabbn", ec000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24993 cCE("wqmiabtn", ed000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24994 cCE("wqmiatbn", ee000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24995 cCE("wqmiattn", ef000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24996 cCE("wqmulm", e100080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24997 cCE("wqmulmr", e300080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24998 cCE("wqmulwm", ec000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24999 cCE("wqmulwmr", ee000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
25000 cCE("wsubaddhx", ed001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
2d447fca 25001
c921be7d
NC
25002#undef ARM_VARIANT
25003#define ARM_VARIANT & arm_cext_maverick /* Cirrus Maverick instructions. */
25004
21d799b5
NC
25005 cCE("cfldrs", c100400, 2, (RMF, ADDRGLDC), rd_cpaddr),
25006 cCE("cfldrd", c500400, 2, (RMD, ADDRGLDC), rd_cpaddr),
25007 cCE("cfldr32", c100500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
25008 cCE("cfldr64", c500500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
25009 cCE("cfstrs", c000400, 2, (RMF, ADDRGLDC), rd_cpaddr),
25010 cCE("cfstrd", c400400, 2, (RMD, ADDRGLDC), rd_cpaddr),
25011 cCE("cfstr32", c000500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
25012 cCE("cfstr64", c400500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
25013 cCE("cfmvsr", e000450, 2, (RMF, RR), rn_rd),
25014 cCE("cfmvrs", e100450, 2, (RR, RMF), rd_rn),
25015 cCE("cfmvdlr", e000410, 2, (RMD, RR), rn_rd),
25016 cCE("cfmvrdl", e100410, 2, (RR, RMD), rd_rn),
25017 cCE("cfmvdhr", e000430, 2, (RMD, RR), rn_rd),
25018 cCE("cfmvrdh", e100430, 2, (RR, RMD), rd_rn),
74db7efb
NC
25019 cCE("cfmv64lr",e000510, 2, (RMDX, RR), rn_rd),
25020 cCE("cfmvr64l",e100510, 2, (RR, RMDX), rd_rn),
25021 cCE("cfmv64hr",e000530, 2, (RMDX, RR), rn_rd),
25022 cCE("cfmvr64h",e100530, 2, (RR, RMDX), rd_rn),
25023 cCE("cfmval32",e200440, 2, (RMAX, RMFX), rd_rn),
25024 cCE("cfmv32al",e100440, 2, (RMFX, RMAX), rd_rn),
25025 cCE("cfmvam32",e200460, 2, (RMAX, RMFX), rd_rn),
25026 cCE("cfmv32am",e100460, 2, (RMFX, RMAX), rd_rn),
25027 cCE("cfmvah32",e200480, 2, (RMAX, RMFX), rd_rn),
25028 cCE("cfmv32ah",e100480, 2, (RMFX, RMAX), rd_rn),
21d799b5
NC
25029 cCE("cfmva32", e2004a0, 2, (RMAX, RMFX), rd_rn),
25030 cCE("cfmv32a", e1004a0, 2, (RMFX, RMAX), rd_rn),
25031 cCE("cfmva64", e2004c0, 2, (RMAX, RMDX), rd_rn),
25032 cCE("cfmv64a", e1004c0, 2, (RMDX, RMAX), rd_rn),
74db7efb
NC
25033 cCE("cfmvsc32",e2004e0, 2, (RMDS, RMDX), mav_dspsc),
25034 cCE("cfmv32sc",e1004e0, 2, (RMDX, RMDS), rd),
21d799b5
NC
25035 cCE("cfcpys", e000400, 2, (RMF, RMF), rd_rn),
25036 cCE("cfcpyd", e000420, 2, (RMD, RMD), rd_rn),
25037 cCE("cfcvtsd", e000460, 2, (RMD, RMF), rd_rn),
25038 cCE("cfcvtds", e000440, 2, (RMF, RMD), rd_rn),
74db7efb
NC
25039 cCE("cfcvt32s",e000480, 2, (RMF, RMFX), rd_rn),
25040 cCE("cfcvt32d",e0004a0, 2, (RMD, RMFX), rd_rn),
25041 cCE("cfcvt64s",e0004c0, 2, (RMF, RMDX), rd_rn),
25042 cCE("cfcvt64d",e0004e0, 2, (RMD, RMDX), rd_rn),
25043 cCE("cfcvts32",e100580, 2, (RMFX, RMF), rd_rn),
25044 cCE("cfcvtd32",e1005a0, 2, (RMFX, RMD), rd_rn),
21d799b5
NC
25045 cCE("cftruncs32",e1005c0, 2, (RMFX, RMF), rd_rn),
25046 cCE("cftruncd32",e1005e0, 2, (RMFX, RMD), rd_rn),
74db7efb
NC
25047 cCE("cfrshl32",e000550, 3, (RMFX, RMFX, RR), mav_triple),
25048 cCE("cfrshl64",e000570, 3, (RMDX, RMDX, RR), mav_triple),
21d799b5
NC
25049 cCE("cfsh32", e000500, 3, (RMFX, RMFX, I63s), mav_shift),
25050 cCE("cfsh64", e200500, 3, (RMDX, RMDX, I63s), mav_shift),
25051 cCE("cfcmps", e100490, 3, (RR, RMF, RMF), rd_rn_rm),
25052 cCE("cfcmpd", e1004b0, 3, (RR, RMD, RMD), rd_rn_rm),
25053 cCE("cfcmp32", e100590, 3, (RR, RMFX, RMFX), rd_rn_rm),
25054 cCE("cfcmp64", e1005b0, 3, (RR, RMDX, RMDX), rd_rn_rm),
25055 cCE("cfabss", e300400, 2, (RMF, RMF), rd_rn),
25056 cCE("cfabsd", e300420, 2, (RMD, RMD), rd_rn),
25057 cCE("cfnegs", e300440, 2, (RMF, RMF), rd_rn),
25058 cCE("cfnegd", e300460, 2, (RMD, RMD), rd_rn),
25059 cCE("cfadds", e300480, 3, (RMF, RMF, RMF), rd_rn_rm),
25060 cCE("cfaddd", e3004a0, 3, (RMD, RMD, RMD), rd_rn_rm),
25061 cCE("cfsubs", e3004c0, 3, (RMF, RMF, RMF), rd_rn_rm),
25062 cCE("cfsubd", e3004e0, 3, (RMD, RMD, RMD), rd_rn_rm),
25063 cCE("cfmuls", e100400, 3, (RMF, RMF, RMF), rd_rn_rm),
25064 cCE("cfmuld", e100420, 3, (RMD, RMD, RMD), rd_rn_rm),
25065 cCE("cfabs32", e300500, 2, (RMFX, RMFX), rd_rn),
25066 cCE("cfabs64", e300520, 2, (RMDX, RMDX), rd_rn),
25067 cCE("cfneg32", e300540, 2, (RMFX, RMFX), rd_rn),
25068 cCE("cfneg64", e300560, 2, (RMDX, RMDX), rd_rn),
25069 cCE("cfadd32", e300580, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
25070 cCE("cfadd64", e3005a0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
25071 cCE("cfsub32", e3005c0, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
25072 cCE("cfsub64", e3005e0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
25073 cCE("cfmul32", e100500, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
25074 cCE("cfmul64", e100520, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
25075 cCE("cfmac32", e100540, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
25076 cCE("cfmsc32", e100560, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
74db7efb
NC
25077 cCE("cfmadd32",e000600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
25078 cCE("cfmsub32",e100600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
21d799b5
NC
25079 cCE("cfmadda32", e200600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
25080 cCE("cfmsuba32", e300600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
4ed7ed8d 25081
7fadb25d
SD
25082 /* ARMv8.5-A instructions. */
25083#undef ARM_VARIANT
25084#define ARM_VARIANT & arm_ext_sb
25085#undef THUMB_VARIANT
25086#define THUMB_VARIANT & arm_ext_sb
25087 TUF("sb", 57ff070, f3bf8f70, 0, (), noargs, noargs),
25088
dad0c3bf
SD
25089#undef ARM_VARIANT
25090#define ARM_VARIANT & arm_ext_predres
25091#undef THUMB_VARIANT
25092#define THUMB_VARIANT & arm_ext_predres
25093 CE("cfprctx", e070f93, 1, (RRnpc), rd),
25094 CE("dvprctx", e070fb3, 1, (RRnpc), rd),
25095 CE("cpprctx", e070ff3, 1, (RRnpc), rd),
25096
16a1fa25 25097 /* ARMv8-M instructions. */
4ed7ed8d
TP
25098#undef ARM_VARIANT
25099#define ARM_VARIANT NULL
25100#undef THUMB_VARIANT
25101#define THUMB_VARIANT & arm_ext_v8m
cf3cf39d
TP
25102 ToU("sg", e97fe97f, 0, (), noargs),
25103 ToC("blxns", 4784, 1, (RRnpc), t_blx),
25104 ToC("bxns", 4704, 1, (RRnpc), t_bx),
25105 ToC("tt", e840f000, 2, (RRnpc, RRnpc), tt),
25106 ToC("ttt", e840f040, 2, (RRnpc, RRnpc), tt),
25107 ToC("tta", e840f080, 2, (RRnpc, RRnpc), tt),
25108 ToC("ttat", e840f0c0, 2, (RRnpc, RRnpc), tt),
16a1fa25
TP
25109
25110 /* FP for ARMv8-M Mainline. Enabled for ARMv8-M Mainline because the
25111 instructions behave as nop if no VFP is present. */
25112#undef THUMB_VARIANT
25113#define THUMB_VARIANT & arm_ext_v8m_main
cf3cf39d
TP
25114 ToC("vlldm", ec300a00, 1, (RRnpc), rn),
25115 ToC("vlstm", ec200a00, 1, (RRnpc), rn),
4389b29a
AV
25116
25117 /* Armv8.1-M Mainline instructions. */
25118#undef THUMB_VARIANT
25119#define THUMB_VARIANT & arm_ext_v8_1m_main
25120 toC("bf", _bf, 2, (EXPs, EXPs), t_branch_future),
f6b2b12d 25121 toU("bfcsel", _bfcsel, 4, (EXPs, EXPs, EXPs, COND), t_branch_future),
f1c7f421 25122 toC("bfx", _bfx, 2, (EXPs, RRnpcsp), t_branch_future),
65d1bc05 25123 toC("bfl", _bfl, 2, (EXPs, EXPs), t_branch_future),
f1c7f421 25124 toC("bflx", _bflx, 2, (EXPs, RRnpcsp), t_branch_future),
60f993ce
AV
25125
25126 toU("dls", _dls, 2, (LR, RRnpcsp), t_loloop),
25127 toU("wls", _wls, 3, (LR, RRnpcsp, EXP), t_loloop),
25128 toU("le", _le, 2, (oLR, EXP), t_loloop),
4b5a202f 25129
efd6b359 25130 ToC("clrm", e89f0000, 1, (CLRMLST), t_clrm),
5ee91343
AV
25131 ToC("vscclrm", ec9f0a00, 1, (VRSDVLST), t_vscclrm),
25132
25133#undef THUMB_VARIANT
25134#define THUMB_VARIANT & mve_ext
1b883319
AV
25135
25136 ToC("vpt", ee410f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
25137 ToC("vptt", ee018f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
25138 ToC("vpte", ee418f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
25139 ToC("vpttt", ee014f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
25140 ToC("vptte", ee01cf00, 3, (COND, RMQ, RMQRZ), mve_vpt),
25141 ToC("vptet", ee41cf00, 3, (COND, RMQ, RMQRZ), mve_vpt),
25142 ToC("vptee", ee414f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
25143 ToC("vptttt", ee012f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
25144 ToC("vpttte", ee016f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
25145 ToC("vpttet", ee01ef00, 3, (COND, RMQ, RMQRZ), mve_vpt),
25146 ToC("vpttee", ee01af00, 3, (COND, RMQ, RMQRZ), mve_vpt),
25147 ToC("vptett", ee41af00, 3, (COND, RMQ, RMQRZ), mve_vpt),
25148 ToC("vptete", ee41ef00, 3, (COND, RMQ, RMQRZ), mve_vpt),
25149 ToC("vpteet", ee416f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
25150 ToC("vpteee", ee412f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
25151
5ee91343
AV
25152 ToC("vpst", fe710f4d, 0, (), mve_vpt),
25153 ToC("vpstt", fe318f4d, 0, (), mve_vpt),
25154 ToC("vpste", fe718f4d, 0, (), mve_vpt),
25155 ToC("vpsttt", fe314f4d, 0, (), mve_vpt),
25156 ToC("vpstte", fe31cf4d, 0, (), mve_vpt),
25157 ToC("vpstet", fe71cf4d, 0, (), mve_vpt),
25158 ToC("vpstee", fe714f4d, 0, (), mve_vpt),
25159 ToC("vpstttt", fe312f4d, 0, (), mve_vpt),
25160 ToC("vpsttte", fe316f4d, 0, (), mve_vpt),
25161 ToC("vpsttet", fe31ef4d, 0, (), mve_vpt),
25162 ToC("vpsttee", fe31af4d, 0, (), mve_vpt),
25163 ToC("vpstett", fe71af4d, 0, (), mve_vpt),
25164 ToC("vpstete", fe71ef4d, 0, (), mve_vpt),
25165 ToC("vpsteet", fe716f4d, 0, (), mve_vpt),
25166 ToC("vpsteee", fe712f4d, 0, (), mve_vpt),
25167
a302e574 25168 /* MVE and MVE FP only. */
7df54120 25169 mToC("vhcadd", ee000f00, 4, (RMQ, RMQ, RMQ, EXPi), mve_vhcadd),
c2dafc2a
AV
25170 mCEF(vadc, _vadc, 3, (RMQ, RMQ, RMQ), mve_vadc),
25171 mCEF(vadci, _vadci, 3, (RMQ, RMQ, RMQ), mve_vadc),
25172 mToC("vsbc", fe300f00, 3, (RMQ, RMQ, RMQ), mve_vsbc),
25173 mToC("vsbci", fe301f00, 3, (RMQ, RMQ, RMQ), mve_vsbc),
886e1c73 25174 mCEF(vmullb, _vmullb, 3, (RMQ, RMQ, RMQ), mve_vmull),
a302e574
AV
25175 mCEF(vabav, _vabav, 3, (RRnpcsp, RMQ, RMQ), mve_vabav),
25176 mCEF(vmladav, _vmladav, 3, (RRe, RMQ, RMQ), mve_vmladav),
25177 mCEF(vmladava, _vmladava, 3, (RRe, RMQ, RMQ), mve_vmladav),
25178 mCEF(vmladavx, _vmladavx, 3, (RRe, RMQ, RMQ), mve_vmladav),
25179 mCEF(vmladavax, _vmladavax, 3, (RRe, RMQ, RMQ), mve_vmladav),
25180 mCEF(vmlav, _vmladav, 3, (RRe, RMQ, RMQ), mve_vmladav),
25181 mCEF(vmlava, _vmladava, 3, (RRe, RMQ, RMQ), mve_vmladav),
25182 mCEF(vmlsdav, _vmlsdav, 3, (RRe, RMQ, RMQ), mve_vmladav),
25183 mCEF(vmlsdava, _vmlsdava, 3, (RRe, RMQ, RMQ), mve_vmladav),
25184 mCEF(vmlsdavx, _vmlsdavx, 3, (RRe, RMQ, RMQ), mve_vmladav),
25185 mCEF(vmlsdavax, _vmlsdavax, 3, (RRe, RMQ, RMQ), mve_vmladav),
25186
35c228db
AV
25187 mCEF(vst20, _vst20, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
25188 mCEF(vst21, _vst21, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
25189 mCEF(vst40, _vst40, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
25190 mCEF(vst41, _vst41, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
25191 mCEF(vst42, _vst42, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
25192 mCEF(vst43, _vst43, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
25193 mCEF(vld20, _vld20, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
25194 mCEF(vld21, _vld21, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
25195 mCEF(vld40, _vld40, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
25196 mCEF(vld41, _vld41, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
25197 mCEF(vld42, _vld42, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
25198 mCEF(vld43, _vld43, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
f5f10c66
AV
25199 mCEF(vstrb, _vstrb, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
25200 mCEF(vstrh, _vstrh, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
25201 mCEF(vstrw, _vstrw, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
25202 mCEF(vstrd, _vstrd, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
25203 mCEF(vldrb, _vldrb, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
25204 mCEF(vldrh, _vldrh, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
25205 mCEF(vldrw, _vldrw, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
25206 mCEF(vldrd, _vldrd, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
35c228db 25207
57785aa2
AV
25208 mCEF(vmovnt, _vmovnt, 2, (RMQ, RMQ), mve_movn),
25209 mCEF(vmovnb, _vmovnb, 2, (RMQ, RMQ), mve_movn),
c2dafc2a 25210 mCEF(vbrsr, _vbrsr, 3, (RMQ, RMQ, RR), mve_vbrsr),
26c1e780
AV
25211 mCEF(vaddlv, _vaddlv, 3, (RRe, RRo, RMQ), mve_vaddlv),
25212 mCEF(vaddlva, _vaddlva, 3, (RRe, RRo, RMQ), mve_vaddlv),
25213 mCEF(vaddv, _vaddv, 2, (RRe, RMQ), mve_vaddv),
25214 mCEF(vaddva, _vaddva, 2, (RRe, RMQ), mve_vaddv),
b409bdb6
AV
25215 mCEF(vddup, _vddup, 3, (RMQ, RRe, EXPi), mve_viddup),
25216 mCEF(vdwdup, _vdwdup, 4, (RMQ, RRe, RR, EXPi), mve_viddup),
25217 mCEF(vidup, _vidup, 3, (RMQ, RRe, EXPi), mve_viddup),
25218 mCEF(viwdup, _viwdup, 4, (RMQ, RRe, RR, EXPi), mve_viddup),
935295b5
AV
25219 mToC("vmaxa", ee330e81, 2, (RMQ, RMQ), mve_vmaxa_vmina),
25220 mToC("vmina", ee331e81, 2, (RMQ, RMQ), mve_vmaxa_vmina),
13ccd4c0
AV
25221 mCEF(vmaxv, _vmaxv, 2, (RR, RMQ), mve_vmaxv),
25222 mCEF(vmaxav, _vmaxav, 2, (RR, RMQ), mve_vmaxv),
25223 mCEF(vminv, _vminv, 2, (RR, RMQ), mve_vmaxv),
25224 mCEF(vminav, _vminav, 2, (RR, RMQ), mve_vmaxv),
57785aa2 25225
93925576
AV
25226 mCEF(vmlaldav, _vmlaldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
25227 mCEF(vmlaldava, _vmlaldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
25228 mCEF(vmlaldavx, _vmlaldavx, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
25229 mCEF(vmlaldavax, _vmlaldavax, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
25230 mCEF(vmlalv, _vmlaldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
25231 mCEF(vmlalva, _vmlaldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
25232 mCEF(vmlsldav, _vmlsldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
25233 mCEF(vmlsldava, _vmlsldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
25234 mCEF(vmlsldavx, _vmlsldavx, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
25235 mCEF(vmlsldavax, _vmlsldavax, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
25236 mToC("vrmlaldavh", ee800f00, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
25237 mToC("vrmlaldavha",ee800f20, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
25238 mCEF(vrmlaldavhx, _vrmlaldavhx, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
25239 mCEF(vrmlaldavhax, _vrmlaldavhax, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
25240 mToC("vrmlalvh", ee800f00, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
25241 mToC("vrmlalvha", ee800f20, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
25242 mCEF(vrmlsldavh, _vrmlsldavh, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
25243 mCEF(vrmlsldavha, _vrmlsldavha, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
25244 mCEF(vrmlsldavhx, _vrmlsldavhx, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
25245 mCEF(vrmlsldavhax, _vrmlsldavhax, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
25246
2d78f95b
AV
25247 mToC("vmlas", ee011e40, 3, (RMQ, RMQ, RR), mve_vmlas),
25248 mToC("vmulh", ee010e01, 3, (RMQ, RMQ, RMQ), mve_vmulh),
25249 mToC("vrmulh", ee011e01, 3, (RMQ, RMQ, RMQ), mve_vmulh),
3063888e
AV
25250 mToC("vpnot", fe310f4d, 0, (), mve_vpnot),
25251 mToC("vpsel", fe310f01, 3, (RMQ, RMQ, RMQ), mve_vpsel),
2d78f95b 25252
8b8b22a4
AV
25253 mToC("vqdmladh", ee000e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
25254 mToC("vqdmladhx", ee001e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
25255 mToC("vqrdmladh", ee000e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
25256 mToC("vqrdmladhx",ee001e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
25257 mToC("vqdmlsdh", fe000e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
25258 mToC("vqdmlsdhx", fe001e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
25259 mToC("vqrdmlsdh", fe000e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
25260 mToC("vqrdmlsdhx",fe001e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
42b16635
AV
25261 mToC("vqdmlah", ee000e60, 3, (RMQ, RMQ, RR), mve_vqdmlah),
25262 mToC("vqdmlash", ee001e60, 3, (RMQ, RMQ, RR), mve_vqdmlah),
25263 mToC("vqrdmlash", ee001e40, 3, (RMQ, RMQ, RR), mve_vqdmlah),
35d1cfc2
AV
25264 mToC("vqdmullt", ee301f00, 3, (RMQ, RMQ, RMQRR), mve_vqdmull),
25265 mToC("vqdmullb", ee300f00, 3, (RMQ, RMQ, RMQRR), mve_vqdmull),
1be7aba3
AV
25266 mCEF(vqmovnt, _vqmovnt, 2, (RMQ, RMQ), mve_vqmovn),
25267 mCEF(vqmovnb, _vqmovnb, 2, (RMQ, RMQ), mve_vqmovn),
25268 mCEF(vqmovunt, _vqmovunt, 2, (RMQ, RMQ), mve_vqmovn),
25269 mCEF(vqmovunb, _vqmovunb, 2, (RMQ, RMQ), mve_vqmovn),
8b8b22a4 25270
4aa88b50
AV
25271 mCEF(vshrnt, _vshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
25272 mCEF(vshrnb, _vshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
25273 mCEF(vrshrnt, _vrshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
25274 mCEF(vrshrnb, _vrshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
25275 mCEF(vqshrnt, _vqrshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
25276 mCEF(vqshrnb, _vqrshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
25277 mCEF(vqshrunt, _vqrshrunt, 3, (RMQ, RMQ, I32z), mve_vshrn),
25278 mCEF(vqshrunb, _vqrshrunb, 3, (RMQ, RMQ, I32z), mve_vshrn),
25279 mCEF(vqrshrnt, _vqrshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
25280 mCEF(vqrshrnb, _vqrshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
25281 mCEF(vqrshrunt, _vqrshrunt, 3, (RMQ, RMQ, I32z), mve_vshrn),
25282 mCEF(vqrshrunb, _vqrshrunb, 3, (RMQ, RMQ, I32z), mve_vshrn),
25283
acca5630
AV
25284 mToC("vshlc", eea00fc0, 3, (RMQ, RR, I32z), mve_vshlc),
25285 mToC("vshllt", ee201e00, 3, (RMQ, RMQ, I32), mve_vshll),
25286 mToC("vshllb", ee200e00, 3, (RMQ, RMQ, I32), mve_vshll),
25287
1f6234a3
AV
25288 toU("dlstp", _dlstp, 2, (LR, RR), t_loloop),
25289 toU("wlstp", _wlstp, 3, (LR, RR, EXP), t_loloop),
25290 toU("letp", _letp, 2, (LR, EXP), t_loloop),
25291 toU("lctp", _lctp, 0, (), t_loloop),
25292
5d281bf0
AV
25293#undef THUMB_VARIANT
25294#define THUMB_VARIANT & mve_fp_ext
25295 mToC("vcmul", ee300e00, 4, (RMQ, RMQ, RMQ, EXPi), mve_vcmul),
f30ee27c 25296 mToC("vfmas", ee311e40, 3, (RMQ, RMQ, RR), mve_vfmas),
935295b5
AV
25297 mToC("vmaxnma", ee3f0e81, 2, (RMQ, RMQ), mve_vmaxnma_vminnma),
25298 mToC("vminnma", ee3f1e81, 2, (RMQ, RMQ), mve_vmaxnma_vminnma),
8cd78170
AV
25299 mToC("vmaxnmv", eeee0f00, 2, (RR, RMQ), mve_vmaxnmv),
25300 mToC("vmaxnmav",eeec0f00, 2, (RR, RMQ), mve_vmaxnmv),
25301 mToC("vminnmv", eeee0f80, 2, (RR, RMQ), mve_vmaxnmv),
25302 mToC("vminnmav",eeec0f80, 2, (RR, RMQ), mve_vmaxnmv),
5d281bf0 25303
5ee91343 25304#undef ARM_VARIANT
57785aa2 25305#define ARM_VARIANT & fpu_vfp_ext_v1
5ee91343
AV
25306#undef THUMB_VARIANT
25307#define THUMB_VARIANT & arm_ext_v6t2
a8465a06
AV
25308 mnCEF(vmla, _vmla, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ_RR), neon_mac_maybe_scalar),
25309 mnCEF(vmul, _vmul, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ_RR), neon_mul),
5ee91343 25310
57785aa2
AV
25311 mcCE(fcpyd, eb00b40, 2, (RVD, RVD), vfp_dp_rd_rm),
25312
25313#undef ARM_VARIANT
25314#define ARM_VARIANT & fpu_vfp_ext_v1xd
25315
25316 MNCE(vmov, 0, 1, (VMOV), neon_mov),
25317 mcCE(fmrs, e100a10, 2, (RR, RVS), vfp_reg_from_sp),
25318 mcCE(fmsr, e000a10, 2, (RVS, RR), vfp_sp_from_reg),
25319 mcCE(fcpys, eb00a40, 2, (RVS, RVS), vfp_sp_monadic),
25320
886e1c73
AV
25321 mCEF(vmullt, _vmullt, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ), mve_vmull),
25322 mnCEF(vadd, _vadd, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
25323 mnCEF(vsub, _vsub, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
5ee91343 25324
485dee97
AV
25325 MNCEF(vabs, 1b10300, 2, (RNSDQMQ, RNSDQMQ), neon_abs_neg),
25326 MNCEF(vneg, 1b10380, 2, (RNSDQMQ, RNSDQMQ), neon_abs_neg),
25327
57785aa2
AV
25328 mCEF(vmovlt, _vmovlt, 1, (VMOV), mve_movl),
25329 mCEF(vmovlb, _vmovlb, 1, (VMOV), mve_movl),
25330
1b883319
AV
25331 mnCE(vcmp, _vcmp, 3, (RVSD_COND, RSVDMQ_FI0, oRMQRZ), vfp_nsyn_cmp),
25332 mnCE(vcmpe, _vcmpe, 3, (RVSD_COND, RSVDMQ_FI0, oRMQRZ), vfp_nsyn_cmp),
25333
57785aa2
AV
25334#undef ARM_VARIANT
25335#define ARM_VARIANT & fpu_vfp_ext_v2
25336
25337 mcCE(fmsrr, c400a10, 3, (VRSLST, RR, RR), vfp_sp2_from_reg2),
25338 mcCE(fmrrs, c500a10, 3, (RR, RR, VRSLST), vfp_reg2_from_sp2),
25339 mcCE(fmdrr, c400b10, 3, (RVD, RR, RR), vfp_dp_rm_rd_rn),
25340 mcCE(fmrrd, c500b10, 3, (RR, RR, RVD), vfp_dp_rd_rn_rm),
25341
dd9634d9
AV
25342#undef ARM_VARIANT
25343#define ARM_VARIANT & fpu_vfp_ext_armv8xd
25344 mnUF(vcvta, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvta),
25345 mnUF(vcvtp, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvtp),
25346 mnUF(vcvtn, _vcvta, 3, (RNSDQMQ, oRNSDQMQ, oI32z), neon_cvtn),
25347 mnUF(vcvtm, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvtm),
935295b5
AV
25348 mnUF(vmaxnm, _vmaxnm, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), vmaxnm),
25349 mnUF(vminnm, _vminnm, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), vmaxnm),
dd9634d9
AV
25350
25351#undef ARM_VARIANT
5ee91343 25352#define ARM_VARIANT & fpu_neon_ext_v1
f601a00c 25353 mnUF(vabd, _vabd, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
5ee91343
AV
25354 mnUF(vabdl, _vabdl, 3, (RNQMQ, RNDMQ, RNDMQ), neon_dyadic_long),
25355 mnUF(vaddl, _vaddl, 3, (RNQMQ, RNDMQ, RNDMQR), neon_dyadic_long),
25356 mnUF(vsubl, _vsubl, 3, (RNQMQ, RNDMQ, RNDMQR), neon_dyadic_long),
f601a00c
AV
25357 mnUF(vand, _vand, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
25358 mnUF(vbic, _vbic, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
25359 mnUF(vorr, _vorr, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
25360 mnUF(vorn, _vorn, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
25361 mnUF(veor, _veor, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_logic),
f30ee27c
AV
25362 MNUF(vcls, 1b00400, 2, (RNDQMQ, RNDQMQ), neon_cls),
25363 MNUF(vclz, 1b00480, 2, (RNDQMQ, RNDQMQ), neon_clz),
b409bdb6 25364 mnCE(vdup, _vdup, 2, (RNDQMQ, RR_RNSC), neon_dup),
7df54120
AV
25365 MNUF(vhadd, 00000000, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i_su),
25366 MNUF(vrhadd, 00000100, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_i_su),
25367 MNUF(vhsub, 00000200, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i_su),
935295b5
AV
25368 mnUF(vmin, _vmin, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
25369 mnUF(vmax, _vmax, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
a8465a06
AV
25370 MNUF(vqadd, 0000010, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i64_su),
25371 MNUF(vqsub, 0000210, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i64_su),
1a186d29
AV
25372 mnUF(vmvn, _vmvn, 2, (RNDQMQ, RNDQMQ_Ibig), neon_mvn),
25373 MNUF(vqabs, 1b00700, 2, (RNDQMQ, RNDQMQ), neon_sat_abs_neg),
25374 MNUF(vqneg, 1b00780, 2, (RNDQMQ, RNDQMQ), neon_sat_abs_neg),
42b16635
AV
25375 mnUF(vqrdmlah, _vqrdmlah,3, (RNDQMQ, oRNDQMQ, RNDQ_RNSC_RR), neon_qrdmlah),
25376 mnUF(vqdmulh, _vqdmulh, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_RNSC_RR), neon_qdmulh),
25377 mnUF(vqrdmulh, _vqrdmulh,3, (RNDQMQ, oRNDQMQ, RNDQMQ_RNSC_RR), neon_qdmulh),
1be7aba3
AV
25378 MNUF(vqrshl, 0000510, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_rshl),
25379 MNUF(vrshl, 0000500, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_rshl),
4401c241
AV
25380 MNUF(vshr, 0800010, 3, (RNDQMQ, oRNDQMQ, I64z), neon_rshift_round_imm),
25381 MNUF(vrshr, 0800210, 3, (RNDQMQ, oRNDQMQ, I64z), neon_rshift_round_imm),
25382 MNUF(vsli, 1800510, 3, (RNDQMQ, oRNDQMQ, I63), neon_sli),
25383 MNUF(vsri, 1800410, 3, (RNDQMQ, oRNDQMQ, I64z), neon_sri),
25384 MNUF(vrev64, 1b00000, 2, (RNDQMQ, RNDQMQ), neon_rev),
25385 MNUF(vrev32, 1b00080, 2, (RNDQMQ, RNDQMQ), neon_rev),
25386 MNUF(vrev16, 1b00100, 2, (RNDQMQ, RNDQMQ), neon_rev),
5150f0d8
AV
25387 mnUF(vshl, _vshl, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_I63b_RR), neon_shl),
25388 mnUF(vqshl, _vqshl, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_I63b_RR), neon_qshl),
25389 MNUF(vqshlu, 1800610, 3, (RNDQMQ, oRNDQMQ, I63), neon_qshlu_imm),
5d281bf0
AV
25390
25391#undef ARM_VARIANT
25392#define ARM_VARIANT & arm_ext_v8_3
25393#undef THUMB_VARIANT
25394#define THUMB_VARIANT & arm_ext_v6t2_v8m
25395 MNUF (vcadd, 0, 4, (RNDQMQ, RNDQMQ, RNDQMQ, EXPi), vcadd),
25396 MNUF (vcmla, 0, 4, (RNDQMQ, RNDQMQ, RNDQMQ_RNSC, EXPi), vcmla),
c19d1205
ZW
25397};
25398#undef ARM_VARIANT
25399#undef THUMB_VARIANT
25400#undef TCE
c19d1205
ZW
25401#undef TUE
25402#undef TUF
25403#undef TCC
8f06b2d8 25404#undef cCE
e3cb604e
PB
25405#undef cCL
25406#undef C3E
4389b29a 25407#undef C3
c19d1205
ZW
25408#undef CE
25409#undef CM
4389b29a 25410#undef CL
c19d1205
ZW
25411#undef UE
25412#undef UF
25413#undef UT
5287ad62
JB
25414#undef NUF
25415#undef nUF
25416#undef NCE
25417#undef nCE
c19d1205
ZW
25418#undef OPS0
25419#undef OPS1
25420#undef OPS2
25421#undef OPS3
25422#undef OPS4
25423#undef OPS5
25424#undef OPS6
25425#undef do_0
4389b29a
AV
25426#undef ToC
25427#undef toC
25428#undef ToU
f6b2b12d 25429#undef toU
c19d1205
ZW
25430\f
25431/* MD interface: bits in the object file. */
bfae80f2 25432
c19d1205
ZW
25433/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
25434 for use in the a.out file, and stores them in the array pointed to by buf.
25435 This knows about the endian-ness of the target machine and does
25436 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
25437 2 (short) and 4 (long) Floating numbers are put out as a series of
25438 LITTLENUMS (shorts, here at least). */
b99bd4ef 25439
c19d1205
ZW
25440void
25441md_number_to_chars (char * buf, valueT val, int n)
25442{
25443 if (target_big_endian)
25444 number_to_chars_bigendian (buf, val, n);
25445 else
25446 number_to_chars_littleendian (buf, val, n);
bfae80f2
RE
25447}
25448
c19d1205
ZW
25449static valueT
25450md_chars_to_number (char * buf, int n)
bfae80f2 25451{
c19d1205
ZW
25452 valueT result = 0;
25453 unsigned char * where = (unsigned char *) buf;
bfae80f2 25454
c19d1205 25455 if (target_big_endian)
b99bd4ef 25456 {
c19d1205
ZW
25457 while (n--)
25458 {
25459 result <<= 8;
25460 result |= (*where++ & 255);
25461 }
b99bd4ef 25462 }
c19d1205 25463 else
b99bd4ef 25464 {
c19d1205
ZW
25465 while (n--)
25466 {
25467 result <<= 8;
25468 result |= (where[n] & 255);
25469 }
bfae80f2 25470 }
b99bd4ef 25471
c19d1205 25472 return result;
bfae80f2 25473}
b99bd4ef 25474
c19d1205 25475/* MD interface: Sections. */
b99bd4ef 25476
fa94de6b
RM
25477/* Calculate the maximum variable size (i.e., excluding fr_fix)
25478 that an rs_machine_dependent frag may reach. */
25479
25480unsigned int
25481arm_frag_max_var (fragS *fragp)
25482{
25483 /* We only use rs_machine_dependent for variable-size Thumb instructions,
25484 which are either THUMB_SIZE (2) or INSN_SIZE (4).
25485
25486 Note that we generate relaxable instructions even for cases that don't
25487 really need it, like an immediate that's a trivial constant. So we're
25488 overestimating the instruction size for some of those cases. Rather
25489 than putting more intelligence here, it would probably be better to
25490 avoid generating a relaxation frag in the first place when it can be
25491 determined up front that a short instruction will suffice. */
25492
25493 gas_assert (fragp->fr_type == rs_machine_dependent);
25494 return INSN_SIZE;
25495}
25496
0110f2b8
PB
25497/* Estimate the size of a frag before relaxing. Assume everything fits in
25498 2 bytes. */
25499
c19d1205 25500int
0110f2b8 25501md_estimate_size_before_relax (fragS * fragp,
c19d1205
ZW
25502 segT segtype ATTRIBUTE_UNUSED)
25503{
0110f2b8
PB
25504 fragp->fr_var = 2;
25505 return 2;
25506}
25507
25508/* Convert a machine dependent frag. */
25509
25510void
25511md_convert_frag (bfd *abfd, segT asec ATTRIBUTE_UNUSED, fragS *fragp)
25512{
25513 unsigned long insn;
25514 unsigned long old_op;
25515 char *buf;
25516 expressionS exp;
25517 fixS *fixp;
25518 int reloc_type;
25519 int pc_rel;
25520 int opcode;
25521
25522 buf = fragp->fr_literal + fragp->fr_fix;
25523
25524 old_op = bfd_get_16(abfd, buf);
5f4273c7
NC
25525 if (fragp->fr_symbol)
25526 {
0110f2b8
PB
25527 exp.X_op = O_symbol;
25528 exp.X_add_symbol = fragp->fr_symbol;
5f4273c7
NC
25529 }
25530 else
25531 {
0110f2b8 25532 exp.X_op = O_constant;
5f4273c7 25533 }
0110f2b8
PB
25534 exp.X_add_number = fragp->fr_offset;
25535 opcode = fragp->fr_subtype;
25536 switch (opcode)
25537 {
25538 case T_MNEM_ldr_pc:
25539 case T_MNEM_ldr_pc2:
25540 case T_MNEM_ldr_sp:
25541 case T_MNEM_str_sp:
25542 case T_MNEM_ldr:
25543 case T_MNEM_ldrb:
25544 case T_MNEM_ldrh:
25545 case T_MNEM_str:
25546 case T_MNEM_strb:
25547 case T_MNEM_strh:
25548 if (fragp->fr_var == 4)
25549 {
5f4273c7 25550 insn = THUMB_OP32 (opcode);
0110f2b8
PB
25551 if ((old_op >> 12) == 4 || (old_op >> 12) == 9)
25552 {
25553 insn |= (old_op & 0x700) << 4;
25554 }
25555 else
25556 {
25557 insn |= (old_op & 7) << 12;
25558 insn |= (old_op & 0x38) << 13;
25559 }
25560 insn |= 0x00000c00;
25561 put_thumb32_insn (buf, insn);
25562 reloc_type = BFD_RELOC_ARM_T32_OFFSET_IMM;
25563 }
25564 else
25565 {
25566 reloc_type = BFD_RELOC_ARM_THUMB_OFFSET;
25567 }
25568 pc_rel = (opcode == T_MNEM_ldr_pc2);
25569 break;
25570 case T_MNEM_adr:
25571 if (fragp->fr_var == 4)
25572 {
25573 insn = THUMB_OP32 (opcode);
25574 insn |= (old_op & 0xf0) << 4;
25575 put_thumb32_insn (buf, insn);
25576 reloc_type = BFD_RELOC_ARM_T32_ADD_PC12;
25577 }
25578 else
25579 {
25580 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
25581 exp.X_add_number -= 4;
25582 }
25583 pc_rel = 1;
25584 break;
25585 case T_MNEM_mov:
25586 case T_MNEM_movs:
25587 case T_MNEM_cmp:
25588 case T_MNEM_cmn:
25589 if (fragp->fr_var == 4)
25590 {
25591 int r0off = (opcode == T_MNEM_mov
25592 || opcode == T_MNEM_movs) ? 0 : 8;
25593 insn = THUMB_OP32 (opcode);
25594 insn = (insn & 0xe1ffffff) | 0x10000000;
25595 insn |= (old_op & 0x700) << r0off;
25596 put_thumb32_insn (buf, insn);
25597 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
25598 }
25599 else
25600 {
25601 reloc_type = BFD_RELOC_ARM_THUMB_IMM;
25602 }
25603 pc_rel = 0;
25604 break;
25605 case T_MNEM_b:
25606 if (fragp->fr_var == 4)
25607 {
25608 insn = THUMB_OP32(opcode);
25609 put_thumb32_insn (buf, insn);
25610 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH25;
25611 }
25612 else
25613 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH12;
25614 pc_rel = 1;
25615 break;
25616 case T_MNEM_bcond:
25617 if (fragp->fr_var == 4)
25618 {
25619 insn = THUMB_OP32(opcode);
25620 insn |= (old_op & 0xf00) << 14;
25621 put_thumb32_insn (buf, insn);
25622 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH20;
25623 }
25624 else
25625 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH9;
25626 pc_rel = 1;
25627 break;
25628 case T_MNEM_add_sp:
25629 case T_MNEM_add_pc:
25630 case T_MNEM_inc_sp:
25631 case T_MNEM_dec_sp:
25632 if (fragp->fr_var == 4)
25633 {
25634 /* ??? Choose between add and addw. */
25635 insn = THUMB_OP32 (opcode);
25636 insn |= (old_op & 0xf0) << 4;
25637 put_thumb32_insn (buf, insn);
16805f35
PB
25638 if (opcode == T_MNEM_add_pc)
25639 reloc_type = BFD_RELOC_ARM_T32_IMM12;
25640 else
25641 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
0110f2b8
PB
25642 }
25643 else
25644 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
25645 pc_rel = 0;
25646 break;
25647
25648 case T_MNEM_addi:
25649 case T_MNEM_addis:
25650 case T_MNEM_subi:
25651 case T_MNEM_subis:
25652 if (fragp->fr_var == 4)
25653 {
25654 insn = THUMB_OP32 (opcode);
25655 insn |= (old_op & 0xf0) << 4;
25656 insn |= (old_op & 0xf) << 16;
25657 put_thumb32_insn (buf, insn);
16805f35
PB
25658 if (insn & (1 << 20))
25659 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
25660 else
25661 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8
PB
25662 }
25663 else
25664 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
25665 pc_rel = 0;
25666 break;
25667 default:
5f4273c7 25668 abort ();
0110f2b8
PB
25669 }
25670 fixp = fix_new_exp (fragp, fragp->fr_fix, fragp->fr_var, &exp, pc_rel,
21d799b5 25671 (enum bfd_reloc_code_real) reloc_type);
0110f2b8
PB
25672 fixp->fx_file = fragp->fr_file;
25673 fixp->fx_line = fragp->fr_line;
25674 fragp->fr_fix += fragp->fr_var;
3cfdb781
TG
25675
25676 /* Set whether we use thumb-2 ISA based on final relaxation results. */
25677 if (thumb_mode && fragp->fr_var == 4 && no_cpu_selected ()
25678 && !ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_t2))
25679 ARM_MERGE_FEATURE_SETS (arm_arch_used, thumb_arch_used, arm_ext_v6t2);
0110f2b8
PB
25680}
25681
25682/* Return the size of a relaxable immediate operand instruction.
25683 SHIFT and SIZE specify the form of the allowable immediate. */
25684static int
25685relax_immediate (fragS *fragp, int size, int shift)
25686{
25687 offsetT offset;
25688 offsetT mask;
25689 offsetT low;
25690
25691 /* ??? Should be able to do better than this. */
25692 if (fragp->fr_symbol)
25693 return 4;
25694
25695 low = (1 << shift) - 1;
25696 mask = (1 << (shift + size)) - (1 << shift);
25697 offset = fragp->fr_offset;
25698 /* Force misaligned offsets to 32-bit variant. */
25699 if (offset & low)
5e77afaa 25700 return 4;
0110f2b8
PB
25701 if (offset & ~mask)
25702 return 4;
25703 return 2;
25704}
25705
5e77afaa
PB
25706/* Get the address of a symbol during relaxation. */
25707static addressT
5f4273c7 25708relaxed_symbol_addr (fragS *fragp, long stretch)
5e77afaa
PB
25709{
25710 fragS *sym_frag;
25711 addressT addr;
25712 symbolS *sym;
25713
25714 sym = fragp->fr_symbol;
25715 sym_frag = symbol_get_frag (sym);
25716 know (S_GET_SEGMENT (sym) != absolute_section
25717 || sym_frag == &zero_address_frag);
25718 addr = S_GET_VALUE (sym) + fragp->fr_offset;
25719
25720 /* If frag has yet to be reached on this pass, assume it will
25721 move by STRETCH just as we did. If this is not so, it will
25722 be because some frag between grows, and that will force
25723 another pass. */
25724
25725 if (stretch != 0
25726 && sym_frag->relax_marker != fragp->relax_marker)
4396b686
PB
25727 {
25728 fragS *f;
25729
25730 /* Adjust stretch for any alignment frag. Note that if have
25731 been expanding the earlier code, the symbol may be
25732 defined in what appears to be an earlier frag. FIXME:
25733 This doesn't handle the fr_subtype field, which specifies
25734 a maximum number of bytes to skip when doing an
25735 alignment. */
25736 for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next)
25737 {
25738 if (f->fr_type == rs_align || f->fr_type == rs_align_code)
25739 {
25740 if (stretch < 0)
25741 stretch = - ((- stretch)
25742 & ~ ((1 << (int) f->fr_offset) - 1));
25743 else
25744 stretch &= ~ ((1 << (int) f->fr_offset) - 1);
25745 if (stretch == 0)
25746 break;
25747 }
25748 }
25749 if (f != NULL)
25750 addr += stretch;
25751 }
5e77afaa
PB
25752
25753 return addr;
25754}
25755
0110f2b8
PB
25756/* Return the size of a relaxable adr pseudo-instruction or PC-relative
25757 load. */
25758static int
5e77afaa 25759relax_adr (fragS *fragp, asection *sec, long stretch)
0110f2b8
PB
25760{
25761 addressT addr;
25762 offsetT val;
25763
25764 /* Assume worst case for symbols not known to be in the same section. */
974da60d
NC
25765 if (fragp->fr_symbol == NULL
25766 || !S_IS_DEFINED (fragp->fr_symbol)
77db8e2e
NC
25767 || sec != S_GET_SEGMENT (fragp->fr_symbol)
25768 || S_IS_WEAK (fragp->fr_symbol))
0110f2b8
PB
25769 return 4;
25770
5f4273c7 25771 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
25772 addr = fragp->fr_address + fragp->fr_fix;
25773 addr = (addr + 4) & ~3;
5e77afaa 25774 /* Force misaligned targets to 32-bit variant. */
0110f2b8 25775 if (val & 3)
5e77afaa 25776 return 4;
0110f2b8
PB
25777 val -= addr;
25778 if (val < 0 || val > 1020)
25779 return 4;
25780 return 2;
25781}
25782
25783/* Return the size of a relaxable add/sub immediate instruction. */
25784static int
25785relax_addsub (fragS *fragp, asection *sec)
25786{
25787 char *buf;
25788 int op;
25789
25790 buf = fragp->fr_literal + fragp->fr_fix;
25791 op = bfd_get_16(sec->owner, buf);
25792 if ((op & 0xf) == ((op >> 4) & 0xf))
25793 return relax_immediate (fragp, 8, 0);
25794 else
25795 return relax_immediate (fragp, 3, 0);
25796}
25797
e83a675f
RE
25798/* Return TRUE iff the definition of symbol S could be pre-empted
25799 (overridden) at link or load time. */
25800static bfd_boolean
25801symbol_preemptible (symbolS *s)
25802{
25803 /* Weak symbols can always be pre-empted. */
25804 if (S_IS_WEAK (s))
25805 return TRUE;
25806
25807 /* Non-global symbols cannot be pre-empted. */
25808 if (! S_IS_EXTERNAL (s))
25809 return FALSE;
25810
25811#ifdef OBJ_ELF
25812 /* In ELF, a global symbol can be marked protected, or private. In that
25813 case it can't be pre-empted (other definitions in the same link unit
25814 would violate the ODR). */
25815 if (ELF_ST_VISIBILITY (S_GET_OTHER (s)) > STV_DEFAULT)
25816 return FALSE;
25817#endif
25818
25819 /* Other global symbols might be pre-empted. */
25820 return TRUE;
25821}
0110f2b8
PB
25822
25823/* Return the size of a relaxable branch instruction. BITS is the
25824 size of the offset field in the narrow instruction. */
25825
25826static int
5e77afaa 25827relax_branch (fragS *fragp, asection *sec, int bits, long stretch)
0110f2b8
PB
25828{
25829 addressT addr;
25830 offsetT val;
25831 offsetT limit;
25832
25833 /* Assume worst case for symbols not known to be in the same section. */
5f4273c7 25834 if (!S_IS_DEFINED (fragp->fr_symbol)
77db8e2e
NC
25835 || sec != S_GET_SEGMENT (fragp->fr_symbol)
25836 || S_IS_WEAK (fragp->fr_symbol))
0110f2b8
PB
25837 return 4;
25838
267bf995 25839#ifdef OBJ_ELF
e83a675f 25840 /* A branch to a function in ARM state will require interworking. */
267bf995
RR
25841 if (S_IS_DEFINED (fragp->fr_symbol)
25842 && ARM_IS_FUNC (fragp->fr_symbol))
25843 return 4;
e83a675f 25844#endif
0d9b4b55 25845
e83a675f 25846 if (symbol_preemptible (fragp->fr_symbol))
0d9b4b55 25847 return 4;
267bf995 25848
5f4273c7 25849 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
25850 addr = fragp->fr_address + fragp->fr_fix + 4;
25851 val -= addr;
25852
25853 /* Offset is a signed value *2 */
25854 limit = 1 << bits;
25855 if (val >= limit || val < -limit)
25856 return 4;
25857 return 2;
25858}
25859
25860
25861/* Relax a machine dependent frag. This returns the amount by which
25862 the current size of the frag should change. */
25863
25864int
5e77afaa 25865arm_relax_frag (asection *sec, fragS *fragp, long stretch)
0110f2b8
PB
25866{
25867 int oldsize;
25868 int newsize;
25869
25870 oldsize = fragp->fr_var;
25871 switch (fragp->fr_subtype)
25872 {
25873 case T_MNEM_ldr_pc2:
5f4273c7 25874 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
25875 break;
25876 case T_MNEM_ldr_pc:
25877 case T_MNEM_ldr_sp:
25878 case T_MNEM_str_sp:
5f4273c7 25879 newsize = relax_immediate (fragp, 8, 2);
0110f2b8
PB
25880 break;
25881 case T_MNEM_ldr:
25882 case T_MNEM_str:
5f4273c7 25883 newsize = relax_immediate (fragp, 5, 2);
0110f2b8
PB
25884 break;
25885 case T_MNEM_ldrh:
25886 case T_MNEM_strh:
5f4273c7 25887 newsize = relax_immediate (fragp, 5, 1);
0110f2b8
PB
25888 break;
25889 case T_MNEM_ldrb:
25890 case T_MNEM_strb:
5f4273c7 25891 newsize = relax_immediate (fragp, 5, 0);
0110f2b8
PB
25892 break;
25893 case T_MNEM_adr:
5f4273c7 25894 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
25895 break;
25896 case T_MNEM_mov:
25897 case T_MNEM_movs:
25898 case T_MNEM_cmp:
25899 case T_MNEM_cmn:
5f4273c7 25900 newsize = relax_immediate (fragp, 8, 0);
0110f2b8
PB
25901 break;
25902 case T_MNEM_b:
5f4273c7 25903 newsize = relax_branch (fragp, sec, 11, stretch);
0110f2b8
PB
25904 break;
25905 case T_MNEM_bcond:
5f4273c7 25906 newsize = relax_branch (fragp, sec, 8, stretch);
0110f2b8
PB
25907 break;
25908 case T_MNEM_add_sp:
25909 case T_MNEM_add_pc:
25910 newsize = relax_immediate (fragp, 8, 2);
25911 break;
25912 case T_MNEM_inc_sp:
25913 case T_MNEM_dec_sp:
25914 newsize = relax_immediate (fragp, 7, 2);
25915 break;
25916 case T_MNEM_addi:
25917 case T_MNEM_addis:
25918 case T_MNEM_subi:
25919 case T_MNEM_subis:
25920 newsize = relax_addsub (fragp, sec);
25921 break;
25922 default:
5f4273c7 25923 abort ();
0110f2b8 25924 }
5e77afaa
PB
25925
25926 fragp->fr_var = newsize;
25927 /* Freeze wide instructions that are at or before the same location as
25928 in the previous pass. This avoids infinite loops.
5f4273c7
NC
25929 Don't freeze them unconditionally because targets may be artificially
25930 misaligned by the expansion of preceding frags. */
5e77afaa 25931 if (stretch <= 0 && newsize > 2)
0110f2b8 25932 {
0110f2b8 25933 md_convert_frag (sec->owner, sec, fragp);
5f4273c7 25934 frag_wane (fragp);
0110f2b8 25935 }
5e77afaa 25936
0110f2b8 25937 return newsize - oldsize;
c19d1205 25938}
b99bd4ef 25939
c19d1205 25940/* Round up a section size to the appropriate boundary. */
b99bd4ef 25941
c19d1205
ZW
25942valueT
25943md_section_align (segT segment ATTRIBUTE_UNUSED,
25944 valueT size)
25945{
6844c0cc 25946 return size;
bfae80f2 25947}
b99bd4ef 25948
c19d1205
ZW
25949/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
25950 of an rs_align_code fragment. */
25951
25952void
25953arm_handle_align (fragS * fragP)
bfae80f2 25954{
d9235011 25955 static unsigned char const arm_noop[2][2][4] =
e7495e45
NS
25956 {
25957 { /* ARMv1 */
25958 {0x00, 0x00, 0xa0, 0xe1}, /* LE */
25959 {0xe1, 0xa0, 0x00, 0x00}, /* BE */
25960 },
25961 { /* ARMv6k */
25962 {0x00, 0xf0, 0x20, 0xe3}, /* LE */
25963 {0xe3, 0x20, 0xf0, 0x00}, /* BE */
25964 },
25965 };
d9235011 25966 static unsigned char const thumb_noop[2][2][2] =
e7495e45
NS
25967 {
25968 { /* Thumb-1 */
25969 {0xc0, 0x46}, /* LE */
25970 {0x46, 0xc0}, /* BE */
25971 },
25972 { /* Thumb-2 */
25973 {0x00, 0xbf}, /* LE */
25974 {0xbf, 0x00} /* BE */
25975 }
25976 };
d9235011 25977 static unsigned char const wide_thumb_noop[2][4] =
e7495e45
NS
25978 { /* Wide Thumb-2 */
25979 {0xaf, 0xf3, 0x00, 0x80}, /* LE */
25980 {0xf3, 0xaf, 0x80, 0x00}, /* BE */
25981 };
c921be7d 25982
e7495e45 25983 unsigned bytes, fix, noop_size;
c19d1205 25984 char * p;
d9235011
TS
25985 const unsigned char * noop;
25986 const unsigned char *narrow_noop = NULL;
cd000bff
DJ
25987#ifdef OBJ_ELF
25988 enum mstate state;
25989#endif
bfae80f2 25990
c19d1205 25991 if (fragP->fr_type != rs_align_code)
bfae80f2
RE
25992 return;
25993
c19d1205
ZW
25994 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
25995 p = fragP->fr_literal + fragP->fr_fix;
25996 fix = 0;
bfae80f2 25997
c19d1205
ZW
25998 if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
25999 bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
bfae80f2 26000
cd000bff 26001 gas_assert ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) != 0);
8dc2430f 26002
cd000bff 26003 if (fragP->tc_frag_data.thumb_mode & (~ MODE_RECORDED))
a737bd4d 26004 {
7f78eb34
JW
26005 if (ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
26006 ? selected_cpu : arm_arch_none, arm_ext_v6t2))
e7495e45
NS
26007 {
26008 narrow_noop = thumb_noop[1][target_big_endian];
26009 noop = wide_thumb_noop[target_big_endian];
26010 }
c19d1205 26011 else
e7495e45
NS
26012 noop = thumb_noop[0][target_big_endian];
26013 noop_size = 2;
cd000bff
DJ
26014#ifdef OBJ_ELF
26015 state = MAP_THUMB;
26016#endif
7ed4c4c5
NC
26017 }
26018 else
26019 {
7f78eb34
JW
26020 noop = arm_noop[ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
26021 ? selected_cpu : arm_arch_none,
26022 arm_ext_v6k) != 0]
e7495e45
NS
26023 [target_big_endian];
26024 noop_size = 4;
cd000bff
DJ
26025#ifdef OBJ_ELF
26026 state = MAP_ARM;
26027#endif
7ed4c4c5 26028 }
c921be7d 26029
e7495e45 26030 fragP->fr_var = noop_size;
c921be7d 26031
c19d1205 26032 if (bytes & (noop_size - 1))
7ed4c4c5 26033 {
c19d1205 26034 fix = bytes & (noop_size - 1);
cd000bff
DJ
26035#ifdef OBJ_ELF
26036 insert_data_mapping_symbol (state, fragP->fr_fix, fragP, fix);
26037#endif
c19d1205
ZW
26038 memset (p, 0, fix);
26039 p += fix;
26040 bytes -= fix;
a737bd4d 26041 }
a737bd4d 26042
e7495e45
NS
26043 if (narrow_noop)
26044 {
26045 if (bytes & noop_size)
26046 {
26047 /* Insert a narrow noop. */
26048 memcpy (p, narrow_noop, noop_size);
26049 p += noop_size;
26050 bytes -= noop_size;
26051 fix += noop_size;
26052 }
26053
26054 /* Use wide noops for the remainder */
26055 noop_size = 4;
26056 }
26057
c19d1205 26058 while (bytes >= noop_size)
a737bd4d 26059 {
c19d1205
ZW
26060 memcpy (p, noop, noop_size);
26061 p += noop_size;
26062 bytes -= noop_size;
26063 fix += noop_size;
a737bd4d
NC
26064 }
26065
c19d1205 26066 fragP->fr_fix += fix;
a737bd4d
NC
26067}
26068
c19d1205
ZW
26069/* Called from md_do_align. Used to create an alignment
26070 frag in a code section. */
26071
26072void
26073arm_frag_align_code (int n, int max)
bfae80f2 26074{
c19d1205 26075 char * p;
7ed4c4c5 26076
c19d1205 26077 /* We assume that there will never be a requirement
6ec8e702 26078 to support alignments greater than MAX_MEM_FOR_RS_ALIGN_CODE bytes. */
c19d1205 26079 if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
6ec8e702
NC
26080 {
26081 char err_msg[128];
26082
fa94de6b 26083 sprintf (err_msg,
477330fc
RM
26084 _("alignments greater than %d bytes not supported in .text sections."),
26085 MAX_MEM_FOR_RS_ALIGN_CODE + 1);
20203fb9 26086 as_fatal ("%s", err_msg);
6ec8e702 26087 }
bfae80f2 26088
c19d1205
ZW
26089 p = frag_var (rs_align_code,
26090 MAX_MEM_FOR_RS_ALIGN_CODE,
26091 1,
26092 (relax_substateT) max,
26093 (symbolS *) NULL,
26094 (offsetT) n,
26095 (char *) NULL);
26096 *p = 0;
26097}
bfae80f2 26098
8dc2430f
NC
26099/* Perform target specific initialisation of a frag.
26100 Note - despite the name this initialisation is not done when the frag
26101 is created, but only when its type is assigned. A frag can be created
26102 and used a long time before its type is set, so beware of assuming that
33eaf5de 26103 this initialisation is performed first. */
bfae80f2 26104
cd000bff
DJ
26105#ifndef OBJ_ELF
26106void
26107arm_init_frag (fragS * fragP, int max_chars ATTRIBUTE_UNUSED)
26108{
26109 /* Record whether this frag is in an ARM or a THUMB area. */
2e98972e 26110 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
cd000bff
DJ
26111}
26112
26113#else /* OBJ_ELF is defined. */
c19d1205 26114void
cd000bff 26115arm_init_frag (fragS * fragP, int max_chars)
c19d1205 26116{
e8d84ca1 26117 bfd_boolean frag_thumb_mode;
b968d18a 26118
8dc2430f
NC
26119 /* If the current ARM vs THUMB mode has not already
26120 been recorded into this frag then do so now. */
cd000bff 26121 if ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) == 0)
b968d18a
JW
26122 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
26123
e8d84ca1
NC
26124 /* PR 21809: Do not set a mapping state for debug sections
26125 - it just confuses other tools. */
26126 if (bfd_get_section_flags (NULL, now_seg) & SEC_DEBUGGING)
26127 return;
26128
b968d18a 26129 frag_thumb_mode = fragP->tc_frag_data.thumb_mode ^ MODE_RECORDED;
cd000bff 26130
f9c1b181
RL
26131 /* Record a mapping symbol for alignment frags. We will delete this
26132 later if the alignment ends up empty. */
26133 switch (fragP->fr_type)
26134 {
26135 case rs_align:
26136 case rs_align_test:
26137 case rs_fill:
26138 mapping_state_2 (MAP_DATA, max_chars);
26139 break;
26140 case rs_align_code:
b968d18a 26141 mapping_state_2 (frag_thumb_mode ? MAP_THUMB : MAP_ARM, max_chars);
f9c1b181
RL
26142 break;
26143 default:
26144 break;
cd000bff 26145 }
bfae80f2
RE
26146}
26147
c19d1205
ZW
26148/* When we change sections we need to issue a new mapping symbol. */
26149
26150void
26151arm_elf_change_section (void)
bfae80f2 26152{
c19d1205
ZW
26153 /* Link an unlinked unwind index table section to the .text section. */
26154 if (elf_section_type (now_seg) == SHT_ARM_EXIDX
26155 && elf_linked_to_section (now_seg) == NULL)
26156 elf_linked_to_section (now_seg) = text_section;
bfae80f2
RE
26157}
26158
c19d1205
ZW
26159int
26160arm_elf_section_type (const char * str, size_t len)
e45d0630 26161{
c19d1205
ZW
26162 if (len == 5 && strncmp (str, "exidx", 5) == 0)
26163 return SHT_ARM_EXIDX;
e45d0630 26164
c19d1205
ZW
26165 return -1;
26166}
26167\f
26168/* Code to deal with unwinding tables. */
e45d0630 26169
c19d1205 26170static void add_unwind_adjustsp (offsetT);
e45d0630 26171
5f4273c7 26172/* Generate any deferred unwind frame offset. */
e45d0630 26173
bfae80f2 26174static void
c19d1205 26175flush_pending_unwind (void)
bfae80f2 26176{
c19d1205 26177 offsetT offset;
bfae80f2 26178
c19d1205
ZW
26179 offset = unwind.pending_offset;
26180 unwind.pending_offset = 0;
26181 if (offset != 0)
26182 add_unwind_adjustsp (offset);
bfae80f2
RE
26183}
26184
c19d1205
ZW
26185/* Add an opcode to this list for this function. Two-byte opcodes should
26186 be passed as op[0] << 8 | op[1]. The list of opcodes is built in reverse
26187 order. */
26188
bfae80f2 26189static void
c19d1205 26190add_unwind_opcode (valueT op, int length)
bfae80f2 26191{
c19d1205
ZW
26192 /* Add any deferred stack adjustment. */
26193 if (unwind.pending_offset)
26194 flush_pending_unwind ();
bfae80f2 26195
c19d1205 26196 unwind.sp_restored = 0;
bfae80f2 26197
c19d1205 26198 if (unwind.opcode_count + length > unwind.opcode_alloc)
bfae80f2 26199 {
c19d1205
ZW
26200 unwind.opcode_alloc += ARM_OPCODE_CHUNK_SIZE;
26201 if (unwind.opcodes)
325801bd
TS
26202 unwind.opcodes = XRESIZEVEC (unsigned char, unwind.opcodes,
26203 unwind.opcode_alloc);
c19d1205 26204 else
325801bd 26205 unwind.opcodes = XNEWVEC (unsigned char, unwind.opcode_alloc);
bfae80f2 26206 }
c19d1205 26207 while (length > 0)
bfae80f2 26208 {
c19d1205
ZW
26209 length--;
26210 unwind.opcodes[unwind.opcode_count] = op & 0xff;
26211 op >>= 8;
26212 unwind.opcode_count++;
bfae80f2 26213 }
bfae80f2
RE
26214}
26215
c19d1205
ZW
26216/* Add unwind opcodes to adjust the stack pointer. */
26217
bfae80f2 26218static void
c19d1205 26219add_unwind_adjustsp (offsetT offset)
bfae80f2 26220{
c19d1205 26221 valueT op;
bfae80f2 26222
c19d1205 26223 if (offset > 0x200)
bfae80f2 26224 {
c19d1205
ZW
26225 /* We need at most 5 bytes to hold a 32-bit value in a uleb128. */
26226 char bytes[5];
26227 int n;
26228 valueT o;
bfae80f2 26229
c19d1205
ZW
26230 /* Long form: 0xb2, uleb128. */
26231 /* This might not fit in a word so add the individual bytes,
26232 remembering the list is built in reverse order. */
26233 o = (valueT) ((offset - 0x204) >> 2);
26234 if (o == 0)
26235 add_unwind_opcode (0, 1);
bfae80f2 26236
c19d1205
ZW
26237 /* Calculate the uleb128 encoding of the offset. */
26238 n = 0;
26239 while (o)
26240 {
26241 bytes[n] = o & 0x7f;
26242 o >>= 7;
26243 if (o)
26244 bytes[n] |= 0x80;
26245 n++;
26246 }
26247 /* Add the insn. */
26248 for (; n; n--)
26249 add_unwind_opcode (bytes[n - 1], 1);
26250 add_unwind_opcode (0xb2, 1);
26251 }
26252 else if (offset > 0x100)
bfae80f2 26253 {
c19d1205
ZW
26254 /* Two short opcodes. */
26255 add_unwind_opcode (0x3f, 1);
26256 op = (offset - 0x104) >> 2;
26257 add_unwind_opcode (op, 1);
bfae80f2 26258 }
c19d1205
ZW
26259 else if (offset > 0)
26260 {
26261 /* Short opcode. */
26262 op = (offset - 4) >> 2;
26263 add_unwind_opcode (op, 1);
26264 }
26265 else if (offset < 0)
bfae80f2 26266 {
c19d1205
ZW
26267 offset = -offset;
26268 while (offset > 0x100)
bfae80f2 26269 {
c19d1205
ZW
26270 add_unwind_opcode (0x7f, 1);
26271 offset -= 0x100;
bfae80f2 26272 }
c19d1205
ZW
26273 op = ((offset - 4) >> 2) | 0x40;
26274 add_unwind_opcode (op, 1);
bfae80f2 26275 }
bfae80f2
RE
26276}
26277
c19d1205 26278/* Finish the list of unwind opcodes for this function. */
0198d5e6 26279
c19d1205
ZW
26280static void
26281finish_unwind_opcodes (void)
bfae80f2 26282{
c19d1205 26283 valueT op;
bfae80f2 26284
c19d1205 26285 if (unwind.fp_used)
bfae80f2 26286 {
708587a4 26287 /* Adjust sp as necessary. */
c19d1205
ZW
26288 unwind.pending_offset += unwind.fp_offset - unwind.frame_size;
26289 flush_pending_unwind ();
bfae80f2 26290
c19d1205
ZW
26291 /* After restoring sp from the frame pointer. */
26292 op = 0x90 | unwind.fp_reg;
26293 add_unwind_opcode (op, 1);
26294 }
26295 else
26296 flush_pending_unwind ();
bfae80f2
RE
26297}
26298
bfae80f2 26299
c19d1205
ZW
26300/* Start an exception table entry. If idx is nonzero this is an index table
26301 entry. */
bfae80f2
RE
26302
26303static void
c19d1205 26304start_unwind_section (const segT text_seg, int idx)
bfae80f2 26305{
c19d1205
ZW
26306 const char * text_name;
26307 const char * prefix;
26308 const char * prefix_once;
26309 const char * group_name;
c19d1205 26310 char * sec_name;
c19d1205
ZW
26311 int type;
26312 int flags;
26313 int linkonce;
bfae80f2 26314
c19d1205 26315 if (idx)
bfae80f2 26316 {
c19d1205
ZW
26317 prefix = ELF_STRING_ARM_unwind;
26318 prefix_once = ELF_STRING_ARM_unwind_once;
26319 type = SHT_ARM_EXIDX;
bfae80f2 26320 }
c19d1205 26321 else
bfae80f2 26322 {
c19d1205
ZW
26323 prefix = ELF_STRING_ARM_unwind_info;
26324 prefix_once = ELF_STRING_ARM_unwind_info_once;
26325 type = SHT_PROGBITS;
bfae80f2
RE
26326 }
26327
c19d1205
ZW
26328 text_name = segment_name (text_seg);
26329 if (streq (text_name, ".text"))
26330 text_name = "";
26331
26332 if (strncmp (text_name, ".gnu.linkonce.t.",
26333 strlen (".gnu.linkonce.t.")) == 0)
bfae80f2 26334 {
c19d1205
ZW
26335 prefix = prefix_once;
26336 text_name += strlen (".gnu.linkonce.t.");
bfae80f2
RE
26337 }
26338
29a2809e 26339 sec_name = concat (prefix, text_name, (char *) NULL);
bfae80f2 26340
c19d1205
ZW
26341 flags = SHF_ALLOC;
26342 linkonce = 0;
26343 group_name = 0;
bfae80f2 26344
c19d1205
ZW
26345 /* Handle COMDAT group. */
26346 if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
bfae80f2 26347 {
c19d1205
ZW
26348 group_name = elf_group_name (text_seg);
26349 if (group_name == NULL)
26350 {
bd3ba5d1 26351 as_bad (_("Group section `%s' has no group signature"),
c19d1205
ZW
26352 segment_name (text_seg));
26353 ignore_rest_of_line ();
26354 return;
26355 }
26356 flags |= SHF_GROUP;
26357 linkonce = 1;
bfae80f2
RE
26358 }
26359
a91e1603
L
26360 obj_elf_change_section (sec_name, type, 0, flags, 0, group_name,
26361 linkonce, 0);
bfae80f2 26362
5f4273c7 26363 /* Set the section link for index tables. */
c19d1205
ZW
26364 if (idx)
26365 elf_linked_to_section (now_seg) = text_seg;
bfae80f2
RE
26366}
26367
bfae80f2 26368
c19d1205
ZW
26369/* Start an unwind table entry. HAVE_DATA is nonzero if we have additional
26370 personality routine data. Returns zero, or the index table value for
cad0da33 26371 an inline entry. */
c19d1205
ZW
26372
26373static valueT
26374create_unwind_entry (int have_data)
bfae80f2 26375{
c19d1205
ZW
26376 int size;
26377 addressT where;
26378 char *ptr;
26379 /* The current word of data. */
26380 valueT data;
26381 /* The number of bytes left in this word. */
26382 int n;
bfae80f2 26383
c19d1205 26384 finish_unwind_opcodes ();
bfae80f2 26385
c19d1205
ZW
26386 /* Remember the current text section. */
26387 unwind.saved_seg = now_seg;
26388 unwind.saved_subseg = now_subseg;
bfae80f2 26389
c19d1205 26390 start_unwind_section (now_seg, 0);
bfae80f2 26391
c19d1205 26392 if (unwind.personality_routine == NULL)
bfae80f2 26393 {
c19d1205
ZW
26394 if (unwind.personality_index == -2)
26395 {
26396 if (have_data)
5f4273c7 26397 as_bad (_("handlerdata in cantunwind frame"));
c19d1205
ZW
26398 return 1; /* EXIDX_CANTUNWIND. */
26399 }
bfae80f2 26400
c19d1205
ZW
26401 /* Use a default personality routine if none is specified. */
26402 if (unwind.personality_index == -1)
26403 {
26404 if (unwind.opcode_count > 3)
26405 unwind.personality_index = 1;
26406 else
26407 unwind.personality_index = 0;
26408 }
bfae80f2 26409
c19d1205
ZW
26410 /* Space for the personality routine entry. */
26411 if (unwind.personality_index == 0)
26412 {
26413 if (unwind.opcode_count > 3)
26414 as_bad (_("too many unwind opcodes for personality routine 0"));
bfae80f2 26415
c19d1205
ZW
26416 if (!have_data)
26417 {
26418 /* All the data is inline in the index table. */
26419 data = 0x80;
26420 n = 3;
26421 while (unwind.opcode_count > 0)
26422 {
26423 unwind.opcode_count--;
26424 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
26425 n--;
26426 }
bfae80f2 26427
c19d1205
ZW
26428 /* Pad with "finish" opcodes. */
26429 while (n--)
26430 data = (data << 8) | 0xb0;
bfae80f2 26431
c19d1205
ZW
26432 return data;
26433 }
26434 size = 0;
26435 }
26436 else
26437 /* We get two opcodes "free" in the first word. */
26438 size = unwind.opcode_count - 2;
26439 }
26440 else
5011093d 26441 {
cad0da33
NC
26442 /* PR 16765: Missing or misplaced unwind directives can trigger this. */
26443 if (unwind.personality_index != -1)
26444 {
26445 as_bad (_("attempt to recreate an unwind entry"));
26446 return 1;
26447 }
5011093d
NC
26448
26449 /* An extra byte is required for the opcode count. */
26450 size = unwind.opcode_count + 1;
26451 }
bfae80f2 26452
c19d1205
ZW
26453 size = (size + 3) >> 2;
26454 if (size > 0xff)
26455 as_bad (_("too many unwind opcodes"));
bfae80f2 26456
c19d1205
ZW
26457 frag_align (2, 0, 0);
26458 record_alignment (now_seg, 2);
26459 unwind.table_entry = expr_build_dot ();
26460
26461 /* Allocate the table entry. */
26462 ptr = frag_more ((size << 2) + 4);
74929e7b
NC
26463 /* PR 13449: Zero the table entries in case some of them are not used. */
26464 memset (ptr, 0, (size << 2) + 4);
c19d1205 26465 where = frag_now_fix () - ((size << 2) + 4);
bfae80f2 26466
c19d1205 26467 switch (unwind.personality_index)
bfae80f2 26468 {
c19d1205
ZW
26469 case -1:
26470 /* ??? Should this be a PLT generating relocation? */
26471 /* Custom personality routine. */
26472 fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1,
26473 BFD_RELOC_ARM_PREL31);
bfae80f2 26474
c19d1205
ZW
26475 where += 4;
26476 ptr += 4;
bfae80f2 26477
c19d1205 26478 /* Set the first byte to the number of additional words. */
5011093d 26479 data = size > 0 ? size - 1 : 0;
c19d1205
ZW
26480 n = 3;
26481 break;
bfae80f2 26482
c19d1205
ZW
26483 /* ABI defined personality routines. */
26484 case 0:
26485 /* Three opcodes bytes are packed into the first word. */
26486 data = 0x80;
26487 n = 3;
26488 break;
bfae80f2 26489
c19d1205
ZW
26490 case 1:
26491 case 2:
26492 /* The size and first two opcode bytes go in the first word. */
26493 data = ((0x80 + unwind.personality_index) << 8) | size;
26494 n = 2;
26495 break;
bfae80f2 26496
c19d1205
ZW
26497 default:
26498 /* Should never happen. */
26499 abort ();
26500 }
bfae80f2 26501
c19d1205
ZW
26502 /* Pack the opcodes into words (MSB first), reversing the list at the same
26503 time. */
26504 while (unwind.opcode_count > 0)
26505 {
26506 if (n == 0)
26507 {
26508 md_number_to_chars (ptr, data, 4);
26509 ptr += 4;
26510 n = 4;
26511 data = 0;
26512 }
26513 unwind.opcode_count--;
26514 n--;
26515 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
26516 }
26517
26518 /* Finish off the last word. */
26519 if (n < 4)
26520 {
26521 /* Pad with "finish" opcodes. */
26522 while (n--)
26523 data = (data << 8) | 0xb0;
26524
26525 md_number_to_chars (ptr, data, 4);
26526 }
26527
26528 if (!have_data)
26529 {
26530 /* Add an empty descriptor if there is no user-specified data. */
26531 ptr = frag_more (4);
26532 md_number_to_chars (ptr, 0, 4);
26533 }
26534
26535 return 0;
bfae80f2
RE
26536}
26537
f0927246
NC
26538
26539/* Initialize the DWARF-2 unwind information for this procedure. */
26540
26541void
26542tc_arm_frame_initial_instructions (void)
26543{
26544 cfi_add_CFA_def_cfa (REG_SP, 0);
26545}
26546#endif /* OBJ_ELF */
26547
c19d1205
ZW
26548/* Convert REGNAME to a DWARF-2 register number. */
26549
26550int
1df69f4f 26551tc_arm_regname_to_dw2regnum (char *regname)
bfae80f2 26552{
1df69f4f 26553 int reg = arm_reg_parse (&regname, REG_TYPE_RN);
1f5afe1c
NC
26554 if (reg != FAIL)
26555 return reg;
c19d1205 26556
1f5afe1c
NC
26557 /* PR 16694: Allow VFP registers as well. */
26558 reg = arm_reg_parse (&regname, REG_TYPE_VFS);
26559 if (reg != FAIL)
26560 return 64 + reg;
c19d1205 26561
1f5afe1c
NC
26562 reg = arm_reg_parse (&regname, REG_TYPE_VFD);
26563 if (reg != FAIL)
26564 return reg + 256;
26565
0198d5e6 26566 return FAIL;
bfae80f2
RE
26567}
26568
f0927246 26569#ifdef TE_PE
c19d1205 26570void
f0927246 26571tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
bfae80f2 26572{
91d6fa6a 26573 expressionS exp;
bfae80f2 26574
91d6fa6a
NC
26575 exp.X_op = O_secrel;
26576 exp.X_add_symbol = symbol;
26577 exp.X_add_number = 0;
26578 emit_expr (&exp, size);
f0927246
NC
26579}
26580#endif
bfae80f2 26581
c19d1205 26582/* MD interface: Symbol and relocation handling. */
bfae80f2 26583
2fc8bdac
ZW
26584/* Return the address within the segment that a PC-relative fixup is
26585 relative to. For ARM, PC-relative fixups applied to instructions
26586 are generally relative to the location of the fixup plus 8 bytes.
26587 Thumb branches are offset by 4, and Thumb loads relative to PC
26588 require special handling. */
bfae80f2 26589
c19d1205 26590long
2fc8bdac 26591md_pcrel_from_section (fixS * fixP, segT seg)
bfae80f2 26592{
2fc8bdac
ZW
26593 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
26594
26595 /* If this is pc-relative and we are going to emit a relocation
26596 then we just want to put out any pipeline compensation that the linker
53baae48
NC
26597 will need. Otherwise we want to use the calculated base.
26598 For WinCE we skip the bias for externals as well, since this
26599 is how the MS ARM-CE assembler behaves and we want to be compatible. */
5f4273c7 26600 if (fixP->fx_pcrel
2fc8bdac 26601 && ((fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != seg)
53baae48
NC
26602 || (arm_force_relocation (fixP)
26603#ifdef TE_WINCE
26604 && !S_IS_EXTERNAL (fixP->fx_addsy)
26605#endif
26606 )))
2fc8bdac 26607 base = 0;
bfae80f2 26608
267bf995 26609
c19d1205 26610 switch (fixP->fx_r_type)
bfae80f2 26611 {
2fc8bdac
ZW
26612 /* PC relative addressing on the Thumb is slightly odd as the
26613 bottom two bits of the PC are forced to zero for the
26614 calculation. This happens *after* application of the
26615 pipeline offset. However, Thumb adrl already adjusts for
26616 this, so we need not do it again. */
c19d1205 26617 case BFD_RELOC_ARM_THUMB_ADD:
2fc8bdac 26618 return base & ~3;
c19d1205
ZW
26619
26620 case BFD_RELOC_ARM_THUMB_OFFSET:
26621 case BFD_RELOC_ARM_T32_OFFSET_IMM:
e9f89963 26622 case BFD_RELOC_ARM_T32_ADD_PC12:
8f06b2d8 26623 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
2fc8bdac 26624 return (base + 4) & ~3;
c19d1205 26625
2fc8bdac 26626 /* Thumb branches are simply offset by +4. */
e12437dc 26627 case BFD_RELOC_THUMB_PCREL_BRANCH5:
2fc8bdac
ZW
26628 case BFD_RELOC_THUMB_PCREL_BRANCH7:
26629 case BFD_RELOC_THUMB_PCREL_BRANCH9:
26630 case BFD_RELOC_THUMB_PCREL_BRANCH12:
26631 case BFD_RELOC_THUMB_PCREL_BRANCH20:
2fc8bdac 26632 case BFD_RELOC_THUMB_PCREL_BRANCH25:
f6b2b12d 26633 case BFD_RELOC_THUMB_PCREL_BFCSEL:
e5d6e09e 26634 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 26635 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 26636 case BFD_RELOC_ARM_THUMB_BF13:
60f993ce 26637 case BFD_RELOC_ARM_THUMB_LOOP12:
2fc8bdac 26638 return base + 4;
bfae80f2 26639
267bf995 26640 case BFD_RELOC_THUMB_PCREL_BRANCH23:
486499d0
CL
26641 if (fixP->fx_addsy
26642 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 26643 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995 26644 && ARM_IS_FUNC (fixP->fx_addsy)
477330fc
RM
26645 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
26646 base = fixP->fx_where + fixP->fx_frag->fr_address;
267bf995
RR
26647 return base + 4;
26648
00adf2d4
JB
26649 /* BLX is like branches above, but forces the low two bits of PC to
26650 zero. */
486499d0
CL
26651 case BFD_RELOC_THUMB_PCREL_BLX:
26652 if (fixP->fx_addsy
26653 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 26654 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
26655 && THUMB_IS_FUNC (fixP->fx_addsy)
26656 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
26657 base = fixP->fx_where + fixP->fx_frag->fr_address;
00adf2d4
JB
26658 return (base + 4) & ~3;
26659
2fc8bdac
ZW
26660 /* ARM mode branches are offset by +8. However, the Windows CE
26661 loader expects the relocation not to take this into account. */
267bf995 26662 case BFD_RELOC_ARM_PCREL_BLX:
486499d0
CL
26663 if (fixP->fx_addsy
26664 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 26665 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
26666 && ARM_IS_FUNC (fixP->fx_addsy)
26667 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
26668 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 26669 return base + 8;
267bf995 26670
486499d0
CL
26671 case BFD_RELOC_ARM_PCREL_CALL:
26672 if (fixP->fx_addsy
26673 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 26674 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
26675 && THUMB_IS_FUNC (fixP->fx_addsy)
26676 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
26677 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 26678 return base + 8;
267bf995 26679
2fc8bdac 26680 case BFD_RELOC_ARM_PCREL_BRANCH:
39b41c9c 26681 case BFD_RELOC_ARM_PCREL_JUMP:
2fc8bdac 26682 case BFD_RELOC_ARM_PLT32:
c19d1205 26683#ifdef TE_WINCE
5f4273c7 26684 /* When handling fixups immediately, because we have already
477330fc 26685 discovered the value of a symbol, or the address of the frag involved
53baae48 26686 we must account for the offset by +8, as the OS loader will never see the reloc.
477330fc
RM
26687 see fixup_segment() in write.c
26688 The S_IS_EXTERNAL test handles the case of global symbols.
26689 Those need the calculated base, not just the pipe compensation the linker will need. */
53baae48
NC
26690 if (fixP->fx_pcrel
26691 && fixP->fx_addsy != NULL
26692 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
26693 && (S_IS_EXTERNAL (fixP->fx_addsy) || !arm_force_relocation (fixP)))
26694 return base + 8;
2fc8bdac 26695 return base;
c19d1205 26696#else
2fc8bdac 26697 return base + 8;
c19d1205 26698#endif
2fc8bdac 26699
267bf995 26700
2fc8bdac
ZW
26701 /* ARM mode loads relative to PC are also offset by +8. Unlike
26702 branches, the Windows CE loader *does* expect the relocation
26703 to take this into account. */
26704 case BFD_RELOC_ARM_OFFSET_IMM:
26705 case BFD_RELOC_ARM_OFFSET_IMM8:
26706 case BFD_RELOC_ARM_HWLITERAL:
26707 case BFD_RELOC_ARM_LITERAL:
26708 case BFD_RELOC_ARM_CP_OFF_IMM:
26709 return base + 8;
26710
26711
26712 /* Other PC-relative relocations are un-offset. */
26713 default:
26714 return base;
26715 }
bfae80f2
RE
26716}
26717
8b2d793c
NC
26718static bfd_boolean flag_warn_syms = TRUE;
26719
ae8714c2
NC
26720bfd_boolean
26721arm_tc_equal_in_insn (int c ATTRIBUTE_UNUSED, char * name)
bfae80f2 26722{
8b2d793c
NC
26723 /* PR 18347 - Warn if the user attempts to create a symbol with the same
26724 name as an ARM instruction. Whilst strictly speaking it is allowed, it
26725 does mean that the resulting code might be very confusing to the reader.
26726 Also this warning can be triggered if the user omits an operand before
26727 an immediate address, eg:
26728
26729 LDR =foo
26730
26731 GAS treats this as an assignment of the value of the symbol foo to a
26732 symbol LDR, and so (without this code) it will not issue any kind of
26733 warning or error message.
26734
26735 Note - ARM instructions are case-insensitive but the strings in the hash
26736 table are all stored in lower case, so we must first ensure that name is
ae8714c2
NC
26737 lower case too. */
26738 if (flag_warn_syms && arm_ops_hsh)
8b2d793c
NC
26739 {
26740 char * nbuf = strdup (name);
26741 char * p;
26742
26743 for (p = nbuf; *p; p++)
26744 *p = TOLOWER (*p);
26745 if (hash_find (arm_ops_hsh, nbuf) != NULL)
26746 {
26747 static struct hash_control * already_warned = NULL;
26748
26749 if (already_warned == NULL)
26750 already_warned = hash_new ();
26751 /* Only warn about the symbol once. To keep the code
26752 simple we let hash_insert do the lookup for us. */
3076e594 26753 if (hash_insert (already_warned, nbuf, NULL) == NULL)
ae8714c2 26754 as_warn (_("[-mwarn-syms]: Assignment makes a symbol match an ARM instruction: %s"), name);
8b2d793c
NC
26755 }
26756 else
26757 free (nbuf);
26758 }
3739860c 26759
ae8714c2
NC
26760 return FALSE;
26761}
26762
26763/* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
26764 Otherwise we have no need to default values of symbols. */
26765
26766symbolS *
26767md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
26768{
26769#ifdef OBJ_ELF
26770 if (name[0] == '_' && name[1] == 'G'
26771 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
26772 {
26773 if (!GOT_symbol)
26774 {
26775 if (symbol_find (name))
26776 as_bad (_("GOT already in the symbol table"));
26777
26778 GOT_symbol = symbol_new (name, undefined_section,
26779 (valueT) 0, & zero_address_frag);
26780 }
26781
26782 return GOT_symbol;
26783 }
26784#endif
26785
c921be7d 26786 return NULL;
bfae80f2
RE
26787}
26788
55cf6793 26789/* Subroutine of md_apply_fix. Check to see if an immediate can be
c19d1205
ZW
26790 computed as two separate immediate values, added together. We
26791 already know that this value cannot be computed by just one ARM
26792 instruction. */
26793
26794static unsigned int
26795validate_immediate_twopart (unsigned int val,
26796 unsigned int * highpart)
bfae80f2 26797{
c19d1205
ZW
26798 unsigned int a;
26799 unsigned int i;
bfae80f2 26800
c19d1205
ZW
26801 for (i = 0; i < 32; i += 2)
26802 if (((a = rotate_left (val, i)) & 0xff) != 0)
26803 {
26804 if (a & 0xff00)
26805 {
26806 if (a & ~ 0xffff)
26807 continue;
26808 * highpart = (a >> 8) | ((i + 24) << 7);
26809 }
26810 else if (a & 0xff0000)
26811 {
26812 if (a & 0xff000000)
26813 continue;
26814 * highpart = (a >> 16) | ((i + 16) << 7);
26815 }
26816 else
26817 {
9c2799c2 26818 gas_assert (a & 0xff000000);
c19d1205
ZW
26819 * highpart = (a >> 24) | ((i + 8) << 7);
26820 }
bfae80f2 26821
c19d1205
ZW
26822 return (a & 0xff) | (i << 7);
26823 }
bfae80f2 26824
c19d1205 26825 return FAIL;
bfae80f2
RE
26826}
26827
c19d1205
ZW
26828static int
26829validate_offset_imm (unsigned int val, int hwse)
26830{
26831 if ((hwse && val > 255) || val > 4095)
26832 return FAIL;
26833 return val;
26834}
bfae80f2 26835
55cf6793 26836/* Subroutine of md_apply_fix. Do those data_ops which can take a
c19d1205
ZW
26837 negative immediate constant by altering the instruction. A bit of
26838 a hack really.
26839 MOV <-> MVN
26840 AND <-> BIC
26841 ADC <-> SBC
26842 by inverting the second operand, and
26843 ADD <-> SUB
26844 CMP <-> CMN
26845 by negating the second operand. */
bfae80f2 26846
c19d1205
ZW
26847static int
26848negate_data_op (unsigned long * instruction,
26849 unsigned long value)
bfae80f2 26850{
c19d1205
ZW
26851 int op, new_inst;
26852 unsigned long negated, inverted;
bfae80f2 26853
c19d1205
ZW
26854 negated = encode_arm_immediate (-value);
26855 inverted = encode_arm_immediate (~value);
bfae80f2 26856
c19d1205
ZW
26857 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
26858 switch (op)
bfae80f2 26859 {
c19d1205
ZW
26860 /* First negates. */
26861 case OPCODE_SUB: /* ADD <-> SUB */
26862 new_inst = OPCODE_ADD;
26863 value = negated;
26864 break;
bfae80f2 26865
c19d1205
ZW
26866 case OPCODE_ADD:
26867 new_inst = OPCODE_SUB;
26868 value = negated;
26869 break;
bfae80f2 26870
c19d1205
ZW
26871 case OPCODE_CMP: /* CMP <-> CMN */
26872 new_inst = OPCODE_CMN;
26873 value = negated;
26874 break;
bfae80f2 26875
c19d1205
ZW
26876 case OPCODE_CMN:
26877 new_inst = OPCODE_CMP;
26878 value = negated;
26879 break;
bfae80f2 26880
c19d1205
ZW
26881 /* Now Inverted ops. */
26882 case OPCODE_MOV: /* MOV <-> MVN */
26883 new_inst = OPCODE_MVN;
26884 value = inverted;
26885 break;
bfae80f2 26886
c19d1205
ZW
26887 case OPCODE_MVN:
26888 new_inst = OPCODE_MOV;
26889 value = inverted;
26890 break;
bfae80f2 26891
c19d1205
ZW
26892 case OPCODE_AND: /* AND <-> BIC */
26893 new_inst = OPCODE_BIC;
26894 value = inverted;
26895 break;
bfae80f2 26896
c19d1205
ZW
26897 case OPCODE_BIC:
26898 new_inst = OPCODE_AND;
26899 value = inverted;
26900 break;
bfae80f2 26901
c19d1205
ZW
26902 case OPCODE_ADC: /* ADC <-> SBC */
26903 new_inst = OPCODE_SBC;
26904 value = inverted;
26905 break;
bfae80f2 26906
c19d1205
ZW
26907 case OPCODE_SBC:
26908 new_inst = OPCODE_ADC;
26909 value = inverted;
26910 break;
bfae80f2 26911
c19d1205
ZW
26912 /* We cannot do anything. */
26913 default:
26914 return FAIL;
b99bd4ef
NC
26915 }
26916
c19d1205
ZW
26917 if (value == (unsigned) FAIL)
26918 return FAIL;
26919
26920 *instruction &= OPCODE_MASK;
26921 *instruction |= new_inst << DATA_OP_SHIFT;
26922 return value;
b99bd4ef
NC
26923}
26924
ef8d22e6
PB
26925/* Like negate_data_op, but for Thumb-2. */
26926
26927static unsigned int
16dd5e42 26928thumb32_negate_data_op (offsetT *instruction, unsigned int value)
ef8d22e6
PB
26929{
26930 int op, new_inst;
26931 int rd;
16dd5e42 26932 unsigned int negated, inverted;
ef8d22e6
PB
26933
26934 negated = encode_thumb32_immediate (-value);
26935 inverted = encode_thumb32_immediate (~value);
26936
26937 rd = (*instruction >> 8) & 0xf;
26938 op = (*instruction >> T2_DATA_OP_SHIFT) & 0xf;
26939 switch (op)
26940 {
26941 /* ADD <-> SUB. Includes CMP <-> CMN. */
26942 case T2_OPCODE_SUB:
26943 new_inst = T2_OPCODE_ADD;
26944 value = negated;
26945 break;
26946
26947 case T2_OPCODE_ADD:
26948 new_inst = T2_OPCODE_SUB;
26949 value = negated;
26950 break;
26951
26952 /* ORR <-> ORN. Includes MOV <-> MVN. */
26953 case T2_OPCODE_ORR:
26954 new_inst = T2_OPCODE_ORN;
26955 value = inverted;
26956 break;
26957
26958 case T2_OPCODE_ORN:
26959 new_inst = T2_OPCODE_ORR;
26960 value = inverted;
26961 break;
26962
26963 /* AND <-> BIC. TST has no inverted equivalent. */
26964 case T2_OPCODE_AND:
26965 new_inst = T2_OPCODE_BIC;
26966 if (rd == 15)
26967 value = FAIL;
26968 else
26969 value = inverted;
26970 break;
26971
26972 case T2_OPCODE_BIC:
26973 new_inst = T2_OPCODE_AND;
26974 value = inverted;
26975 break;
26976
26977 /* ADC <-> SBC */
26978 case T2_OPCODE_ADC:
26979 new_inst = T2_OPCODE_SBC;
26980 value = inverted;
26981 break;
26982
26983 case T2_OPCODE_SBC:
26984 new_inst = T2_OPCODE_ADC;
26985 value = inverted;
26986 break;
26987
26988 /* We cannot do anything. */
26989 default:
26990 return FAIL;
26991 }
26992
16dd5e42 26993 if (value == (unsigned int)FAIL)
ef8d22e6
PB
26994 return FAIL;
26995
26996 *instruction &= T2_OPCODE_MASK;
26997 *instruction |= new_inst << T2_DATA_OP_SHIFT;
26998 return value;
26999}
27000
8f06b2d8 27001/* Read a 32-bit thumb instruction from buf. */
0198d5e6 27002
8f06b2d8
PB
27003static unsigned long
27004get_thumb32_insn (char * buf)
27005{
27006 unsigned long insn;
27007 insn = md_chars_to_number (buf, THUMB_SIZE) << 16;
27008 insn |= md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
27009
27010 return insn;
27011}
27012
a8bc6c78
PB
27013/* We usually want to set the low bit on the address of thumb function
27014 symbols. In particular .word foo - . should have the low bit set.
27015 Generic code tries to fold the difference of two symbols to
27016 a constant. Prevent this and force a relocation when the first symbols
27017 is a thumb function. */
c921be7d
NC
27018
27019bfd_boolean
a8bc6c78
PB
27020arm_optimize_expr (expressionS *l, operatorT op, expressionS *r)
27021{
27022 if (op == O_subtract
27023 && l->X_op == O_symbol
27024 && r->X_op == O_symbol
27025 && THUMB_IS_FUNC (l->X_add_symbol))
27026 {
27027 l->X_op = O_subtract;
27028 l->X_op_symbol = r->X_add_symbol;
27029 l->X_add_number -= r->X_add_number;
c921be7d 27030 return TRUE;
a8bc6c78 27031 }
c921be7d 27032
a8bc6c78 27033 /* Process as normal. */
c921be7d 27034 return FALSE;
a8bc6c78
PB
27035}
27036
4a42ebbc
RR
27037/* Encode Thumb2 unconditional branches and calls. The encoding
27038 for the 2 are identical for the immediate values. */
27039
27040static void
27041encode_thumb2_b_bl_offset (char * buf, offsetT value)
27042{
27043#define T2I1I2MASK ((1 << 13) | (1 << 11))
27044 offsetT newval;
27045 offsetT newval2;
27046 addressT S, I1, I2, lo, hi;
27047
27048 S = (value >> 24) & 0x01;
27049 I1 = (value >> 23) & 0x01;
27050 I2 = (value >> 22) & 0x01;
27051 hi = (value >> 12) & 0x3ff;
fa94de6b 27052 lo = (value >> 1) & 0x7ff;
4a42ebbc
RR
27053 newval = md_chars_to_number (buf, THUMB_SIZE);
27054 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
27055 newval |= (S << 10) | hi;
27056 newval2 &= ~T2I1I2MASK;
27057 newval2 |= (((I1 ^ S) << 13) | ((I2 ^ S) << 11) | lo) ^ T2I1I2MASK;
27058 md_number_to_chars (buf, newval, THUMB_SIZE);
27059 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
27060}
27061
c19d1205 27062void
55cf6793 27063md_apply_fix (fixS * fixP,
c19d1205
ZW
27064 valueT * valP,
27065 segT seg)
27066{
27067 offsetT value = * valP;
27068 offsetT newval;
27069 unsigned int newimm;
27070 unsigned long temp;
27071 int sign;
27072 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
b99bd4ef 27073
9c2799c2 27074 gas_assert (fixP->fx_r_type <= BFD_RELOC_UNUSED);
b99bd4ef 27075
c19d1205 27076 /* Note whether this will delete the relocation. */
4962c51a 27077
c19d1205
ZW
27078 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
27079 fixP->fx_done = 1;
b99bd4ef 27080
adbaf948 27081 /* On a 64-bit host, silently truncate 'value' to 32 bits for
5f4273c7 27082 consistency with the behaviour on 32-bit hosts. Remember value
adbaf948
ZW
27083 for emit_reloc. */
27084 value &= 0xffffffff;
27085 value ^= 0x80000000;
5f4273c7 27086 value -= 0x80000000;
adbaf948
ZW
27087
27088 *valP = value;
c19d1205 27089 fixP->fx_addnumber = value;
b99bd4ef 27090
adbaf948
ZW
27091 /* Same treatment for fixP->fx_offset. */
27092 fixP->fx_offset &= 0xffffffff;
27093 fixP->fx_offset ^= 0x80000000;
27094 fixP->fx_offset -= 0x80000000;
27095
c19d1205 27096 switch (fixP->fx_r_type)
b99bd4ef 27097 {
c19d1205
ZW
27098 case BFD_RELOC_NONE:
27099 /* This will need to go in the object file. */
27100 fixP->fx_done = 0;
27101 break;
b99bd4ef 27102
c19d1205
ZW
27103 case BFD_RELOC_ARM_IMMEDIATE:
27104 /* We claim that this fixup has been processed here,
27105 even if in fact we generate an error because we do
27106 not have a reloc for it, so tc_gen_reloc will reject it. */
27107 fixP->fx_done = 1;
b99bd4ef 27108
77db8e2e 27109 if (fixP->fx_addsy)
b99bd4ef 27110 {
77db8e2e 27111 const char *msg = 0;
b99bd4ef 27112
77db8e2e
NC
27113 if (! S_IS_DEFINED (fixP->fx_addsy))
27114 msg = _("undefined symbol %s used as an immediate value");
27115 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
27116 msg = _("symbol %s is in a different section");
27117 else if (S_IS_WEAK (fixP->fx_addsy))
27118 msg = _("symbol %s is weak and may be overridden later");
27119
27120 if (msg)
27121 {
27122 as_bad_where (fixP->fx_file, fixP->fx_line,
27123 msg, S_GET_NAME (fixP->fx_addsy));
27124 break;
27125 }
42e5fcbf
AS
27126 }
27127
c19d1205
ZW
27128 temp = md_chars_to_number (buf, INSN_SIZE);
27129
5e73442d
SL
27130 /* If the offset is negative, we should use encoding A2 for ADR. */
27131 if ((temp & 0xfff0000) == 0x28f0000 && value < 0)
27132 newimm = negate_data_op (&temp, value);
27133 else
27134 {
27135 newimm = encode_arm_immediate (value);
27136
27137 /* If the instruction will fail, see if we can fix things up by
27138 changing the opcode. */
27139 if (newimm == (unsigned int) FAIL)
27140 newimm = negate_data_op (&temp, value);
bada4342
JW
27141 /* MOV accepts both ARM modified immediate (A1 encoding) and
27142 UINT16 (A2 encoding) when possible, MOVW only accepts UINT16.
27143 When disassembling, MOV is preferred when there is no encoding
27144 overlap. */
27145 if (newimm == (unsigned int) FAIL
27146 && ((temp >> DATA_OP_SHIFT) & 0xf) == OPCODE_MOV
27147 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
27148 && !((temp >> SBIT_SHIFT) & 0x1)
27149 && value >= 0 && value <= 0xffff)
27150 {
27151 /* Clear bits[23:20] to change encoding from A1 to A2. */
27152 temp &= 0xff0fffff;
27153 /* Encoding high 4bits imm. Code below will encode the remaining
27154 low 12bits. */
27155 temp |= (value & 0x0000f000) << 4;
27156 newimm = value & 0x00000fff;
27157 }
5e73442d
SL
27158 }
27159
27160 if (newimm == (unsigned int) FAIL)
b99bd4ef 27161 {
c19d1205
ZW
27162 as_bad_where (fixP->fx_file, fixP->fx_line,
27163 _("invalid constant (%lx) after fixup"),
27164 (unsigned long) value);
27165 break;
b99bd4ef 27166 }
b99bd4ef 27167
c19d1205
ZW
27168 newimm |= (temp & 0xfffff000);
27169 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
27170 break;
b99bd4ef 27171
c19d1205
ZW
27172 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
27173 {
27174 unsigned int highpart = 0;
27175 unsigned int newinsn = 0xe1a00000; /* nop. */
b99bd4ef 27176
77db8e2e 27177 if (fixP->fx_addsy)
42e5fcbf 27178 {
77db8e2e 27179 const char *msg = 0;
42e5fcbf 27180
77db8e2e
NC
27181 if (! S_IS_DEFINED (fixP->fx_addsy))
27182 msg = _("undefined symbol %s used as an immediate value");
27183 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
27184 msg = _("symbol %s is in a different section");
27185 else if (S_IS_WEAK (fixP->fx_addsy))
27186 msg = _("symbol %s is weak and may be overridden later");
42e5fcbf 27187
77db8e2e
NC
27188 if (msg)
27189 {
27190 as_bad_where (fixP->fx_file, fixP->fx_line,
27191 msg, S_GET_NAME (fixP->fx_addsy));
27192 break;
27193 }
27194 }
fa94de6b 27195
c19d1205
ZW
27196 newimm = encode_arm_immediate (value);
27197 temp = md_chars_to_number (buf, INSN_SIZE);
b99bd4ef 27198
c19d1205
ZW
27199 /* If the instruction will fail, see if we can fix things up by
27200 changing the opcode. */
27201 if (newimm == (unsigned int) FAIL
27202 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
27203 {
27204 /* No ? OK - try using two ADD instructions to generate
27205 the value. */
27206 newimm = validate_immediate_twopart (value, & highpart);
b99bd4ef 27207
c19d1205
ZW
27208 /* Yes - then make sure that the second instruction is
27209 also an add. */
27210 if (newimm != (unsigned int) FAIL)
27211 newinsn = temp;
27212 /* Still No ? Try using a negated value. */
27213 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
27214 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
27215 /* Otherwise - give up. */
27216 else
27217 {
27218 as_bad_where (fixP->fx_file, fixP->fx_line,
27219 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
27220 (long) value);
27221 break;
27222 }
b99bd4ef 27223
c19d1205
ZW
27224 /* Replace the first operand in the 2nd instruction (which
27225 is the PC) with the destination register. We have
27226 already added in the PC in the first instruction and we
27227 do not want to do it again. */
27228 newinsn &= ~ 0xf0000;
27229 newinsn |= ((newinsn & 0x0f000) << 4);
27230 }
b99bd4ef 27231
c19d1205
ZW
27232 newimm |= (temp & 0xfffff000);
27233 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
b99bd4ef 27234
c19d1205
ZW
27235 highpart |= (newinsn & 0xfffff000);
27236 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
27237 }
27238 break;
b99bd4ef 27239
c19d1205 27240 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
27241 if (!fixP->fx_done && seg->use_rela_p)
27242 value = 0;
1a0670f3 27243 /* Fall through. */
00a97672 27244
c19d1205 27245 case BFD_RELOC_ARM_LITERAL:
26d97720 27246 sign = value > 0;
b99bd4ef 27247
c19d1205
ZW
27248 if (value < 0)
27249 value = - value;
b99bd4ef 27250
c19d1205 27251 if (validate_offset_imm (value, 0) == FAIL)
f03698e6 27252 {
c19d1205
ZW
27253 if (fixP->fx_r_type == BFD_RELOC_ARM_LITERAL)
27254 as_bad_where (fixP->fx_file, fixP->fx_line,
27255 _("invalid literal constant: pool needs to be closer"));
27256 else
27257 as_bad_where (fixP->fx_file, fixP->fx_line,
27258 _("bad immediate value for offset (%ld)"),
27259 (long) value);
27260 break;
f03698e6
RE
27261 }
27262
c19d1205 27263 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
27264 if (value == 0)
27265 newval &= 0xfffff000;
27266 else
27267 {
27268 newval &= 0xff7ff000;
27269 newval |= value | (sign ? INDEX_UP : 0);
27270 }
c19d1205
ZW
27271 md_number_to_chars (buf, newval, INSN_SIZE);
27272 break;
b99bd4ef 27273
c19d1205
ZW
27274 case BFD_RELOC_ARM_OFFSET_IMM8:
27275 case BFD_RELOC_ARM_HWLITERAL:
26d97720 27276 sign = value > 0;
b99bd4ef 27277
c19d1205
ZW
27278 if (value < 0)
27279 value = - value;
b99bd4ef 27280
c19d1205 27281 if (validate_offset_imm (value, 1) == FAIL)
b99bd4ef 27282 {
c19d1205
ZW
27283 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
27284 as_bad_where (fixP->fx_file, fixP->fx_line,
27285 _("invalid literal constant: pool needs to be closer"));
27286 else
427d0db6
RM
27287 as_bad_where (fixP->fx_file, fixP->fx_line,
27288 _("bad immediate value for 8-bit offset (%ld)"),
27289 (long) value);
c19d1205 27290 break;
b99bd4ef
NC
27291 }
27292
c19d1205 27293 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
27294 if (value == 0)
27295 newval &= 0xfffff0f0;
27296 else
27297 {
27298 newval &= 0xff7ff0f0;
27299 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
27300 }
c19d1205
ZW
27301 md_number_to_chars (buf, newval, INSN_SIZE);
27302 break;
b99bd4ef 27303
c19d1205
ZW
27304 case BFD_RELOC_ARM_T32_OFFSET_U8:
27305 if (value < 0 || value > 1020 || value % 4 != 0)
27306 as_bad_where (fixP->fx_file, fixP->fx_line,
27307 _("bad immediate value for offset (%ld)"), (long) value);
27308 value /= 4;
b99bd4ef 27309
c19d1205 27310 newval = md_chars_to_number (buf+2, THUMB_SIZE);
c19d1205
ZW
27311 newval |= value;
27312 md_number_to_chars (buf+2, newval, THUMB_SIZE);
27313 break;
b99bd4ef 27314
c19d1205
ZW
27315 case BFD_RELOC_ARM_T32_OFFSET_IMM:
27316 /* This is a complicated relocation used for all varieties of Thumb32
27317 load/store instruction with immediate offset:
27318
27319 1110 100P u1WL NNNN XXXX YYYY iiii iiii - +/-(U) pre/post(P) 8-bit,
477330fc 27320 *4, optional writeback(W)
c19d1205
ZW
27321 (doubleword load/store)
27322
27323 1111 100S uTTL 1111 XXXX iiii iiii iiii - +/-(U) 12-bit PC-rel
27324 1111 100S 0TTL NNNN XXXX 1Pu1 iiii iiii - +/-(U) pre/post(P) 8-bit
27325 1111 100S 0TTL NNNN XXXX 1110 iiii iiii - positive 8-bit (T instruction)
27326 1111 100S 1TTL NNNN XXXX iiii iiii iiii - positive 12-bit
27327 1111 100S 0TTL NNNN XXXX 1100 iiii iiii - negative 8-bit
27328
27329 Uppercase letters indicate bits that are already encoded at
27330 this point. Lowercase letters are our problem. For the
27331 second block of instructions, the secondary opcode nybble
27332 (bits 8..11) is present, and bit 23 is zero, even if this is
27333 a PC-relative operation. */
27334 newval = md_chars_to_number (buf, THUMB_SIZE);
27335 newval <<= 16;
27336 newval |= md_chars_to_number (buf+THUMB_SIZE, THUMB_SIZE);
b99bd4ef 27337
c19d1205 27338 if ((newval & 0xf0000000) == 0xe0000000)
b99bd4ef 27339 {
c19d1205
ZW
27340 /* Doubleword load/store: 8-bit offset, scaled by 4. */
27341 if (value >= 0)
27342 newval |= (1 << 23);
27343 else
27344 value = -value;
27345 if (value % 4 != 0)
27346 {
27347 as_bad_where (fixP->fx_file, fixP->fx_line,
27348 _("offset not a multiple of 4"));
27349 break;
27350 }
27351 value /= 4;
216d22bc 27352 if (value > 0xff)
c19d1205
ZW
27353 {
27354 as_bad_where (fixP->fx_file, fixP->fx_line,
27355 _("offset out of range"));
27356 break;
27357 }
27358 newval &= ~0xff;
b99bd4ef 27359 }
c19d1205 27360 else if ((newval & 0x000f0000) == 0x000f0000)
b99bd4ef 27361 {
c19d1205
ZW
27362 /* PC-relative, 12-bit offset. */
27363 if (value >= 0)
27364 newval |= (1 << 23);
27365 else
27366 value = -value;
216d22bc 27367 if (value > 0xfff)
c19d1205
ZW
27368 {
27369 as_bad_where (fixP->fx_file, fixP->fx_line,
27370 _("offset out of range"));
27371 break;
27372 }
27373 newval &= ~0xfff;
b99bd4ef 27374 }
c19d1205 27375 else if ((newval & 0x00000100) == 0x00000100)
b99bd4ef 27376 {
c19d1205
ZW
27377 /* Writeback: 8-bit, +/- offset. */
27378 if (value >= 0)
27379 newval |= (1 << 9);
27380 else
27381 value = -value;
216d22bc 27382 if (value > 0xff)
c19d1205
ZW
27383 {
27384 as_bad_where (fixP->fx_file, fixP->fx_line,
27385 _("offset out of range"));
27386 break;
27387 }
27388 newval &= ~0xff;
b99bd4ef 27389 }
c19d1205 27390 else if ((newval & 0x00000f00) == 0x00000e00)
b99bd4ef 27391 {
c19d1205 27392 /* T-instruction: positive 8-bit offset. */
216d22bc 27393 if (value < 0 || value > 0xff)
b99bd4ef 27394 {
c19d1205
ZW
27395 as_bad_where (fixP->fx_file, fixP->fx_line,
27396 _("offset out of range"));
27397 break;
b99bd4ef 27398 }
c19d1205
ZW
27399 newval &= ~0xff;
27400 newval |= value;
b99bd4ef
NC
27401 }
27402 else
b99bd4ef 27403 {
c19d1205
ZW
27404 /* Positive 12-bit or negative 8-bit offset. */
27405 int limit;
27406 if (value >= 0)
b99bd4ef 27407 {
c19d1205
ZW
27408 newval |= (1 << 23);
27409 limit = 0xfff;
27410 }
27411 else
27412 {
27413 value = -value;
27414 limit = 0xff;
27415 }
27416 if (value > limit)
27417 {
27418 as_bad_where (fixP->fx_file, fixP->fx_line,
27419 _("offset out of range"));
27420 break;
b99bd4ef 27421 }
c19d1205 27422 newval &= ~limit;
b99bd4ef 27423 }
b99bd4ef 27424
c19d1205
ZW
27425 newval |= value;
27426 md_number_to_chars (buf, (newval >> 16) & 0xffff, THUMB_SIZE);
27427 md_number_to_chars (buf + THUMB_SIZE, newval & 0xffff, THUMB_SIZE);
27428 break;
404ff6b5 27429
c19d1205
ZW
27430 case BFD_RELOC_ARM_SHIFT_IMM:
27431 newval = md_chars_to_number (buf, INSN_SIZE);
27432 if (((unsigned long) value) > 32
27433 || (value == 32
27434 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
27435 {
27436 as_bad_where (fixP->fx_file, fixP->fx_line,
27437 _("shift expression is too large"));
27438 break;
27439 }
404ff6b5 27440
c19d1205
ZW
27441 if (value == 0)
27442 /* Shifts of zero must be done as lsl. */
27443 newval &= ~0x60;
27444 else if (value == 32)
27445 value = 0;
27446 newval &= 0xfffff07f;
27447 newval |= (value & 0x1f) << 7;
27448 md_number_to_chars (buf, newval, INSN_SIZE);
27449 break;
404ff6b5 27450
c19d1205 27451 case BFD_RELOC_ARM_T32_IMMEDIATE:
16805f35 27452 case BFD_RELOC_ARM_T32_ADD_IMM:
92e90b6e 27453 case BFD_RELOC_ARM_T32_IMM12:
e9f89963 27454 case BFD_RELOC_ARM_T32_ADD_PC12:
c19d1205
ZW
27455 /* We claim that this fixup has been processed here,
27456 even if in fact we generate an error because we do
27457 not have a reloc for it, so tc_gen_reloc will reject it. */
27458 fixP->fx_done = 1;
404ff6b5 27459
c19d1205
ZW
27460 if (fixP->fx_addsy
27461 && ! S_IS_DEFINED (fixP->fx_addsy))
27462 {
27463 as_bad_where (fixP->fx_file, fixP->fx_line,
27464 _("undefined symbol %s used as an immediate value"),
27465 S_GET_NAME (fixP->fx_addsy));
27466 break;
27467 }
404ff6b5 27468
c19d1205
ZW
27469 newval = md_chars_to_number (buf, THUMB_SIZE);
27470 newval <<= 16;
27471 newval |= md_chars_to_number (buf+2, THUMB_SIZE);
404ff6b5 27472
16805f35 27473 newimm = FAIL;
bada4342
JW
27474 if ((fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
27475 /* ARMv8-M Baseline MOV will reach here, but it doesn't support
27476 Thumb2 modified immediate encoding (T2). */
27477 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
16805f35 27478 || fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
ef8d22e6
PB
27479 {
27480 newimm = encode_thumb32_immediate (value);
27481 if (newimm == (unsigned int) FAIL)
27482 newimm = thumb32_negate_data_op (&newval, value);
27483 }
bada4342 27484 if (newimm == (unsigned int) FAIL)
92e90b6e 27485 {
bada4342 27486 if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE)
e9f89963 27487 {
bada4342
JW
27488 /* Turn add/sum into addw/subw. */
27489 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
27490 newval = (newval & 0xfeffffff) | 0x02000000;
27491 /* No flat 12-bit imm encoding for addsw/subsw. */
27492 if ((newval & 0x00100000) == 0)
40f246e3 27493 {
bada4342
JW
27494 /* 12 bit immediate for addw/subw. */
27495 if (value < 0)
27496 {
27497 value = -value;
27498 newval ^= 0x00a00000;
27499 }
27500 if (value > 0xfff)
27501 newimm = (unsigned int) FAIL;
27502 else
27503 newimm = value;
27504 }
27505 }
27506 else
27507 {
27508 /* MOV accepts both Thumb2 modified immediate (T2 encoding) and
27509 UINT16 (T3 encoding), MOVW only accepts UINT16. When
27510 disassembling, MOV is preferred when there is no encoding
db7bf105 27511 overlap. */
bada4342 27512 if (((newval >> T2_DATA_OP_SHIFT) & 0xf) == T2_OPCODE_ORR
db7bf105
NC
27513 /* NOTE: MOV uses the ORR opcode in Thumb 2 mode
27514 but with the Rn field [19:16] set to 1111. */
27515 && (((newval >> 16) & 0xf) == 0xf)
bada4342
JW
27516 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m)
27517 && !((newval >> T2_SBIT_SHIFT) & 0x1)
db7bf105 27518 && value >= 0 && value <= 0xffff)
bada4342
JW
27519 {
27520 /* Toggle bit[25] to change encoding from T2 to T3. */
27521 newval ^= 1 << 25;
27522 /* Clear bits[19:16]. */
27523 newval &= 0xfff0ffff;
27524 /* Encoding high 4bits imm. Code below will encode the
27525 remaining low 12bits. */
27526 newval |= (value & 0x0000f000) << 4;
27527 newimm = value & 0x00000fff;
40f246e3 27528 }
e9f89963 27529 }
92e90b6e 27530 }
cc8a6dd0 27531
c19d1205 27532 if (newimm == (unsigned int)FAIL)
3631a3c8 27533 {
c19d1205
ZW
27534 as_bad_where (fixP->fx_file, fixP->fx_line,
27535 _("invalid constant (%lx) after fixup"),
27536 (unsigned long) value);
27537 break;
3631a3c8
NC
27538 }
27539
c19d1205
ZW
27540 newval |= (newimm & 0x800) << 15;
27541 newval |= (newimm & 0x700) << 4;
27542 newval |= (newimm & 0x0ff);
cc8a6dd0 27543
c19d1205
ZW
27544 md_number_to_chars (buf, (valueT) ((newval >> 16) & 0xffff), THUMB_SIZE);
27545 md_number_to_chars (buf+2, (valueT) (newval & 0xffff), THUMB_SIZE);
27546 break;
a737bd4d 27547
3eb17e6b 27548 case BFD_RELOC_ARM_SMC:
c19d1205
ZW
27549 if (((unsigned long) value) > 0xffff)
27550 as_bad_where (fixP->fx_file, fixP->fx_line,
3eb17e6b 27551 _("invalid smc expression"));
2fc8bdac 27552 newval = md_chars_to_number (buf, INSN_SIZE);
c19d1205
ZW
27553 newval |= (value & 0xf) | ((value & 0xfff0) << 4);
27554 md_number_to_chars (buf, newval, INSN_SIZE);
27555 break;
a737bd4d 27556
90ec0d68
MGD
27557 case BFD_RELOC_ARM_HVC:
27558 if (((unsigned long) value) > 0xffff)
27559 as_bad_where (fixP->fx_file, fixP->fx_line,
27560 _("invalid hvc expression"));
27561 newval = md_chars_to_number (buf, INSN_SIZE);
27562 newval |= (value & 0xf) | ((value & 0xfff0) << 4);
27563 md_number_to_chars (buf, newval, INSN_SIZE);
27564 break;
27565
c19d1205 27566 case BFD_RELOC_ARM_SWI:
adbaf948 27567 if (fixP->tc_fix_data != 0)
c19d1205
ZW
27568 {
27569 if (((unsigned long) value) > 0xff)
27570 as_bad_where (fixP->fx_file, fixP->fx_line,
27571 _("invalid swi expression"));
2fc8bdac 27572 newval = md_chars_to_number (buf, THUMB_SIZE);
c19d1205
ZW
27573 newval |= value;
27574 md_number_to_chars (buf, newval, THUMB_SIZE);
27575 }
27576 else
27577 {
27578 if (((unsigned long) value) > 0x00ffffff)
27579 as_bad_where (fixP->fx_file, fixP->fx_line,
27580 _("invalid swi expression"));
2fc8bdac 27581 newval = md_chars_to_number (buf, INSN_SIZE);
c19d1205
ZW
27582 newval |= value;
27583 md_number_to_chars (buf, newval, INSN_SIZE);
27584 }
27585 break;
a737bd4d 27586
c19d1205
ZW
27587 case BFD_RELOC_ARM_MULTI:
27588 if (((unsigned long) value) > 0xffff)
27589 as_bad_where (fixP->fx_file, fixP->fx_line,
27590 _("invalid expression in load/store multiple"));
27591 newval = value | md_chars_to_number (buf, INSN_SIZE);
27592 md_number_to_chars (buf, newval, INSN_SIZE);
27593 break;
a737bd4d 27594
c19d1205 27595#ifdef OBJ_ELF
39b41c9c 27596 case BFD_RELOC_ARM_PCREL_CALL:
267bf995
RR
27597
27598 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
27599 && fixP->fx_addsy
34e77a92 27600 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
27601 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
27602 && THUMB_IS_FUNC (fixP->fx_addsy))
27603 /* Flip the bl to blx. This is a simple flip
27604 bit here because we generate PCREL_CALL for
27605 unconditional bls. */
27606 {
27607 newval = md_chars_to_number (buf, INSN_SIZE);
27608 newval = newval | 0x10000000;
27609 md_number_to_chars (buf, newval, INSN_SIZE);
27610 temp = 1;
27611 fixP->fx_done = 1;
27612 }
39b41c9c
PB
27613 else
27614 temp = 3;
27615 goto arm_branch_common;
27616
27617 case BFD_RELOC_ARM_PCREL_JUMP:
267bf995
RR
27618 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
27619 && fixP->fx_addsy
34e77a92 27620 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
27621 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
27622 && THUMB_IS_FUNC (fixP->fx_addsy))
27623 {
27624 /* This would map to a bl<cond>, b<cond>,
27625 b<always> to a Thumb function. We
27626 need to force a relocation for this particular
27627 case. */
27628 newval = md_chars_to_number (buf, INSN_SIZE);
27629 fixP->fx_done = 0;
27630 }
1a0670f3 27631 /* Fall through. */
267bf995 27632
2fc8bdac 27633 case BFD_RELOC_ARM_PLT32:
c19d1205 27634#endif
39b41c9c
PB
27635 case BFD_RELOC_ARM_PCREL_BRANCH:
27636 temp = 3;
27637 goto arm_branch_common;
a737bd4d 27638
39b41c9c 27639 case BFD_RELOC_ARM_PCREL_BLX:
267bf995 27640
39b41c9c 27641 temp = 1;
267bf995
RR
27642 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
27643 && fixP->fx_addsy
34e77a92 27644 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
27645 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
27646 && ARM_IS_FUNC (fixP->fx_addsy))
27647 {
27648 /* Flip the blx to a bl and warn. */
27649 const char *name = S_GET_NAME (fixP->fx_addsy);
27650 newval = 0xeb000000;
27651 as_warn_where (fixP->fx_file, fixP->fx_line,
27652 _("blx to '%s' an ARM ISA state function changed to bl"),
27653 name);
27654 md_number_to_chars (buf, newval, INSN_SIZE);
27655 temp = 3;
27656 fixP->fx_done = 1;
27657 }
27658
27659#ifdef OBJ_ELF
27660 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
477330fc 27661 fixP->fx_r_type = BFD_RELOC_ARM_PCREL_CALL;
267bf995
RR
27662#endif
27663
39b41c9c 27664 arm_branch_common:
c19d1205 27665 /* We are going to store value (shifted right by two) in the
39b41c9c
PB
27666 instruction, in a 24 bit, signed field. Bits 26 through 32 either
27667 all clear or all set and bit 0 must be clear. For B/BL bit 1 must
de194d85 27668 also be clear. */
39b41c9c 27669 if (value & temp)
c19d1205 27670 as_bad_where (fixP->fx_file, fixP->fx_line,
2fc8bdac
ZW
27671 _("misaligned branch destination"));
27672 if ((value & (offsetT)0xfe000000) != (offsetT)0
27673 && (value & (offsetT)0xfe000000) != (offsetT)0xfe000000)
08f10d51 27674 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 27675
2fc8bdac 27676 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 27677 {
2fc8bdac
ZW
27678 newval = md_chars_to_number (buf, INSN_SIZE);
27679 newval |= (value >> 2) & 0x00ffffff;
7ae2971b
PB
27680 /* Set the H bit on BLX instructions. */
27681 if (temp == 1)
27682 {
27683 if (value & 2)
27684 newval |= 0x01000000;
27685 else
27686 newval &= ~0x01000000;
27687 }
2fc8bdac 27688 md_number_to_chars (buf, newval, INSN_SIZE);
c19d1205 27689 }
c19d1205 27690 break;
a737bd4d 27691
25fe350b
MS
27692 case BFD_RELOC_THUMB_PCREL_BRANCH7: /* CBZ */
27693 /* CBZ can only branch forward. */
a737bd4d 27694
738755b0 27695 /* Attempts to use CBZ to branch to the next instruction
477330fc
RM
27696 (which, strictly speaking, are prohibited) will be turned into
27697 no-ops.
738755b0
MS
27698
27699 FIXME: It may be better to remove the instruction completely and
27700 perform relaxation. */
27701 if (value == -2)
2fc8bdac
ZW
27702 {
27703 newval = md_chars_to_number (buf, THUMB_SIZE);
738755b0 27704 newval = 0xbf00; /* NOP encoding T1 */
2fc8bdac
ZW
27705 md_number_to_chars (buf, newval, THUMB_SIZE);
27706 }
738755b0
MS
27707 else
27708 {
27709 if (value & ~0x7e)
08f10d51 27710 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
738755b0 27711
477330fc 27712 if (fixP->fx_done || !seg->use_rela_p)
738755b0
MS
27713 {
27714 newval = md_chars_to_number (buf, THUMB_SIZE);
27715 newval |= ((value & 0x3e) << 2) | ((value & 0x40) << 3);
27716 md_number_to_chars (buf, newval, THUMB_SIZE);
27717 }
27718 }
c19d1205 27719 break;
a737bd4d 27720
c19d1205 27721 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
2fc8bdac 27722 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
08f10d51 27723 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 27724
2fc8bdac
ZW
27725 if (fixP->fx_done || !seg->use_rela_p)
27726 {
27727 newval = md_chars_to_number (buf, THUMB_SIZE);
27728 newval |= (value & 0x1ff) >> 1;
27729 md_number_to_chars (buf, newval, THUMB_SIZE);
27730 }
c19d1205 27731 break;
a737bd4d 27732
c19d1205 27733 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
2fc8bdac 27734 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
08f10d51 27735 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 27736
2fc8bdac
ZW
27737 if (fixP->fx_done || !seg->use_rela_p)
27738 {
27739 newval = md_chars_to_number (buf, THUMB_SIZE);
27740 newval |= (value & 0xfff) >> 1;
27741 md_number_to_chars (buf, newval, THUMB_SIZE);
27742 }
c19d1205 27743 break;
a737bd4d 27744
c19d1205 27745 case BFD_RELOC_THUMB_PCREL_BRANCH20:
267bf995
RR
27746 if (fixP->fx_addsy
27747 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 27748 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
27749 && ARM_IS_FUNC (fixP->fx_addsy)
27750 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
27751 {
27752 /* Force a relocation for a branch 20 bits wide. */
27753 fixP->fx_done = 0;
27754 }
08f10d51 27755 if ((value & ~0x1fffff) && ((value & ~0x0fffff) != ~0x0fffff))
2fc8bdac
ZW
27756 as_bad_where (fixP->fx_file, fixP->fx_line,
27757 _("conditional branch out of range"));
404ff6b5 27758
2fc8bdac
ZW
27759 if (fixP->fx_done || !seg->use_rela_p)
27760 {
27761 offsetT newval2;
27762 addressT S, J1, J2, lo, hi;
404ff6b5 27763
2fc8bdac
ZW
27764 S = (value & 0x00100000) >> 20;
27765 J2 = (value & 0x00080000) >> 19;
27766 J1 = (value & 0x00040000) >> 18;
27767 hi = (value & 0x0003f000) >> 12;
27768 lo = (value & 0x00000ffe) >> 1;
6c43fab6 27769
2fc8bdac
ZW
27770 newval = md_chars_to_number (buf, THUMB_SIZE);
27771 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
27772 newval |= (S << 10) | hi;
27773 newval2 |= (J1 << 13) | (J2 << 11) | lo;
27774 md_number_to_chars (buf, newval, THUMB_SIZE);
27775 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
27776 }
c19d1205 27777 break;
6c43fab6 27778
c19d1205 27779 case BFD_RELOC_THUMB_PCREL_BLX:
267bf995
RR
27780 /* If there is a blx from a thumb state function to
27781 another thumb function flip this to a bl and warn
27782 about it. */
27783
27784 if (fixP->fx_addsy
34e77a92 27785 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
27786 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
27787 && THUMB_IS_FUNC (fixP->fx_addsy))
27788 {
27789 const char *name = S_GET_NAME (fixP->fx_addsy);
27790 as_warn_where (fixP->fx_file, fixP->fx_line,
27791 _("blx to Thumb func '%s' from Thumb ISA state changed to bl"),
27792 name);
27793 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
27794 newval = newval | 0x1000;
27795 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
27796 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
27797 fixP->fx_done = 1;
27798 }
27799
27800
27801 goto thumb_bl_common;
27802
c19d1205 27803 case BFD_RELOC_THUMB_PCREL_BRANCH23:
267bf995
RR
27804 /* A bl from Thumb state ISA to an internal ARM state function
27805 is converted to a blx. */
27806 if (fixP->fx_addsy
27807 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 27808 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
27809 && ARM_IS_FUNC (fixP->fx_addsy)
27810 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
27811 {
27812 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
27813 newval = newval & ~0x1000;
27814 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
27815 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BLX;
27816 fixP->fx_done = 1;
27817 }
27818
27819 thumb_bl_common:
27820
2fc8bdac
ZW
27821 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
27822 /* For a BLX instruction, make sure that the relocation is rounded up
27823 to a word boundary. This follows the semantics of the instruction
27824 which specifies that bit 1 of the target address will come from bit
27825 1 of the base address. */
d406f3e4
JB
27826 value = (value + 3) & ~ 3;
27827
27828#ifdef OBJ_ELF
27829 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4
27830 && fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
27831 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
27832#endif
404ff6b5 27833
2b2f5df9
NC
27834 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
27835 {
fc289b0a 27836 if (!(ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)))
2b2f5df9
NC
27837 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
27838 else if ((value & ~0x1ffffff)
27839 && ((value & ~0x1ffffff) != ~0x1ffffff))
27840 as_bad_where (fixP->fx_file, fixP->fx_line,
27841 _("Thumb2 branch out of range"));
27842 }
4a42ebbc
RR
27843
27844 if (fixP->fx_done || !seg->use_rela_p)
27845 encode_thumb2_b_bl_offset (buf, value);
27846
c19d1205 27847 break;
404ff6b5 27848
c19d1205 27849 case BFD_RELOC_THUMB_PCREL_BRANCH25:
08f10d51
NC
27850 if ((value & ~0x0ffffff) && ((value & ~0x0ffffff) != ~0x0ffffff))
27851 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
6c43fab6 27852
2fc8bdac 27853 if (fixP->fx_done || !seg->use_rela_p)
4a42ebbc 27854 encode_thumb2_b_bl_offset (buf, value);
6c43fab6 27855
2fc8bdac 27856 break;
a737bd4d 27857
2fc8bdac
ZW
27858 case BFD_RELOC_8:
27859 if (fixP->fx_done || !seg->use_rela_p)
4b1a927e 27860 *buf = value;
c19d1205 27861 break;
a737bd4d 27862
c19d1205 27863 case BFD_RELOC_16:
2fc8bdac 27864 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 27865 md_number_to_chars (buf, value, 2);
c19d1205 27866 break;
a737bd4d 27867
c19d1205 27868#ifdef OBJ_ELF
0855e32b
NS
27869 case BFD_RELOC_ARM_TLS_CALL:
27870 case BFD_RELOC_ARM_THM_TLS_CALL:
27871 case BFD_RELOC_ARM_TLS_DESCSEQ:
27872 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
0855e32b 27873 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205
ZW
27874 case BFD_RELOC_ARM_TLS_GD32:
27875 case BFD_RELOC_ARM_TLS_LE32:
27876 case BFD_RELOC_ARM_TLS_IE32:
27877 case BFD_RELOC_ARM_TLS_LDM32:
27878 case BFD_RELOC_ARM_TLS_LDO32:
27879 S_SET_THREAD_LOCAL (fixP->fx_addsy);
4b1a927e 27880 break;
6c43fab6 27881
5c5a4843
CL
27882 /* Same handling as above, but with the arm_fdpic guard. */
27883 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
27884 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
27885 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
27886 if (arm_fdpic)
27887 {
27888 S_SET_THREAD_LOCAL (fixP->fx_addsy);
27889 }
27890 else
27891 {
27892 as_bad_where (fixP->fx_file, fixP->fx_line,
27893 _("Relocation supported only in FDPIC mode"));
27894 }
27895 break;
27896
c19d1205
ZW
27897 case BFD_RELOC_ARM_GOT32:
27898 case BFD_RELOC_ARM_GOTOFF:
c19d1205 27899 break;
b43420e6
NC
27900
27901 case BFD_RELOC_ARM_GOT_PREL:
27902 if (fixP->fx_done || !seg->use_rela_p)
477330fc 27903 md_number_to_chars (buf, value, 4);
b43420e6
NC
27904 break;
27905
9a6f4e97
NS
27906 case BFD_RELOC_ARM_TARGET2:
27907 /* TARGET2 is not partial-inplace, so we need to write the
477330fc
RM
27908 addend here for REL targets, because it won't be written out
27909 during reloc processing later. */
9a6f4e97
NS
27910 if (fixP->fx_done || !seg->use_rela_p)
27911 md_number_to_chars (buf, fixP->fx_offset, 4);
27912 break;
188fd7ae
CL
27913
27914 /* Relocations for FDPIC. */
27915 case BFD_RELOC_ARM_GOTFUNCDESC:
27916 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
27917 case BFD_RELOC_ARM_FUNCDESC:
27918 if (arm_fdpic)
27919 {
27920 if (fixP->fx_done || !seg->use_rela_p)
27921 md_number_to_chars (buf, 0, 4);
27922 }
27923 else
27924 {
27925 as_bad_where (fixP->fx_file, fixP->fx_line,
27926 _("Relocation supported only in FDPIC mode"));
27927 }
27928 break;
c19d1205 27929#endif
6c43fab6 27930
c19d1205
ZW
27931 case BFD_RELOC_RVA:
27932 case BFD_RELOC_32:
27933 case BFD_RELOC_ARM_TARGET1:
27934 case BFD_RELOC_ARM_ROSEGREL32:
27935 case BFD_RELOC_ARM_SBREL32:
27936 case BFD_RELOC_32_PCREL:
f0927246
NC
27937#ifdef TE_PE
27938 case BFD_RELOC_32_SECREL:
27939#endif
2fc8bdac 27940 if (fixP->fx_done || !seg->use_rela_p)
53baae48
NC
27941#ifdef TE_WINCE
27942 /* For WinCE we only do this for pcrel fixups. */
27943 if (fixP->fx_done || fixP->fx_pcrel)
27944#endif
27945 md_number_to_chars (buf, value, 4);
c19d1205 27946 break;
6c43fab6 27947
c19d1205
ZW
27948#ifdef OBJ_ELF
27949 case BFD_RELOC_ARM_PREL31:
2fc8bdac 27950 if (fixP->fx_done || !seg->use_rela_p)
c19d1205
ZW
27951 {
27952 newval = md_chars_to_number (buf, 4) & 0x80000000;
27953 if ((value ^ (value >> 1)) & 0x40000000)
27954 {
27955 as_bad_where (fixP->fx_file, fixP->fx_line,
27956 _("rel31 relocation overflow"));
27957 }
27958 newval |= value & 0x7fffffff;
27959 md_number_to_chars (buf, newval, 4);
27960 }
27961 break;
c19d1205 27962#endif
a737bd4d 27963
c19d1205 27964 case BFD_RELOC_ARM_CP_OFF_IMM:
8f06b2d8 27965 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
32c36c3c 27966 case BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM:
9db2f6b4
RL
27967 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM)
27968 newval = md_chars_to_number (buf, INSN_SIZE);
27969 else
27970 newval = get_thumb32_insn (buf);
27971 if ((newval & 0x0f200f00) == 0x0d000900)
27972 {
27973 /* This is a fp16 vstr/vldr. The immediate offset in the mnemonic
27974 has permitted values that are multiples of 2, in the range 0
27975 to 510. */
27976 if (value < -510 || value > 510 || (value & 1))
27977 as_bad_where (fixP->fx_file, fixP->fx_line,
27978 _("co-processor offset out of range"));
27979 }
32c36c3c
AV
27980 else if ((newval & 0xfe001f80) == 0xec000f80)
27981 {
27982 if (value < -511 || value > 512 || (value & 3))
27983 as_bad_where (fixP->fx_file, fixP->fx_line,
27984 _("co-processor offset out of range"));
27985 }
9db2f6b4 27986 else if (value < -1023 || value > 1023 || (value & 3))
c19d1205
ZW
27987 as_bad_where (fixP->fx_file, fixP->fx_line,
27988 _("co-processor offset out of range"));
27989 cp_off_common:
26d97720 27990 sign = value > 0;
c19d1205
ZW
27991 if (value < 0)
27992 value = -value;
8f06b2d8
PB
27993 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
27994 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
27995 newval = md_chars_to_number (buf, INSN_SIZE);
27996 else
27997 newval = get_thumb32_insn (buf);
26d97720 27998 if (value == 0)
32c36c3c
AV
27999 {
28000 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM)
28001 newval &= 0xffffff80;
28002 else
28003 newval &= 0xffffff00;
28004 }
26d97720
NS
28005 else
28006 {
32c36c3c
AV
28007 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM)
28008 newval &= 0xff7fff80;
28009 else
28010 newval &= 0xff7fff00;
9db2f6b4
RL
28011 if ((newval & 0x0f200f00) == 0x0d000900)
28012 {
28013 /* This is a fp16 vstr/vldr.
28014
28015 It requires the immediate offset in the instruction is shifted
28016 left by 1 to be a half-word offset.
28017
28018 Here, left shift by 1 first, and later right shift by 2
28019 should get the right offset. */
28020 value <<= 1;
28021 }
26d97720
NS
28022 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
28023 }
8f06b2d8
PB
28024 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
28025 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
28026 md_number_to_chars (buf, newval, INSN_SIZE);
28027 else
28028 put_thumb32_insn (buf, newval);
c19d1205 28029 break;
a737bd4d 28030
c19d1205 28031 case BFD_RELOC_ARM_CP_OFF_IMM_S2:
8f06b2d8 28032 case BFD_RELOC_ARM_T32_CP_OFF_IMM_S2:
c19d1205
ZW
28033 if (value < -255 || value > 255)
28034 as_bad_where (fixP->fx_file, fixP->fx_line,
28035 _("co-processor offset out of range"));
df7849c5 28036 value *= 4;
c19d1205 28037 goto cp_off_common;
6c43fab6 28038
c19d1205
ZW
28039 case BFD_RELOC_ARM_THUMB_OFFSET:
28040 newval = md_chars_to_number (buf, THUMB_SIZE);
28041 /* Exactly what ranges, and where the offset is inserted depends
28042 on the type of instruction, we can establish this from the
28043 top 4 bits. */
28044 switch (newval >> 12)
28045 {
28046 case 4: /* PC load. */
28047 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
28048 forced to zero for these loads; md_pcrel_from has already
28049 compensated for this. */
28050 if (value & 3)
28051 as_bad_where (fixP->fx_file, fixP->fx_line,
28052 _("invalid offset, target not word aligned (0x%08lX)"),
0359e808
NC
28053 (((unsigned long) fixP->fx_frag->fr_address
28054 + (unsigned long) fixP->fx_where) & ~3)
28055 + (unsigned long) value);
a737bd4d 28056
c19d1205
ZW
28057 if (value & ~0x3fc)
28058 as_bad_where (fixP->fx_file, fixP->fx_line,
28059 _("invalid offset, value too big (0x%08lX)"),
28060 (long) value);
a737bd4d 28061
c19d1205
ZW
28062 newval |= value >> 2;
28063 break;
a737bd4d 28064
c19d1205
ZW
28065 case 9: /* SP load/store. */
28066 if (value & ~0x3fc)
28067 as_bad_where (fixP->fx_file, fixP->fx_line,
28068 _("invalid offset, value too big (0x%08lX)"),
28069 (long) value);
28070 newval |= value >> 2;
28071 break;
6c43fab6 28072
c19d1205
ZW
28073 case 6: /* Word load/store. */
28074 if (value & ~0x7c)
28075 as_bad_where (fixP->fx_file, fixP->fx_line,
28076 _("invalid offset, value too big (0x%08lX)"),
28077 (long) value);
28078 newval |= value << 4; /* 6 - 2. */
28079 break;
a737bd4d 28080
c19d1205
ZW
28081 case 7: /* Byte load/store. */
28082 if (value & ~0x1f)
28083 as_bad_where (fixP->fx_file, fixP->fx_line,
28084 _("invalid offset, value too big (0x%08lX)"),
28085 (long) value);
28086 newval |= value << 6;
28087 break;
a737bd4d 28088
c19d1205
ZW
28089 case 8: /* Halfword load/store. */
28090 if (value & ~0x3e)
28091 as_bad_where (fixP->fx_file, fixP->fx_line,
28092 _("invalid offset, value too big (0x%08lX)"),
28093 (long) value);
28094 newval |= value << 5; /* 6 - 1. */
28095 break;
a737bd4d 28096
c19d1205
ZW
28097 default:
28098 as_bad_where (fixP->fx_file, fixP->fx_line,
28099 "Unable to process relocation for thumb opcode: %lx",
28100 (unsigned long) newval);
28101 break;
28102 }
28103 md_number_to_chars (buf, newval, THUMB_SIZE);
28104 break;
a737bd4d 28105
c19d1205
ZW
28106 case BFD_RELOC_ARM_THUMB_ADD:
28107 /* This is a complicated relocation, since we use it for all of
28108 the following immediate relocations:
a737bd4d 28109
c19d1205
ZW
28110 3bit ADD/SUB
28111 8bit ADD/SUB
28112 9bit ADD/SUB SP word-aligned
28113 10bit ADD PC/SP word-aligned
a737bd4d 28114
c19d1205
ZW
28115 The type of instruction being processed is encoded in the
28116 instruction field:
a737bd4d 28117
c19d1205
ZW
28118 0x8000 SUB
28119 0x00F0 Rd
28120 0x000F Rs
28121 */
28122 newval = md_chars_to_number (buf, THUMB_SIZE);
28123 {
28124 int rd = (newval >> 4) & 0xf;
28125 int rs = newval & 0xf;
28126 int subtract = !!(newval & 0x8000);
a737bd4d 28127
c19d1205
ZW
28128 /* Check for HI regs, only very restricted cases allowed:
28129 Adjusting SP, and using PC or SP to get an address. */
28130 if ((rd > 7 && (rd != REG_SP || rs != REG_SP))
28131 || (rs > 7 && rs != REG_SP && rs != REG_PC))
28132 as_bad_where (fixP->fx_file, fixP->fx_line,
28133 _("invalid Hi register with immediate"));
a737bd4d 28134
c19d1205
ZW
28135 /* If value is negative, choose the opposite instruction. */
28136 if (value < 0)
28137 {
28138 value = -value;
28139 subtract = !subtract;
28140 if (value < 0)
28141 as_bad_where (fixP->fx_file, fixP->fx_line,
28142 _("immediate value out of range"));
28143 }
a737bd4d 28144
c19d1205
ZW
28145 if (rd == REG_SP)
28146 {
75c11999 28147 if (value & ~0x1fc)
c19d1205
ZW
28148 as_bad_where (fixP->fx_file, fixP->fx_line,
28149 _("invalid immediate for stack address calculation"));
28150 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
28151 newval |= value >> 2;
28152 }
28153 else if (rs == REG_PC || rs == REG_SP)
28154 {
c12d2c9d
NC
28155 /* PR gas/18541. If the addition is for a defined symbol
28156 within range of an ADR instruction then accept it. */
28157 if (subtract
28158 && value == 4
28159 && fixP->fx_addsy != NULL)
28160 {
28161 subtract = 0;
28162
28163 if (! S_IS_DEFINED (fixP->fx_addsy)
28164 || S_GET_SEGMENT (fixP->fx_addsy) != seg
28165 || S_IS_WEAK (fixP->fx_addsy))
28166 {
28167 as_bad_where (fixP->fx_file, fixP->fx_line,
28168 _("address calculation needs a strongly defined nearby symbol"));
28169 }
28170 else
28171 {
28172 offsetT v = fixP->fx_where + fixP->fx_frag->fr_address;
28173
28174 /* Round up to the next 4-byte boundary. */
28175 if (v & 3)
28176 v = (v + 3) & ~ 3;
28177 else
28178 v += 4;
28179 v = S_GET_VALUE (fixP->fx_addsy) - v;
28180
28181 if (v & ~0x3fc)
28182 {
28183 as_bad_where (fixP->fx_file, fixP->fx_line,
28184 _("symbol too far away"));
28185 }
28186 else
28187 {
28188 fixP->fx_done = 1;
28189 value = v;
28190 }
28191 }
28192 }
28193
c19d1205
ZW
28194 if (subtract || value & ~0x3fc)
28195 as_bad_where (fixP->fx_file, fixP->fx_line,
28196 _("invalid immediate for address calculation (value = 0x%08lX)"),
5fc177c8 28197 (unsigned long) (subtract ? - value : value));
c19d1205
ZW
28198 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
28199 newval |= rd << 8;
28200 newval |= value >> 2;
28201 }
28202 else if (rs == rd)
28203 {
28204 if (value & ~0xff)
28205 as_bad_where (fixP->fx_file, fixP->fx_line,
28206 _("immediate value out of range"));
28207 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
28208 newval |= (rd << 8) | value;
28209 }
28210 else
28211 {
28212 if (value & ~0x7)
28213 as_bad_where (fixP->fx_file, fixP->fx_line,
28214 _("immediate value out of range"));
28215 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
28216 newval |= rd | (rs << 3) | (value << 6);
28217 }
28218 }
28219 md_number_to_chars (buf, newval, THUMB_SIZE);
28220 break;
a737bd4d 28221
c19d1205
ZW
28222 case BFD_RELOC_ARM_THUMB_IMM:
28223 newval = md_chars_to_number (buf, THUMB_SIZE);
28224 if (value < 0 || value > 255)
28225 as_bad_where (fixP->fx_file, fixP->fx_line,
4e6e072b 28226 _("invalid immediate: %ld is out of range"),
c19d1205
ZW
28227 (long) value);
28228 newval |= value;
28229 md_number_to_chars (buf, newval, THUMB_SIZE);
28230 break;
a737bd4d 28231
c19d1205
ZW
28232 case BFD_RELOC_ARM_THUMB_SHIFT:
28233 /* 5bit shift value (0..32). LSL cannot take 32. */
28234 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf83f;
28235 temp = newval & 0xf800;
28236 if (value < 0 || value > 32 || (value == 32 && temp == T_OPCODE_LSL_I))
28237 as_bad_where (fixP->fx_file, fixP->fx_line,
28238 _("invalid shift value: %ld"), (long) value);
28239 /* Shifts of zero must be encoded as LSL. */
28240 if (value == 0)
28241 newval = (newval & 0x003f) | T_OPCODE_LSL_I;
28242 /* Shifts of 32 are encoded as zero. */
28243 else if (value == 32)
28244 value = 0;
28245 newval |= value << 6;
28246 md_number_to_chars (buf, newval, THUMB_SIZE);
28247 break;
a737bd4d 28248
c19d1205
ZW
28249 case BFD_RELOC_VTABLE_INHERIT:
28250 case BFD_RELOC_VTABLE_ENTRY:
28251 fixP->fx_done = 0;
28252 return;
6c43fab6 28253
b6895b4f
PB
28254 case BFD_RELOC_ARM_MOVW:
28255 case BFD_RELOC_ARM_MOVT:
28256 case BFD_RELOC_ARM_THUMB_MOVW:
28257 case BFD_RELOC_ARM_THUMB_MOVT:
28258 if (fixP->fx_done || !seg->use_rela_p)
28259 {
28260 /* REL format relocations are limited to a 16-bit addend. */
28261 if (!fixP->fx_done)
28262 {
39623e12 28263 if (value < -0x8000 || value > 0x7fff)
b6895b4f 28264 as_bad_where (fixP->fx_file, fixP->fx_line,
ff5075ca 28265 _("offset out of range"));
b6895b4f
PB
28266 }
28267 else if (fixP->fx_r_type == BFD_RELOC_ARM_MOVT
28268 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
28269 {
28270 value >>= 16;
28271 }
28272
28273 if (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
28274 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
28275 {
28276 newval = get_thumb32_insn (buf);
28277 newval &= 0xfbf08f00;
28278 newval |= (value & 0xf000) << 4;
28279 newval |= (value & 0x0800) << 15;
28280 newval |= (value & 0x0700) << 4;
28281 newval |= (value & 0x00ff);
28282 put_thumb32_insn (buf, newval);
28283 }
28284 else
28285 {
28286 newval = md_chars_to_number (buf, 4);
28287 newval &= 0xfff0f000;
28288 newval |= value & 0x0fff;
28289 newval |= (value & 0xf000) << 4;
28290 md_number_to_chars (buf, newval, 4);
28291 }
28292 }
28293 return;
28294
72d98d16
MG
28295 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
28296 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
28297 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
28298 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
28299 gas_assert (!fixP->fx_done);
28300 {
28301 bfd_vma insn;
28302 bfd_boolean is_mov;
28303 bfd_vma encoded_addend = value;
28304
28305 /* Check that addend can be encoded in instruction. */
28306 if (!seg->use_rela_p && (value < 0 || value > 255))
28307 as_bad_where (fixP->fx_file, fixP->fx_line,
28308 _("the offset 0x%08lX is not representable"),
28309 (unsigned long) encoded_addend);
28310
28311 /* Extract the instruction. */
28312 insn = md_chars_to_number (buf, THUMB_SIZE);
28313 is_mov = (insn & 0xf800) == 0x2000;
28314
28315 /* Encode insn. */
28316 if (is_mov)
28317 {
28318 if (!seg->use_rela_p)
28319 insn |= encoded_addend;
28320 }
28321 else
28322 {
28323 int rd, rs;
28324
28325 /* Extract the instruction. */
28326 /* Encoding is the following
28327 0x8000 SUB
28328 0x00F0 Rd
28329 0x000F Rs
28330 */
28331 /* The following conditions must be true :
28332 - ADD
28333 - Rd == Rs
28334 - Rd <= 7
28335 */
28336 rd = (insn >> 4) & 0xf;
28337 rs = insn & 0xf;
28338 if ((insn & 0x8000) || (rd != rs) || rd > 7)
28339 as_bad_where (fixP->fx_file, fixP->fx_line,
28340 _("Unable to process relocation for thumb opcode: %lx"),
28341 (unsigned long) insn);
28342
28343 /* Encode as ADD immediate8 thumb 1 code. */
28344 insn = 0x3000 | (rd << 8);
28345
28346 /* Place the encoded addend into the first 8 bits of the
28347 instruction. */
28348 if (!seg->use_rela_p)
28349 insn |= encoded_addend;
28350 }
28351
28352 /* Update the instruction. */
28353 md_number_to_chars (buf, insn, THUMB_SIZE);
28354 }
28355 break;
28356
4962c51a
MS
28357 case BFD_RELOC_ARM_ALU_PC_G0_NC:
28358 case BFD_RELOC_ARM_ALU_PC_G0:
28359 case BFD_RELOC_ARM_ALU_PC_G1_NC:
28360 case BFD_RELOC_ARM_ALU_PC_G1:
28361 case BFD_RELOC_ARM_ALU_PC_G2:
28362 case BFD_RELOC_ARM_ALU_SB_G0_NC:
28363 case BFD_RELOC_ARM_ALU_SB_G0:
28364 case BFD_RELOC_ARM_ALU_SB_G1_NC:
28365 case BFD_RELOC_ARM_ALU_SB_G1:
28366 case BFD_RELOC_ARM_ALU_SB_G2:
9c2799c2 28367 gas_assert (!fixP->fx_done);
4962c51a
MS
28368 if (!seg->use_rela_p)
28369 {
477330fc
RM
28370 bfd_vma insn;
28371 bfd_vma encoded_addend;
3ca4a8ec 28372 bfd_vma addend_abs = llabs (value);
477330fc
RM
28373
28374 /* Check that the absolute value of the addend can be
28375 expressed as an 8-bit constant plus a rotation. */
28376 encoded_addend = encode_arm_immediate (addend_abs);
28377 if (encoded_addend == (unsigned int) FAIL)
4962c51a 28378 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
28379 _("the offset 0x%08lX is not representable"),
28380 (unsigned long) addend_abs);
28381
28382 /* Extract the instruction. */
28383 insn = md_chars_to_number (buf, INSN_SIZE);
28384
28385 /* If the addend is positive, use an ADD instruction.
28386 Otherwise use a SUB. Take care not to destroy the S bit. */
28387 insn &= 0xff1fffff;
28388 if (value < 0)
28389 insn |= 1 << 22;
28390 else
28391 insn |= 1 << 23;
28392
28393 /* Place the encoded addend into the first 12 bits of the
28394 instruction. */
28395 insn &= 0xfffff000;
28396 insn |= encoded_addend;
28397
28398 /* Update the instruction. */
28399 md_number_to_chars (buf, insn, INSN_SIZE);
4962c51a
MS
28400 }
28401 break;
28402
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_LDR_SB_G0:
28407 case BFD_RELOC_ARM_LDR_SB_G1:
28408 case BFD_RELOC_ARM_LDR_SB_G2:
9c2799c2 28409 gas_assert (!fixP->fx_done);
4962c51a 28410 if (!seg->use_rela_p)
477330fc
RM
28411 {
28412 bfd_vma insn;
3ca4a8ec 28413 bfd_vma addend_abs = llabs (value);
4962c51a 28414
477330fc
RM
28415 /* Check that the absolute value of the addend can be
28416 encoded in 12 bits. */
28417 if (addend_abs >= 0x1000)
4962c51a 28418 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
28419 _("bad offset 0x%08lX (only 12 bits available for the magnitude)"),
28420 (unsigned long) addend_abs);
28421
28422 /* Extract the instruction. */
28423 insn = md_chars_to_number (buf, INSN_SIZE);
28424
28425 /* If the addend is negative, clear bit 23 of the instruction.
28426 Otherwise set it. */
28427 if (value < 0)
28428 insn &= ~(1 << 23);
28429 else
28430 insn |= 1 << 23;
28431
28432 /* Place the absolute value of the addend into the first 12 bits
28433 of the instruction. */
28434 insn &= 0xfffff000;
28435 insn |= addend_abs;
28436
28437 /* Update the instruction. */
28438 md_number_to_chars (buf, insn, INSN_SIZE);
28439 }
4962c51a
MS
28440 break;
28441
28442 case BFD_RELOC_ARM_LDRS_PC_G0:
28443 case BFD_RELOC_ARM_LDRS_PC_G1:
28444 case BFD_RELOC_ARM_LDRS_PC_G2:
28445 case BFD_RELOC_ARM_LDRS_SB_G0:
28446 case BFD_RELOC_ARM_LDRS_SB_G1:
28447 case BFD_RELOC_ARM_LDRS_SB_G2:
9c2799c2 28448 gas_assert (!fixP->fx_done);
4962c51a 28449 if (!seg->use_rela_p)
477330fc
RM
28450 {
28451 bfd_vma insn;
3ca4a8ec 28452 bfd_vma addend_abs = llabs (value);
4962c51a 28453
477330fc
RM
28454 /* Check that the absolute value of the addend can be
28455 encoded in 8 bits. */
28456 if (addend_abs >= 0x100)
4962c51a 28457 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
28458 _("bad offset 0x%08lX (only 8 bits available for the magnitude)"),
28459 (unsigned long) addend_abs);
28460
28461 /* Extract the instruction. */
28462 insn = md_chars_to_number (buf, INSN_SIZE);
28463
28464 /* If the addend is negative, clear bit 23 of the instruction.
28465 Otherwise set it. */
28466 if (value < 0)
28467 insn &= ~(1 << 23);
28468 else
28469 insn |= 1 << 23;
28470
28471 /* Place the first four bits of the absolute value of the addend
28472 into the first 4 bits of the instruction, and the remaining
28473 four into bits 8 .. 11. */
28474 insn &= 0xfffff0f0;
28475 insn |= (addend_abs & 0xf) | ((addend_abs & 0xf0) << 4);
28476
28477 /* Update the instruction. */
28478 md_number_to_chars (buf, insn, INSN_SIZE);
28479 }
4962c51a
MS
28480 break;
28481
28482 case BFD_RELOC_ARM_LDC_PC_G0:
28483 case BFD_RELOC_ARM_LDC_PC_G1:
28484 case BFD_RELOC_ARM_LDC_PC_G2:
28485 case BFD_RELOC_ARM_LDC_SB_G0:
28486 case BFD_RELOC_ARM_LDC_SB_G1:
28487 case BFD_RELOC_ARM_LDC_SB_G2:
9c2799c2 28488 gas_assert (!fixP->fx_done);
4962c51a 28489 if (!seg->use_rela_p)
477330fc
RM
28490 {
28491 bfd_vma insn;
3ca4a8ec 28492 bfd_vma addend_abs = llabs (value);
4962c51a 28493
477330fc
RM
28494 /* Check that the absolute value of the addend is a multiple of
28495 four and, when divided by four, fits in 8 bits. */
28496 if (addend_abs & 0x3)
4962c51a 28497 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
28498 _("bad offset 0x%08lX (must be word-aligned)"),
28499 (unsigned long) addend_abs);
4962c51a 28500
477330fc 28501 if ((addend_abs >> 2) > 0xff)
4962c51a 28502 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
28503 _("bad offset 0x%08lX (must be an 8-bit number of words)"),
28504 (unsigned long) addend_abs);
28505
28506 /* Extract the instruction. */
28507 insn = md_chars_to_number (buf, INSN_SIZE);
28508
28509 /* If the addend is negative, clear bit 23 of the instruction.
28510 Otherwise set it. */
28511 if (value < 0)
28512 insn &= ~(1 << 23);
28513 else
28514 insn |= 1 << 23;
28515
28516 /* Place the addend (divided by four) into the first eight
28517 bits of the instruction. */
28518 insn &= 0xfffffff0;
28519 insn |= addend_abs >> 2;
28520
28521 /* Update the instruction. */
28522 md_number_to_chars (buf, insn, INSN_SIZE);
28523 }
4962c51a
MS
28524 break;
28525
e12437dc
AV
28526 case BFD_RELOC_THUMB_PCREL_BRANCH5:
28527 if (fixP->fx_addsy
28528 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28529 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
28530 && ARM_IS_FUNC (fixP->fx_addsy)
28531 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
28532 {
28533 /* Force a relocation for a branch 5 bits wide. */
28534 fixP->fx_done = 0;
28535 }
28536 if (v8_1_branch_value_check (value, 5, FALSE) == FAIL)
28537 as_bad_where (fixP->fx_file, fixP->fx_line,
28538 BAD_BRANCH_OFF);
28539
28540 if (fixP->fx_done || !seg->use_rela_p)
28541 {
28542 addressT boff = value >> 1;
28543
28544 newval = md_chars_to_number (buf, THUMB_SIZE);
28545 newval |= (boff << 7);
28546 md_number_to_chars (buf, newval, THUMB_SIZE);
28547 }
28548 break;
28549
f6b2b12d
AV
28550 case BFD_RELOC_THUMB_PCREL_BFCSEL:
28551 if (fixP->fx_addsy
28552 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28553 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
28554 && ARM_IS_FUNC (fixP->fx_addsy)
28555 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
28556 {
28557 fixP->fx_done = 0;
28558 }
28559 if ((value & ~0x7f) && ((value & ~0x3f) != ~0x3f))
28560 as_bad_where (fixP->fx_file, fixP->fx_line,
28561 _("branch out of range"));
28562
28563 if (fixP->fx_done || !seg->use_rela_p)
28564 {
28565 newval = md_chars_to_number (buf, THUMB_SIZE);
28566
28567 addressT boff = ((newval & 0x0780) >> 7) << 1;
28568 addressT diff = value - boff;
28569
28570 if (diff == 4)
28571 {
28572 newval |= 1 << 1; /* T bit. */
28573 }
28574 else if (diff != 2)
28575 {
28576 as_bad_where (fixP->fx_file, fixP->fx_line,
28577 _("out of range label-relative fixup value"));
28578 }
28579 md_number_to_chars (buf, newval, THUMB_SIZE);
28580 }
28581 break;
28582
e5d6e09e
AV
28583 case BFD_RELOC_ARM_THUMB_BF17:
28584 if (fixP->fx_addsy
28585 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28586 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
28587 && ARM_IS_FUNC (fixP->fx_addsy)
28588 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
28589 {
28590 /* Force a relocation for a branch 17 bits wide. */
28591 fixP->fx_done = 0;
28592 }
28593
28594 if (v8_1_branch_value_check (value, 17, TRUE) == FAIL)
28595 as_bad_where (fixP->fx_file, fixP->fx_line,
28596 BAD_BRANCH_OFF);
28597
28598 if (fixP->fx_done || !seg->use_rela_p)
28599 {
28600 offsetT newval2;
28601 addressT immA, immB, immC;
28602
28603 immA = (value & 0x0001f000) >> 12;
28604 immB = (value & 0x00000ffc) >> 2;
28605 immC = (value & 0x00000002) >> 1;
28606
28607 newval = md_chars_to_number (buf, THUMB_SIZE);
28608 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
28609 newval |= immA;
28610 newval2 |= (immC << 11) | (immB << 1);
28611 md_number_to_chars (buf, newval, THUMB_SIZE);
28612 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
28613 }
28614 break;
28615
1caf72a5
AV
28616 case BFD_RELOC_ARM_THUMB_BF19:
28617 if (fixP->fx_addsy
28618 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28619 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
28620 && ARM_IS_FUNC (fixP->fx_addsy)
28621 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
28622 {
28623 /* Force a relocation for a branch 19 bits wide. */
28624 fixP->fx_done = 0;
28625 }
28626
28627 if (v8_1_branch_value_check (value, 19, TRUE) == FAIL)
28628 as_bad_where (fixP->fx_file, fixP->fx_line,
28629 BAD_BRANCH_OFF);
28630
28631 if (fixP->fx_done || !seg->use_rela_p)
28632 {
28633 offsetT newval2;
28634 addressT immA, immB, immC;
28635
28636 immA = (value & 0x0007f000) >> 12;
28637 immB = (value & 0x00000ffc) >> 2;
28638 immC = (value & 0x00000002) >> 1;
28639
28640 newval = md_chars_to_number (buf, THUMB_SIZE);
28641 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
28642 newval |= immA;
28643 newval2 |= (immC << 11) | (immB << 1);
28644 md_number_to_chars (buf, newval, THUMB_SIZE);
28645 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
28646 }
28647 break;
28648
1889da70
AV
28649 case BFD_RELOC_ARM_THUMB_BF13:
28650 if (fixP->fx_addsy
28651 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28652 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
28653 && ARM_IS_FUNC (fixP->fx_addsy)
28654 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
28655 {
28656 /* Force a relocation for a branch 13 bits wide. */
28657 fixP->fx_done = 0;
28658 }
28659
28660 if (v8_1_branch_value_check (value, 13, TRUE) == FAIL)
28661 as_bad_where (fixP->fx_file, fixP->fx_line,
28662 BAD_BRANCH_OFF);
28663
28664 if (fixP->fx_done || !seg->use_rela_p)
28665 {
28666 offsetT newval2;
28667 addressT immA, immB, immC;
28668
28669 immA = (value & 0x00001000) >> 12;
28670 immB = (value & 0x00000ffc) >> 2;
28671 immC = (value & 0x00000002) >> 1;
28672
28673 newval = md_chars_to_number (buf, THUMB_SIZE);
28674 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
28675 newval |= immA;
28676 newval2 |= (immC << 11) | (immB << 1);
28677 md_number_to_chars (buf, newval, THUMB_SIZE);
28678 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
28679 }
28680 break;
28681
60f993ce
AV
28682 case BFD_RELOC_ARM_THUMB_LOOP12:
28683 if (fixP->fx_addsy
28684 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28685 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
28686 && ARM_IS_FUNC (fixP->fx_addsy)
28687 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
28688 {
28689 /* Force a relocation for a branch 12 bits wide. */
28690 fixP->fx_done = 0;
28691 }
28692
28693 bfd_vma insn = get_thumb32_insn (buf);
1f6234a3 28694 /* le lr, <label>, le <label> or letp lr, <label> */
60f993ce 28695 if (((insn & 0xffffffff) == 0xf00fc001)
1f6234a3
AV
28696 || ((insn & 0xffffffff) == 0xf02fc001)
28697 || ((insn & 0xffffffff) == 0xf01fc001))
60f993ce
AV
28698 value = -value;
28699
28700 if (v8_1_branch_value_check (value, 12, FALSE) == FAIL)
28701 as_bad_where (fixP->fx_file, fixP->fx_line,
28702 BAD_BRANCH_OFF);
28703 if (fixP->fx_done || !seg->use_rela_p)
28704 {
28705 addressT imml, immh;
28706
28707 immh = (value & 0x00000ffc) >> 2;
28708 imml = (value & 0x00000002) >> 1;
28709
28710 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
28711 newval |= (imml << 11) | (immh << 1);
28712 md_number_to_chars (buf + THUMB_SIZE, newval, THUMB_SIZE);
28713 }
28714 break;
28715
845b51d6
PB
28716 case BFD_RELOC_ARM_V4BX:
28717 /* This will need to go in the object file. */
28718 fixP->fx_done = 0;
28719 break;
28720
c19d1205
ZW
28721 case BFD_RELOC_UNUSED:
28722 default:
28723 as_bad_where (fixP->fx_file, fixP->fx_line,
28724 _("bad relocation fixup type (%d)"), fixP->fx_r_type);
28725 }
6c43fab6
RE
28726}
28727
c19d1205
ZW
28728/* Translate internal representation of relocation info to BFD target
28729 format. */
a737bd4d 28730
c19d1205 28731arelent *
00a97672 28732tc_gen_reloc (asection *section, fixS *fixp)
a737bd4d 28733{
c19d1205
ZW
28734 arelent * reloc;
28735 bfd_reloc_code_real_type code;
a737bd4d 28736
325801bd 28737 reloc = XNEW (arelent);
a737bd4d 28738
325801bd 28739 reloc->sym_ptr_ptr = XNEW (asymbol *);
c19d1205
ZW
28740 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
28741 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
a737bd4d 28742
2fc8bdac 28743 if (fixp->fx_pcrel)
00a97672
RS
28744 {
28745 if (section->use_rela_p)
28746 fixp->fx_offset -= md_pcrel_from_section (fixp, section);
28747 else
28748 fixp->fx_offset = reloc->address;
28749 }
c19d1205 28750 reloc->addend = fixp->fx_offset;
a737bd4d 28751
c19d1205 28752 switch (fixp->fx_r_type)
a737bd4d 28753 {
c19d1205
ZW
28754 case BFD_RELOC_8:
28755 if (fixp->fx_pcrel)
28756 {
28757 code = BFD_RELOC_8_PCREL;
28758 break;
28759 }
1a0670f3 28760 /* Fall through. */
a737bd4d 28761
c19d1205
ZW
28762 case BFD_RELOC_16:
28763 if (fixp->fx_pcrel)
28764 {
28765 code = BFD_RELOC_16_PCREL;
28766 break;
28767 }
1a0670f3 28768 /* Fall through. */
6c43fab6 28769
c19d1205
ZW
28770 case BFD_RELOC_32:
28771 if (fixp->fx_pcrel)
28772 {
28773 code = BFD_RELOC_32_PCREL;
28774 break;
28775 }
1a0670f3 28776 /* Fall through. */
a737bd4d 28777
b6895b4f
PB
28778 case BFD_RELOC_ARM_MOVW:
28779 if (fixp->fx_pcrel)
28780 {
28781 code = BFD_RELOC_ARM_MOVW_PCREL;
28782 break;
28783 }
1a0670f3 28784 /* Fall through. */
b6895b4f
PB
28785
28786 case BFD_RELOC_ARM_MOVT:
28787 if (fixp->fx_pcrel)
28788 {
28789 code = BFD_RELOC_ARM_MOVT_PCREL;
28790 break;
28791 }
1a0670f3 28792 /* Fall through. */
b6895b4f
PB
28793
28794 case BFD_RELOC_ARM_THUMB_MOVW:
28795 if (fixp->fx_pcrel)
28796 {
28797 code = BFD_RELOC_ARM_THUMB_MOVW_PCREL;
28798 break;
28799 }
1a0670f3 28800 /* Fall through. */
b6895b4f
PB
28801
28802 case BFD_RELOC_ARM_THUMB_MOVT:
28803 if (fixp->fx_pcrel)
28804 {
28805 code = BFD_RELOC_ARM_THUMB_MOVT_PCREL;
28806 break;
28807 }
1a0670f3 28808 /* Fall through. */
b6895b4f 28809
c19d1205
ZW
28810 case BFD_RELOC_NONE:
28811 case BFD_RELOC_ARM_PCREL_BRANCH:
28812 case BFD_RELOC_ARM_PCREL_BLX:
28813 case BFD_RELOC_RVA:
28814 case BFD_RELOC_THUMB_PCREL_BRANCH7:
28815 case BFD_RELOC_THUMB_PCREL_BRANCH9:
28816 case BFD_RELOC_THUMB_PCREL_BRANCH12:
28817 case BFD_RELOC_THUMB_PCREL_BRANCH20:
28818 case BFD_RELOC_THUMB_PCREL_BRANCH23:
28819 case BFD_RELOC_THUMB_PCREL_BRANCH25:
c19d1205
ZW
28820 case BFD_RELOC_VTABLE_ENTRY:
28821 case BFD_RELOC_VTABLE_INHERIT:
f0927246
NC
28822#ifdef TE_PE
28823 case BFD_RELOC_32_SECREL:
28824#endif
c19d1205
ZW
28825 code = fixp->fx_r_type;
28826 break;
a737bd4d 28827
00adf2d4
JB
28828 case BFD_RELOC_THUMB_PCREL_BLX:
28829#ifdef OBJ_ELF
28830 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
28831 code = BFD_RELOC_THUMB_PCREL_BRANCH23;
28832 else
28833#endif
28834 code = BFD_RELOC_THUMB_PCREL_BLX;
28835 break;
28836
c19d1205
ZW
28837 case BFD_RELOC_ARM_LITERAL:
28838 case BFD_RELOC_ARM_HWLITERAL:
28839 /* If this is called then the a literal has
28840 been referenced across a section boundary. */
28841 as_bad_where (fixp->fx_file, fixp->fx_line,
28842 _("literal referenced across section boundary"));
28843 return NULL;
a737bd4d 28844
c19d1205 28845#ifdef OBJ_ELF
0855e32b
NS
28846 case BFD_RELOC_ARM_TLS_CALL:
28847 case BFD_RELOC_ARM_THM_TLS_CALL:
28848 case BFD_RELOC_ARM_TLS_DESCSEQ:
28849 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
c19d1205
ZW
28850 case BFD_RELOC_ARM_GOT32:
28851 case BFD_RELOC_ARM_GOTOFF:
b43420e6 28852 case BFD_RELOC_ARM_GOT_PREL:
c19d1205
ZW
28853 case BFD_RELOC_ARM_PLT32:
28854 case BFD_RELOC_ARM_TARGET1:
28855 case BFD_RELOC_ARM_ROSEGREL32:
28856 case BFD_RELOC_ARM_SBREL32:
28857 case BFD_RELOC_ARM_PREL31:
28858 case BFD_RELOC_ARM_TARGET2:
c19d1205 28859 case BFD_RELOC_ARM_TLS_LDO32:
39b41c9c
PB
28860 case BFD_RELOC_ARM_PCREL_CALL:
28861 case BFD_RELOC_ARM_PCREL_JUMP:
4962c51a
MS
28862 case BFD_RELOC_ARM_ALU_PC_G0_NC:
28863 case BFD_RELOC_ARM_ALU_PC_G0:
28864 case BFD_RELOC_ARM_ALU_PC_G1_NC:
28865 case BFD_RELOC_ARM_ALU_PC_G1:
28866 case BFD_RELOC_ARM_ALU_PC_G2:
28867 case BFD_RELOC_ARM_LDR_PC_G0:
28868 case BFD_RELOC_ARM_LDR_PC_G1:
28869 case BFD_RELOC_ARM_LDR_PC_G2:
28870 case BFD_RELOC_ARM_LDRS_PC_G0:
28871 case BFD_RELOC_ARM_LDRS_PC_G1:
28872 case BFD_RELOC_ARM_LDRS_PC_G2:
28873 case BFD_RELOC_ARM_LDC_PC_G0:
28874 case BFD_RELOC_ARM_LDC_PC_G1:
28875 case BFD_RELOC_ARM_LDC_PC_G2:
28876 case BFD_RELOC_ARM_ALU_SB_G0_NC:
28877 case BFD_RELOC_ARM_ALU_SB_G0:
28878 case BFD_RELOC_ARM_ALU_SB_G1_NC:
28879 case BFD_RELOC_ARM_ALU_SB_G1:
28880 case BFD_RELOC_ARM_ALU_SB_G2:
28881 case BFD_RELOC_ARM_LDR_SB_G0:
28882 case BFD_RELOC_ARM_LDR_SB_G1:
28883 case BFD_RELOC_ARM_LDR_SB_G2:
28884 case BFD_RELOC_ARM_LDRS_SB_G0:
28885 case BFD_RELOC_ARM_LDRS_SB_G1:
28886 case BFD_RELOC_ARM_LDRS_SB_G2:
28887 case BFD_RELOC_ARM_LDC_SB_G0:
28888 case BFD_RELOC_ARM_LDC_SB_G1:
28889 case BFD_RELOC_ARM_LDC_SB_G2:
845b51d6 28890 case BFD_RELOC_ARM_V4BX:
72d98d16
MG
28891 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
28892 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
28893 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
28894 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
188fd7ae
CL
28895 case BFD_RELOC_ARM_GOTFUNCDESC:
28896 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
28897 case BFD_RELOC_ARM_FUNCDESC:
e5d6e09e 28898 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 28899 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 28900 case BFD_RELOC_ARM_THUMB_BF13:
c19d1205
ZW
28901 code = fixp->fx_r_type;
28902 break;
a737bd4d 28903
0855e32b 28904 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205 28905 case BFD_RELOC_ARM_TLS_GD32:
5c5a4843 28906 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
75c11999 28907 case BFD_RELOC_ARM_TLS_LE32:
c19d1205 28908 case BFD_RELOC_ARM_TLS_IE32:
5c5a4843 28909 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
c19d1205 28910 case BFD_RELOC_ARM_TLS_LDM32:
5c5a4843 28911 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
c19d1205
ZW
28912 /* BFD will include the symbol's address in the addend.
28913 But we don't want that, so subtract it out again here. */
28914 if (!S_IS_COMMON (fixp->fx_addsy))
28915 reloc->addend -= (*reloc->sym_ptr_ptr)->value;
28916 code = fixp->fx_r_type;
28917 break;
28918#endif
a737bd4d 28919
c19d1205
ZW
28920 case BFD_RELOC_ARM_IMMEDIATE:
28921 as_bad_where (fixp->fx_file, fixp->fx_line,
28922 _("internal relocation (type: IMMEDIATE) not fixed up"));
28923 return NULL;
a737bd4d 28924
c19d1205
ZW
28925 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
28926 as_bad_where (fixp->fx_file, fixp->fx_line,
28927 _("ADRL used for a symbol not defined in the same file"));
28928 return NULL;
a737bd4d 28929
e12437dc 28930 case BFD_RELOC_THUMB_PCREL_BRANCH5:
f6b2b12d 28931 case BFD_RELOC_THUMB_PCREL_BFCSEL:
60f993ce 28932 case BFD_RELOC_ARM_THUMB_LOOP12:
e12437dc
AV
28933 as_bad_where (fixp->fx_file, fixp->fx_line,
28934 _("%s used for a symbol not defined in the same file"),
28935 bfd_get_reloc_code_name (fixp->fx_r_type));
28936 return NULL;
28937
c19d1205 28938 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
28939 if (section->use_rela_p)
28940 {
28941 code = fixp->fx_r_type;
28942 break;
28943 }
28944
c19d1205
ZW
28945 if (fixp->fx_addsy != NULL
28946 && !S_IS_DEFINED (fixp->fx_addsy)
28947 && S_IS_LOCAL (fixp->fx_addsy))
a737bd4d 28948 {
c19d1205
ZW
28949 as_bad_where (fixp->fx_file, fixp->fx_line,
28950 _("undefined local label `%s'"),
28951 S_GET_NAME (fixp->fx_addsy));
28952 return NULL;
a737bd4d
NC
28953 }
28954
c19d1205
ZW
28955 as_bad_where (fixp->fx_file, fixp->fx_line,
28956 _("internal_relocation (type: OFFSET_IMM) not fixed up"));
28957 return NULL;
a737bd4d 28958
c19d1205
ZW
28959 default:
28960 {
e0471c16 28961 const char * type;
6c43fab6 28962
c19d1205
ZW
28963 switch (fixp->fx_r_type)
28964 {
28965 case BFD_RELOC_NONE: type = "NONE"; break;
28966 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
28967 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
3eb17e6b 28968 case BFD_RELOC_ARM_SMC: type = "SMC"; break;
c19d1205
ZW
28969 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
28970 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
28971 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
db187cb9 28972 case BFD_RELOC_ARM_T32_OFFSET_IMM: type = "T32_OFFSET_IMM"; break;
8f06b2d8 28973 case BFD_RELOC_ARM_T32_CP_OFF_IMM: type = "T32_CP_OFF_IMM"; break;
c19d1205
ZW
28974 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
28975 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
28976 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
28977 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
28978 default: type = _("<unknown>"); break;
28979 }
28980 as_bad_where (fixp->fx_file, fixp->fx_line,
28981 _("cannot represent %s relocation in this object file format"),
28982 type);
28983 return NULL;
28984 }
a737bd4d 28985 }
6c43fab6 28986
c19d1205
ZW
28987#ifdef OBJ_ELF
28988 if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
28989 && GOT_symbol
28990 && fixp->fx_addsy == GOT_symbol)
28991 {
28992 code = BFD_RELOC_ARM_GOTPC;
28993 reloc->addend = fixp->fx_offset = reloc->address;
28994 }
28995#endif
6c43fab6 28996
c19d1205 28997 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
6c43fab6 28998
c19d1205
ZW
28999 if (reloc->howto == NULL)
29000 {
29001 as_bad_where (fixp->fx_file, fixp->fx_line,
29002 _("cannot represent %s relocation in this object file format"),
29003 bfd_get_reloc_code_name (code));
29004 return NULL;
29005 }
6c43fab6 29006
c19d1205
ZW
29007 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
29008 vtable entry to be used in the relocation's section offset. */
29009 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
29010 reloc->address = fixp->fx_offset;
6c43fab6 29011
c19d1205 29012 return reloc;
6c43fab6
RE
29013}
29014
c19d1205 29015/* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6c43fab6 29016
c19d1205
ZW
29017void
29018cons_fix_new_arm (fragS * frag,
29019 int where,
29020 int size,
62ebcb5c
AM
29021 expressionS * exp,
29022 bfd_reloc_code_real_type reloc)
6c43fab6 29023{
c19d1205 29024 int pcrel = 0;
6c43fab6 29025
c19d1205
ZW
29026 /* Pick a reloc.
29027 FIXME: @@ Should look at CPU word size. */
29028 switch (size)
29029 {
29030 case 1:
62ebcb5c 29031 reloc = BFD_RELOC_8;
c19d1205
ZW
29032 break;
29033 case 2:
62ebcb5c 29034 reloc = BFD_RELOC_16;
c19d1205
ZW
29035 break;
29036 case 4:
29037 default:
62ebcb5c 29038 reloc = BFD_RELOC_32;
c19d1205
ZW
29039 break;
29040 case 8:
62ebcb5c 29041 reloc = BFD_RELOC_64;
c19d1205
ZW
29042 break;
29043 }
6c43fab6 29044
f0927246
NC
29045#ifdef TE_PE
29046 if (exp->X_op == O_secrel)
29047 {
29048 exp->X_op = O_symbol;
62ebcb5c 29049 reloc = BFD_RELOC_32_SECREL;
f0927246
NC
29050 }
29051#endif
29052
62ebcb5c 29053 fix_new_exp (frag, where, size, exp, pcrel, reloc);
c19d1205 29054}
6c43fab6 29055
4343666d 29056#if defined (OBJ_COFF)
c19d1205
ZW
29057void
29058arm_validate_fix (fixS * fixP)
6c43fab6 29059{
c19d1205
ZW
29060 /* If the destination of the branch is a defined symbol which does not have
29061 the THUMB_FUNC attribute, then we must be calling a function which has
29062 the (interfacearm) attribute. We look for the Thumb entry point to that
29063 function and change the branch to refer to that function instead. */
29064 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
29065 && fixP->fx_addsy != NULL
29066 && S_IS_DEFINED (fixP->fx_addsy)
29067 && ! THUMB_IS_FUNC (fixP->fx_addsy))
6c43fab6 29068 {
c19d1205 29069 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
6c43fab6 29070 }
c19d1205
ZW
29071}
29072#endif
6c43fab6 29073
267bf995 29074
c19d1205
ZW
29075int
29076arm_force_relocation (struct fix * fixp)
29077{
29078#if defined (OBJ_COFF) && defined (TE_PE)
29079 if (fixp->fx_r_type == BFD_RELOC_RVA)
29080 return 1;
29081#endif
6c43fab6 29082
267bf995
RR
29083 /* In case we have a call or a branch to a function in ARM ISA mode from
29084 a thumb function or vice-versa force the relocation. These relocations
29085 are cleared off for some cores that might have blx and simple transformations
29086 are possible. */
29087
29088#ifdef OBJ_ELF
29089 switch (fixp->fx_r_type)
29090 {
29091 case BFD_RELOC_ARM_PCREL_JUMP:
29092 case BFD_RELOC_ARM_PCREL_CALL:
29093 case BFD_RELOC_THUMB_PCREL_BLX:
29094 if (THUMB_IS_FUNC (fixp->fx_addsy))
29095 return 1;
29096 break;
29097
29098 case BFD_RELOC_ARM_PCREL_BLX:
29099 case BFD_RELOC_THUMB_PCREL_BRANCH25:
29100 case BFD_RELOC_THUMB_PCREL_BRANCH20:
29101 case BFD_RELOC_THUMB_PCREL_BRANCH23:
29102 if (ARM_IS_FUNC (fixp->fx_addsy))
29103 return 1;
29104 break;
29105
29106 default:
29107 break;
29108 }
29109#endif
29110
b5884301
PB
29111 /* Resolve these relocations even if the symbol is extern or weak.
29112 Technically this is probably wrong due to symbol preemption.
29113 In practice these relocations do not have enough range to be useful
29114 at dynamic link time, and some code (e.g. in the Linux kernel)
29115 expects these references to be resolved. */
c19d1205
ZW
29116 if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
29117 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
b5884301 29118 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM8
0110f2b8 29119 || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE
b5884301
PB
29120 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
29121 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2
29122 || fixp->fx_r_type == BFD_RELOC_ARM_THUMB_OFFSET
16805f35 29123 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM
0110f2b8
PB
29124 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
29125 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMM12
b5884301
PB
29126 || fixp->fx_r_type == BFD_RELOC_ARM_T32_OFFSET_IMM
29127 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_PC12
29128 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM
29129 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM_S2)
c19d1205 29130 return 0;
a737bd4d 29131
4962c51a
MS
29132 /* Always leave these relocations for the linker. */
29133 if ((fixp->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
29134 && fixp->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
29135 || fixp->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
29136 return 1;
29137
f0291e4c
PB
29138 /* Always generate relocations against function symbols. */
29139 if (fixp->fx_r_type == BFD_RELOC_32
29140 && fixp->fx_addsy
29141 && (symbol_get_bfdsym (fixp->fx_addsy)->flags & BSF_FUNCTION))
29142 return 1;
29143
c19d1205 29144 return generic_force_reloc (fixp);
404ff6b5
AH
29145}
29146
0ffdc86c 29147#if defined (OBJ_ELF) || defined (OBJ_COFF)
e28387c3
PB
29148/* Relocations against function names must be left unadjusted,
29149 so that the linker can use this information to generate interworking
29150 stubs. The MIPS version of this function
c19d1205
ZW
29151 also prevents relocations that are mips-16 specific, but I do not
29152 know why it does this.
404ff6b5 29153
c19d1205
ZW
29154 FIXME:
29155 There is one other problem that ought to be addressed here, but
29156 which currently is not: Taking the address of a label (rather
29157 than a function) and then later jumping to that address. Such
29158 addresses also ought to have their bottom bit set (assuming that
29159 they reside in Thumb code), but at the moment they will not. */
404ff6b5 29160
c19d1205
ZW
29161bfd_boolean
29162arm_fix_adjustable (fixS * fixP)
404ff6b5 29163{
c19d1205
ZW
29164 if (fixP->fx_addsy == NULL)
29165 return 1;
404ff6b5 29166
e28387c3
PB
29167 /* Preserve relocations against symbols with function type. */
29168 if (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_FUNCTION)
c921be7d 29169 return FALSE;
e28387c3 29170
c19d1205
ZW
29171 if (THUMB_IS_FUNC (fixP->fx_addsy)
29172 && fixP->fx_subsy == NULL)
c921be7d 29173 return FALSE;
a737bd4d 29174
c19d1205
ZW
29175 /* We need the symbol name for the VTABLE entries. */
29176 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
29177 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
c921be7d 29178 return FALSE;
404ff6b5 29179
c19d1205
ZW
29180 /* Don't allow symbols to be discarded on GOT related relocs. */
29181 if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
29182 || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
29183 || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
29184 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32
5c5a4843 29185 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32_FDPIC
c19d1205
ZW
29186 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LE32
29187 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32
5c5a4843 29188 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32_FDPIC
c19d1205 29189 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32
5c5a4843 29190 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32_FDPIC
c19d1205 29191 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDO32
0855e32b
NS
29192 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GOTDESC
29193 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_CALL
29194 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_CALL
29195 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_DESCSEQ
29196 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_DESCSEQ
c19d1205 29197 || fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
c921be7d 29198 return FALSE;
a737bd4d 29199
4962c51a
MS
29200 /* Similarly for group relocations. */
29201 if ((fixP->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
29202 && fixP->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
29203 || fixP->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
c921be7d 29204 return FALSE;
4962c51a 29205
79947c54
CD
29206 /* MOVW/MOVT REL relocations have limited offsets, so keep the symbols. */
29207 if (fixP->fx_r_type == BFD_RELOC_ARM_MOVW
29208 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT
29209 || fixP->fx_r_type == BFD_RELOC_ARM_MOVW_PCREL
29210 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT_PCREL
29211 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
29212 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT
29213 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW_PCREL
29214 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT_PCREL)
c921be7d 29215 return FALSE;
79947c54 29216
72d98d16
MG
29217 /* BFD_RELOC_ARM_THUMB_ALU_ABS_Gx_NC relocations have VERY limited
29218 offsets, so keep these symbols. */
29219 if (fixP->fx_r_type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
29220 && fixP->fx_r_type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
29221 return FALSE;
29222
c921be7d 29223 return TRUE;
a737bd4d 29224}
0ffdc86c
NC
29225#endif /* defined (OBJ_ELF) || defined (OBJ_COFF) */
29226
29227#ifdef OBJ_ELF
c19d1205
ZW
29228const char *
29229elf32_arm_target_format (void)
404ff6b5 29230{
c19d1205
ZW
29231#ifdef TE_SYMBIAN
29232 return (target_big_endian
29233 ? "elf32-bigarm-symbian"
29234 : "elf32-littlearm-symbian");
29235#elif defined (TE_VXWORKS)
29236 return (target_big_endian
29237 ? "elf32-bigarm-vxworks"
29238 : "elf32-littlearm-vxworks");
b38cadfb
NC
29239#elif defined (TE_NACL)
29240 return (target_big_endian
29241 ? "elf32-bigarm-nacl"
29242 : "elf32-littlearm-nacl");
c19d1205 29243#else
18a20338
CL
29244 if (arm_fdpic)
29245 {
29246 if (target_big_endian)
29247 return "elf32-bigarm-fdpic";
29248 else
29249 return "elf32-littlearm-fdpic";
29250 }
c19d1205 29251 else
18a20338
CL
29252 {
29253 if (target_big_endian)
29254 return "elf32-bigarm";
29255 else
29256 return "elf32-littlearm";
29257 }
c19d1205 29258#endif
404ff6b5
AH
29259}
29260
c19d1205
ZW
29261void
29262armelf_frob_symbol (symbolS * symp,
29263 int * puntp)
404ff6b5 29264{
c19d1205
ZW
29265 elf_frob_symbol (symp, puntp);
29266}
29267#endif
404ff6b5 29268
c19d1205 29269/* MD interface: Finalization. */
a737bd4d 29270
c19d1205
ZW
29271void
29272arm_cleanup (void)
29273{
29274 literal_pool * pool;
a737bd4d 29275
5ee91343
AV
29276 /* Ensure that all the predication blocks are properly closed. */
29277 check_pred_blocks_finished ();
e07e6e58 29278
c19d1205
ZW
29279 for (pool = list_of_pools; pool; pool = pool->next)
29280 {
5f4273c7 29281 /* Put it at the end of the relevant section. */
c19d1205
ZW
29282 subseg_set (pool->section, pool->sub_section);
29283#ifdef OBJ_ELF
29284 arm_elf_change_section ();
29285#endif
29286 s_ltorg (0);
29287 }
404ff6b5
AH
29288}
29289
cd000bff
DJ
29290#ifdef OBJ_ELF
29291/* Remove any excess mapping symbols generated for alignment frags in
29292 SEC. We may have created a mapping symbol before a zero byte
29293 alignment; remove it if there's a mapping symbol after the
29294 alignment. */
29295static void
29296check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
29297 void *dummy ATTRIBUTE_UNUSED)
29298{
29299 segment_info_type *seginfo = seg_info (sec);
29300 fragS *fragp;
29301
29302 if (seginfo == NULL || seginfo->frchainP == NULL)
29303 return;
29304
29305 for (fragp = seginfo->frchainP->frch_root;
29306 fragp != NULL;
29307 fragp = fragp->fr_next)
29308 {
29309 symbolS *sym = fragp->tc_frag_data.last_map;
29310 fragS *next = fragp->fr_next;
29311
29312 /* Variable-sized frags have been converted to fixed size by
29313 this point. But if this was variable-sized to start with,
29314 there will be a fixed-size frag after it. So don't handle
29315 next == NULL. */
29316 if (sym == NULL || next == NULL)
29317 continue;
29318
29319 if (S_GET_VALUE (sym) < next->fr_address)
29320 /* Not at the end of this frag. */
29321 continue;
29322 know (S_GET_VALUE (sym) == next->fr_address);
29323
29324 do
29325 {
29326 if (next->tc_frag_data.first_map != NULL)
29327 {
29328 /* Next frag starts with a mapping symbol. Discard this
29329 one. */
29330 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
29331 break;
29332 }
29333
29334 if (next->fr_next == NULL)
29335 {
29336 /* This mapping symbol is at the end of the section. Discard
29337 it. */
29338 know (next->fr_fix == 0 && next->fr_var == 0);
29339 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
29340 break;
29341 }
29342
29343 /* As long as we have empty frags without any mapping symbols,
29344 keep looking. */
29345 /* If the next frag is non-empty and does not start with a
29346 mapping symbol, then this mapping symbol is required. */
29347 if (next->fr_address != next->fr_next->fr_address)
29348 break;
29349
29350 next = next->fr_next;
29351 }
29352 while (next != NULL);
29353 }
29354}
29355#endif
29356
c19d1205
ZW
29357/* Adjust the symbol table. This marks Thumb symbols as distinct from
29358 ARM ones. */
404ff6b5 29359
c19d1205
ZW
29360void
29361arm_adjust_symtab (void)
404ff6b5 29362{
c19d1205
ZW
29363#ifdef OBJ_COFF
29364 symbolS * sym;
404ff6b5 29365
c19d1205
ZW
29366 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
29367 {
29368 if (ARM_IS_THUMB (sym))
29369 {
29370 if (THUMB_IS_FUNC (sym))
29371 {
29372 /* Mark the symbol as a Thumb function. */
29373 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
29374 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
29375 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
404ff6b5 29376
c19d1205
ZW
29377 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
29378 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
29379 else
29380 as_bad (_("%s: unexpected function type: %d"),
29381 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
29382 }
29383 else switch (S_GET_STORAGE_CLASS (sym))
29384 {
29385 case C_EXT:
29386 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
29387 break;
29388 case C_STAT:
29389 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
29390 break;
29391 case C_LABEL:
29392 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
29393 break;
29394 default:
29395 /* Do nothing. */
29396 break;
29397 }
29398 }
a737bd4d 29399
c19d1205
ZW
29400 if (ARM_IS_INTERWORK (sym))
29401 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
404ff6b5 29402 }
c19d1205
ZW
29403#endif
29404#ifdef OBJ_ELF
29405 symbolS * sym;
29406 char bind;
404ff6b5 29407
c19d1205 29408 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
404ff6b5 29409 {
c19d1205
ZW
29410 if (ARM_IS_THUMB (sym))
29411 {
29412 elf_symbol_type * elf_sym;
404ff6b5 29413
c19d1205
ZW
29414 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
29415 bind = ELF_ST_BIND (elf_sym->internal_elf_sym.st_info);
404ff6b5 29416
b0796911
PB
29417 if (! bfd_is_arm_special_symbol_name (elf_sym->symbol.name,
29418 BFD_ARM_SPECIAL_SYM_TYPE_ANY))
c19d1205
ZW
29419 {
29420 /* If it's a .thumb_func, declare it as so,
29421 otherwise tag label as .code 16. */
29422 if (THUMB_IS_FUNC (sym))
39d911fc
TP
29423 ARM_SET_SYM_BRANCH_TYPE (elf_sym->internal_elf_sym.st_target_internal,
29424 ST_BRANCH_TO_THUMB);
3ba67470 29425 else if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
c19d1205
ZW
29426 elf_sym->internal_elf_sym.st_info =
29427 ELF_ST_INFO (bind, STT_ARM_16BIT);
29428 }
29429 }
29430 }
cd000bff
DJ
29431
29432 /* Remove any overlapping mapping symbols generated by alignment frags. */
29433 bfd_map_over_sections (stdoutput, check_mapping_symbols, (char *) 0);
709001e9
MM
29434 /* Now do generic ELF adjustments. */
29435 elf_adjust_symtab ();
c19d1205 29436#endif
404ff6b5
AH
29437}
29438
c19d1205 29439/* MD interface: Initialization. */
404ff6b5 29440
a737bd4d 29441static void
c19d1205 29442set_constant_flonums (void)
a737bd4d 29443{
c19d1205 29444 int i;
404ff6b5 29445
c19d1205
ZW
29446 for (i = 0; i < NUM_FLOAT_VALS; i++)
29447 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
29448 abort ();
a737bd4d 29449}
404ff6b5 29450
3e9e4fcf
JB
29451/* Auto-select Thumb mode if it's the only available instruction set for the
29452 given architecture. */
29453
29454static void
29455autoselect_thumb_from_cpu_variant (void)
29456{
29457 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
29458 opcode_select (16);
29459}
29460
c19d1205
ZW
29461void
29462md_begin (void)
a737bd4d 29463{
c19d1205
ZW
29464 unsigned mach;
29465 unsigned int i;
404ff6b5 29466
c19d1205
ZW
29467 if ( (arm_ops_hsh = hash_new ()) == NULL
29468 || (arm_cond_hsh = hash_new ()) == NULL
5ee91343 29469 || (arm_vcond_hsh = hash_new ()) == NULL
c19d1205
ZW
29470 || (arm_shift_hsh = hash_new ()) == NULL
29471 || (arm_psr_hsh = hash_new ()) == NULL
62b3e311 29472 || (arm_v7m_psr_hsh = hash_new ()) == NULL
c19d1205 29473 || (arm_reg_hsh = hash_new ()) == NULL
62b3e311
PB
29474 || (arm_reloc_hsh = hash_new ()) == NULL
29475 || (arm_barrier_opt_hsh = hash_new ()) == NULL)
c19d1205
ZW
29476 as_fatal (_("virtual memory exhausted"));
29477
29478 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
d3ce72d0 29479 hash_insert (arm_ops_hsh, insns[i].template_name, (void *) (insns + i));
c19d1205 29480 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
d3ce72d0 29481 hash_insert (arm_cond_hsh, conds[i].template_name, (void *) (conds + i));
5ee91343
AV
29482 for (i = 0; i < sizeof (vconds) / sizeof (struct asm_cond); i++)
29483 hash_insert (arm_vcond_hsh, vconds[i].template_name, (void *) (vconds + i));
c19d1205 29484 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
5a49b8ac 29485 hash_insert (arm_shift_hsh, shift_names[i].name, (void *) (shift_names + i));
c19d1205 29486 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
d3ce72d0 29487 hash_insert (arm_psr_hsh, psrs[i].template_name, (void *) (psrs + i));
62b3e311 29488 for (i = 0; i < sizeof (v7m_psrs) / sizeof (struct asm_psr); i++)
d3ce72d0 29489 hash_insert (arm_v7m_psr_hsh, v7m_psrs[i].template_name,
477330fc 29490 (void *) (v7m_psrs + i));
c19d1205 29491 for (i = 0; i < sizeof (reg_names) / sizeof (struct reg_entry); i++)
5a49b8ac 29492 hash_insert (arm_reg_hsh, reg_names[i].name, (void *) (reg_names + i));
62b3e311
PB
29493 for (i = 0;
29494 i < sizeof (barrier_opt_names) / sizeof (struct asm_barrier_opt);
29495 i++)
d3ce72d0 29496 hash_insert (arm_barrier_opt_hsh, barrier_opt_names[i].template_name,
5a49b8ac 29497 (void *) (barrier_opt_names + i));
c19d1205 29498#ifdef OBJ_ELF
3da1d841
NC
29499 for (i = 0; i < ARRAY_SIZE (reloc_names); i++)
29500 {
29501 struct reloc_entry * entry = reloc_names + i;
29502
29503 if (arm_is_eabi() && entry->reloc == BFD_RELOC_ARM_PLT32)
29504 /* This makes encode_branch() use the EABI versions of this relocation. */
29505 entry->reloc = BFD_RELOC_UNUSED;
29506
29507 hash_insert (arm_reloc_hsh, entry->name, (void *) entry);
29508 }
c19d1205
ZW
29509#endif
29510
29511 set_constant_flonums ();
404ff6b5 29512
c19d1205
ZW
29513 /* Set the cpu variant based on the command-line options. We prefer
29514 -mcpu= over -march= if both are set (as for GCC); and we prefer
29515 -mfpu= over any other way of setting the floating point unit.
29516 Use of legacy options with new options are faulted. */
e74cfd16 29517 if (legacy_cpu)
404ff6b5 29518 {
e74cfd16 29519 if (mcpu_cpu_opt || march_cpu_opt)
c19d1205
ZW
29520 as_bad (_("use of old and new-style options to set CPU type"));
29521
4d354d8b 29522 selected_arch = *legacy_cpu;
404ff6b5 29523 }
4d354d8b
TP
29524 else if (mcpu_cpu_opt)
29525 {
29526 selected_arch = *mcpu_cpu_opt;
29527 selected_ext = *mcpu_ext_opt;
29528 }
29529 else if (march_cpu_opt)
c168ce07 29530 {
4d354d8b
TP
29531 selected_arch = *march_cpu_opt;
29532 selected_ext = *march_ext_opt;
c168ce07 29533 }
4d354d8b 29534 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
404ff6b5 29535
e74cfd16 29536 if (legacy_fpu)
c19d1205 29537 {
e74cfd16 29538 if (mfpu_opt)
c19d1205 29539 as_bad (_("use of old and new-style options to set FPU type"));
03b1477f 29540
4d354d8b 29541 selected_fpu = *legacy_fpu;
03b1477f 29542 }
4d354d8b
TP
29543 else if (mfpu_opt)
29544 selected_fpu = *mfpu_opt;
29545 else
03b1477f 29546 {
45eb4c1b
NS
29547#if !(defined (EABI_DEFAULT) || defined (TE_LINUX) \
29548 || defined (TE_NetBSD) || defined (TE_VXWORKS))
39c2da32
RE
29549 /* Some environments specify a default FPU. If they don't, infer it
29550 from the processor. */
e74cfd16 29551 if (mcpu_fpu_opt)
4d354d8b 29552 selected_fpu = *mcpu_fpu_opt;
e7da50fa 29553 else if (march_fpu_opt)
4d354d8b 29554 selected_fpu = *march_fpu_opt;
39c2da32 29555#else
4d354d8b 29556 selected_fpu = fpu_default;
39c2da32 29557#endif
03b1477f
RE
29558 }
29559
4d354d8b 29560 if (ARM_FEATURE_ZERO (selected_fpu))
03b1477f 29561 {
4d354d8b
TP
29562 if (!no_cpu_selected ())
29563 selected_fpu = fpu_default;
03b1477f 29564 else
4d354d8b 29565 selected_fpu = fpu_arch_fpa;
03b1477f
RE
29566 }
29567
ee065d83 29568#ifdef CPU_DEFAULT
4d354d8b 29569 if (ARM_FEATURE_ZERO (selected_arch))
ee065d83 29570 {
4d354d8b
TP
29571 selected_arch = cpu_default;
29572 selected_cpu = selected_arch;
ee065d83 29573 }
4d354d8b 29574 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
e74cfd16 29575#else
4d354d8b
TP
29576 /* Autodection of feature mode: allow all features in cpu_variant but leave
29577 selected_cpu unset. It will be set in aeabi_set_public_attributes ()
29578 after all instruction have been processed and we can decide what CPU
29579 should be selected. */
29580 if (ARM_FEATURE_ZERO (selected_arch))
29581 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
ee065d83 29582 else
4d354d8b 29583 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83 29584#endif
03b1477f 29585
3e9e4fcf
JB
29586 autoselect_thumb_from_cpu_variant ();
29587
e74cfd16 29588 arm_arch_used = thumb_arch_used = arm_arch_none;
ee065d83 29589
f17c130b 29590#if defined OBJ_COFF || defined OBJ_ELF
b99bd4ef 29591 {
7cc69913
NC
29592 unsigned int flags = 0;
29593
29594#if defined OBJ_ELF
29595 flags = meabi_flags;
d507cf36
PB
29596
29597 switch (meabi_flags)
33a392fb 29598 {
d507cf36 29599 case EF_ARM_EABI_UNKNOWN:
7cc69913 29600#endif
d507cf36
PB
29601 /* Set the flags in the private structure. */
29602 if (uses_apcs_26) flags |= F_APCS26;
29603 if (support_interwork) flags |= F_INTERWORK;
29604 if (uses_apcs_float) flags |= F_APCS_FLOAT;
c19d1205 29605 if (pic_code) flags |= F_PIC;
e74cfd16 29606 if (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_any_hard))
7cc69913
NC
29607 flags |= F_SOFT_FLOAT;
29608
d507cf36
PB
29609 switch (mfloat_abi_opt)
29610 {
29611 case ARM_FLOAT_ABI_SOFT:
29612 case ARM_FLOAT_ABI_SOFTFP:
29613 flags |= F_SOFT_FLOAT;
29614 break;
33a392fb 29615
d507cf36
PB
29616 case ARM_FLOAT_ABI_HARD:
29617 if (flags & F_SOFT_FLOAT)
29618 as_bad (_("hard-float conflicts with specified fpu"));
29619 break;
29620 }
03b1477f 29621
e74cfd16
PB
29622 /* Using pure-endian doubles (even if soft-float). */
29623 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_endian_pure))
7cc69913 29624 flags |= F_VFP_FLOAT;
f17c130b 29625
fde78edd 29626#if defined OBJ_ELF
e74cfd16 29627 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_maverick))
d507cf36 29628 flags |= EF_ARM_MAVERICK_FLOAT;
d507cf36
PB
29629 break;
29630
8cb51566 29631 case EF_ARM_EABI_VER4:
3a4a14e9 29632 case EF_ARM_EABI_VER5:
c19d1205 29633 /* No additional flags to set. */
d507cf36
PB
29634 break;
29635
29636 default:
29637 abort ();
29638 }
7cc69913 29639#endif
b99bd4ef
NC
29640 bfd_set_private_flags (stdoutput, flags);
29641
29642 /* We have run out flags in the COFF header to encode the
29643 status of ATPCS support, so instead we create a dummy,
c19d1205 29644 empty, debug section called .arm.atpcs. */
b99bd4ef
NC
29645 if (atpcs)
29646 {
29647 asection * sec;
29648
29649 sec = bfd_make_section (stdoutput, ".arm.atpcs");
29650
29651 if (sec != NULL)
29652 {
29653 bfd_set_section_flags
29654 (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
29655 bfd_set_section_size (stdoutput, sec, 0);
29656 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
29657 }
29658 }
7cc69913 29659 }
f17c130b 29660#endif
b99bd4ef
NC
29661
29662 /* Record the CPU type as well. */
2d447fca
JM
29663 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2))
29664 mach = bfd_mach_arm_iWMMXt2;
29665 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt))
e16bb312 29666 mach = bfd_mach_arm_iWMMXt;
e74cfd16 29667 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_xscale))
b99bd4ef 29668 mach = bfd_mach_arm_XScale;
e74cfd16 29669 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_maverick))
fde78edd 29670 mach = bfd_mach_arm_ep9312;
e74cfd16 29671 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5e))
b99bd4ef 29672 mach = bfd_mach_arm_5TE;
e74cfd16 29673 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5))
b99bd4ef 29674 {
e74cfd16 29675 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
29676 mach = bfd_mach_arm_5T;
29677 else
29678 mach = bfd_mach_arm_5;
29679 }
e74cfd16 29680 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4))
b99bd4ef 29681 {
e74cfd16 29682 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
29683 mach = bfd_mach_arm_4T;
29684 else
29685 mach = bfd_mach_arm_4;
29686 }
e74cfd16 29687 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3m))
b99bd4ef 29688 mach = bfd_mach_arm_3M;
e74cfd16
PB
29689 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3))
29690 mach = bfd_mach_arm_3;
29691 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2s))
29692 mach = bfd_mach_arm_2a;
29693 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2))
29694 mach = bfd_mach_arm_2;
29695 else
29696 mach = bfd_mach_arm_unknown;
b99bd4ef
NC
29697
29698 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
29699}
29700
c19d1205 29701/* Command line processing. */
b99bd4ef 29702
c19d1205
ZW
29703/* md_parse_option
29704 Invocation line includes a switch not recognized by the base assembler.
29705 See if it's a processor-specific option.
b99bd4ef 29706
c19d1205
ZW
29707 This routine is somewhat complicated by the need for backwards
29708 compatibility (since older releases of gcc can't be changed).
29709 The new options try to make the interface as compatible as
29710 possible with GCC.
b99bd4ef 29711
c19d1205 29712 New options (supported) are:
b99bd4ef 29713
c19d1205
ZW
29714 -mcpu=<cpu name> Assemble for selected processor
29715 -march=<architecture name> Assemble for selected architecture
29716 -mfpu=<fpu architecture> Assemble for selected FPU.
29717 -EB/-mbig-endian Big-endian
29718 -EL/-mlittle-endian Little-endian
29719 -k Generate PIC code
29720 -mthumb Start in Thumb mode
29721 -mthumb-interwork Code supports ARM/Thumb interworking
b99bd4ef 29722
278df34e 29723 -m[no-]warn-deprecated Warn about deprecated features
8b2d793c 29724 -m[no-]warn-syms Warn when symbols match instructions
267bf995 29725
c19d1205 29726 For now we will also provide support for:
b99bd4ef 29727
c19d1205
ZW
29728 -mapcs-32 32-bit Program counter
29729 -mapcs-26 26-bit Program counter
29730 -macps-float Floats passed in FP registers
29731 -mapcs-reentrant Reentrant code
29732 -matpcs
29733 (sometime these will probably be replaced with -mapcs=<list of options>
29734 and -matpcs=<list of options>)
b99bd4ef 29735
c19d1205
ZW
29736 The remaining options are only supported for back-wards compatibility.
29737 Cpu variants, the arm part is optional:
29738 -m[arm]1 Currently not supported.
29739 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
29740 -m[arm]3 Arm 3 processor
29741 -m[arm]6[xx], Arm 6 processors
29742 -m[arm]7[xx][t][[d]m] Arm 7 processors
29743 -m[arm]8[10] Arm 8 processors
29744 -m[arm]9[20][tdmi] Arm 9 processors
29745 -mstrongarm[110[0]] StrongARM processors
29746 -mxscale XScale processors
29747 -m[arm]v[2345[t[e]]] Arm architectures
29748 -mall All (except the ARM1)
29749 FP variants:
29750 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
29751 -mfpe-old (No float load/store multiples)
29752 -mvfpxd VFP Single precision
29753 -mvfp All VFP
29754 -mno-fpu Disable all floating point instructions
b99bd4ef 29755
c19d1205
ZW
29756 The following CPU names are recognized:
29757 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
29758 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
29759 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
29760 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
29761 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
29762 arm10t arm10e, arm1020t, arm1020e, arm10200e,
29763 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
b99bd4ef 29764
c19d1205 29765 */
b99bd4ef 29766
c19d1205 29767const char * md_shortopts = "m:k";
b99bd4ef 29768
c19d1205
ZW
29769#ifdef ARM_BI_ENDIAN
29770#define OPTION_EB (OPTION_MD_BASE + 0)
29771#define OPTION_EL (OPTION_MD_BASE + 1)
b99bd4ef 29772#else
c19d1205
ZW
29773#if TARGET_BYTES_BIG_ENDIAN
29774#define OPTION_EB (OPTION_MD_BASE + 0)
b99bd4ef 29775#else
c19d1205
ZW
29776#define OPTION_EL (OPTION_MD_BASE + 1)
29777#endif
b99bd4ef 29778#endif
845b51d6 29779#define OPTION_FIX_V4BX (OPTION_MD_BASE + 2)
18a20338 29780#define OPTION_FDPIC (OPTION_MD_BASE + 3)
b99bd4ef 29781
c19d1205 29782struct option md_longopts[] =
b99bd4ef 29783{
c19d1205
ZW
29784#ifdef OPTION_EB
29785 {"EB", no_argument, NULL, OPTION_EB},
29786#endif
29787#ifdef OPTION_EL
29788 {"EL", no_argument, NULL, OPTION_EL},
b99bd4ef 29789#endif
845b51d6 29790 {"fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX},
18a20338
CL
29791#ifdef OBJ_ELF
29792 {"fdpic", no_argument, NULL, OPTION_FDPIC},
29793#endif
c19d1205
ZW
29794 {NULL, no_argument, NULL, 0}
29795};
b99bd4ef 29796
c19d1205 29797size_t md_longopts_size = sizeof (md_longopts);
b99bd4ef 29798
c19d1205 29799struct arm_option_table
b99bd4ef 29800{
0198d5e6
TC
29801 const char * option; /* Option name to match. */
29802 const char * help; /* Help information. */
29803 int * var; /* Variable to change. */
29804 int value; /* What to change it to. */
29805 const char * deprecated; /* If non-null, print this message. */
c19d1205 29806};
b99bd4ef 29807
c19d1205
ZW
29808struct arm_option_table arm_opts[] =
29809{
29810 {"k", N_("generate PIC code"), &pic_code, 1, NULL},
29811 {"mthumb", N_("assemble Thumb code"), &thumb_mode, 1, NULL},
29812 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
29813 &support_interwork, 1, NULL},
29814 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
29815 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
29816 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
29817 1, NULL},
29818 {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
29819 {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
29820 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
29821 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 0,
29822 NULL},
b99bd4ef 29823
c19d1205
ZW
29824 /* These are recognized by the assembler, but have no affect on code. */
29825 {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
29826 {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
278df34e
NS
29827
29828 {"mwarn-deprecated", NULL, &warn_on_deprecated, 1, NULL},
29829 {"mno-warn-deprecated", N_("do not warn on use of deprecated feature"),
29830 &warn_on_deprecated, 0, NULL},
8b2d793c
NC
29831 {"mwarn-syms", N_("warn about symbols that match instruction names [default]"), (int *) (& flag_warn_syms), TRUE, NULL},
29832 {"mno-warn-syms", N_("disable warnings about symobls that match instructions"), (int *) (& flag_warn_syms), FALSE, NULL},
e74cfd16
PB
29833 {NULL, NULL, NULL, 0, NULL}
29834};
29835
29836struct arm_legacy_option_table
29837{
0198d5e6
TC
29838 const char * option; /* Option name to match. */
29839 const arm_feature_set ** var; /* Variable to change. */
29840 const arm_feature_set value; /* What to change it to. */
29841 const char * deprecated; /* If non-null, print this message. */
e74cfd16 29842};
b99bd4ef 29843
e74cfd16
PB
29844const struct arm_legacy_option_table arm_legacy_opts[] =
29845{
c19d1205
ZW
29846 /* DON'T add any new processors to this list -- we want the whole list
29847 to go away... Add them to the processors table instead. */
e74cfd16
PB
29848 {"marm1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
29849 {"m1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
29850 {"marm2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
29851 {"m2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
29852 {"marm250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
29853 {"m250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
29854 {"marm3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
29855 {"m3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
29856 {"marm6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
29857 {"m6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
29858 {"marm600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
29859 {"m600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
29860 {"marm610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
29861 {"m610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
29862 {"marm620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
29863 {"m620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
29864 {"marm7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
29865 {"m7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
29866 {"marm70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
29867 {"m70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
29868 {"marm700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
29869 {"m700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
29870 {"marm700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
29871 {"m700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
29872 {"marm710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
29873 {"m710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
29874 {"marm710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
29875 {"m710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
29876 {"marm720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
29877 {"m720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
29878 {"marm7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
29879 {"m7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
29880 {"marm7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
29881 {"m7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
29882 {"marm7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
29883 {"m7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
29884 {"marm7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
29885 {"m7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
29886 {"marm7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
29887 {"m7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
29888 {"marm7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
29889 {"m7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
29890 {"marm7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
29891 {"m7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
29892 {"marm7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
29893 {"m7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
29894 {"marm7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
29895 {"m7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
29896 {"marm7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
29897 {"m7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
29898 {"marm710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
29899 {"m710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
29900 {"marm720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
29901 {"m720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
29902 {"marm740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
29903 {"m740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
29904 {"marm8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
29905 {"m8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
29906 {"marm810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
29907 {"m810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
29908 {"marm9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
29909 {"m9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
29910 {"marm9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
29911 {"m9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
29912 {"marm920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
29913 {"m920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
29914 {"marm940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
29915 {"m940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
29916 {"mstrongarm", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")},
29917 {"mstrongarm110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 29918 N_("use -mcpu=strongarm110")},
e74cfd16 29919 {"mstrongarm1100", &legacy_cpu, ARM_ARCH_V4,
c19d1205 29920 N_("use -mcpu=strongarm1100")},
e74cfd16 29921 {"mstrongarm1110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 29922 N_("use -mcpu=strongarm1110")},
e74cfd16
PB
29923 {"mxscale", &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
29924 {"miwmmxt", &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
29925 {"mall", &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
7ed4c4c5 29926
c19d1205 29927 /* Architecture variants -- don't add any more to this list either. */
e74cfd16
PB
29928 {"mv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
29929 {"marmv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
29930 {"mv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
29931 {"marmv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
29932 {"mv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
29933 {"marmv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
29934 {"mv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
29935 {"marmv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
29936 {"mv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
29937 {"marmv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
29938 {"mv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
29939 {"marmv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
29940 {"mv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
29941 {"marmv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
29942 {"mv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
29943 {"marmv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
29944 {"mv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
29945 {"marmv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
7ed4c4c5 29946
c19d1205 29947 /* Floating point variants -- don't add any more to this list either. */
0198d5e6
TC
29948 {"mfpe-old", &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
29949 {"mfpa10", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
29950 {"mfpa11", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
29951 {"mno-fpu", &legacy_fpu, ARM_ARCH_NONE,
c19d1205 29952 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
7ed4c4c5 29953
e74cfd16 29954 {NULL, NULL, ARM_ARCH_NONE, NULL}
c19d1205 29955};
7ed4c4c5 29956
c19d1205 29957struct arm_cpu_option_table
7ed4c4c5 29958{
0198d5e6
TC
29959 const char * name;
29960 size_t name_len;
29961 const arm_feature_set value;
29962 const arm_feature_set ext;
c19d1205
ZW
29963 /* For some CPUs we assume an FPU unless the user explicitly sets
29964 -mfpu=... */
0198d5e6 29965 const arm_feature_set default_fpu;
ee065d83
PB
29966 /* The canonical name of the CPU, or NULL to use NAME converted to upper
29967 case. */
0198d5e6 29968 const char * canonical_name;
c19d1205 29969};
7ed4c4c5 29970
c19d1205
ZW
29971/* This list should, at a minimum, contain all the cpu names
29972 recognized by GCC. */
996b5569 29973#define ARM_CPU_OPT(N, CN, V, E, DF) { N, sizeof (N) - 1, V, E, DF, CN }
0198d5e6 29974
e74cfd16 29975static const struct arm_cpu_option_table arm_cpus[] =
c19d1205 29976{
996b5569
TP
29977 ARM_CPU_OPT ("all", NULL, ARM_ANY,
29978 ARM_ARCH_NONE,
29979 FPU_ARCH_FPA),
29980 ARM_CPU_OPT ("arm1", NULL, ARM_ARCH_V1,
29981 ARM_ARCH_NONE,
29982 FPU_ARCH_FPA),
29983 ARM_CPU_OPT ("arm2", NULL, ARM_ARCH_V2,
29984 ARM_ARCH_NONE,
29985 FPU_ARCH_FPA),
29986 ARM_CPU_OPT ("arm250", NULL, ARM_ARCH_V2S,
29987 ARM_ARCH_NONE,
29988 FPU_ARCH_FPA),
29989 ARM_CPU_OPT ("arm3", NULL, ARM_ARCH_V2S,
29990 ARM_ARCH_NONE,
29991 FPU_ARCH_FPA),
29992 ARM_CPU_OPT ("arm6", NULL, ARM_ARCH_V3,
29993 ARM_ARCH_NONE,
29994 FPU_ARCH_FPA),
29995 ARM_CPU_OPT ("arm60", NULL, ARM_ARCH_V3,
29996 ARM_ARCH_NONE,
29997 FPU_ARCH_FPA),
29998 ARM_CPU_OPT ("arm600", NULL, ARM_ARCH_V3,
29999 ARM_ARCH_NONE,
30000 FPU_ARCH_FPA),
30001 ARM_CPU_OPT ("arm610", NULL, ARM_ARCH_V3,
30002 ARM_ARCH_NONE,
30003 FPU_ARCH_FPA),
30004 ARM_CPU_OPT ("arm620", NULL, ARM_ARCH_V3,
30005 ARM_ARCH_NONE,
30006 FPU_ARCH_FPA),
30007 ARM_CPU_OPT ("arm7", NULL, ARM_ARCH_V3,
30008 ARM_ARCH_NONE,
30009 FPU_ARCH_FPA),
30010 ARM_CPU_OPT ("arm7m", NULL, ARM_ARCH_V3M,
30011 ARM_ARCH_NONE,
30012 FPU_ARCH_FPA),
30013 ARM_CPU_OPT ("arm7d", NULL, ARM_ARCH_V3,
30014 ARM_ARCH_NONE,
30015 FPU_ARCH_FPA),
30016 ARM_CPU_OPT ("arm7dm", NULL, ARM_ARCH_V3M,
30017 ARM_ARCH_NONE,
30018 FPU_ARCH_FPA),
30019 ARM_CPU_OPT ("arm7di", NULL, ARM_ARCH_V3,
30020 ARM_ARCH_NONE,
30021 FPU_ARCH_FPA),
30022 ARM_CPU_OPT ("arm7dmi", NULL, ARM_ARCH_V3M,
30023 ARM_ARCH_NONE,
30024 FPU_ARCH_FPA),
30025 ARM_CPU_OPT ("arm70", NULL, ARM_ARCH_V3,
30026 ARM_ARCH_NONE,
30027 FPU_ARCH_FPA),
30028 ARM_CPU_OPT ("arm700", NULL, ARM_ARCH_V3,
30029 ARM_ARCH_NONE,
30030 FPU_ARCH_FPA),
30031 ARM_CPU_OPT ("arm700i", NULL, ARM_ARCH_V3,
30032 ARM_ARCH_NONE,
30033 FPU_ARCH_FPA),
30034 ARM_CPU_OPT ("arm710", NULL, ARM_ARCH_V3,
30035 ARM_ARCH_NONE,
30036 FPU_ARCH_FPA),
30037 ARM_CPU_OPT ("arm710t", NULL, ARM_ARCH_V4T,
30038 ARM_ARCH_NONE,
30039 FPU_ARCH_FPA),
30040 ARM_CPU_OPT ("arm720", NULL, ARM_ARCH_V3,
30041 ARM_ARCH_NONE,
30042 FPU_ARCH_FPA),
30043 ARM_CPU_OPT ("arm720t", NULL, ARM_ARCH_V4T,
30044 ARM_ARCH_NONE,
30045 FPU_ARCH_FPA),
30046 ARM_CPU_OPT ("arm740t", NULL, ARM_ARCH_V4T,
30047 ARM_ARCH_NONE,
30048 FPU_ARCH_FPA),
30049 ARM_CPU_OPT ("arm710c", NULL, ARM_ARCH_V3,
30050 ARM_ARCH_NONE,
30051 FPU_ARCH_FPA),
30052 ARM_CPU_OPT ("arm7100", NULL, ARM_ARCH_V3,
30053 ARM_ARCH_NONE,
30054 FPU_ARCH_FPA),
30055 ARM_CPU_OPT ("arm7500", NULL, ARM_ARCH_V3,
30056 ARM_ARCH_NONE,
30057 FPU_ARCH_FPA),
30058 ARM_CPU_OPT ("arm7500fe", NULL, ARM_ARCH_V3,
30059 ARM_ARCH_NONE,
30060 FPU_ARCH_FPA),
30061 ARM_CPU_OPT ("arm7t", NULL, ARM_ARCH_V4T,
30062 ARM_ARCH_NONE,
30063 FPU_ARCH_FPA),
30064 ARM_CPU_OPT ("arm7tdmi", NULL, ARM_ARCH_V4T,
30065 ARM_ARCH_NONE,
30066 FPU_ARCH_FPA),
30067 ARM_CPU_OPT ("arm7tdmi-s", NULL, ARM_ARCH_V4T,
30068 ARM_ARCH_NONE,
30069 FPU_ARCH_FPA),
30070 ARM_CPU_OPT ("arm8", NULL, ARM_ARCH_V4,
30071 ARM_ARCH_NONE,
30072 FPU_ARCH_FPA),
30073 ARM_CPU_OPT ("arm810", NULL, ARM_ARCH_V4,
30074 ARM_ARCH_NONE,
30075 FPU_ARCH_FPA),
30076 ARM_CPU_OPT ("strongarm", NULL, ARM_ARCH_V4,
30077 ARM_ARCH_NONE,
30078 FPU_ARCH_FPA),
30079 ARM_CPU_OPT ("strongarm1", NULL, ARM_ARCH_V4,
30080 ARM_ARCH_NONE,
30081 FPU_ARCH_FPA),
30082 ARM_CPU_OPT ("strongarm110", NULL, ARM_ARCH_V4,
30083 ARM_ARCH_NONE,
30084 FPU_ARCH_FPA),
30085 ARM_CPU_OPT ("strongarm1100", NULL, ARM_ARCH_V4,
30086 ARM_ARCH_NONE,
30087 FPU_ARCH_FPA),
30088 ARM_CPU_OPT ("strongarm1110", NULL, ARM_ARCH_V4,
30089 ARM_ARCH_NONE,
30090 FPU_ARCH_FPA),
30091 ARM_CPU_OPT ("arm9", NULL, ARM_ARCH_V4T,
30092 ARM_ARCH_NONE,
30093 FPU_ARCH_FPA),
30094 ARM_CPU_OPT ("arm920", "ARM920T", ARM_ARCH_V4T,
30095 ARM_ARCH_NONE,
30096 FPU_ARCH_FPA),
30097 ARM_CPU_OPT ("arm920t", NULL, ARM_ARCH_V4T,
30098 ARM_ARCH_NONE,
30099 FPU_ARCH_FPA),
30100 ARM_CPU_OPT ("arm922t", NULL, ARM_ARCH_V4T,
30101 ARM_ARCH_NONE,
30102 FPU_ARCH_FPA),
30103 ARM_CPU_OPT ("arm940t", NULL, ARM_ARCH_V4T,
30104 ARM_ARCH_NONE,
30105 FPU_ARCH_FPA),
30106 ARM_CPU_OPT ("arm9tdmi", NULL, ARM_ARCH_V4T,
30107 ARM_ARCH_NONE,
30108 FPU_ARCH_FPA),
30109 ARM_CPU_OPT ("fa526", NULL, ARM_ARCH_V4,
30110 ARM_ARCH_NONE,
30111 FPU_ARCH_FPA),
30112 ARM_CPU_OPT ("fa626", NULL, ARM_ARCH_V4,
30113 ARM_ARCH_NONE,
30114 FPU_ARCH_FPA),
30115
c19d1205
ZW
30116 /* For V5 or later processors we default to using VFP; but the user
30117 should really set the FPU type explicitly. */
996b5569
TP
30118 ARM_CPU_OPT ("arm9e-r0", NULL, ARM_ARCH_V5TExP,
30119 ARM_ARCH_NONE,
30120 FPU_ARCH_VFP_V2),
30121 ARM_CPU_OPT ("arm9e", NULL, ARM_ARCH_V5TE,
30122 ARM_ARCH_NONE,
30123 FPU_ARCH_VFP_V2),
30124 ARM_CPU_OPT ("arm926ej", "ARM926EJ-S", ARM_ARCH_V5TEJ,
30125 ARM_ARCH_NONE,
30126 FPU_ARCH_VFP_V2),
30127 ARM_CPU_OPT ("arm926ejs", "ARM926EJ-S", ARM_ARCH_V5TEJ,
30128 ARM_ARCH_NONE,
30129 FPU_ARCH_VFP_V2),
30130 ARM_CPU_OPT ("arm926ej-s", NULL, ARM_ARCH_V5TEJ,
30131 ARM_ARCH_NONE,
30132 FPU_ARCH_VFP_V2),
30133 ARM_CPU_OPT ("arm946e-r0", NULL, ARM_ARCH_V5TExP,
30134 ARM_ARCH_NONE,
30135 FPU_ARCH_VFP_V2),
30136 ARM_CPU_OPT ("arm946e", "ARM946E-S", ARM_ARCH_V5TE,
30137 ARM_ARCH_NONE,
30138 FPU_ARCH_VFP_V2),
30139 ARM_CPU_OPT ("arm946e-s", NULL, ARM_ARCH_V5TE,
30140 ARM_ARCH_NONE,
30141 FPU_ARCH_VFP_V2),
30142 ARM_CPU_OPT ("arm966e-r0", NULL, ARM_ARCH_V5TExP,
30143 ARM_ARCH_NONE,
30144 FPU_ARCH_VFP_V2),
30145 ARM_CPU_OPT ("arm966e", "ARM966E-S", ARM_ARCH_V5TE,
30146 ARM_ARCH_NONE,
30147 FPU_ARCH_VFP_V2),
30148 ARM_CPU_OPT ("arm966e-s", NULL, ARM_ARCH_V5TE,
30149 ARM_ARCH_NONE,
30150 FPU_ARCH_VFP_V2),
30151 ARM_CPU_OPT ("arm968e-s", NULL, ARM_ARCH_V5TE,
30152 ARM_ARCH_NONE,
30153 FPU_ARCH_VFP_V2),
30154 ARM_CPU_OPT ("arm10t", NULL, ARM_ARCH_V5T,
30155 ARM_ARCH_NONE,
30156 FPU_ARCH_VFP_V1),
30157 ARM_CPU_OPT ("arm10tdmi", NULL, ARM_ARCH_V5T,
30158 ARM_ARCH_NONE,
30159 FPU_ARCH_VFP_V1),
30160 ARM_CPU_OPT ("arm10e", NULL, ARM_ARCH_V5TE,
30161 ARM_ARCH_NONE,
30162 FPU_ARCH_VFP_V2),
30163 ARM_CPU_OPT ("arm1020", "ARM1020E", ARM_ARCH_V5TE,
30164 ARM_ARCH_NONE,
30165 FPU_ARCH_VFP_V2),
30166 ARM_CPU_OPT ("arm1020t", NULL, ARM_ARCH_V5T,
30167 ARM_ARCH_NONE,
30168 FPU_ARCH_VFP_V1),
30169 ARM_CPU_OPT ("arm1020e", NULL, ARM_ARCH_V5TE,
30170 ARM_ARCH_NONE,
30171 FPU_ARCH_VFP_V2),
30172 ARM_CPU_OPT ("arm1022e", NULL, ARM_ARCH_V5TE,
30173 ARM_ARCH_NONE,
30174 FPU_ARCH_VFP_V2),
30175 ARM_CPU_OPT ("arm1026ejs", "ARM1026EJ-S", ARM_ARCH_V5TEJ,
30176 ARM_ARCH_NONE,
30177 FPU_ARCH_VFP_V2),
30178 ARM_CPU_OPT ("arm1026ej-s", NULL, ARM_ARCH_V5TEJ,
30179 ARM_ARCH_NONE,
30180 FPU_ARCH_VFP_V2),
30181 ARM_CPU_OPT ("fa606te", NULL, ARM_ARCH_V5TE,
30182 ARM_ARCH_NONE,
30183 FPU_ARCH_VFP_V2),
30184 ARM_CPU_OPT ("fa616te", NULL, ARM_ARCH_V5TE,
30185 ARM_ARCH_NONE,
30186 FPU_ARCH_VFP_V2),
30187 ARM_CPU_OPT ("fa626te", NULL, ARM_ARCH_V5TE,
30188 ARM_ARCH_NONE,
30189 FPU_ARCH_VFP_V2),
30190 ARM_CPU_OPT ("fmp626", NULL, ARM_ARCH_V5TE,
30191 ARM_ARCH_NONE,
30192 FPU_ARCH_VFP_V2),
30193 ARM_CPU_OPT ("fa726te", NULL, ARM_ARCH_V5TE,
30194 ARM_ARCH_NONE,
30195 FPU_ARCH_VFP_V2),
30196 ARM_CPU_OPT ("arm1136js", "ARM1136J-S", ARM_ARCH_V6,
30197 ARM_ARCH_NONE,
30198 FPU_NONE),
30199 ARM_CPU_OPT ("arm1136j-s", NULL, ARM_ARCH_V6,
30200 ARM_ARCH_NONE,
30201 FPU_NONE),
30202 ARM_CPU_OPT ("arm1136jfs", "ARM1136JF-S", ARM_ARCH_V6,
30203 ARM_ARCH_NONE,
30204 FPU_ARCH_VFP_V2),
30205 ARM_CPU_OPT ("arm1136jf-s", NULL, ARM_ARCH_V6,
30206 ARM_ARCH_NONE,
30207 FPU_ARCH_VFP_V2),
30208 ARM_CPU_OPT ("mpcore", "MPCore", ARM_ARCH_V6K,
30209 ARM_ARCH_NONE,
30210 FPU_ARCH_VFP_V2),
30211 ARM_CPU_OPT ("mpcorenovfp", "MPCore", ARM_ARCH_V6K,
30212 ARM_ARCH_NONE,
30213 FPU_NONE),
30214 ARM_CPU_OPT ("arm1156t2-s", NULL, ARM_ARCH_V6T2,
30215 ARM_ARCH_NONE,
30216 FPU_NONE),
30217 ARM_CPU_OPT ("arm1156t2f-s", NULL, ARM_ARCH_V6T2,
30218 ARM_ARCH_NONE,
30219 FPU_ARCH_VFP_V2),
30220 ARM_CPU_OPT ("arm1176jz-s", NULL, ARM_ARCH_V6KZ,
30221 ARM_ARCH_NONE,
30222 FPU_NONE),
30223 ARM_CPU_OPT ("arm1176jzf-s", NULL, ARM_ARCH_V6KZ,
30224 ARM_ARCH_NONE,
30225 FPU_ARCH_VFP_V2),
30226 ARM_CPU_OPT ("cortex-a5", "Cortex-A5", ARM_ARCH_V7A,
30227 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
30228 FPU_NONE),
30229 ARM_CPU_OPT ("cortex-a7", "Cortex-A7", ARM_ARCH_V7VE,
30230 ARM_ARCH_NONE,
30231 FPU_ARCH_NEON_VFP_V4),
30232 ARM_CPU_OPT ("cortex-a8", "Cortex-A8", ARM_ARCH_V7A,
30233 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
30234 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
30235 ARM_CPU_OPT ("cortex-a9", "Cortex-A9", ARM_ARCH_V7A,
30236 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
30237 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
30238 ARM_CPU_OPT ("cortex-a12", "Cortex-A12", ARM_ARCH_V7VE,
30239 ARM_ARCH_NONE,
30240 FPU_ARCH_NEON_VFP_V4),
30241 ARM_CPU_OPT ("cortex-a15", "Cortex-A15", ARM_ARCH_V7VE,
30242 ARM_ARCH_NONE,
30243 FPU_ARCH_NEON_VFP_V4),
30244 ARM_CPU_OPT ("cortex-a17", "Cortex-A17", ARM_ARCH_V7VE,
30245 ARM_ARCH_NONE,
30246 FPU_ARCH_NEON_VFP_V4),
30247 ARM_CPU_OPT ("cortex-a32", "Cortex-A32", ARM_ARCH_V8A,
30248 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
30249 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
30250 ARM_CPU_OPT ("cortex-a35", "Cortex-A35", ARM_ARCH_V8A,
30251 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
30252 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
30253 ARM_CPU_OPT ("cortex-a53", "Cortex-A53", ARM_ARCH_V8A,
30254 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
30255 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
30256 ARM_CPU_OPT ("cortex-a55", "Cortex-A55", ARM_ARCH_V8_2A,
30257 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 30258 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569
TP
30259 ARM_CPU_OPT ("cortex-a57", "Cortex-A57", ARM_ARCH_V8A,
30260 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
30261 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
30262 ARM_CPU_OPT ("cortex-a72", "Cortex-A72", ARM_ARCH_V8A,
30263 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
30264 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
30265 ARM_CPU_OPT ("cortex-a73", "Cortex-A73", ARM_ARCH_V8A,
30266 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
30267 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
30268 ARM_CPU_OPT ("cortex-a75", "Cortex-A75", ARM_ARCH_V8_2A,
30269 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 30270 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
7ebd1359 30271 ARM_CPU_OPT ("cortex-a76", "Cortex-A76", ARM_ARCH_V8_2A,
30272 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
30273 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
ef8df4ca
KT
30274 ARM_CPU_OPT ("ares", "Ares", ARM_ARCH_V8_2A,
30275 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
30276 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569
TP
30277 ARM_CPU_OPT ("cortex-r4", "Cortex-R4", ARM_ARCH_V7R,
30278 ARM_ARCH_NONE,
30279 FPU_NONE),
30280 ARM_CPU_OPT ("cortex-r4f", "Cortex-R4F", ARM_ARCH_V7R,
30281 ARM_ARCH_NONE,
30282 FPU_ARCH_VFP_V3D16),
30283 ARM_CPU_OPT ("cortex-r5", "Cortex-R5", ARM_ARCH_V7R,
30284 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
30285 FPU_NONE),
30286 ARM_CPU_OPT ("cortex-r7", "Cortex-R7", ARM_ARCH_V7R,
30287 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
30288 FPU_ARCH_VFP_V3D16),
30289 ARM_CPU_OPT ("cortex-r8", "Cortex-R8", ARM_ARCH_V7R,
30290 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
30291 FPU_ARCH_VFP_V3D16),
0cda1e19
TP
30292 ARM_CPU_OPT ("cortex-r52", "Cortex-R52", ARM_ARCH_V8R,
30293 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
30294 FPU_ARCH_NEON_VFP_ARMV8),
996b5569
TP
30295 ARM_CPU_OPT ("cortex-m33", "Cortex-M33", ARM_ARCH_V8M_MAIN,
30296 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
30297 FPU_NONE),
30298 ARM_CPU_OPT ("cortex-m23", "Cortex-M23", ARM_ARCH_V8M_BASE,
30299 ARM_ARCH_NONE,
30300 FPU_NONE),
30301 ARM_CPU_OPT ("cortex-m7", "Cortex-M7", ARM_ARCH_V7EM,
30302 ARM_ARCH_NONE,
30303 FPU_NONE),
30304 ARM_CPU_OPT ("cortex-m4", "Cortex-M4", ARM_ARCH_V7EM,
30305 ARM_ARCH_NONE,
30306 FPU_NONE),
30307 ARM_CPU_OPT ("cortex-m3", "Cortex-M3", ARM_ARCH_V7M,
30308 ARM_ARCH_NONE,
30309 FPU_NONE),
30310 ARM_CPU_OPT ("cortex-m1", "Cortex-M1", ARM_ARCH_V6SM,
30311 ARM_ARCH_NONE,
30312 FPU_NONE),
30313 ARM_CPU_OPT ("cortex-m0", "Cortex-M0", ARM_ARCH_V6SM,
30314 ARM_ARCH_NONE,
30315 FPU_NONE),
30316 ARM_CPU_OPT ("cortex-m0plus", "Cortex-M0+", ARM_ARCH_V6SM,
30317 ARM_ARCH_NONE,
30318 FPU_NONE),
30319 ARM_CPU_OPT ("exynos-m1", "Samsung Exynos M1", ARM_ARCH_V8A,
30320 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
30321 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
83f43c83
KT
30322 ARM_CPU_OPT ("neoverse-n1", "Neoverse N1", ARM_ARCH_V8_2A,
30323 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
30324 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
c19d1205 30325 /* ??? XSCALE is really an architecture. */
996b5569
TP
30326 ARM_CPU_OPT ("xscale", NULL, ARM_ARCH_XSCALE,
30327 ARM_ARCH_NONE,
30328 FPU_ARCH_VFP_V2),
30329
c19d1205 30330 /* ??? iwmmxt is not a processor. */
996b5569
TP
30331 ARM_CPU_OPT ("iwmmxt", NULL, ARM_ARCH_IWMMXT,
30332 ARM_ARCH_NONE,
30333 FPU_ARCH_VFP_V2),
30334 ARM_CPU_OPT ("iwmmxt2", NULL, ARM_ARCH_IWMMXT2,
30335 ARM_ARCH_NONE,
30336 FPU_ARCH_VFP_V2),
30337 ARM_CPU_OPT ("i80200", NULL, ARM_ARCH_XSCALE,
30338 ARM_ARCH_NONE,
30339 FPU_ARCH_VFP_V2),
30340
0198d5e6 30341 /* Maverick. */
996b5569
TP
30342 ARM_CPU_OPT ("ep9312", "ARM920T",
30343 ARM_FEATURE_LOW (ARM_AEXT_V4T, ARM_CEXT_MAVERICK),
30344 ARM_ARCH_NONE, FPU_ARCH_MAVERICK),
30345
da4339ed 30346 /* Marvell processors. */
996b5569
TP
30347 ARM_CPU_OPT ("marvell-pj4", NULL, ARM_ARCH_V7A,
30348 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
30349 FPU_ARCH_VFP_V3D16),
30350 ARM_CPU_OPT ("marvell-whitney", NULL, ARM_ARCH_V7A,
30351 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
30352 FPU_ARCH_NEON_VFP_V4),
da4339ed 30353
996b5569
TP
30354 /* APM X-Gene family. */
30355 ARM_CPU_OPT ("xgene1", "APM X-Gene 1", ARM_ARCH_V8A,
30356 ARM_ARCH_NONE,
30357 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
30358 ARM_CPU_OPT ("xgene2", "APM X-Gene 2", ARM_ARCH_V8A,
30359 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
30360 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
30361
30362 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 30363};
f3bad469 30364#undef ARM_CPU_OPT
7ed4c4c5 30365
34ef62f4
AV
30366struct arm_ext_table
30367{
30368 const char * name;
30369 size_t name_len;
30370 const arm_feature_set merge;
30371 const arm_feature_set clear;
30372};
30373
c19d1205 30374struct arm_arch_option_table
7ed4c4c5 30375{
34ef62f4
AV
30376 const char * name;
30377 size_t name_len;
30378 const arm_feature_set value;
30379 const arm_feature_set default_fpu;
30380 const struct arm_ext_table * ext_table;
30381};
30382
30383/* Used to add support for +E and +noE extension. */
30384#define ARM_EXT(E, M, C) { E, sizeof (E) - 1, M, C }
30385/* Used to add support for a +E extension. */
30386#define ARM_ADD(E, M) { E, sizeof(E) - 1, M, ARM_ARCH_NONE }
30387/* Used to add support for a +noE extension. */
30388#define ARM_REMOVE(E, C) { E, sizeof(E) -1, ARM_ARCH_NONE, C }
30389
30390#define ALL_FP ARM_FEATURE (0, ARM_EXT2_FP16_INST | ARM_EXT2_FP16_FML, \
30391 ~0 & ~FPU_ENDIAN_PURE)
30392
30393static const struct arm_ext_table armv5te_ext_table[] =
30394{
30395 ARM_EXT ("fp", FPU_ARCH_VFP_V2, ALL_FP),
30396 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30397};
30398
30399static const struct arm_ext_table armv7_ext_table[] =
30400{
30401 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
30402 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30403};
30404
30405static const struct arm_ext_table armv7ve_ext_table[] =
30406{
30407 ARM_EXT ("fp", FPU_ARCH_VFP_V4D16, ALL_FP),
30408 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16),
30409 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
30410 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
30411 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
30412 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16), /* Alias for +fp. */
30413 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
30414
30415 ARM_EXT ("simd", FPU_ARCH_NEON_VFP_V4,
30416 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
30417
30418 /* Aliases for +simd. */
30419 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
30420
30421 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
30422 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
30423 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
30424
30425 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30426};
30427
30428static const struct arm_ext_table armv7a_ext_table[] =
30429{
30430 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
30431 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
30432 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
30433 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
30434 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
30435 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16),
30436 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
30437
30438 ARM_EXT ("simd", FPU_ARCH_VFP_V3_PLUS_NEON_V1,
30439 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
30440
30441 /* Aliases for +simd. */
30442 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
30443 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
30444
30445 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
30446 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
30447
30448 ARM_ADD ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP)),
30449 ARM_ADD ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC)),
30450 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30451};
30452
30453static const struct arm_ext_table armv7r_ext_table[] =
30454{
30455 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V3xD),
30456 ARM_ADD ("vfpv3xd", FPU_ARCH_VFP_V3xD), /* Alias for +fp.sp. */
30457 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
30458 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
30459 ARM_ADD ("vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16),
30460 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
30461 ARM_EXT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
30462 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV)),
30463 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30464};
30465
30466static const struct arm_ext_table armv7em_ext_table[] =
30467{
30468 ARM_EXT ("fp", FPU_ARCH_VFP_V4_SP_D16, ALL_FP),
30469 /* Alias for +fp, used to be known as fpv4-sp-d16. */
30470 ARM_ADD ("vfpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16),
30471 ARM_ADD ("fpv5", FPU_ARCH_VFP_V5_SP_D16),
30472 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
30473 ARM_ADD ("fpv5-d16", FPU_ARCH_VFP_V5D16),
30474 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30475};
30476
30477static const struct arm_ext_table armv8a_ext_table[] =
30478{
30479 ARM_ADD ("crc", ARCH_CRC_ARMV8),
30480 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
30481 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
30482 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
30483
30484 /* Armv8-a does not allow an FP implementation without SIMD, so the user
30485 should use the +simd option to turn on FP. */
30486 ARM_REMOVE ("fp", ALL_FP),
30487 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
30488 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
30489 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30490};
30491
30492
30493static const struct arm_ext_table armv81a_ext_table[] =
30494{
30495 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
30496 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
30497 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
30498
30499 /* Armv8-a does not allow an FP implementation without SIMD, so the user
30500 should use the +simd option to turn on FP. */
30501 ARM_REMOVE ("fp", ALL_FP),
30502 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
30503 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
30504 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30505};
30506
30507static const struct arm_ext_table armv82a_ext_table[] =
30508{
30509 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
30510 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_2_FP16),
30511 ARM_ADD ("fp16fml", FPU_ARCH_NEON_VFP_ARMV8_2_FP16FML),
30512 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
30513 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
30514 ARM_ADD ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
30515
30516 /* Armv8-a does not allow an FP implementation without SIMD, so the user
30517 should use the +simd option to turn on FP. */
30518 ARM_REMOVE ("fp", ALL_FP),
30519 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
30520 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
30521 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30522};
30523
30524static const struct arm_ext_table armv84a_ext_table[] =
30525{
30526 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
30527 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
30528 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
30529 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
30530
30531 /* Armv8-a does not allow an FP implementation without SIMD, so the user
30532 should use the +simd option to turn on FP. */
30533 ARM_REMOVE ("fp", ALL_FP),
30534 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
30535 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
30536 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30537};
30538
30539static const struct arm_ext_table armv85a_ext_table[] =
30540{
30541 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
30542 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
30543 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
30544 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
30545
30546 /* Armv8-a does not allow an FP implementation without SIMD, so the user
30547 should use the +simd option to turn on FP. */
30548 ARM_REMOVE ("fp", ALL_FP),
30549 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30550};
30551
30552static const struct arm_ext_table armv8m_main_ext_table[] =
30553{
30554 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
30555 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP)),
30556 ARM_EXT ("fp", FPU_ARCH_VFP_V5_SP_D16, ALL_FP),
30557 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
30558 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30559};
30560
e0991585
AV
30561static const struct arm_ext_table armv8_1m_main_ext_table[] =
30562{
30563 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
30564 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP)),
30565 ARM_EXT ("fp",
30566 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
30567 FPU_VFP_V5_SP_D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA),
30568 ALL_FP),
30569 ARM_ADD ("fp.dp",
30570 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
30571 FPU_VFP_V5D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
a7ad558c
AV
30572 ARM_EXT ("mve", ARM_FEATURE_COPROC (FPU_MVE),
30573 ARM_FEATURE_COPROC (FPU_MVE | FPU_MVE_FP)),
30574 ARM_ADD ("mve.fp",
30575 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
30576 FPU_MVE | FPU_MVE_FP | FPU_VFP_V5_SP_D16 |
30577 FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
e0991585
AV
30578 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
30579};
30580
34ef62f4
AV
30581static const struct arm_ext_table armv8r_ext_table[] =
30582{
30583 ARM_ADD ("crc", ARCH_CRC_ARMV8),
30584 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
30585 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
30586 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
30587 ARM_REMOVE ("fp", ALL_FP),
30588 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V5_SP_D16),
30589 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
c19d1205 30590};
7ed4c4c5 30591
c19d1205
ZW
30592/* This list should, at a minimum, contain all the architecture names
30593 recognized by GCC. */
34ef62f4
AV
30594#define ARM_ARCH_OPT(N, V, DF) { N, sizeof (N) - 1, V, DF, NULL }
30595#define ARM_ARCH_OPT2(N, V, DF, ext) \
30596 { N, sizeof (N) - 1, V, DF, ext##_ext_table }
0198d5e6 30597
e74cfd16 30598static const struct arm_arch_option_table arm_archs[] =
c19d1205 30599{
497d849d
TP
30600 ARM_ARCH_OPT ("all", ARM_ANY, FPU_ARCH_FPA),
30601 ARM_ARCH_OPT ("armv1", ARM_ARCH_V1, FPU_ARCH_FPA),
30602 ARM_ARCH_OPT ("armv2", ARM_ARCH_V2, FPU_ARCH_FPA),
30603 ARM_ARCH_OPT ("armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA),
30604 ARM_ARCH_OPT ("armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA),
30605 ARM_ARCH_OPT ("armv3", ARM_ARCH_V3, FPU_ARCH_FPA),
30606 ARM_ARCH_OPT ("armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA),
30607 ARM_ARCH_OPT ("armv4", ARM_ARCH_V4, FPU_ARCH_FPA),
30608 ARM_ARCH_OPT ("armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA),
30609 ARM_ARCH_OPT ("armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA),
30610 ARM_ARCH_OPT ("armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA),
30611 ARM_ARCH_OPT ("armv5", ARM_ARCH_V5, FPU_ARCH_VFP),
30612 ARM_ARCH_OPT ("armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP),
30613 ARM_ARCH_OPT ("armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP),
34ef62f4
AV
30614 ARM_ARCH_OPT2 ("armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP, armv5te),
30615 ARM_ARCH_OPT2 ("armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP, armv5te),
30616 ARM_ARCH_OPT2 ("armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP, armv5te),
30617 ARM_ARCH_OPT2 ("armv6", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
30618 ARM_ARCH_OPT2 ("armv6j", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
30619 ARM_ARCH_OPT2 ("armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP, armv5te),
30620 ARM_ARCH_OPT2 ("armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP, armv5te),
f33026a9
MW
30621 /* The official spelling of this variant is ARMv6KZ, the name "armv6zk" is
30622 kept to preserve existing behaviour. */
34ef62f4
AV
30623 ARM_ARCH_OPT2 ("armv6kz", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
30624 ARM_ARCH_OPT2 ("armv6zk", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
30625 ARM_ARCH_OPT2 ("armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP, armv5te),
30626 ARM_ARCH_OPT2 ("armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP, armv5te),
30627 ARM_ARCH_OPT2 ("armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP, armv5te),
f33026a9
MW
30628 /* The official spelling of this variant is ARMv6KZ, the name "armv6zkt2" is
30629 kept to preserve existing behaviour. */
34ef62f4
AV
30630 ARM_ARCH_OPT2 ("armv6kzt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
30631 ARM_ARCH_OPT2 ("armv6zkt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
497d849d
TP
30632 ARM_ARCH_OPT ("armv6-m", ARM_ARCH_V6M, FPU_ARCH_VFP),
30633 ARM_ARCH_OPT ("armv6s-m", ARM_ARCH_V6SM, FPU_ARCH_VFP),
34ef62f4 30634 ARM_ARCH_OPT2 ("armv7", ARM_ARCH_V7, FPU_ARCH_VFP, armv7),
c450d570
PB
30635 /* The official spelling of the ARMv7 profile variants is the dashed form.
30636 Accept the non-dashed form for compatibility with old toolchains. */
34ef62f4
AV
30637 ARM_ARCH_OPT2 ("armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
30638 ARM_ARCH_OPT2 ("armv7ve", ARM_ARCH_V7VE, FPU_ARCH_VFP, armv7ve),
30639 ARM_ARCH_OPT2 ("armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 30640 ARM_ARCH_OPT ("armv7m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4
AV
30641 ARM_ARCH_OPT2 ("armv7-a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
30642 ARM_ARCH_OPT2 ("armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 30643 ARM_ARCH_OPT ("armv7-m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4 30644 ARM_ARCH_OPT2 ("armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP, armv7em),
497d849d 30645 ARM_ARCH_OPT ("armv8-m.base", ARM_ARCH_V8M_BASE, FPU_ARCH_VFP),
34ef62f4
AV
30646 ARM_ARCH_OPT2 ("armv8-m.main", ARM_ARCH_V8M_MAIN, FPU_ARCH_VFP,
30647 armv8m_main),
e0991585
AV
30648 ARM_ARCH_OPT2 ("armv8.1-m.main", ARM_ARCH_V8_1M_MAIN, FPU_ARCH_VFP,
30649 armv8_1m_main),
34ef62f4
AV
30650 ARM_ARCH_OPT2 ("armv8-a", ARM_ARCH_V8A, FPU_ARCH_VFP, armv8a),
30651 ARM_ARCH_OPT2 ("armv8.1-a", ARM_ARCH_V8_1A, FPU_ARCH_VFP, armv81a),
30652 ARM_ARCH_OPT2 ("armv8.2-a", ARM_ARCH_V8_2A, FPU_ARCH_VFP, armv82a),
30653 ARM_ARCH_OPT2 ("armv8.3-a", ARM_ARCH_V8_3A, FPU_ARCH_VFP, armv82a),
30654 ARM_ARCH_OPT2 ("armv8-r", ARM_ARCH_V8R, FPU_ARCH_VFP, armv8r),
30655 ARM_ARCH_OPT2 ("armv8.4-a", ARM_ARCH_V8_4A, FPU_ARCH_VFP, armv84a),
30656 ARM_ARCH_OPT2 ("armv8.5-a", ARM_ARCH_V8_5A, FPU_ARCH_VFP, armv85a),
497d849d
TP
30657 ARM_ARCH_OPT ("xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP),
30658 ARM_ARCH_OPT ("iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP),
30659 ARM_ARCH_OPT ("iwmmxt2", ARM_ARCH_IWMMXT2, FPU_ARCH_VFP),
34ef62f4 30660 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 30661};
f3bad469 30662#undef ARM_ARCH_OPT
7ed4c4c5 30663
69133863 30664/* ISA extensions in the co-processor and main instruction set space. */
0198d5e6 30665
69133863 30666struct arm_option_extension_value_table
c19d1205 30667{
0198d5e6
TC
30668 const char * name;
30669 size_t name_len;
30670 const arm_feature_set merge_value;
30671 const arm_feature_set clear_value;
d942732e
TP
30672 /* List of architectures for which an extension is available. ARM_ARCH_NONE
30673 indicates that an extension is available for all architectures while
30674 ARM_ANY marks an empty entry. */
0198d5e6 30675 const arm_feature_set allowed_archs[2];
c19d1205 30676};
7ed4c4c5 30677
0198d5e6
TC
30678/* The following table must be in alphabetical order with a NULL last entry. */
30679
d942732e
TP
30680#define ARM_EXT_OPT(N, M, C, AA) { N, sizeof (N) - 1, M, C, { AA, ARM_ANY } }
30681#define ARM_EXT_OPT2(N, M, C, AA1, AA2) { N, sizeof (N) - 1, M, C, {AA1, AA2} }
0198d5e6 30682
34ef62f4
AV
30683/* DEPRECATED: Refrain from using this table to add any new extensions, instead
30684 use the context sensitive approach using arm_ext_table's. */
69133863 30685static const struct arm_option_extension_value_table arm_extensions[] =
c19d1205 30686{
823d2571
TG
30687 ARM_EXT_OPT ("crc", ARCH_CRC_ARMV8, ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
30688 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
bca38921 30689 ARM_EXT_OPT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
823d2571
TG
30690 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8),
30691 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
c604a79a
JW
30692 ARM_EXT_OPT ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8,
30693 ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD),
30694 ARM_ARCH_V8_2A),
15afaa63
TP
30695 ARM_EXT_OPT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
30696 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
30697 ARM_FEATURE_CORE (ARM_EXT_V7M, ARM_EXT2_V8M)),
823d2571
TG
30698 ARM_EXT_OPT ("fp", FPU_ARCH_VFP_ARMV8, ARM_FEATURE_COPROC (FPU_VFP_ARMV8),
30699 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
b8ec4e87
JW
30700 ARM_EXT_OPT ("fp16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
30701 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
30702 ARM_ARCH_V8_2A),
01f48020
TC
30703 ARM_EXT_OPT ("fp16fml", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
30704 | ARM_EXT2_FP16_FML),
30705 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
30706 | ARM_EXT2_FP16_FML),
30707 ARM_ARCH_V8_2A),
d942732e 30708 ARM_EXT_OPT2 ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
823d2571 30709 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
d942732e
TP
30710 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
30711 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
3d030cdb
TP
30712 /* Duplicate entry for the purpose of allowing ARMv7 to match in presence of
30713 Thumb divide instruction. Due to this having the same name as the
30714 previous entry, this will be ignored when doing command-line parsing and
30715 only considered by build attribute selection code. */
30716 ARM_EXT_OPT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
30717 ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
30718 ARM_FEATURE_CORE_LOW (ARM_EXT_V7)),
823d2571 30719 ARM_EXT_OPT ("iwmmxt",ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT),
d942732e 30720 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT), ARM_ARCH_NONE),
823d2571 30721 ARM_EXT_OPT ("iwmmxt2", ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2),
d942732e 30722 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2), ARM_ARCH_NONE),
823d2571 30723 ARM_EXT_OPT ("maverick", ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK),
d942732e
TP
30724 ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK), ARM_ARCH_NONE),
30725 ARM_EXT_OPT2 ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
823d2571 30726 ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
d942732e
TP
30727 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
30728 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
823d2571
TG
30729 ARM_EXT_OPT ("os", ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
30730 ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
30731 ARM_FEATURE_CORE_LOW (ARM_EXT_V6M)),
ddfded2f
MW
30732 ARM_EXT_OPT ("pan", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN),
30733 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_PAN, 0),
ced40572 30734 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
dad0c3bf
SD
30735 ARM_EXT_OPT ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
30736 ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
30737 ARM_ARCH_V8A),
4d1464f2
MW
30738 ARM_EXT_OPT ("ras", ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS),
30739 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_RAS, 0),
ced40572 30740 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
643afb90
MW
30741 ARM_EXT_OPT ("rdma", FPU_ARCH_NEON_VFP_ARMV8_1,
30742 ARM_FEATURE_COPROC (FPU_NEON_ARMV8 | FPU_NEON_EXT_RDMA),
ced40572 30743 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
7fadb25d
SD
30744 ARM_EXT_OPT ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
30745 ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
30746 ARM_ARCH_V8A),
d942732e 30747 ARM_EXT_OPT2 ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
823d2571 30748 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
d942732e
TP
30749 ARM_FEATURE_CORE_LOW (ARM_EXT_V6K),
30750 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
643afb90
MW
30751 ARM_EXT_OPT ("simd", FPU_ARCH_NEON_VFP_ARMV8,
30752 ARM_FEATURE_COPROC (FPU_NEON_ARMV8),
30753 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
823d2571
TG
30754 ARM_EXT_OPT ("virt", ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT | ARM_EXT_ADIV
30755 | ARM_EXT_DIV),
30756 ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT),
30757 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
30758 ARM_EXT_OPT ("xscale",ARM_FEATURE_COPROC (ARM_CEXT_XSCALE),
d942732e
TP
30759 ARM_FEATURE_COPROC (ARM_CEXT_XSCALE), ARM_ARCH_NONE),
30760 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, { ARM_ARCH_NONE, ARM_ARCH_NONE } }
69133863 30761};
f3bad469 30762#undef ARM_EXT_OPT
69133863
MGD
30763
30764/* ISA floating-point and Advanced SIMD extensions. */
30765struct arm_option_fpu_value_table
30766{
0198d5e6
TC
30767 const char * name;
30768 const arm_feature_set value;
c19d1205 30769};
7ed4c4c5 30770
c19d1205
ZW
30771/* This list should, at a minimum, contain all the fpu names
30772 recognized by GCC. */
69133863 30773static const struct arm_option_fpu_value_table arm_fpus[] =
c19d1205
ZW
30774{
30775 {"softfpa", FPU_NONE},
30776 {"fpe", FPU_ARCH_FPE},
30777 {"fpe2", FPU_ARCH_FPE},
30778 {"fpe3", FPU_ARCH_FPA}, /* Third release supports LFM/SFM. */
30779 {"fpa", FPU_ARCH_FPA},
30780 {"fpa10", FPU_ARCH_FPA},
30781 {"fpa11", FPU_ARCH_FPA},
30782 {"arm7500fe", FPU_ARCH_FPA},
30783 {"softvfp", FPU_ARCH_VFP},
30784 {"softvfp+vfp", FPU_ARCH_VFP_V2},
30785 {"vfp", FPU_ARCH_VFP_V2},
30786 {"vfp9", FPU_ARCH_VFP_V2},
d5e0ba9c 30787 {"vfp3", FPU_ARCH_VFP_V3}, /* Undocumented, use vfpv3. */
c19d1205
ZW
30788 {"vfp10", FPU_ARCH_VFP_V2},
30789 {"vfp10-r0", FPU_ARCH_VFP_V1},
30790 {"vfpxd", FPU_ARCH_VFP_V1xD},
b1cc4aeb
PB
30791 {"vfpv2", FPU_ARCH_VFP_V2},
30792 {"vfpv3", FPU_ARCH_VFP_V3},
62f3b8c8 30793 {"vfpv3-fp16", FPU_ARCH_VFP_V3_FP16},
b1cc4aeb 30794 {"vfpv3-d16", FPU_ARCH_VFP_V3D16},
62f3b8c8
PB
30795 {"vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16},
30796 {"vfpv3xd", FPU_ARCH_VFP_V3xD},
30797 {"vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16},
c19d1205
ZW
30798 {"arm1020t", FPU_ARCH_VFP_V1},
30799 {"arm1020e", FPU_ARCH_VFP_V2},
d5e0ba9c 30800 {"arm1136jfs", FPU_ARCH_VFP_V2}, /* Undocumented, use arm1136jf-s. */
c19d1205
ZW
30801 {"arm1136jf-s", FPU_ARCH_VFP_V2},
30802 {"maverick", FPU_ARCH_MAVERICK},
d5e0ba9c 30803 {"neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
d3375ddd 30804 {"neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
8e79c3df 30805 {"neon-fp16", FPU_ARCH_NEON_FP16},
62f3b8c8
PB
30806 {"vfpv4", FPU_ARCH_VFP_V4},
30807 {"vfpv4-d16", FPU_ARCH_VFP_V4D16},
ada65aa3 30808 {"fpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16},
a715796b
TG
30809 {"fpv5-d16", FPU_ARCH_VFP_V5D16},
30810 {"fpv5-sp-d16", FPU_ARCH_VFP_V5_SP_D16},
62f3b8c8 30811 {"neon-vfpv4", FPU_ARCH_NEON_VFP_V4},
bca38921
MGD
30812 {"fp-armv8", FPU_ARCH_VFP_ARMV8},
30813 {"neon-fp-armv8", FPU_ARCH_NEON_VFP_ARMV8},
30814 {"crypto-neon-fp-armv8",
30815 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8},
d6b4b13e 30816 {"neon-fp-armv8.1", FPU_ARCH_NEON_VFP_ARMV8_1},
081e4c7d
MW
30817 {"crypto-neon-fp-armv8.1",
30818 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1},
e74cfd16
PB
30819 {NULL, ARM_ARCH_NONE}
30820};
30821
30822struct arm_option_value_table
30823{
e0471c16 30824 const char *name;
e74cfd16 30825 long value;
c19d1205 30826};
7ed4c4c5 30827
e74cfd16 30828static const struct arm_option_value_table arm_float_abis[] =
c19d1205
ZW
30829{
30830 {"hard", ARM_FLOAT_ABI_HARD},
30831 {"softfp", ARM_FLOAT_ABI_SOFTFP},
30832 {"soft", ARM_FLOAT_ABI_SOFT},
e74cfd16 30833 {NULL, 0}
c19d1205 30834};
7ed4c4c5 30835
c19d1205 30836#ifdef OBJ_ELF
3a4a14e9 30837/* We only know how to output GNU and ver 4/5 (AAELF) formats. */
e74cfd16 30838static const struct arm_option_value_table arm_eabis[] =
c19d1205
ZW
30839{
30840 {"gnu", EF_ARM_EABI_UNKNOWN},
30841 {"4", EF_ARM_EABI_VER4},
3a4a14e9 30842 {"5", EF_ARM_EABI_VER5},
e74cfd16 30843 {NULL, 0}
c19d1205
ZW
30844};
30845#endif
7ed4c4c5 30846
c19d1205
ZW
30847struct arm_long_option_table
30848{
0198d5e6 30849 const char * option; /* Substring to match. */
e0471c16 30850 const char * help; /* Help information. */
17b9d67d 30851 int (* func) (const char * subopt); /* Function to decode sub-option. */
e0471c16 30852 const char * deprecated; /* If non-null, print this message. */
c19d1205 30853};
7ed4c4c5 30854
c921be7d 30855static bfd_boolean
c168ce07 30856arm_parse_extension (const char *str, const arm_feature_set *opt_set,
34ef62f4
AV
30857 arm_feature_set *ext_set,
30858 const struct arm_ext_table *ext_table)
7ed4c4c5 30859{
69133863 30860 /* We insist on extensions being specified in alphabetical order, and with
fa94de6b
RM
30861 extensions being added before being removed. We achieve this by having
30862 the global ARM_EXTENSIONS table in alphabetical order, and using the
69133863 30863 ADDING_VALUE variable to indicate whether we are adding an extension (1)
fa94de6b 30864 or removing it (0) and only allowing it to change in the order
69133863
MGD
30865 -1 -> 1 -> 0. */
30866 const struct arm_option_extension_value_table * opt = NULL;
d942732e 30867 const arm_feature_set arm_any = ARM_ANY;
69133863
MGD
30868 int adding_value = -1;
30869
c19d1205 30870 while (str != NULL && *str != 0)
7ed4c4c5 30871 {
82b8a785 30872 const char *ext;
f3bad469 30873 size_t len;
7ed4c4c5 30874
c19d1205
ZW
30875 if (*str != '+')
30876 {
30877 as_bad (_("invalid architectural extension"));
c921be7d 30878 return FALSE;
c19d1205 30879 }
7ed4c4c5 30880
c19d1205
ZW
30881 str++;
30882 ext = strchr (str, '+');
7ed4c4c5 30883
c19d1205 30884 if (ext != NULL)
f3bad469 30885 len = ext - str;
c19d1205 30886 else
f3bad469 30887 len = strlen (str);
7ed4c4c5 30888
f3bad469 30889 if (len >= 2 && strncmp (str, "no", 2) == 0)
69133863
MGD
30890 {
30891 if (adding_value != 0)
30892 {
30893 adding_value = 0;
30894 opt = arm_extensions;
30895 }
30896
f3bad469 30897 len -= 2;
69133863
MGD
30898 str += 2;
30899 }
f3bad469 30900 else if (len > 0)
69133863
MGD
30901 {
30902 if (adding_value == -1)
30903 {
30904 adding_value = 1;
30905 opt = arm_extensions;
30906 }
30907 else if (adding_value != 1)
30908 {
30909 as_bad (_("must specify extensions to add before specifying "
30910 "those to remove"));
30911 return FALSE;
30912 }
30913 }
30914
f3bad469 30915 if (len == 0)
c19d1205
ZW
30916 {
30917 as_bad (_("missing architectural extension"));
c921be7d 30918 return FALSE;
c19d1205 30919 }
7ed4c4c5 30920
69133863
MGD
30921 gas_assert (adding_value != -1);
30922 gas_assert (opt != NULL);
30923
34ef62f4
AV
30924 if (ext_table != NULL)
30925 {
30926 const struct arm_ext_table * ext_opt = ext_table;
30927 bfd_boolean found = FALSE;
30928 for (; ext_opt->name != NULL; ext_opt++)
30929 if (ext_opt->name_len == len
30930 && strncmp (ext_opt->name, str, len) == 0)
30931 {
30932 if (adding_value)
30933 {
30934 if (ARM_FEATURE_ZERO (ext_opt->merge))
30935 /* TODO: Option not supported. When we remove the
30936 legacy table this case should error out. */
30937 continue;
30938
30939 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, ext_opt->merge);
30940 }
30941 else
30942 {
30943 if (ARM_FEATURE_ZERO (ext_opt->clear))
30944 /* TODO: Option not supported. When we remove the
30945 legacy table this case should error out. */
30946 continue;
30947 ARM_CLEAR_FEATURE (*ext_set, *ext_set, ext_opt->clear);
30948 }
30949 found = TRUE;
30950 break;
30951 }
30952 if (found)
30953 {
30954 str = ext;
30955 continue;
30956 }
30957 }
30958
69133863
MGD
30959 /* Scan over the options table trying to find an exact match. */
30960 for (; opt->name != NULL; opt++)
f3bad469 30961 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 30962 {
d942732e
TP
30963 int i, nb_allowed_archs =
30964 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
69133863 30965 /* Check we can apply the extension to this architecture. */
d942732e
TP
30966 for (i = 0; i < nb_allowed_archs; i++)
30967 {
30968 /* Empty entry. */
30969 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_any))
30970 continue;
c168ce07 30971 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *opt_set))
d942732e
TP
30972 break;
30973 }
30974 if (i == nb_allowed_archs)
69133863
MGD
30975 {
30976 as_bad (_("extension does not apply to the base architecture"));
30977 return FALSE;
30978 }
30979
30980 /* Add or remove the extension. */
30981 if (adding_value)
4d354d8b 30982 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, opt->merge_value);
69133863 30983 else
4d354d8b 30984 ARM_CLEAR_FEATURE (*ext_set, *ext_set, opt->clear_value);
69133863 30985
3d030cdb
TP
30986 /* Allowing Thumb division instructions for ARMv7 in autodetection
30987 rely on this break so that duplicate extensions (extensions
30988 with the same name as a previous extension in the list) are not
30989 considered for command-line parsing. */
c19d1205
ZW
30990 break;
30991 }
7ed4c4c5 30992
c19d1205
ZW
30993 if (opt->name == NULL)
30994 {
69133863
MGD
30995 /* Did we fail to find an extension because it wasn't specified in
30996 alphabetical order, or because it does not exist? */
30997
30998 for (opt = arm_extensions; opt->name != NULL; opt++)
f3bad469 30999 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
69133863
MGD
31000 break;
31001
31002 if (opt->name == NULL)
31003 as_bad (_("unknown architectural extension `%s'"), str);
31004 else
31005 as_bad (_("architectural extensions must be specified in "
31006 "alphabetical order"));
31007
c921be7d 31008 return FALSE;
c19d1205 31009 }
69133863
MGD
31010 else
31011 {
31012 /* We should skip the extension we've just matched the next time
31013 round. */
31014 opt++;
31015 }
7ed4c4c5 31016
c19d1205
ZW
31017 str = ext;
31018 };
7ed4c4c5 31019
c921be7d 31020 return TRUE;
c19d1205 31021}
7ed4c4c5 31022
c921be7d 31023static bfd_boolean
17b9d67d 31024arm_parse_cpu (const char *str)
7ed4c4c5 31025{
f3bad469 31026 const struct arm_cpu_option_table *opt;
82b8a785 31027 const char *ext = strchr (str, '+');
f3bad469 31028 size_t len;
7ed4c4c5 31029
c19d1205 31030 if (ext != NULL)
f3bad469 31031 len = ext - str;
7ed4c4c5 31032 else
f3bad469 31033 len = strlen (str);
7ed4c4c5 31034
f3bad469 31035 if (len == 0)
7ed4c4c5 31036 {
c19d1205 31037 as_bad (_("missing cpu name `%s'"), str);
c921be7d 31038 return FALSE;
7ed4c4c5
NC
31039 }
31040
c19d1205 31041 for (opt = arm_cpus; opt->name != NULL; opt++)
f3bad469 31042 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 31043 {
c168ce07 31044 mcpu_cpu_opt = &opt->value;
4d354d8b
TP
31045 if (mcpu_ext_opt == NULL)
31046 mcpu_ext_opt = XNEW (arm_feature_set);
31047 *mcpu_ext_opt = opt->ext;
e74cfd16 31048 mcpu_fpu_opt = &opt->default_fpu;
ee065d83 31049 if (opt->canonical_name)
ef8e6722
JW
31050 {
31051 gas_assert (sizeof selected_cpu_name > strlen (opt->canonical_name));
31052 strcpy (selected_cpu_name, opt->canonical_name);
31053 }
ee065d83
PB
31054 else
31055 {
f3bad469 31056 size_t i;
c921be7d 31057
ef8e6722
JW
31058 if (len >= sizeof selected_cpu_name)
31059 len = (sizeof selected_cpu_name) - 1;
31060
f3bad469 31061 for (i = 0; i < len; i++)
ee065d83
PB
31062 selected_cpu_name[i] = TOUPPER (opt->name[i]);
31063 selected_cpu_name[i] = 0;
31064 }
7ed4c4c5 31065
c19d1205 31066 if (ext != NULL)
34ef62f4 31067 return arm_parse_extension (ext, mcpu_cpu_opt, mcpu_ext_opt, NULL);
7ed4c4c5 31068
c921be7d 31069 return TRUE;
c19d1205 31070 }
7ed4c4c5 31071
c19d1205 31072 as_bad (_("unknown cpu `%s'"), str);
c921be7d 31073 return FALSE;
7ed4c4c5
NC
31074}
31075
c921be7d 31076static bfd_boolean
17b9d67d 31077arm_parse_arch (const char *str)
7ed4c4c5 31078{
e74cfd16 31079 const struct arm_arch_option_table *opt;
82b8a785 31080 const char *ext = strchr (str, '+');
f3bad469 31081 size_t len;
7ed4c4c5 31082
c19d1205 31083 if (ext != NULL)
f3bad469 31084 len = ext - str;
7ed4c4c5 31085 else
f3bad469 31086 len = strlen (str);
7ed4c4c5 31087
f3bad469 31088 if (len == 0)
7ed4c4c5 31089 {
c19d1205 31090 as_bad (_("missing architecture name `%s'"), str);
c921be7d 31091 return FALSE;
7ed4c4c5
NC
31092 }
31093
c19d1205 31094 for (opt = arm_archs; opt->name != NULL; opt++)
f3bad469 31095 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 31096 {
e74cfd16 31097 march_cpu_opt = &opt->value;
4d354d8b
TP
31098 if (march_ext_opt == NULL)
31099 march_ext_opt = XNEW (arm_feature_set);
31100 *march_ext_opt = arm_arch_none;
e74cfd16 31101 march_fpu_opt = &opt->default_fpu;
5f4273c7 31102 strcpy (selected_cpu_name, opt->name);
7ed4c4c5 31103
c19d1205 31104 if (ext != NULL)
34ef62f4
AV
31105 return arm_parse_extension (ext, march_cpu_opt, march_ext_opt,
31106 opt->ext_table);
7ed4c4c5 31107
c921be7d 31108 return TRUE;
c19d1205
ZW
31109 }
31110
31111 as_bad (_("unknown architecture `%s'\n"), str);
c921be7d 31112 return FALSE;
7ed4c4c5 31113}
eb043451 31114
c921be7d 31115static bfd_boolean
17b9d67d 31116arm_parse_fpu (const char * str)
c19d1205 31117{
69133863 31118 const struct arm_option_fpu_value_table * opt;
b99bd4ef 31119
c19d1205
ZW
31120 for (opt = arm_fpus; opt->name != NULL; opt++)
31121 if (streq (opt->name, str))
31122 {
e74cfd16 31123 mfpu_opt = &opt->value;
c921be7d 31124 return TRUE;
c19d1205 31125 }
b99bd4ef 31126
c19d1205 31127 as_bad (_("unknown floating point format `%s'\n"), str);
c921be7d 31128 return FALSE;
c19d1205
ZW
31129}
31130
c921be7d 31131static bfd_boolean
17b9d67d 31132arm_parse_float_abi (const char * str)
b99bd4ef 31133{
e74cfd16 31134 const struct arm_option_value_table * opt;
b99bd4ef 31135
c19d1205
ZW
31136 for (opt = arm_float_abis; opt->name != NULL; opt++)
31137 if (streq (opt->name, str))
31138 {
31139 mfloat_abi_opt = opt->value;
c921be7d 31140 return TRUE;
c19d1205 31141 }
cc8a6dd0 31142
c19d1205 31143 as_bad (_("unknown floating point abi `%s'\n"), str);
c921be7d 31144 return FALSE;
c19d1205 31145}
b99bd4ef 31146
c19d1205 31147#ifdef OBJ_ELF
c921be7d 31148static bfd_boolean
17b9d67d 31149arm_parse_eabi (const char * str)
c19d1205 31150{
e74cfd16 31151 const struct arm_option_value_table *opt;
cc8a6dd0 31152
c19d1205
ZW
31153 for (opt = arm_eabis; opt->name != NULL; opt++)
31154 if (streq (opt->name, str))
31155 {
31156 meabi_flags = opt->value;
c921be7d 31157 return TRUE;
c19d1205
ZW
31158 }
31159 as_bad (_("unknown EABI `%s'\n"), str);
c921be7d 31160 return FALSE;
c19d1205
ZW
31161}
31162#endif
cc8a6dd0 31163
c921be7d 31164static bfd_boolean
17b9d67d 31165arm_parse_it_mode (const char * str)
e07e6e58 31166{
c921be7d 31167 bfd_boolean ret = TRUE;
e07e6e58
NC
31168
31169 if (streq ("arm", str))
31170 implicit_it_mode = IMPLICIT_IT_MODE_ARM;
31171 else if (streq ("thumb", str))
31172 implicit_it_mode = IMPLICIT_IT_MODE_THUMB;
31173 else if (streq ("always", str))
31174 implicit_it_mode = IMPLICIT_IT_MODE_ALWAYS;
31175 else if (streq ("never", str))
31176 implicit_it_mode = IMPLICIT_IT_MODE_NEVER;
31177 else
31178 {
31179 as_bad (_("unknown implicit IT mode `%s', should be "\
477330fc 31180 "arm, thumb, always, or never."), str);
c921be7d 31181 ret = FALSE;
e07e6e58
NC
31182 }
31183
31184 return ret;
31185}
31186
2e6976a8 31187static bfd_boolean
17b9d67d 31188arm_ccs_mode (const char * unused ATTRIBUTE_UNUSED)
2e6976a8
DG
31189{
31190 codecomposer_syntax = TRUE;
31191 arm_comment_chars[0] = ';';
31192 arm_line_separator_chars[0] = 0;
31193 return TRUE;
31194}
31195
c19d1205
ZW
31196struct arm_long_option_table arm_long_opts[] =
31197{
31198 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
31199 arm_parse_cpu, NULL},
31200 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
31201 arm_parse_arch, NULL},
31202 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
31203 arm_parse_fpu, NULL},
31204 {"mfloat-abi=", N_("<abi>\t assemble for floating point ABI <abi>"),
31205 arm_parse_float_abi, NULL},
31206#ifdef OBJ_ELF
7fac0536 31207 {"meabi=", N_("<ver>\t\t assemble for eabi version <ver>"),
c19d1205
ZW
31208 arm_parse_eabi, NULL},
31209#endif
e07e6e58
NC
31210 {"mimplicit-it=", N_("<mode>\t controls implicit insertion of IT instructions"),
31211 arm_parse_it_mode, NULL},
2e6976a8
DG
31212 {"mccs", N_("\t\t\t TI CodeComposer Studio syntax compatibility mode"),
31213 arm_ccs_mode, NULL},
c19d1205
ZW
31214 {NULL, NULL, 0, NULL}
31215};
cc8a6dd0 31216
c19d1205 31217int
17b9d67d 31218md_parse_option (int c, const char * arg)
c19d1205
ZW
31219{
31220 struct arm_option_table *opt;
e74cfd16 31221 const struct arm_legacy_option_table *fopt;
c19d1205 31222 struct arm_long_option_table *lopt;
b99bd4ef 31223
c19d1205 31224 switch (c)
b99bd4ef 31225 {
c19d1205
ZW
31226#ifdef OPTION_EB
31227 case OPTION_EB:
31228 target_big_endian = 1;
31229 break;
31230#endif
cc8a6dd0 31231
c19d1205
ZW
31232#ifdef OPTION_EL
31233 case OPTION_EL:
31234 target_big_endian = 0;
31235 break;
31236#endif
b99bd4ef 31237
845b51d6
PB
31238 case OPTION_FIX_V4BX:
31239 fix_v4bx = TRUE;
31240 break;
31241
18a20338
CL
31242#ifdef OBJ_ELF
31243 case OPTION_FDPIC:
31244 arm_fdpic = TRUE;
31245 break;
31246#endif /* OBJ_ELF */
31247
c19d1205
ZW
31248 case 'a':
31249 /* Listing option. Just ignore these, we don't support additional
31250 ones. */
31251 return 0;
b99bd4ef 31252
c19d1205
ZW
31253 default:
31254 for (opt = arm_opts; opt->option != NULL; opt++)
31255 {
31256 if (c == opt->option[0]
31257 && ((arg == NULL && opt->option[1] == 0)
31258 || streq (arg, opt->option + 1)))
31259 {
c19d1205 31260 /* If the option is deprecated, tell the user. */
278df34e 31261 if (warn_on_deprecated && opt->deprecated != NULL)
c19d1205
ZW
31262 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
31263 arg ? arg : "", _(opt->deprecated));
b99bd4ef 31264
c19d1205
ZW
31265 if (opt->var != NULL)
31266 *opt->var = opt->value;
cc8a6dd0 31267
c19d1205
ZW
31268 return 1;
31269 }
31270 }
b99bd4ef 31271
e74cfd16
PB
31272 for (fopt = arm_legacy_opts; fopt->option != NULL; fopt++)
31273 {
31274 if (c == fopt->option[0]
31275 && ((arg == NULL && fopt->option[1] == 0)
31276 || streq (arg, fopt->option + 1)))
31277 {
e74cfd16 31278 /* If the option is deprecated, tell the user. */
278df34e 31279 if (warn_on_deprecated && fopt->deprecated != NULL)
e74cfd16
PB
31280 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
31281 arg ? arg : "", _(fopt->deprecated));
e74cfd16
PB
31282
31283 if (fopt->var != NULL)
31284 *fopt->var = &fopt->value;
31285
31286 return 1;
31287 }
31288 }
31289
c19d1205
ZW
31290 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
31291 {
31292 /* These options are expected to have an argument. */
31293 if (c == lopt->option[0]
31294 && arg != NULL
31295 && strncmp (arg, lopt->option + 1,
31296 strlen (lopt->option + 1)) == 0)
31297 {
c19d1205 31298 /* If the option is deprecated, tell the user. */
278df34e 31299 if (warn_on_deprecated && lopt->deprecated != NULL)
c19d1205
ZW
31300 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
31301 _(lopt->deprecated));
b99bd4ef 31302
c19d1205
ZW
31303 /* Call the sup-option parser. */
31304 return lopt->func (arg + strlen (lopt->option) - 1);
31305 }
31306 }
a737bd4d 31307
c19d1205
ZW
31308 return 0;
31309 }
a394c00f 31310
c19d1205
ZW
31311 return 1;
31312}
a394c00f 31313
c19d1205
ZW
31314void
31315md_show_usage (FILE * fp)
a394c00f 31316{
c19d1205
ZW
31317 struct arm_option_table *opt;
31318 struct arm_long_option_table *lopt;
a394c00f 31319
c19d1205 31320 fprintf (fp, _(" ARM-specific assembler options:\n"));
a394c00f 31321
c19d1205
ZW
31322 for (opt = arm_opts; opt->option != NULL; opt++)
31323 if (opt->help != NULL)
31324 fprintf (fp, " -%-23s%s\n", opt->option, _(opt->help));
a394c00f 31325
c19d1205
ZW
31326 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
31327 if (lopt->help != NULL)
31328 fprintf (fp, " -%s%s\n", lopt->option, _(lopt->help));
a394c00f 31329
c19d1205
ZW
31330#ifdef OPTION_EB
31331 fprintf (fp, _("\
31332 -EB assemble code for a big-endian cpu\n"));
a394c00f
NC
31333#endif
31334
c19d1205
ZW
31335#ifdef OPTION_EL
31336 fprintf (fp, _("\
31337 -EL assemble code for a little-endian cpu\n"));
a737bd4d 31338#endif
845b51d6
PB
31339
31340 fprintf (fp, _("\
31341 --fix-v4bx Allow BX in ARMv4 code\n"));
18a20338
CL
31342
31343#ifdef OBJ_ELF
31344 fprintf (fp, _("\
31345 --fdpic generate an FDPIC object file\n"));
31346#endif /* OBJ_ELF */
c19d1205 31347}
ee065d83 31348
ee065d83 31349#ifdef OBJ_ELF
0198d5e6 31350
62b3e311
PB
31351typedef struct
31352{
31353 int val;
31354 arm_feature_set flags;
31355} cpu_arch_ver_table;
31356
2c6b98ea
TP
31357/* Mapping from CPU features to EABI CPU arch values. Table must be sorted
31358 chronologically for architectures, with an exception for ARMv6-M and
31359 ARMv6S-M due to legacy reasons. No new architecture should have a
31360 special case. This allows for build attribute selection results to be
31361 stable when new architectures are added. */
62b3e311
PB
31362static const cpu_arch_ver_table cpu_arch_ver[] =
31363{
031254f2
AV
31364 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V1},
31365 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2},
31366 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2S},
31367 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3},
31368 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3M},
31369 {TAG_CPU_ARCH_V4, ARM_ARCH_V4xM},
31370 {TAG_CPU_ARCH_V4, ARM_ARCH_V4},
31371 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4TxM},
31372 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4T},
31373 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5xM},
31374 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5},
31375 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5TxM},
31376 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5T},
31377 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TExP},
31378 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TE},
31379 {TAG_CPU_ARCH_V5TEJ, ARM_ARCH_V5TEJ},
31380 {TAG_CPU_ARCH_V6, ARM_ARCH_V6},
31381 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6Z},
31382 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6KZ},
31383 {TAG_CPU_ARCH_V6K, ARM_ARCH_V6K},
31384 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6T2},
31385 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KT2},
31386 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6ZT2},
31387 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KZT2},
2c6b98ea
TP
31388
31389 /* When assembling a file with only ARMv6-M or ARMv6S-M instruction, GNU as
31390 always selected build attributes to match those of ARMv6-M
31391 (resp. ARMv6S-M). However, due to these architectures being a strict
31392 subset of ARMv7-M in terms of instructions available, ARMv7-M attributes
31393 would be selected when fully respecting chronology of architectures.
31394 It is thus necessary to make a special case of ARMv6-M and ARMv6S-M and
31395 move them before ARMv7 architectures. */
031254f2
AV
31396 {TAG_CPU_ARCH_V6_M, ARM_ARCH_V6M},
31397 {TAG_CPU_ARCH_V6S_M, ARM_ARCH_V6SM},
31398
31399 {TAG_CPU_ARCH_V7, ARM_ARCH_V7},
31400 {TAG_CPU_ARCH_V7, ARM_ARCH_V7A},
31401 {TAG_CPU_ARCH_V7, ARM_ARCH_V7R},
31402 {TAG_CPU_ARCH_V7, ARM_ARCH_V7M},
31403 {TAG_CPU_ARCH_V7, ARM_ARCH_V7VE},
31404 {TAG_CPU_ARCH_V7E_M, ARM_ARCH_V7EM},
31405 {TAG_CPU_ARCH_V8, ARM_ARCH_V8A},
31406 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_1A},
31407 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_2A},
31408 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_3A},
31409 {TAG_CPU_ARCH_V8M_BASE, ARM_ARCH_V8M_BASE},
31410 {TAG_CPU_ARCH_V8M_MAIN, ARM_ARCH_V8M_MAIN},
31411 {TAG_CPU_ARCH_V8R, ARM_ARCH_V8R},
31412 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_4A},
31413 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_5A},
31414 {TAG_CPU_ARCH_V8_1M_MAIN, ARM_ARCH_V8_1M_MAIN},
31415 {-1, ARM_ARCH_NONE}
62b3e311
PB
31416};
31417
ee3c0378 31418/* Set an attribute if it has not already been set by the user. */
0198d5e6 31419
ee3c0378
AS
31420static void
31421aeabi_set_attribute_int (int tag, int value)
31422{
31423 if (tag < 1
31424 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
31425 || !attributes_set_explicitly[tag])
31426 bfd_elf_add_proc_attr_int (stdoutput, tag, value);
31427}
31428
31429static void
31430aeabi_set_attribute_string (int tag, const char *value)
31431{
31432 if (tag < 1
31433 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
31434 || !attributes_set_explicitly[tag])
31435 bfd_elf_add_proc_attr_string (stdoutput, tag, value);
31436}
31437
2c6b98ea
TP
31438/* Return whether features in the *NEEDED feature set are available via
31439 extensions for the architecture whose feature set is *ARCH_FSET. */
0198d5e6 31440
2c6b98ea
TP
31441static bfd_boolean
31442have_ext_for_needed_feat_p (const arm_feature_set *arch_fset,
31443 const arm_feature_set *needed)
31444{
31445 int i, nb_allowed_archs;
31446 arm_feature_set ext_fset;
31447 const struct arm_option_extension_value_table *opt;
31448
31449 ext_fset = arm_arch_none;
31450 for (opt = arm_extensions; opt->name != NULL; opt++)
31451 {
31452 /* Extension does not provide any feature we need. */
31453 if (!ARM_CPU_HAS_FEATURE (*needed, opt->merge_value))
31454 continue;
31455
31456 nb_allowed_archs =
31457 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
31458 for (i = 0; i < nb_allowed_archs; i++)
31459 {
31460 /* Empty entry. */
31461 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_arch_any))
31462 break;
31463
31464 /* Extension is available, add it. */
31465 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *arch_fset))
31466 ARM_MERGE_FEATURE_SETS (ext_fset, ext_fset, opt->merge_value);
31467 }
31468 }
31469
31470 /* Can we enable all features in *needed? */
31471 return ARM_FSET_CPU_SUBSET (*needed, ext_fset);
31472}
31473
31474/* Select value for Tag_CPU_arch and Tag_CPU_arch_profile build attributes for
31475 a given architecture feature set *ARCH_EXT_FSET including extension feature
31476 set *EXT_FSET. Selection logic used depend on EXACT_MATCH:
31477 - if true, check for an exact match of the architecture modulo extensions;
31478 - otherwise, select build attribute value of the first superset
31479 architecture released so that results remains stable when new architectures
31480 are added.
31481 For -march/-mcpu=all the build attribute value of the most featureful
31482 architecture is returned. Tag_CPU_arch_profile result is returned in
31483 PROFILE. */
0198d5e6 31484
2c6b98ea
TP
31485static int
31486get_aeabi_cpu_arch_from_fset (const arm_feature_set *arch_ext_fset,
31487 const arm_feature_set *ext_fset,
31488 char *profile, int exact_match)
31489{
31490 arm_feature_set arch_fset;
31491 const cpu_arch_ver_table *p_ver, *p_ver_ret = NULL;
31492
31493 /* Select most featureful architecture with all its extensions if building
31494 for -march=all as the feature sets used to set build attributes. */
31495 if (ARM_FEATURE_EQUAL (*arch_ext_fset, arm_arch_any))
31496 {
31497 /* Force revisiting of decision for each new architecture. */
031254f2 31498 gas_assert (MAX_TAG_CPU_ARCH <= TAG_CPU_ARCH_V8_1M_MAIN);
2c6b98ea
TP
31499 *profile = 'A';
31500 return TAG_CPU_ARCH_V8;
31501 }
31502
31503 ARM_CLEAR_FEATURE (arch_fset, *arch_ext_fset, *ext_fset);
31504
31505 for (p_ver = cpu_arch_ver; p_ver->val != -1; p_ver++)
31506 {
31507 arm_feature_set known_arch_fset;
31508
31509 ARM_CLEAR_FEATURE (known_arch_fset, p_ver->flags, fpu_any);
31510 if (exact_match)
31511 {
31512 /* Base architecture match user-specified architecture and
31513 extensions, eg. ARMv6S-M matching -march=armv6-m+os. */
31514 if (ARM_FEATURE_EQUAL (*arch_ext_fset, known_arch_fset))
31515 {
31516 p_ver_ret = p_ver;
31517 goto found;
31518 }
31519 /* Base architecture match user-specified architecture only
31520 (eg. ARMv6-M in the same case as above). Record it in case we
31521 find a match with above condition. */
31522 else if (p_ver_ret == NULL
31523 && ARM_FEATURE_EQUAL (arch_fset, known_arch_fset))
31524 p_ver_ret = p_ver;
31525 }
31526 else
31527 {
31528
31529 /* Architecture has all features wanted. */
31530 if (ARM_FSET_CPU_SUBSET (arch_fset, known_arch_fset))
31531 {
31532 arm_feature_set added_fset;
31533
31534 /* Compute features added by this architecture over the one
31535 recorded in p_ver_ret. */
31536 if (p_ver_ret != NULL)
31537 ARM_CLEAR_FEATURE (added_fset, known_arch_fset,
31538 p_ver_ret->flags);
31539 /* First architecture that match incl. with extensions, or the
31540 only difference in features over the recorded match is
31541 features that were optional and are now mandatory. */
31542 if (p_ver_ret == NULL
31543 || ARM_FSET_CPU_SUBSET (added_fset, arch_fset))
31544 {
31545 p_ver_ret = p_ver;
31546 goto found;
31547 }
31548 }
31549 else if (p_ver_ret == NULL)
31550 {
31551 arm_feature_set needed_ext_fset;
31552
31553 ARM_CLEAR_FEATURE (needed_ext_fset, arch_fset, known_arch_fset);
31554
31555 /* Architecture has all features needed when using some
31556 extensions. Record it and continue searching in case there
31557 exist an architecture providing all needed features without
31558 the need for extensions (eg. ARMv6S-M Vs ARMv6-M with
31559 OS extension). */
31560 if (have_ext_for_needed_feat_p (&known_arch_fset,
31561 &needed_ext_fset))
31562 p_ver_ret = p_ver;
31563 }
31564 }
31565 }
31566
31567 if (p_ver_ret == NULL)
31568 return -1;
31569
31570found:
31571 /* Tag_CPU_arch_profile. */
31572 if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7a)
31573 || ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8)
31574 || (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_atomics)
31575 && !ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8m_m_only)))
31576 *profile = 'A';
31577 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7r))
31578 *profile = 'R';
31579 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_m))
31580 *profile = 'M';
31581 else
31582 *profile = '\0';
31583 return p_ver_ret->val;
31584}
31585
ee065d83 31586/* Set the public EABI object attributes. */
0198d5e6 31587
c168ce07 31588static void
ee065d83
PB
31589aeabi_set_public_attributes (void)
31590{
b90d5ba0 31591 char profile = '\0';
2c6b98ea 31592 int arch = -1;
90ec0d68 31593 int virt_sec = 0;
bca38921 31594 int fp16_optional = 0;
2c6b98ea
TP
31595 int skip_exact_match = 0;
31596 arm_feature_set flags, flags_arch, flags_ext;
ee065d83 31597
54bab281
TP
31598 /* Autodetection mode, choose the architecture based the instructions
31599 actually used. */
31600 if (no_cpu_selected ())
31601 {
31602 ARM_MERGE_FEATURE_SETS (flags, arm_arch_used, thumb_arch_used);
ddd7f988 31603
54bab281
TP
31604 if (ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any))
31605 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v1);
ddd7f988 31606
54bab281
TP
31607 if (ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_any))
31608 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v4t);
ddd7f988 31609
54bab281 31610 /* Code run during relaxation relies on selected_cpu being set. */
4d354d8b
TP
31611 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
31612 flags_ext = arm_arch_none;
31613 ARM_CLEAR_FEATURE (selected_arch, flags_arch, flags_ext);
31614 selected_ext = flags_ext;
54bab281
TP
31615 selected_cpu = flags;
31616 }
31617 /* Otherwise, choose the architecture based on the capabilities of the
31618 requested cpu. */
31619 else
4d354d8b
TP
31620 {
31621 ARM_MERGE_FEATURE_SETS (flags_arch, selected_arch, selected_ext);
31622 ARM_CLEAR_FEATURE (flags_arch, flags_arch, fpu_any);
31623 flags_ext = selected_ext;
31624 flags = selected_cpu;
31625 }
31626 ARM_MERGE_FEATURE_SETS (flags, flags, selected_fpu);
7f78eb34 31627
ddd7f988 31628 /* Allow the user to override the reported architecture. */
4d354d8b 31629 if (!ARM_FEATURE_ZERO (selected_object_arch))
7a1d4c38 31630 {
4d354d8b 31631 ARM_CLEAR_FEATURE (flags_arch, selected_object_arch, fpu_any);
2c6b98ea 31632 flags_ext = arm_arch_none;
7a1d4c38 31633 }
2c6b98ea 31634 else
4d354d8b 31635 skip_exact_match = ARM_FEATURE_EQUAL (selected_cpu, arm_arch_any);
2c6b98ea
TP
31636
31637 /* When this function is run again after relaxation has happened there is no
31638 way to determine whether an architecture or CPU was specified by the user:
31639 - selected_cpu is set above for relaxation to work;
31640 - march_cpu_opt is not set if only -mcpu or .cpu is used;
31641 - mcpu_cpu_opt is set to arm_arch_any for autodetection.
31642 Therefore, if not in -march=all case we first try an exact match and fall
31643 back to autodetection. */
31644 if (!skip_exact_match)
31645 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 1);
31646 if (arch == -1)
31647 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 0);
31648 if (arch == -1)
31649 as_bad (_("no architecture contains all the instructions used\n"));
9e3c6df6 31650
ee065d83
PB
31651 /* Tag_CPU_name. */
31652 if (selected_cpu_name[0])
31653 {
91d6fa6a 31654 char *q;
ee065d83 31655
91d6fa6a
NC
31656 q = selected_cpu_name;
31657 if (strncmp (q, "armv", 4) == 0)
ee065d83
PB
31658 {
31659 int i;
5f4273c7 31660
91d6fa6a
NC
31661 q += 4;
31662 for (i = 0; q[i]; i++)
31663 q[i] = TOUPPER (q[i]);
ee065d83 31664 }
91d6fa6a 31665 aeabi_set_attribute_string (Tag_CPU_name, q);
ee065d83 31666 }
62f3b8c8 31667
ee065d83 31668 /* Tag_CPU_arch. */
ee3c0378 31669 aeabi_set_attribute_int (Tag_CPU_arch, arch);
62f3b8c8 31670
62b3e311 31671 /* Tag_CPU_arch_profile. */
69239280
MGD
31672 if (profile != '\0')
31673 aeabi_set_attribute_int (Tag_CPU_arch_profile, profile);
62f3b8c8 31674
15afaa63 31675 /* Tag_DSP_extension. */
4d354d8b 31676 if (ARM_CPU_HAS_FEATURE (selected_ext, arm_ext_dsp))
6c290d53 31677 aeabi_set_attribute_int (Tag_DSP_extension, 1);
15afaa63 31678
2c6b98ea 31679 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
ee065d83 31680 /* Tag_ARM_ISA_use. */
ee3c0378 31681 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v1)
2c6b98ea 31682 || ARM_FEATURE_ZERO (flags_arch))
ee3c0378 31683 aeabi_set_attribute_int (Tag_ARM_ISA_use, 1);
62f3b8c8 31684
ee065d83 31685 /* Tag_THUMB_ISA_use. */
ee3c0378 31686 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v4t)
2c6b98ea 31687 || ARM_FEATURE_ZERO (flags_arch))
4ed7ed8d
TP
31688 {
31689 int thumb_isa_use;
31690
31691 if (!ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
16a1fa25 31692 && ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m_m_only))
4ed7ed8d
TP
31693 thumb_isa_use = 3;
31694 else if (ARM_CPU_HAS_FEATURE (flags, arm_arch_t2))
31695 thumb_isa_use = 2;
31696 else
31697 thumb_isa_use = 1;
31698 aeabi_set_attribute_int (Tag_THUMB_ISA_use, thumb_isa_use);
31699 }
62f3b8c8 31700
ee065d83 31701 /* Tag_VFP_arch. */
a715796b
TG
31702 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_armv8xd))
31703 aeabi_set_attribute_int (Tag_VFP_arch,
31704 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
31705 ? 7 : 8);
bca38921 31706 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_fma))
62f3b8c8
PB
31707 aeabi_set_attribute_int (Tag_VFP_arch,
31708 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
31709 ? 5 : 6);
31710 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32))
bca38921
MGD
31711 {
31712 fp16_optional = 1;
31713 aeabi_set_attribute_int (Tag_VFP_arch, 3);
31714 }
ada65aa3 31715 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v3xd))
bca38921
MGD
31716 {
31717 aeabi_set_attribute_int (Tag_VFP_arch, 4);
31718 fp16_optional = 1;
31719 }
ee3c0378
AS
31720 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v2))
31721 aeabi_set_attribute_int (Tag_VFP_arch, 2);
31722 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1)
477330fc 31723 || ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd))
ee3c0378 31724 aeabi_set_attribute_int (Tag_VFP_arch, 1);
62f3b8c8 31725
4547cb56
NC
31726 /* Tag_ABI_HardFP_use. */
31727 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd)
31728 && !ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1))
31729 aeabi_set_attribute_int (Tag_ABI_HardFP_use, 1);
31730
ee065d83 31731 /* Tag_WMMX_arch. */
ee3c0378
AS
31732 if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt2))
31733 aeabi_set_attribute_int (Tag_WMMX_arch, 2);
31734 else if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt))
31735 aeabi_set_attribute_int (Tag_WMMX_arch, 1);
62f3b8c8 31736
ee3c0378 31737 /* Tag_Advanced_SIMD_arch (formerly Tag_NEON_arch). */
9411fd44
MW
31738 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v8_1))
31739 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 4);
31740 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_armv8))
bca38921
MGD
31741 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 3);
31742 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v1))
31743 {
31744 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_fma))
31745 {
31746 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 2);
31747 }
31748 else
31749 {
31750 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 1);
31751 fp16_optional = 1;
31752 }
31753 }
fa94de6b 31754
a7ad558c
AV
31755 if (ARM_CPU_HAS_FEATURE (flags, mve_fp_ext))
31756 aeabi_set_attribute_int (Tag_MVE_arch, 2);
31757 else if (ARM_CPU_HAS_FEATURE (flags, mve_ext))
31758 aeabi_set_attribute_int (Tag_MVE_arch, 1);
31759
ee3c0378 31760 /* Tag_VFP_HP_extension (formerly Tag_NEON_FP16_arch). */
bca38921 31761 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_fp16) && fp16_optional)
ee3c0378 31762 aeabi_set_attribute_int (Tag_VFP_HP_extension, 1);
4547cb56 31763
69239280
MGD
31764 /* Tag_DIV_use.
31765
31766 We set Tag_DIV_use to two when integer divide instructions have been used
31767 in ARM state, or when Thumb integer divide instructions have been used,
31768 but we have no architecture profile set, nor have we any ARM instructions.
31769
4ed7ed8d
TP
31770 For ARMv8-A and ARMv8-M we set the tag to 0 as integer divide is implied
31771 by the base architecture.
bca38921 31772
69239280 31773 For new architectures we will have to check these tests. */
031254f2 31774 gas_assert (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
4ed7ed8d
TP
31775 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
31776 || ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m))
bca38921
MGD
31777 aeabi_set_attribute_int (Tag_DIV_use, 0);
31778 else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_adiv)
31779 || (profile == '\0'
31780 && ARM_CPU_HAS_FEATURE (flags, arm_ext_div)
31781 && !ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any)))
eea54501 31782 aeabi_set_attribute_int (Tag_DIV_use, 2);
60e5ef9f
MGD
31783
31784 /* Tag_MP_extension_use. */
31785 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_mp))
31786 aeabi_set_attribute_int (Tag_MPextension_use, 1);
f4c65163
MGD
31787
31788 /* Tag Virtualization_use. */
31789 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_sec))
90ec0d68
MGD
31790 virt_sec |= 1;
31791 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_virt))
31792 virt_sec |= 2;
31793 if (virt_sec != 0)
31794 aeabi_set_attribute_int (Tag_Virtualization_use, virt_sec);
ee065d83
PB
31795}
31796
c168ce07
TP
31797/* Post relaxation hook. Recompute ARM attributes now that relaxation is
31798 finished and free extension feature bits which will not be used anymore. */
0198d5e6 31799
c168ce07
TP
31800void
31801arm_md_post_relax (void)
31802{
31803 aeabi_set_public_attributes ();
4d354d8b
TP
31804 XDELETE (mcpu_ext_opt);
31805 mcpu_ext_opt = NULL;
31806 XDELETE (march_ext_opt);
31807 march_ext_opt = NULL;
c168ce07
TP
31808}
31809
104d59d1 31810/* Add the default contents for the .ARM.attributes section. */
0198d5e6 31811
ee065d83
PB
31812void
31813arm_md_end (void)
31814{
ee065d83
PB
31815 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
31816 return;
31817
31818 aeabi_set_public_attributes ();
ee065d83 31819}
8463be01 31820#endif /* OBJ_ELF */
ee065d83 31821
ee065d83
PB
31822/* Parse a .cpu directive. */
31823
31824static void
31825s_arm_cpu (int ignored ATTRIBUTE_UNUSED)
31826{
e74cfd16 31827 const struct arm_cpu_option_table *opt;
ee065d83
PB
31828 char *name;
31829 char saved_char;
31830
31831 name = input_line_pointer;
5f4273c7 31832 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
31833 input_line_pointer++;
31834 saved_char = *input_line_pointer;
31835 *input_line_pointer = 0;
31836
31837 /* Skip the first "all" entry. */
31838 for (opt = arm_cpus + 1; opt->name != NULL; opt++)
31839 if (streq (opt->name, name))
31840 {
4d354d8b
TP
31841 selected_arch = opt->value;
31842 selected_ext = opt->ext;
31843 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
ee065d83 31844 if (opt->canonical_name)
5f4273c7 31845 strcpy (selected_cpu_name, opt->canonical_name);
ee065d83
PB
31846 else
31847 {
31848 int i;
31849 for (i = 0; opt->name[i]; i++)
31850 selected_cpu_name[i] = TOUPPER (opt->name[i]);
f3bad469 31851
ee065d83
PB
31852 selected_cpu_name[i] = 0;
31853 }
4d354d8b
TP
31854 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
31855
ee065d83
PB
31856 *input_line_pointer = saved_char;
31857 demand_empty_rest_of_line ();
31858 return;
31859 }
31860 as_bad (_("unknown cpu `%s'"), name);
31861 *input_line_pointer = saved_char;
31862 ignore_rest_of_line ();
31863}
31864
ee065d83
PB
31865/* Parse a .arch directive. */
31866
31867static void
31868s_arm_arch (int ignored ATTRIBUTE_UNUSED)
31869{
e74cfd16 31870 const struct arm_arch_option_table *opt;
ee065d83
PB
31871 char saved_char;
31872 char *name;
31873
31874 name = input_line_pointer;
5f4273c7 31875 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
31876 input_line_pointer++;
31877 saved_char = *input_line_pointer;
31878 *input_line_pointer = 0;
31879
31880 /* Skip the first "all" entry. */
31881 for (opt = arm_archs + 1; opt->name != NULL; opt++)
31882 if (streq (opt->name, name))
31883 {
4d354d8b
TP
31884 selected_arch = opt->value;
31885 selected_ext = arm_arch_none;
31886 selected_cpu = selected_arch;
5f4273c7 31887 strcpy (selected_cpu_name, opt->name);
4d354d8b 31888 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83
PB
31889 *input_line_pointer = saved_char;
31890 demand_empty_rest_of_line ();
31891 return;
31892 }
31893
31894 as_bad (_("unknown architecture `%s'\n"), name);
31895 *input_line_pointer = saved_char;
31896 ignore_rest_of_line ();
31897}
31898
7a1d4c38
PB
31899/* Parse a .object_arch directive. */
31900
31901static void
31902s_arm_object_arch (int ignored ATTRIBUTE_UNUSED)
31903{
31904 const struct arm_arch_option_table *opt;
31905 char saved_char;
31906 char *name;
31907
31908 name = input_line_pointer;
5f4273c7 31909 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
7a1d4c38
PB
31910 input_line_pointer++;
31911 saved_char = *input_line_pointer;
31912 *input_line_pointer = 0;
31913
31914 /* Skip the first "all" entry. */
31915 for (opt = arm_archs + 1; opt->name != NULL; opt++)
31916 if (streq (opt->name, name))
31917 {
4d354d8b 31918 selected_object_arch = opt->value;
7a1d4c38
PB
31919 *input_line_pointer = saved_char;
31920 demand_empty_rest_of_line ();
31921 return;
31922 }
31923
31924 as_bad (_("unknown architecture `%s'\n"), name);
31925 *input_line_pointer = saved_char;
31926 ignore_rest_of_line ();
31927}
31928
69133863
MGD
31929/* Parse a .arch_extension directive. */
31930
31931static void
31932s_arm_arch_extension (int ignored ATTRIBUTE_UNUSED)
31933{
31934 const struct arm_option_extension_value_table *opt;
31935 char saved_char;
31936 char *name;
31937 int adding_value = 1;
31938
31939 name = input_line_pointer;
31940 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
31941 input_line_pointer++;
31942 saved_char = *input_line_pointer;
31943 *input_line_pointer = 0;
31944
31945 if (strlen (name) >= 2
31946 && strncmp (name, "no", 2) == 0)
31947 {
31948 adding_value = 0;
31949 name += 2;
31950 }
31951
31952 for (opt = arm_extensions; opt->name != NULL; opt++)
31953 if (streq (opt->name, name))
31954 {
d942732e
TP
31955 int i, nb_allowed_archs =
31956 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[i]);
31957 for (i = 0; i < nb_allowed_archs; i++)
31958 {
31959 /* Empty entry. */
4d354d8b 31960 if (ARM_CPU_IS_ANY (opt->allowed_archs[i]))
d942732e 31961 continue;
4d354d8b 31962 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], selected_arch))
d942732e
TP
31963 break;
31964 }
31965
31966 if (i == nb_allowed_archs)
69133863
MGD
31967 {
31968 as_bad (_("architectural extension `%s' is not allowed for the "
31969 "current base architecture"), name);
31970 break;
31971 }
31972
31973 if (adding_value)
4d354d8b 31974 ARM_MERGE_FEATURE_SETS (selected_ext, selected_ext,
5a70a223 31975 opt->merge_value);
69133863 31976 else
4d354d8b 31977 ARM_CLEAR_FEATURE (selected_ext, selected_ext, opt->clear_value);
69133863 31978
4d354d8b
TP
31979 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
31980 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
69133863
MGD
31981 *input_line_pointer = saved_char;
31982 demand_empty_rest_of_line ();
3d030cdb
TP
31983 /* Allowing Thumb division instructions for ARMv7 in autodetection rely
31984 on this return so that duplicate extensions (extensions with the
31985 same name as a previous extension in the list) are not considered
31986 for command-line parsing. */
69133863
MGD
31987 return;
31988 }
31989
31990 if (opt->name == NULL)
e673710a 31991 as_bad (_("unknown architecture extension `%s'\n"), name);
69133863
MGD
31992
31993 *input_line_pointer = saved_char;
31994 ignore_rest_of_line ();
31995}
31996
ee065d83
PB
31997/* Parse a .fpu directive. */
31998
31999static void
32000s_arm_fpu (int ignored ATTRIBUTE_UNUSED)
32001{
69133863 32002 const struct arm_option_fpu_value_table *opt;
ee065d83
PB
32003 char saved_char;
32004 char *name;
32005
32006 name = input_line_pointer;
5f4273c7 32007 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
32008 input_line_pointer++;
32009 saved_char = *input_line_pointer;
32010 *input_line_pointer = 0;
5f4273c7 32011
ee065d83
PB
32012 for (opt = arm_fpus; opt->name != NULL; opt++)
32013 if (streq (opt->name, name))
32014 {
4d354d8b
TP
32015 selected_fpu = opt->value;
32016#ifndef CPU_DEFAULT
32017 if (no_cpu_selected ())
32018 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
32019 else
32020#endif
32021 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83
PB
32022 *input_line_pointer = saved_char;
32023 demand_empty_rest_of_line ();
32024 return;
32025 }
32026
32027 as_bad (_("unknown floating point format `%s'\n"), name);
32028 *input_line_pointer = saved_char;
32029 ignore_rest_of_line ();
32030}
ee065d83 32031
794ba86a 32032/* Copy symbol information. */
f31fef98 32033
794ba86a
DJ
32034void
32035arm_copy_symbol_attributes (symbolS *dest, symbolS *src)
32036{
32037 ARM_GET_FLAG (dest) = ARM_GET_FLAG (src);
32038}
e04befd0 32039
f31fef98 32040#ifdef OBJ_ELF
e04befd0
AS
32041/* Given a symbolic attribute NAME, return the proper integer value.
32042 Returns -1 if the attribute is not known. */
f31fef98 32043
e04befd0
AS
32044int
32045arm_convert_symbolic_attribute (const char *name)
32046{
f31fef98
NC
32047 static const struct
32048 {
32049 const char * name;
32050 const int tag;
32051 }
32052 attribute_table[] =
32053 {
32054 /* When you modify this table you should
32055 also modify the list in doc/c-arm.texi. */
e04befd0 32056#define T(tag) {#tag, tag}
f31fef98
NC
32057 T (Tag_CPU_raw_name),
32058 T (Tag_CPU_name),
32059 T (Tag_CPU_arch),
32060 T (Tag_CPU_arch_profile),
32061 T (Tag_ARM_ISA_use),
32062 T (Tag_THUMB_ISA_use),
75375b3e 32063 T (Tag_FP_arch),
f31fef98
NC
32064 T (Tag_VFP_arch),
32065 T (Tag_WMMX_arch),
32066 T (Tag_Advanced_SIMD_arch),
32067 T (Tag_PCS_config),
32068 T (Tag_ABI_PCS_R9_use),
32069 T (Tag_ABI_PCS_RW_data),
32070 T (Tag_ABI_PCS_RO_data),
32071 T (Tag_ABI_PCS_GOT_use),
32072 T (Tag_ABI_PCS_wchar_t),
32073 T (Tag_ABI_FP_rounding),
32074 T (Tag_ABI_FP_denormal),
32075 T (Tag_ABI_FP_exceptions),
32076 T (Tag_ABI_FP_user_exceptions),
32077 T (Tag_ABI_FP_number_model),
75375b3e 32078 T (Tag_ABI_align_needed),
f31fef98 32079 T (Tag_ABI_align8_needed),
75375b3e 32080 T (Tag_ABI_align_preserved),
f31fef98
NC
32081 T (Tag_ABI_align8_preserved),
32082 T (Tag_ABI_enum_size),
32083 T (Tag_ABI_HardFP_use),
32084 T (Tag_ABI_VFP_args),
32085 T (Tag_ABI_WMMX_args),
32086 T (Tag_ABI_optimization_goals),
32087 T (Tag_ABI_FP_optimization_goals),
32088 T (Tag_compatibility),
32089 T (Tag_CPU_unaligned_access),
75375b3e 32090 T (Tag_FP_HP_extension),
f31fef98
NC
32091 T (Tag_VFP_HP_extension),
32092 T (Tag_ABI_FP_16bit_format),
cd21e546
MGD
32093 T (Tag_MPextension_use),
32094 T (Tag_DIV_use),
f31fef98
NC
32095 T (Tag_nodefaults),
32096 T (Tag_also_compatible_with),
32097 T (Tag_conformance),
32098 T (Tag_T2EE_use),
32099 T (Tag_Virtualization_use),
15afaa63 32100 T (Tag_DSP_extension),
a7ad558c 32101 T (Tag_MVE_arch),
cd21e546 32102 /* We deliberately do not include Tag_MPextension_use_legacy. */
e04befd0 32103#undef T
f31fef98 32104 };
e04befd0
AS
32105 unsigned int i;
32106
32107 if (name == NULL)
32108 return -1;
32109
f31fef98 32110 for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
c921be7d 32111 if (streq (name, attribute_table[i].name))
e04befd0
AS
32112 return attribute_table[i].tag;
32113
32114 return -1;
32115}
267bf995 32116
93ef582d
NC
32117/* Apply sym value for relocations only in the case that they are for
32118 local symbols in the same segment as the fixup and you have the
32119 respective architectural feature for blx and simple switches. */
0198d5e6 32120
267bf995 32121int
93ef582d 32122arm_apply_sym_value (struct fix * fixP, segT this_seg)
267bf995
RR
32123{
32124 if (fixP->fx_addsy
32125 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
93ef582d
NC
32126 /* PR 17444: If the local symbol is in a different section then a reloc
32127 will always be generated for it, so applying the symbol value now
32128 will result in a double offset being stored in the relocation. */
32129 && (S_GET_SEGMENT (fixP->fx_addsy) == this_seg)
34e77a92 32130 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE))
267bf995
RR
32131 {
32132 switch (fixP->fx_r_type)
32133 {
32134 case BFD_RELOC_ARM_PCREL_BLX:
32135 case BFD_RELOC_THUMB_PCREL_BRANCH23:
32136 if (ARM_IS_FUNC (fixP->fx_addsy))
32137 return 1;
32138 break;
32139
32140 case BFD_RELOC_ARM_PCREL_CALL:
32141 case BFD_RELOC_THUMB_PCREL_BLX:
32142 if (THUMB_IS_FUNC (fixP->fx_addsy))
93ef582d 32143 return 1;
267bf995
RR
32144 break;
32145
32146 default:
32147 break;
32148 }
32149
32150 }
32151 return 0;
32152}
f31fef98 32153#endif /* OBJ_ELF */
This page took 5.791696 seconds and 4 git commands to generate.