]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-arm.c
[binutils, ARM, 15/16] Add support for VSCCLRM
[thirdparty/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);
69c9e028 305#ifdef OBJ_ELF
823d2571
TG
306static const arm_feature_set fpu_vfp_fp16 =
307 ARM_FEATURE_COPROC (FPU_VFP_EXT_FP16);
308static const arm_feature_set fpu_neon_ext_fma =
309 ARM_FEATURE_COPROC (FPU_NEON_EXT_FMA);
69c9e028 310#endif
823d2571
TG
311static const arm_feature_set fpu_vfp_ext_fma =
312 ARM_FEATURE_COPROC (FPU_VFP_EXT_FMA);
bca38921 313static const arm_feature_set fpu_vfp_ext_armv8 =
823d2571 314 ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8);
a715796b 315static const arm_feature_set fpu_vfp_ext_armv8xd =
823d2571 316 ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8xD);
bca38921 317static const arm_feature_set fpu_neon_ext_armv8 =
823d2571 318 ARM_FEATURE_COPROC (FPU_NEON_EXT_ARMV8);
bca38921 319static const arm_feature_set fpu_crypto_ext_armv8 =
823d2571 320 ARM_FEATURE_COPROC (FPU_CRYPTO_EXT_ARMV8);
dd5181d5 321static const arm_feature_set crc_ext_armv8 =
823d2571 322 ARM_FEATURE_COPROC (CRC_EXT_ARMV8);
d6b4b13e 323static const arm_feature_set fpu_neon_ext_v8_1 =
643afb90 324 ARM_FEATURE_COPROC (FPU_NEON_EXT_RDMA);
c604a79a
JW
325static const arm_feature_set fpu_neon_ext_dotprod =
326 ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD);
e74cfd16 327
33a392fb 328static int mfloat_abi_opt = -1;
4d354d8b
TP
329/* Architecture feature bits selected by the last -mcpu/-march or .cpu/.arch
330 directive. */
331static arm_feature_set selected_arch = ARM_ARCH_NONE;
332/* Extension feature bits selected by the last -mcpu/-march or .arch_extension
333 directive. */
334static arm_feature_set selected_ext = ARM_ARCH_NONE;
335/* Feature bits selected by the last -mcpu/-march or by the combination of the
336 last .cpu/.arch directive .arch_extension directives since that
337 directive. */
e74cfd16 338static arm_feature_set selected_cpu = ARM_ARCH_NONE;
4d354d8b
TP
339/* FPU feature bits selected by the last -mfpu or .fpu directive. */
340static arm_feature_set selected_fpu = FPU_NONE;
341/* Feature bits selected by the last .object_arch directive. */
342static arm_feature_set selected_object_arch = ARM_ARCH_NONE;
ee065d83 343/* Must be long enough to hold any of the names in arm_cpus. */
ef8e6722 344static char selected_cpu_name[20];
8d67f500 345
aacf0b33
KT
346extern FLONUM_TYPE generic_floating_point_number;
347
8d67f500
NC
348/* Return if no cpu was selected on command-line. */
349static bfd_boolean
350no_cpu_selected (void)
351{
823d2571 352 return ARM_FEATURE_EQUAL (selected_cpu, arm_arch_none);
8d67f500
NC
353}
354
7cc69913 355#ifdef OBJ_ELF
deeaaff8
DJ
356# ifdef EABI_DEFAULT
357static int meabi_flags = EABI_DEFAULT;
358# else
d507cf36 359static int meabi_flags = EF_ARM_EABI_UNKNOWN;
deeaaff8 360# endif
e1da3f5b 361
ee3c0378
AS
362static int attributes_set_explicitly[NUM_KNOWN_OBJ_ATTRIBUTES];
363
e1da3f5b 364bfd_boolean
5f4273c7 365arm_is_eabi (void)
e1da3f5b
PB
366{
367 return (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4);
368}
7cc69913 369#endif
b99bd4ef 370
b99bd4ef 371#ifdef OBJ_ELF
c19d1205 372/* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
b99bd4ef
NC
373symbolS * GOT_symbol;
374#endif
375
b99bd4ef
NC
376/* 0: assemble for ARM,
377 1: assemble for Thumb,
378 2: assemble for Thumb even though target CPU does not support thumb
379 instructions. */
380static int thumb_mode = 0;
8dc2430f
NC
381/* A value distinct from the possible values for thumb_mode that we
382 can use to record whether thumb_mode has been copied into the
383 tc_frag_data field of a frag. */
384#define MODE_RECORDED (1 << 4)
b99bd4ef 385
e07e6e58
NC
386/* Specifies the intrinsic IT insn behavior mode. */
387enum implicit_it_mode
388{
389 IMPLICIT_IT_MODE_NEVER = 0x00,
390 IMPLICIT_IT_MODE_ARM = 0x01,
391 IMPLICIT_IT_MODE_THUMB = 0x02,
392 IMPLICIT_IT_MODE_ALWAYS = (IMPLICIT_IT_MODE_ARM | IMPLICIT_IT_MODE_THUMB)
393};
394static int implicit_it_mode = IMPLICIT_IT_MODE_ARM;
395
c19d1205
ZW
396/* If unified_syntax is true, we are processing the new unified
397 ARM/Thumb syntax. Important differences from the old ARM mode:
398
399 - Immediate operands do not require a # prefix.
400 - Conditional affixes always appear at the end of the
401 instruction. (For backward compatibility, those instructions
402 that formerly had them in the middle, continue to accept them
403 there.)
404 - The IT instruction may appear, and if it does is validated
405 against subsequent conditional affixes. It does not generate
406 machine code.
407
408 Important differences from the old Thumb mode:
409
410 - Immediate operands do not require a # prefix.
411 - Most of the V6T2 instructions are only available in unified mode.
412 - The .N and .W suffixes are recognized and honored (it is an error
413 if they cannot be honored).
414 - All instructions set the flags if and only if they have an 's' affix.
415 - Conditional affixes may be used. They are validated against
416 preceding IT instructions. Unlike ARM mode, you cannot use a
417 conditional affix except in the scope of an IT instruction. */
418
419static bfd_boolean unified_syntax = FALSE;
b99bd4ef 420
bacebabc
RM
421/* An immediate operand can start with #, and ld*, st*, pld operands
422 can contain [ and ]. We need to tell APP not to elide whitespace
477330fc
RM
423 before a [, which can appear as the first operand for pld.
424 Likewise, a { can appear as the first operand for push, pop, vld*, etc. */
425const char arm_symbol_chars[] = "#[]{}";
bacebabc 426
5287ad62
JB
427enum neon_el_type
428{
dcbf9037 429 NT_invtype,
5287ad62
JB
430 NT_untyped,
431 NT_integer,
432 NT_float,
433 NT_poly,
434 NT_signed,
dcbf9037 435 NT_unsigned
5287ad62
JB
436};
437
438struct neon_type_el
439{
440 enum neon_el_type type;
441 unsigned size;
442};
443
444#define NEON_MAX_TYPE_ELS 4
445
446struct neon_type
447{
448 struct neon_type_el el[NEON_MAX_TYPE_ELS];
449 unsigned elems;
450};
451
e07e6e58
NC
452enum it_instruction_type
453{
454 OUTSIDE_IT_INSN,
455 INSIDE_IT_INSN,
456 INSIDE_IT_LAST_INSN,
457 IF_INSIDE_IT_LAST_INSN, /* Either outside or inside;
477330fc 458 if inside, should be the last one. */
e07e6e58 459 NEUTRAL_IT_INSN, /* This could be either inside or outside,
477330fc 460 i.e. BKPT and NOP. */
e07e6e58
NC
461 IT_INSN /* The IT insn has been parsed. */
462};
463
ad6cec43
MGD
464/* The maximum number of operands we need. */
465#define ARM_IT_MAX_OPERANDS 6
e2b0ab59 466#define ARM_IT_MAX_RELOCS 3
ad6cec43 467
b99bd4ef
NC
468struct arm_it
469{
c19d1205 470 const char * error;
b99bd4ef 471 unsigned long instruction;
c19d1205
ZW
472 int size;
473 int size_req;
474 int cond;
037e8744
JB
475 /* "uncond_value" is set to the value in place of the conditional field in
476 unconditional versions of the instruction, or -1 if nothing is
477 appropriate. */
478 int uncond_value;
5287ad62 479 struct neon_type vectype;
88714cb8
DG
480 /* This does not indicate an actual NEON instruction, only that
481 the mnemonic accepts neon-style type suffixes. */
482 int is_neon;
0110f2b8
PB
483 /* Set to the opcode if the instruction needs relaxation.
484 Zero if the instruction is not relaxed. */
485 unsigned long relax;
b99bd4ef
NC
486 struct
487 {
488 bfd_reloc_code_real_type type;
c19d1205
ZW
489 expressionS exp;
490 int pc_rel;
e2b0ab59 491 } relocs[ARM_IT_MAX_RELOCS];
b99bd4ef 492
e07e6e58
NC
493 enum it_instruction_type it_insn_type;
494
c19d1205
ZW
495 struct
496 {
497 unsigned reg;
ca3f61f7 498 signed int imm;
dcbf9037 499 struct neon_type_el vectype;
ca3f61f7
NC
500 unsigned present : 1; /* Operand present. */
501 unsigned isreg : 1; /* Operand was a register. */
502 unsigned immisreg : 1; /* .imm field is a second register. */
5287ad62
JB
503 unsigned isscalar : 1; /* Operand is a (Neon) scalar. */
504 unsigned immisalign : 1; /* Immediate is an alignment specifier. */
c96612cc 505 unsigned immisfloat : 1; /* Immediate was parsed as a float. */
5287ad62
JB
506 /* Note: we abuse "regisimm" to mean "is Neon register" in VMOV
507 instructions. This allows us to disambiguate ARM <-> vector insns. */
508 unsigned regisimm : 1; /* 64-bit immediate, reg forms high 32 bits. */
037e8744 509 unsigned isvec : 1; /* Is a single, double or quad VFP/Neon reg. */
5287ad62 510 unsigned isquad : 1; /* Operand is Neon quad-precision register. */
037e8744 511 unsigned issingle : 1; /* Operand is VFP single-precision register. */
ca3f61f7
NC
512 unsigned hasreloc : 1; /* Operand has relocation suffix. */
513 unsigned writeback : 1; /* Operand has trailing ! */
514 unsigned preind : 1; /* Preindexed address. */
515 unsigned postind : 1; /* Postindexed address. */
516 unsigned negative : 1; /* Index register was negated. */
517 unsigned shifted : 1; /* Shift applied to operation. */
518 unsigned shift_kind : 3; /* Shift operation (enum shift_kind). */
ad6cec43 519 } operands[ARM_IT_MAX_OPERANDS];
b99bd4ef
NC
520};
521
c19d1205 522static struct arm_it inst;
b99bd4ef
NC
523
524#define NUM_FLOAT_VALS 8
525
05d2d07e 526const char * fp_const[] =
b99bd4ef
NC
527{
528 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
529};
530
c19d1205 531/* Number of littlenums required to hold an extended precision number. */
b99bd4ef
NC
532#define MAX_LITTLENUMS 6
533
534LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
535
536#define FAIL (-1)
537#define SUCCESS (0)
538
539#define SUFF_S 1
540#define SUFF_D 2
541#define SUFF_E 3
542#define SUFF_P 4
543
c19d1205
ZW
544#define CP_T_X 0x00008000
545#define CP_T_Y 0x00400000
b99bd4ef 546
c19d1205
ZW
547#define CONDS_BIT 0x00100000
548#define LOAD_BIT 0x00100000
b99bd4ef
NC
549
550#define DOUBLE_LOAD_FLAG 0x00000001
551
552struct asm_cond
553{
d3ce72d0 554 const char * template_name;
c921be7d 555 unsigned long value;
b99bd4ef
NC
556};
557
c19d1205 558#define COND_ALWAYS 0xE
b99bd4ef 559
b99bd4ef
NC
560struct asm_psr
561{
d3ce72d0 562 const char * template_name;
c921be7d 563 unsigned long field;
b99bd4ef
NC
564};
565
62b3e311
PB
566struct asm_barrier_opt
567{
e797f7e0
MGD
568 const char * template_name;
569 unsigned long value;
570 const arm_feature_set arch;
62b3e311
PB
571};
572
2d2255b5 573/* The bit that distinguishes CPSR and SPSR. */
b99bd4ef
NC
574#define SPSR_BIT (1 << 22)
575
c19d1205
ZW
576/* The individual PSR flag bits. */
577#define PSR_c (1 << 16)
578#define PSR_x (1 << 17)
579#define PSR_s (1 << 18)
580#define PSR_f (1 << 19)
b99bd4ef 581
c19d1205 582struct reloc_entry
bfae80f2 583{
0198d5e6 584 const char * name;
c921be7d 585 bfd_reloc_code_real_type reloc;
bfae80f2
RE
586};
587
5287ad62 588enum vfp_reg_pos
bfae80f2 589{
5287ad62
JB
590 VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn,
591 VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
bfae80f2
RE
592};
593
594enum vfp_ldstm_type
595{
596 VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
597};
598
dcbf9037
JB
599/* Bits for DEFINED field in neon_typed_alias. */
600#define NTA_HASTYPE 1
601#define NTA_HASINDEX 2
602
603struct neon_typed_alias
604{
c921be7d
NC
605 unsigned char defined;
606 unsigned char index;
607 struct neon_type_el eltype;
dcbf9037
JB
608};
609
c19d1205 610/* ARM register categories. This includes coprocessor numbers and various
5aa75429
TP
611 architecture extensions' registers. Each entry should have an error message
612 in reg_expected_msgs below. */
c19d1205 613enum arm_reg_type
bfae80f2 614{
c19d1205
ZW
615 REG_TYPE_RN,
616 REG_TYPE_CP,
617 REG_TYPE_CN,
618 REG_TYPE_FN,
619 REG_TYPE_VFS,
620 REG_TYPE_VFD,
5287ad62 621 REG_TYPE_NQ,
037e8744 622 REG_TYPE_VFSD,
5287ad62 623 REG_TYPE_NDQ,
dec41383 624 REG_TYPE_NSD,
037e8744 625 REG_TYPE_NSDQ,
c19d1205
ZW
626 REG_TYPE_VFC,
627 REG_TYPE_MVF,
628 REG_TYPE_MVD,
629 REG_TYPE_MVFX,
630 REG_TYPE_MVDX,
631 REG_TYPE_MVAX,
632 REG_TYPE_DSPSC,
633 REG_TYPE_MMXWR,
634 REG_TYPE_MMXWC,
635 REG_TYPE_MMXWCG,
636 REG_TYPE_XSCALE,
90ec0d68 637 REG_TYPE_RNB
bfae80f2
RE
638};
639
dcbf9037
JB
640/* Structure for a hash table entry for a register.
641 If TYPE is REG_TYPE_VFD or REG_TYPE_NQ, the NEON field can point to extra
642 information which states whether a vector type or index is specified (for a
643 register alias created with .dn or .qn). Otherwise NEON should be NULL. */
6c43fab6
RE
644struct reg_entry
645{
c921be7d 646 const char * name;
90ec0d68 647 unsigned int number;
c921be7d
NC
648 unsigned char type;
649 unsigned char builtin;
650 struct neon_typed_alias * neon;
6c43fab6
RE
651};
652
c19d1205 653/* Diagnostics used when we don't get a register of the expected type. */
c921be7d 654const char * const reg_expected_msgs[] =
c19d1205 655{
5aa75429
TP
656 [REG_TYPE_RN] = N_("ARM register expected"),
657 [REG_TYPE_CP] = N_("bad or missing co-processor number"),
658 [REG_TYPE_CN] = N_("co-processor register expected"),
659 [REG_TYPE_FN] = N_("FPA register expected"),
660 [REG_TYPE_VFS] = N_("VFP single precision register expected"),
661 [REG_TYPE_VFD] = N_("VFP/Neon double precision register expected"),
662 [REG_TYPE_NQ] = N_("Neon quad precision register expected"),
663 [REG_TYPE_VFSD] = N_("VFP single or double precision register expected"),
664 [REG_TYPE_NDQ] = N_("Neon double or quad precision register expected"),
665 [REG_TYPE_NSD] = N_("Neon single or double precision register expected"),
666 [REG_TYPE_NSDQ] = N_("VFP single, double or Neon quad precision register"
667 " expected"),
668 [REG_TYPE_VFC] = N_("VFP system register expected"),
669 [REG_TYPE_MVF] = N_("Maverick MVF register expected"),
670 [REG_TYPE_MVD] = N_("Maverick MVD register expected"),
671 [REG_TYPE_MVFX] = N_("Maverick MVFX register expected"),
672 [REG_TYPE_MVDX] = N_("Maverick MVDX register expected"),
673 [REG_TYPE_MVAX] = N_("Maverick MVAX register expected"),
674 [REG_TYPE_DSPSC] = N_("Maverick DSPSC register expected"),
675 [REG_TYPE_MMXWR] = N_("iWMMXt data register expected"),
676 [REG_TYPE_MMXWC] = N_("iWMMXt control register expected"),
677 [REG_TYPE_MMXWCG] = N_("iWMMXt scalar register expected"),
678 [REG_TYPE_XSCALE] = N_("XScale accumulator register expected"),
679 [REG_TYPE_RNB] = N_("")
6c43fab6
RE
680};
681
c19d1205 682/* Some well known registers that we refer to directly elsewhere. */
bd340a04 683#define REG_R12 12
c19d1205
ZW
684#define REG_SP 13
685#define REG_LR 14
686#define REG_PC 15
404ff6b5 687
b99bd4ef
NC
688/* ARM instructions take 4bytes in the object file, Thumb instructions
689 take 2: */
c19d1205 690#define INSN_SIZE 4
b99bd4ef
NC
691
692struct asm_opcode
693{
694 /* Basic string to match. */
d3ce72d0 695 const char * template_name;
c19d1205
ZW
696
697 /* Parameters to instruction. */
5be8be5d 698 unsigned int operands[8];
c19d1205
ZW
699
700 /* Conditional tag - see opcode_lookup. */
701 unsigned int tag : 4;
b99bd4ef
NC
702
703 /* Basic instruction code. */
c19d1205 704 unsigned int avalue : 28;
b99bd4ef 705
c19d1205
ZW
706 /* Thumb-format instruction code. */
707 unsigned int tvalue;
b99bd4ef 708
90e4755a 709 /* Which architecture variant provides this instruction. */
c921be7d
NC
710 const arm_feature_set * avariant;
711 const arm_feature_set * tvariant;
c19d1205
ZW
712
713 /* Function to call to encode instruction in ARM format. */
714 void (* aencode) (void);
b99bd4ef 715
c19d1205
ZW
716 /* Function to call to encode instruction in Thumb format. */
717 void (* tencode) (void);
b99bd4ef
NC
718};
719
a737bd4d
NC
720/* Defines for various bits that we will want to toggle. */
721#define INST_IMMEDIATE 0x02000000
722#define OFFSET_REG 0x02000000
c19d1205 723#define HWOFFSET_IMM 0x00400000
a737bd4d
NC
724#define SHIFT_BY_REG 0x00000010
725#define PRE_INDEX 0x01000000
726#define INDEX_UP 0x00800000
727#define WRITE_BACK 0x00200000
728#define LDM_TYPE_2_OR_3 0x00400000
a028a6f5 729#define CPSI_MMOD 0x00020000
90e4755a 730
a737bd4d
NC
731#define LITERAL_MASK 0xf000f000
732#define OPCODE_MASK 0xfe1fffff
733#define V4_STR_BIT 0x00000020
8335d6aa 734#define VLDR_VMOV_SAME 0x0040f000
90e4755a 735
efd81785
PB
736#define T2_SUBS_PC_LR 0xf3de8f00
737
a737bd4d 738#define DATA_OP_SHIFT 21
bada4342 739#define SBIT_SHIFT 20
90e4755a 740
ef8d22e6
PB
741#define T2_OPCODE_MASK 0xfe1fffff
742#define T2_DATA_OP_SHIFT 21
bada4342 743#define T2_SBIT_SHIFT 20
ef8d22e6 744
6530b175
NC
745#define A_COND_MASK 0xf0000000
746#define A_PUSH_POP_OP_MASK 0x0fff0000
747
748/* Opcodes for pushing/poping registers to/from the stack. */
749#define A1_OPCODE_PUSH 0x092d0000
750#define A2_OPCODE_PUSH 0x052d0004
751#define A2_OPCODE_POP 0x049d0004
752
a737bd4d
NC
753/* Codes to distinguish the arithmetic instructions. */
754#define OPCODE_AND 0
755#define OPCODE_EOR 1
756#define OPCODE_SUB 2
757#define OPCODE_RSB 3
758#define OPCODE_ADD 4
759#define OPCODE_ADC 5
760#define OPCODE_SBC 6
761#define OPCODE_RSC 7
762#define OPCODE_TST 8
763#define OPCODE_TEQ 9
764#define OPCODE_CMP 10
765#define OPCODE_CMN 11
766#define OPCODE_ORR 12
767#define OPCODE_MOV 13
768#define OPCODE_BIC 14
769#define OPCODE_MVN 15
90e4755a 770
ef8d22e6
PB
771#define T2_OPCODE_AND 0
772#define T2_OPCODE_BIC 1
773#define T2_OPCODE_ORR 2
774#define T2_OPCODE_ORN 3
775#define T2_OPCODE_EOR 4
776#define T2_OPCODE_ADD 8
777#define T2_OPCODE_ADC 10
778#define T2_OPCODE_SBC 11
779#define T2_OPCODE_SUB 13
780#define T2_OPCODE_RSB 14
781
a737bd4d
NC
782#define T_OPCODE_MUL 0x4340
783#define T_OPCODE_TST 0x4200
784#define T_OPCODE_CMN 0x42c0
785#define T_OPCODE_NEG 0x4240
786#define T_OPCODE_MVN 0x43c0
90e4755a 787
a737bd4d
NC
788#define T_OPCODE_ADD_R3 0x1800
789#define T_OPCODE_SUB_R3 0x1a00
790#define T_OPCODE_ADD_HI 0x4400
791#define T_OPCODE_ADD_ST 0xb000
792#define T_OPCODE_SUB_ST 0xb080
793#define T_OPCODE_ADD_SP 0xa800
794#define T_OPCODE_ADD_PC 0xa000
795#define T_OPCODE_ADD_I8 0x3000
796#define T_OPCODE_SUB_I8 0x3800
797#define T_OPCODE_ADD_I3 0x1c00
798#define T_OPCODE_SUB_I3 0x1e00
b99bd4ef 799
a737bd4d
NC
800#define T_OPCODE_ASR_R 0x4100
801#define T_OPCODE_LSL_R 0x4080
c19d1205
ZW
802#define T_OPCODE_LSR_R 0x40c0
803#define T_OPCODE_ROR_R 0x41c0
a737bd4d
NC
804#define T_OPCODE_ASR_I 0x1000
805#define T_OPCODE_LSL_I 0x0000
806#define T_OPCODE_LSR_I 0x0800
b99bd4ef 807
a737bd4d
NC
808#define T_OPCODE_MOV_I8 0x2000
809#define T_OPCODE_CMP_I8 0x2800
810#define T_OPCODE_CMP_LR 0x4280
811#define T_OPCODE_MOV_HR 0x4600
812#define T_OPCODE_CMP_HR 0x4500
b99bd4ef 813
a737bd4d
NC
814#define T_OPCODE_LDR_PC 0x4800
815#define T_OPCODE_LDR_SP 0x9800
816#define T_OPCODE_STR_SP 0x9000
817#define T_OPCODE_LDR_IW 0x6800
818#define T_OPCODE_STR_IW 0x6000
819#define T_OPCODE_LDR_IH 0x8800
820#define T_OPCODE_STR_IH 0x8000
821#define T_OPCODE_LDR_IB 0x7800
822#define T_OPCODE_STR_IB 0x7000
823#define T_OPCODE_LDR_RW 0x5800
824#define T_OPCODE_STR_RW 0x5000
825#define T_OPCODE_LDR_RH 0x5a00
826#define T_OPCODE_STR_RH 0x5200
827#define T_OPCODE_LDR_RB 0x5c00
828#define T_OPCODE_STR_RB 0x5400
c9b604bd 829
a737bd4d
NC
830#define T_OPCODE_PUSH 0xb400
831#define T_OPCODE_POP 0xbc00
b99bd4ef 832
2fc8bdac 833#define T_OPCODE_BRANCH 0xe000
b99bd4ef 834
a737bd4d 835#define THUMB_SIZE 2 /* Size of thumb instruction. */
a737bd4d 836#define THUMB_PP_PC_LR 0x0100
c19d1205 837#define THUMB_LOAD_BIT 0x0800
53365c0d 838#define THUMB2_LOAD_BIT 0x00100000
c19d1205
ZW
839
840#define BAD_ARGS _("bad arguments to instruction")
fdfde340 841#define BAD_SP _("r13 not allowed here")
c19d1205
ZW
842#define BAD_PC _("r15 not allowed here")
843#define BAD_COND _("instruction cannot be conditional")
844#define BAD_OVERLAP _("registers may not be the same")
845#define BAD_HIREG _("lo register required")
846#define BAD_THUMB32 _("instruction not supported in Thumb16 mode")
01cfc07f 847#define BAD_ADDR_MODE _("instruction does not accept this addressing mode");
dfa9f0d5 848#define BAD_BRANCH _("branch must be last instruction in IT block")
e12437dc 849#define BAD_BRANCH_OFF _("branch out of range or not a multiple of 2")
dfa9f0d5 850#define BAD_NOT_IT _("instruction not allowed in IT block")
037e8744 851#define BAD_FPU _("selected FPU does not support instruction")
e07e6e58
NC
852#define BAD_OUT_IT _("thumb conditional instruction should be in IT block")
853#define BAD_IT_COND _("incorrect condition in IT block")
854#define BAD_IT_IT _("IT falling in the range of a previous IT block")
921e5f0a 855#define MISSING_FNSTART _("missing .fnstart before unwinding directive")
5be8be5d
DG
856#define BAD_PC_ADDRESSING \
857 _("cannot use register index with PC-relative addressing")
858#define BAD_PC_WRITEBACK \
859 _("cannot use writeback with PC-relative addressing")
9db2f6b4
RL
860#define BAD_RANGE _("branch out of range")
861#define BAD_FP16 _("selected processor does not support fp16 instruction")
dd5181d5 862#define UNPRED_REG(R) _("using " R " results in unpredictable behaviour")
a9f02af8 863#define THUMB1_RELOC_ONLY _("relocation valid in thumb1 code only")
c19d1205 864
c921be7d
NC
865static struct hash_control * arm_ops_hsh;
866static struct hash_control * arm_cond_hsh;
867static struct hash_control * arm_shift_hsh;
868static struct hash_control * arm_psr_hsh;
869static struct hash_control * arm_v7m_psr_hsh;
870static struct hash_control * arm_reg_hsh;
871static struct hash_control * arm_reloc_hsh;
872static struct hash_control * arm_barrier_opt_hsh;
b99bd4ef 873
b99bd4ef
NC
874/* Stuff needed to resolve the label ambiguity
875 As:
876 ...
877 label: <insn>
878 may differ from:
879 ...
880 label:
5f4273c7 881 <insn> */
b99bd4ef
NC
882
883symbolS * last_label_seen;
b34976b6 884static int label_is_thumb_function_name = FALSE;
e07e6e58 885
3d0c9500
NC
886/* Literal pool structure. Held on a per-section
887 and per-sub-section basis. */
a737bd4d 888
c19d1205 889#define MAX_LITERAL_POOL_SIZE 1024
3d0c9500 890typedef struct literal_pool
b99bd4ef 891{
c921be7d
NC
892 expressionS literals [MAX_LITERAL_POOL_SIZE];
893 unsigned int next_free_entry;
894 unsigned int id;
895 symbolS * symbol;
896 segT section;
897 subsegT sub_section;
a8040cf2
NC
898#ifdef OBJ_ELF
899 struct dwarf2_line_info locs [MAX_LITERAL_POOL_SIZE];
900#endif
c921be7d 901 struct literal_pool * next;
8335d6aa 902 unsigned int alignment;
3d0c9500 903} literal_pool;
b99bd4ef 904
3d0c9500
NC
905/* Pointer to a linked list of literal pools. */
906literal_pool * list_of_pools = NULL;
e27ec89e 907
2e6976a8
DG
908typedef enum asmfunc_states
909{
910 OUTSIDE_ASMFUNC,
911 WAITING_ASMFUNC_NAME,
912 WAITING_ENDASMFUNC
913} asmfunc_states;
914
915static asmfunc_states asmfunc_state = OUTSIDE_ASMFUNC;
916
e07e6e58
NC
917#ifdef OBJ_ELF
918# define now_it seg_info (now_seg)->tc_segment_info_data.current_it
919#else
920static struct current_it now_it;
921#endif
922
923static inline int
924now_it_compatible (int cond)
925{
926 return (cond & ~1) == (now_it.cc & ~1);
927}
928
929static inline int
930conditional_insn (void)
931{
932 return inst.cond != COND_ALWAYS;
933}
934
935static int in_it_block (void);
936
937static int handle_it_state (void);
938
939static void force_automatic_it_block_close (void);
940
c921be7d
NC
941static void it_fsm_post_encode (void);
942
e07e6e58
NC
943#define set_it_insn_type(type) \
944 do \
945 { \
946 inst.it_insn_type = type; \
947 if (handle_it_state () == FAIL) \
477330fc 948 return; \
e07e6e58
NC
949 } \
950 while (0)
951
c921be7d
NC
952#define set_it_insn_type_nonvoid(type, failret) \
953 do \
954 { \
955 inst.it_insn_type = type; \
956 if (handle_it_state () == FAIL) \
477330fc 957 return failret; \
c921be7d
NC
958 } \
959 while(0)
960
e07e6e58
NC
961#define set_it_insn_type_last() \
962 do \
963 { \
964 if (inst.cond == COND_ALWAYS) \
477330fc 965 set_it_insn_type (IF_INSIDE_IT_LAST_INSN); \
e07e6e58 966 else \
477330fc 967 set_it_insn_type (INSIDE_IT_LAST_INSN); \
e07e6e58
NC
968 } \
969 while (0)
970
c19d1205 971/* Pure syntax. */
b99bd4ef 972
c19d1205
ZW
973/* This array holds the chars that always start a comment. If the
974 pre-processor is disabled, these aren't very useful. */
2e6976a8 975char arm_comment_chars[] = "@";
3d0c9500 976
c19d1205
ZW
977/* This array holds the chars that only start a comment at the beginning of
978 a line. If the line seems to have the form '# 123 filename'
979 .line and .file directives will appear in the pre-processed output. */
980/* Note that input_file.c hand checks for '#' at the beginning of the
981 first line of the input file. This is because the compiler outputs
982 #NO_APP at the beginning of its output. */
983/* Also note that comments like this one will always work. */
984const char line_comment_chars[] = "#";
3d0c9500 985
2e6976a8 986char arm_line_separator_chars[] = ";";
b99bd4ef 987
c19d1205
ZW
988/* Chars that can be used to separate mant
989 from exp in floating point numbers. */
990const char EXP_CHARS[] = "eE";
3d0c9500 991
c19d1205
ZW
992/* Chars that mean this number is a floating point constant. */
993/* As in 0f12.456 */
994/* or 0d1.2345e12 */
b99bd4ef 995
c19d1205 996const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
3d0c9500 997
c19d1205
ZW
998/* Prefix characters that indicate the start of an immediate
999 value. */
1000#define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
3d0c9500 1001
c19d1205
ZW
1002/* Separator character handling. */
1003
1004#define skip_whitespace(str) do { if (*(str) == ' ') ++(str); } while (0)
1005
1006static inline int
1007skip_past_char (char ** str, char c)
1008{
8ab8155f
NC
1009 /* PR gas/14987: Allow for whitespace before the expected character. */
1010 skip_whitespace (*str);
427d0db6 1011
c19d1205
ZW
1012 if (**str == c)
1013 {
1014 (*str)++;
1015 return SUCCESS;
3d0c9500 1016 }
c19d1205
ZW
1017 else
1018 return FAIL;
1019}
c921be7d 1020
c19d1205 1021#define skip_past_comma(str) skip_past_char (str, ',')
3d0c9500 1022
c19d1205
ZW
1023/* Arithmetic expressions (possibly involving symbols). */
1024
1025/* Return TRUE if anything in the expression is a bignum. */
1026
0198d5e6 1027static bfd_boolean
c19d1205
ZW
1028walk_no_bignums (symbolS * sp)
1029{
1030 if (symbol_get_value_expression (sp)->X_op == O_big)
0198d5e6 1031 return TRUE;
c19d1205
ZW
1032
1033 if (symbol_get_value_expression (sp)->X_add_symbol)
3d0c9500 1034 {
c19d1205
ZW
1035 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
1036 || (symbol_get_value_expression (sp)->X_op_symbol
1037 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
3d0c9500
NC
1038 }
1039
0198d5e6 1040 return FALSE;
3d0c9500
NC
1041}
1042
0198d5e6 1043static bfd_boolean in_my_get_expression = FALSE;
c19d1205
ZW
1044
1045/* Third argument to my_get_expression. */
1046#define GE_NO_PREFIX 0
1047#define GE_IMM_PREFIX 1
1048#define GE_OPT_PREFIX 2
5287ad62
JB
1049/* This is a bit of a hack. Use an optional prefix, and also allow big (64-bit)
1050 immediates, as can be used in Neon VMVN and VMOV immediate instructions. */
1051#define GE_OPT_PREFIX_BIG 3
a737bd4d 1052
b99bd4ef 1053static int
c19d1205 1054my_get_expression (expressionS * ep, char ** str, int prefix_mode)
b99bd4ef 1055{
c19d1205 1056 char * save_in;
b99bd4ef 1057
c19d1205
ZW
1058 /* In unified syntax, all prefixes are optional. */
1059 if (unified_syntax)
5287ad62 1060 prefix_mode = (prefix_mode == GE_OPT_PREFIX_BIG) ? prefix_mode
477330fc 1061 : GE_OPT_PREFIX;
b99bd4ef 1062
c19d1205 1063 switch (prefix_mode)
b99bd4ef 1064 {
c19d1205
ZW
1065 case GE_NO_PREFIX: break;
1066 case GE_IMM_PREFIX:
1067 if (!is_immediate_prefix (**str))
1068 {
1069 inst.error = _("immediate expression requires a # prefix");
1070 return FAIL;
1071 }
1072 (*str)++;
1073 break;
1074 case GE_OPT_PREFIX:
5287ad62 1075 case GE_OPT_PREFIX_BIG:
c19d1205
ZW
1076 if (is_immediate_prefix (**str))
1077 (*str)++;
1078 break;
0198d5e6
TC
1079 default:
1080 abort ();
c19d1205 1081 }
b99bd4ef 1082
c19d1205 1083 memset (ep, 0, sizeof (expressionS));
b99bd4ef 1084
c19d1205
ZW
1085 save_in = input_line_pointer;
1086 input_line_pointer = *str;
0198d5e6 1087 in_my_get_expression = TRUE;
2ac93be7 1088 expression (ep);
0198d5e6 1089 in_my_get_expression = FALSE;
c19d1205 1090
f86adc07 1091 if (ep->X_op == O_illegal || ep->X_op == O_absent)
b99bd4ef 1092 {
f86adc07 1093 /* We found a bad or missing expression in md_operand(). */
c19d1205
ZW
1094 *str = input_line_pointer;
1095 input_line_pointer = save_in;
1096 if (inst.error == NULL)
f86adc07
NS
1097 inst.error = (ep->X_op == O_absent
1098 ? _("missing expression") :_("bad expression"));
c19d1205
ZW
1099 return 1;
1100 }
b99bd4ef 1101
c19d1205
ZW
1102 /* Get rid of any bignums now, so that we don't generate an error for which
1103 we can't establish a line number later on. Big numbers are never valid
1104 in instructions, which is where this routine is always called. */
5287ad62
JB
1105 if (prefix_mode != GE_OPT_PREFIX_BIG
1106 && (ep->X_op == O_big
477330fc 1107 || (ep->X_add_symbol
5287ad62 1108 && (walk_no_bignums (ep->X_add_symbol)
477330fc 1109 || (ep->X_op_symbol
5287ad62 1110 && walk_no_bignums (ep->X_op_symbol))))))
c19d1205
ZW
1111 {
1112 inst.error = _("invalid constant");
1113 *str = input_line_pointer;
1114 input_line_pointer = save_in;
1115 return 1;
1116 }
b99bd4ef 1117
c19d1205
ZW
1118 *str = input_line_pointer;
1119 input_line_pointer = save_in;
0198d5e6 1120 return SUCCESS;
b99bd4ef
NC
1121}
1122
c19d1205
ZW
1123/* Turn a string in input_line_pointer into a floating point constant
1124 of type TYPE, and store the appropriate bytes in *LITP. The number
1125 of LITTLENUMS emitted is stored in *SIZEP. An error message is
1126 returned, or NULL on OK.
b99bd4ef 1127
c19d1205
ZW
1128 Note that fp constants aren't represent in the normal way on the ARM.
1129 In big endian mode, things are as expected. However, in little endian
1130 mode fp constants are big-endian word-wise, and little-endian byte-wise
1131 within the words. For example, (double) 1.1 in big endian mode is
1132 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
1133 the byte sequence 99 99 f1 3f 9a 99 99 99.
b99bd4ef 1134
c19d1205 1135 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
b99bd4ef 1136
6d4af3c2 1137const char *
c19d1205
ZW
1138md_atof (int type, char * litP, int * sizeP)
1139{
1140 int prec;
1141 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1142 char *t;
1143 int i;
b99bd4ef 1144
c19d1205
ZW
1145 switch (type)
1146 {
1147 case 'f':
1148 case 'F':
1149 case 's':
1150 case 'S':
1151 prec = 2;
1152 break;
b99bd4ef 1153
c19d1205
ZW
1154 case 'd':
1155 case 'D':
1156 case 'r':
1157 case 'R':
1158 prec = 4;
1159 break;
b99bd4ef 1160
c19d1205
ZW
1161 case 'x':
1162 case 'X':
499ac353 1163 prec = 5;
c19d1205 1164 break;
b99bd4ef 1165
c19d1205
ZW
1166 case 'p':
1167 case 'P':
499ac353 1168 prec = 5;
c19d1205 1169 break;
a737bd4d 1170
c19d1205
ZW
1171 default:
1172 *sizeP = 0;
499ac353 1173 return _("Unrecognized or unsupported floating point constant");
c19d1205 1174 }
b99bd4ef 1175
c19d1205
ZW
1176 t = atof_ieee (input_line_pointer, type, words);
1177 if (t)
1178 input_line_pointer = t;
499ac353 1179 *sizeP = prec * sizeof (LITTLENUM_TYPE);
b99bd4ef 1180
c19d1205
ZW
1181 if (target_big_endian)
1182 {
1183 for (i = 0; i < prec; i++)
1184 {
499ac353
NC
1185 md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
1186 litP += sizeof (LITTLENUM_TYPE);
c19d1205
ZW
1187 }
1188 }
1189 else
1190 {
e74cfd16 1191 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_endian_pure))
c19d1205
ZW
1192 for (i = prec - 1; i >= 0; i--)
1193 {
499ac353
NC
1194 md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
1195 litP += sizeof (LITTLENUM_TYPE);
c19d1205
ZW
1196 }
1197 else
1198 /* For a 4 byte float the order of elements in `words' is 1 0.
1199 For an 8 byte float the order is 1 0 3 2. */
1200 for (i = 0; i < prec; i += 2)
1201 {
499ac353
NC
1202 md_number_to_chars (litP, (valueT) words[i + 1],
1203 sizeof (LITTLENUM_TYPE));
1204 md_number_to_chars (litP + sizeof (LITTLENUM_TYPE),
1205 (valueT) words[i], sizeof (LITTLENUM_TYPE));
1206 litP += 2 * sizeof (LITTLENUM_TYPE);
c19d1205
ZW
1207 }
1208 }
b99bd4ef 1209
499ac353 1210 return NULL;
c19d1205 1211}
b99bd4ef 1212
c19d1205
ZW
1213/* We handle all bad expressions here, so that we can report the faulty
1214 instruction in the error message. */
0198d5e6 1215
c19d1205 1216void
91d6fa6a 1217md_operand (expressionS * exp)
c19d1205
ZW
1218{
1219 if (in_my_get_expression)
91d6fa6a 1220 exp->X_op = O_illegal;
b99bd4ef
NC
1221}
1222
c19d1205 1223/* Immediate values. */
b99bd4ef 1224
0198d5e6 1225#ifdef OBJ_ELF
c19d1205
ZW
1226/* Generic immediate-value read function for use in directives.
1227 Accepts anything that 'expression' can fold to a constant.
1228 *val receives the number. */
0198d5e6 1229
c19d1205
ZW
1230static int
1231immediate_for_directive (int *val)
b99bd4ef 1232{
c19d1205
ZW
1233 expressionS exp;
1234 exp.X_op = O_illegal;
b99bd4ef 1235
c19d1205
ZW
1236 if (is_immediate_prefix (*input_line_pointer))
1237 {
1238 input_line_pointer++;
1239 expression (&exp);
1240 }
b99bd4ef 1241
c19d1205
ZW
1242 if (exp.X_op != O_constant)
1243 {
1244 as_bad (_("expected #constant"));
1245 ignore_rest_of_line ();
1246 return FAIL;
1247 }
1248 *val = exp.X_add_number;
1249 return SUCCESS;
b99bd4ef 1250}
c19d1205 1251#endif
b99bd4ef 1252
c19d1205 1253/* Register parsing. */
b99bd4ef 1254
c19d1205
ZW
1255/* Generic register parser. CCP points to what should be the
1256 beginning of a register name. If it is indeed a valid register
1257 name, advance CCP over it and return the reg_entry structure;
1258 otherwise return NULL. Does not issue diagnostics. */
1259
1260static struct reg_entry *
1261arm_reg_parse_multi (char **ccp)
b99bd4ef 1262{
c19d1205
ZW
1263 char *start = *ccp;
1264 char *p;
1265 struct reg_entry *reg;
b99bd4ef 1266
477330fc
RM
1267 skip_whitespace (start);
1268
c19d1205
ZW
1269#ifdef REGISTER_PREFIX
1270 if (*start != REGISTER_PREFIX)
01cfc07f 1271 return NULL;
c19d1205
ZW
1272 start++;
1273#endif
1274#ifdef OPTIONAL_REGISTER_PREFIX
1275 if (*start == OPTIONAL_REGISTER_PREFIX)
1276 start++;
1277#endif
b99bd4ef 1278
c19d1205
ZW
1279 p = start;
1280 if (!ISALPHA (*p) || !is_name_beginner (*p))
1281 return NULL;
b99bd4ef 1282
c19d1205
ZW
1283 do
1284 p++;
1285 while (ISALPHA (*p) || ISDIGIT (*p) || *p == '_');
1286
1287 reg = (struct reg_entry *) hash_find_n (arm_reg_hsh, start, p - start);
1288
1289 if (!reg)
1290 return NULL;
1291
1292 *ccp = p;
1293 return reg;
b99bd4ef
NC
1294}
1295
1296static int
dcbf9037 1297arm_reg_alt_syntax (char **ccp, char *start, struct reg_entry *reg,
477330fc 1298 enum arm_reg_type type)
b99bd4ef 1299{
c19d1205
ZW
1300 /* Alternative syntaxes are accepted for a few register classes. */
1301 switch (type)
1302 {
1303 case REG_TYPE_MVF:
1304 case REG_TYPE_MVD:
1305 case REG_TYPE_MVFX:
1306 case REG_TYPE_MVDX:
1307 /* Generic coprocessor register names are allowed for these. */
79134647 1308 if (reg && reg->type == REG_TYPE_CN)
c19d1205
ZW
1309 return reg->number;
1310 break;
69b97547 1311
c19d1205
ZW
1312 case REG_TYPE_CP:
1313 /* For backward compatibility, a bare number is valid here. */
1314 {
1315 unsigned long processor = strtoul (start, ccp, 10);
1316 if (*ccp != start && processor <= 15)
1317 return processor;
1318 }
1a0670f3 1319 /* Fall through. */
6057a28f 1320
c19d1205
ZW
1321 case REG_TYPE_MMXWC:
1322 /* WC includes WCG. ??? I'm not sure this is true for all
1323 instructions that take WC registers. */
79134647 1324 if (reg && reg->type == REG_TYPE_MMXWCG)
c19d1205 1325 return reg->number;
6057a28f 1326 break;
c19d1205 1327
6057a28f 1328 default:
c19d1205 1329 break;
6057a28f
NC
1330 }
1331
dcbf9037
JB
1332 return FAIL;
1333}
1334
1335/* As arm_reg_parse_multi, but the register must be of type TYPE, and the
1336 return value is the register number or FAIL. */
1337
1338static int
1339arm_reg_parse (char **ccp, enum arm_reg_type type)
1340{
1341 char *start = *ccp;
1342 struct reg_entry *reg = arm_reg_parse_multi (ccp);
1343 int ret;
1344
1345 /* Do not allow a scalar (reg+index) to parse as a register. */
1346 if (reg && reg->neon && (reg->neon->defined & NTA_HASINDEX))
1347 return FAIL;
1348
1349 if (reg && reg->type == type)
1350 return reg->number;
1351
1352 if ((ret = arm_reg_alt_syntax (ccp, start, reg, type)) != FAIL)
1353 return ret;
1354
c19d1205
ZW
1355 *ccp = start;
1356 return FAIL;
1357}
69b97547 1358
dcbf9037
JB
1359/* Parse a Neon type specifier. *STR should point at the leading '.'
1360 character. Does no verification at this stage that the type fits the opcode
1361 properly. E.g.,
1362
1363 .i32.i32.s16
1364 .s32.f32
1365 .u16
1366
1367 Can all be legally parsed by this function.
1368
1369 Fills in neon_type struct pointer with parsed information, and updates STR
1370 to point after the parsed type specifier. Returns SUCCESS if this was a legal
1371 type, FAIL if not. */
1372
1373static int
1374parse_neon_type (struct neon_type *type, char **str)
1375{
1376 char *ptr = *str;
1377
1378 if (type)
1379 type->elems = 0;
1380
1381 while (type->elems < NEON_MAX_TYPE_ELS)
1382 {
1383 enum neon_el_type thistype = NT_untyped;
1384 unsigned thissize = -1u;
1385
1386 if (*ptr != '.')
1387 break;
1388
1389 ptr++;
1390
1391 /* Just a size without an explicit type. */
1392 if (ISDIGIT (*ptr))
1393 goto parsesize;
1394
1395 switch (TOLOWER (*ptr))
1396 {
1397 case 'i': thistype = NT_integer; break;
1398 case 'f': thistype = NT_float; break;
1399 case 'p': thistype = NT_poly; break;
1400 case 's': thistype = NT_signed; break;
1401 case 'u': thistype = NT_unsigned; break;
477330fc
RM
1402 case 'd':
1403 thistype = NT_float;
1404 thissize = 64;
1405 ptr++;
1406 goto done;
dcbf9037
JB
1407 default:
1408 as_bad (_("unexpected character `%c' in type specifier"), *ptr);
1409 return FAIL;
1410 }
1411
1412 ptr++;
1413
1414 /* .f is an abbreviation for .f32. */
1415 if (thistype == NT_float && !ISDIGIT (*ptr))
1416 thissize = 32;
1417 else
1418 {
1419 parsesize:
1420 thissize = strtoul (ptr, &ptr, 10);
1421
1422 if (thissize != 8 && thissize != 16 && thissize != 32
477330fc
RM
1423 && thissize != 64)
1424 {
1425 as_bad (_("bad size %d in type specifier"), thissize);
dcbf9037
JB
1426 return FAIL;
1427 }
1428 }
1429
037e8744 1430 done:
dcbf9037 1431 if (type)
477330fc
RM
1432 {
1433 type->el[type->elems].type = thistype;
dcbf9037
JB
1434 type->el[type->elems].size = thissize;
1435 type->elems++;
1436 }
1437 }
1438
1439 /* Empty/missing type is not a successful parse. */
1440 if (type->elems == 0)
1441 return FAIL;
1442
1443 *str = ptr;
1444
1445 return SUCCESS;
1446}
1447
1448/* Errors may be set multiple times during parsing or bit encoding
1449 (particularly in the Neon bits), but usually the earliest error which is set
1450 will be the most meaningful. Avoid overwriting it with later (cascading)
1451 errors by calling this function. */
1452
1453static void
1454first_error (const char *err)
1455{
1456 if (!inst.error)
1457 inst.error = err;
1458}
1459
1460/* Parse a single type, e.g. ".s32", leading period included. */
1461static int
1462parse_neon_operand_type (struct neon_type_el *vectype, char **ccp)
1463{
1464 char *str = *ccp;
1465 struct neon_type optype;
1466
1467 if (*str == '.')
1468 {
1469 if (parse_neon_type (&optype, &str) == SUCCESS)
477330fc
RM
1470 {
1471 if (optype.elems == 1)
1472 *vectype = optype.el[0];
1473 else
1474 {
1475 first_error (_("only one type should be specified for operand"));
1476 return FAIL;
1477 }
1478 }
dcbf9037 1479 else
477330fc
RM
1480 {
1481 first_error (_("vector type expected"));
1482 return FAIL;
1483 }
dcbf9037
JB
1484 }
1485 else
1486 return FAIL;
5f4273c7 1487
dcbf9037 1488 *ccp = str;
5f4273c7 1489
dcbf9037
JB
1490 return SUCCESS;
1491}
1492
1493/* Special meanings for indices (which have a range of 0-7), which will fit into
1494 a 4-bit integer. */
1495
1496#define NEON_ALL_LANES 15
1497#define NEON_INTERLEAVE_LANES 14
1498
1499/* Parse either a register or a scalar, with an optional type. Return the
1500 register number, and optionally fill in the actual type of the register
1501 when multiple alternatives were given (NEON_TYPE_NDQ) in *RTYPE, and
1502 type/index information in *TYPEINFO. */
1503
1504static int
1505parse_typed_reg_or_scalar (char **ccp, enum arm_reg_type type,
477330fc
RM
1506 enum arm_reg_type *rtype,
1507 struct neon_typed_alias *typeinfo)
dcbf9037
JB
1508{
1509 char *str = *ccp;
1510 struct reg_entry *reg = arm_reg_parse_multi (&str);
1511 struct neon_typed_alias atype;
1512 struct neon_type_el parsetype;
1513
1514 atype.defined = 0;
1515 atype.index = -1;
1516 atype.eltype.type = NT_invtype;
1517 atype.eltype.size = -1;
1518
1519 /* Try alternate syntax for some types of register. Note these are mutually
1520 exclusive with the Neon syntax extensions. */
1521 if (reg == NULL)
1522 {
1523 int altreg = arm_reg_alt_syntax (&str, *ccp, reg, type);
1524 if (altreg != FAIL)
477330fc 1525 *ccp = str;
dcbf9037 1526 if (typeinfo)
477330fc 1527 *typeinfo = atype;
dcbf9037
JB
1528 return altreg;
1529 }
1530
037e8744
JB
1531 /* Undo polymorphism when a set of register types may be accepted. */
1532 if ((type == REG_TYPE_NDQ
1533 && (reg->type == REG_TYPE_NQ || reg->type == REG_TYPE_VFD))
1534 || (type == REG_TYPE_VFSD
477330fc 1535 && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD))
037e8744 1536 || (type == REG_TYPE_NSDQ
477330fc
RM
1537 && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD
1538 || reg->type == REG_TYPE_NQ))
dec41383
JW
1539 || (type == REG_TYPE_NSD
1540 && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD))
f512f76f
NC
1541 || (type == REG_TYPE_MMXWC
1542 && (reg->type == REG_TYPE_MMXWCG)))
21d799b5 1543 type = (enum arm_reg_type) reg->type;
dcbf9037
JB
1544
1545 if (type != reg->type)
1546 return FAIL;
1547
1548 if (reg->neon)
1549 atype = *reg->neon;
5f4273c7 1550
dcbf9037
JB
1551 if (parse_neon_operand_type (&parsetype, &str) == SUCCESS)
1552 {
1553 if ((atype.defined & NTA_HASTYPE) != 0)
477330fc
RM
1554 {
1555 first_error (_("can't redefine type for operand"));
1556 return FAIL;
1557 }
dcbf9037
JB
1558 atype.defined |= NTA_HASTYPE;
1559 atype.eltype = parsetype;
1560 }
5f4273c7 1561
dcbf9037
JB
1562 if (skip_past_char (&str, '[') == SUCCESS)
1563 {
dec41383
JW
1564 if (type != REG_TYPE_VFD
1565 && !(type == REG_TYPE_VFS
1566 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_2)))
477330fc
RM
1567 {
1568 first_error (_("only D registers may be indexed"));
1569 return FAIL;
1570 }
5f4273c7 1571
dcbf9037 1572 if ((atype.defined & NTA_HASINDEX) != 0)
477330fc
RM
1573 {
1574 first_error (_("can't change index for operand"));
1575 return FAIL;
1576 }
dcbf9037
JB
1577
1578 atype.defined |= NTA_HASINDEX;
1579
1580 if (skip_past_char (&str, ']') == SUCCESS)
477330fc 1581 atype.index = NEON_ALL_LANES;
dcbf9037 1582 else
477330fc
RM
1583 {
1584 expressionS exp;
dcbf9037 1585
477330fc 1586 my_get_expression (&exp, &str, GE_NO_PREFIX);
dcbf9037 1587
477330fc
RM
1588 if (exp.X_op != O_constant)
1589 {
1590 first_error (_("constant expression required"));
1591 return FAIL;
1592 }
dcbf9037 1593
477330fc
RM
1594 if (skip_past_char (&str, ']') == FAIL)
1595 return FAIL;
dcbf9037 1596
477330fc
RM
1597 atype.index = exp.X_add_number;
1598 }
dcbf9037 1599 }
5f4273c7 1600
dcbf9037
JB
1601 if (typeinfo)
1602 *typeinfo = atype;
5f4273c7 1603
dcbf9037
JB
1604 if (rtype)
1605 *rtype = type;
5f4273c7 1606
dcbf9037 1607 *ccp = str;
5f4273c7 1608
dcbf9037
JB
1609 return reg->number;
1610}
1611
efd6b359 1612/* Like arm_reg_parse, but also allow the following extra features:
dcbf9037
JB
1613 - If RTYPE is non-zero, return the (possibly restricted) type of the
1614 register (e.g. Neon double or quad reg when either has been requested).
1615 - If this is a Neon vector type with additional type information, fill
1616 in the struct pointed to by VECTYPE (if non-NULL).
5f4273c7 1617 This function will fault on encountering a scalar. */
dcbf9037
JB
1618
1619static int
1620arm_typed_reg_parse (char **ccp, enum arm_reg_type type,
477330fc 1621 enum arm_reg_type *rtype, struct neon_type_el *vectype)
dcbf9037
JB
1622{
1623 struct neon_typed_alias atype;
1624 char *str = *ccp;
1625 int reg = parse_typed_reg_or_scalar (&str, type, rtype, &atype);
1626
1627 if (reg == FAIL)
1628 return FAIL;
1629
0855e32b
NS
1630 /* Do not allow regname(... to parse as a register. */
1631 if (*str == '(')
1632 return FAIL;
1633
dcbf9037
JB
1634 /* Do not allow a scalar (reg+index) to parse as a register. */
1635 if ((atype.defined & NTA_HASINDEX) != 0)
1636 {
1637 first_error (_("register operand expected, but got scalar"));
1638 return FAIL;
1639 }
1640
1641 if (vectype)
1642 *vectype = atype.eltype;
1643
1644 *ccp = str;
1645
1646 return reg;
1647}
1648
1649#define NEON_SCALAR_REG(X) ((X) >> 4)
1650#define NEON_SCALAR_INDEX(X) ((X) & 15)
1651
5287ad62
JB
1652/* Parse a Neon scalar. Most of the time when we're parsing a scalar, we don't
1653 have enough information to be able to do a good job bounds-checking. So, we
1654 just do easy checks here, and do further checks later. */
1655
1656static int
dcbf9037 1657parse_scalar (char **ccp, int elsize, struct neon_type_el *type)
5287ad62 1658{
dcbf9037 1659 int reg;
5287ad62 1660 char *str = *ccp;
dcbf9037 1661 struct neon_typed_alias atype;
dec41383
JW
1662 enum arm_reg_type reg_type = REG_TYPE_VFD;
1663
1664 if (elsize == 4)
1665 reg_type = REG_TYPE_VFS;
5f4273c7 1666
dec41383 1667 reg = parse_typed_reg_or_scalar (&str, reg_type, NULL, &atype);
5f4273c7 1668
dcbf9037 1669 if (reg == FAIL || (atype.defined & NTA_HASINDEX) == 0)
5287ad62 1670 return FAIL;
5f4273c7 1671
dcbf9037 1672 if (atype.index == NEON_ALL_LANES)
5287ad62 1673 {
dcbf9037 1674 first_error (_("scalar must have an index"));
5287ad62
JB
1675 return FAIL;
1676 }
dcbf9037 1677 else if (atype.index >= 64 / elsize)
5287ad62 1678 {
dcbf9037 1679 first_error (_("scalar index out of range"));
5287ad62
JB
1680 return FAIL;
1681 }
5f4273c7 1682
dcbf9037
JB
1683 if (type)
1684 *type = atype.eltype;
5f4273c7 1685
5287ad62 1686 *ccp = str;
5f4273c7 1687
dcbf9037 1688 return reg * 16 + atype.index;
5287ad62
JB
1689}
1690
4b5a202f
AV
1691/* Types of registers in a list. */
1692
1693enum reg_list_els
1694{
1695 REGLIST_RN,
1696 REGLIST_CLRM,
1697 REGLIST_VFP_S,
efd6b359 1698 REGLIST_VFP_S_VPR,
4b5a202f 1699 REGLIST_VFP_D,
efd6b359 1700 REGLIST_VFP_D_VPR,
4b5a202f
AV
1701 REGLIST_NEON_D
1702};
1703
c19d1205 1704/* Parse an ARM register list. Returns the bitmask, or FAIL. */
e07e6e58 1705
c19d1205 1706static long
4b5a202f 1707parse_reg_list (char ** strp, enum reg_list_els etype)
c19d1205 1708{
4b5a202f
AV
1709 char *str = *strp;
1710 long range = 0;
1711 int another_range;
1712
1713 gas_assert (etype == REGLIST_RN || etype == REGLIST_CLRM);
a737bd4d 1714
c19d1205
ZW
1715 /* We come back here if we get ranges concatenated by '+' or '|'. */
1716 do
6057a28f 1717 {
477330fc
RM
1718 skip_whitespace (str);
1719
c19d1205 1720 another_range = 0;
a737bd4d 1721
c19d1205
ZW
1722 if (*str == '{')
1723 {
1724 int in_range = 0;
1725 int cur_reg = -1;
a737bd4d 1726
c19d1205
ZW
1727 str++;
1728 do
1729 {
1730 int reg;
4b5a202f
AV
1731 const char apsr_str[] = "apsr";
1732 int apsr_str_len = strlen (apsr_str);
6057a28f 1733
4b5a202f
AV
1734 reg = arm_reg_parse (&str, REGLIST_RN);
1735 if (etype == REGLIST_CLRM)
c19d1205 1736 {
4b5a202f
AV
1737 if (reg == REG_SP || reg == REG_PC)
1738 reg = FAIL;
1739 else if (reg == FAIL
1740 && !strncasecmp (str, apsr_str, apsr_str_len)
1741 && !ISALPHA (*(str + apsr_str_len)))
1742 {
1743 reg = 15;
1744 str += apsr_str_len;
1745 }
1746
1747 if (reg == FAIL)
1748 {
1749 first_error (_("r0-r12, lr or APSR expected"));
1750 return FAIL;
1751 }
1752 }
1753 else /* etype == REGLIST_RN. */
1754 {
1755 if (reg == FAIL)
1756 {
1757 first_error (_(reg_expected_msgs[REGLIST_RN]));
1758 return FAIL;
1759 }
c19d1205 1760 }
a737bd4d 1761
c19d1205
ZW
1762 if (in_range)
1763 {
1764 int i;
a737bd4d 1765
c19d1205
ZW
1766 if (reg <= cur_reg)
1767 {
dcbf9037 1768 first_error (_("bad range in register list"));
c19d1205
ZW
1769 return FAIL;
1770 }
40a18ebd 1771
c19d1205
ZW
1772 for (i = cur_reg + 1; i < reg; i++)
1773 {
1774 if (range & (1 << i))
1775 as_tsktsk
1776 (_("Warning: duplicated register (r%d) in register list"),
1777 i);
1778 else
1779 range |= 1 << i;
1780 }
1781 in_range = 0;
1782 }
a737bd4d 1783
c19d1205
ZW
1784 if (range & (1 << reg))
1785 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
1786 reg);
1787 else if (reg <= cur_reg)
1788 as_tsktsk (_("Warning: register range not in ascending order"));
a737bd4d 1789
c19d1205
ZW
1790 range |= 1 << reg;
1791 cur_reg = reg;
1792 }
1793 while (skip_past_comma (&str) != FAIL
1794 || (in_range = 1, *str++ == '-'));
1795 str--;
a737bd4d 1796
d996d970 1797 if (skip_past_char (&str, '}') == FAIL)
c19d1205 1798 {
dcbf9037 1799 first_error (_("missing `}'"));
c19d1205
ZW
1800 return FAIL;
1801 }
1802 }
4b5a202f 1803 else if (etype == REGLIST_RN)
c19d1205 1804 {
91d6fa6a 1805 expressionS exp;
40a18ebd 1806
91d6fa6a 1807 if (my_get_expression (&exp, &str, GE_NO_PREFIX))
c19d1205 1808 return FAIL;
40a18ebd 1809
91d6fa6a 1810 if (exp.X_op == O_constant)
c19d1205 1811 {
91d6fa6a
NC
1812 if (exp.X_add_number
1813 != (exp.X_add_number & 0x0000ffff))
c19d1205
ZW
1814 {
1815 inst.error = _("invalid register mask");
1816 return FAIL;
1817 }
a737bd4d 1818
91d6fa6a 1819 if ((range & exp.X_add_number) != 0)
c19d1205 1820 {
91d6fa6a 1821 int regno = range & exp.X_add_number;
a737bd4d 1822
c19d1205
ZW
1823 regno &= -regno;
1824 regno = (1 << regno) - 1;
1825 as_tsktsk
1826 (_("Warning: duplicated register (r%d) in register list"),
1827 regno);
1828 }
a737bd4d 1829
91d6fa6a 1830 range |= exp.X_add_number;
c19d1205
ZW
1831 }
1832 else
1833 {
e2b0ab59 1834 if (inst.relocs[0].type != 0)
c19d1205
ZW
1835 {
1836 inst.error = _("expression too complex");
1837 return FAIL;
1838 }
a737bd4d 1839
e2b0ab59
AV
1840 memcpy (&inst.relocs[0].exp, &exp, sizeof (expressionS));
1841 inst.relocs[0].type = BFD_RELOC_ARM_MULTI;
1842 inst.relocs[0].pc_rel = 0;
c19d1205
ZW
1843 }
1844 }
a737bd4d 1845
c19d1205
ZW
1846 if (*str == '|' || *str == '+')
1847 {
1848 str++;
1849 another_range = 1;
1850 }
a737bd4d 1851 }
c19d1205 1852 while (another_range);
a737bd4d 1853
c19d1205
ZW
1854 *strp = str;
1855 return range;
a737bd4d
NC
1856}
1857
c19d1205
ZW
1858/* Parse a VFP register list. If the string is invalid return FAIL.
1859 Otherwise return the number of registers, and set PBASE to the first
5287ad62
JB
1860 register. Parses registers of type ETYPE.
1861 If REGLIST_NEON_D is used, several syntax enhancements are enabled:
1862 - Q registers can be used to specify pairs of D registers
1863 - { } can be omitted from around a singleton register list
477330fc
RM
1864 FIXME: This is not implemented, as it would require backtracking in
1865 some cases, e.g.:
1866 vtbl.8 d3,d4,d5
1867 This could be done (the meaning isn't really ambiguous), but doesn't
1868 fit in well with the current parsing framework.
dcbf9037
JB
1869 - 32 D registers may be used (also true for VFPv3).
1870 FIXME: Types are ignored in these register lists, which is probably a
1871 bug. */
6057a28f 1872
c19d1205 1873static int
efd6b359
AV
1874parse_vfp_reg_list (char **ccp, unsigned int *pbase, enum reg_list_els etype,
1875 bfd_boolean *partial_match)
6057a28f 1876{
037e8744 1877 char *str = *ccp;
c19d1205
ZW
1878 int base_reg;
1879 int new_base;
21d799b5 1880 enum arm_reg_type regtype = (enum arm_reg_type) 0;
5287ad62 1881 int max_regs = 0;
c19d1205
ZW
1882 int count = 0;
1883 int warned = 0;
1884 unsigned long mask = 0;
a737bd4d 1885 int i;
efd6b359
AV
1886 bfd_boolean vpr_seen = FALSE;
1887 bfd_boolean expect_vpr =
1888 (etype == REGLIST_VFP_S_VPR) || (etype == REGLIST_VFP_D_VPR);
6057a28f 1889
477330fc 1890 if (skip_past_char (&str, '{') == FAIL)
5287ad62
JB
1891 {
1892 inst.error = _("expecting {");
1893 return FAIL;
1894 }
6057a28f 1895
5287ad62 1896 switch (etype)
c19d1205 1897 {
5287ad62 1898 case REGLIST_VFP_S:
efd6b359 1899 case REGLIST_VFP_S_VPR:
c19d1205
ZW
1900 regtype = REG_TYPE_VFS;
1901 max_regs = 32;
5287ad62 1902 break;
5f4273c7 1903
5287ad62 1904 case REGLIST_VFP_D:
efd6b359 1905 case REGLIST_VFP_D_VPR:
5287ad62 1906 regtype = REG_TYPE_VFD;
b7fc2769 1907 break;
5f4273c7 1908
b7fc2769
JB
1909 case REGLIST_NEON_D:
1910 regtype = REG_TYPE_NDQ;
1911 break;
4b5a202f
AV
1912
1913 default:
1914 gas_assert (0);
b7fc2769
JB
1915 }
1916
efd6b359 1917 if (etype != REGLIST_VFP_S && etype != REGLIST_VFP_S_VPR)
b7fc2769 1918 {
b1cc4aeb
PB
1919 /* VFPv3 allows 32 D registers, except for the VFPv3-D16 variant. */
1920 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
477330fc
RM
1921 {
1922 max_regs = 32;
1923 if (thumb_mode)
1924 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
1925 fpu_vfp_ext_d32);
1926 else
1927 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
1928 fpu_vfp_ext_d32);
1929 }
5287ad62 1930 else
477330fc 1931 max_regs = 16;
c19d1205 1932 }
6057a28f 1933
c19d1205 1934 base_reg = max_regs;
efd6b359 1935 *partial_match = FALSE;
a737bd4d 1936
c19d1205
ZW
1937 do
1938 {
5287ad62 1939 int setmask = 1, addregs = 1;
efd6b359
AV
1940 const char vpr_str[] = "vpr";
1941 int vpr_str_len = strlen (vpr_str);
dcbf9037 1942
037e8744 1943 new_base = arm_typed_reg_parse (&str, regtype, &regtype, NULL);
dcbf9037 1944
efd6b359
AV
1945 if (expect_vpr)
1946 {
1947 if (new_base == FAIL
1948 && !strncasecmp (str, vpr_str, vpr_str_len)
1949 && !ISALPHA (*(str + vpr_str_len))
1950 && !vpr_seen)
1951 {
1952 vpr_seen = TRUE;
1953 str += vpr_str_len;
1954 if (count == 0)
1955 base_reg = 0; /* Canonicalize VPR only on d0 with 0 regs. */
1956 }
1957 else if (vpr_seen)
1958 {
1959 first_error (_("VPR expected last"));
1960 return FAIL;
1961 }
1962 else if (new_base == FAIL)
1963 {
1964 if (regtype == REG_TYPE_VFS)
1965 first_error (_("VFP single precision register or VPR "
1966 "expected"));
1967 else /* regtype == REG_TYPE_VFD. */
1968 first_error (_("VFP/Neon double precision register or VPR "
1969 "expected"));
1970 return FAIL;
1971 }
1972 }
1973 else if (new_base == FAIL)
a737bd4d 1974 {
dcbf9037 1975 first_error (_(reg_expected_msgs[regtype]));
c19d1205
ZW
1976 return FAIL;
1977 }
5f4273c7 1978
efd6b359
AV
1979 *partial_match = TRUE;
1980 if (vpr_seen)
1981 continue;
1982
b7fc2769 1983 if (new_base >= max_regs)
477330fc
RM
1984 {
1985 first_error (_("register out of range in list"));
1986 return FAIL;
1987 }
5f4273c7 1988
5287ad62
JB
1989 /* Note: a value of 2 * n is returned for the register Q<n>. */
1990 if (regtype == REG_TYPE_NQ)
477330fc
RM
1991 {
1992 setmask = 3;
1993 addregs = 2;
1994 }
5287ad62 1995
c19d1205
ZW
1996 if (new_base < base_reg)
1997 base_reg = new_base;
a737bd4d 1998
5287ad62 1999 if (mask & (setmask << new_base))
c19d1205 2000 {
dcbf9037 2001 first_error (_("invalid register list"));
c19d1205 2002 return FAIL;
a737bd4d 2003 }
a737bd4d 2004
efd6b359 2005 if ((mask >> new_base) != 0 && ! warned && !vpr_seen)
c19d1205
ZW
2006 {
2007 as_tsktsk (_("register list not in ascending order"));
2008 warned = 1;
2009 }
0bbf2aa4 2010
5287ad62
JB
2011 mask |= setmask << new_base;
2012 count += addregs;
0bbf2aa4 2013
037e8744 2014 if (*str == '-') /* We have the start of a range expression */
c19d1205
ZW
2015 {
2016 int high_range;
0bbf2aa4 2017
037e8744 2018 str++;
0bbf2aa4 2019
037e8744 2020 if ((high_range = arm_typed_reg_parse (&str, regtype, NULL, NULL))
477330fc 2021 == FAIL)
c19d1205
ZW
2022 {
2023 inst.error = gettext (reg_expected_msgs[regtype]);
2024 return FAIL;
2025 }
0bbf2aa4 2026
477330fc
RM
2027 if (high_range >= max_regs)
2028 {
2029 first_error (_("register out of range in list"));
2030 return FAIL;
2031 }
b7fc2769 2032
477330fc
RM
2033 if (regtype == REG_TYPE_NQ)
2034 high_range = high_range + 1;
5287ad62 2035
c19d1205
ZW
2036 if (high_range <= new_base)
2037 {
2038 inst.error = _("register range not in ascending order");
2039 return FAIL;
2040 }
0bbf2aa4 2041
5287ad62 2042 for (new_base += addregs; new_base <= high_range; new_base += addregs)
0bbf2aa4 2043 {
5287ad62 2044 if (mask & (setmask << new_base))
0bbf2aa4 2045 {
c19d1205
ZW
2046 inst.error = _("invalid register list");
2047 return FAIL;
0bbf2aa4 2048 }
c19d1205 2049
5287ad62
JB
2050 mask |= setmask << new_base;
2051 count += addregs;
0bbf2aa4 2052 }
0bbf2aa4 2053 }
0bbf2aa4 2054 }
037e8744 2055 while (skip_past_comma (&str) != FAIL);
0bbf2aa4 2056
037e8744 2057 str++;
0bbf2aa4 2058
c19d1205 2059 /* Sanity check -- should have raised a parse error above. */
efd6b359 2060 if ((!vpr_seen && count == 0) || count > max_regs)
c19d1205
ZW
2061 abort ();
2062
2063 *pbase = base_reg;
2064
efd6b359
AV
2065 if (expect_vpr && !vpr_seen)
2066 {
2067 first_error (_("VPR expected last"));
2068 return FAIL;
2069 }
2070
c19d1205
ZW
2071 /* Final test -- the registers must be consecutive. */
2072 mask >>= base_reg;
2073 for (i = 0; i < count; i++)
2074 {
2075 if ((mask & (1u << i)) == 0)
2076 {
2077 inst.error = _("non-contiguous register range");
2078 return FAIL;
2079 }
2080 }
2081
037e8744
JB
2082 *ccp = str;
2083
c19d1205 2084 return count;
b99bd4ef
NC
2085}
2086
dcbf9037
JB
2087/* True if two alias types are the same. */
2088
c921be7d 2089static bfd_boolean
dcbf9037
JB
2090neon_alias_types_same (struct neon_typed_alias *a, struct neon_typed_alias *b)
2091{
2092 if (!a && !b)
c921be7d 2093 return TRUE;
5f4273c7 2094
dcbf9037 2095 if (!a || !b)
c921be7d 2096 return FALSE;
dcbf9037
JB
2097
2098 if (a->defined != b->defined)
c921be7d 2099 return FALSE;
5f4273c7 2100
dcbf9037
JB
2101 if ((a->defined & NTA_HASTYPE) != 0
2102 && (a->eltype.type != b->eltype.type
477330fc 2103 || a->eltype.size != b->eltype.size))
c921be7d 2104 return FALSE;
dcbf9037
JB
2105
2106 if ((a->defined & NTA_HASINDEX) != 0
2107 && (a->index != b->index))
c921be7d 2108 return FALSE;
5f4273c7 2109
c921be7d 2110 return TRUE;
dcbf9037
JB
2111}
2112
5287ad62
JB
2113/* Parse element/structure lists for Neon VLD<n> and VST<n> instructions.
2114 The base register is put in *PBASE.
dcbf9037 2115 The lane (or one of the NEON_*_LANES constants) is placed in bits [3:0] of
5287ad62
JB
2116 the return value.
2117 The register stride (minus one) is put in bit 4 of the return value.
dcbf9037
JB
2118 Bits [6:5] encode the list length (minus one).
2119 The type of the list elements is put in *ELTYPE, if non-NULL. */
5287ad62 2120
5287ad62 2121#define NEON_LANE(X) ((X) & 0xf)
dcbf9037 2122#define NEON_REG_STRIDE(X) ((((X) >> 4) & 1) + 1)
5287ad62
JB
2123#define NEON_REGLIST_LENGTH(X) ((((X) >> 5) & 3) + 1)
2124
2125static int
dcbf9037 2126parse_neon_el_struct_list (char **str, unsigned *pbase,
477330fc 2127 struct neon_type_el *eltype)
5287ad62
JB
2128{
2129 char *ptr = *str;
2130 int base_reg = -1;
2131 int reg_incr = -1;
2132 int count = 0;
2133 int lane = -1;
2134 int leading_brace = 0;
2135 enum arm_reg_type rtype = REG_TYPE_NDQ;
20203fb9
NC
2136 const char *const incr_error = _("register stride must be 1 or 2");
2137 const char *const type_error = _("mismatched element/structure types in list");
dcbf9037 2138 struct neon_typed_alias firsttype;
f85d59c3
KT
2139 firsttype.defined = 0;
2140 firsttype.eltype.type = NT_invtype;
2141 firsttype.eltype.size = -1;
2142 firsttype.index = -1;
5f4273c7 2143
5287ad62
JB
2144 if (skip_past_char (&ptr, '{') == SUCCESS)
2145 leading_brace = 1;
5f4273c7 2146
5287ad62
JB
2147 do
2148 {
dcbf9037
JB
2149 struct neon_typed_alias atype;
2150 int getreg = parse_typed_reg_or_scalar (&ptr, rtype, &rtype, &atype);
2151
5287ad62 2152 if (getreg == FAIL)
477330fc
RM
2153 {
2154 first_error (_(reg_expected_msgs[rtype]));
2155 return FAIL;
2156 }
5f4273c7 2157
5287ad62 2158 if (base_reg == -1)
477330fc
RM
2159 {
2160 base_reg = getreg;
2161 if (rtype == REG_TYPE_NQ)
2162 {
2163 reg_incr = 1;
2164 }
2165 firsttype = atype;
2166 }
5287ad62 2167 else if (reg_incr == -1)
477330fc
RM
2168 {
2169 reg_incr = getreg - base_reg;
2170 if (reg_incr < 1 || reg_incr > 2)
2171 {
2172 first_error (_(incr_error));
2173 return FAIL;
2174 }
2175 }
5287ad62 2176 else if (getreg != base_reg + reg_incr * count)
477330fc
RM
2177 {
2178 first_error (_(incr_error));
2179 return FAIL;
2180 }
dcbf9037 2181
c921be7d 2182 if (! neon_alias_types_same (&atype, &firsttype))
477330fc
RM
2183 {
2184 first_error (_(type_error));
2185 return FAIL;
2186 }
5f4273c7 2187
5287ad62 2188 /* Handle Dn-Dm or Qn-Qm syntax. Can only be used with non-indexed list
477330fc 2189 modes. */
5287ad62 2190 if (ptr[0] == '-')
477330fc
RM
2191 {
2192 struct neon_typed_alias htype;
2193 int hireg, dregs = (rtype == REG_TYPE_NQ) ? 2 : 1;
2194 if (lane == -1)
2195 lane = NEON_INTERLEAVE_LANES;
2196 else if (lane != NEON_INTERLEAVE_LANES)
2197 {
2198 first_error (_(type_error));
2199 return FAIL;
2200 }
2201 if (reg_incr == -1)
2202 reg_incr = 1;
2203 else if (reg_incr != 1)
2204 {
2205 first_error (_("don't use Rn-Rm syntax with non-unit stride"));
2206 return FAIL;
2207 }
2208 ptr++;
2209 hireg = parse_typed_reg_or_scalar (&ptr, rtype, NULL, &htype);
2210 if (hireg == FAIL)
2211 {
2212 first_error (_(reg_expected_msgs[rtype]));
2213 return FAIL;
2214 }
2215 if (! neon_alias_types_same (&htype, &firsttype))
2216 {
2217 first_error (_(type_error));
2218 return FAIL;
2219 }
2220 count += hireg + dregs - getreg;
2221 continue;
2222 }
5f4273c7 2223
5287ad62
JB
2224 /* If we're using Q registers, we can't use [] or [n] syntax. */
2225 if (rtype == REG_TYPE_NQ)
477330fc
RM
2226 {
2227 count += 2;
2228 continue;
2229 }
5f4273c7 2230
dcbf9037 2231 if ((atype.defined & NTA_HASINDEX) != 0)
477330fc
RM
2232 {
2233 if (lane == -1)
2234 lane = atype.index;
2235 else if (lane != atype.index)
2236 {
2237 first_error (_(type_error));
2238 return FAIL;
2239 }
2240 }
5287ad62 2241 else if (lane == -1)
477330fc 2242 lane = NEON_INTERLEAVE_LANES;
5287ad62 2243 else if (lane != NEON_INTERLEAVE_LANES)
477330fc
RM
2244 {
2245 first_error (_(type_error));
2246 return FAIL;
2247 }
5287ad62
JB
2248 count++;
2249 }
2250 while ((count != 1 || leading_brace) && skip_past_comma (&ptr) != FAIL);
5f4273c7 2251
5287ad62
JB
2252 /* No lane set by [x]. We must be interleaving structures. */
2253 if (lane == -1)
2254 lane = NEON_INTERLEAVE_LANES;
5f4273c7 2255
5287ad62
JB
2256 /* Sanity check. */
2257 if (lane == -1 || base_reg == -1 || count < 1 || count > 4
2258 || (count > 1 && reg_incr == -1))
2259 {
dcbf9037 2260 first_error (_("error parsing element/structure list"));
5287ad62
JB
2261 return FAIL;
2262 }
2263
2264 if ((count > 1 || leading_brace) && skip_past_char (&ptr, '}') == FAIL)
2265 {
dcbf9037 2266 first_error (_("expected }"));
5287ad62
JB
2267 return FAIL;
2268 }
5f4273c7 2269
5287ad62
JB
2270 if (reg_incr == -1)
2271 reg_incr = 1;
2272
dcbf9037
JB
2273 if (eltype)
2274 *eltype = firsttype.eltype;
2275
5287ad62
JB
2276 *pbase = base_reg;
2277 *str = ptr;
5f4273c7 2278
5287ad62
JB
2279 return lane | ((reg_incr - 1) << 4) | ((count - 1) << 5);
2280}
2281
c19d1205
ZW
2282/* Parse an explicit relocation suffix on an expression. This is
2283 either nothing, or a word in parentheses. Note that if !OBJ_ELF,
2284 arm_reloc_hsh contains no entries, so this function can only
2285 succeed if there is no () after the word. Returns -1 on error,
2286 BFD_RELOC_UNUSED if there wasn't any suffix. */
3da1d841 2287
c19d1205
ZW
2288static int
2289parse_reloc (char **str)
b99bd4ef 2290{
c19d1205
ZW
2291 struct reloc_entry *r;
2292 char *p, *q;
b99bd4ef 2293
c19d1205
ZW
2294 if (**str != '(')
2295 return BFD_RELOC_UNUSED;
b99bd4ef 2296
c19d1205
ZW
2297 p = *str + 1;
2298 q = p;
2299
2300 while (*q && *q != ')' && *q != ',')
2301 q++;
2302 if (*q != ')')
2303 return -1;
2304
21d799b5
NC
2305 if ((r = (struct reloc_entry *)
2306 hash_find_n (arm_reloc_hsh, p, q - p)) == NULL)
c19d1205
ZW
2307 return -1;
2308
2309 *str = q + 1;
2310 return r->reloc;
b99bd4ef
NC
2311}
2312
c19d1205
ZW
2313/* Directives: register aliases. */
2314
dcbf9037 2315static struct reg_entry *
90ec0d68 2316insert_reg_alias (char *str, unsigned number, int type)
b99bd4ef 2317{
d3ce72d0 2318 struct reg_entry *new_reg;
c19d1205 2319 const char *name;
b99bd4ef 2320
d3ce72d0 2321 if ((new_reg = (struct reg_entry *) hash_find (arm_reg_hsh, str)) != 0)
c19d1205 2322 {
d3ce72d0 2323 if (new_reg->builtin)
c19d1205 2324 as_warn (_("ignoring attempt to redefine built-in register '%s'"), str);
b99bd4ef 2325
c19d1205
ZW
2326 /* Only warn about a redefinition if it's not defined as the
2327 same register. */
d3ce72d0 2328 else if (new_reg->number != number || new_reg->type != type)
c19d1205 2329 as_warn (_("ignoring redefinition of register alias '%s'"), str);
69b97547 2330
d929913e 2331 return NULL;
c19d1205 2332 }
b99bd4ef 2333
c19d1205 2334 name = xstrdup (str);
325801bd 2335 new_reg = XNEW (struct reg_entry);
b99bd4ef 2336
d3ce72d0
NC
2337 new_reg->name = name;
2338 new_reg->number = number;
2339 new_reg->type = type;
2340 new_reg->builtin = FALSE;
2341 new_reg->neon = NULL;
b99bd4ef 2342
d3ce72d0 2343 if (hash_insert (arm_reg_hsh, name, (void *) new_reg))
c19d1205 2344 abort ();
5f4273c7 2345
d3ce72d0 2346 return new_reg;
dcbf9037
JB
2347}
2348
2349static void
2350insert_neon_reg_alias (char *str, int number, int type,
477330fc 2351 struct neon_typed_alias *atype)
dcbf9037
JB
2352{
2353 struct reg_entry *reg = insert_reg_alias (str, number, type);
5f4273c7 2354
dcbf9037
JB
2355 if (!reg)
2356 {
2357 first_error (_("attempt to redefine typed alias"));
2358 return;
2359 }
5f4273c7 2360
dcbf9037
JB
2361 if (atype)
2362 {
325801bd 2363 reg->neon = XNEW (struct neon_typed_alias);
dcbf9037
JB
2364 *reg->neon = *atype;
2365 }
c19d1205 2366}
b99bd4ef 2367
c19d1205 2368/* Look for the .req directive. This is of the form:
b99bd4ef 2369
c19d1205 2370 new_register_name .req existing_register_name
b99bd4ef 2371
c19d1205 2372 If we find one, or if it looks sufficiently like one that we want to
d929913e 2373 handle any error here, return TRUE. Otherwise return FALSE. */
b99bd4ef 2374
d929913e 2375static bfd_boolean
c19d1205
ZW
2376create_register_alias (char * newname, char *p)
2377{
2378 struct reg_entry *old;
2379 char *oldname, *nbuf;
2380 size_t nlen;
b99bd4ef 2381
c19d1205
ZW
2382 /* The input scrubber ensures that whitespace after the mnemonic is
2383 collapsed to single spaces. */
2384 oldname = p;
2385 if (strncmp (oldname, " .req ", 6) != 0)
d929913e 2386 return FALSE;
b99bd4ef 2387
c19d1205
ZW
2388 oldname += 6;
2389 if (*oldname == '\0')
d929913e 2390 return FALSE;
b99bd4ef 2391
21d799b5 2392 old = (struct reg_entry *) hash_find (arm_reg_hsh, oldname);
c19d1205 2393 if (!old)
b99bd4ef 2394 {
c19d1205 2395 as_warn (_("unknown register '%s' -- .req ignored"), oldname);
d929913e 2396 return TRUE;
b99bd4ef
NC
2397 }
2398
c19d1205
ZW
2399 /* If TC_CASE_SENSITIVE is defined, then newname already points to
2400 the desired alias name, and p points to its end. If not, then
2401 the desired alias name is in the global original_case_string. */
2402#ifdef TC_CASE_SENSITIVE
2403 nlen = p - newname;
2404#else
2405 newname = original_case_string;
2406 nlen = strlen (newname);
2407#endif
b99bd4ef 2408
29a2809e 2409 nbuf = xmemdup0 (newname, nlen);
b99bd4ef 2410
c19d1205
ZW
2411 /* Create aliases under the new name as stated; an all-lowercase
2412 version of the new name; and an all-uppercase version of the new
2413 name. */
d929913e
NC
2414 if (insert_reg_alias (nbuf, old->number, old->type) != NULL)
2415 {
2416 for (p = nbuf; *p; p++)
2417 *p = TOUPPER (*p);
c19d1205 2418
d929913e
NC
2419 if (strncmp (nbuf, newname, nlen))
2420 {
2421 /* If this attempt to create an additional alias fails, do not bother
2422 trying to create the all-lower case alias. We will fail and issue
2423 a second, duplicate error message. This situation arises when the
2424 programmer does something like:
2425 foo .req r0
2426 Foo .req r1
2427 The second .req creates the "Foo" alias but then fails to create
5f4273c7 2428 the artificial FOO alias because it has already been created by the
d929913e
NC
2429 first .req. */
2430 if (insert_reg_alias (nbuf, old->number, old->type) == NULL)
e1fa0163
NC
2431 {
2432 free (nbuf);
2433 return TRUE;
2434 }
d929913e 2435 }
c19d1205 2436
d929913e
NC
2437 for (p = nbuf; *p; p++)
2438 *p = TOLOWER (*p);
c19d1205 2439
d929913e
NC
2440 if (strncmp (nbuf, newname, nlen))
2441 insert_reg_alias (nbuf, old->number, old->type);
2442 }
c19d1205 2443
e1fa0163 2444 free (nbuf);
d929913e 2445 return TRUE;
b99bd4ef
NC
2446}
2447
dcbf9037
JB
2448/* Create a Neon typed/indexed register alias using directives, e.g.:
2449 X .dn d5.s32[1]
2450 Y .qn 6.s16
2451 Z .dn d7
2452 T .dn Z[0]
2453 These typed registers can be used instead of the types specified after the
2454 Neon mnemonic, so long as all operands given have types. Types can also be
2455 specified directly, e.g.:
5f4273c7 2456 vadd d0.s32, d1.s32, d2.s32 */
dcbf9037 2457
c921be7d 2458static bfd_boolean
dcbf9037
JB
2459create_neon_reg_alias (char *newname, char *p)
2460{
2461 enum arm_reg_type basetype;
2462 struct reg_entry *basereg;
2463 struct reg_entry mybasereg;
2464 struct neon_type ntype;
2465 struct neon_typed_alias typeinfo;
12d6b0b7 2466 char *namebuf, *nameend ATTRIBUTE_UNUSED;
dcbf9037 2467 int namelen;
5f4273c7 2468
dcbf9037
JB
2469 typeinfo.defined = 0;
2470 typeinfo.eltype.type = NT_invtype;
2471 typeinfo.eltype.size = -1;
2472 typeinfo.index = -1;
5f4273c7 2473
dcbf9037 2474 nameend = p;
5f4273c7 2475
dcbf9037
JB
2476 if (strncmp (p, " .dn ", 5) == 0)
2477 basetype = REG_TYPE_VFD;
2478 else if (strncmp (p, " .qn ", 5) == 0)
2479 basetype = REG_TYPE_NQ;
2480 else
c921be7d 2481 return FALSE;
5f4273c7 2482
dcbf9037 2483 p += 5;
5f4273c7 2484
dcbf9037 2485 if (*p == '\0')
c921be7d 2486 return FALSE;
5f4273c7 2487
dcbf9037
JB
2488 basereg = arm_reg_parse_multi (&p);
2489
2490 if (basereg && basereg->type != basetype)
2491 {
2492 as_bad (_("bad type for register"));
c921be7d 2493 return FALSE;
dcbf9037
JB
2494 }
2495
2496 if (basereg == NULL)
2497 {
2498 expressionS exp;
2499 /* Try parsing as an integer. */
2500 my_get_expression (&exp, &p, GE_NO_PREFIX);
2501 if (exp.X_op != O_constant)
477330fc
RM
2502 {
2503 as_bad (_("expression must be constant"));
2504 return FALSE;
2505 }
dcbf9037
JB
2506 basereg = &mybasereg;
2507 basereg->number = (basetype == REG_TYPE_NQ) ? exp.X_add_number * 2
477330fc 2508 : exp.X_add_number;
dcbf9037
JB
2509 basereg->neon = 0;
2510 }
2511
2512 if (basereg->neon)
2513 typeinfo = *basereg->neon;
2514
2515 if (parse_neon_type (&ntype, &p) == SUCCESS)
2516 {
2517 /* We got a type. */
2518 if (typeinfo.defined & NTA_HASTYPE)
477330fc
RM
2519 {
2520 as_bad (_("can't redefine the type of a register alias"));
2521 return FALSE;
2522 }
5f4273c7 2523
dcbf9037
JB
2524 typeinfo.defined |= NTA_HASTYPE;
2525 if (ntype.elems != 1)
477330fc
RM
2526 {
2527 as_bad (_("you must specify a single type only"));
2528 return FALSE;
2529 }
dcbf9037
JB
2530 typeinfo.eltype = ntype.el[0];
2531 }
5f4273c7 2532
dcbf9037
JB
2533 if (skip_past_char (&p, '[') == SUCCESS)
2534 {
2535 expressionS exp;
2536 /* We got a scalar index. */
5f4273c7 2537
dcbf9037 2538 if (typeinfo.defined & NTA_HASINDEX)
477330fc
RM
2539 {
2540 as_bad (_("can't redefine the index of a scalar alias"));
2541 return FALSE;
2542 }
5f4273c7 2543
dcbf9037 2544 my_get_expression (&exp, &p, GE_NO_PREFIX);
5f4273c7 2545
dcbf9037 2546 if (exp.X_op != O_constant)
477330fc
RM
2547 {
2548 as_bad (_("scalar index must be constant"));
2549 return FALSE;
2550 }
5f4273c7 2551
dcbf9037
JB
2552 typeinfo.defined |= NTA_HASINDEX;
2553 typeinfo.index = exp.X_add_number;
5f4273c7 2554
dcbf9037 2555 if (skip_past_char (&p, ']') == FAIL)
477330fc
RM
2556 {
2557 as_bad (_("expecting ]"));
2558 return FALSE;
2559 }
dcbf9037
JB
2560 }
2561
15735687
NS
2562 /* If TC_CASE_SENSITIVE is defined, then newname already points to
2563 the desired alias name, and p points to its end. If not, then
2564 the desired alias name is in the global original_case_string. */
2565#ifdef TC_CASE_SENSITIVE
dcbf9037 2566 namelen = nameend - newname;
15735687
NS
2567#else
2568 newname = original_case_string;
2569 namelen = strlen (newname);
2570#endif
2571
29a2809e 2572 namebuf = xmemdup0 (newname, namelen);
5f4273c7 2573
dcbf9037 2574 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2575 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2576
dcbf9037
JB
2577 /* Insert name in all uppercase. */
2578 for (p = namebuf; *p; p++)
2579 *p = TOUPPER (*p);
5f4273c7 2580
dcbf9037
JB
2581 if (strncmp (namebuf, newname, namelen))
2582 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2583 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2584
dcbf9037
JB
2585 /* Insert name in all lowercase. */
2586 for (p = namebuf; *p; p++)
2587 *p = TOLOWER (*p);
5f4273c7 2588
dcbf9037
JB
2589 if (strncmp (namebuf, newname, namelen))
2590 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2591 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2592
e1fa0163 2593 free (namebuf);
c921be7d 2594 return TRUE;
dcbf9037
JB
2595}
2596
c19d1205
ZW
2597/* Should never be called, as .req goes between the alias and the
2598 register name, not at the beginning of the line. */
c921be7d 2599
b99bd4ef 2600static void
c19d1205 2601s_req (int a ATTRIBUTE_UNUSED)
b99bd4ef 2602{
c19d1205
ZW
2603 as_bad (_("invalid syntax for .req directive"));
2604}
b99bd4ef 2605
dcbf9037
JB
2606static void
2607s_dn (int a ATTRIBUTE_UNUSED)
2608{
2609 as_bad (_("invalid syntax for .dn directive"));
2610}
2611
2612static void
2613s_qn (int a ATTRIBUTE_UNUSED)
2614{
2615 as_bad (_("invalid syntax for .qn directive"));
2616}
2617
c19d1205
ZW
2618/* The .unreq directive deletes an alias which was previously defined
2619 by .req. For example:
b99bd4ef 2620
c19d1205
ZW
2621 my_alias .req r11
2622 .unreq my_alias */
b99bd4ef
NC
2623
2624static void
c19d1205 2625s_unreq (int a ATTRIBUTE_UNUSED)
b99bd4ef 2626{
c19d1205
ZW
2627 char * name;
2628 char saved_char;
b99bd4ef 2629
c19d1205
ZW
2630 name = input_line_pointer;
2631
2632 while (*input_line_pointer != 0
2633 && *input_line_pointer != ' '
2634 && *input_line_pointer != '\n')
2635 ++input_line_pointer;
2636
2637 saved_char = *input_line_pointer;
2638 *input_line_pointer = 0;
2639
2640 if (!*name)
2641 as_bad (_("invalid syntax for .unreq directive"));
2642 else
2643 {
21d799b5 2644 struct reg_entry *reg = (struct reg_entry *) hash_find (arm_reg_hsh,
477330fc 2645 name);
c19d1205
ZW
2646
2647 if (!reg)
2648 as_bad (_("unknown register alias '%s'"), name);
2649 else if (reg->builtin)
a1727c1a 2650 as_warn (_("ignoring attempt to use .unreq on fixed register name: '%s'"),
c19d1205
ZW
2651 name);
2652 else
2653 {
d929913e
NC
2654 char * p;
2655 char * nbuf;
2656
db0bc284 2657 hash_delete (arm_reg_hsh, name, FALSE);
c19d1205 2658 free ((char *) reg->name);
477330fc
RM
2659 if (reg->neon)
2660 free (reg->neon);
c19d1205 2661 free (reg);
d929913e
NC
2662
2663 /* Also locate the all upper case and all lower case versions.
2664 Do not complain if we cannot find one or the other as it
2665 was probably deleted above. */
5f4273c7 2666
d929913e
NC
2667 nbuf = strdup (name);
2668 for (p = nbuf; *p; p++)
2669 *p = TOUPPER (*p);
21d799b5 2670 reg = (struct reg_entry *) hash_find (arm_reg_hsh, nbuf);
d929913e
NC
2671 if (reg)
2672 {
db0bc284 2673 hash_delete (arm_reg_hsh, nbuf, FALSE);
d929913e
NC
2674 free ((char *) reg->name);
2675 if (reg->neon)
2676 free (reg->neon);
2677 free (reg);
2678 }
2679
2680 for (p = nbuf; *p; p++)
2681 *p = TOLOWER (*p);
21d799b5 2682 reg = (struct reg_entry *) hash_find (arm_reg_hsh, nbuf);
d929913e
NC
2683 if (reg)
2684 {
db0bc284 2685 hash_delete (arm_reg_hsh, nbuf, FALSE);
d929913e
NC
2686 free ((char *) reg->name);
2687 if (reg->neon)
2688 free (reg->neon);
2689 free (reg);
2690 }
2691
2692 free (nbuf);
c19d1205
ZW
2693 }
2694 }
b99bd4ef 2695
c19d1205 2696 *input_line_pointer = saved_char;
b99bd4ef
NC
2697 demand_empty_rest_of_line ();
2698}
2699
c19d1205
ZW
2700/* Directives: Instruction set selection. */
2701
2702#ifdef OBJ_ELF
2703/* This code is to handle mapping symbols as defined in the ARM ELF spec.
2704 (See "Mapping symbols", section 4.5.5, ARM AAELF version 1.0).
2705 Note that previously, $a and $t has type STT_FUNC (BSF_OBJECT flag),
2706 and $d has type STT_OBJECT (BSF_OBJECT flag). Now all three are untyped. */
2707
cd000bff
DJ
2708/* Create a new mapping symbol for the transition to STATE. */
2709
2710static void
2711make_mapping_symbol (enum mstate state, valueT value, fragS *frag)
b99bd4ef 2712{
a737bd4d 2713 symbolS * symbolP;
c19d1205
ZW
2714 const char * symname;
2715 int type;
b99bd4ef 2716
c19d1205 2717 switch (state)
b99bd4ef 2718 {
c19d1205
ZW
2719 case MAP_DATA:
2720 symname = "$d";
2721 type = BSF_NO_FLAGS;
2722 break;
2723 case MAP_ARM:
2724 symname = "$a";
2725 type = BSF_NO_FLAGS;
2726 break;
2727 case MAP_THUMB:
2728 symname = "$t";
2729 type = BSF_NO_FLAGS;
2730 break;
c19d1205
ZW
2731 default:
2732 abort ();
2733 }
2734
cd000bff 2735 symbolP = symbol_new (symname, now_seg, value, frag);
c19d1205
ZW
2736 symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
2737
2738 switch (state)
2739 {
2740 case MAP_ARM:
2741 THUMB_SET_FUNC (symbolP, 0);
2742 ARM_SET_THUMB (symbolP, 0);
2743 ARM_SET_INTERWORK (symbolP, support_interwork);
2744 break;
2745
2746 case MAP_THUMB:
2747 THUMB_SET_FUNC (symbolP, 1);
2748 ARM_SET_THUMB (symbolP, 1);
2749 ARM_SET_INTERWORK (symbolP, support_interwork);
2750 break;
2751
2752 case MAP_DATA:
2753 default:
cd000bff
DJ
2754 break;
2755 }
2756
2757 /* Save the mapping symbols for future reference. Also check that
2758 we do not place two mapping symbols at the same offset within a
2759 frag. We'll handle overlap between frags in
2de7820f
JZ
2760 check_mapping_symbols.
2761
2762 If .fill or other data filling directive generates zero sized data,
2763 the mapping symbol for the following code will have the same value
2764 as the one generated for the data filling directive. In this case,
2765 we replace the old symbol with the new one at the same address. */
cd000bff
DJ
2766 if (value == 0)
2767 {
2de7820f
JZ
2768 if (frag->tc_frag_data.first_map != NULL)
2769 {
2770 know (S_GET_VALUE (frag->tc_frag_data.first_map) == 0);
2771 symbol_remove (frag->tc_frag_data.first_map, &symbol_rootP, &symbol_lastP);
2772 }
cd000bff
DJ
2773 frag->tc_frag_data.first_map = symbolP;
2774 }
2775 if (frag->tc_frag_data.last_map != NULL)
0f020cef
JZ
2776 {
2777 know (S_GET_VALUE (frag->tc_frag_data.last_map) <= S_GET_VALUE (symbolP));
0f020cef
JZ
2778 if (S_GET_VALUE (frag->tc_frag_data.last_map) == S_GET_VALUE (symbolP))
2779 symbol_remove (frag->tc_frag_data.last_map, &symbol_rootP, &symbol_lastP);
2780 }
cd000bff
DJ
2781 frag->tc_frag_data.last_map = symbolP;
2782}
2783
2784/* We must sometimes convert a region marked as code to data during
2785 code alignment, if an odd number of bytes have to be padded. The
2786 code mapping symbol is pushed to an aligned address. */
2787
2788static void
2789insert_data_mapping_symbol (enum mstate state,
2790 valueT value, fragS *frag, offsetT bytes)
2791{
2792 /* If there was already a mapping symbol, remove it. */
2793 if (frag->tc_frag_data.last_map != NULL
2794 && S_GET_VALUE (frag->tc_frag_data.last_map) == frag->fr_address + value)
2795 {
2796 symbolS *symp = frag->tc_frag_data.last_map;
2797
2798 if (value == 0)
2799 {
2800 know (frag->tc_frag_data.first_map == symp);
2801 frag->tc_frag_data.first_map = NULL;
2802 }
2803 frag->tc_frag_data.last_map = NULL;
2804 symbol_remove (symp, &symbol_rootP, &symbol_lastP);
c19d1205 2805 }
cd000bff
DJ
2806
2807 make_mapping_symbol (MAP_DATA, value, frag);
2808 make_mapping_symbol (state, value + bytes, frag);
2809}
2810
2811static void mapping_state_2 (enum mstate state, int max_chars);
2812
2813/* Set the mapping state to STATE. Only call this when about to
2814 emit some STATE bytes to the file. */
2815
4e9aaefb 2816#define TRANSITION(from, to) (mapstate == (from) && state == (to))
cd000bff
DJ
2817void
2818mapping_state (enum mstate state)
2819{
940b5ce0
DJ
2820 enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate;
2821
cd000bff
DJ
2822 if (mapstate == state)
2823 /* The mapping symbol has already been emitted.
2824 There is nothing else to do. */
2825 return;
49c62a33
NC
2826
2827 if (state == MAP_ARM || state == MAP_THUMB)
2828 /* PR gas/12931
2829 All ARM instructions require 4-byte alignment.
2830 (Almost) all Thumb instructions require 2-byte alignment.
2831
2832 When emitting instructions into any section, mark the section
2833 appropriately.
2834
2835 Some Thumb instructions are alignment-sensitive modulo 4 bytes,
2836 but themselves require 2-byte alignment; this applies to some
33eaf5de 2837 PC- relative forms. However, these cases will involve implicit
49c62a33
NC
2838 literal pool generation or an explicit .align >=2, both of
2839 which will cause the section to me marked with sufficient
2840 alignment. Thus, we don't handle those cases here. */
2841 record_alignment (now_seg, state == MAP_ARM ? 2 : 1);
2842
2843 if (TRANSITION (MAP_UNDEFINED, MAP_DATA))
4e9aaefb 2844 /* This case will be evaluated later. */
cd000bff 2845 return;
cd000bff
DJ
2846
2847 mapping_state_2 (state, 0);
cd000bff
DJ
2848}
2849
2850/* Same as mapping_state, but MAX_CHARS bytes have already been
2851 allocated. Put the mapping symbol that far back. */
2852
2853static void
2854mapping_state_2 (enum mstate state, int max_chars)
2855{
940b5ce0
DJ
2856 enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate;
2857
2858 if (!SEG_NORMAL (now_seg))
2859 return;
2860
cd000bff
DJ
2861 if (mapstate == state)
2862 /* The mapping symbol has already been emitted.
2863 There is nothing else to do. */
2864 return;
2865
4e9aaefb
SA
2866 if (TRANSITION (MAP_UNDEFINED, MAP_ARM)
2867 || TRANSITION (MAP_UNDEFINED, MAP_THUMB))
2868 {
2869 struct frag * const frag_first = seg_info (now_seg)->frchainP->frch_root;
2870 const int add_symbol = (frag_now != frag_first) || (frag_now_fix () > 0);
2871
2872 if (add_symbol)
2873 make_mapping_symbol (MAP_DATA, (valueT) 0, frag_first);
2874 }
2875
cd000bff
DJ
2876 seg_info (now_seg)->tc_segment_info_data.mapstate = state;
2877 make_mapping_symbol (state, (valueT) frag_now_fix () - max_chars, frag_now);
c19d1205 2878}
4e9aaefb 2879#undef TRANSITION
c19d1205 2880#else
d3106081
NS
2881#define mapping_state(x) ((void)0)
2882#define mapping_state_2(x, y) ((void)0)
c19d1205
ZW
2883#endif
2884
2885/* Find the real, Thumb encoded start of a Thumb function. */
2886
4343666d 2887#ifdef OBJ_COFF
c19d1205
ZW
2888static symbolS *
2889find_real_start (symbolS * symbolP)
2890{
2891 char * real_start;
2892 const char * name = S_GET_NAME (symbolP);
2893 symbolS * new_target;
2894
2895 /* This definition must agree with the one in gcc/config/arm/thumb.c. */
2896#define STUB_NAME ".real_start_of"
2897
2898 if (name == NULL)
2899 abort ();
2900
37f6032b
ZW
2901 /* The compiler may generate BL instructions to local labels because
2902 it needs to perform a branch to a far away location. These labels
2903 do not have a corresponding ".real_start_of" label. We check
2904 both for S_IS_LOCAL and for a leading dot, to give a way to bypass
2905 the ".real_start_of" convention for nonlocal branches. */
2906 if (S_IS_LOCAL (symbolP) || name[0] == '.')
c19d1205
ZW
2907 return symbolP;
2908
e1fa0163 2909 real_start = concat (STUB_NAME, name, NULL);
c19d1205 2910 new_target = symbol_find (real_start);
e1fa0163 2911 free (real_start);
c19d1205
ZW
2912
2913 if (new_target == NULL)
2914 {
bd3ba5d1 2915 as_warn (_("Failed to find real start of function: %s\n"), name);
c19d1205
ZW
2916 new_target = symbolP;
2917 }
2918
c19d1205
ZW
2919 return new_target;
2920}
4343666d 2921#endif
c19d1205
ZW
2922
2923static void
2924opcode_select (int width)
2925{
2926 switch (width)
2927 {
2928 case 16:
2929 if (! thumb_mode)
2930 {
e74cfd16 2931 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
c19d1205
ZW
2932 as_bad (_("selected processor does not support THUMB opcodes"));
2933
2934 thumb_mode = 1;
2935 /* No need to force the alignment, since we will have been
2936 coming from ARM mode, which is word-aligned. */
2937 record_alignment (now_seg, 1);
2938 }
c19d1205
ZW
2939 break;
2940
2941 case 32:
2942 if (thumb_mode)
2943 {
e74cfd16 2944 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
c19d1205
ZW
2945 as_bad (_("selected processor does not support ARM opcodes"));
2946
2947 thumb_mode = 0;
2948
2949 if (!need_pass_2)
2950 frag_align (2, 0, 0);
2951
2952 record_alignment (now_seg, 1);
2953 }
c19d1205
ZW
2954 break;
2955
2956 default:
2957 as_bad (_("invalid instruction size selected (%d)"), width);
2958 }
2959}
2960
2961static void
2962s_arm (int ignore ATTRIBUTE_UNUSED)
2963{
2964 opcode_select (32);
2965 demand_empty_rest_of_line ();
2966}
2967
2968static void
2969s_thumb (int ignore ATTRIBUTE_UNUSED)
2970{
2971 opcode_select (16);
2972 demand_empty_rest_of_line ();
2973}
2974
2975static void
2976s_code (int unused ATTRIBUTE_UNUSED)
2977{
2978 int temp;
2979
2980 temp = get_absolute_expression ();
2981 switch (temp)
2982 {
2983 case 16:
2984 case 32:
2985 opcode_select (temp);
2986 break;
2987
2988 default:
2989 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
2990 }
2991}
2992
2993static void
2994s_force_thumb (int ignore ATTRIBUTE_UNUSED)
2995{
2996 /* If we are not already in thumb mode go into it, EVEN if
2997 the target processor does not support thumb instructions.
2998 This is used by gcc/config/arm/lib1funcs.asm for example
2999 to compile interworking support functions even if the
3000 target processor should not support interworking. */
3001 if (! thumb_mode)
3002 {
3003 thumb_mode = 2;
3004 record_alignment (now_seg, 1);
3005 }
3006
3007 demand_empty_rest_of_line ();
3008}
3009
3010static void
3011s_thumb_func (int ignore ATTRIBUTE_UNUSED)
3012{
3013 s_thumb (0);
3014
3015 /* The following label is the name/address of the start of a Thumb function.
3016 We need to know this for the interworking support. */
3017 label_is_thumb_function_name = TRUE;
3018}
3019
3020/* Perform a .set directive, but also mark the alias as
3021 being a thumb function. */
3022
3023static void
3024s_thumb_set (int equiv)
3025{
3026 /* XXX the following is a duplicate of the code for s_set() in read.c
3027 We cannot just call that code as we need to get at the symbol that
3028 is created. */
3029 char * name;
3030 char delim;
3031 char * end_name;
3032 symbolS * symbolP;
3033
3034 /* Especial apologies for the random logic:
3035 This just grew, and could be parsed much more simply!
3036 Dean - in haste. */
d02603dc 3037 delim = get_symbol_name (& name);
c19d1205 3038 end_name = input_line_pointer;
d02603dc 3039 (void) restore_line_pointer (delim);
c19d1205
ZW
3040
3041 if (*input_line_pointer != ',')
3042 {
3043 *end_name = 0;
3044 as_bad (_("expected comma after name \"%s\""), name);
b99bd4ef
NC
3045 *end_name = delim;
3046 ignore_rest_of_line ();
3047 return;
3048 }
3049
3050 input_line_pointer++;
3051 *end_name = 0;
3052
3053 if (name[0] == '.' && name[1] == '\0')
3054 {
3055 /* XXX - this should not happen to .thumb_set. */
3056 abort ();
3057 }
3058
3059 if ((symbolP = symbol_find (name)) == NULL
3060 && (symbolP = md_undefined_symbol (name)) == NULL)
3061 {
3062#ifndef NO_LISTING
3063 /* When doing symbol listings, play games with dummy fragments living
3064 outside the normal fragment chain to record the file and line info
c19d1205 3065 for this symbol. */
b99bd4ef
NC
3066 if (listing & LISTING_SYMBOLS)
3067 {
3068 extern struct list_info_struct * listing_tail;
21d799b5 3069 fragS * dummy_frag = (fragS * ) xmalloc (sizeof (fragS));
b99bd4ef
NC
3070
3071 memset (dummy_frag, 0, sizeof (fragS));
3072 dummy_frag->fr_type = rs_fill;
3073 dummy_frag->line = listing_tail;
3074 symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
3075 dummy_frag->fr_symbol = symbolP;
3076 }
3077 else
3078#endif
3079 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
3080
3081#ifdef OBJ_COFF
3082 /* "set" symbols are local unless otherwise specified. */
3083 SF_SET_LOCAL (symbolP);
3084#endif /* OBJ_COFF */
3085 } /* Make a new symbol. */
3086
3087 symbol_table_insert (symbolP);
3088
3089 * end_name = delim;
3090
3091 if (equiv
3092 && S_IS_DEFINED (symbolP)
3093 && S_GET_SEGMENT (symbolP) != reg_section)
3094 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
3095
3096 pseudo_set (symbolP);
3097
3098 demand_empty_rest_of_line ();
3099
c19d1205 3100 /* XXX Now we come to the Thumb specific bit of code. */
b99bd4ef
NC
3101
3102 THUMB_SET_FUNC (symbolP, 1);
3103 ARM_SET_THUMB (symbolP, 1);
3104#if defined OBJ_ELF || defined OBJ_COFF
3105 ARM_SET_INTERWORK (symbolP, support_interwork);
3106#endif
3107}
3108
c19d1205 3109/* Directives: Mode selection. */
b99bd4ef 3110
c19d1205
ZW
3111/* .syntax [unified|divided] - choose the new unified syntax
3112 (same for Arm and Thumb encoding, modulo slight differences in what
3113 can be represented) or the old divergent syntax for each mode. */
b99bd4ef 3114static void
c19d1205 3115s_syntax (int unused ATTRIBUTE_UNUSED)
b99bd4ef 3116{
c19d1205
ZW
3117 char *name, delim;
3118
d02603dc 3119 delim = get_symbol_name (& name);
c19d1205
ZW
3120
3121 if (!strcasecmp (name, "unified"))
3122 unified_syntax = TRUE;
3123 else if (!strcasecmp (name, "divided"))
3124 unified_syntax = FALSE;
3125 else
3126 {
3127 as_bad (_("unrecognized syntax mode \"%s\""), name);
3128 return;
3129 }
d02603dc 3130 (void) restore_line_pointer (delim);
b99bd4ef
NC
3131 demand_empty_rest_of_line ();
3132}
3133
c19d1205
ZW
3134/* Directives: sectioning and alignment. */
3135
c19d1205
ZW
3136static void
3137s_bss (int ignore ATTRIBUTE_UNUSED)
b99bd4ef 3138{
c19d1205
ZW
3139 /* We don't support putting frags in the BSS segment, we fake it by
3140 marking in_bss, then looking at s_skip for clues. */
3141 subseg_set (bss_section, 0);
3142 demand_empty_rest_of_line ();
cd000bff
DJ
3143
3144#ifdef md_elf_section_change_hook
3145 md_elf_section_change_hook ();
3146#endif
c19d1205 3147}
b99bd4ef 3148
c19d1205
ZW
3149static void
3150s_even (int ignore ATTRIBUTE_UNUSED)
3151{
3152 /* Never make frag if expect extra pass. */
3153 if (!need_pass_2)
3154 frag_align (1, 0, 0);
b99bd4ef 3155
c19d1205 3156 record_alignment (now_seg, 1);
b99bd4ef 3157
c19d1205 3158 demand_empty_rest_of_line ();
b99bd4ef
NC
3159}
3160
2e6976a8
DG
3161/* Directives: CodeComposer Studio. */
3162
3163/* .ref (for CodeComposer Studio syntax only). */
3164static void
3165s_ccs_ref (int unused ATTRIBUTE_UNUSED)
3166{
3167 if (codecomposer_syntax)
3168 ignore_rest_of_line ();
3169 else
3170 as_bad (_(".ref pseudo-op only available with -mccs flag."));
3171}
3172
3173/* If name is not NULL, then it is used for marking the beginning of a
2b0f3761 3174 function, whereas if it is NULL then it means the function end. */
2e6976a8
DG
3175static void
3176asmfunc_debug (const char * name)
3177{
3178 static const char * last_name = NULL;
3179
3180 if (name != NULL)
3181 {
3182 gas_assert (last_name == NULL);
3183 last_name = name;
3184
3185 if (debug_type == DEBUG_STABS)
3186 stabs_generate_asm_func (name, name);
3187 }
3188 else
3189 {
3190 gas_assert (last_name != NULL);
3191
3192 if (debug_type == DEBUG_STABS)
3193 stabs_generate_asm_endfunc (last_name, last_name);
3194
3195 last_name = NULL;
3196 }
3197}
3198
3199static void
3200s_ccs_asmfunc (int unused ATTRIBUTE_UNUSED)
3201{
3202 if (codecomposer_syntax)
3203 {
3204 switch (asmfunc_state)
3205 {
3206 case OUTSIDE_ASMFUNC:
3207 asmfunc_state = WAITING_ASMFUNC_NAME;
3208 break;
3209
3210 case WAITING_ASMFUNC_NAME:
3211 as_bad (_(".asmfunc repeated."));
3212 break;
3213
3214 case WAITING_ENDASMFUNC:
3215 as_bad (_(".asmfunc without function."));
3216 break;
3217 }
3218 demand_empty_rest_of_line ();
3219 }
3220 else
3221 as_bad (_(".asmfunc pseudo-op only available with -mccs flag."));
3222}
3223
3224static void
3225s_ccs_endasmfunc (int unused ATTRIBUTE_UNUSED)
3226{
3227 if (codecomposer_syntax)
3228 {
3229 switch (asmfunc_state)
3230 {
3231 case OUTSIDE_ASMFUNC:
3232 as_bad (_(".endasmfunc without a .asmfunc."));
3233 break;
3234
3235 case WAITING_ASMFUNC_NAME:
3236 as_bad (_(".endasmfunc without function."));
3237 break;
3238
3239 case WAITING_ENDASMFUNC:
3240 asmfunc_state = OUTSIDE_ASMFUNC;
3241 asmfunc_debug (NULL);
3242 break;
3243 }
3244 demand_empty_rest_of_line ();
3245 }
3246 else
3247 as_bad (_(".endasmfunc pseudo-op only available with -mccs flag."));
3248}
3249
3250static void
3251s_ccs_def (int name)
3252{
3253 if (codecomposer_syntax)
3254 s_globl (name);
3255 else
3256 as_bad (_(".def pseudo-op only available with -mccs flag."));
3257}
3258
c19d1205 3259/* Directives: Literal pools. */
a737bd4d 3260
c19d1205
ZW
3261static literal_pool *
3262find_literal_pool (void)
a737bd4d 3263{
c19d1205 3264 literal_pool * pool;
a737bd4d 3265
c19d1205 3266 for (pool = list_of_pools; pool != NULL; pool = pool->next)
a737bd4d 3267 {
c19d1205
ZW
3268 if (pool->section == now_seg
3269 && pool->sub_section == now_subseg)
3270 break;
a737bd4d
NC
3271 }
3272
c19d1205 3273 return pool;
a737bd4d
NC
3274}
3275
c19d1205
ZW
3276static literal_pool *
3277find_or_make_literal_pool (void)
a737bd4d 3278{
c19d1205
ZW
3279 /* Next literal pool ID number. */
3280 static unsigned int latest_pool_num = 1;
3281 literal_pool * pool;
a737bd4d 3282
c19d1205 3283 pool = find_literal_pool ();
a737bd4d 3284
c19d1205 3285 if (pool == NULL)
a737bd4d 3286 {
c19d1205 3287 /* Create a new pool. */
325801bd 3288 pool = XNEW (literal_pool);
c19d1205
ZW
3289 if (! pool)
3290 return NULL;
a737bd4d 3291
c19d1205
ZW
3292 pool->next_free_entry = 0;
3293 pool->section = now_seg;
3294 pool->sub_section = now_subseg;
3295 pool->next = list_of_pools;
3296 pool->symbol = NULL;
8335d6aa 3297 pool->alignment = 2;
c19d1205
ZW
3298
3299 /* Add it to the list. */
3300 list_of_pools = pool;
a737bd4d 3301 }
a737bd4d 3302
c19d1205
ZW
3303 /* New pools, and emptied pools, will have a NULL symbol. */
3304 if (pool->symbol == NULL)
a737bd4d 3305 {
c19d1205
ZW
3306 pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
3307 (valueT) 0, &zero_address_frag);
3308 pool->id = latest_pool_num ++;
a737bd4d
NC
3309 }
3310
c19d1205
ZW
3311 /* Done. */
3312 return pool;
a737bd4d
NC
3313}
3314
c19d1205 3315/* Add the literal in the global 'inst'
5f4273c7 3316 structure to the relevant literal pool. */
b99bd4ef
NC
3317
3318static int
8335d6aa 3319add_to_lit_pool (unsigned int nbytes)
b99bd4ef 3320{
8335d6aa
JW
3321#define PADDING_SLOT 0x1
3322#define LIT_ENTRY_SIZE_MASK 0xFF
c19d1205 3323 literal_pool * pool;
8335d6aa
JW
3324 unsigned int entry, pool_size = 0;
3325 bfd_boolean padding_slot_p = FALSE;
e56c722b 3326 unsigned imm1 = 0;
8335d6aa
JW
3327 unsigned imm2 = 0;
3328
3329 if (nbytes == 8)
3330 {
3331 imm1 = inst.operands[1].imm;
3332 imm2 = (inst.operands[1].regisimm ? inst.operands[1].reg
e2b0ab59 3333 : inst.relocs[0].exp.X_unsigned ? 0
2569ceb0 3334 : ((bfd_int64_t) inst.operands[1].imm) >> 32);
8335d6aa
JW
3335 if (target_big_endian)
3336 {
3337 imm1 = imm2;
3338 imm2 = inst.operands[1].imm;
3339 }
3340 }
b99bd4ef 3341
c19d1205
ZW
3342 pool = find_or_make_literal_pool ();
3343
3344 /* Check if this literal value is already in the pool. */
3345 for (entry = 0; entry < pool->next_free_entry; entry ++)
b99bd4ef 3346 {
8335d6aa
JW
3347 if (nbytes == 4)
3348 {
e2b0ab59
AV
3349 if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
3350 && (inst.relocs[0].exp.X_op == O_constant)
8335d6aa 3351 && (pool->literals[entry].X_add_number
e2b0ab59 3352 == inst.relocs[0].exp.X_add_number)
8335d6aa
JW
3353 && (pool->literals[entry].X_md == nbytes)
3354 && (pool->literals[entry].X_unsigned
e2b0ab59 3355 == inst.relocs[0].exp.X_unsigned))
8335d6aa
JW
3356 break;
3357
e2b0ab59
AV
3358 if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
3359 && (inst.relocs[0].exp.X_op == O_symbol)
8335d6aa 3360 && (pool->literals[entry].X_add_number
e2b0ab59 3361 == inst.relocs[0].exp.X_add_number)
8335d6aa 3362 && (pool->literals[entry].X_add_symbol
e2b0ab59 3363 == inst.relocs[0].exp.X_add_symbol)
8335d6aa 3364 && (pool->literals[entry].X_op_symbol
e2b0ab59 3365 == inst.relocs[0].exp.X_op_symbol)
8335d6aa
JW
3366 && (pool->literals[entry].X_md == nbytes))
3367 break;
3368 }
3369 else if ((nbytes == 8)
3370 && !(pool_size & 0x7)
3371 && ((entry + 1) != pool->next_free_entry)
3372 && (pool->literals[entry].X_op == O_constant)
19f2f6a9 3373 && (pool->literals[entry].X_add_number == (offsetT) imm1)
8335d6aa 3374 && (pool->literals[entry].X_unsigned
e2b0ab59 3375 == inst.relocs[0].exp.X_unsigned)
8335d6aa 3376 && (pool->literals[entry + 1].X_op == O_constant)
19f2f6a9 3377 && (pool->literals[entry + 1].X_add_number == (offsetT) imm2)
8335d6aa 3378 && (pool->literals[entry + 1].X_unsigned
e2b0ab59 3379 == inst.relocs[0].exp.X_unsigned))
c19d1205
ZW
3380 break;
3381
8335d6aa
JW
3382 padding_slot_p = ((pool->literals[entry].X_md >> 8) == PADDING_SLOT);
3383 if (padding_slot_p && (nbytes == 4))
c19d1205 3384 break;
8335d6aa
JW
3385
3386 pool_size += 4;
b99bd4ef
NC
3387 }
3388
c19d1205
ZW
3389 /* Do we need to create a new entry? */
3390 if (entry == pool->next_free_entry)
3391 {
3392 if (entry >= MAX_LITERAL_POOL_SIZE)
3393 {
3394 inst.error = _("literal pool overflow");
3395 return FAIL;
3396 }
3397
8335d6aa
JW
3398 if (nbytes == 8)
3399 {
3400 /* For 8-byte entries, we align to an 8-byte boundary,
3401 and split it into two 4-byte entries, because on 32-bit
3402 host, 8-byte constants are treated as big num, thus
3403 saved in "generic_bignum" which will be overwritten
3404 by later assignments.
3405
3406 We also need to make sure there is enough space for
3407 the split.
3408
3409 We also check to make sure the literal operand is a
3410 constant number. */
e2b0ab59
AV
3411 if (!(inst.relocs[0].exp.X_op == O_constant
3412 || inst.relocs[0].exp.X_op == O_big))
8335d6aa
JW
3413 {
3414 inst.error = _("invalid type for literal pool");
3415 return FAIL;
3416 }
3417 else if (pool_size & 0x7)
3418 {
3419 if ((entry + 2) >= MAX_LITERAL_POOL_SIZE)
3420 {
3421 inst.error = _("literal pool overflow");
3422 return FAIL;
3423 }
3424
e2b0ab59 3425 pool->literals[entry] = inst.relocs[0].exp;
a6684f0d 3426 pool->literals[entry].X_op = O_constant;
8335d6aa
JW
3427 pool->literals[entry].X_add_number = 0;
3428 pool->literals[entry++].X_md = (PADDING_SLOT << 8) | 4;
3429 pool->next_free_entry += 1;
3430 pool_size += 4;
3431 }
3432 else if ((entry + 1) >= MAX_LITERAL_POOL_SIZE)
3433 {
3434 inst.error = _("literal pool overflow");
3435 return FAIL;
3436 }
3437
e2b0ab59 3438 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3439 pool->literals[entry].X_op = O_constant;
3440 pool->literals[entry].X_add_number = imm1;
e2b0ab59 3441 pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
8335d6aa 3442 pool->literals[entry++].X_md = 4;
e2b0ab59 3443 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3444 pool->literals[entry].X_op = O_constant;
3445 pool->literals[entry].X_add_number = imm2;
e2b0ab59 3446 pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
8335d6aa
JW
3447 pool->literals[entry].X_md = 4;
3448 pool->alignment = 3;
3449 pool->next_free_entry += 1;
3450 }
3451 else
3452 {
e2b0ab59 3453 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3454 pool->literals[entry].X_md = 4;
3455 }
3456
a8040cf2
NC
3457#ifdef OBJ_ELF
3458 /* PR ld/12974: Record the location of the first source line to reference
3459 this entry in the literal pool. If it turns out during linking that the
3460 symbol does not exist we will be able to give an accurate line number for
3461 the (first use of the) missing reference. */
3462 if (debug_type == DEBUG_DWARF2)
3463 dwarf2_where (pool->locs + entry);
3464#endif
c19d1205
ZW
3465 pool->next_free_entry += 1;
3466 }
8335d6aa
JW
3467 else if (padding_slot_p)
3468 {
e2b0ab59 3469 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3470 pool->literals[entry].X_md = nbytes;
3471 }
b99bd4ef 3472
e2b0ab59
AV
3473 inst.relocs[0].exp.X_op = O_symbol;
3474 inst.relocs[0].exp.X_add_number = pool_size;
3475 inst.relocs[0].exp.X_add_symbol = pool->symbol;
b99bd4ef 3476
c19d1205 3477 return SUCCESS;
b99bd4ef
NC
3478}
3479
2e6976a8 3480bfd_boolean
2e57ce7b 3481tc_start_label_without_colon (void)
2e6976a8
DG
3482{
3483 bfd_boolean ret = TRUE;
3484
3485 if (codecomposer_syntax && asmfunc_state == WAITING_ASMFUNC_NAME)
3486 {
2e57ce7b 3487 const char *label = input_line_pointer;
2e6976a8
DG
3488
3489 while (!is_end_of_line[(int) label[-1]])
3490 --label;
3491
3492 if (*label == '.')
3493 {
3494 as_bad (_("Invalid label '%s'"), label);
3495 ret = FALSE;
3496 }
3497
3498 asmfunc_debug (label);
3499
3500 asmfunc_state = WAITING_ENDASMFUNC;
3501 }
3502
3503 return ret;
3504}
3505
c19d1205 3506/* Can't use symbol_new here, so have to create a symbol and then at
33eaf5de 3507 a later date assign it a value. That's what these functions do. */
e16bb312 3508
c19d1205
ZW
3509static void
3510symbol_locate (symbolS * symbolP,
3511 const char * name, /* It is copied, the caller can modify. */
3512 segT segment, /* Segment identifier (SEG_<something>). */
3513 valueT valu, /* Symbol value. */
3514 fragS * frag) /* Associated fragment. */
3515{
e57e6ddc 3516 size_t name_length;
c19d1205 3517 char * preserved_copy_of_name;
e16bb312 3518
c19d1205
ZW
3519 name_length = strlen (name) + 1; /* +1 for \0. */
3520 obstack_grow (&notes, name, name_length);
21d799b5 3521 preserved_copy_of_name = (char *) obstack_finish (&notes);
e16bb312 3522
c19d1205
ZW
3523#ifdef tc_canonicalize_symbol_name
3524 preserved_copy_of_name =
3525 tc_canonicalize_symbol_name (preserved_copy_of_name);
3526#endif
b99bd4ef 3527
c19d1205 3528 S_SET_NAME (symbolP, preserved_copy_of_name);
b99bd4ef 3529
c19d1205
ZW
3530 S_SET_SEGMENT (symbolP, segment);
3531 S_SET_VALUE (symbolP, valu);
3532 symbol_clear_list_pointers (symbolP);
b99bd4ef 3533
c19d1205 3534 symbol_set_frag (symbolP, frag);
b99bd4ef 3535
c19d1205
ZW
3536 /* Link to end of symbol chain. */
3537 {
3538 extern int symbol_table_frozen;
b99bd4ef 3539
c19d1205
ZW
3540 if (symbol_table_frozen)
3541 abort ();
3542 }
b99bd4ef 3543
c19d1205 3544 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
b99bd4ef 3545
c19d1205 3546 obj_symbol_new_hook (symbolP);
b99bd4ef 3547
c19d1205
ZW
3548#ifdef tc_symbol_new_hook
3549 tc_symbol_new_hook (symbolP);
3550#endif
3551
3552#ifdef DEBUG_SYMS
3553 verify_symbol_chain (symbol_rootP, symbol_lastP);
3554#endif /* DEBUG_SYMS */
b99bd4ef
NC
3555}
3556
c19d1205
ZW
3557static void
3558s_ltorg (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 3559{
c19d1205
ZW
3560 unsigned int entry;
3561 literal_pool * pool;
3562 char sym_name[20];
b99bd4ef 3563
c19d1205
ZW
3564 pool = find_literal_pool ();
3565 if (pool == NULL
3566 || pool->symbol == NULL
3567 || pool->next_free_entry == 0)
3568 return;
b99bd4ef 3569
c19d1205
ZW
3570 /* Align pool as you have word accesses.
3571 Only make a frag if we have to. */
3572 if (!need_pass_2)
8335d6aa 3573 frag_align (pool->alignment, 0, 0);
b99bd4ef 3574
c19d1205 3575 record_alignment (now_seg, 2);
b99bd4ef 3576
aaca88ef 3577#ifdef OBJ_ELF
47fc6e36
WN
3578 seg_info (now_seg)->tc_segment_info_data.mapstate = MAP_DATA;
3579 make_mapping_symbol (MAP_DATA, (valueT) frag_now_fix (), frag_now);
aaca88ef 3580#endif
c19d1205 3581 sprintf (sym_name, "$$lit_\002%x", pool->id);
b99bd4ef 3582
c19d1205
ZW
3583 symbol_locate (pool->symbol, sym_name, now_seg,
3584 (valueT) frag_now_fix (), frag_now);
3585 symbol_table_insert (pool->symbol);
b99bd4ef 3586
c19d1205 3587 ARM_SET_THUMB (pool->symbol, thumb_mode);
b99bd4ef 3588
c19d1205
ZW
3589#if defined OBJ_COFF || defined OBJ_ELF
3590 ARM_SET_INTERWORK (pool->symbol, support_interwork);
3591#endif
6c43fab6 3592
c19d1205 3593 for (entry = 0; entry < pool->next_free_entry; entry ++)
a8040cf2
NC
3594 {
3595#ifdef OBJ_ELF
3596 if (debug_type == DEBUG_DWARF2)
3597 dwarf2_gen_line_info (frag_now_fix (), pool->locs + entry);
3598#endif
3599 /* First output the expression in the instruction to the pool. */
8335d6aa
JW
3600 emit_expr (&(pool->literals[entry]),
3601 pool->literals[entry].X_md & LIT_ENTRY_SIZE_MASK);
a8040cf2 3602 }
b99bd4ef 3603
c19d1205
ZW
3604 /* Mark the pool as empty. */
3605 pool->next_free_entry = 0;
3606 pool->symbol = NULL;
b99bd4ef
NC
3607}
3608
c19d1205
ZW
3609#ifdef OBJ_ELF
3610/* Forward declarations for functions below, in the MD interface
3611 section. */
3612static void fix_new_arm (fragS *, int, short, expressionS *, int, int);
3613static valueT create_unwind_entry (int);
3614static void start_unwind_section (const segT, int);
3615static void add_unwind_opcode (valueT, int);
3616static void flush_pending_unwind (void);
b99bd4ef 3617
c19d1205 3618/* Directives: Data. */
b99bd4ef 3619
c19d1205
ZW
3620static void
3621s_arm_elf_cons (int nbytes)
3622{
3623 expressionS exp;
b99bd4ef 3624
c19d1205
ZW
3625#ifdef md_flush_pending_output
3626 md_flush_pending_output ();
3627#endif
b99bd4ef 3628
c19d1205 3629 if (is_it_end_of_statement ())
b99bd4ef 3630 {
c19d1205
ZW
3631 demand_empty_rest_of_line ();
3632 return;
b99bd4ef
NC
3633 }
3634
c19d1205
ZW
3635#ifdef md_cons_align
3636 md_cons_align (nbytes);
3637#endif
b99bd4ef 3638
c19d1205
ZW
3639 mapping_state (MAP_DATA);
3640 do
b99bd4ef 3641 {
c19d1205
ZW
3642 int reloc;
3643 char *base = input_line_pointer;
b99bd4ef 3644
c19d1205 3645 expression (& exp);
b99bd4ef 3646
c19d1205
ZW
3647 if (exp.X_op != O_symbol)
3648 emit_expr (&exp, (unsigned int) nbytes);
3649 else
3650 {
3651 char *before_reloc = input_line_pointer;
3652 reloc = parse_reloc (&input_line_pointer);
3653 if (reloc == -1)
3654 {
3655 as_bad (_("unrecognized relocation suffix"));
3656 ignore_rest_of_line ();
3657 return;
3658 }
3659 else if (reloc == BFD_RELOC_UNUSED)
3660 emit_expr (&exp, (unsigned int) nbytes);
3661 else
3662 {
21d799b5 3663 reloc_howto_type *howto = (reloc_howto_type *)
477330fc
RM
3664 bfd_reloc_type_lookup (stdoutput,
3665 (bfd_reloc_code_real_type) reloc);
c19d1205 3666 int size = bfd_get_reloc_size (howto);
b99bd4ef 3667
2fc8bdac
ZW
3668 if (reloc == BFD_RELOC_ARM_PLT32)
3669 {
3670 as_bad (_("(plt) is only valid on branch targets"));
3671 reloc = BFD_RELOC_UNUSED;
3672 size = 0;
3673 }
3674
c19d1205 3675 if (size > nbytes)
992a06ee
AM
3676 as_bad (ngettext ("%s relocations do not fit in %d byte",
3677 "%s relocations do not fit in %d bytes",
3678 nbytes),
c19d1205
ZW
3679 howto->name, nbytes);
3680 else
3681 {
3682 /* We've parsed an expression stopping at O_symbol.
3683 But there may be more expression left now that we
3684 have parsed the relocation marker. Parse it again.
3685 XXX Surely there is a cleaner way to do this. */
3686 char *p = input_line_pointer;
3687 int offset;
325801bd 3688 char *save_buf = XNEWVEC (char, input_line_pointer - base);
e1fa0163 3689
c19d1205
ZW
3690 memcpy (save_buf, base, input_line_pointer - base);
3691 memmove (base + (input_line_pointer - before_reloc),
3692 base, before_reloc - base);
3693
3694 input_line_pointer = base + (input_line_pointer-before_reloc);
3695 expression (&exp);
3696 memcpy (base, save_buf, p - base);
3697
3698 offset = nbytes - size;
4b1a927e
AM
3699 p = frag_more (nbytes);
3700 memset (p, 0, nbytes);
c19d1205 3701 fix_new_exp (frag_now, p - frag_now->fr_literal + offset,
21d799b5 3702 size, &exp, 0, (enum bfd_reloc_code_real) reloc);
e1fa0163 3703 free (save_buf);
c19d1205
ZW
3704 }
3705 }
3706 }
b99bd4ef 3707 }
c19d1205 3708 while (*input_line_pointer++ == ',');
b99bd4ef 3709
c19d1205
ZW
3710 /* Put terminator back into stream. */
3711 input_line_pointer --;
3712 demand_empty_rest_of_line ();
b99bd4ef
NC
3713}
3714
c921be7d
NC
3715/* Emit an expression containing a 32-bit thumb instruction.
3716 Implementation based on put_thumb32_insn. */
3717
3718static void
3719emit_thumb32_expr (expressionS * exp)
3720{
3721 expressionS exp_high = *exp;
3722
3723 exp_high.X_add_number = (unsigned long)exp_high.X_add_number >> 16;
3724 emit_expr (& exp_high, (unsigned int) THUMB_SIZE);
3725 exp->X_add_number &= 0xffff;
3726 emit_expr (exp, (unsigned int) THUMB_SIZE);
3727}
3728
3729/* Guess the instruction size based on the opcode. */
3730
3731static int
3732thumb_insn_size (int opcode)
3733{
3734 if ((unsigned int) opcode < 0xe800u)
3735 return 2;
3736 else if ((unsigned int) opcode >= 0xe8000000u)
3737 return 4;
3738 else
3739 return 0;
3740}
3741
3742static bfd_boolean
3743emit_insn (expressionS *exp, int nbytes)
3744{
3745 int size = 0;
3746
3747 if (exp->X_op == O_constant)
3748 {
3749 size = nbytes;
3750
3751 if (size == 0)
3752 size = thumb_insn_size (exp->X_add_number);
3753
3754 if (size != 0)
3755 {
3756 if (size == 2 && (unsigned int)exp->X_add_number > 0xffffu)
3757 {
3758 as_bad (_(".inst.n operand too big. "\
3759 "Use .inst.w instead"));
3760 size = 0;
3761 }
3762 else
3763 {
3764 if (now_it.state == AUTOMATIC_IT_BLOCK)
3765 set_it_insn_type_nonvoid (OUTSIDE_IT_INSN, 0);
3766 else
3767 set_it_insn_type_nonvoid (NEUTRAL_IT_INSN, 0);
3768
3769 if (thumb_mode && (size > THUMB_SIZE) && !target_big_endian)
3770 emit_thumb32_expr (exp);
3771 else
3772 emit_expr (exp, (unsigned int) size);
3773
3774 it_fsm_post_encode ();
3775 }
3776 }
3777 else
3778 as_bad (_("cannot determine Thumb instruction size. " \
3779 "Use .inst.n/.inst.w instead"));
3780 }
3781 else
3782 as_bad (_("constant expression required"));
3783
3784 return (size != 0);
3785}
3786
3787/* Like s_arm_elf_cons but do not use md_cons_align and
3788 set the mapping state to MAP_ARM/MAP_THUMB. */
3789
3790static void
3791s_arm_elf_inst (int nbytes)
3792{
3793 if (is_it_end_of_statement ())
3794 {
3795 demand_empty_rest_of_line ();
3796 return;
3797 }
3798
3799 /* Calling mapping_state () here will not change ARM/THUMB,
3800 but will ensure not to be in DATA state. */
3801
3802 if (thumb_mode)
3803 mapping_state (MAP_THUMB);
3804 else
3805 {
3806 if (nbytes != 0)
3807 {
3808 as_bad (_("width suffixes are invalid in ARM mode"));
3809 ignore_rest_of_line ();
3810 return;
3811 }
3812
3813 nbytes = 4;
3814
3815 mapping_state (MAP_ARM);
3816 }
3817
3818 do
3819 {
3820 expressionS exp;
3821
3822 expression (& exp);
3823
3824 if (! emit_insn (& exp, nbytes))
3825 {
3826 ignore_rest_of_line ();
3827 return;
3828 }
3829 }
3830 while (*input_line_pointer++ == ',');
3831
3832 /* Put terminator back into stream. */
3833 input_line_pointer --;
3834 demand_empty_rest_of_line ();
3835}
b99bd4ef 3836
c19d1205 3837/* Parse a .rel31 directive. */
b99bd4ef 3838
c19d1205
ZW
3839static void
3840s_arm_rel31 (int ignored ATTRIBUTE_UNUSED)
3841{
3842 expressionS exp;
3843 char *p;
3844 valueT highbit;
b99bd4ef 3845
c19d1205
ZW
3846 highbit = 0;
3847 if (*input_line_pointer == '1')
3848 highbit = 0x80000000;
3849 else if (*input_line_pointer != '0')
3850 as_bad (_("expected 0 or 1"));
b99bd4ef 3851
c19d1205
ZW
3852 input_line_pointer++;
3853 if (*input_line_pointer != ',')
3854 as_bad (_("missing comma"));
3855 input_line_pointer++;
b99bd4ef 3856
c19d1205
ZW
3857#ifdef md_flush_pending_output
3858 md_flush_pending_output ();
3859#endif
b99bd4ef 3860
c19d1205
ZW
3861#ifdef md_cons_align
3862 md_cons_align (4);
3863#endif
b99bd4ef 3864
c19d1205 3865 mapping_state (MAP_DATA);
b99bd4ef 3866
c19d1205 3867 expression (&exp);
b99bd4ef 3868
c19d1205
ZW
3869 p = frag_more (4);
3870 md_number_to_chars (p, highbit, 4);
3871 fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 1,
3872 BFD_RELOC_ARM_PREL31);
b99bd4ef 3873
c19d1205 3874 demand_empty_rest_of_line ();
b99bd4ef
NC
3875}
3876
c19d1205 3877/* Directives: AEABI stack-unwind tables. */
b99bd4ef 3878
c19d1205 3879/* Parse an unwind_fnstart directive. Simply records the current location. */
b99bd4ef 3880
c19d1205
ZW
3881static void
3882s_arm_unwind_fnstart (int ignored ATTRIBUTE_UNUSED)
3883{
3884 demand_empty_rest_of_line ();
921e5f0a
PB
3885 if (unwind.proc_start)
3886 {
c921be7d 3887 as_bad (_("duplicate .fnstart directive"));
921e5f0a
PB
3888 return;
3889 }
3890
c19d1205
ZW
3891 /* Mark the start of the function. */
3892 unwind.proc_start = expr_build_dot ();
b99bd4ef 3893
c19d1205
ZW
3894 /* Reset the rest of the unwind info. */
3895 unwind.opcode_count = 0;
3896 unwind.table_entry = NULL;
3897 unwind.personality_routine = NULL;
3898 unwind.personality_index = -1;
3899 unwind.frame_size = 0;
3900 unwind.fp_offset = 0;
fdfde340 3901 unwind.fp_reg = REG_SP;
c19d1205
ZW
3902 unwind.fp_used = 0;
3903 unwind.sp_restored = 0;
3904}
b99bd4ef 3905
b99bd4ef 3906
c19d1205
ZW
3907/* Parse a handlerdata directive. Creates the exception handling table entry
3908 for the function. */
b99bd4ef 3909
c19d1205
ZW
3910static void
3911s_arm_unwind_handlerdata (int ignored ATTRIBUTE_UNUSED)
3912{
3913 demand_empty_rest_of_line ();
921e5f0a 3914 if (!unwind.proc_start)
c921be7d 3915 as_bad (MISSING_FNSTART);
921e5f0a 3916
c19d1205 3917 if (unwind.table_entry)
6decc662 3918 as_bad (_("duplicate .handlerdata directive"));
f02232aa 3919
c19d1205
ZW
3920 create_unwind_entry (1);
3921}
a737bd4d 3922
c19d1205 3923/* Parse an unwind_fnend directive. Generates the index table entry. */
b99bd4ef 3924
c19d1205
ZW
3925static void
3926s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
3927{
3928 long where;
3929 char *ptr;
3930 valueT val;
940b5ce0 3931 unsigned int marked_pr_dependency;
f02232aa 3932
c19d1205 3933 demand_empty_rest_of_line ();
f02232aa 3934
921e5f0a
PB
3935 if (!unwind.proc_start)
3936 {
c921be7d 3937 as_bad (_(".fnend directive without .fnstart"));
921e5f0a
PB
3938 return;
3939 }
3940
c19d1205
ZW
3941 /* Add eh table entry. */
3942 if (unwind.table_entry == NULL)
3943 val = create_unwind_entry (0);
3944 else
3945 val = 0;
f02232aa 3946
c19d1205
ZW
3947 /* Add index table entry. This is two words. */
3948 start_unwind_section (unwind.saved_seg, 1);
3949 frag_align (2, 0, 0);
3950 record_alignment (now_seg, 2);
b99bd4ef 3951
c19d1205 3952 ptr = frag_more (8);
5011093d 3953 memset (ptr, 0, 8);
c19d1205 3954 where = frag_now_fix () - 8;
f02232aa 3955
c19d1205
ZW
3956 /* Self relative offset of the function start. */
3957 fix_new (frag_now, where, 4, unwind.proc_start, 0, 1,
3958 BFD_RELOC_ARM_PREL31);
f02232aa 3959
c19d1205
ZW
3960 /* Indicate dependency on EHABI-defined personality routines to the
3961 linker, if it hasn't been done already. */
940b5ce0
DJ
3962 marked_pr_dependency
3963 = seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency;
c19d1205
ZW
3964 if (unwind.personality_index >= 0 && unwind.personality_index < 3
3965 && !(marked_pr_dependency & (1 << unwind.personality_index)))
3966 {
5f4273c7
NC
3967 static const char *const name[] =
3968 {
3969 "__aeabi_unwind_cpp_pr0",
3970 "__aeabi_unwind_cpp_pr1",
3971 "__aeabi_unwind_cpp_pr2"
3972 };
c19d1205
ZW
3973 symbolS *pr = symbol_find_or_make (name[unwind.personality_index]);
3974 fix_new (frag_now, where, 0, pr, 0, 1, BFD_RELOC_NONE);
c19d1205 3975 seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency
940b5ce0 3976 |= 1 << unwind.personality_index;
c19d1205 3977 }
f02232aa 3978
c19d1205
ZW
3979 if (val)
3980 /* Inline exception table entry. */
3981 md_number_to_chars (ptr + 4, val, 4);
3982 else
3983 /* Self relative offset of the table entry. */
3984 fix_new (frag_now, where + 4, 4, unwind.table_entry, 0, 1,
3985 BFD_RELOC_ARM_PREL31);
f02232aa 3986
c19d1205
ZW
3987 /* Restore the original section. */
3988 subseg_set (unwind.saved_seg, unwind.saved_subseg);
921e5f0a
PB
3989
3990 unwind.proc_start = NULL;
c19d1205 3991}
f02232aa 3992
f02232aa 3993
c19d1205 3994/* Parse an unwind_cantunwind directive. */
b99bd4ef 3995
c19d1205
ZW
3996static void
3997s_arm_unwind_cantunwind (int ignored ATTRIBUTE_UNUSED)
3998{
3999 demand_empty_rest_of_line ();
921e5f0a 4000 if (!unwind.proc_start)
c921be7d 4001 as_bad (MISSING_FNSTART);
921e5f0a 4002
c19d1205
ZW
4003 if (unwind.personality_routine || unwind.personality_index != -1)
4004 as_bad (_("personality routine specified for cantunwind frame"));
b99bd4ef 4005
c19d1205
ZW
4006 unwind.personality_index = -2;
4007}
b99bd4ef 4008
b99bd4ef 4009
c19d1205 4010/* Parse a personalityindex directive. */
b99bd4ef 4011
c19d1205
ZW
4012static void
4013s_arm_unwind_personalityindex (int ignored ATTRIBUTE_UNUSED)
4014{
4015 expressionS exp;
b99bd4ef 4016
921e5f0a 4017 if (!unwind.proc_start)
c921be7d 4018 as_bad (MISSING_FNSTART);
921e5f0a 4019
c19d1205
ZW
4020 if (unwind.personality_routine || unwind.personality_index != -1)
4021 as_bad (_("duplicate .personalityindex directive"));
b99bd4ef 4022
c19d1205 4023 expression (&exp);
b99bd4ef 4024
c19d1205
ZW
4025 if (exp.X_op != O_constant
4026 || exp.X_add_number < 0 || exp.X_add_number > 15)
b99bd4ef 4027 {
c19d1205
ZW
4028 as_bad (_("bad personality routine number"));
4029 ignore_rest_of_line ();
4030 return;
b99bd4ef
NC
4031 }
4032
c19d1205 4033 unwind.personality_index = exp.X_add_number;
b99bd4ef 4034
c19d1205
ZW
4035 demand_empty_rest_of_line ();
4036}
e16bb312 4037
e16bb312 4038
c19d1205 4039/* Parse a personality directive. */
e16bb312 4040
c19d1205
ZW
4041static void
4042s_arm_unwind_personality (int ignored ATTRIBUTE_UNUSED)
4043{
4044 char *name, *p, c;
a737bd4d 4045
921e5f0a 4046 if (!unwind.proc_start)
c921be7d 4047 as_bad (MISSING_FNSTART);
921e5f0a 4048
c19d1205
ZW
4049 if (unwind.personality_routine || unwind.personality_index != -1)
4050 as_bad (_("duplicate .personality directive"));
a737bd4d 4051
d02603dc 4052 c = get_symbol_name (& name);
c19d1205 4053 p = input_line_pointer;
d02603dc
NC
4054 if (c == '"')
4055 ++ input_line_pointer;
c19d1205
ZW
4056 unwind.personality_routine = symbol_find_or_make (name);
4057 *p = c;
4058 demand_empty_rest_of_line ();
4059}
e16bb312 4060
e16bb312 4061
c19d1205 4062/* Parse a directive saving core registers. */
e16bb312 4063
c19d1205
ZW
4064static void
4065s_arm_unwind_save_core (void)
e16bb312 4066{
c19d1205
ZW
4067 valueT op;
4068 long range;
4069 int n;
e16bb312 4070
4b5a202f 4071 range = parse_reg_list (&input_line_pointer, REGLIST_RN);
c19d1205 4072 if (range == FAIL)
e16bb312 4073 {
c19d1205
ZW
4074 as_bad (_("expected register list"));
4075 ignore_rest_of_line ();
4076 return;
4077 }
e16bb312 4078
c19d1205 4079 demand_empty_rest_of_line ();
e16bb312 4080
c19d1205
ZW
4081 /* Turn .unwind_movsp ip followed by .unwind_save {..., ip, ...}
4082 into .unwind_save {..., sp...}. We aren't bothered about the value of
4083 ip because it is clobbered by calls. */
4084 if (unwind.sp_restored && unwind.fp_reg == 12
4085 && (range & 0x3000) == 0x1000)
4086 {
4087 unwind.opcode_count--;
4088 unwind.sp_restored = 0;
4089 range = (range | 0x2000) & ~0x1000;
4090 unwind.pending_offset = 0;
4091 }
e16bb312 4092
01ae4198
DJ
4093 /* Pop r4-r15. */
4094 if (range & 0xfff0)
c19d1205 4095 {
01ae4198
DJ
4096 /* See if we can use the short opcodes. These pop a block of up to 8
4097 registers starting with r4, plus maybe r14. */
4098 for (n = 0; n < 8; n++)
4099 {
4100 /* Break at the first non-saved register. */
4101 if ((range & (1 << (n + 4))) == 0)
4102 break;
4103 }
4104 /* See if there are any other bits set. */
4105 if (n == 0 || (range & (0xfff0 << n) & 0xbff0) != 0)
4106 {
4107 /* Use the long form. */
4108 op = 0x8000 | ((range >> 4) & 0xfff);
4109 add_unwind_opcode (op, 2);
4110 }
0dd132b6 4111 else
01ae4198
DJ
4112 {
4113 /* Use the short form. */
4114 if (range & 0x4000)
4115 op = 0xa8; /* Pop r14. */
4116 else
4117 op = 0xa0; /* Do not pop r14. */
4118 op |= (n - 1);
4119 add_unwind_opcode (op, 1);
4120 }
c19d1205 4121 }
0dd132b6 4122
c19d1205
ZW
4123 /* Pop r0-r3. */
4124 if (range & 0xf)
4125 {
4126 op = 0xb100 | (range & 0xf);
4127 add_unwind_opcode (op, 2);
0dd132b6
NC
4128 }
4129
c19d1205
ZW
4130 /* Record the number of bytes pushed. */
4131 for (n = 0; n < 16; n++)
4132 {
4133 if (range & (1 << n))
4134 unwind.frame_size += 4;
4135 }
0dd132b6
NC
4136}
4137
c19d1205
ZW
4138
4139/* Parse a directive saving FPA registers. */
b99bd4ef
NC
4140
4141static void
c19d1205 4142s_arm_unwind_save_fpa (int reg)
b99bd4ef 4143{
c19d1205
ZW
4144 expressionS exp;
4145 int num_regs;
4146 valueT op;
b99bd4ef 4147
c19d1205
ZW
4148 /* Get Number of registers to transfer. */
4149 if (skip_past_comma (&input_line_pointer) != FAIL)
4150 expression (&exp);
4151 else
4152 exp.X_op = O_illegal;
b99bd4ef 4153
c19d1205 4154 if (exp.X_op != O_constant)
b99bd4ef 4155 {
c19d1205
ZW
4156 as_bad (_("expected , <constant>"));
4157 ignore_rest_of_line ();
b99bd4ef
NC
4158 return;
4159 }
4160
c19d1205
ZW
4161 num_regs = exp.X_add_number;
4162
4163 if (num_regs < 1 || num_regs > 4)
b99bd4ef 4164 {
c19d1205
ZW
4165 as_bad (_("number of registers must be in the range [1:4]"));
4166 ignore_rest_of_line ();
b99bd4ef
NC
4167 return;
4168 }
4169
c19d1205 4170 demand_empty_rest_of_line ();
b99bd4ef 4171
c19d1205
ZW
4172 if (reg == 4)
4173 {
4174 /* Short form. */
4175 op = 0xb4 | (num_regs - 1);
4176 add_unwind_opcode (op, 1);
4177 }
b99bd4ef
NC
4178 else
4179 {
c19d1205
ZW
4180 /* Long form. */
4181 op = 0xc800 | (reg << 4) | (num_regs - 1);
4182 add_unwind_opcode (op, 2);
b99bd4ef 4183 }
c19d1205 4184 unwind.frame_size += num_regs * 12;
b99bd4ef
NC
4185}
4186
c19d1205 4187
fa073d69
MS
4188/* Parse a directive saving VFP registers for ARMv6 and above. */
4189
4190static void
4191s_arm_unwind_save_vfp_armv6 (void)
4192{
4193 int count;
4194 unsigned int start;
4195 valueT op;
4196 int num_vfpv3_regs = 0;
4197 int num_regs_below_16;
efd6b359 4198 bfd_boolean partial_match;
fa073d69 4199
efd6b359
AV
4200 count = parse_vfp_reg_list (&input_line_pointer, &start, REGLIST_VFP_D,
4201 &partial_match);
fa073d69
MS
4202 if (count == FAIL)
4203 {
4204 as_bad (_("expected register list"));
4205 ignore_rest_of_line ();
4206 return;
4207 }
4208
4209 demand_empty_rest_of_line ();
4210
4211 /* We always generate FSTMD/FLDMD-style unwinding opcodes (rather
4212 than FSTMX/FLDMX-style ones). */
4213
4214 /* Generate opcode for (VFPv3) registers numbered in the range 16 .. 31. */
4215 if (start >= 16)
4216 num_vfpv3_regs = count;
4217 else if (start + count > 16)
4218 num_vfpv3_regs = start + count - 16;
4219
4220 if (num_vfpv3_regs > 0)
4221 {
4222 int start_offset = start > 16 ? start - 16 : 0;
4223 op = 0xc800 | (start_offset << 4) | (num_vfpv3_regs - 1);
4224 add_unwind_opcode (op, 2);
4225 }
4226
4227 /* Generate opcode for registers numbered in the range 0 .. 15. */
4228 num_regs_below_16 = num_vfpv3_regs > 0 ? 16 - (int) start : count;
9c2799c2 4229 gas_assert (num_regs_below_16 + num_vfpv3_regs == count);
fa073d69
MS
4230 if (num_regs_below_16 > 0)
4231 {
4232 op = 0xc900 | (start << 4) | (num_regs_below_16 - 1);
4233 add_unwind_opcode (op, 2);
4234 }
4235
4236 unwind.frame_size += count * 8;
4237}
4238
4239
4240/* Parse a directive saving VFP registers for pre-ARMv6. */
b99bd4ef
NC
4241
4242static void
c19d1205 4243s_arm_unwind_save_vfp (void)
b99bd4ef 4244{
c19d1205 4245 int count;
ca3f61f7 4246 unsigned int reg;
c19d1205 4247 valueT op;
efd6b359 4248 bfd_boolean partial_match;
b99bd4ef 4249
efd6b359
AV
4250 count = parse_vfp_reg_list (&input_line_pointer, &reg, REGLIST_VFP_D,
4251 &partial_match);
c19d1205 4252 if (count == FAIL)
b99bd4ef 4253 {
c19d1205
ZW
4254 as_bad (_("expected register list"));
4255 ignore_rest_of_line ();
b99bd4ef
NC
4256 return;
4257 }
4258
c19d1205 4259 demand_empty_rest_of_line ();
b99bd4ef 4260
c19d1205 4261 if (reg == 8)
b99bd4ef 4262 {
c19d1205
ZW
4263 /* Short form. */
4264 op = 0xb8 | (count - 1);
4265 add_unwind_opcode (op, 1);
b99bd4ef 4266 }
c19d1205 4267 else
b99bd4ef 4268 {
c19d1205
ZW
4269 /* Long form. */
4270 op = 0xb300 | (reg << 4) | (count - 1);
4271 add_unwind_opcode (op, 2);
b99bd4ef 4272 }
c19d1205
ZW
4273 unwind.frame_size += count * 8 + 4;
4274}
b99bd4ef 4275
b99bd4ef 4276
c19d1205
ZW
4277/* Parse a directive saving iWMMXt data registers. */
4278
4279static void
4280s_arm_unwind_save_mmxwr (void)
4281{
4282 int reg;
4283 int hi_reg;
4284 int i;
4285 unsigned mask = 0;
4286 valueT op;
b99bd4ef 4287
c19d1205
ZW
4288 if (*input_line_pointer == '{')
4289 input_line_pointer++;
b99bd4ef 4290
c19d1205 4291 do
b99bd4ef 4292 {
dcbf9037 4293 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
b99bd4ef 4294
c19d1205 4295 if (reg == FAIL)
b99bd4ef 4296 {
9b7132d3 4297 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWR]));
c19d1205 4298 goto error;
b99bd4ef
NC
4299 }
4300
c19d1205
ZW
4301 if (mask >> reg)
4302 as_tsktsk (_("register list not in ascending order"));
4303 mask |= 1 << reg;
b99bd4ef 4304
c19d1205
ZW
4305 if (*input_line_pointer == '-')
4306 {
4307 input_line_pointer++;
dcbf9037 4308 hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
c19d1205
ZW
4309 if (hi_reg == FAIL)
4310 {
9b7132d3 4311 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWR]));
c19d1205
ZW
4312 goto error;
4313 }
4314 else if (reg >= hi_reg)
4315 {
4316 as_bad (_("bad register range"));
4317 goto error;
4318 }
4319 for (; reg < hi_reg; reg++)
4320 mask |= 1 << reg;
4321 }
4322 }
4323 while (skip_past_comma (&input_line_pointer) != FAIL);
b99bd4ef 4324
d996d970 4325 skip_past_char (&input_line_pointer, '}');
b99bd4ef 4326
c19d1205 4327 demand_empty_rest_of_line ();
b99bd4ef 4328
708587a4 4329 /* Generate any deferred opcodes because we're going to be looking at
c19d1205
ZW
4330 the list. */
4331 flush_pending_unwind ();
b99bd4ef 4332
c19d1205 4333 for (i = 0; i < 16; i++)
b99bd4ef 4334 {
c19d1205
ZW
4335 if (mask & (1 << i))
4336 unwind.frame_size += 8;
b99bd4ef
NC
4337 }
4338
c19d1205
ZW
4339 /* Attempt to combine with a previous opcode. We do this because gcc
4340 likes to output separate unwind directives for a single block of
4341 registers. */
4342 if (unwind.opcode_count > 0)
b99bd4ef 4343 {
c19d1205
ZW
4344 i = unwind.opcodes[unwind.opcode_count - 1];
4345 if ((i & 0xf8) == 0xc0)
4346 {
4347 i &= 7;
4348 /* Only merge if the blocks are contiguous. */
4349 if (i < 6)
4350 {
4351 if ((mask & 0xfe00) == (1 << 9))
4352 {
4353 mask |= ((1 << (i + 11)) - 1) & 0xfc00;
4354 unwind.opcode_count--;
4355 }
4356 }
4357 else if (i == 6 && unwind.opcode_count >= 2)
4358 {
4359 i = unwind.opcodes[unwind.opcode_count - 2];
4360 reg = i >> 4;
4361 i &= 0xf;
b99bd4ef 4362
c19d1205
ZW
4363 op = 0xffff << (reg - 1);
4364 if (reg > 0
87a1fd79 4365 && ((mask & op) == (1u << (reg - 1))))
c19d1205
ZW
4366 {
4367 op = (1 << (reg + i + 1)) - 1;
4368 op &= ~((1 << reg) - 1);
4369 mask |= op;
4370 unwind.opcode_count -= 2;
4371 }
4372 }
4373 }
b99bd4ef
NC
4374 }
4375
c19d1205
ZW
4376 hi_reg = 15;
4377 /* We want to generate opcodes in the order the registers have been
4378 saved, ie. descending order. */
4379 for (reg = 15; reg >= -1; reg--)
b99bd4ef 4380 {
c19d1205
ZW
4381 /* Save registers in blocks. */
4382 if (reg < 0
4383 || !(mask & (1 << reg)))
4384 {
4385 /* We found an unsaved reg. Generate opcodes to save the
5f4273c7 4386 preceding block. */
c19d1205
ZW
4387 if (reg != hi_reg)
4388 {
4389 if (reg == 9)
4390 {
4391 /* Short form. */
4392 op = 0xc0 | (hi_reg - 10);
4393 add_unwind_opcode (op, 1);
4394 }
4395 else
4396 {
4397 /* Long form. */
4398 op = 0xc600 | ((reg + 1) << 4) | ((hi_reg - reg) - 1);
4399 add_unwind_opcode (op, 2);
4400 }
4401 }
4402 hi_reg = reg - 1;
4403 }
b99bd4ef
NC
4404 }
4405
c19d1205
ZW
4406 return;
4407error:
4408 ignore_rest_of_line ();
b99bd4ef
NC
4409}
4410
4411static void
c19d1205 4412s_arm_unwind_save_mmxwcg (void)
b99bd4ef 4413{
c19d1205
ZW
4414 int reg;
4415 int hi_reg;
4416 unsigned mask = 0;
4417 valueT op;
b99bd4ef 4418
c19d1205
ZW
4419 if (*input_line_pointer == '{')
4420 input_line_pointer++;
b99bd4ef 4421
477330fc
RM
4422 skip_whitespace (input_line_pointer);
4423
c19d1205 4424 do
b99bd4ef 4425 {
dcbf9037 4426 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
b99bd4ef 4427
c19d1205
ZW
4428 if (reg == FAIL)
4429 {
9b7132d3 4430 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWCG]));
c19d1205
ZW
4431 goto error;
4432 }
b99bd4ef 4433
c19d1205
ZW
4434 reg -= 8;
4435 if (mask >> reg)
4436 as_tsktsk (_("register list not in ascending order"));
4437 mask |= 1 << reg;
b99bd4ef 4438
c19d1205
ZW
4439 if (*input_line_pointer == '-')
4440 {
4441 input_line_pointer++;
dcbf9037 4442 hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
c19d1205
ZW
4443 if (hi_reg == FAIL)
4444 {
9b7132d3 4445 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWCG]));
c19d1205
ZW
4446 goto error;
4447 }
4448 else if (reg >= hi_reg)
4449 {
4450 as_bad (_("bad register range"));
4451 goto error;
4452 }
4453 for (; reg < hi_reg; reg++)
4454 mask |= 1 << reg;
4455 }
b99bd4ef 4456 }
c19d1205 4457 while (skip_past_comma (&input_line_pointer) != FAIL);
b99bd4ef 4458
d996d970 4459 skip_past_char (&input_line_pointer, '}');
b99bd4ef 4460
c19d1205
ZW
4461 demand_empty_rest_of_line ();
4462
708587a4 4463 /* Generate any deferred opcodes because we're going to be looking at
c19d1205
ZW
4464 the list. */
4465 flush_pending_unwind ();
b99bd4ef 4466
c19d1205 4467 for (reg = 0; reg < 16; reg++)
b99bd4ef 4468 {
c19d1205
ZW
4469 if (mask & (1 << reg))
4470 unwind.frame_size += 4;
b99bd4ef 4471 }
c19d1205
ZW
4472 op = 0xc700 | mask;
4473 add_unwind_opcode (op, 2);
4474 return;
4475error:
4476 ignore_rest_of_line ();
b99bd4ef
NC
4477}
4478
c19d1205 4479
fa073d69
MS
4480/* Parse an unwind_save directive.
4481 If the argument is non-zero, this is a .vsave directive. */
c19d1205 4482
b99bd4ef 4483static void
fa073d69 4484s_arm_unwind_save (int arch_v6)
b99bd4ef 4485{
c19d1205
ZW
4486 char *peek;
4487 struct reg_entry *reg;
4488 bfd_boolean had_brace = FALSE;
b99bd4ef 4489
921e5f0a 4490 if (!unwind.proc_start)
c921be7d 4491 as_bad (MISSING_FNSTART);
921e5f0a 4492
c19d1205
ZW
4493 /* Figure out what sort of save we have. */
4494 peek = input_line_pointer;
b99bd4ef 4495
c19d1205 4496 if (*peek == '{')
b99bd4ef 4497 {
c19d1205
ZW
4498 had_brace = TRUE;
4499 peek++;
b99bd4ef
NC
4500 }
4501
c19d1205 4502 reg = arm_reg_parse_multi (&peek);
b99bd4ef 4503
c19d1205 4504 if (!reg)
b99bd4ef 4505 {
c19d1205
ZW
4506 as_bad (_("register expected"));
4507 ignore_rest_of_line ();
b99bd4ef
NC
4508 return;
4509 }
4510
c19d1205 4511 switch (reg->type)
b99bd4ef 4512 {
c19d1205
ZW
4513 case REG_TYPE_FN:
4514 if (had_brace)
4515 {
4516 as_bad (_("FPA .unwind_save does not take a register list"));
4517 ignore_rest_of_line ();
4518 return;
4519 }
93ac2687 4520 input_line_pointer = peek;
c19d1205 4521 s_arm_unwind_save_fpa (reg->number);
b99bd4ef 4522 return;
c19d1205 4523
1f5afe1c
NC
4524 case REG_TYPE_RN:
4525 s_arm_unwind_save_core ();
4526 return;
4527
fa073d69
MS
4528 case REG_TYPE_VFD:
4529 if (arch_v6)
477330fc 4530 s_arm_unwind_save_vfp_armv6 ();
fa073d69 4531 else
477330fc 4532 s_arm_unwind_save_vfp ();
fa073d69 4533 return;
1f5afe1c
NC
4534
4535 case REG_TYPE_MMXWR:
4536 s_arm_unwind_save_mmxwr ();
4537 return;
4538
4539 case REG_TYPE_MMXWCG:
4540 s_arm_unwind_save_mmxwcg ();
4541 return;
c19d1205
ZW
4542
4543 default:
4544 as_bad (_(".unwind_save does not support this kind of register"));
4545 ignore_rest_of_line ();
b99bd4ef 4546 }
c19d1205 4547}
b99bd4ef 4548
b99bd4ef 4549
c19d1205
ZW
4550/* Parse an unwind_movsp directive. */
4551
4552static void
4553s_arm_unwind_movsp (int ignored ATTRIBUTE_UNUSED)
4554{
4555 int reg;
4556 valueT op;
4fa3602b 4557 int offset;
c19d1205 4558
921e5f0a 4559 if (!unwind.proc_start)
c921be7d 4560 as_bad (MISSING_FNSTART);
921e5f0a 4561
dcbf9037 4562 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
c19d1205 4563 if (reg == FAIL)
b99bd4ef 4564 {
9b7132d3 4565 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_RN]));
c19d1205 4566 ignore_rest_of_line ();
b99bd4ef
NC
4567 return;
4568 }
4fa3602b
PB
4569
4570 /* Optional constant. */
4571 if (skip_past_comma (&input_line_pointer) != FAIL)
4572 {
4573 if (immediate_for_directive (&offset) == FAIL)
4574 return;
4575 }
4576 else
4577 offset = 0;
4578
c19d1205 4579 demand_empty_rest_of_line ();
b99bd4ef 4580
c19d1205 4581 if (reg == REG_SP || reg == REG_PC)
b99bd4ef 4582 {
c19d1205 4583 as_bad (_("SP and PC not permitted in .unwind_movsp directive"));
b99bd4ef
NC
4584 return;
4585 }
4586
c19d1205
ZW
4587 if (unwind.fp_reg != REG_SP)
4588 as_bad (_("unexpected .unwind_movsp directive"));
b99bd4ef 4589
c19d1205
ZW
4590 /* Generate opcode to restore the value. */
4591 op = 0x90 | reg;
4592 add_unwind_opcode (op, 1);
4593
4594 /* Record the information for later. */
4595 unwind.fp_reg = reg;
4fa3602b 4596 unwind.fp_offset = unwind.frame_size - offset;
c19d1205 4597 unwind.sp_restored = 1;
b05fe5cf
ZW
4598}
4599
c19d1205
ZW
4600/* Parse an unwind_pad directive. */
4601
b05fe5cf 4602static void
c19d1205 4603s_arm_unwind_pad (int ignored ATTRIBUTE_UNUSED)
b05fe5cf 4604{
c19d1205 4605 int offset;
b05fe5cf 4606
921e5f0a 4607 if (!unwind.proc_start)
c921be7d 4608 as_bad (MISSING_FNSTART);
921e5f0a 4609
c19d1205
ZW
4610 if (immediate_for_directive (&offset) == FAIL)
4611 return;
b99bd4ef 4612
c19d1205
ZW
4613 if (offset & 3)
4614 {
4615 as_bad (_("stack increment must be multiple of 4"));
4616 ignore_rest_of_line ();
4617 return;
4618 }
b99bd4ef 4619
c19d1205
ZW
4620 /* Don't generate any opcodes, just record the details for later. */
4621 unwind.frame_size += offset;
4622 unwind.pending_offset += offset;
4623
4624 demand_empty_rest_of_line ();
4625}
4626
4627/* Parse an unwind_setfp directive. */
4628
4629static void
4630s_arm_unwind_setfp (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 4631{
c19d1205
ZW
4632 int sp_reg;
4633 int fp_reg;
4634 int offset;
4635
921e5f0a 4636 if (!unwind.proc_start)
c921be7d 4637 as_bad (MISSING_FNSTART);
921e5f0a 4638
dcbf9037 4639 fp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
c19d1205
ZW
4640 if (skip_past_comma (&input_line_pointer) == FAIL)
4641 sp_reg = FAIL;
4642 else
dcbf9037 4643 sp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
b99bd4ef 4644
c19d1205
ZW
4645 if (fp_reg == FAIL || sp_reg == FAIL)
4646 {
4647 as_bad (_("expected <reg>, <reg>"));
4648 ignore_rest_of_line ();
4649 return;
4650 }
b99bd4ef 4651
c19d1205
ZW
4652 /* Optional constant. */
4653 if (skip_past_comma (&input_line_pointer) != FAIL)
4654 {
4655 if (immediate_for_directive (&offset) == FAIL)
4656 return;
4657 }
4658 else
4659 offset = 0;
a737bd4d 4660
c19d1205 4661 demand_empty_rest_of_line ();
a737bd4d 4662
fdfde340 4663 if (sp_reg != REG_SP && sp_reg != unwind.fp_reg)
a737bd4d 4664 {
c19d1205
ZW
4665 as_bad (_("register must be either sp or set by a previous"
4666 "unwind_movsp directive"));
4667 return;
a737bd4d
NC
4668 }
4669
c19d1205
ZW
4670 /* Don't generate any opcodes, just record the information for later. */
4671 unwind.fp_reg = fp_reg;
4672 unwind.fp_used = 1;
fdfde340 4673 if (sp_reg == REG_SP)
c19d1205
ZW
4674 unwind.fp_offset = unwind.frame_size - offset;
4675 else
4676 unwind.fp_offset -= offset;
a737bd4d
NC
4677}
4678
c19d1205
ZW
4679/* Parse an unwind_raw directive. */
4680
4681static void
4682s_arm_unwind_raw (int ignored ATTRIBUTE_UNUSED)
a737bd4d 4683{
c19d1205 4684 expressionS exp;
708587a4 4685 /* This is an arbitrary limit. */
c19d1205
ZW
4686 unsigned char op[16];
4687 int count;
a737bd4d 4688
921e5f0a 4689 if (!unwind.proc_start)
c921be7d 4690 as_bad (MISSING_FNSTART);
921e5f0a 4691
c19d1205
ZW
4692 expression (&exp);
4693 if (exp.X_op == O_constant
4694 && skip_past_comma (&input_line_pointer) != FAIL)
a737bd4d 4695 {
c19d1205
ZW
4696 unwind.frame_size += exp.X_add_number;
4697 expression (&exp);
4698 }
4699 else
4700 exp.X_op = O_illegal;
a737bd4d 4701
c19d1205
ZW
4702 if (exp.X_op != O_constant)
4703 {
4704 as_bad (_("expected <offset>, <opcode>"));
4705 ignore_rest_of_line ();
4706 return;
4707 }
a737bd4d 4708
c19d1205 4709 count = 0;
a737bd4d 4710
c19d1205
ZW
4711 /* Parse the opcode. */
4712 for (;;)
4713 {
4714 if (count >= 16)
4715 {
4716 as_bad (_("unwind opcode too long"));
4717 ignore_rest_of_line ();
a737bd4d 4718 }
c19d1205 4719 if (exp.X_op != O_constant || exp.X_add_number & ~0xff)
a737bd4d 4720 {
c19d1205
ZW
4721 as_bad (_("invalid unwind opcode"));
4722 ignore_rest_of_line ();
4723 return;
a737bd4d 4724 }
c19d1205 4725 op[count++] = exp.X_add_number;
a737bd4d 4726
c19d1205
ZW
4727 /* Parse the next byte. */
4728 if (skip_past_comma (&input_line_pointer) == FAIL)
4729 break;
a737bd4d 4730
c19d1205
ZW
4731 expression (&exp);
4732 }
b99bd4ef 4733
c19d1205
ZW
4734 /* Add the opcode bytes in reverse order. */
4735 while (count--)
4736 add_unwind_opcode (op[count], 1);
b99bd4ef 4737
c19d1205 4738 demand_empty_rest_of_line ();
b99bd4ef 4739}
ee065d83
PB
4740
4741
4742/* Parse a .eabi_attribute directive. */
4743
4744static void
4745s_arm_eabi_attribute (int ignored ATTRIBUTE_UNUSED)
4746{
0420f52b 4747 int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC);
ee3c0378
AS
4748
4749 if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
4750 attributes_set_explicitly[tag] = 1;
ee065d83
PB
4751}
4752
0855e32b
NS
4753/* Emit a tls fix for the symbol. */
4754
4755static void
4756s_arm_tls_descseq (int ignored ATTRIBUTE_UNUSED)
4757{
4758 char *p;
4759 expressionS exp;
4760#ifdef md_flush_pending_output
4761 md_flush_pending_output ();
4762#endif
4763
4764#ifdef md_cons_align
4765 md_cons_align (4);
4766#endif
4767
4768 /* Since we're just labelling the code, there's no need to define a
4769 mapping symbol. */
4770 expression (&exp);
4771 p = obstack_next_free (&frchain_now->frch_obstack);
4772 fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
4773 thumb_mode ? BFD_RELOC_ARM_THM_TLS_DESCSEQ
4774 : BFD_RELOC_ARM_TLS_DESCSEQ);
4775}
cdf9ccec 4776#endif /* OBJ_ELF */
0855e32b 4777
ee065d83 4778static void s_arm_arch (int);
7a1d4c38 4779static void s_arm_object_arch (int);
ee065d83
PB
4780static void s_arm_cpu (int);
4781static void s_arm_fpu (int);
69133863 4782static void s_arm_arch_extension (int);
b99bd4ef 4783
f0927246
NC
4784#ifdef TE_PE
4785
4786static void
5f4273c7 4787pe_directive_secrel (int dummy ATTRIBUTE_UNUSED)
f0927246
NC
4788{
4789 expressionS exp;
4790
4791 do
4792 {
4793 expression (&exp);
4794 if (exp.X_op == O_symbol)
4795 exp.X_op = O_secrel;
4796
4797 emit_expr (&exp, 4);
4798 }
4799 while (*input_line_pointer++ == ',');
4800
4801 input_line_pointer--;
4802 demand_empty_rest_of_line ();
4803}
4804#endif /* TE_PE */
4805
c19d1205
ZW
4806/* This table describes all the machine specific pseudo-ops the assembler
4807 has to support. The fields are:
4808 pseudo-op name without dot
4809 function to call to execute this pseudo-op
4810 Integer arg to pass to the function. */
b99bd4ef 4811
c19d1205 4812const pseudo_typeS md_pseudo_table[] =
b99bd4ef 4813{
c19d1205
ZW
4814 /* Never called because '.req' does not start a line. */
4815 { "req", s_req, 0 },
dcbf9037
JB
4816 /* Following two are likewise never called. */
4817 { "dn", s_dn, 0 },
4818 { "qn", s_qn, 0 },
c19d1205
ZW
4819 { "unreq", s_unreq, 0 },
4820 { "bss", s_bss, 0 },
db2ed2e0 4821 { "align", s_align_ptwo, 2 },
c19d1205
ZW
4822 { "arm", s_arm, 0 },
4823 { "thumb", s_thumb, 0 },
4824 { "code", s_code, 0 },
4825 { "force_thumb", s_force_thumb, 0 },
4826 { "thumb_func", s_thumb_func, 0 },
4827 { "thumb_set", s_thumb_set, 0 },
4828 { "even", s_even, 0 },
4829 { "ltorg", s_ltorg, 0 },
4830 { "pool", s_ltorg, 0 },
4831 { "syntax", s_syntax, 0 },
8463be01
PB
4832 { "cpu", s_arm_cpu, 0 },
4833 { "arch", s_arm_arch, 0 },
7a1d4c38 4834 { "object_arch", s_arm_object_arch, 0 },
8463be01 4835 { "fpu", s_arm_fpu, 0 },
69133863 4836 { "arch_extension", s_arm_arch_extension, 0 },
c19d1205 4837#ifdef OBJ_ELF
c921be7d
NC
4838 { "word", s_arm_elf_cons, 4 },
4839 { "long", s_arm_elf_cons, 4 },
4840 { "inst.n", s_arm_elf_inst, 2 },
4841 { "inst.w", s_arm_elf_inst, 4 },
4842 { "inst", s_arm_elf_inst, 0 },
4843 { "rel31", s_arm_rel31, 0 },
c19d1205
ZW
4844 { "fnstart", s_arm_unwind_fnstart, 0 },
4845 { "fnend", s_arm_unwind_fnend, 0 },
4846 { "cantunwind", s_arm_unwind_cantunwind, 0 },
4847 { "personality", s_arm_unwind_personality, 0 },
4848 { "personalityindex", s_arm_unwind_personalityindex, 0 },
4849 { "handlerdata", s_arm_unwind_handlerdata, 0 },
4850 { "save", s_arm_unwind_save, 0 },
fa073d69 4851 { "vsave", s_arm_unwind_save, 1 },
c19d1205
ZW
4852 { "movsp", s_arm_unwind_movsp, 0 },
4853 { "pad", s_arm_unwind_pad, 0 },
4854 { "setfp", s_arm_unwind_setfp, 0 },
4855 { "unwind_raw", s_arm_unwind_raw, 0 },
ee065d83 4856 { "eabi_attribute", s_arm_eabi_attribute, 0 },
0855e32b 4857 { "tlsdescseq", s_arm_tls_descseq, 0 },
c19d1205
ZW
4858#else
4859 { "word", cons, 4},
f0927246
NC
4860
4861 /* These are used for dwarf. */
4862 {"2byte", cons, 2},
4863 {"4byte", cons, 4},
4864 {"8byte", cons, 8},
4865 /* These are used for dwarf2. */
68d20676 4866 { "file", dwarf2_directive_file, 0 },
f0927246
NC
4867 { "loc", dwarf2_directive_loc, 0 },
4868 { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 },
c19d1205
ZW
4869#endif
4870 { "extend", float_cons, 'x' },
4871 { "ldouble", float_cons, 'x' },
4872 { "packed", float_cons, 'p' },
f0927246
NC
4873#ifdef TE_PE
4874 {"secrel32", pe_directive_secrel, 0},
4875#endif
2e6976a8
DG
4876
4877 /* These are for compatibility with CodeComposer Studio. */
4878 {"ref", s_ccs_ref, 0},
4879 {"def", s_ccs_def, 0},
4880 {"asmfunc", s_ccs_asmfunc, 0},
4881 {"endasmfunc", s_ccs_endasmfunc, 0},
4882
c19d1205
ZW
4883 { 0, 0, 0 }
4884};
4885\f
4886/* Parser functions used exclusively in instruction operands. */
b99bd4ef 4887
c19d1205
ZW
4888/* Generic immediate-value read function for use in insn parsing.
4889 STR points to the beginning of the immediate (the leading #);
4890 VAL receives the value; if the value is outside [MIN, MAX]
4891 issue an error. PREFIX_OPT is true if the immediate prefix is
4892 optional. */
b99bd4ef 4893
c19d1205
ZW
4894static int
4895parse_immediate (char **str, int *val, int min, int max,
4896 bfd_boolean prefix_opt)
4897{
4898 expressionS exp;
0198d5e6 4899
c19d1205
ZW
4900 my_get_expression (&exp, str, prefix_opt ? GE_OPT_PREFIX : GE_IMM_PREFIX);
4901 if (exp.X_op != O_constant)
b99bd4ef 4902 {
c19d1205
ZW
4903 inst.error = _("constant expression required");
4904 return FAIL;
4905 }
b99bd4ef 4906
c19d1205
ZW
4907 if (exp.X_add_number < min || exp.X_add_number > max)
4908 {
4909 inst.error = _("immediate value out of range");
4910 return FAIL;
4911 }
b99bd4ef 4912
c19d1205
ZW
4913 *val = exp.X_add_number;
4914 return SUCCESS;
4915}
b99bd4ef 4916
5287ad62 4917/* Less-generic immediate-value read function with the possibility of loading a
036dc3f7 4918 big (64-bit) immediate, as required by Neon VMOV, VMVN and logic immediate
5287ad62
JB
4919 instructions. Puts the result directly in inst.operands[i]. */
4920
4921static int
8335d6aa
JW
4922parse_big_immediate (char **str, int i, expressionS *in_exp,
4923 bfd_boolean allow_symbol_p)
5287ad62
JB
4924{
4925 expressionS exp;
8335d6aa 4926 expressionS *exp_p = in_exp ? in_exp : &exp;
5287ad62
JB
4927 char *ptr = *str;
4928
8335d6aa 4929 my_get_expression (exp_p, &ptr, GE_OPT_PREFIX_BIG);
5287ad62 4930
8335d6aa 4931 if (exp_p->X_op == O_constant)
036dc3f7 4932 {
8335d6aa 4933 inst.operands[i].imm = exp_p->X_add_number & 0xffffffff;
036dc3f7
PB
4934 /* If we're on a 64-bit host, then a 64-bit number can be returned using
4935 O_constant. We have to be careful not to break compilation for
4936 32-bit X_add_number, though. */
8335d6aa 4937 if ((exp_p->X_add_number & ~(offsetT)(0xffffffffU)) != 0)
036dc3f7 4938 {
8335d6aa
JW
4939 /* X >> 32 is illegal if sizeof (exp_p->X_add_number) == 4. */
4940 inst.operands[i].reg = (((exp_p->X_add_number >> 16) >> 16)
4941 & 0xffffffff);
036dc3f7
PB
4942 inst.operands[i].regisimm = 1;
4943 }
4944 }
8335d6aa
JW
4945 else if (exp_p->X_op == O_big
4946 && LITTLENUM_NUMBER_OF_BITS * exp_p->X_add_number > 32)
5287ad62
JB
4947 {
4948 unsigned parts = 32 / LITTLENUM_NUMBER_OF_BITS, j, idx = 0;
95b75c01 4949
5287ad62 4950 /* Bignums have their least significant bits in
477330fc
RM
4951 generic_bignum[0]. Make sure we put 32 bits in imm and
4952 32 bits in reg, in a (hopefully) portable way. */
9c2799c2 4953 gas_assert (parts != 0);
95b75c01
NC
4954
4955 /* Make sure that the number is not too big.
4956 PR 11972: Bignums can now be sign-extended to the
4957 size of a .octa so check that the out of range bits
4958 are all zero or all one. */
8335d6aa 4959 if (LITTLENUM_NUMBER_OF_BITS * exp_p->X_add_number > 64)
95b75c01
NC
4960 {
4961 LITTLENUM_TYPE m = -1;
4962
4963 if (generic_bignum[parts * 2] != 0
4964 && generic_bignum[parts * 2] != m)
4965 return FAIL;
4966
8335d6aa 4967 for (j = parts * 2 + 1; j < (unsigned) exp_p->X_add_number; j++)
95b75c01
NC
4968 if (generic_bignum[j] != generic_bignum[j-1])
4969 return FAIL;
4970 }
4971
5287ad62
JB
4972 inst.operands[i].imm = 0;
4973 for (j = 0; j < parts; j++, idx++)
477330fc
RM
4974 inst.operands[i].imm |= generic_bignum[idx]
4975 << (LITTLENUM_NUMBER_OF_BITS * j);
5287ad62
JB
4976 inst.operands[i].reg = 0;
4977 for (j = 0; j < parts; j++, idx++)
477330fc
RM
4978 inst.operands[i].reg |= generic_bignum[idx]
4979 << (LITTLENUM_NUMBER_OF_BITS * j);
5287ad62
JB
4980 inst.operands[i].regisimm = 1;
4981 }
8335d6aa 4982 else if (!(exp_p->X_op == O_symbol && allow_symbol_p))
5287ad62 4983 return FAIL;
5f4273c7 4984
5287ad62
JB
4985 *str = ptr;
4986
4987 return SUCCESS;
4988}
4989
c19d1205
ZW
4990/* Returns the pseudo-register number of an FPA immediate constant,
4991 or FAIL if there isn't a valid constant here. */
b99bd4ef 4992
c19d1205
ZW
4993static int
4994parse_fpa_immediate (char ** str)
4995{
4996 LITTLENUM_TYPE words[MAX_LITTLENUMS];
4997 char * save_in;
4998 expressionS exp;
4999 int i;
5000 int j;
b99bd4ef 5001
c19d1205
ZW
5002 /* First try and match exact strings, this is to guarantee
5003 that some formats will work even for cross assembly. */
b99bd4ef 5004
c19d1205
ZW
5005 for (i = 0; fp_const[i]; i++)
5006 {
5007 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
b99bd4ef 5008 {
c19d1205 5009 char *start = *str;
b99bd4ef 5010
c19d1205
ZW
5011 *str += strlen (fp_const[i]);
5012 if (is_end_of_line[(unsigned char) **str])
5013 return i + 8;
5014 *str = start;
5015 }
5016 }
b99bd4ef 5017
c19d1205
ZW
5018 /* Just because we didn't get a match doesn't mean that the constant
5019 isn't valid, just that it is in a format that we don't
5020 automatically recognize. Try parsing it with the standard
5021 expression routines. */
b99bd4ef 5022
c19d1205 5023 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
b99bd4ef 5024
c19d1205
ZW
5025 /* Look for a raw floating point number. */
5026 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
5027 && is_end_of_line[(unsigned char) *save_in])
5028 {
5029 for (i = 0; i < NUM_FLOAT_VALS; i++)
5030 {
5031 for (j = 0; j < MAX_LITTLENUMS; j++)
b99bd4ef 5032 {
c19d1205
ZW
5033 if (words[j] != fp_values[i][j])
5034 break;
b99bd4ef
NC
5035 }
5036
c19d1205 5037 if (j == MAX_LITTLENUMS)
b99bd4ef 5038 {
c19d1205
ZW
5039 *str = save_in;
5040 return i + 8;
b99bd4ef
NC
5041 }
5042 }
5043 }
b99bd4ef 5044
c19d1205
ZW
5045 /* Try and parse a more complex expression, this will probably fail
5046 unless the code uses a floating point prefix (eg "0f"). */
5047 save_in = input_line_pointer;
5048 input_line_pointer = *str;
5049 if (expression (&exp) == absolute_section
5050 && exp.X_op == O_big
5051 && exp.X_add_number < 0)
5052 {
5053 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
5054 Ditto for 15. */
ba592044
AM
5055#define X_PRECISION 5
5056#define E_PRECISION 15L
5057 if (gen_to_words (words, X_PRECISION, E_PRECISION) == 0)
c19d1205
ZW
5058 {
5059 for (i = 0; i < NUM_FLOAT_VALS; i++)
5060 {
5061 for (j = 0; j < MAX_LITTLENUMS; j++)
5062 {
5063 if (words[j] != fp_values[i][j])
5064 break;
5065 }
b99bd4ef 5066
c19d1205
ZW
5067 if (j == MAX_LITTLENUMS)
5068 {
5069 *str = input_line_pointer;
5070 input_line_pointer = save_in;
5071 return i + 8;
5072 }
5073 }
5074 }
b99bd4ef
NC
5075 }
5076
c19d1205
ZW
5077 *str = input_line_pointer;
5078 input_line_pointer = save_in;
5079 inst.error = _("invalid FPA immediate expression");
5080 return FAIL;
b99bd4ef
NC
5081}
5082
136da414
JB
5083/* Returns 1 if a number has "quarter-precision" float format
5084 0baBbbbbbc defgh000 00000000 00000000. */
5085
5086static int
5087is_quarter_float (unsigned imm)
5088{
5089 int bs = (imm & 0x20000000) ? 0x3e000000 : 0x40000000;
5090 return (imm & 0x7ffff) == 0 && ((imm & 0x7e000000) ^ bs) == 0;
5091}
5092
aacf0b33
KT
5093
5094/* Detect the presence of a floating point or integer zero constant,
5095 i.e. #0.0 or #0. */
5096
5097static bfd_boolean
5098parse_ifimm_zero (char **in)
5099{
5100 int error_code;
5101
5102 if (!is_immediate_prefix (**in))
3c6452ae
TP
5103 {
5104 /* In unified syntax, all prefixes are optional. */
5105 if (!unified_syntax)
5106 return FALSE;
5107 }
5108 else
5109 ++*in;
0900a05b
JW
5110
5111 /* Accept #0x0 as a synonym for #0. */
5112 if (strncmp (*in, "0x", 2) == 0)
5113 {
5114 int val;
5115 if (parse_immediate (in, &val, 0, 0, TRUE) == FAIL)
5116 return FALSE;
5117 return TRUE;
5118 }
5119
aacf0b33
KT
5120 error_code = atof_generic (in, ".", EXP_CHARS,
5121 &generic_floating_point_number);
5122
5123 if (!error_code
5124 && generic_floating_point_number.sign == '+'
5125 && (generic_floating_point_number.low
5126 > generic_floating_point_number.leader))
5127 return TRUE;
5128
5129 return FALSE;
5130}
5131
136da414
JB
5132/* Parse an 8-bit "quarter-precision" floating point number of the form:
5133 0baBbbbbbc defgh000 00000000 00000000.
c96612cc
JB
5134 The zero and minus-zero cases need special handling, since they can't be
5135 encoded in the "quarter-precision" float format, but can nonetheless be
5136 loaded as integer constants. */
136da414
JB
5137
5138static unsigned
5139parse_qfloat_immediate (char **ccp, int *immed)
5140{
5141 char *str = *ccp;
c96612cc 5142 char *fpnum;
136da414 5143 LITTLENUM_TYPE words[MAX_LITTLENUMS];
c96612cc 5144 int found_fpchar = 0;
5f4273c7 5145
136da414 5146 skip_past_char (&str, '#');
5f4273c7 5147
c96612cc
JB
5148 /* We must not accidentally parse an integer as a floating-point number. Make
5149 sure that the value we parse is not an integer by checking for special
5150 characters '.' or 'e'.
5151 FIXME: This is a horrible hack, but doing better is tricky because type
5152 information isn't in a very usable state at parse time. */
5153 fpnum = str;
5154 skip_whitespace (fpnum);
5155
5156 if (strncmp (fpnum, "0x", 2) == 0)
5157 return FAIL;
5158 else
5159 {
5160 for (; *fpnum != '\0' && *fpnum != ' ' && *fpnum != '\n'; fpnum++)
477330fc
RM
5161 if (*fpnum == '.' || *fpnum == 'e' || *fpnum == 'E')
5162 {
5163 found_fpchar = 1;
5164 break;
5165 }
c96612cc
JB
5166
5167 if (!found_fpchar)
477330fc 5168 return FAIL;
c96612cc 5169 }
5f4273c7 5170
136da414
JB
5171 if ((str = atof_ieee (str, 's', words)) != NULL)
5172 {
5173 unsigned fpword = 0;
5174 int i;
5f4273c7 5175
136da414
JB
5176 /* Our FP word must be 32 bits (single-precision FP). */
5177 for (i = 0; i < 32 / LITTLENUM_NUMBER_OF_BITS; i++)
477330fc
RM
5178 {
5179 fpword <<= LITTLENUM_NUMBER_OF_BITS;
5180 fpword |= words[i];
5181 }
5f4273c7 5182
c96612cc 5183 if (is_quarter_float (fpword) || (fpword & 0x7fffffff) == 0)
477330fc 5184 *immed = fpword;
136da414 5185 else
477330fc 5186 return FAIL;
136da414
JB
5187
5188 *ccp = str;
5f4273c7 5189
136da414
JB
5190 return SUCCESS;
5191 }
5f4273c7 5192
136da414
JB
5193 return FAIL;
5194}
5195
c19d1205
ZW
5196/* Shift operands. */
5197enum shift_kind
b99bd4ef 5198{
c19d1205
ZW
5199 SHIFT_LSL, SHIFT_LSR, SHIFT_ASR, SHIFT_ROR, SHIFT_RRX
5200};
b99bd4ef 5201
c19d1205
ZW
5202struct asm_shift_name
5203{
5204 const char *name;
5205 enum shift_kind kind;
5206};
b99bd4ef 5207
c19d1205
ZW
5208/* Third argument to parse_shift. */
5209enum parse_shift_mode
5210{
5211 NO_SHIFT_RESTRICT, /* Any kind of shift is accepted. */
5212 SHIFT_IMMEDIATE, /* Shift operand must be an immediate. */
5213 SHIFT_LSL_OR_ASR_IMMEDIATE, /* Shift must be LSL or ASR immediate. */
5214 SHIFT_ASR_IMMEDIATE, /* Shift must be ASR immediate. */
5215 SHIFT_LSL_IMMEDIATE, /* Shift must be LSL immediate. */
5216};
b99bd4ef 5217
c19d1205
ZW
5218/* Parse a <shift> specifier on an ARM data processing instruction.
5219 This has three forms:
b99bd4ef 5220
c19d1205
ZW
5221 (LSL|LSR|ASL|ASR|ROR) Rs
5222 (LSL|LSR|ASL|ASR|ROR) #imm
5223 RRX
b99bd4ef 5224
c19d1205
ZW
5225 Note that ASL is assimilated to LSL in the instruction encoding, and
5226 RRX to ROR #0 (which cannot be written as such). */
b99bd4ef 5227
c19d1205
ZW
5228static int
5229parse_shift (char **str, int i, enum parse_shift_mode mode)
b99bd4ef 5230{
c19d1205
ZW
5231 const struct asm_shift_name *shift_name;
5232 enum shift_kind shift;
5233 char *s = *str;
5234 char *p = s;
5235 int reg;
b99bd4ef 5236
c19d1205
ZW
5237 for (p = *str; ISALPHA (*p); p++)
5238 ;
b99bd4ef 5239
c19d1205 5240 if (p == *str)
b99bd4ef 5241 {
c19d1205
ZW
5242 inst.error = _("shift expression expected");
5243 return FAIL;
b99bd4ef
NC
5244 }
5245
21d799b5 5246 shift_name = (const struct asm_shift_name *) hash_find_n (arm_shift_hsh, *str,
477330fc 5247 p - *str);
c19d1205
ZW
5248
5249 if (shift_name == NULL)
b99bd4ef 5250 {
c19d1205
ZW
5251 inst.error = _("shift expression expected");
5252 return FAIL;
b99bd4ef
NC
5253 }
5254
c19d1205 5255 shift = shift_name->kind;
b99bd4ef 5256
c19d1205
ZW
5257 switch (mode)
5258 {
5259 case NO_SHIFT_RESTRICT:
5260 case SHIFT_IMMEDIATE: break;
b99bd4ef 5261
c19d1205
ZW
5262 case SHIFT_LSL_OR_ASR_IMMEDIATE:
5263 if (shift != SHIFT_LSL && shift != SHIFT_ASR)
5264 {
5265 inst.error = _("'LSL' or 'ASR' required");
5266 return FAIL;
5267 }
5268 break;
b99bd4ef 5269
c19d1205
ZW
5270 case SHIFT_LSL_IMMEDIATE:
5271 if (shift != SHIFT_LSL)
5272 {
5273 inst.error = _("'LSL' required");
5274 return FAIL;
5275 }
5276 break;
b99bd4ef 5277
c19d1205
ZW
5278 case SHIFT_ASR_IMMEDIATE:
5279 if (shift != SHIFT_ASR)
5280 {
5281 inst.error = _("'ASR' required");
5282 return FAIL;
5283 }
5284 break;
b99bd4ef 5285
c19d1205
ZW
5286 default: abort ();
5287 }
b99bd4ef 5288
c19d1205
ZW
5289 if (shift != SHIFT_RRX)
5290 {
5291 /* Whitespace can appear here if the next thing is a bare digit. */
5292 skip_whitespace (p);
b99bd4ef 5293
c19d1205 5294 if (mode == NO_SHIFT_RESTRICT
dcbf9037 5295 && (reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
c19d1205
ZW
5296 {
5297 inst.operands[i].imm = reg;
5298 inst.operands[i].immisreg = 1;
5299 }
e2b0ab59 5300 else if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
c19d1205
ZW
5301 return FAIL;
5302 }
5303 inst.operands[i].shift_kind = shift;
5304 inst.operands[i].shifted = 1;
5305 *str = p;
5306 return SUCCESS;
b99bd4ef
NC
5307}
5308
c19d1205 5309/* Parse a <shifter_operand> for an ARM data processing instruction:
b99bd4ef 5310
c19d1205
ZW
5311 #<immediate>
5312 #<immediate>, <rotate>
5313 <Rm>
5314 <Rm>, <shift>
b99bd4ef 5315
c19d1205
ZW
5316 where <shift> is defined by parse_shift above, and <rotate> is a
5317 multiple of 2 between 0 and 30. Validation of immediate operands
55cf6793 5318 is deferred to md_apply_fix. */
b99bd4ef 5319
c19d1205
ZW
5320static int
5321parse_shifter_operand (char **str, int i)
5322{
5323 int value;
91d6fa6a 5324 expressionS exp;
b99bd4ef 5325
dcbf9037 5326 if ((value = arm_reg_parse (str, REG_TYPE_RN)) != FAIL)
c19d1205
ZW
5327 {
5328 inst.operands[i].reg = value;
5329 inst.operands[i].isreg = 1;
b99bd4ef 5330
c19d1205 5331 /* parse_shift will override this if appropriate */
e2b0ab59
AV
5332 inst.relocs[0].exp.X_op = O_constant;
5333 inst.relocs[0].exp.X_add_number = 0;
b99bd4ef 5334
c19d1205
ZW
5335 if (skip_past_comma (str) == FAIL)
5336 return SUCCESS;
b99bd4ef 5337
c19d1205
ZW
5338 /* Shift operation on register. */
5339 return parse_shift (str, i, NO_SHIFT_RESTRICT);
b99bd4ef
NC
5340 }
5341
e2b0ab59 5342 if (my_get_expression (&inst.relocs[0].exp, str, GE_IMM_PREFIX))
c19d1205 5343 return FAIL;
b99bd4ef 5344
c19d1205 5345 if (skip_past_comma (str) == SUCCESS)
b99bd4ef 5346 {
c19d1205 5347 /* #x, y -- ie explicit rotation by Y. */
91d6fa6a 5348 if (my_get_expression (&exp, str, GE_NO_PREFIX))
c19d1205 5349 return FAIL;
b99bd4ef 5350
e2b0ab59 5351 if (exp.X_op != O_constant || inst.relocs[0].exp.X_op != O_constant)
c19d1205
ZW
5352 {
5353 inst.error = _("constant expression expected");
5354 return FAIL;
5355 }
b99bd4ef 5356
91d6fa6a 5357 value = exp.X_add_number;
c19d1205
ZW
5358 if (value < 0 || value > 30 || value % 2 != 0)
5359 {
5360 inst.error = _("invalid rotation");
5361 return FAIL;
5362 }
e2b0ab59
AV
5363 if (inst.relocs[0].exp.X_add_number < 0
5364 || inst.relocs[0].exp.X_add_number > 255)
c19d1205
ZW
5365 {
5366 inst.error = _("invalid constant");
5367 return FAIL;
5368 }
09d92015 5369
a415b1cd 5370 /* Encode as specified. */
e2b0ab59 5371 inst.operands[i].imm = inst.relocs[0].exp.X_add_number | value << 7;
a415b1cd 5372 return SUCCESS;
09d92015
MM
5373 }
5374
e2b0ab59
AV
5375 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
5376 inst.relocs[0].pc_rel = 0;
c19d1205 5377 return SUCCESS;
09d92015
MM
5378}
5379
4962c51a
MS
5380/* Group relocation information. Each entry in the table contains the
5381 textual name of the relocation as may appear in assembler source
5382 and must end with a colon.
5383 Along with this textual name are the relocation codes to be used if
5384 the corresponding instruction is an ALU instruction (ADD or SUB only),
5385 an LDR, an LDRS, or an LDC. */
5386
5387struct group_reloc_table_entry
5388{
5389 const char *name;
5390 int alu_code;
5391 int ldr_code;
5392 int ldrs_code;
5393 int ldc_code;
5394};
5395
5396typedef enum
5397{
5398 /* Varieties of non-ALU group relocation. */
5399
5400 GROUP_LDR,
5401 GROUP_LDRS,
5402 GROUP_LDC
5403} group_reloc_type;
5404
5405static struct group_reloc_table_entry group_reloc_table[] =
5406 { /* Program counter relative: */
5407 { "pc_g0_nc",
5408 BFD_RELOC_ARM_ALU_PC_G0_NC, /* ALU */
5409 0, /* LDR */
5410 0, /* LDRS */
5411 0 }, /* LDC */
5412 { "pc_g0",
5413 BFD_RELOC_ARM_ALU_PC_G0, /* ALU */
5414 BFD_RELOC_ARM_LDR_PC_G0, /* LDR */
5415 BFD_RELOC_ARM_LDRS_PC_G0, /* LDRS */
5416 BFD_RELOC_ARM_LDC_PC_G0 }, /* LDC */
5417 { "pc_g1_nc",
5418 BFD_RELOC_ARM_ALU_PC_G1_NC, /* ALU */
5419 0, /* LDR */
5420 0, /* LDRS */
5421 0 }, /* LDC */
5422 { "pc_g1",
5423 BFD_RELOC_ARM_ALU_PC_G1, /* ALU */
5424 BFD_RELOC_ARM_LDR_PC_G1, /* LDR */
5425 BFD_RELOC_ARM_LDRS_PC_G1, /* LDRS */
5426 BFD_RELOC_ARM_LDC_PC_G1 }, /* LDC */
5427 { "pc_g2",
5428 BFD_RELOC_ARM_ALU_PC_G2, /* ALU */
5429 BFD_RELOC_ARM_LDR_PC_G2, /* LDR */
5430 BFD_RELOC_ARM_LDRS_PC_G2, /* LDRS */
5431 BFD_RELOC_ARM_LDC_PC_G2 }, /* LDC */
5432 /* Section base relative */
5433 { "sb_g0_nc",
5434 BFD_RELOC_ARM_ALU_SB_G0_NC, /* ALU */
5435 0, /* LDR */
5436 0, /* LDRS */
5437 0 }, /* LDC */
5438 { "sb_g0",
5439 BFD_RELOC_ARM_ALU_SB_G0, /* ALU */
5440 BFD_RELOC_ARM_LDR_SB_G0, /* LDR */
5441 BFD_RELOC_ARM_LDRS_SB_G0, /* LDRS */
5442 BFD_RELOC_ARM_LDC_SB_G0 }, /* LDC */
5443 { "sb_g1_nc",
5444 BFD_RELOC_ARM_ALU_SB_G1_NC, /* ALU */
5445 0, /* LDR */
5446 0, /* LDRS */
5447 0 }, /* LDC */
5448 { "sb_g1",
5449 BFD_RELOC_ARM_ALU_SB_G1, /* ALU */
5450 BFD_RELOC_ARM_LDR_SB_G1, /* LDR */
5451 BFD_RELOC_ARM_LDRS_SB_G1, /* LDRS */
5452 BFD_RELOC_ARM_LDC_SB_G1 }, /* LDC */
5453 { "sb_g2",
5454 BFD_RELOC_ARM_ALU_SB_G2, /* ALU */
5455 BFD_RELOC_ARM_LDR_SB_G2, /* LDR */
5456 BFD_RELOC_ARM_LDRS_SB_G2, /* LDRS */
72d98d16
MG
5457 BFD_RELOC_ARM_LDC_SB_G2 }, /* LDC */
5458 /* Absolute thumb alu relocations. */
5459 { "lower0_7",
5460 BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC,/* ALU. */
5461 0, /* LDR. */
5462 0, /* LDRS. */
5463 0 }, /* LDC. */
5464 { "lower8_15",
5465 BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC,/* ALU. */
5466 0, /* LDR. */
5467 0, /* LDRS. */
5468 0 }, /* LDC. */
5469 { "upper0_7",
5470 BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC,/* ALU. */
5471 0, /* LDR. */
5472 0, /* LDRS. */
5473 0 }, /* LDC. */
5474 { "upper8_15",
5475 BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC,/* ALU. */
5476 0, /* LDR. */
5477 0, /* LDRS. */
5478 0 } }; /* LDC. */
4962c51a
MS
5479
5480/* Given the address of a pointer pointing to the textual name of a group
5481 relocation as may appear in assembler source, attempt to find its details
5482 in group_reloc_table. The pointer will be updated to the character after
5483 the trailing colon. On failure, FAIL will be returned; SUCCESS
5484 otherwise. On success, *entry will be updated to point at the relevant
5485 group_reloc_table entry. */
5486
5487static int
5488find_group_reloc_table_entry (char **str, struct group_reloc_table_entry **out)
5489{
5490 unsigned int i;
5491 for (i = 0; i < ARRAY_SIZE (group_reloc_table); i++)
5492 {
5493 int length = strlen (group_reloc_table[i].name);
5494
5f4273c7
NC
5495 if (strncasecmp (group_reloc_table[i].name, *str, length) == 0
5496 && (*str)[length] == ':')
477330fc
RM
5497 {
5498 *out = &group_reloc_table[i];
5499 *str += (length + 1);
5500 return SUCCESS;
5501 }
4962c51a
MS
5502 }
5503
5504 return FAIL;
5505}
5506
5507/* Parse a <shifter_operand> for an ARM data processing instruction
5508 (as for parse_shifter_operand) where group relocations are allowed:
5509
5510 #<immediate>
5511 #<immediate>, <rotate>
5512 #:<group_reloc>:<expression>
5513 <Rm>
5514 <Rm>, <shift>
5515
5516 where <group_reloc> is one of the strings defined in group_reloc_table.
5517 The hashes are optional.
5518
5519 Everything else is as for parse_shifter_operand. */
5520
5521static parse_operand_result
5522parse_shifter_operand_group_reloc (char **str, int i)
5523{
5524 /* Determine if we have the sequence of characters #: or just :
5525 coming next. If we do, then we check for a group relocation.
5526 If we don't, punt the whole lot to parse_shifter_operand. */
5527
5528 if (((*str)[0] == '#' && (*str)[1] == ':')
5529 || (*str)[0] == ':')
5530 {
5531 struct group_reloc_table_entry *entry;
5532
5533 if ((*str)[0] == '#')
477330fc 5534 (*str) += 2;
4962c51a 5535 else
477330fc 5536 (*str)++;
4962c51a
MS
5537
5538 /* Try to parse a group relocation. Anything else is an error. */
5539 if (find_group_reloc_table_entry (str, &entry) == FAIL)
477330fc
RM
5540 {
5541 inst.error = _("unknown group relocation");
5542 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5543 }
4962c51a
MS
5544
5545 /* We now have the group relocation table entry corresponding to
477330fc 5546 the name in the assembler source. Next, we parse the expression. */
e2b0ab59 5547 if (my_get_expression (&inst.relocs[0].exp, str, GE_NO_PREFIX))
477330fc 5548 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
4962c51a
MS
5549
5550 /* Record the relocation type (always the ALU variant here). */
e2b0ab59
AV
5551 inst.relocs[0].type = (bfd_reloc_code_real_type) entry->alu_code;
5552 gas_assert (inst.relocs[0].type != 0);
4962c51a
MS
5553
5554 return PARSE_OPERAND_SUCCESS;
5555 }
5556 else
5557 return parse_shifter_operand (str, i) == SUCCESS
477330fc 5558 ? PARSE_OPERAND_SUCCESS : PARSE_OPERAND_FAIL;
4962c51a
MS
5559
5560 /* Never reached. */
5561}
5562
8e560766
MGD
5563/* Parse a Neon alignment expression. Information is written to
5564 inst.operands[i]. We assume the initial ':' has been skipped.
fa94de6b 5565
8e560766
MGD
5566 align .imm = align << 8, .immisalign=1, .preind=0 */
5567static parse_operand_result
5568parse_neon_alignment (char **str, int i)
5569{
5570 char *p = *str;
5571 expressionS exp;
5572
5573 my_get_expression (&exp, &p, GE_NO_PREFIX);
5574
5575 if (exp.X_op != O_constant)
5576 {
5577 inst.error = _("alignment must be constant");
5578 return PARSE_OPERAND_FAIL;
5579 }
5580
5581 inst.operands[i].imm = exp.X_add_number << 8;
5582 inst.operands[i].immisalign = 1;
5583 /* Alignments are not pre-indexes. */
5584 inst.operands[i].preind = 0;
5585
5586 *str = p;
5587 return PARSE_OPERAND_SUCCESS;
5588}
5589
c19d1205 5590/* Parse all forms of an ARM address expression. Information is written
e2b0ab59 5591 to inst.operands[i] and/or inst.relocs[0].
09d92015 5592
c19d1205 5593 Preindexed addressing (.preind=1):
09d92015 5594
e2b0ab59 5595 [Rn, #offset] .reg=Rn .relocs[0].exp=offset
c19d1205
ZW
5596 [Rn, +/-Rm] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
5597 [Rn, +/-Rm, shift] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
e2b0ab59 5598 .shift_kind=shift .relocs[0].exp=shift_imm
09d92015 5599
c19d1205 5600 These three may have a trailing ! which causes .writeback to be set also.
09d92015 5601
c19d1205 5602 Postindexed addressing (.postind=1, .writeback=1):
09d92015 5603
e2b0ab59 5604 [Rn], #offset .reg=Rn .relocs[0].exp=offset
c19d1205
ZW
5605 [Rn], +/-Rm .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
5606 [Rn], +/-Rm, shift .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
e2b0ab59 5607 .shift_kind=shift .relocs[0].exp=shift_imm
09d92015 5608
c19d1205 5609 Unindexed addressing (.preind=0, .postind=0):
09d92015 5610
c19d1205 5611 [Rn], {option} .reg=Rn .imm=option .immisreg=0
09d92015 5612
c19d1205 5613 Other:
09d92015 5614
c19d1205 5615 [Rn]{!} shorthand for [Rn,#0]{!}
e2b0ab59
AV
5616 =immediate .isreg=0 .relocs[0].exp=immediate
5617 label .reg=PC .relocs[0].pc_rel=1 .relocs[0].exp=label
09d92015 5618
c19d1205 5619 It is the caller's responsibility to check for addressing modes not
e2b0ab59 5620 supported by the instruction, and to set inst.relocs[0].type. */
c19d1205 5621
4962c51a
MS
5622static parse_operand_result
5623parse_address_main (char **str, int i, int group_relocations,
477330fc 5624 group_reloc_type group_type)
09d92015 5625{
c19d1205
ZW
5626 char *p = *str;
5627 int reg;
09d92015 5628
c19d1205 5629 if (skip_past_char (&p, '[') == FAIL)
09d92015 5630 {
c19d1205
ZW
5631 if (skip_past_char (&p, '=') == FAIL)
5632 {
974da60d 5633 /* Bare address - translate to PC-relative offset. */
e2b0ab59 5634 inst.relocs[0].pc_rel = 1;
c19d1205
ZW
5635 inst.operands[i].reg = REG_PC;
5636 inst.operands[i].isreg = 1;
5637 inst.operands[i].preind = 1;
09d92015 5638
e2b0ab59 5639 if (my_get_expression (&inst.relocs[0].exp, &p, GE_OPT_PREFIX_BIG))
8335d6aa
JW
5640 return PARSE_OPERAND_FAIL;
5641 }
e2b0ab59 5642 else if (parse_big_immediate (&p, i, &inst.relocs[0].exp,
8335d6aa 5643 /*allow_symbol_p=*/TRUE))
4962c51a 5644 return PARSE_OPERAND_FAIL;
09d92015 5645
c19d1205 5646 *str = p;
4962c51a 5647 return PARSE_OPERAND_SUCCESS;
09d92015
MM
5648 }
5649
8ab8155f
NC
5650 /* PR gas/14887: Allow for whitespace after the opening bracket. */
5651 skip_whitespace (p);
5652
dcbf9037 5653 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
09d92015 5654 {
c19d1205 5655 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
4962c51a 5656 return PARSE_OPERAND_FAIL;
09d92015 5657 }
c19d1205
ZW
5658 inst.operands[i].reg = reg;
5659 inst.operands[i].isreg = 1;
09d92015 5660
c19d1205 5661 if (skip_past_comma (&p) == SUCCESS)
09d92015 5662 {
c19d1205 5663 inst.operands[i].preind = 1;
09d92015 5664
c19d1205
ZW
5665 if (*p == '+') p++;
5666 else if (*p == '-') p++, inst.operands[i].negative = 1;
5667
dcbf9037 5668 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
09d92015 5669 {
c19d1205
ZW
5670 inst.operands[i].imm = reg;
5671 inst.operands[i].immisreg = 1;
5672
5673 if (skip_past_comma (&p) == SUCCESS)
5674 if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
4962c51a 5675 return PARSE_OPERAND_FAIL;
c19d1205 5676 }
5287ad62 5677 else if (skip_past_char (&p, ':') == SUCCESS)
8e560766
MGD
5678 {
5679 /* FIXME: '@' should be used here, but it's filtered out by generic
5680 code before we get to see it here. This may be subject to
5681 change. */
5682 parse_operand_result result = parse_neon_alignment (&p, i);
fa94de6b 5683
8e560766
MGD
5684 if (result != PARSE_OPERAND_SUCCESS)
5685 return result;
5686 }
c19d1205
ZW
5687 else
5688 {
5689 if (inst.operands[i].negative)
5690 {
5691 inst.operands[i].negative = 0;
5692 p--;
5693 }
4962c51a 5694
5f4273c7
NC
5695 if (group_relocations
5696 && ((*p == '#' && *(p + 1) == ':') || *p == ':'))
4962c51a
MS
5697 {
5698 struct group_reloc_table_entry *entry;
5699
477330fc
RM
5700 /* Skip over the #: or : sequence. */
5701 if (*p == '#')
5702 p += 2;
5703 else
5704 p++;
4962c51a
MS
5705
5706 /* Try to parse a group relocation. Anything else is an
477330fc 5707 error. */
4962c51a
MS
5708 if (find_group_reloc_table_entry (&p, &entry) == FAIL)
5709 {
5710 inst.error = _("unknown group relocation");
5711 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5712 }
5713
5714 /* We now have the group relocation table entry corresponding to
5715 the name in the assembler source. Next, we parse the
477330fc 5716 expression. */
e2b0ab59 5717 if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
4962c51a
MS
5718 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5719
5720 /* Record the relocation type. */
477330fc
RM
5721 switch (group_type)
5722 {
5723 case GROUP_LDR:
e2b0ab59
AV
5724 inst.relocs[0].type
5725 = (bfd_reloc_code_real_type) entry->ldr_code;
477330fc 5726 break;
4962c51a 5727
477330fc 5728 case GROUP_LDRS:
e2b0ab59
AV
5729 inst.relocs[0].type
5730 = (bfd_reloc_code_real_type) entry->ldrs_code;
477330fc 5731 break;
4962c51a 5732
477330fc 5733 case GROUP_LDC:
e2b0ab59
AV
5734 inst.relocs[0].type
5735 = (bfd_reloc_code_real_type) entry->ldc_code;
477330fc 5736 break;
4962c51a 5737
477330fc
RM
5738 default:
5739 gas_assert (0);
5740 }
4962c51a 5741
e2b0ab59 5742 if (inst.relocs[0].type == 0)
4962c51a
MS
5743 {
5744 inst.error = _("this group relocation is not allowed on this instruction");
5745 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5746 }
477330fc
RM
5747 }
5748 else
26d97720
NS
5749 {
5750 char *q = p;
0198d5e6 5751
e2b0ab59 5752 if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
26d97720
NS
5753 return PARSE_OPERAND_FAIL;
5754 /* If the offset is 0, find out if it's a +0 or -0. */
e2b0ab59
AV
5755 if (inst.relocs[0].exp.X_op == O_constant
5756 && inst.relocs[0].exp.X_add_number == 0)
26d97720
NS
5757 {
5758 skip_whitespace (q);
5759 if (*q == '#')
5760 {
5761 q++;
5762 skip_whitespace (q);
5763 }
5764 if (*q == '-')
5765 inst.operands[i].negative = 1;
5766 }
5767 }
09d92015
MM
5768 }
5769 }
8e560766
MGD
5770 else if (skip_past_char (&p, ':') == SUCCESS)
5771 {
5772 /* FIXME: '@' should be used here, but it's filtered out by generic code
5773 before we get to see it here. This may be subject to change. */
5774 parse_operand_result result = parse_neon_alignment (&p, i);
fa94de6b 5775
8e560766
MGD
5776 if (result != PARSE_OPERAND_SUCCESS)
5777 return result;
5778 }
09d92015 5779
c19d1205 5780 if (skip_past_char (&p, ']') == FAIL)
09d92015 5781 {
c19d1205 5782 inst.error = _("']' expected");
4962c51a 5783 return PARSE_OPERAND_FAIL;
09d92015
MM
5784 }
5785
c19d1205
ZW
5786 if (skip_past_char (&p, '!') == SUCCESS)
5787 inst.operands[i].writeback = 1;
09d92015 5788
c19d1205 5789 else if (skip_past_comma (&p) == SUCCESS)
09d92015 5790 {
c19d1205
ZW
5791 if (skip_past_char (&p, '{') == SUCCESS)
5792 {
5793 /* [Rn], {expr} - unindexed, with option */
5794 if (parse_immediate (&p, &inst.operands[i].imm,
ca3f61f7 5795 0, 255, TRUE) == FAIL)
4962c51a 5796 return PARSE_OPERAND_FAIL;
09d92015 5797
c19d1205
ZW
5798 if (skip_past_char (&p, '}') == FAIL)
5799 {
5800 inst.error = _("'}' expected at end of 'option' field");
4962c51a 5801 return PARSE_OPERAND_FAIL;
c19d1205
ZW
5802 }
5803 if (inst.operands[i].preind)
5804 {
5805 inst.error = _("cannot combine index with option");
4962c51a 5806 return PARSE_OPERAND_FAIL;
c19d1205
ZW
5807 }
5808 *str = p;
4962c51a 5809 return PARSE_OPERAND_SUCCESS;
09d92015 5810 }
c19d1205
ZW
5811 else
5812 {
5813 inst.operands[i].postind = 1;
5814 inst.operands[i].writeback = 1;
09d92015 5815
c19d1205
ZW
5816 if (inst.operands[i].preind)
5817 {
5818 inst.error = _("cannot combine pre- and post-indexing");
4962c51a 5819 return PARSE_OPERAND_FAIL;
c19d1205 5820 }
09d92015 5821
c19d1205
ZW
5822 if (*p == '+') p++;
5823 else if (*p == '-') p++, inst.operands[i].negative = 1;
a737bd4d 5824
dcbf9037 5825 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
c19d1205 5826 {
477330fc
RM
5827 /* We might be using the immediate for alignment already. If we
5828 are, OR the register number into the low-order bits. */
5829 if (inst.operands[i].immisalign)
5830 inst.operands[i].imm |= reg;
5831 else
5832 inst.operands[i].imm = reg;
c19d1205 5833 inst.operands[i].immisreg = 1;
a737bd4d 5834
c19d1205
ZW
5835 if (skip_past_comma (&p) == SUCCESS)
5836 if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
4962c51a 5837 return PARSE_OPERAND_FAIL;
c19d1205
ZW
5838 }
5839 else
5840 {
26d97720 5841 char *q = p;
0198d5e6 5842
c19d1205
ZW
5843 if (inst.operands[i].negative)
5844 {
5845 inst.operands[i].negative = 0;
5846 p--;
5847 }
e2b0ab59 5848 if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
4962c51a 5849 return PARSE_OPERAND_FAIL;
26d97720 5850 /* If the offset is 0, find out if it's a +0 or -0. */
e2b0ab59
AV
5851 if (inst.relocs[0].exp.X_op == O_constant
5852 && inst.relocs[0].exp.X_add_number == 0)
26d97720
NS
5853 {
5854 skip_whitespace (q);
5855 if (*q == '#')
5856 {
5857 q++;
5858 skip_whitespace (q);
5859 }
5860 if (*q == '-')
5861 inst.operands[i].negative = 1;
5862 }
c19d1205
ZW
5863 }
5864 }
a737bd4d
NC
5865 }
5866
c19d1205
ZW
5867 /* If at this point neither .preind nor .postind is set, we have a
5868 bare [Rn]{!}, which is shorthand for [Rn,#0]{!}. */
5869 if (inst.operands[i].preind == 0 && inst.operands[i].postind == 0)
5870 {
5871 inst.operands[i].preind = 1;
e2b0ab59
AV
5872 inst.relocs[0].exp.X_op = O_constant;
5873 inst.relocs[0].exp.X_add_number = 0;
c19d1205
ZW
5874 }
5875 *str = p;
4962c51a
MS
5876 return PARSE_OPERAND_SUCCESS;
5877}
5878
5879static int
5880parse_address (char **str, int i)
5881{
21d799b5 5882 return parse_address_main (str, i, 0, GROUP_LDR) == PARSE_OPERAND_SUCCESS
477330fc 5883 ? SUCCESS : FAIL;
4962c51a
MS
5884}
5885
5886static parse_operand_result
5887parse_address_group_reloc (char **str, int i, group_reloc_type type)
5888{
5889 return parse_address_main (str, i, 1, type);
a737bd4d
NC
5890}
5891
b6895b4f
PB
5892/* Parse an operand for a MOVW or MOVT instruction. */
5893static int
5894parse_half (char **str)
5895{
5896 char * p;
5f4273c7 5897
b6895b4f
PB
5898 p = *str;
5899 skip_past_char (&p, '#');
5f4273c7 5900 if (strncasecmp (p, ":lower16:", 9) == 0)
e2b0ab59 5901 inst.relocs[0].type = BFD_RELOC_ARM_MOVW;
b6895b4f 5902 else if (strncasecmp (p, ":upper16:", 9) == 0)
e2b0ab59 5903 inst.relocs[0].type = BFD_RELOC_ARM_MOVT;
b6895b4f 5904
e2b0ab59 5905 if (inst.relocs[0].type != BFD_RELOC_UNUSED)
b6895b4f
PB
5906 {
5907 p += 9;
5f4273c7 5908 skip_whitespace (p);
b6895b4f
PB
5909 }
5910
e2b0ab59 5911 if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
b6895b4f
PB
5912 return FAIL;
5913
e2b0ab59 5914 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 5915 {
e2b0ab59 5916 if (inst.relocs[0].exp.X_op != O_constant)
b6895b4f
PB
5917 {
5918 inst.error = _("constant expression expected");
5919 return FAIL;
5920 }
e2b0ab59
AV
5921 if (inst.relocs[0].exp.X_add_number < 0
5922 || inst.relocs[0].exp.X_add_number > 0xffff)
b6895b4f
PB
5923 {
5924 inst.error = _("immediate value out of range");
5925 return FAIL;
5926 }
5927 }
5928 *str = p;
5929 return SUCCESS;
5930}
5931
c19d1205 5932/* Miscellaneous. */
a737bd4d 5933
c19d1205
ZW
5934/* Parse a PSR flag operand. The value returned is FAIL on syntax error,
5935 or a bitmask suitable to be or-ed into the ARM msr instruction. */
5936static int
d2cd1205 5937parse_psr (char **str, bfd_boolean lhs)
09d92015 5938{
c19d1205
ZW
5939 char *p;
5940 unsigned long psr_field;
62b3e311
PB
5941 const struct asm_psr *psr;
5942 char *start;
d2cd1205 5943 bfd_boolean is_apsr = FALSE;
ac7f631b 5944 bfd_boolean m_profile = ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m);
09d92015 5945
a4482bb6
NC
5946 /* PR gas/12698: If the user has specified -march=all then m_profile will
5947 be TRUE, but we want to ignore it in this case as we are building for any
5948 CPU type, including non-m variants. */
823d2571 5949 if (ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any))
a4482bb6
NC
5950 m_profile = FALSE;
5951
c19d1205
ZW
5952 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
5953 feature for ease of use and backwards compatibility. */
5954 p = *str;
62b3e311 5955 if (strncasecmp (p, "SPSR", 4) == 0)
d2cd1205
JB
5956 {
5957 if (m_profile)
5958 goto unsupported_psr;
fa94de6b 5959
d2cd1205
JB
5960 psr_field = SPSR_BIT;
5961 }
5962 else if (strncasecmp (p, "CPSR", 4) == 0)
5963 {
5964 if (m_profile)
5965 goto unsupported_psr;
5966
5967 psr_field = 0;
5968 }
5969 else if (strncasecmp (p, "APSR", 4) == 0)
5970 {
5971 /* APSR[_<bits>] can be used as a synonym for CPSR[_<flags>] on ARMv7-A
5972 and ARMv7-R architecture CPUs. */
5973 is_apsr = TRUE;
5974 psr_field = 0;
5975 }
5976 else if (m_profile)
62b3e311
PB
5977 {
5978 start = p;
5979 do
5980 p++;
5981 while (ISALNUM (*p) || *p == '_');
5982
d2cd1205
JB
5983 if (strncasecmp (start, "iapsr", 5) == 0
5984 || strncasecmp (start, "eapsr", 5) == 0
5985 || strncasecmp (start, "xpsr", 4) == 0
5986 || strncasecmp (start, "psr", 3) == 0)
5987 p = start + strcspn (start, "rR") + 1;
5988
21d799b5 5989 psr = (const struct asm_psr *) hash_find_n (arm_v7m_psr_hsh, start,
477330fc 5990 p - start);
d2cd1205 5991
62b3e311
PB
5992 if (!psr)
5993 return FAIL;
09d92015 5994
d2cd1205
JB
5995 /* If APSR is being written, a bitfield may be specified. Note that
5996 APSR itself is handled above. */
5997 if (psr->field <= 3)
5998 {
5999 psr_field = psr->field;
6000 is_apsr = TRUE;
6001 goto check_suffix;
6002 }
6003
62b3e311 6004 *str = p;
d2cd1205
JB
6005 /* M-profile MSR instructions have the mask field set to "10", except
6006 *PSR variants which modify APSR, which may use a different mask (and
6007 have been handled already). Do that by setting the PSR_f field
6008 here. */
6009 return psr->field | (lhs ? PSR_f : 0);
62b3e311 6010 }
d2cd1205
JB
6011 else
6012 goto unsupported_psr;
09d92015 6013
62b3e311 6014 p += 4;
d2cd1205 6015check_suffix:
c19d1205
ZW
6016 if (*p == '_')
6017 {
6018 /* A suffix follows. */
c19d1205
ZW
6019 p++;
6020 start = p;
a737bd4d 6021
c19d1205
ZW
6022 do
6023 p++;
6024 while (ISALNUM (*p) || *p == '_');
a737bd4d 6025
d2cd1205
JB
6026 if (is_apsr)
6027 {
6028 /* APSR uses a notation for bits, rather than fields. */
6029 unsigned int nzcvq_bits = 0;
6030 unsigned int g_bit = 0;
6031 char *bit;
fa94de6b 6032
d2cd1205
JB
6033 for (bit = start; bit != p; bit++)
6034 {
6035 switch (TOLOWER (*bit))
477330fc 6036 {
d2cd1205
JB
6037 case 'n':
6038 nzcvq_bits |= (nzcvq_bits & 0x01) ? 0x20 : 0x01;
6039 break;
6040
6041 case 'z':
6042 nzcvq_bits |= (nzcvq_bits & 0x02) ? 0x20 : 0x02;
6043 break;
6044
6045 case 'c':
6046 nzcvq_bits |= (nzcvq_bits & 0x04) ? 0x20 : 0x04;
6047 break;
6048
6049 case 'v':
6050 nzcvq_bits |= (nzcvq_bits & 0x08) ? 0x20 : 0x08;
6051 break;
fa94de6b 6052
d2cd1205
JB
6053 case 'q':
6054 nzcvq_bits |= (nzcvq_bits & 0x10) ? 0x20 : 0x10;
6055 break;
fa94de6b 6056
d2cd1205
JB
6057 case 'g':
6058 g_bit |= (g_bit & 0x1) ? 0x2 : 0x1;
6059 break;
fa94de6b 6060
d2cd1205
JB
6061 default:
6062 inst.error = _("unexpected bit specified after APSR");
6063 return FAIL;
6064 }
6065 }
fa94de6b 6066
d2cd1205
JB
6067 if (nzcvq_bits == 0x1f)
6068 psr_field |= PSR_f;
fa94de6b 6069
d2cd1205
JB
6070 if (g_bit == 0x1)
6071 {
6072 if (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp))
477330fc 6073 {
d2cd1205
JB
6074 inst.error = _("selected processor does not "
6075 "support DSP extension");
6076 return FAIL;
6077 }
6078
6079 psr_field |= PSR_s;
6080 }
fa94de6b 6081
d2cd1205
JB
6082 if ((nzcvq_bits & 0x20) != 0
6083 || (nzcvq_bits != 0x1f && nzcvq_bits != 0)
6084 || (g_bit & 0x2) != 0)
6085 {
6086 inst.error = _("bad bitmask specified after APSR");
6087 return FAIL;
6088 }
6089 }
6090 else
477330fc 6091 {
d2cd1205 6092 psr = (const struct asm_psr *) hash_find_n (arm_psr_hsh, start,
477330fc 6093 p - start);
d2cd1205 6094 if (!psr)
477330fc 6095 goto error;
a737bd4d 6096
d2cd1205
JB
6097 psr_field |= psr->field;
6098 }
a737bd4d 6099 }
c19d1205 6100 else
a737bd4d 6101 {
c19d1205
ZW
6102 if (ISALNUM (*p))
6103 goto error; /* Garbage after "[CS]PSR". */
6104
d2cd1205 6105 /* Unadorned APSR is equivalent to APSR_nzcvq/CPSR_f (for writes). This
477330fc 6106 is deprecated, but allow it anyway. */
d2cd1205
JB
6107 if (is_apsr && lhs)
6108 {
6109 psr_field |= PSR_f;
6110 as_tsktsk (_("writing to APSR without specifying a bitmask is "
6111 "deprecated"));
6112 }
6113 else if (!m_profile)
6114 /* These bits are never right for M-profile devices: don't set them
6115 (only code paths which read/write APSR reach here). */
6116 psr_field |= (PSR_c | PSR_f);
a737bd4d 6117 }
c19d1205
ZW
6118 *str = p;
6119 return psr_field;
a737bd4d 6120
d2cd1205
JB
6121 unsupported_psr:
6122 inst.error = _("selected processor does not support requested special "
6123 "purpose register");
6124 return FAIL;
6125
c19d1205
ZW
6126 error:
6127 inst.error = _("flag for {c}psr instruction expected");
6128 return FAIL;
a737bd4d
NC
6129}
6130
c19d1205
ZW
6131/* Parse the flags argument to CPSI[ED]. Returns FAIL on error, or a
6132 value suitable for splatting into the AIF field of the instruction. */
a737bd4d 6133
c19d1205
ZW
6134static int
6135parse_cps_flags (char **str)
a737bd4d 6136{
c19d1205
ZW
6137 int val = 0;
6138 int saw_a_flag = 0;
6139 char *s = *str;
a737bd4d 6140
c19d1205
ZW
6141 for (;;)
6142 switch (*s++)
6143 {
6144 case '\0': case ',':
6145 goto done;
a737bd4d 6146
c19d1205
ZW
6147 case 'a': case 'A': saw_a_flag = 1; val |= 0x4; break;
6148 case 'i': case 'I': saw_a_flag = 1; val |= 0x2; break;
6149 case 'f': case 'F': saw_a_flag = 1; val |= 0x1; break;
a737bd4d 6150
c19d1205
ZW
6151 default:
6152 inst.error = _("unrecognized CPS flag");
6153 return FAIL;
6154 }
a737bd4d 6155
c19d1205
ZW
6156 done:
6157 if (saw_a_flag == 0)
a737bd4d 6158 {
c19d1205
ZW
6159 inst.error = _("missing CPS flags");
6160 return FAIL;
a737bd4d 6161 }
a737bd4d 6162
c19d1205
ZW
6163 *str = s - 1;
6164 return val;
a737bd4d
NC
6165}
6166
c19d1205
ZW
6167/* Parse an endian specifier ("BE" or "LE", case insensitive);
6168 returns 0 for big-endian, 1 for little-endian, FAIL for an error. */
a737bd4d
NC
6169
6170static int
c19d1205 6171parse_endian_specifier (char **str)
a737bd4d 6172{
c19d1205
ZW
6173 int little_endian;
6174 char *s = *str;
a737bd4d 6175
c19d1205
ZW
6176 if (strncasecmp (s, "BE", 2))
6177 little_endian = 0;
6178 else if (strncasecmp (s, "LE", 2))
6179 little_endian = 1;
6180 else
a737bd4d 6181 {
c19d1205 6182 inst.error = _("valid endian specifiers are be or le");
a737bd4d
NC
6183 return FAIL;
6184 }
6185
c19d1205 6186 if (ISALNUM (s[2]) || s[2] == '_')
a737bd4d 6187 {
c19d1205 6188 inst.error = _("valid endian specifiers are be or le");
a737bd4d
NC
6189 return FAIL;
6190 }
6191
c19d1205
ZW
6192 *str = s + 2;
6193 return little_endian;
6194}
a737bd4d 6195
c19d1205
ZW
6196/* Parse a rotation specifier: ROR #0, #8, #16, #24. *val receives a
6197 value suitable for poking into the rotate field of an sxt or sxta
6198 instruction, or FAIL on error. */
6199
6200static int
6201parse_ror (char **str)
6202{
6203 int rot;
6204 char *s = *str;
6205
6206 if (strncasecmp (s, "ROR", 3) == 0)
6207 s += 3;
6208 else
a737bd4d 6209 {
c19d1205 6210 inst.error = _("missing rotation field after comma");
a737bd4d
NC
6211 return FAIL;
6212 }
c19d1205
ZW
6213
6214 if (parse_immediate (&s, &rot, 0, 24, FALSE) == FAIL)
6215 return FAIL;
6216
6217 switch (rot)
a737bd4d 6218 {
c19d1205
ZW
6219 case 0: *str = s; return 0x0;
6220 case 8: *str = s; return 0x1;
6221 case 16: *str = s; return 0x2;
6222 case 24: *str = s; return 0x3;
6223
6224 default:
6225 inst.error = _("rotation can only be 0, 8, 16, or 24");
a737bd4d
NC
6226 return FAIL;
6227 }
c19d1205 6228}
a737bd4d 6229
c19d1205
ZW
6230/* Parse a conditional code (from conds[] below). The value returned is in the
6231 range 0 .. 14, or FAIL. */
6232static int
6233parse_cond (char **str)
6234{
c462b453 6235 char *q;
c19d1205 6236 const struct asm_cond *c;
c462b453
PB
6237 int n;
6238 /* Condition codes are always 2 characters, so matching up to
6239 3 characters is sufficient. */
6240 char cond[3];
a737bd4d 6241
c462b453
PB
6242 q = *str;
6243 n = 0;
6244 while (ISALPHA (*q) && n < 3)
6245 {
e07e6e58 6246 cond[n] = TOLOWER (*q);
c462b453
PB
6247 q++;
6248 n++;
6249 }
a737bd4d 6250
21d799b5 6251 c = (const struct asm_cond *) hash_find_n (arm_cond_hsh, cond, n);
c19d1205 6252 if (!c)
a737bd4d 6253 {
c19d1205 6254 inst.error = _("condition required");
a737bd4d
NC
6255 return FAIL;
6256 }
6257
c19d1205
ZW
6258 *str = q;
6259 return c->value;
6260}
6261
643afb90
MW
6262/* Record a use of the given feature. */
6263static void
6264record_feature_use (const arm_feature_set *feature)
6265{
6266 if (thumb_mode)
6267 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used, *feature);
6268 else
6269 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, *feature);
6270}
6271
4d354d8b
TP
6272/* If the given feature is currently allowed, mark it as used and return TRUE.
6273 Return FALSE otherwise. */
e797f7e0
MGD
6274static bfd_boolean
6275mark_feature_used (const arm_feature_set *feature)
6276{
4d354d8b 6277 /* Ensure the option is currently allowed. */
e797f7e0
MGD
6278 if (!ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
6279 return FALSE;
6280
4d354d8b 6281 /* Add the appropriate architecture feature for the barrier option used. */
643afb90 6282 record_feature_use (feature);
e797f7e0
MGD
6283
6284 return TRUE;
6285}
6286
62b3e311
PB
6287/* Parse an option for a barrier instruction. Returns the encoding for the
6288 option, or FAIL. */
6289static int
6290parse_barrier (char **str)
6291{
6292 char *p, *q;
6293 const struct asm_barrier_opt *o;
6294
6295 p = q = *str;
6296 while (ISALPHA (*q))
6297 q++;
6298
21d799b5 6299 o = (const struct asm_barrier_opt *) hash_find_n (arm_barrier_opt_hsh, p,
477330fc 6300 q - p);
62b3e311
PB
6301 if (!o)
6302 return FAIL;
6303
e797f7e0
MGD
6304 if (!mark_feature_used (&o->arch))
6305 return FAIL;
6306
62b3e311
PB
6307 *str = q;
6308 return o->value;
6309}
6310
92e90b6e
PB
6311/* Parse the operands of a table branch instruction. Similar to a memory
6312 operand. */
6313static int
6314parse_tb (char **str)
6315{
6316 char * p = *str;
6317 int reg;
6318
6319 if (skip_past_char (&p, '[') == FAIL)
ab1eb5fe
PB
6320 {
6321 inst.error = _("'[' expected");
6322 return FAIL;
6323 }
92e90b6e 6324
dcbf9037 6325 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
92e90b6e
PB
6326 {
6327 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
6328 return FAIL;
6329 }
6330 inst.operands[0].reg = reg;
6331
6332 if (skip_past_comma (&p) == FAIL)
ab1eb5fe
PB
6333 {
6334 inst.error = _("',' expected");
6335 return FAIL;
6336 }
5f4273c7 6337
dcbf9037 6338 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
92e90b6e
PB
6339 {
6340 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
6341 return FAIL;
6342 }
6343 inst.operands[0].imm = reg;
6344
6345 if (skip_past_comma (&p) == SUCCESS)
6346 {
6347 if (parse_shift (&p, 0, SHIFT_LSL_IMMEDIATE) == FAIL)
6348 return FAIL;
e2b0ab59 6349 if (inst.relocs[0].exp.X_add_number != 1)
92e90b6e
PB
6350 {
6351 inst.error = _("invalid shift");
6352 return FAIL;
6353 }
6354 inst.operands[0].shifted = 1;
6355 }
6356
6357 if (skip_past_char (&p, ']') == FAIL)
6358 {
6359 inst.error = _("']' expected");
6360 return FAIL;
6361 }
6362 *str = p;
6363 return SUCCESS;
6364}
6365
5287ad62
JB
6366/* Parse the operands of a Neon VMOV instruction. See do_neon_mov for more
6367 information on the types the operands can take and how they are encoded.
037e8744
JB
6368 Up to four operands may be read; this function handles setting the
6369 ".present" field for each read operand itself.
5287ad62
JB
6370 Updates STR and WHICH_OPERAND if parsing is successful and returns SUCCESS,
6371 else returns FAIL. */
6372
6373static int
6374parse_neon_mov (char **str, int *which_operand)
6375{
6376 int i = *which_operand, val;
6377 enum arm_reg_type rtype;
6378 char *ptr = *str;
dcbf9037 6379 struct neon_type_el optype;
5f4273c7 6380
dcbf9037 6381 if ((val = parse_scalar (&ptr, 8, &optype)) != FAIL)
5287ad62
JB
6382 {
6383 /* Case 4: VMOV<c><q>.<size> <Dn[x]>, <Rd>. */
6384 inst.operands[i].reg = val;
6385 inst.operands[i].isscalar = 1;
dcbf9037 6386 inst.operands[i].vectype = optype;
5287ad62
JB
6387 inst.operands[i++].present = 1;
6388
6389 if (skip_past_comma (&ptr) == FAIL)
477330fc 6390 goto wanted_comma;
5f4273c7 6391
dcbf9037 6392 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
477330fc 6393 goto wanted_arm;
5f4273c7 6394
5287ad62
JB
6395 inst.operands[i].reg = val;
6396 inst.operands[i].isreg = 1;
6397 inst.operands[i].present = 1;
6398 }
037e8744 6399 else if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_NSDQ, &rtype, &optype))
477330fc 6400 != FAIL)
5287ad62
JB
6401 {
6402 /* Cases 0, 1, 2, 3, 5 (D only). */
6403 if (skip_past_comma (&ptr) == FAIL)
477330fc 6404 goto wanted_comma;
5f4273c7 6405
5287ad62
JB
6406 inst.operands[i].reg = val;
6407 inst.operands[i].isreg = 1;
6408 inst.operands[i].isquad = (rtype == REG_TYPE_NQ);
037e8744
JB
6409 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6410 inst.operands[i].isvec = 1;
dcbf9037 6411 inst.operands[i].vectype = optype;
5287ad62
JB
6412 inst.operands[i++].present = 1;
6413
dcbf9037 6414 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
477330fc
RM
6415 {
6416 /* Case 5: VMOV<c><q> <Dm>, <Rd>, <Rn>.
6417 Case 13: VMOV <Sd>, <Rm> */
6418 inst.operands[i].reg = val;
6419 inst.operands[i].isreg = 1;
6420 inst.operands[i].present = 1;
6421
6422 if (rtype == REG_TYPE_NQ)
6423 {
6424 first_error (_("can't use Neon quad register here"));
6425 return FAIL;
6426 }
6427 else if (rtype != REG_TYPE_VFS)
6428 {
6429 i++;
6430 if (skip_past_comma (&ptr) == FAIL)
6431 goto wanted_comma;
6432 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6433 goto wanted_arm;
6434 inst.operands[i].reg = val;
6435 inst.operands[i].isreg = 1;
6436 inst.operands[i].present = 1;
6437 }
6438 }
037e8744 6439 else if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_NSDQ, &rtype,
477330fc
RM
6440 &optype)) != FAIL)
6441 {
6442 /* Case 0: VMOV<c><q> <Qd>, <Qm>
6443 Case 1: VMOV<c><q> <Dd>, <Dm>
6444 Case 8: VMOV.F32 <Sd>, <Sm>
6445 Case 15: VMOV <Sd>, <Se>, <Rn>, <Rm> */
6446
6447 inst.operands[i].reg = val;
6448 inst.operands[i].isreg = 1;
6449 inst.operands[i].isquad = (rtype == REG_TYPE_NQ);
6450 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6451 inst.operands[i].isvec = 1;
6452 inst.operands[i].vectype = optype;
6453 inst.operands[i].present = 1;
6454
6455 if (skip_past_comma (&ptr) == SUCCESS)
6456 {
6457 /* Case 15. */
6458 i++;
6459
6460 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6461 goto wanted_arm;
6462
6463 inst.operands[i].reg = val;
6464 inst.operands[i].isreg = 1;
6465 inst.operands[i++].present = 1;
6466
6467 if (skip_past_comma (&ptr) == FAIL)
6468 goto wanted_comma;
6469
6470 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6471 goto wanted_arm;
6472
6473 inst.operands[i].reg = val;
6474 inst.operands[i].isreg = 1;
6475 inst.operands[i].present = 1;
6476 }
6477 }
4641781c 6478 else if (parse_qfloat_immediate (&ptr, &inst.operands[i].imm) == SUCCESS)
477330fc
RM
6479 /* Case 2: VMOV<c><q>.<dt> <Qd>, #<float-imm>
6480 Case 3: VMOV<c><q>.<dt> <Dd>, #<float-imm>
6481 Case 10: VMOV.F32 <Sd>, #<imm>
6482 Case 11: VMOV.F64 <Dd>, #<imm> */
6483 inst.operands[i].immisfloat = 1;
8335d6aa
JW
6484 else if (parse_big_immediate (&ptr, i, NULL, /*allow_symbol_p=*/FALSE)
6485 == SUCCESS)
477330fc
RM
6486 /* Case 2: VMOV<c><q>.<dt> <Qd>, #<imm>
6487 Case 3: VMOV<c><q>.<dt> <Dd>, #<imm> */
6488 ;
5287ad62 6489 else
477330fc
RM
6490 {
6491 first_error (_("expected <Rm> or <Dm> or <Qm> operand"));
6492 return FAIL;
6493 }
5287ad62 6494 }
dcbf9037 6495 else if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
5287ad62
JB
6496 {
6497 /* Cases 6, 7. */
6498 inst.operands[i].reg = val;
6499 inst.operands[i].isreg = 1;
6500 inst.operands[i++].present = 1;
5f4273c7 6501
5287ad62 6502 if (skip_past_comma (&ptr) == FAIL)
477330fc 6503 goto wanted_comma;
5f4273c7 6504
dcbf9037 6505 if ((val = parse_scalar (&ptr, 8, &optype)) != FAIL)
477330fc
RM
6506 {
6507 /* Case 6: VMOV<c><q>.<dt> <Rd>, <Dn[x]> */
6508 inst.operands[i].reg = val;
6509 inst.operands[i].isscalar = 1;
6510 inst.operands[i].present = 1;
6511 inst.operands[i].vectype = optype;
6512 }
dcbf9037 6513 else if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
477330fc
RM
6514 {
6515 /* Case 7: VMOV<c><q> <Rd>, <Rn>, <Dm> */
6516 inst.operands[i].reg = val;
6517 inst.operands[i].isreg = 1;
6518 inst.operands[i++].present = 1;
6519
6520 if (skip_past_comma (&ptr) == FAIL)
6521 goto wanted_comma;
6522
6523 if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFSD, &rtype, &optype))
6524 == FAIL)
6525 {
6526 first_error (_(reg_expected_msgs[REG_TYPE_VFSD]));
6527 return FAIL;
6528 }
6529
6530 inst.operands[i].reg = val;
6531 inst.operands[i].isreg = 1;
6532 inst.operands[i].isvec = 1;
6533 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6534 inst.operands[i].vectype = optype;
6535 inst.operands[i].present = 1;
6536
6537 if (rtype == REG_TYPE_VFS)
6538 {
6539 /* Case 14. */
6540 i++;
6541 if (skip_past_comma (&ptr) == FAIL)
6542 goto wanted_comma;
6543 if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL,
6544 &optype)) == FAIL)
6545 {
6546 first_error (_(reg_expected_msgs[REG_TYPE_VFS]));
6547 return FAIL;
6548 }
6549 inst.operands[i].reg = val;
6550 inst.operands[i].isreg = 1;
6551 inst.operands[i].isvec = 1;
6552 inst.operands[i].issingle = 1;
6553 inst.operands[i].vectype = optype;
6554 inst.operands[i].present = 1;
6555 }
6556 }
037e8744 6557 else if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL, &optype))
477330fc
RM
6558 != FAIL)
6559 {
6560 /* Case 13. */
6561 inst.operands[i].reg = val;
6562 inst.operands[i].isreg = 1;
6563 inst.operands[i].isvec = 1;
6564 inst.operands[i].issingle = 1;
6565 inst.operands[i].vectype = optype;
6566 inst.operands[i].present = 1;
6567 }
5287ad62
JB
6568 }
6569 else
6570 {
dcbf9037 6571 first_error (_("parse error"));
5287ad62
JB
6572 return FAIL;
6573 }
6574
6575 /* Successfully parsed the operands. Update args. */
6576 *which_operand = i;
6577 *str = ptr;
6578 return SUCCESS;
6579
5f4273c7 6580 wanted_comma:
dcbf9037 6581 first_error (_("expected comma"));
5287ad62 6582 return FAIL;
5f4273c7
NC
6583
6584 wanted_arm:
dcbf9037 6585 first_error (_(reg_expected_msgs[REG_TYPE_RN]));
5287ad62 6586 return FAIL;
5287ad62
JB
6587}
6588
5be8be5d
DG
6589/* Use this macro when the operand constraints are different
6590 for ARM and THUMB (e.g. ldrd). */
6591#define MIX_ARM_THUMB_OPERANDS(arm_operand, thumb_operand) \
6592 ((arm_operand) | ((thumb_operand) << 16))
6593
c19d1205
ZW
6594/* Matcher codes for parse_operands. */
6595enum operand_parse_code
6596{
6597 OP_stop, /* end of line */
6598
6599 OP_RR, /* ARM register */
6600 OP_RRnpc, /* ARM register, not r15 */
5be8be5d 6601 OP_RRnpcsp, /* ARM register, neither r15 nor r13 (a.k.a. 'BadReg') */
c19d1205 6602 OP_RRnpcb, /* ARM register, not r15, in square brackets */
fa94de6b 6603 OP_RRnpctw, /* ARM register, not r15 in Thumb-state or with writeback,
55881a11 6604 optional trailing ! */
c19d1205
ZW
6605 OP_RRw, /* ARM register, not r15, optional trailing ! */
6606 OP_RCP, /* Coprocessor number */
6607 OP_RCN, /* Coprocessor register */
6608 OP_RF, /* FPA register */
6609 OP_RVS, /* VFP single precision register */
5287ad62
JB
6610 OP_RVD, /* VFP double precision register (0..15) */
6611 OP_RND, /* Neon double precision register (0..31) */
6612 OP_RNQ, /* Neon quad precision register */
037e8744 6613 OP_RVSD, /* VFP single or double precision register */
dec41383 6614 OP_RNSD, /* Neon single or double precision register */
5287ad62 6615 OP_RNDQ, /* Neon double or quad precision register */
037e8744 6616 OP_RNSDQ, /* Neon single, double or quad precision register */
5287ad62 6617 OP_RNSC, /* Neon scalar D[X] */
c19d1205
ZW
6618 OP_RVC, /* VFP control register */
6619 OP_RMF, /* Maverick F register */
6620 OP_RMD, /* Maverick D register */
6621 OP_RMFX, /* Maverick FX register */
6622 OP_RMDX, /* Maverick DX register */
6623 OP_RMAX, /* Maverick AX register */
6624 OP_RMDS, /* Maverick DSPSC register */
6625 OP_RIWR, /* iWMMXt wR register */
6626 OP_RIWC, /* iWMMXt wC register */
6627 OP_RIWG, /* iWMMXt wCG register */
6628 OP_RXA, /* XScale accumulator register */
6629
60f993ce
AV
6630 /* New operands for Armv8.1-M Mainline. */
6631 OP_LR, /* ARM LR register */
6632 OP_RRnpcsp_I32, /* ARM register (no BadReg) or literal 1 .. 32 */
6633
c19d1205 6634 OP_REGLST, /* ARM register list */
4b5a202f 6635 OP_CLRMLST, /* CLRM register list */
c19d1205
ZW
6636 OP_VRSLST, /* VFP single-precision register list */
6637 OP_VRDLST, /* VFP double-precision register list */
037e8744 6638 OP_VRSDLST, /* VFP single or double-precision register list (& quad) */
5287ad62
JB
6639 OP_NRDLST, /* Neon double-precision register list (d0-d31, qN aliases) */
6640 OP_NSTRLST, /* Neon element/structure list */
efd6b359 6641 OP_VRSDVLST, /* VFP single or double-precision register list and VPR */
5287ad62 6642
5287ad62 6643 OP_RNDQ_I0, /* Neon D or Q reg, or immediate zero. */
037e8744 6644 OP_RVSD_I0, /* VFP S or D reg, or immediate zero. */
aacf0b33 6645 OP_RSVD_FI0, /* VFP S or D reg, or floating point immediate zero. */
5287ad62 6646 OP_RR_RNSC, /* ARM reg or Neon scalar. */
dec41383 6647 OP_RNSD_RNSC, /* Neon S or D reg, or Neon scalar. */
037e8744 6648 OP_RNSDQ_RNSC, /* Vector S, D or Q reg, or Neon scalar. */
5287ad62
JB
6649 OP_RNDQ_RNSC, /* Neon D or Q reg, or Neon scalar. */
6650 OP_RND_RNSC, /* Neon D reg, or Neon scalar. */
6651 OP_VMOV, /* Neon VMOV operands. */
4316f0d2 6652 OP_RNDQ_Ibig, /* Neon D or Q reg, or big immediate for logic and VMVN. */
5287ad62 6653 OP_RNDQ_I63b, /* Neon D or Q reg, or immediate for shift. */
2d447fca 6654 OP_RIWR_I32z, /* iWMMXt wR register, or immediate 0 .. 32 for iWMMXt2. */
5287ad62
JB
6655
6656 OP_I0, /* immediate zero */
c19d1205
ZW
6657 OP_I7, /* immediate value 0 .. 7 */
6658 OP_I15, /* 0 .. 15 */
6659 OP_I16, /* 1 .. 16 */
5287ad62 6660 OP_I16z, /* 0 .. 16 */
c19d1205
ZW
6661 OP_I31, /* 0 .. 31 */
6662 OP_I31w, /* 0 .. 31, optional trailing ! */
6663 OP_I32, /* 1 .. 32 */
5287ad62
JB
6664 OP_I32z, /* 0 .. 32 */
6665 OP_I63, /* 0 .. 63 */
c19d1205 6666 OP_I63s, /* -64 .. 63 */
5287ad62
JB
6667 OP_I64, /* 1 .. 64 */
6668 OP_I64z, /* 0 .. 64 */
c19d1205 6669 OP_I255, /* 0 .. 255 */
c19d1205
ZW
6670
6671 OP_I4b, /* immediate, prefix optional, 1 .. 4 */
6672 OP_I7b, /* 0 .. 7 */
6673 OP_I15b, /* 0 .. 15 */
6674 OP_I31b, /* 0 .. 31 */
6675
6676 OP_SH, /* shifter operand */
4962c51a 6677 OP_SHG, /* shifter operand with possible group relocation */
c19d1205 6678 OP_ADDR, /* Memory address expression (any mode) */
4962c51a
MS
6679 OP_ADDRGLDR, /* Mem addr expr (any mode) with possible LDR group reloc */
6680 OP_ADDRGLDRS, /* Mem addr expr (any mode) with possible LDRS group reloc */
6681 OP_ADDRGLDC, /* Mem addr expr (any mode) with possible LDC group reloc */
c19d1205
ZW
6682 OP_EXP, /* arbitrary expression */
6683 OP_EXPi, /* same, with optional immediate prefix */
6684 OP_EXPr, /* same, with optional relocation suffix */
e2b0ab59 6685 OP_EXPs, /* same, with optional non-first operand relocation suffix */
b6895b4f 6686 OP_HALF, /* 0 .. 65535 or low/high reloc. */
c28eeff2
SN
6687 OP_IROT1, /* VCADD rotate immediate: 90, 270. */
6688 OP_IROT2, /* VCMLA rotate immediate: 0, 90, 180, 270. */
c19d1205
ZW
6689
6690 OP_CPSF, /* CPS flags */
6691 OP_ENDI, /* Endianness specifier */
d2cd1205
JB
6692 OP_wPSR, /* CPSR/SPSR/APSR mask for msr (writing). */
6693 OP_rPSR, /* CPSR/SPSR/APSR mask for msr (reading). */
c19d1205 6694 OP_COND, /* conditional code */
92e90b6e 6695 OP_TB, /* Table branch. */
c19d1205 6696
037e8744
JB
6697 OP_APSR_RR, /* ARM register or "APSR_nzcv". */
6698
c19d1205 6699 OP_RRnpc_I0, /* ARM register or literal 0 */
33eaf5de 6700 OP_RR_EXr, /* ARM register or expression with opt. reloc stuff. */
c19d1205
ZW
6701 OP_RR_EXi, /* ARM register or expression with imm prefix */
6702 OP_RF_IF, /* FPA register or immediate */
6703 OP_RIWR_RIWC, /* iWMMXt R or C reg */
41adaa5c 6704 OP_RIWC_RIWG, /* iWMMXt wC or wCG reg */
c19d1205
ZW
6705
6706 /* Optional operands. */
6707 OP_oI7b, /* immediate, prefix optional, 0 .. 7 */
6708 OP_oI31b, /* 0 .. 31 */
5287ad62 6709 OP_oI32b, /* 1 .. 32 */
5f1af56b 6710 OP_oI32z, /* 0 .. 32 */
c19d1205
ZW
6711 OP_oIffffb, /* 0 .. 65535 */
6712 OP_oI255c, /* curly-brace enclosed, 0 .. 255 */
6713
6714 OP_oRR, /* ARM register */
60f993ce 6715 OP_oLR, /* ARM LR register */
c19d1205 6716 OP_oRRnpc, /* ARM register, not the PC */
5be8be5d 6717 OP_oRRnpcsp, /* ARM register, neither the PC nor the SP (a.k.a. BadReg) */
b6702015 6718 OP_oRRw, /* ARM register, not r15, optional trailing ! */
5287ad62
JB
6719 OP_oRND, /* Optional Neon double precision register */
6720 OP_oRNQ, /* Optional Neon quad precision register */
6721 OP_oRNDQ, /* Optional Neon double or quad precision register */
037e8744 6722 OP_oRNSDQ, /* Optional single, double or quad precision vector register */
c19d1205
ZW
6723 OP_oSHll, /* LSL immediate */
6724 OP_oSHar, /* ASR immediate */
6725 OP_oSHllar, /* LSL or ASR immediate */
6726 OP_oROR, /* ROR 0/8/16/24 */
52e7f43d 6727 OP_oBARRIER_I15, /* Option argument for a barrier instruction. */
c19d1205 6728
5be8be5d
DG
6729 /* Some pre-defined mixed (ARM/THUMB) operands. */
6730 OP_RR_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RR, OP_RRnpcsp),
6731 OP_RRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RRnpc, OP_RRnpcsp),
6732 OP_oRRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_oRRnpc, OP_oRRnpcsp),
6733
c19d1205
ZW
6734 OP_FIRST_OPTIONAL = OP_oI7b
6735};
a737bd4d 6736
c19d1205
ZW
6737/* Generic instruction operand parser. This does no encoding and no
6738 semantic validation; it merely squirrels values away in the inst
6739 structure. Returns SUCCESS or FAIL depending on whether the
6740 specified grammar matched. */
6741static int
5be8be5d 6742parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
c19d1205 6743{
5be8be5d 6744 unsigned const int *upat = pattern;
c19d1205
ZW
6745 char *backtrack_pos = 0;
6746 const char *backtrack_error = 0;
99aad254 6747 int i, val = 0, backtrack_index = 0;
5287ad62 6748 enum arm_reg_type rtype;
4962c51a 6749 parse_operand_result result;
5be8be5d 6750 unsigned int op_parse_code;
efd6b359 6751 bfd_boolean partial_match;
c19d1205 6752
e07e6e58
NC
6753#define po_char_or_fail(chr) \
6754 do \
6755 { \
6756 if (skip_past_char (&str, chr) == FAIL) \
477330fc 6757 goto bad_args; \
e07e6e58
NC
6758 } \
6759 while (0)
c19d1205 6760
e07e6e58
NC
6761#define po_reg_or_fail(regtype) \
6762 do \
dcbf9037 6763 { \
e07e6e58 6764 val = arm_typed_reg_parse (& str, regtype, & rtype, \
477330fc 6765 & inst.operands[i].vectype); \
e07e6e58 6766 if (val == FAIL) \
477330fc
RM
6767 { \
6768 first_error (_(reg_expected_msgs[regtype])); \
6769 goto failure; \
6770 } \
e07e6e58
NC
6771 inst.operands[i].reg = val; \
6772 inst.operands[i].isreg = 1; \
6773 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
6774 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
6775 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc
RM
6776 || rtype == REG_TYPE_VFD \
6777 || rtype == REG_TYPE_NQ); \
dcbf9037 6778 } \
e07e6e58
NC
6779 while (0)
6780
6781#define po_reg_or_goto(regtype, label) \
6782 do \
6783 { \
6784 val = arm_typed_reg_parse (& str, regtype, & rtype, \
6785 & inst.operands[i].vectype); \
6786 if (val == FAIL) \
6787 goto label; \
dcbf9037 6788 \
e07e6e58
NC
6789 inst.operands[i].reg = val; \
6790 inst.operands[i].isreg = 1; \
6791 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
6792 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
6793 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc 6794 || rtype == REG_TYPE_VFD \
e07e6e58
NC
6795 || rtype == REG_TYPE_NQ); \
6796 } \
6797 while (0)
6798
6799#define po_imm_or_fail(min, max, popt) \
6800 do \
6801 { \
6802 if (parse_immediate (&str, &val, min, max, popt) == FAIL) \
6803 goto failure; \
6804 inst.operands[i].imm = val; \
6805 } \
6806 while (0)
6807
6808#define po_scalar_or_goto(elsz, label) \
6809 do \
6810 { \
6811 val = parse_scalar (& str, elsz, & inst.operands[i].vectype); \
6812 if (val == FAIL) \
6813 goto label; \
6814 inst.operands[i].reg = val; \
6815 inst.operands[i].isscalar = 1; \
6816 } \
6817 while (0)
6818
6819#define po_misc_or_fail(expr) \
6820 do \
6821 { \
6822 if (expr) \
6823 goto failure; \
6824 } \
6825 while (0)
6826
6827#define po_misc_or_fail_no_backtrack(expr) \
6828 do \
6829 { \
6830 result = expr; \
6831 if (result == PARSE_OPERAND_FAIL_NO_BACKTRACK) \
6832 backtrack_pos = 0; \
6833 if (result != PARSE_OPERAND_SUCCESS) \
6834 goto failure; \
6835 } \
6836 while (0)
4962c51a 6837
52e7f43d
RE
6838#define po_barrier_or_imm(str) \
6839 do \
6840 { \
6841 val = parse_barrier (&str); \
ccb84d65
JB
6842 if (val == FAIL && ! ISALPHA (*str)) \
6843 goto immediate; \
6844 if (val == FAIL \
6845 /* ISB can only take SY as an option. */ \
6846 || ((inst.instruction & 0xf0) == 0x60 \
6847 && val != 0xf)) \
52e7f43d 6848 { \
ccb84d65
JB
6849 inst.error = _("invalid barrier type"); \
6850 backtrack_pos = 0; \
6851 goto failure; \
52e7f43d
RE
6852 } \
6853 } \
6854 while (0)
6855
c19d1205
ZW
6856 skip_whitespace (str);
6857
6858 for (i = 0; upat[i] != OP_stop; i++)
6859 {
5be8be5d
DG
6860 op_parse_code = upat[i];
6861 if (op_parse_code >= 1<<16)
6862 op_parse_code = thumb ? (op_parse_code >> 16)
6863 : (op_parse_code & ((1<<16)-1));
6864
6865 if (op_parse_code >= OP_FIRST_OPTIONAL)
c19d1205
ZW
6866 {
6867 /* Remember where we are in case we need to backtrack. */
9c2799c2 6868 gas_assert (!backtrack_pos);
c19d1205
ZW
6869 backtrack_pos = str;
6870 backtrack_error = inst.error;
6871 backtrack_index = i;
6872 }
6873
b6702015 6874 if (i > 0 && (i > 1 || inst.operands[0].present))
c19d1205
ZW
6875 po_char_or_fail (',');
6876
5be8be5d 6877 switch (op_parse_code)
c19d1205
ZW
6878 {
6879 /* Registers */
6880 case OP_oRRnpc:
5be8be5d 6881 case OP_oRRnpcsp:
c19d1205 6882 case OP_RRnpc:
5be8be5d 6883 case OP_RRnpcsp:
c19d1205 6884 case OP_oRR:
60f993ce
AV
6885 case OP_LR:
6886 case OP_oLR:
c19d1205
ZW
6887 case OP_RR: po_reg_or_fail (REG_TYPE_RN); break;
6888 case OP_RCP: po_reg_or_fail (REG_TYPE_CP); break;
6889 case OP_RCN: po_reg_or_fail (REG_TYPE_CN); break;
6890 case OP_RF: po_reg_or_fail (REG_TYPE_FN); break;
6891 case OP_RVS: po_reg_or_fail (REG_TYPE_VFS); break;
6892 case OP_RVD: po_reg_or_fail (REG_TYPE_VFD); break;
477330fc 6893 case OP_oRND:
5287ad62 6894 case OP_RND: po_reg_or_fail (REG_TYPE_VFD); break;
cd2cf30b
PB
6895 case OP_RVC:
6896 po_reg_or_goto (REG_TYPE_VFC, coproc_reg);
6897 break;
6898 /* Also accept generic coprocessor regs for unknown registers. */
6899 coproc_reg:
6900 po_reg_or_fail (REG_TYPE_CN);
6901 break;
c19d1205
ZW
6902 case OP_RMF: po_reg_or_fail (REG_TYPE_MVF); break;
6903 case OP_RMD: po_reg_or_fail (REG_TYPE_MVD); break;
6904 case OP_RMFX: po_reg_or_fail (REG_TYPE_MVFX); break;
6905 case OP_RMDX: po_reg_or_fail (REG_TYPE_MVDX); break;
6906 case OP_RMAX: po_reg_or_fail (REG_TYPE_MVAX); break;
6907 case OP_RMDS: po_reg_or_fail (REG_TYPE_DSPSC); break;
6908 case OP_RIWR: po_reg_or_fail (REG_TYPE_MMXWR); break;
6909 case OP_RIWC: po_reg_or_fail (REG_TYPE_MMXWC); break;
6910 case OP_RIWG: po_reg_or_fail (REG_TYPE_MMXWCG); break;
6911 case OP_RXA: po_reg_or_fail (REG_TYPE_XSCALE); break;
477330fc 6912 case OP_oRNQ:
5287ad62 6913 case OP_RNQ: po_reg_or_fail (REG_TYPE_NQ); break;
dec41383 6914 case OP_RNSD: po_reg_or_fail (REG_TYPE_NSD); break;
477330fc 6915 case OP_oRNDQ:
5287ad62 6916 case OP_RNDQ: po_reg_or_fail (REG_TYPE_NDQ); break;
477330fc
RM
6917 case OP_RVSD: po_reg_or_fail (REG_TYPE_VFSD); break;
6918 case OP_oRNSDQ:
6919 case OP_RNSDQ: po_reg_or_fail (REG_TYPE_NSDQ); break;
6920
6921 /* Neon scalar. Using an element size of 8 means that some invalid
6922 scalars are accepted here, so deal with those in later code. */
6923 case OP_RNSC: po_scalar_or_goto (8, failure); break;
6924
6925 case OP_RNDQ_I0:
6926 {
6927 po_reg_or_goto (REG_TYPE_NDQ, try_imm0);
6928 break;
6929 try_imm0:
6930 po_imm_or_fail (0, 0, TRUE);
6931 }
6932 break;
6933
6934 case OP_RVSD_I0:
6935 po_reg_or_goto (REG_TYPE_VFSD, try_imm0);
6936 break;
6937
aacf0b33
KT
6938 case OP_RSVD_FI0:
6939 {
6940 po_reg_or_goto (REG_TYPE_VFSD, try_ifimm0);
6941 break;
6942 try_ifimm0:
6943 if (parse_ifimm_zero (&str))
6944 inst.operands[i].imm = 0;
6945 else
6946 {
6947 inst.error
6948 = _("only floating point zero is allowed as immediate value");
6949 goto failure;
6950 }
6951 }
6952 break;
6953
477330fc
RM
6954 case OP_RR_RNSC:
6955 {
6956 po_scalar_or_goto (8, try_rr);
6957 break;
6958 try_rr:
6959 po_reg_or_fail (REG_TYPE_RN);
6960 }
6961 break;
6962
6963 case OP_RNSDQ_RNSC:
6964 {
6965 po_scalar_or_goto (8, try_nsdq);
6966 break;
6967 try_nsdq:
6968 po_reg_or_fail (REG_TYPE_NSDQ);
6969 }
6970 break;
6971
dec41383
JW
6972 case OP_RNSD_RNSC:
6973 {
6974 po_scalar_or_goto (8, try_s_scalar);
6975 break;
6976 try_s_scalar:
6977 po_scalar_or_goto (4, try_nsd);
6978 break;
6979 try_nsd:
6980 po_reg_or_fail (REG_TYPE_NSD);
6981 }
6982 break;
6983
477330fc
RM
6984 case OP_RNDQ_RNSC:
6985 {
6986 po_scalar_or_goto (8, try_ndq);
6987 break;
6988 try_ndq:
6989 po_reg_or_fail (REG_TYPE_NDQ);
6990 }
6991 break;
6992
6993 case OP_RND_RNSC:
6994 {
6995 po_scalar_or_goto (8, try_vfd);
6996 break;
6997 try_vfd:
6998 po_reg_or_fail (REG_TYPE_VFD);
6999 }
7000 break;
7001
7002 case OP_VMOV:
7003 /* WARNING: parse_neon_mov can move the operand counter, i. If we're
7004 not careful then bad things might happen. */
7005 po_misc_or_fail (parse_neon_mov (&str, &i) == FAIL);
7006 break;
7007
7008 case OP_RNDQ_Ibig:
7009 {
7010 po_reg_or_goto (REG_TYPE_NDQ, try_immbig);
7011 break;
7012 try_immbig:
7013 /* There's a possibility of getting a 64-bit immediate here, so
7014 we need special handling. */
8335d6aa
JW
7015 if (parse_big_immediate (&str, i, NULL, /*allow_symbol_p=*/FALSE)
7016 == FAIL)
477330fc
RM
7017 {
7018 inst.error = _("immediate value is out of range");
7019 goto failure;
7020 }
7021 }
7022 break;
7023
7024 case OP_RNDQ_I63b:
7025 {
7026 po_reg_or_goto (REG_TYPE_NDQ, try_shimm);
7027 break;
7028 try_shimm:
7029 po_imm_or_fail (0, 63, TRUE);
7030 }
7031 break;
c19d1205
ZW
7032
7033 case OP_RRnpcb:
7034 po_char_or_fail ('[');
7035 po_reg_or_fail (REG_TYPE_RN);
7036 po_char_or_fail (']');
7037 break;
a737bd4d 7038
55881a11 7039 case OP_RRnpctw:
c19d1205 7040 case OP_RRw:
b6702015 7041 case OP_oRRw:
c19d1205
ZW
7042 po_reg_or_fail (REG_TYPE_RN);
7043 if (skip_past_char (&str, '!') == SUCCESS)
7044 inst.operands[i].writeback = 1;
7045 break;
7046
7047 /* Immediates */
7048 case OP_I7: po_imm_or_fail ( 0, 7, FALSE); break;
7049 case OP_I15: po_imm_or_fail ( 0, 15, FALSE); break;
7050 case OP_I16: po_imm_or_fail ( 1, 16, FALSE); break;
477330fc 7051 case OP_I16z: po_imm_or_fail ( 0, 16, FALSE); break;
c19d1205
ZW
7052 case OP_I31: po_imm_or_fail ( 0, 31, FALSE); break;
7053 case OP_I32: po_imm_or_fail ( 1, 32, FALSE); break;
477330fc 7054 case OP_I32z: po_imm_or_fail ( 0, 32, FALSE); break;
c19d1205 7055 case OP_I63s: po_imm_or_fail (-64, 63, FALSE); break;
477330fc
RM
7056 case OP_I63: po_imm_or_fail ( 0, 63, FALSE); break;
7057 case OP_I64: po_imm_or_fail ( 1, 64, FALSE); break;
7058 case OP_I64z: po_imm_or_fail ( 0, 64, FALSE); break;
c19d1205 7059 case OP_I255: po_imm_or_fail ( 0, 255, FALSE); break;
c19d1205
ZW
7060
7061 case OP_I4b: po_imm_or_fail ( 1, 4, TRUE); break;
7062 case OP_oI7b:
7063 case OP_I7b: po_imm_or_fail ( 0, 7, TRUE); break;
7064 case OP_I15b: po_imm_or_fail ( 0, 15, TRUE); break;
7065 case OP_oI31b:
7066 case OP_I31b: po_imm_or_fail ( 0, 31, TRUE); break;
477330fc
RM
7067 case OP_oI32b: po_imm_or_fail ( 1, 32, TRUE); break;
7068 case OP_oI32z: po_imm_or_fail ( 0, 32, TRUE); break;
c19d1205
ZW
7069 case OP_oIffffb: po_imm_or_fail ( 0, 0xffff, TRUE); break;
7070
7071 /* Immediate variants */
7072 case OP_oI255c:
7073 po_char_or_fail ('{');
7074 po_imm_or_fail (0, 255, TRUE);
7075 po_char_or_fail ('}');
7076 break;
7077
7078 case OP_I31w:
7079 /* The expression parser chokes on a trailing !, so we have
7080 to find it first and zap it. */
7081 {
7082 char *s = str;
7083 while (*s && *s != ',')
7084 s++;
7085 if (s[-1] == '!')
7086 {
7087 s[-1] = '\0';
7088 inst.operands[i].writeback = 1;
7089 }
7090 po_imm_or_fail (0, 31, TRUE);
7091 if (str == s - 1)
7092 str = s;
7093 }
7094 break;
7095
7096 /* Expressions */
7097 case OP_EXPi: EXPi:
e2b0ab59 7098 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7099 GE_OPT_PREFIX));
7100 break;
7101
7102 case OP_EXP:
e2b0ab59 7103 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7104 GE_NO_PREFIX));
7105 break;
7106
7107 case OP_EXPr: EXPr:
e2b0ab59 7108 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205 7109 GE_NO_PREFIX));
e2b0ab59 7110 if (inst.relocs[0].exp.X_op == O_symbol)
a737bd4d 7111 {
c19d1205
ZW
7112 val = parse_reloc (&str);
7113 if (val == -1)
7114 {
7115 inst.error = _("unrecognized relocation suffix");
7116 goto failure;
7117 }
7118 else if (val != BFD_RELOC_UNUSED)
7119 {
7120 inst.operands[i].imm = val;
7121 inst.operands[i].hasreloc = 1;
7122 }
a737bd4d 7123 }
c19d1205 7124 break;
a737bd4d 7125
e2b0ab59
AV
7126 case OP_EXPs:
7127 po_misc_or_fail (my_get_expression (&inst.relocs[i].exp, &str,
7128 GE_NO_PREFIX));
7129 if (inst.relocs[i].exp.X_op == O_symbol)
7130 {
7131 inst.operands[i].hasreloc = 1;
7132 }
7133 else if (inst.relocs[i].exp.X_op == O_constant)
7134 {
7135 inst.operands[i].imm = inst.relocs[i].exp.X_add_number;
7136 inst.operands[i].hasreloc = 0;
7137 }
7138 break;
7139
b6895b4f
PB
7140 /* Operand for MOVW or MOVT. */
7141 case OP_HALF:
7142 po_misc_or_fail (parse_half (&str));
7143 break;
7144
e07e6e58 7145 /* Register or expression. */
c19d1205
ZW
7146 case OP_RR_EXr: po_reg_or_goto (REG_TYPE_RN, EXPr); break;
7147 case OP_RR_EXi: po_reg_or_goto (REG_TYPE_RN, EXPi); break;
a737bd4d 7148
e07e6e58 7149 /* Register or immediate. */
c19d1205
ZW
7150 case OP_RRnpc_I0: po_reg_or_goto (REG_TYPE_RN, I0); break;
7151 I0: po_imm_or_fail (0, 0, FALSE); break;
a737bd4d 7152
c19d1205
ZW
7153 case OP_RF_IF: po_reg_or_goto (REG_TYPE_FN, IF); break;
7154 IF:
7155 if (!is_immediate_prefix (*str))
7156 goto bad_args;
7157 str++;
7158 val = parse_fpa_immediate (&str);
7159 if (val == FAIL)
7160 goto failure;
7161 /* FPA immediates are encoded as registers 8-15.
7162 parse_fpa_immediate has already applied the offset. */
7163 inst.operands[i].reg = val;
7164 inst.operands[i].isreg = 1;
7165 break;
09d92015 7166
2d447fca
JM
7167 case OP_RIWR_I32z: po_reg_or_goto (REG_TYPE_MMXWR, I32z); break;
7168 I32z: po_imm_or_fail (0, 32, FALSE); break;
7169
e07e6e58 7170 /* Two kinds of register. */
c19d1205
ZW
7171 case OP_RIWR_RIWC:
7172 {
7173 struct reg_entry *rege = arm_reg_parse_multi (&str);
97f87066
JM
7174 if (!rege
7175 || (rege->type != REG_TYPE_MMXWR
7176 && rege->type != REG_TYPE_MMXWC
7177 && rege->type != REG_TYPE_MMXWCG))
c19d1205
ZW
7178 {
7179 inst.error = _("iWMMXt data or control register expected");
7180 goto failure;
7181 }
7182 inst.operands[i].reg = rege->number;
7183 inst.operands[i].isreg = (rege->type == REG_TYPE_MMXWR);
7184 }
7185 break;
09d92015 7186
41adaa5c
JM
7187 case OP_RIWC_RIWG:
7188 {
7189 struct reg_entry *rege = arm_reg_parse_multi (&str);
7190 if (!rege
7191 || (rege->type != REG_TYPE_MMXWC
7192 && rege->type != REG_TYPE_MMXWCG))
7193 {
7194 inst.error = _("iWMMXt control register expected");
7195 goto failure;
7196 }
7197 inst.operands[i].reg = rege->number;
7198 inst.operands[i].isreg = 1;
7199 }
7200 break;
7201
c19d1205
ZW
7202 /* Misc */
7203 case OP_CPSF: val = parse_cps_flags (&str); break;
7204 case OP_ENDI: val = parse_endian_specifier (&str); break;
7205 case OP_oROR: val = parse_ror (&str); break;
c19d1205 7206 case OP_COND: val = parse_cond (&str); break;
52e7f43d
RE
7207 case OP_oBARRIER_I15:
7208 po_barrier_or_imm (str); break;
7209 immediate:
7210 if (parse_immediate (&str, &val, 0, 15, TRUE) == FAIL)
477330fc 7211 goto failure;
52e7f43d 7212 break;
c19d1205 7213
fa94de6b 7214 case OP_wPSR:
d2cd1205 7215 case OP_rPSR:
90ec0d68
MGD
7216 po_reg_or_goto (REG_TYPE_RNB, try_psr);
7217 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_virt))
7218 {
7219 inst.error = _("Banked registers are not available with this "
7220 "architecture.");
7221 goto failure;
7222 }
7223 break;
d2cd1205
JB
7224 try_psr:
7225 val = parse_psr (&str, op_parse_code == OP_wPSR);
7226 break;
037e8744 7227
477330fc
RM
7228 case OP_APSR_RR:
7229 po_reg_or_goto (REG_TYPE_RN, try_apsr);
7230 break;
7231 try_apsr:
7232 /* Parse "APSR_nvzc" operand (for FMSTAT-equivalent MRS
7233 instruction). */
7234 if (strncasecmp (str, "APSR_", 5) == 0)
7235 {
7236 unsigned found = 0;
7237 str += 5;
7238 while (found < 15)
7239 switch (*str++)
7240 {
7241 case 'c': found = (found & 1) ? 16 : found | 1; break;
7242 case 'n': found = (found & 2) ? 16 : found | 2; break;
7243 case 'z': found = (found & 4) ? 16 : found | 4; break;
7244 case 'v': found = (found & 8) ? 16 : found | 8; break;
7245 default: found = 16;
7246 }
7247 if (found != 15)
7248 goto failure;
7249 inst.operands[i].isvec = 1;
f7c21dc7
NC
7250 /* APSR_nzcv is encoded in instructions as if it were the REG_PC. */
7251 inst.operands[i].reg = REG_PC;
477330fc
RM
7252 }
7253 else
7254 goto failure;
7255 break;
037e8744 7256
92e90b6e
PB
7257 case OP_TB:
7258 po_misc_or_fail (parse_tb (&str));
7259 break;
7260
e07e6e58 7261 /* Register lists. */
c19d1205 7262 case OP_REGLST:
4b5a202f 7263 val = parse_reg_list (&str, REGLIST_RN);
c19d1205
ZW
7264 if (*str == '^')
7265 {
5e0d7f77 7266 inst.operands[i].writeback = 1;
c19d1205
ZW
7267 str++;
7268 }
7269 break;
09d92015 7270
4b5a202f
AV
7271 case OP_CLRMLST:
7272 val = parse_reg_list (&str, REGLIST_CLRM);
7273 break;
7274
c19d1205 7275 case OP_VRSLST:
efd6b359
AV
7276 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_S,
7277 &partial_match);
c19d1205 7278 break;
09d92015 7279
c19d1205 7280 case OP_VRDLST:
efd6b359
AV
7281 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_D,
7282 &partial_match);
c19d1205 7283 break;
a737bd4d 7284
477330fc
RM
7285 case OP_VRSDLST:
7286 /* Allow Q registers too. */
7287 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359 7288 REGLIST_NEON_D, &partial_match);
477330fc
RM
7289 if (val == FAIL)
7290 {
7291 inst.error = NULL;
7292 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359
AV
7293 REGLIST_VFP_S, &partial_match);
7294 inst.operands[i].issingle = 1;
7295 }
7296 break;
7297
7298 case OP_VRSDVLST:
7299 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
7300 REGLIST_VFP_D_VPR, &partial_match);
7301 if (val == FAIL && !partial_match)
7302 {
7303 inst.error = NULL;
7304 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
7305 REGLIST_VFP_S_VPR, &partial_match);
477330fc
RM
7306 inst.operands[i].issingle = 1;
7307 }
7308 break;
7309
7310 case OP_NRDLST:
7311 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359 7312 REGLIST_NEON_D, &partial_match);
477330fc 7313 break;
5287ad62
JB
7314
7315 case OP_NSTRLST:
477330fc
RM
7316 val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
7317 &inst.operands[i].vectype);
7318 break;
5287ad62 7319
c19d1205
ZW
7320 /* Addressing modes */
7321 case OP_ADDR:
7322 po_misc_or_fail (parse_address (&str, i));
7323 break;
09d92015 7324
4962c51a
MS
7325 case OP_ADDRGLDR:
7326 po_misc_or_fail_no_backtrack (
477330fc 7327 parse_address_group_reloc (&str, i, GROUP_LDR));
4962c51a
MS
7328 break;
7329
7330 case OP_ADDRGLDRS:
7331 po_misc_or_fail_no_backtrack (
477330fc 7332 parse_address_group_reloc (&str, i, GROUP_LDRS));
4962c51a
MS
7333 break;
7334
7335 case OP_ADDRGLDC:
7336 po_misc_or_fail_no_backtrack (
477330fc 7337 parse_address_group_reloc (&str, i, GROUP_LDC));
4962c51a
MS
7338 break;
7339
c19d1205
ZW
7340 case OP_SH:
7341 po_misc_or_fail (parse_shifter_operand (&str, i));
7342 break;
09d92015 7343
4962c51a
MS
7344 case OP_SHG:
7345 po_misc_or_fail_no_backtrack (
477330fc 7346 parse_shifter_operand_group_reloc (&str, i));
4962c51a
MS
7347 break;
7348
c19d1205
ZW
7349 case OP_oSHll:
7350 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_IMMEDIATE));
7351 break;
09d92015 7352
c19d1205
ZW
7353 case OP_oSHar:
7354 po_misc_or_fail (parse_shift (&str, i, SHIFT_ASR_IMMEDIATE));
7355 break;
09d92015 7356
c19d1205
ZW
7357 case OP_oSHllar:
7358 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_OR_ASR_IMMEDIATE));
7359 break;
09d92015 7360
c19d1205 7361 default:
5be8be5d 7362 as_fatal (_("unhandled operand code %d"), op_parse_code);
c19d1205 7363 }
09d92015 7364
c19d1205
ZW
7365 /* Various value-based sanity checks and shared operations. We
7366 do not signal immediate failures for the register constraints;
7367 this allows a syntax error to take precedence. */
5be8be5d 7368 switch (op_parse_code)
c19d1205
ZW
7369 {
7370 case OP_oRRnpc:
7371 case OP_RRnpc:
7372 case OP_RRnpcb:
7373 case OP_RRw:
b6702015 7374 case OP_oRRw:
c19d1205
ZW
7375 case OP_RRnpc_I0:
7376 if (inst.operands[i].isreg && inst.operands[i].reg == REG_PC)
7377 inst.error = BAD_PC;
7378 break;
09d92015 7379
5be8be5d
DG
7380 case OP_oRRnpcsp:
7381 case OP_RRnpcsp:
7382 if (inst.operands[i].isreg)
7383 {
7384 if (inst.operands[i].reg == REG_PC)
7385 inst.error = BAD_PC;
5c8ed6a4
JW
7386 else if (inst.operands[i].reg == REG_SP
7387 /* The restriction on Rd/Rt/Rt2 on Thumb mode has been
7388 relaxed since ARMv8-A. */
7389 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
7390 {
7391 gas_assert (thumb);
7392 inst.error = BAD_SP;
7393 }
5be8be5d
DG
7394 }
7395 break;
7396
55881a11 7397 case OP_RRnpctw:
fa94de6b
RM
7398 if (inst.operands[i].isreg
7399 && inst.operands[i].reg == REG_PC
55881a11
MGD
7400 && (inst.operands[i].writeback || thumb))
7401 inst.error = BAD_PC;
7402 break;
7403
c19d1205
ZW
7404 case OP_CPSF:
7405 case OP_ENDI:
7406 case OP_oROR:
d2cd1205
JB
7407 case OP_wPSR:
7408 case OP_rPSR:
c19d1205 7409 case OP_COND:
52e7f43d 7410 case OP_oBARRIER_I15:
c19d1205 7411 case OP_REGLST:
4b5a202f 7412 case OP_CLRMLST:
c19d1205
ZW
7413 case OP_VRSLST:
7414 case OP_VRDLST:
477330fc 7415 case OP_VRSDLST:
efd6b359 7416 case OP_VRSDVLST:
477330fc
RM
7417 case OP_NRDLST:
7418 case OP_NSTRLST:
c19d1205
ZW
7419 if (val == FAIL)
7420 goto failure;
7421 inst.operands[i].imm = val;
7422 break;
a737bd4d 7423
60f993ce
AV
7424 case OP_LR:
7425 case OP_oLR:
7426 if (inst.operands[i].reg != REG_LR)
7427 inst.error = _("operand must be LR register");
7428 break;
7429
c19d1205
ZW
7430 default:
7431 break;
7432 }
09d92015 7433
c19d1205
ZW
7434 /* If we get here, this operand was successfully parsed. */
7435 inst.operands[i].present = 1;
7436 continue;
09d92015 7437
c19d1205 7438 bad_args:
09d92015 7439 inst.error = BAD_ARGS;
c19d1205
ZW
7440
7441 failure:
7442 if (!backtrack_pos)
d252fdde
PB
7443 {
7444 /* The parse routine should already have set inst.error, but set a
5f4273c7 7445 default here just in case. */
d252fdde
PB
7446 if (!inst.error)
7447 inst.error = _("syntax error");
7448 return FAIL;
7449 }
c19d1205
ZW
7450
7451 /* Do not backtrack over a trailing optional argument that
7452 absorbed some text. We will only fail again, with the
7453 'garbage following instruction' error message, which is
7454 probably less helpful than the current one. */
7455 if (backtrack_index == i && backtrack_pos != str
7456 && upat[i+1] == OP_stop)
d252fdde
PB
7457 {
7458 if (!inst.error)
7459 inst.error = _("syntax error");
7460 return FAIL;
7461 }
c19d1205
ZW
7462
7463 /* Try again, skipping the optional argument at backtrack_pos. */
7464 str = backtrack_pos;
7465 inst.error = backtrack_error;
7466 inst.operands[backtrack_index].present = 0;
7467 i = backtrack_index;
7468 backtrack_pos = 0;
09d92015 7469 }
09d92015 7470
c19d1205
ZW
7471 /* Check that we have parsed all the arguments. */
7472 if (*str != '\0' && !inst.error)
7473 inst.error = _("garbage following instruction");
09d92015 7474
c19d1205 7475 return inst.error ? FAIL : SUCCESS;
09d92015
MM
7476}
7477
c19d1205
ZW
7478#undef po_char_or_fail
7479#undef po_reg_or_fail
7480#undef po_reg_or_goto
7481#undef po_imm_or_fail
5287ad62 7482#undef po_scalar_or_fail
52e7f43d 7483#undef po_barrier_or_imm
e07e6e58 7484
c19d1205 7485/* Shorthand macro for instruction encoding functions issuing errors. */
e07e6e58
NC
7486#define constraint(expr, err) \
7487 do \
c19d1205 7488 { \
e07e6e58
NC
7489 if (expr) \
7490 { \
7491 inst.error = err; \
7492 return; \
7493 } \
c19d1205 7494 } \
e07e6e58 7495 while (0)
c19d1205 7496
fdfde340
JM
7497/* Reject "bad registers" for Thumb-2 instructions. Many Thumb-2
7498 instructions are unpredictable if these registers are used. This
5c8ed6a4
JW
7499 is the BadReg predicate in ARM's Thumb-2 documentation.
7500
7501 Before ARMv8-A, REG_PC and REG_SP were not allowed in quite a few
7502 places, while the restriction on REG_SP was relaxed since ARMv8-A. */
7503#define reject_bad_reg(reg) \
7504 do \
7505 if (reg == REG_PC) \
7506 { \
7507 inst.error = BAD_PC; \
7508 return; \
7509 } \
7510 else if (reg == REG_SP \
7511 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)) \
7512 { \
7513 inst.error = BAD_SP; \
7514 return; \
7515 } \
fdfde340
JM
7516 while (0)
7517
94206790
MM
7518/* If REG is R13 (the stack pointer), warn that its use is
7519 deprecated. */
7520#define warn_deprecated_sp(reg) \
7521 do \
7522 if (warn_on_deprecated && reg == REG_SP) \
5c3696f8 7523 as_tsktsk (_("use of r13 is deprecated")); \
94206790
MM
7524 while (0)
7525
c19d1205
ZW
7526/* Functions for operand encoding. ARM, then Thumb. */
7527
d840c081 7528#define rotate_left(v, n) (v << (n & 31) | v >> ((32 - n) & 31))
c19d1205 7529
9db2f6b4
RL
7530/* If the current inst is scalar ARMv8.2 fp16 instruction, do special encoding.
7531
7532 The only binary encoding difference is the Coprocessor number. Coprocessor
7533 9 is used for half-precision calculations or conversions. The format of the
2b0f3761 7534 instruction is the same as the equivalent Coprocessor 10 instruction that
9db2f6b4
RL
7535 exists for Single-Precision operation. */
7536
7537static void
7538do_scalar_fp16_v82_encode (void)
7539{
7540 if (inst.cond != COND_ALWAYS)
7541 as_warn (_("ARMv8.2 scalar fp16 instruction cannot be conditional,"
7542 " the behaviour is UNPREDICTABLE"));
7543 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
7544 _(BAD_FP16));
7545
7546 inst.instruction = (inst.instruction & 0xfffff0ff) | 0x900;
7547 mark_feature_used (&arm_ext_fp16);
7548}
7549
c19d1205
ZW
7550/* If VAL can be encoded in the immediate field of an ARM instruction,
7551 return the encoded form. Otherwise, return FAIL. */
7552
7553static unsigned int
7554encode_arm_immediate (unsigned int val)
09d92015 7555{
c19d1205
ZW
7556 unsigned int a, i;
7557
4f1d6205
L
7558 if (val <= 0xff)
7559 return val;
7560
7561 for (i = 2; i < 32; i += 2)
c19d1205
ZW
7562 if ((a = rotate_left (val, i)) <= 0xff)
7563 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
7564
7565 return FAIL;
09d92015
MM
7566}
7567
c19d1205
ZW
7568/* If VAL can be encoded in the immediate field of a Thumb32 instruction,
7569 return the encoded form. Otherwise, return FAIL. */
7570static unsigned int
7571encode_thumb32_immediate (unsigned int val)
09d92015 7572{
c19d1205 7573 unsigned int a, i;
09d92015 7574
9c3c69f2 7575 if (val <= 0xff)
c19d1205 7576 return val;
a737bd4d 7577
9c3c69f2 7578 for (i = 1; i <= 24; i++)
09d92015 7579 {
9c3c69f2
PB
7580 a = val >> i;
7581 if ((val & ~(0xff << i)) == 0)
7582 return ((val >> i) & 0x7f) | ((32 - i) << 7);
09d92015 7583 }
a737bd4d 7584
c19d1205
ZW
7585 a = val & 0xff;
7586 if (val == ((a << 16) | a))
7587 return 0x100 | a;
7588 if (val == ((a << 24) | (a << 16) | (a << 8) | a))
7589 return 0x300 | a;
09d92015 7590
c19d1205
ZW
7591 a = val & 0xff00;
7592 if (val == ((a << 16) | a))
7593 return 0x200 | (a >> 8);
a737bd4d 7594
c19d1205 7595 return FAIL;
09d92015 7596}
5287ad62 7597/* Encode a VFP SP or DP register number into inst.instruction. */
09d92015
MM
7598
7599static void
5287ad62
JB
7600encode_arm_vfp_reg (int reg, enum vfp_reg_pos pos)
7601{
7602 if ((pos == VFP_REG_Dd || pos == VFP_REG_Dn || pos == VFP_REG_Dm)
7603 && reg > 15)
7604 {
b1cc4aeb 7605 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
477330fc
RM
7606 {
7607 if (thumb_mode)
7608 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
7609 fpu_vfp_ext_d32);
7610 else
7611 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
7612 fpu_vfp_ext_d32);
7613 }
5287ad62 7614 else
477330fc
RM
7615 {
7616 first_error (_("D register out of range for selected VFP version"));
7617 return;
7618 }
5287ad62
JB
7619 }
7620
c19d1205 7621 switch (pos)
09d92015 7622 {
c19d1205
ZW
7623 case VFP_REG_Sd:
7624 inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
7625 break;
7626
7627 case VFP_REG_Sn:
7628 inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
7629 break;
7630
7631 case VFP_REG_Sm:
7632 inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
7633 break;
7634
5287ad62
JB
7635 case VFP_REG_Dd:
7636 inst.instruction |= ((reg & 15) << 12) | ((reg >> 4) << 22);
7637 break;
5f4273c7 7638
5287ad62
JB
7639 case VFP_REG_Dn:
7640 inst.instruction |= ((reg & 15) << 16) | ((reg >> 4) << 7);
7641 break;
5f4273c7 7642
5287ad62
JB
7643 case VFP_REG_Dm:
7644 inst.instruction |= (reg & 15) | ((reg >> 4) << 5);
7645 break;
7646
c19d1205
ZW
7647 default:
7648 abort ();
09d92015 7649 }
09d92015
MM
7650}
7651
c19d1205 7652/* Encode a <shift> in an ARM-format instruction. The immediate,
55cf6793 7653 if any, is handled by md_apply_fix. */
09d92015 7654static void
c19d1205 7655encode_arm_shift (int i)
09d92015 7656{
008a97ef
RL
7657 /* register-shifted register. */
7658 if (inst.operands[i].immisreg)
7659 {
bf355b69
MR
7660 int op_index;
7661 for (op_index = 0; op_index <= i; ++op_index)
008a97ef 7662 {
5689c942
RL
7663 /* Check the operand only when it's presented. In pre-UAL syntax,
7664 if the destination register is the same as the first operand, two
7665 register form of the instruction can be used. */
bf355b69
MR
7666 if (inst.operands[op_index].present && inst.operands[op_index].isreg
7667 && inst.operands[op_index].reg == REG_PC)
008a97ef
RL
7668 as_warn (UNPRED_REG ("r15"));
7669 }
7670
7671 if (inst.operands[i].imm == REG_PC)
7672 as_warn (UNPRED_REG ("r15"));
7673 }
7674
c19d1205
ZW
7675 if (inst.operands[i].shift_kind == SHIFT_RRX)
7676 inst.instruction |= SHIFT_ROR << 5;
7677 else
09d92015 7678 {
c19d1205
ZW
7679 inst.instruction |= inst.operands[i].shift_kind << 5;
7680 if (inst.operands[i].immisreg)
7681 {
7682 inst.instruction |= SHIFT_BY_REG;
7683 inst.instruction |= inst.operands[i].imm << 8;
7684 }
7685 else
e2b0ab59 7686 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
09d92015 7687 }
c19d1205 7688}
09d92015 7689
c19d1205
ZW
7690static void
7691encode_arm_shifter_operand (int i)
7692{
7693 if (inst.operands[i].isreg)
09d92015 7694 {
c19d1205
ZW
7695 inst.instruction |= inst.operands[i].reg;
7696 encode_arm_shift (i);
09d92015 7697 }
c19d1205 7698 else
a415b1cd
JB
7699 {
7700 inst.instruction |= INST_IMMEDIATE;
e2b0ab59 7701 if (inst.relocs[0].type != BFD_RELOC_ARM_IMMEDIATE)
a415b1cd
JB
7702 inst.instruction |= inst.operands[i].imm;
7703 }
09d92015
MM
7704}
7705
c19d1205 7706/* Subroutine of encode_arm_addr_mode_2 and encode_arm_addr_mode_3. */
09d92015 7707static void
c19d1205 7708encode_arm_addr_mode_common (int i, bfd_boolean is_t)
09d92015 7709{
2b2f5df9
NC
7710 /* PR 14260:
7711 Generate an error if the operand is not a register. */
7712 constraint (!inst.operands[i].isreg,
7713 _("Instruction does not support =N addresses"));
7714
c19d1205 7715 inst.instruction |= inst.operands[i].reg << 16;
a737bd4d 7716
c19d1205 7717 if (inst.operands[i].preind)
09d92015 7718 {
c19d1205
ZW
7719 if (is_t)
7720 {
7721 inst.error = _("instruction does not accept preindexed addressing");
7722 return;
7723 }
7724 inst.instruction |= PRE_INDEX;
7725 if (inst.operands[i].writeback)
7726 inst.instruction |= WRITE_BACK;
09d92015 7727
c19d1205
ZW
7728 }
7729 else if (inst.operands[i].postind)
7730 {
9c2799c2 7731 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
7732 if (is_t)
7733 inst.instruction |= WRITE_BACK;
7734 }
7735 else /* unindexed - only for coprocessor */
09d92015 7736 {
c19d1205 7737 inst.error = _("instruction does not accept unindexed addressing");
09d92015
MM
7738 return;
7739 }
7740
c19d1205
ZW
7741 if (((inst.instruction & WRITE_BACK) || !(inst.instruction & PRE_INDEX))
7742 && (((inst.instruction & 0x000f0000) >> 16)
7743 == ((inst.instruction & 0x0000f000) >> 12)))
7744 as_warn ((inst.instruction & LOAD_BIT)
7745 ? _("destination register same as write-back base")
7746 : _("source register same as write-back base"));
09d92015
MM
7747}
7748
c19d1205
ZW
7749/* inst.operands[i] was set up by parse_address. Encode it into an
7750 ARM-format mode 2 load or store instruction. If is_t is true,
7751 reject forms that cannot be used with a T instruction (i.e. not
7752 post-indexed). */
a737bd4d 7753static void
c19d1205 7754encode_arm_addr_mode_2 (int i, bfd_boolean is_t)
09d92015 7755{
5be8be5d
DG
7756 const bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
7757
c19d1205 7758 encode_arm_addr_mode_common (i, is_t);
a737bd4d 7759
c19d1205 7760 if (inst.operands[i].immisreg)
09d92015 7761 {
5be8be5d
DG
7762 constraint ((inst.operands[i].imm == REG_PC
7763 || (is_pc && inst.operands[i].writeback)),
7764 BAD_PC_ADDRESSING);
c19d1205
ZW
7765 inst.instruction |= INST_IMMEDIATE; /* yes, this is backwards */
7766 inst.instruction |= inst.operands[i].imm;
7767 if (!inst.operands[i].negative)
7768 inst.instruction |= INDEX_UP;
7769 if (inst.operands[i].shifted)
7770 {
7771 if (inst.operands[i].shift_kind == SHIFT_RRX)
7772 inst.instruction |= SHIFT_ROR << 5;
7773 else
7774 {
7775 inst.instruction |= inst.operands[i].shift_kind << 5;
e2b0ab59 7776 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
c19d1205
ZW
7777 }
7778 }
09d92015 7779 }
e2b0ab59 7780 else /* immediate offset in inst.relocs[0] */
09d92015 7781 {
e2b0ab59 7782 if (is_pc && !inst.relocs[0].pc_rel)
5be8be5d
DG
7783 {
7784 const bfd_boolean is_load = ((inst.instruction & LOAD_BIT) != 0);
23a10334
JZ
7785
7786 /* If is_t is TRUE, it's called from do_ldstt. ldrt/strt
7787 cannot use PC in addressing.
7788 PC cannot be used in writeback addressing, either. */
7789 constraint ((is_t || inst.operands[i].writeback),
5be8be5d 7790 BAD_PC_ADDRESSING);
23a10334 7791
dc5ec521 7792 /* Use of PC in str is deprecated for ARMv7. */
23a10334
JZ
7793 if (warn_on_deprecated
7794 && !is_load
7795 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7))
5c3696f8 7796 as_tsktsk (_("use of PC in this instruction is deprecated"));
5be8be5d
DG
7797 }
7798
e2b0ab59 7799 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
7800 {
7801 /* Prefer + for zero encoded value. */
7802 if (!inst.operands[i].negative)
7803 inst.instruction |= INDEX_UP;
e2b0ab59 7804 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM;
26d97720 7805 }
09d92015 7806 }
09d92015
MM
7807}
7808
c19d1205
ZW
7809/* inst.operands[i] was set up by parse_address. Encode it into an
7810 ARM-format mode 3 load or store instruction. Reject forms that
7811 cannot be used with such instructions. If is_t is true, reject
7812 forms that cannot be used with a T instruction (i.e. not
7813 post-indexed). */
7814static void
7815encode_arm_addr_mode_3 (int i, bfd_boolean is_t)
09d92015 7816{
c19d1205 7817 if (inst.operands[i].immisreg && inst.operands[i].shifted)
09d92015 7818 {
c19d1205
ZW
7819 inst.error = _("instruction does not accept scaled register index");
7820 return;
09d92015 7821 }
a737bd4d 7822
c19d1205 7823 encode_arm_addr_mode_common (i, is_t);
a737bd4d 7824
c19d1205
ZW
7825 if (inst.operands[i].immisreg)
7826 {
5be8be5d 7827 constraint ((inst.operands[i].imm == REG_PC
eb9f3f00 7828 || (is_t && inst.operands[i].reg == REG_PC)),
5be8be5d 7829 BAD_PC_ADDRESSING);
eb9f3f00
JB
7830 constraint (inst.operands[i].reg == REG_PC && inst.operands[i].writeback,
7831 BAD_PC_WRITEBACK);
c19d1205
ZW
7832 inst.instruction |= inst.operands[i].imm;
7833 if (!inst.operands[i].negative)
7834 inst.instruction |= INDEX_UP;
7835 }
e2b0ab59 7836 else /* immediate offset in inst.relocs[0] */
c19d1205 7837 {
e2b0ab59 7838 constraint ((inst.operands[i].reg == REG_PC && !inst.relocs[0].pc_rel
5be8be5d
DG
7839 && inst.operands[i].writeback),
7840 BAD_PC_WRITEBACK);
c19d1205 7841 inst.instruction |= HWOFFSET_IMM;
e2b0ab59 7842 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
7843 {
7844 /* Prefer + for zero encoded value. */
7845 if (!inst.operands[i].negative)
7846 inst.instruction |= INDEX_UP;
7847
e2b0ab59 7848 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM8;
26d97720 7849 }
c19d1205 7850 }
a737bd4d
NC
7851}
7852
8335d6aa
JW
7853/* Write immediate bits [7:0] to the following locations:
7854
7855 |28/24|23 19|18 16|15 4|3 0|
7856 | 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|
7857
7858 This function is used by VMOV/VMVN/VORR/VBIC. */
7859
7860static void
7861neon_write_immbits (unsigned immbits)
7862{
7863 inst.instruction |= immbits & 0xf;
7864 inst.instruction |= ((immbits >> 4) & 0x7) << 16;
7865 inst.instruction |= ((immbits >> 7) & 0x1) << (thumb_mode ? 28 : 24);
7866}
7867
7868/* Invert low-order SIZE bits of XHI:XLO. */
7869
7870static void
7871neon_invert_size (unsigned *xlo, unsigned *xhi, int size)
7872{
7873 unsigned immlo = xlo ? *xlo : 0;
7874 unsigned immhi = xhi ? *xhi : 0;
7875
7876 switch (size)
7877 {
7878 case 8:
7879 immlo = (~immlo) & 0xff;
7880 break;
7881
7882 case 16:
7883 immlo = (~immlo) & 0xffff;
7884 break;
7885
7886 case 64:
7887 immhi = (~immhi) & 0xffffffff;
7888 /* fall through. */
7889
7890 case 32:
7891 immlo = (~immlo) & 0xffffffff;
7892 break;
7893
7894 default:
7895 abort ();
7896 }
7897
7898 if (xlo)
7899 *xlo = immlo;
7900
7901 if (xhi)
7902 *xhi = immhi;
7903}
7904
7905/* True if IMM has form 0bAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD for bits
7906 A, B, C, D. */
09d92015 7907
c19d1205 7908static int
8335d6aa 7909neon_bits_same_in_bytes (unsigned imm)
09d92015 7910{
8335d6aa
JW
7911 return ((imm & 0x000000ff) == 0 || (imm & 0x000000ff) == 0x000000ff)
7912 && ((imm & 0x0000ff00) == 0 || (imm & 0x0000ff00) == 0x0000ff00)
7913 && ((imm & 0x00ff0000) == 0 || (imm & 0x00ff0000) == 0x00ff0000)
7914 && ((imm & 0xff000000) == 0 || (imm & 0xff000000) == 0xff000000);
7915}
a737bd4d 7916
8335d6aa 7917/* For immediate of above form, return 0bABCD. */
09d92015 7918
8335d6aa
JW
7919static unsigned
7920neon_squash_bits (unsigned imm)
7921{
7922 return (imm & 0x01) | ((imm & 0x0100) >> 7) | ((imm & 0x010000) >> 14)
7923 | ((imm & 0x01000000) >> 21);
7924}
7925
7926/* Compress quarter-float representation to 0b...000 abcdefgh. */
7927
7928static unsigned
7929neon_qfloat_bits (unsigned imm)
7930{
7931 return ((imm >> 19) & 0x7f) | ((imm >> 24) & 0x80);
7932}
7933
7934/* Returns CMODE. IMMBITS [7:0] is set to bits suitable for inserting into
7935 the instruction. *OP is passed as the initial value of the op field, and
7936 may be set to a different value depending on the constant (i.e.
7937 "MOV I64, 0bAAAAAAAABBBB..." which uses OP = 1 despite being MOV not
7938 MVN). If the immediate looks like a repeated pattern then also
7939 try smaller element sizes. */
7940
7941static int
7942neon_cmode_for_move_imm (unsigned immlo, unsigned immhi, int float_p,
7943 unsigned *immbits, int *op, int size,
7944 enum neon_el_type type)
7945{
7946 /* Only permit float immediates (including 0.0/-0.0) if the operand type is
7947 float. */
7948 if (type == NT_float && !float_p)
7949 return FAIL;
7950
7951 if (type == NT_float && is_quarter_float (immlo) && immhi == 0)
09d92015 7952 {
8335d6aa
JW
7953 if (size != 32 || *op == 1)
7954 return FAIL;
7955 *immbits = neon_qfloat_bits (immlo);
7956 return 0xf;
7957 }
7958
7959 if (size == 64)
7960 {
7961 if (neon_bits_same_in_bytes (immhi)
7962 && neon_bits_same_in_bytes (immlo))
c19d1205 7963 {
8335d6aa
JW
7964 if (*op == 1)
7965 return FAIL;
7966 *immbits = (neon_squash_bits (immhi) << 4)
7967 | neon_squash_bits (immlo);
7968 *op = 1;
7969 return 0xe;
c19d1205 7970 }
a737bd4d 7971
8335d6aa
JW
7972 if (immhi != immlo)
7973 return FAIL;
7974 }
a737bd4d 7975
8335d6aa 7976 if (size >= 32)
09d92015 7977 {
8335d6aa 7978 if (immlo == (immlo & 0x000000ff))
c19d1205 7979 {
8335d6aa
JW
7980 *immbits = immlo;
7981 return 0x0;
c19d1205 7982 }
8335d6aa 7983 else if (immlo == (immlo & 0x0000ff00))
c19d1205 7984 {
8335d6aa
JW
7985 *immbits = immlo >> 8;
7986 return 0x2;
c19d1205 7987 }
8335d6aa
JW
7988 else if (immlo == (immlo & 0x00ff0000))
7989 {
7990 *immbits = immlo >> 16;
7991 return 0x4;
7992 }
7993 else if (immlo == (immlo & 0xff000000))
7994 {
7995 *immbits = immlo >> 24;
7996 return 0x6;
7997 }
7998 else if (immlo == ((immlo & 0x0000ff00) | 0x000000ff))
7999 {
8000 *immbits = (immlo >> 8) & 0xff;
8001 return 0xc;
8002 }
8003 else if (immlo == ((immlo & 0x00ff0000) | 0x0000ffff))
8004 {
8005 *immbits = (immlo >> 16) & 0xff;
8006 return 0xd;
8007 }
8008
8009 if ((immlo & 0xffff) != (immlo >> 16))
8010 return FAIL;
8011 immlo &= 0xffff;
09d92015 8012 }
a737bd4d 8013
8335d6aa 8014 if (size >= 16)
4962c51a 8015 {
8335d6aa
JW
8016 if (immlo == (immlo & 0x000000ff))
8017 {
8018 *immbits = immlo;
8019 return 0x8;
8020 }
8021 else if (immlo == (immlo & 0x0000ff00))
8022 {
8023 *immbits = immlo >> 8;
8024 return 0xa;
8025 }
8026
8027 if ((immlo & 0xff) != (immlo >> 8))
8028 return FAIL;
8029 immlo &= 0xff;
4962c51a
MS
8030 }
8031
8335d6aa
JW
8032 if (immlo == (immlo & 0x000000ff))
8033 {
8034 /* Don't allow MVN with 8-bit immediate. */
8035 if (*op == 1)
8036 return FAIL;
8037 *immbits = immlo;
8038 return 0xe;
8039 }
26d97720 8040
8335d6aa 8041 return FAIL;
c19d1205 8042}
a737bd4d 8043
5fc177c8 8044#if defined BFD_HOST_64_BIT
ba592044
AM
8045/* Returns TRUE if double precision value V may be cast
8046 to single precision without loss of accuracy. */
8047
8048static bfd_boolean
5fc177c8 8049is_double_a_single (bfd_int64_t v)
ba592044 8050{
5fc177c8 8051 int exp = (int)((v >> 52) & 0x7FF);
8fe3f3d6 8052 bfd_int64_t mantissa = (v & (bfd_int64_t)0xFFFFFFFFFFFFFULL);
ba592044
AM
8053
8054 return (exp == 0 || exp == 0x7FF
8055 || (exp >= 1023 - 126 && exp <= 1023 + 127))
8056 && (mantissa & 0x1FFFFFFFl) == 0;
8057}
8058
3739860c 8059/* Returns a double precision value casted to single precision
ba592044
AM
8060 (ignoring the least significant bits in exponent and mantissa). */
8061
8062static int
5fc177c8 8063double_to_single (bfd_int64_t v)
ba592044
AM
8064{
8065 int sign = (int) ((v >> 63) & 1l);
5fc177c8 8066 int exp = (int) ((v >> 52) & 0x7FF);
8fe3f3d6 8067 bfd_int64_t mantissa = (v & (bfd_int64_t)0xFFFFFFFFFFFFFULL);
ba592044
AM
8068
8069 if (exp == 0x7FF)
8070 exp = 0xFF;
8071 else
8072 {
8073 exp = exp - 1023 + 127;
8074 if (exp >= 0xFF)
8075 {
8076 /* Infinity. */
8077 exp = 0x7F;
8078 mantissa = 0;
8079 }
8080 else if (exp < 0)
8081 {
8082 /* No denormalized numbers. */
8083 exp = 0;
8084 mantissa = 0;
8085 }
8086 }
8087 mantissa >>= 29;
8088 return (sign << 31) | (exp << 23) | mantissa;
8089}
5fc177c8 8090#endif /* BFD_HOST_64_BIT */
ba592044 8091
8335d6aa
JW
8092enum lit_type
8093{
8094 CONST_THUMB,
8095 CONST_ARM,
8096 CONST_VEC
8097};
8098
ba592044
AM
8099static void do_vfp_nsyn_opcode (const char *);
8100
e2b0ab59 8101/* inst.relocs[0].exp describes an "=expr" load pseudo-operation.
c19d1205
ZW
8102 Determine whether it can be performed with a move instruction; if
8103 it can, convert inst.instruction to that move instruction and
c921be7d
NC
8104 return TRUE; if it can't, convert inst.instruction to a literal-pool
8105 load and return FALSE. If this is not a valid thing to do in the
8106 current context, set inst.error and return TRUE.
a737bd4d 8107
c19d1205
ZW
8108 inst.operands[i] describes the destination register. */
8109
c921be7d 8110static bfd_boolean
8335d6aa 8111move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
c19d1205 8112{
53365c0d 8113 unsigned long tbit;
8335d6aa
JW
8114 bfd_boolean thumb_p = (t == CONST_THUMB);
8115 bfd_boolean arm_p = (t == CONST_ARM);
53365c0d
PB
8116
8117 if (thumb_p)
8118 tbit = (inst.instruction > 0xffff) ? THUMB2_LOAD_BIT : THUMB_LOAD_BIT;
8119 else
8120 tbit = LOAD_BIT;
8121
8122 if ((inst.instruction & tbit) == 0)
09d92015 8123 {
c19d1205 8124 inst.error = _("invalid pseudo operation");
c921be7d 8125 return TRUE;
09d92015 8126 }
ba592044 8127
e2b0ab59
AV
8128 if (inst.relocs[0].exp.X_op != O_constant
8129 && inst.relocs[0].exp.X_op != O_symbol
8130 && inst.relocs[0].exp.X_op != O_big)
09d92015
MM
8131 {
8132 inst.error = _("constant expression expected");
c921be7d 8133 return TRUE;
09d92015 8134 }
ba592044 8135
e2b0ab59
AV
8136 if (inst.relocs[0].exp.X_op == O_constant
8137 || inst.relocs[0].exp.X_op == O_big)
8335d6aa 8138 {
5fc177c8
NC
8139#if defined BFD_HOST_64_BIT
8140 bfd_int64_t v;
8141#else
ba592044 8142 offsetT v;
5fc177c8 8143#endif
e2b0ab59 8144 if (inst.relocs[0].exp.X_op == O_big)
8335d6aa 8145 {
ba592044
AM
8146 LITTLENUM_TYPE w[X_PRECISION];
8147 LITTLENUM_TYPE * l;
8148
e2b0ab59 8149 if (inst.relocs[0].exp.X_add_number == -1)
8335d6aa 8150 {
ba592044
AM
8151 gen_to_words (w, X_PRECISION, E_PRECISION);
8152 l = w;
8153 /* FIXME: Should we check words w[2..5] ? */
8335d6aa 8154 }
ba592044
AM
8155 else
8156 l = generic_bignum;
3739860c 8157
5fc177c8
NC
8158#if defined BFD_HOST_64_BIT
8159 v =
8160 ((((((((bfd_int64_t) l[3] & LITTLENUM_MASK)
8161 << LITTLENUM_NUMBER_OF_BITS)
8162 | ((bfd_int64_t) l[2] & LITTLENUM_MASK))
8163 << LITTLENUM_NUMBER_OF_BITS)
8164 | ((bfd_int64_t) l[1] & LITTLENUM_MASK))
8165 << LITTLENUM_NUMBER_OF_BITS)
8166 | ((bfd_int64_t) l[0] & LITTLENUM_MASK));
8167#else
ba592044
AM
8168 v = ((l[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
8169 | (l[0] & LITTLENUM_MASK);
5fc177c8 8170#endif
8335d6aa 8171 }
ba592044 8172 else
e2b0ab59 8173 v = inst.relocs[0].exp.X_add_number;
ba592044
AM
8174
8175 if (!inst.operands[i].issingle)
8335d6aa 8176 {
12569877 8177 if (thumb_p)
8335d6aa 8178 {
53445554
TP
8179 /* LDR should not use lead in a flag-setting instruction being
8180 chosen so we do not check whether movs can be used. */
12569877 8181
53445554 8182 if ((ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
ff8646ee 8183 || ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
53445554
TP
8184 && inst.operands[i].reg != 13
8185 && inst.operands[i].reg != 15)
12569877 8186 {
fc289b0a
TP
8187 /* Check if on thumb2 it can be done with a mov.w, mvn or
8188 movw instruction. */
12569877
AM
8189 unsigned int newimm;
8190 bfd_boolean isNegated;
8191
8192 newimm = encode_thumb32_immediate (v);
8193 if (newimm != (unsigned int) FAIL)
8194 isNegated = FALSE;
8195 else
8196 {
582cfe03 8197 newimm = encode_thumb32_immediate (~v);
12569877
AM
8198 if (newimm != (unsigned int) FAIL)
8199 isNegated = TRUE;
8200 }
8201
fc289b0a
TP
8202 /* The number can be loaded with a mov.w or mvn
8203 instruction. */
ff8646ee
TP
8204 if (newimm != (unsigned int) FAIL
8205 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
12569877 8206 {
fc289b0a 8207 inst.instruction = (0xf04f0000 /* MOV.W. */
582cfe03 8208 | (inst.operands[i].reg << 8));
fc289b0a 8209 /* Change to MOVN. */
582cfe03 8210 inst.instruction |= (isNegated ? 0x200000 : 0);
12569877
AM
8211 inst.instruction |= (newimm & 0x800) << 15;
8212 inst.instruction |= (newimm & 0x700) << 4;
8213 inst.instruction |= (newimm & 0x0ff);
8214 return TRUE;
8215 }
fc289b0a 8216 /* The number can be loaded with a movw instruction. */
ff8646ee
TP
8217 else if ((v & ~0xFFFF) == 0
8218 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
3739860c 8219 {
582cfe03 8220 int imm = v & 0xFFFF;
12569877 8221
582cfe03 8222 inst.instruction = 0xf2400000; /* MOVW. */
12569877
AM
8223 inst.instruction |= (inst.operands[i].reg << 8);
8224 inst.instruction |= (imm & 0xf000) << 4;
8225 inst.instruction |= (imm & 0x0800) << 15;
8226 inst.instruction |= (imm & 0x0700) << 4;
8227 inst.instruction |= (imm & 0x00ff);
8228 return TRUE;
8229 }
8230 }
8335d6aa 8231 }
12569877 8232 else if (arm_p)
ba592044
AM
8233 {
8234 int value = encode_arm_immediate (v);
12569877 8235
ba592044
AM
8236 if (value != FAIL)
8237 {
8238 /* This can be done with a mov instruction. */
8239 inst.instruction &= LITERAL_MASK;
8240 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
8241 inst.instruction |= value & 0xfff;
8242 return TRUE;
8243 }
8335d6aa 8244
ba592044
AM
8245 value = encode_arm_immediate (~ v);
8246 if (value != FAIL)
8247 {
8248 /* This can be done with a mvn instruction. */
8249 inst.instruction &= LITERAL_MASK;
8250 inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
8251 inst.instruction |= value & 0xfff;
8252 return TRUE;
8253 }
8254 }
934c2632 8255 else if (t == CONST_VEC && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
8335d6aa 8256 {
ba592044
AM
8257 int op = 0;
8258 unsigned immbits = 0;
8259 unsigned immlo = inst.operands[1].imm;
8260 unsigned immhi = inst.operands[1].regisimm
8261 ? inst.operands[1].reg
e2b0ab59 8262 : inst.relocs[0].exp.X_unsigned
ba592044
AM
8263 ? 0
8264 : ((bfd_int64_t)((int) immlo)) >> 32;
8265 int cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
8266 &op, 64, NT_invtype);
8267
8268 if (cmode == FAIL)
8269 {
8270 neon_invert_size (&immlo, &immhi, 64);
8271 op = !op;
8272 cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
8273 &op, 64, NT_invtype);
8274 }
8275
8276 if (cmode != FAIL)
8277 {
8278 inst.instruction = (inst.instruction & VLDR_VMOV_SAME)
8279 | (1 << 23)
8280 | (cmode << 8)
8281 | (op << 5)
8282 | (1 << 4);
8283
8284 /* Fill other bits in vmov encoding for both thumb and arm. */
8285 if (thumb_mode)
eff0bc54 8286 inst.instruction |= (0x7U << 29) | (0xF << 24);
ba592044 8287 else
eff0bc54 8288 inst.instruction |= (0xFU << 28) | (0x1 << 25);
ba592044
AM
8289 neon_write_immbits (immbits);
8290 return TRUE;
8291 }
8335d6aa
JW
8292 }
8293 }
8335d6aa 8294
ba592044
AM
8295 if (t == CONST_VEC)
8296 {
8297 /* Check if vldr Rx, =constant could be optimized to vmov Rx, #constant. */
8298 if (inst.operands[i].issingle
8299 && is_quarter_float (inst.operands[1].imm)
8300 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3xd))
8335d6aa 8301 {
ba592044
AM
8302 inst.operands[1].imm =
8303 neon_qfloat_bits (v);
8304 do_vfp_nsyn_opcode ("fconsts");
8305 return TRUE;
8335d6aa 8306 }
5fc177c8
NC
8307
8308 /* If our host does not support a 64-bit type then we cannot perform
8309 the following optimization. This mean that there will be a
8310 discrepancy between the output produced by an assembler built for
8311 a 32-bit-only host and the output produced from a 64-bit host, but
8312 this cannot be helped. */
8313#if defined BFD_HOST_64_BIT
ba592044
AM
8314 else if (!inst.operands[1].issingle
8315 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3))
8335d6aa 8316 {
ba592044
AM
8317 if (is_double_a_single (v)
8318 && is_quarter_float (double_to_single (v)))
8319 {
8320 inst.operands[1].imm =
8321 neon_qfloat_bits (double_to_single (v));
8322 do_vfp_nsyn_opcode ("fconstd");
8323 return TRUE;
8324 }
8335d6aa 8325 }
5fc177c8 8326#endif
8335d6aa
JW
8327 }
8328 }
8329
8330 if (add_to_lit_pool ((!inst.operands[i].isvec
8331 || inst.operands[i].issingle) ? 4 : 8) == FAIL)
8332 return TRUE;
8333
8334 inst.operands[1].reg = REG_PC;
8335 inst.operands[1].isreg = 1;
8336 inst.operands[1].preind = 1;
e2b0ab59
AV
8337 inst.relocs[0].pc_rel = 1;
8338 inst.relocs[0].type = (thumb_p
8335d6aa
JW
8339 ? BFD_RELOC_ARM_THUMB_OFFSET
8340 : (mode_3
8341 ? BFD_RELOC_ARM_HWLITERAL
8342 : BFD_RELOC_ARM_LITERAL));
8343 return FALSE;
8344}
8345
8346/* inst.operands[i] was set up by parse_address. Encode it into an
8347 ARM-format instruction. Reject all forms which cannot be encoded
8348 into a coprocessor load/store instruction. If wb_ok is false,
8349 reject use of writeback; if unind_ok is false, reject use of
8350 unindexed addressing. If reloc_override is not 0, use it instead
8351 of BFD_ARM_CP_OFF_IMM, unless the initial relocation is a group one
8352 (in which case it is preserved). */
8353
8354static int
8355encode_arm_cp_address (int i, int wb_ok, int unind_ok, int reloc_override)
8356{
8357 if (!inst.operands[i].isreg)
8358 {
99b2a2dd
NC
8359 /* PR 18256 */
8360 if (! inst.operands[0].isvec)
8361 {
8362 inst.error = _("invalid co-processor operand");
8363 return FAIL;
8364 }
8335d6aa
JW
8365 if (move_or_literal_pool (0, CONST_VEC, /*mode_3=*/FALSE))
8366 return SUCCESS;
8367 }
8368
8369 inst.instruction |= inst.operands[i].reg << 16;
8370
8371 gas_assert (!(inst.operands[i].preind && inst.operands[i].postind));
8372
8373 if (!inst.operands[i].preind && !inst.operands[i].postind) /* unindexed */
8374 {
8375 gas_assert (!inst.operands[i].writeback);
8376 if (!unind_ok)
8377 {
8378 inst.error = _("instruction does not support unindexed addressing");
8379 return FAIL;
8380 }
8381 inst.instruction |= inst.operands[i].imm;
8382 inst.instruction |= INDEX_UP;
8383 return SUCCESS;
8384 }
8385
8386 if (inst.operands[i].preind)
8387 inst.instruction |= PRE_INDEX;
8388
8389 if (inst.operands[i].writeback)
09d92015 8390 {
8335d6aa 8391 if (inst.operands[i].reg == REG_PC)
c19d1205 8392 {
8335d6aa
JW
8393 inst.error = _("pc may not be used with write-back");
8394 return FAIL;
c19d1205 8395 }
8335d6aa 8396 if (!wb_ok)
c19d1205 8397 {
8335d6aa
JW
8398 inst.error = _("instruction does not support writeback");
8399 return FAIL;
c19d1205 8400 }
8335d6aa 8401 inst.instruction |= WRITE_BACK;
09d92015
MM
8402 }
8403
8335d6aa 8404 if (reloc_override)
e2b0ab59
AV
8405 inst.relocs[0].type = (bfd_reloc_code_real_type) reloc_override;
8406 else if ((inst.relocs[0].type < BFD_RELOC_ARM_ALU_PC_G0_NC
8407 || inst.relocs[0].type > BFD_RELOC_ARM_LDC_SB_G2)
8408 && inst.relocs[0].type != BFD_RELOC_ARM_LDR_PC_G0)
c19d1205 8409 {
8335d6aa 8410 if (thumb_mode)
e2b0ab59 8411 inst.relocs[0].type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
8335d6aa 8412 else
e2b0ab59 8413 inst.relocs[0].type = BFD_RELOC_ARM_CP_OFF_IMM;
c19d1205 8414 }
8335d6aa
JW
8415
8416 /* Prefer + for zero encoded value. */
8417 if (!inst.operands[i].negative)
8418 inst.instruction |= INDEX_UP;
8419
8420 return SUCCESS;
09d92015
MM
8421}
8422
5f4273c7 8423/* Functions for instruction encoding, sorted by sub-architecture.
c19d1205
ZW
8424 First some generics; their names are taken from the conventional
8425 bit positions for register arguments in ARM format instructions. */
09d92015 8426
a737bd4d 8427static void
c19d1205 8428do_noargs (void)
09d92015 8429{
c19d1205 8430}
a737bd4d 8431
c19d1205
ZW
8432static void
8433do_rd (void)
8434{
8435 inst.instruction |= inst.operands[0].reg << 12;
8436}
a737bd4d 8437
16a1fa25
TP
8438static void
8439do_rn (void)
8440{
8441 inst.instruction |= inst.operands[0].reg << 16;
8442}
8443
c19d1205
ZW
8444static void
8445do_rd_rm (void)
8446{
8447 inst.instruction |= inst.operands[0].reg << 12;
8448 inst.instruction |= inst.operands[1].reg;
8449}
09d92015 8450
9eb6c0f1
MGD
8451static void
8452do_rm_rn (void)
8453{
8454 inst.instruction |= inst.operands[0].reg;
8455 inst.instruction |= inst.operands[1].reg << 16;
8456}
8457
c19d1205
ZW
8458static void
8459do_rd_rn (void)
8460{
8461 inst.instruction |= inst.operands[0].reg << 12;
8462 inst.instruction |= inst.operands[1].reg << 16;
8463}
a737bd4d 8464
c19d1205
ZW
8465static void
8466do_rn_rd (void)
8467{
8468 inst.instruction |= inst.operands[0].reg << 16;
8469 inst.instruction |= inst.operands[1].reg << 12;
8470}
09d92015 8471
4ed7ed8d
TP
8472static void
8473do_tt (void)
8474{
8475 inst.instruction |= inst.operands[0].reg << 8;
8476 inst.instruction |= inst.operands[1].reg << 16;
8477}
8478
59d09be6
MGD
8479static bfd_boolean
8480check_obsolete (const arm_feature_set *feature, const char *msg)
8481{
8482 if (ARM_CPU_IS_ANY (cpu_variant))
8483 {
5c3696f8 8484 as_tsktsk ("%s", msg);
59d09be6
MGD
8485 return TRUE;
8486 }
8487 else if (ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
8488 {
8489 as_bad ("%s", msg);
8490 return TRUE;
8491 }
8492
8493 return FALSE;
8494}
8495
c19d1205
ZW
8496static void
8497do_rd_rm_rn (void)
8498{
9a64e435 8499 unsigned Rn = inst.operands[2].reg;
708587a4 8500 /* Enforce restrictions on SWP instruction. */
9a64e435 8501 if ((inst.instruction & 0x0fbfffff) == 0x01000090)
56adecf4
DG
8502 {
8503 constraint (Rn == inst.operands[0].reg || Rn == inst.operands[1].reg,
8504 _("Rn must not overlap other operands"));
8505
59d09be6
MGD
8506 /* SWP{b} is obsolete for ARMv8-A, and deprecated for ARMv6* and ARMv7.
8507 */
8508 if (!check_obsolete (&arm_ext_v8,
8509 _("swp{b} use is obsoleted for ARMv8 and later"))
8510 && warn_on_deprecated
8511 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6))
5c3696f8 8512 as_tsktsk (_("swp{b} use is deprecated for ARMv6 and ARMv7"));
56adecf4 8513 }
59d09be6 8514
c19d1205
ZW
8515 inst.instruction |= inst.operands[0].reg << 12;
8516 inst.instruction |= inst.operands[1].reg;
9a64e435 8517 inst.instruction |= Rn << 16;
c19d1205 8518}
09d92015 8519
c19d1205
ZW
8520static void
8521do_rd_rn_rm (void)
8522{
8523 inst.instruction |= inst.operands[0].reg << 12;
8524 inst.instruction |= inst.operands[1].reg << 16;
8525 inst.instruction |= inst.operands[2].reg;
8526}
a737bd4d 8527
c19d1205
ZW
8528static void
8529do_rm_rd_rn (void)
8530{
5be8be5d 8531 constraint ((inst.operands[2].reg == REG_PC), BAD_PC);
e2b0ab59
AV
8532 constraint (((inst.relocs[0].exp.X_op != O_constant
8533 && inst.relocs[0].exp.X_op != O_illegal)
8534 || inst.relocs[0].exp.X_add_number != 0),
5be8be5d 8535 BAD_ADDR_MODE);
c19d1205
ZW
8536 inst.instruction |= inst.operands[0].reg;
8537 inst.instruction |= inst.operands[1].reg << 12;
8538 inst.instruction |= inst.operands[2].reg << 16;
8539}
09d92015 8540
c19d1205
ZW
8541static void
8542do_imm0 (void)
8543{
8544 inst.instruction |= inst.operands[0].imm;
8545}
09d92015 8546
c19d1205
ZW
8547static void
8548do_rd_cpaddr (void)
8549{
8550 inst.instruction |= inst.operands[0].reg << 12;
8551 encode_arm_cp_address (1, TRUE, TRUE, 0);
09d92015 8552}
a737bd4d 8553
c19d1205
ZW
8554/* ARM instructions, in alphabetical order by function name (except
8555 that wrapper functions appear immediately after the function they
8556 wrap). */
09d92015 8557
c19d1205
ZW
8558/* This is a pseudo-op of the form "adr rd, label" to be converted
8559 into a relative address of the form "add rd, pc, #label-.-8". */
09d92015
MM
8560
8561static void
c19d1205 8562do_adr (void)
09d92015 8563{
c19d1205 8564 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 8565
c19d1205
ZW
8566 /* Frag hacking will turn this into a sub instruction if the offset turns
8567 out to be negative. */
e2b0ab59
AV
8568 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
8569 inst.relocs[0].pc_rel = 1;
8570 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 8571
fc6141f0 8572 if (support_interwork
e2b0ab59
AV
8573 && inst.relocs[0].exp.X_op == O_symbol
8574 && inst.relocs[0].exp.X_add_symbol != NULL
8575 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
8576 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
8577 inst.relocs[0].exp.X_add_number |= 1;
c19d1205 8578}
b99bd4ef 8579
c19d1205
ZW
8580/* This is a pseudo-op of the form "adrl rd, label" to be converted
8581 into a relative address of the form:
8582 add rd, pc, #low(label-.-8)"
8583 add rd, rd, #high(label-.-8)" */
b99bd4ef 8584
c19d1205
ZW
8585static void
8586do_adrl (void)
8587{
8588 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 8589
c19d1205
ZW
8590 /* Frag hacking will turn this into a sub instruction if the offset turns
8591 out to be negative. */
e2b0ab59
AV
8592 inst.relocs[0].type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
8593 inst.relocs[0].pc_rel = 1;
c19d1205 8594 inst.size = INSN_SIZE * 2;
e2b0ab59 8595 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 8596
fc6141f0 8597 if (support_interwork
e2b0ab59
AV
8598 && inst.relocs[0].exp.X_op == O_symbol
8599 && inst.relocs[0].exp.X_add_symbol != NULL
8600 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
8601 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
8602 inst.relocs[0].exp.X_add_number |= 1;
b99bd4ef
NC
8603}
8604
b99bd4ef 8605static void
c19d1205 8606do_arit (void)
b99bd4ef 8607{
e2b0ab59
AV
8608 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
8609 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 8610 THUMB1_RELOC_ONLY);
c19d1205
ZW
8611 if (!inst.operands[1].present)
8612 inst.operands[1].reg = inst.operands[0].reg;
8613 inst.instruction |= inst.operands[0].reg << 12;
8614 inst.instruction |= inst.operands[1].reg << 16;
8615 encode_arm_shifter_operand (2);
8616}
b99bd4ef 8617
62b3e311
PB
8618static void
8619do_barrier (void)
8620{
8621 if (inst.operands[0].present)
ccb84d65 8622 inst.instruction |= inst.operands[0].imm;
62b3e311
PB
8623 else
8624 inst.instruction |= 0xf;
8625}
8626
c19d1205
ZW
8627static void
8628do_bfc (void)
8629{
8630 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
8631 constraint (msb > 32, _("bit-field extends past end of register"));
8632 /* The instruction encoding stores the LSB and MSB,
8633 not the LSB and width. */
8634 inst.instruction |= inst.operands[0].reg << 12;
8635 inst.instruction |= inst.operands[1].imm << 7;
8636 inst.instruction |= (msb - 1) << 16;
8637}
b99bd4ef 8638
c19d1205
ZW
8639static void
8640do_bfi (void)
8641{
8642 unsigned int msb;
b99bd4ef 8643
c19d1205
ZW
8644 /* #0 in second position is alternative syntax for bfc, which is
8645 the same instruction but with REG_PC in the Rm field. */
8646 if (!inst.operands[1].isreg)
8647 inst.operands[1].reg = REG_PC;
b99bd4ef 8648
c19d1205
ZW
8649 msb = inst.operands[2].imm + inst.operands[3].imm;
8650 constraint (msb > 32, _("bit-field extends past end of register"));
8651 /* The instruction encoding stores the LSB and MSB,
8652 not the LSB and width. */
8653 inst.instruction |= inst.operands[0].reg << 12;
8654 inst.instruction |= inst.operands[1].reg;
8655 inst.instruction |= inst.operands[2].imm << 7;
8656 inst.instruction |= (msb - 1) << 16;
b99bd4ef
NC
8657}
8658
b99bd4ef 8659static void
c19d1205 8660do_bfx (void)
b99bd4ef 8661{
c19d1205
ZW
8662 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
8663 _("bit-field extends past end of register"));
8664 inst.instruction |= inst.operands[0].reg << 12;
8665 inst.instruction |= inst.operands[1].reg;
8666 inst.instruction |= inst.operands[2].imm << 7;
8667 inst.instruction |= (inst.operands[3].imm - 1) << 16;
8668}
09d92015 8669
c19d1205
ZW
8670/* ARM V5 breakpoint instruction (argument parse)
8671 BKPT <16 bit unsigned immediate>
8672 Instruction is not conditional.
8673 The bit pattern given in insns[] has the COND_ALWAYS condition,
8674 and it is an error if the caller tried to override that. */
b99bd4ef 8675
c19d1205
ZW
8676static void
8677do_bkpt (void)
8678{
8679 /* Top 12 of 16 bits to bits 19:8. */
8680 inst.instruction |= (inst.operands[0].imm & 0xfff0) << 4;
09d92015 8681
c19d1205
ZW
8682 /* Bottom 4 of 16 bits to bits 3:0. */
8683 inst.instruction |= inst.operands[0].imm & 0xf;
8684}
09d92015 8685
c19d1205
ZW
8686static void
8687encode_branch (int default_reloc)
8688{
8689 if (inst.operands[0].hasreloc)
8690 {
0855e32b
NS
8691 constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32
8692 && inst.operands[0].imm != BFD_RELOC_ARM_TLS_CALL,
8693 _("the only valid suffixes here are '(plt)' and '(tlscall)'"));
e2b0ab59 8694 inst.relocs[0].type = inst.operands[0].imm == BFD_RELOC_ARM_PLT32
0855e32b
NS
8695 ? BFD_RELOC_ARM_PLT32
8696 : thumb_mode ? BFD_RELOC_ARM_THM_TLS_CALL : BFD_RELOC_ARM_TLS_CALL;
c19d1205 8697 }
b99bd4ef 8698 else
e2b0ab59
AV
8699 inst.relocs[0].type = (bfd_reloc_code_real_type) default_reloc;
8700 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
8701}
8702
b99bd4ef 8703static void
c19d1205 8704do_branch (void)
b99bd4ef 8705{
39b41c9c
PB
8706#ifdef OBJ_ELF
8707 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
8708 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
8709 else
8710#endif
8711 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
8712}
8713
8714static void
8715do_bl (void)
8716{
8717#ifdef OBJ_ELF
8718 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
8719 {
8720 if (inst.cond == COND_ALWAYS)
8721 encode_branch (BFD_RELOC_ARM_PCREL_CALL);
8722 else
8723 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
8724 }
8725 else
8726#endif
8727 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
c19d1205 8728}
b99bd4ef 8729
c19d1205
ZW
8730/* ARM V5 branch-link-exchange instruction (argument parse)
8731 BLX <target_addr> ie BLX(1)
8732 BLX{<condition>} <Rm> ie BLX(2)
8733 Unfortunately, there are two different opcodes for this mnemonic.
8734 So, the insns[].value is not used, and the code here zaps values
8735 into inst.instruction.
8736 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
b99bd4ef 8737
c19d1205
ZW
8738static void
8739do_blx (void)
8740{
8741 if (inst.operands[0].isreg)
b99bd4ef 8742 {
c19d1205
ZW
8743 /* Arg is a register; the opcode provided by insns[] is correct.
8744 It is not illegal to do "blx pc", just useless. */
8745 if (inst.operands[0].reg == REG_PC)
8746 as_tsktsk (_("use of r15 in blx in ARM mode is not really useful"));
b99bd4ef 8747
c19d1205
ZW
8748 inst.instruction |= inst.operands[0].reg;
8749 }
8750 else
b99bd4ef 8751 {
c19d1205 8752 /* Arg is an address; this instruction cannot be executed
267bf995
RR
8753 conditionally, and the opcode must be adjusted.
8754 We retain the BFD_RELOC_ARM_PCREL_BLX till the very end
8755 where we generate out a BFD_RELOC_ARM_PCREL_CALL instead. */
c19d1205 8756 constraint (inst.cond != COND_ALWAYS, BAD_COND);
2fc8bdac 8757 inst.instruction = 0xfa000000;
267bf995 8758 encode_branch (BFD_RELOC_ARM_PCREL_BLX);
b99bd4ef 8759 }
c19d1205
ZW
8760}
8761
8762static void
8763do_bx (void)
8764{
845b51d6
PB
8765 bfd_boolean want_reloc;
8766
c19d1205
ZW
8767 if (inst.operands[0].reg == REG_PC)
8768 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
b99bd4ef 8769
c19d1205 8770 inst.instruction |= inst.operands[0].reg;
845b51d6
PB
8771 /* Output R_ARM_V4BX relocations if is an EABI object that looks like
8772 it is for ARMv4t or earlier. */
8773 want_reloc = !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5);
4d354d8b
TP
8774 if (!ARM_FEATURE_ZERO (selected_object_arch)
8775 && !ARM_CPU_HAS_FEATURE (selected_object_arch, arm_ext_v5))
845b51d6
PB
8776 want_reloc = TRUE;
8777
5ad34203 8778#ifdef OBJ_ELF
845b51d6 8779 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
5ad34203 8780#endif
584206db 8781 want_reloc = FALSE;
845b51d6
PB
8782
8783 if (want_reloc)
e2b0ab59 8784 inst.relocs[0].type = BFD_RELOC_ARM_V4BX;
09d92015
MM
8785}
8786
c19d1205
ZW
8787
8788/* ARM v5TEJ. Jump to Jazelle code. */
a737bd4d
NC
8789
8790static void
c19d1205 8791do_bxj (void)
a737bd4d 8792{
c19d1205
ZW
8793 if (inst.operands[0].reg == REG_PC)
8794 as_tsktsk (_("use of r15 in bxj is not really useful"));
8795
8796 inst.instruction |= inst.operands[0].reg;
a737bd4d
NC
8797}
8798
c19d1205
ZW
8799/* Co-processor data operation:
8800 CDP{cond} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>}
8801 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>} */
8802static void
8803do_cdp (void)
8804{
8805 inst.instruction |= inst.operands[0].reg << 8;
8806 inst.instruction |= inst.operands[1].imm << 20;
8807 inst.instruction |= inst.operands[2].reg << 12;
8808 inst.instruction |= inst.operands[3].reg << 16;
8809 inst.instruction |= inst.operands[4].reg;
8810 inst.instruction |= inst.operands[5].imm << 5;
8811}
a737bd4d
NC
8812
8813static void
c19d1205 8814do_cmp (void)
a737bd4d 8815{
c19d1205
ZW
8816 inst.instruction |= inst.operands[0].reg << 16;
8817 encode_arm_shifter_operand (1);
a737bd4d
NC
8818}
8819
c19d1205
ZW
8820/* Transfer between coprocessor and ARM registers.
8821 MRC{cond} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}
8822 MRC2
8823 MCR{cond}
8824 MCR2
8825
8826 No special properties. */
09d92015 8827
dcbd0d71
MGD
8828struct deprecated_coproc_regs_s
8829{
8830 unsigned cp;
8831 int opc1;
8832 unsigned crn;
8833 unsigned crm;
8834 int opc2;
8835 arm_feature_set deprecated;
8836 arm_feature_set obsoleted;
8837 const char *dep_msg;
8838 const char *obs_msg;
8839};
8840
8841#define DEPR_ACCESS_V8 \
8842 N_("This coprocessor register access is deprecated in ARMv8")
8843
8844/* Table of all deprecated coprocessor registers. */
8845static struct deprecated_coproc_regs_s deprecated_coproc_regs[] =
8846{
8847 {15, 0, 7, 10, 5, /* CP15DMB. */
823d2571 8848 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
8849 DEPR_ACCESS_V8, NULL},
8850 {15, 0, 7, 10, 4, /* CP15DSB. */
823d2571 8851 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
8852 DEPR_ACCESS_V8, NULL},
8853 {15, 0, 7, 5, 4, /* CP15ISB. */
823d2571 8854 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
8855 DEPR_ACCESS_V8, NULL},
8856 {14, 6, 1, 0, 0, /* TEEHBR. */
823d2571 8857 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
8858 DEPR_ACCESS_V8, NULL},
8859 {14, 6, 0, 0, 0, /* TEECR. */
823d2571 8860 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
8861 DEPR_ACCESS_V8, NULL},
8862};
8863
8864#undef DEPR_ACCESS_V8
8865
8866static const size_t deprecated_coproc_reg_count =
8867 sizeof (deprecated_coproc_regs) / sizeof (deprecated_coproc_regs[0]);
8868
09d92015 8869static void
c19d1205 8870do_co_reg (void)
09d92015 8871{
fdfde340 8872 unsigned Rd;
dcbd0d71 8873 size_t i;
fdfde340
JM
8874
8875 Rd = inst.operands[2].reg;
8876 if (thumb_mode)
8877 {
8878 if (inst.instruction == 0xee000010
8879 || inst.instruction == 0xfe000010)
8880 /* MCR, MCR2 */
8881 reject_bad_reg (Rd);
5c8ed6a4 8882 else if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
fdfde340
JM
8883 /* MRC, MRC2 */
8884 constraint (Rd == REG_SP, BAD_SP);
8885 }
8886 else
8887 {
8888 /* MCR */
8889 if (inst.instruction == 0xe000010)
8890 constraint (Rd == REG_PC, BAD_PC);
8891 }
8892
dcbd0d71
MGD
8893 for (i = 0; i < deprecated_coproc_reg_count; ++i)
8894 {
8895 const struct deprecated_coproc_regs_s *r =
8896 deprecated_coproc_regs + i;
8897
8898 if (inst.operands[0].reg == r->cp
8899 && inst.operands[1].imm == r->opc1
8900 && inst.operands[3].reg == r->crn
8901 && inst.operands[4].reg == r->crm
8902 && inst.operands[5].imm == r->opc2)
8903 {
b10bf8c5 8904 if (! ARM_CPU_IS_ANY (cpu_variant)
477330fc 8905 && warn_on_deprecated
dcbd0d71 8906 && ARM_CPU_HAS_FEATURE (cpu_variant, r->deprecated))
5c3696f8 8907 as_tsktsk ("%s", r->dep_msg);
dcbd0d71
MGD
8908 }
8909 }
fdfde340 8910
c19d1205
ZW
8911 inst.instruction |= inst.operands[0].reg << 8;
8912 inst.instruction |= inst.operands[1].imm << 21;
fdfde340 8913 inst.instruction |= Rd << 12;
c19d1205
ZW
8914 inst.instruction |= inst.operands[3].reg << 16;
8915 inst.instruction |= inst.operands[4].reg;
8916 inst.instruction |= inst.operands[5].imm << 5;
8917}
09d92015 8918
c19d1205
ZW
8919/* Transfer between coprocessor register and pair of ARM registers.
8920 MCRR{cond} <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
8921 MCRR2
8922 MRRC{cond}
8923 MRRC2
b99bd4ef 8924
c19d1205 8925 Two XScale instructions are special cases of these:
09d92015 8926
c19d1205
ZW
8927 MAR{cond} acc0, <RdLo>, <RdHi> == MCRR{cond} p0, #0, <RdLo>, <RdHi>, c0
8928 MRA{cond} acc0, <RdLo>, <RdHi> == MRRC{cond} p0, #0, <RdLo>, <RdHi>, c0
b99bd4ef 8929
5f4273c7 8930 Result unpredictable if Rd or Rn is R15. */
a737bd4d 8931
c19d1205
ZW
8932static void
8933do_co_reg2c (void)
8934{
fdfde340
JM
8935 unsigned Rd, Rn;
8936
8937 Rd = inst.operands[2].reg;
8938 Rn = inst.operands[3].reg;
8939
8940 if (thumb_mode)
8941 {
8942 reject_bad_reg (Rd);
8943 reject_bad_reg (Rn);
8944 }
8945 else
8946 {
8947 constraint (Rd == REG_PC, BAD_PC);
8948 constraint (Rn == REG_PC, BAD_PC);
8949 }
8950
873f10f0
TC
8951 /* Only check the MRRC{2} variants. */
8952 if ((inst.instruction & 0x0FF00000) == 0x0C500000)
8953 {
8954 /* If Rd == Rn, error that the operation is
8955 unpredictable (example MRRC p3,#1,r1,r1,c4). */
8956 constraint (Rd == Rn, BAD_OVERLAP);
8957 }
8958
c19d1205
ZW
8959 inst.instruction |= inst.operands[0].reg << 8;
8960 inst.instruction |= inst.operands[1].imm << 4;
fdfde340
JM
8961 inst.instruction |= Rd << 12;
8962 inst.instruction |= Rn << 16;
c19d1205 8963 inst.instruction |= inst.operands[4].reg;
b99bd4ef
NC
8964}
8965
c19d1205
ZW
8966static void
8967do_cpsi (void)
8968{
8969 inst.instruction |= inst.operands[0].imm << 6;
a028a6f5
PB
8970 if (inst.operands[1].present)
8971 {
8972 inst.instruction |= CPSI_MMOD;
8973 inst.instruction |= inst.operands[1].imm;
8974 }
c19d1205 8975}
b99bd4ef 8976
62b3e311
PB
8977static void
8978do_dbg (void)
8979{
8980 inst.instruction |= inst.operands[0].imm;
8981}
8982
eea54501
MGD
8983static void
8984do_div (void)
8985{
8986 unsigned Rd, Rn, Rm;
8987
8988 Rd = inst.operands[0].reg;
8989 Rn = (inst.operands[1].present
8990 ? inst.operands[1].reg : Rd);
8991 Rm = inst.operands[2].reg;
8992
8993 constraint ((Rd == REG_PC), BAD_PC);
8994 constraint ((Rn == REG_PC), BAD_PC);
8995 constraint ((Rm == REG_PC), BAD_PC);
8996
8997 inst.instruction |= Rd << 16;
8998 inst.instruction |= Rn << 0;
8999 inst.instruction |= Rm << 8;
9000}
9001
b99bd4ef 9002static void
c19d1205 9003do_it (void)
b99bd4ef 9004{
c19d1205 9005 /* There is no IT instruction in ARM mode. We
e07e6e58
NC
9006 process it to do the validation as if in
9007 thumb mode, just in case the code gets
9008 assembled for thumb using the unified syntax. */
9009
c19d1205 9010 inst.size = 0;
e07e6e58
NC
9011 if (unified_syntax)
9012 {
9013 set_it_insn_type (IT_INSN);
9014 now_it.mask = (inst.instruction & 0xf) | 0x10;
9015 now_it.cc = inst.operands[0].imm;
9016 }
09d92015 9017}
b99bd4ef 9018
6530b175
NC
9019/* If there is only one register in the register list,
9020 then return its register number. Otherwise return -1. */
9021static int
9022only_one_reg_in_list (int range)
9023{
9024 int i = ffs (range) - 1;
9025 return (i > 15 || range != (1 << i)) ? -1 : i;
9026}
9027
09d92015 9028static void
6530b175 9029encode_ldmstm(int from_push_pop_mnem)
ea6ef066 9030{
c19d1205
ZW
9031 int base_reg = inst.operands[0].reg;
9032 int range = inst.operands[1].imm;
6530b175 9033 int one_reg;
ea6ef066 9034
c19d1205
ZW
9035 inst.instruction |= base_reg << 16;
9036 inst.instruction |= range;
ea6ef066 9037
c19d1205
ZW
9038 if (inst.operands[1].writeback)
9039 inst.instruction |= LDM_TYPE_2_OR_3;
09d92015 9040
c19d1205 9041 if (inst.operands[0].writeback)
ea6ef066 9042 {
c19d1205
ZW
9043 inst.instruction |= WRITE_BACK;
9044 /* Check for unpredictable uses of writeback. */
9045 if (inst.instruction & LOAD_BIT)
09d92015 9046 {
c19d1205
ZW
9047 /* Not allowed in LDM type 2. */
9048 if ((inst.instruction & LDM_TYPE_2_OR_3)
9049 && ((range & (1 << REG_PC)) == 0))
9050 as_warn (_("writeback of base register is UNPREDICTABLE"));
9051 /* Only allowed if base reg not in list for other types. */
9052 else if (range & (1 << base_reg))
9053 as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
9054 }
9055 else /* STM. */
9056 {
9057 /* Not allowed for type 2. */
9058 if (inst.instruction & LDM_TYPE_2_OR_3)
9059 as_warn (_("writeback of base register is UNPREDICTABLE"));
9060 /* Only allowed if base reg not in list, or first in list. */
9061 else if ((range & (1 << base_reg))
9062 && (range & ((1 << base_reg) - 1)))
9063 as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
09d92015 9064 }
ea6ef066 9065 }
6530b175
NC
9066
9067 /* If PUSH/POP has only one register, then use the A2 encoding. */
9068 one_reg = only_one_reg_in_list (range);
9069 if (from_push_pop_mnem && one_reg >= 0)
9070 {
9071 int is_push = (inst.instruction & A_PUSH_POP_OP_MASK) == A1_OPCODE_PUSH;
9072
4f588891
NC
9073 if (is_push && one_reg == 13 /* SP */)
9074 /* PR 22483: The A2 encoding cannot be used when
9075 pushing the stack pointer as this is UNPREDICTABLE. */
9076 return;
9077
6530b175
NC
9078 inst.instruction &= A_COND_MASK;
9079 inst.instruction |= is_push ? A2_OPCODE_PUSH : A2_OPCODE_POP;
9080 inst.instruction |= one_reg << 12;
9081 }
9082}
9083
9084static void
9085do_ldmstm (void)
9086{
9087 encode_ldmstm (/*from_push_pop_mnem=*/FALSE);
a737bd4d
NC
9088}
9089
c19d1205
ZW
9090/* ARMv5TE load-consecutive (argument parse)
9091 Mode is like LDRH.
9092
9093 LDRccD R, mode
9094 STRccD R, mode. */
9095
a737bd4d 9096static void
c19d1205 9097do_ldrd (void)
a737bd4d 9098{
c19d1205 9099 constraint (inst.operands[0].reg % 2 != 0,
c56791bb 9100 _("first transfer register must be even"));
c19d1205
ZW
9101 constraint (inst.operands[1].present
9102 && inst.operands[1].reg != inst.operands[0].reg + 1,
c56791bb 9103 _("can only transfer two consecutive registers"));
c19d1205
ZW
9104 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
9105 constraint (!inst.operands[2].isreg, _("'[' expected"));
a737bd4d 9106
c19d1205
ZW
9107 if (!inst.operands[1].present)
9108 inst.operands[1].reg = inst.operands[0].reg + 1;
5f4273c7 9109
c56791bb
RE
9110 /* encode_arm_addr_mode_3 will diagnose overlap between the base
9111 register and the first register written; we have to diagnose
9112 overlap between the base and the second register written here. */
ea6ef066 9113
c56791bb
RE
9114 if (inst.operands[2].reg == inst.operands[1].reg
9115 && (inst.operands[2].writeback || inst.operands[2].postind))
9116 as_warn (_("base register written back, and overlaps "
9117 "second transfer register"));
b05fe5cf 9118
c56791bb
RE
9119 if (!(inst.instruction & V4_STR_BIT))
9120 {
c19d1205 9121 /* For an index-register load, the index register must not overlap the
c56791bb
RE
9122 destination (even if not write-back). */
9123 if (inst.operands[2].immisreg
9124 && ((unsigned) inst.operands[2].imm == inst.operands[0].reg
9125 || (unsigned) inst.operands[2].imm == inst.operands[1].reg))
9126 as_warn (_("index register overlaps transfer register"));
b05fe5cf 9127 }
c19d1205
ZW
9128 inst.instruction |= inst.operands[0].reg << 12;
9129 encode_arm_addr_mode_3 (2, /*is_t=*/FALSE);
b05fe5cf
ZW
9130}
9131
9132static void
c19d1205 9133do_ldrex (void)
b05fe5cf 9134{
c19d1205
ZW
9135 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
9136 || inst.operands[1].postind || inst.operands[1].writeback
9137 || inst.operands[1].immisreg || inst.operands[1].shifted
01cfc07f
NC
9138 || inst.operands[1].negative
9139 /* This can arise if the programmer has written
9140 strex rN, rM, foo
9141 or if they have mistakenly used a register name as the last
9142 operand, eg:
9143 strex rN, rM, rX
9144 It is very difficult to distinguish between these two cases
9145 because "rX" might actually be a label. ie the register
9146 name has been occluded by a symbol of the same name. So we
9147 just generate a general 'bad addressing mode' type error
9148 message and leave it up to the programmer to discover the
9149 true cause and fix their mistake. */
9150 || (inst.operands[1].reg == REG_PC),
9151 BAD_ADDR_MODE);
b05fe5cf 9152
e2b0ab59
AV
9153 constraint (inst.relocs[0].exp.X_op != O_constant
9154 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9155 _("offset must be zero in ARM encoding"));
b05fe5cf 9156
5be8be5d
DG
9157 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
9158
c19d1205
ZW
9159 inst.instruction |= inst.operands[0].reg << 12;
9160 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 9161 inst.relocs[0].type = BFD_RELOC_UNUSED;
b05fe5cf
ZW
9162}
9163
9164static void
c19d1205 9165do_ldrexd (void)
b05fe5cf 9166{
c19d1205
ZW
9167 constraint (inst.operands[0].reg % 2 != 0,
9168 _("even register required"));
9169 constraint (inst.operands[1].present
9170 && inst.operands[1].reg != inst.operands[0].reg + 1,
9171 _("can only load two consecutive registers"));
9172 /* If op 1 were present and equal to PC, this function wouldn't
9173 have been called in the first place. */
9174 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
b05fe5cf 9175
c19d1205
ZW
9176 inst.instruction |= inst.operands[0].reg << 12;
9177 inst.instruction |= inst.operands[2].reg << 16;
b05fe5cf
ZW
9178}
9179
1be5fd2e
NC
9180/* In both ARM and thumb state 'ldr pc, #imm' with an immediate
9181 which is not a multiple of four is UNPREDICTABLE. */
9182static void
9183check_ldr_r15_aligned (void)
9184{
9185 constraint (!(inst.operands[1].immisreg)
9186 && (inst.operands[0].reg == REG_PC
9187 && inst.operands[1].reg == REG_PC
e2b0ab59 9188 && (inst.relocs[0].exp.X_add_number & 0x3)),
de194d85 9189 _("ldr to register 15 must be 4-byte aligned"));
1be5fd2e
NC
9190}
9191
b05fe5cf 9192static void
c19d1205 9193do_ldst (void)
b05fe5cf 9194{
c19d1205
ZW
9195 inst.instruction |= inst.operands[0].reg << 12;
9196 if (!inst.operands[1].isreg)
8335d6aa 9197 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/FALSE))
b05fe5cf 9198 return;
c19d1205 9199 encode_arm_addr_mode_2 (1, /*is_t=*/FALSE);
1be5fd2e 9200 check_ldr_r15_aligned ();
b05fe5cf
ZW
9201}
9202
9203static void
c19d1205 9204do_ldstt (void)
b05fe5cf 9205{
c19d1205
ZW
9206 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
9207 reject [Rn,...]. */
9208 if (inst.operands[1].preind)
b05fe5cf 9209 {
e2b0ab59
AV
9210 constraint (inst.relocs[0].exp.X_op != O_constant
9211 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9212 _("this instruction requires a post-indexed address"));
b05fe5cf 9213
c19d1205
ZW
9214 inst.operands[1].preind = 0;
9215 inst.operands[1].postind = 1;
9216 inst.operands[1].writeback = 1;
b05fe5cf 9217 }
c19d1205
ZW
9218 inst.instruction |= inst.operands[0].reg << 12;
9219 encode_arm_addr_mode_2 (1, /*is_t=*/TRUE);
9220}
b05fe5cf 9221
c19d1205 9222/* Halfword and signed-byte load/store operations. */
b05fe5cf 9223
c19d1205
ZW
9224static void
9225do_ldstv4 (void)
9226{
ff4a8d2b 9227 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205
ZW
9228 inst.instruction |= inst.operands[0].reg << 12;
9229 if (!inst.operands[1].isreg)
8335d6aa 9230 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/TRUE))
b05fe5cf 9231 return;
c19d1205 9232 encode_arm_addr_mode_3 (1, /*is_t=*/FALSE);
b05fe5cf
ZW
9233}
9234
9235static void
c19d1205 9236do_ldsttv4 (void)
b05fe5cf 9237{
c19d1205
ZW
9238 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
9239 reject [Rn,...]. */
9240 if (inst.operands[1].preind)
b05fe5cf 9241 {
e2b0ab59
AV
9242 constraint (inst.relocs[0].exp.X_op != O_constant
9243 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9244 _("this instruction requires a post-indexed address"));
b05fe5cf 9245
c19d1205
ZW
9246 inst.operands[1].preind = 0;
9247 inst.operands[1].postind = 1;
9248 inst.operands[1].writeback = 1;
b05fe5cf 9249 }
c19d1205
ZW
9250 inst.instruction |= inst.operands[0].reg << 12;
9251 encode_arm_addr_mode_3 (1, /*is_t=*/TRUE);
9252}
b05fe5cf 9253
c19d1205
ZW
9254/* Co-processor register load/store.
9255 Format: <LDC|STC>{cond}[L] CP#,CRd,<address> */
9256static void
9257do_lstc (void)
9258{
9259 inst.instruction |= inst.operands[0].reg << 8;
9260 inst.instruction |= inst.operands[1].reg << 12;
9261 encode_arm_cp_address (2, TRUE, TRUE, 0);
b05fe5cf
ZW
9262}
9263
b05fe5cf 9264static void
c19d1205 9265do_mlas (void)
b05fe5cf 9266{
8fb9d7b9 9267 /* This restriction does not apply to mls (nor to mla in v6 or later). */
c19d1205 9268 if (inst.operands[0].reg == inst.operands[1].reg
8fb9d7b9 9269 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6)
c19d1205 9270 && !(inst.instruction & 0x00400000))
8fb9d7b9 9271 as_tsktsk (_("Rd and Rm should be different in mla"));
b05fe5cf 9272
c19d1205
ZW
9273 inst.instruction |= inst.operands[0].reg << 16;
9274 inst.instruction |= inst.operands[1].reg;
9275 inst.instruction |= inst.operands[2].reg << 8;
9276 inst.instruction |= inst.operands[3].reg << 12;
c19d1205 9277}
b05fe5cf 9278
c19d1205
ZW
9279static void
9280do_mov (void)
9281{
e2b0ab59
AV
9282 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
9283 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 9284 THUMB1_RELOC_ONLY);
c19d1205
ZW
9285 inst.instruction |= inst.operands[0].reg << 12;
9286 encode_arm_shifter_operand (1);
9287}
b05fe5cf 9288
c19d1205
ZW
9289/* ARM V6T2 16-bit immediate register load: MOV[WT]{cond} Rd, #<imm16>. */
9290static void
9291do_mov16 (void)
9292{
b6895b4f
PB
9293 bfd_vma imm;
9294 bfd_boolean top;
9295
9296 top = (inst.instruction & 0x00400000) != 0;
e2b0ab59 9297 constraint (top && inst.relocs[0].type == BFD_RELOC_ARM_MOVW,
33eaf5de 9298 _(":lower16: not allowed in this instruction"));
e2b0ab59 9299 constraint (!top && inst.relocs[0].type == BFD_RELOC_ARM_MOVT,
33eaf5de 9300 _(":upper16: not allowed in this instruction"));
c19d1205 9301 inst.instruction |= inst.operands[0].reg << 12;
e2b0ab59 9302 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 9303 {
e2b0ab59 9304 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
9305 /* The value is in two pieces: 0:11, 16:19. */
9306 inst.instruction |= (imm & 0x00000fff);
9307 inst.instruction |= (imm & 0x0000f000) << 4;
9308 }
b05fe5cf 9309}
b99bd4ef 9310
037e8744
JB
9311static int
9312do_vfp_nsyn_mrs (void)
9313{
9314 if (inst.operands[0].isvec)
9315 {
9316 if (inst.operands[1].reg != 1)
477330fc 9317 first_error (_("operand 1 must be FPSCR"));
037e8744
JB
9318 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
9319 memset (&inst.operands[1], '\0', sizeof (inst.operands[1]));
9320 do_vfp_nsyn_opcode ("fmstat");
9321 }
9322 else if (inst.operands[1].isvec)
9323 do_vfp_nsyn_opcode ("fmrx");
9324 else
9325 return FAIL;
5f4273c7 9326
037e8744
JB
9327 return SUCCESS;
9328}
9329
9330static int
9331do_vfp_nsyn_msr (void)
9332{
9333 if (inst.operands[0].isvec)
9334 do_vfp_nsyn_opcode ("fmxr");
9335 else
9336 return FAIL;
9337
9338 return SUCCESS;
9339}
9340
f7c21dc7
NC
9341static void
9342do_vmrs (void)
9343{
9344 unsigned Rt = inst.operands[0].reg;
fa94de6b 9345
16d02dc9 9346 if (thumb_mode && Rt == REG_SP)
f7c21dc7
NC
9347 {
9348 inst.error = BAD_SP;
9349 return;
9350 }
9351
40c7d507
RR
9352 /* MVFR2 is only valid at ARMv8-A. */
9353 if (inst.operands[1].reg == 5)
9354 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
9355 _(BAD_FPU));
9356
f7c21dc7 9357 /* APSR_ sets isvec. All other refs to PC are illegal. */
16d02dc9 9358 if (!inst.operands[0].isvec && Rt == REG_PC)
f7c21dc7
NC
9359 {
9360 inst.error = BAD_PC;
9361 return;
9362 }
9363
16d02dc9
JB
9364 /* If we get through parsing the register name, we just insert the number
9365 generated into the instruction without further validation. */
9366 inst.instruction |= (inst.operands[1].reg << 16);
f7c21dc7
NC
9367 inst.instruction |= (Rt << 12);
9368}
9369
9370static void
9371do_vmsr (void)
9372{
9373 unsigned Rt = inst.operands[1].reg;
fa94de6b 9374
f7c21dc7
NC
9375 if (thumb_mode)
9376 reject_bad_reg (Rt);
9377 else if (Rt == REG_PC)
9378 {
9379 inst.error = BAD_PC;
9380 return;
9381 }
9382
40c7d507
RR
9383 /* MVFR2 is only valid for ARMv8-A. */
9384 if (inst.operands[0].reg == 5)
9385 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
9386 _(BAD_FPU));
9387
16d02dc9
JB
9388 /* If we get through parsing the register name, we just insert the number
9389 generated into the instruction without further validation. */
9390 inst.instruction |= (inst.operands[0].reg << 16);
f7c21dc7
NC
9391 inst.instruction |= (Rt << 12);
9392}
9393
b99bd4ef 9394static void
c19d1205 9395do_mrs (void)
b99bd4ef 9396{
90ec0d68
MGD
9397 unsigned br;
9398
037e8744
JB
9399 if (do_vfp_nsyn_mrs () == SUCCESS)
9400 return;
9401
ff4a8d2b 9402 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205 9403 inst.instruction |= inst.operands[0].reg << 12;
90ec0d68
MGD
9404
9405 if (inst.operands[1].isreg)
9406 {
9407 br = inst.operands[1].reg;
806ab1c0 9408 if (((br & 0x200) == 0) && ((br & 0xf0000) != 0xf0000))
90ec0d68
MGD
9409 as_bad (_("bad register for mrs"));
9410 }
9411 else
9412 {
9413 /* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all. */
9414 constraint ((inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f))
9415 != (PSR_c|PSR_f),
d2cd1205 9416 _("'APSR', 'CPSR' or 'SPSR' expected"));
90ec0d68
MGD
9417 br = (15<<16) | (inst.operands[1].imm & SPSR_BIT);
9418 }
9419
9420 inst.instruction |= br;
c19d1205 9421}
b99bd4ef 9422
c19d1205
ZW
9423/* Two possible forms:
9424 "{C|S}PSR_<field>, Rm",
9425 "{C|S}PSR_f, #expression". */
b99bd4ef 9426
c19d1205
ZW
9427static void
9428do_msr (void)
9429{
037e8744
JB
9430 if (do_vfp_nsyn_msr () == SUCCESS)
9431 return;
9432
c19d1205
ZW
9433 inst.instruction |= inst.operands[0].imm;
9434 if (inst.operands[1].isreg)
9435 inst.instruction |= inst.operands[1].reg;
9436 else
b99bd4ef 9437 {
c19d1205 9438 inst.instruction |= INST_IMMEDIATE;
e2b0ab59
AV
9439 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
9440 inst.relocs[0].pc_rel = 0;
b99bd4ef 9441 }
b99bd4ef
NC
9442}
9443
c19d1205
ZW
9444static void
9445do_mul (void)
a737bd4d 9446{
ff4a8d2b
NC
9447 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
9448
c19d1205
ZW
9449 if (!inst.operands[2].present)
9450 inst.operands[2].reg = inst.operands[0].reg;
9451 inst.instruction |= inst.operands[0].reg << 16;
9452 inst.instruction |= inst.operands[1].reg;
9453 inst.instruction |= inst.operands[2].reg << 8;
a737bd4d 9454
8fb9d7b9
MS
9455 if (inst.operands[0].reg == inst.operands[1].reg
9456 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
9457 as_tsktsk (_("Rd and Rm should be different in mul"));
a737bd4d
NC
9458}
9459
c19d1205
ZW
9460/* Long Multiply Parser
9461 UMULL RdLo, RdHi, Rm, Rs
9462 SMULL RdLo, RdHi, Rm, Rs
9463 UMLAL RdLo, RdHi, Rm, Rs
9464 SMLAL RdLo, RdHi, Rm, Rs. */
b99bd4ef
NC
9465
9466static void
c19d1205 9467do_mull (void)
b99bd4ef 9468{
c19d1205
ZW
9469 inst.instruction |= inst.operands[0].reg << 12;
9470 inst.instruction |= inst.operands[1].reg << 16;
9471 inst.instruction |= inst.operands[2].reg;
9472 inst.instruction |= inst.operands[3].reg << 8;
b99bd4ef 9473
682b27ad
PB
9474 /* rdhi and rdlo must be different. */
9475 if (inst.operands[0].reg == inst.operands[1].reg)
9476 as_tsktsk (_("rdhi and rdlo must be different"));
9477
9478 /* rdhi, rdlo and rm must all be different before armv6. */
9479 if ((inst.operands[0].reg == inst.operands[2].reg
c19d1205 9480 || inst.operands[1].reg == inst.operands[2].reg)
682b27ad 9481 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
c19d1205
ZW
9482 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
9483}
b99bd4ef 9484
c19d1205
ZW
9485static void
9486do_nop (void)
9487{
e7495e45
NS
9488 if (inst.operands[0].present
9489 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6k))
c19d1205
ZW
9490 {
9491 /* Architectural NOP hints are CPSR sets with no bits selected. */
9492 inst.instruction &= 0xf0000000;
e7495e45
NS
9493 inst.instruction |= 0x0320f000;
9494 if (inst.operands[0].present)
9495 inst.instruction |= inst.operands[0].imm;
c19d1205 9496 }
b99bd4ef
NC
9497}
9498
c19d1205
ZW
9499/* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
9500 PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
9501 Condition defaults to COND_ALWAYS.
9502 Error if Rd, Rn or Rm are R15. */
b99bd4ef
NC
9503
9504static void
c19d1205 9505do_pkhbt (void)
b99bd4ef 9506{
c19d1205
ZW
9507 inst.instruction |= inst.operands[0].reg << 12;
9508 inst.instruction |= inst.operands[1].reg << 16;
9509 inst.instruction |= inst.operands[2].reg;
9510 if (inst.operands[3].present)
9511 encode_arm_shift (3);
9512}
b99bd4ef 9513
c19d1205 9514/* ARM V6 PKHTB (Argument Parse). */
b99bd4ef 9515
c19d1205
ZW
9516static void
9517do_pkhtb (void)
9518{
9519 if (!inst.operands[3].present)
b99bd4ef 9520 {
c19d1205
ZW
9521 /* If the shift specifier is omitted, turn the instruction
9522 into pkhbt rd, rm, rn. */
9523 inst.instruction &= 0xfff00010;
9524 inst.instruction |= inst.operands[0].reg << 12;
9525 inst.instruction |= inst.operands[1].reg;
9526 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
9527 }
9528 else
9529 {
c19d1205
ZW
9530 inst.instruction |= inst.operands[0].reg << 12;
9531 inst.instruction |= inst.operands[1].reg << 16;
9532 inst.instruction |= inst.operands[2].reg;
9533 encode_arm_shift (3);
b99bd4ef
NC
9534 }
9535}
9536
c19d1205 9537/* ARMv5TE: Preload-Cache
60e5ef9f 9538 MP Extensions: Preload for write
c19d1205 9539
60e5ef9f 9540 PLD(W) <addr_mode>
c19d1205
ZW
9541
9542 Syntactically, like LDR with B=1, W=0, L=1. */
b99bd4ef
NC
9543
9544static void
c19d1205 9545do_pld (void)
b99bd4ef 9546{
c19d1205
ZW
9547 constraint (!inst.operands[0].isreg,
9548 _("'[' expected after PLD mnemonic"));
9549 constraint (inst.operands[0].postind,
9550 _("post-indexed expression used in preload instruction"));
9551 constraint (inst.operands[0].writeback,
9552 _("writeback used in preload instruction"));
9553 constraint (!inst.operands[0].preind,
9554 _("unindexed addressing used in preload instruction"));
c19d1205
ZW
9555 encode_arm_addr_mode_2 (0, /*is_t=*/FALSE);
9556}
b99bd4ef 9557
62b3e311
PB
9558/* ARMv7: PLI <addr_mode> */
9559static void
9560do_pli (void)
9561{
9562 constraint (!inst.operands[0].isreg,
9563 _("'[' expected after PLI mnemonic"));
9564 constraint (inst.operands[0].postind,
9565 _("post-indexed expression used in preload instruction"));
9566 constraint (inst.operands[0].writeback,
9567 _("writeback used in preload instruction"));
9568 constraint (!inst.operands[0].preind,
9569 _("unindexed addressing used in preload instruction"));
9570 encode_arm_addr_mode_2 (0, /*is_t=*/FALSE);
9571 inst.instruction &= ~PRE_INDEX;
9572}
9573
c19d1205
ZW
9574static void
9575do_push_pop (void)
9576{
5e0d7f77
MP
9577 constraint (inst.operands[0].writeback,
9578 _("push/pop do not support {reglist}^"));
c19d1205
ZW
9579 inst.operands[1] = inst.operands[0];
9580 memset (&inst.operands[0], 0, sizeof inst.operands[0]);
9581 inst.operands[0].isreg = 1;
9582 inst.operands[0].writeback = 1;
9583 inst.operands[0].reg = REG_SP;
6530b175 9584 encode_ldmstm (/*from_push_pop_mnem=*/TRUE);
c19d1205 9585}
b99bd4ef 9586
c19d1205
ZW
9587/* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
9588 word at the specified address and the following word
9589 respectively.
9590 Unconditionally executed.
9591 Error if Rn is R15. */
b99bd4ef 9592
c19d1205
ZW
9593static void
9594do_rfe (void)
9595{
9596 inst.instruction |= inst.operands[0].reg << 16;
9597 if (inst.operands[0].writeback)
9598 inst.instruction |= WRITE_BACK;
9599}
b99bd4ef 9600
c19d1205 9601/* ARM V6 ssat (argument parse). */
b99bd4ef 9602
c19d1205
ZW
9603static void
9604do_ssat (void)
9605{
9606 inst.instruction |= inst.operands[0].reg << 12;
9607 inst.instruction |= (inst.operands[1].imm - 1) << 16;
9608 inst.instruction |= inst.operands[2].reg;
b99bd4ef 9609
c19d1205
ZW
9610 if (inst.operands[3].present)
9611 encode_arm_shift (3);
b99bd4ef
NC
9612}
9613
c19d1205 9614/* ARM V6 usat (argument parse). */
b99bd4ef
NC
9615
9616static void
c19d1205 9617do_usat (void)
b99bd4ef 9618{
c19d1205
ZW
9619 inst.instruction |= inst.operands[0].reg << 12;
9620 inst.instruction |= inst.operands[1].imm << 16;
9621 inst.instruction |= inst.operands[2].reg;
b99bd4ef 9622
c19d1205
ZW
9623 if (inst.operands[3].present)
9624 encode_arm_shift (3);
b99bd4ef
NC
9625}
9626
c19d1205 9627/* ARM V6 ssat16 (argument parse). */
09d92015
MM
9628
9629static void
c19d1205 9630do_ssat16 (void)
09d92015 9631{
c19d1205
ZW
9632 inst.instruction |= inst.operands[0].reg << 12;
9633 inst.instruction |= ((inst.operands[1].imm - 1) << 16);
9634 inst.instruction |= inst.operands[2].reg;
09d92015
MM
9635}
9636
c19d1205
ZW
9637static void
9638do_usat16 (void)
a737bd4d 9639{
c19d1205
ZW
9640 inst.instruction |= inst.operands[0].reg << 12;
9641 inst.instruction |= inst.operands[1].imm << 16;
9642 inst.instruction |= inst.operands[2].reg;
9643}
a737bd4d 9644
c19d1205
ZW
9645/* ARM V6 SETEND (argument parse). Sets the E bit in the CPSR while
9646 preserving the other bits.
a737bd4d 9647
c19d1205
ZW
9648 setend <endian_specifier>, where <endian_specifier> is either
9649 BE or LE. */
a737bd4d 9650
c19d1205
ZW
9651static void
9652do_setend (void)
9653{
12e37cbc
MGD
9654 if (warn_on_deprecated
9655 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 9656 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 9657
c19d1205
ZW
9658 if (inst.operands[0].imm)
9659 inst.instruction |= 0x200;
a737bd4d
NC
9660}
9661
9662static void
c19d1205 9663do_shift (void)
a737bd4d 9664{
c19d1205
ZW
9665 unsigned int Rm = (inst.operands[1].present
9666 ? inst.operands[1].reg
9667 : inst.operands[0].reg);
a737bd4d 9668
c19d1205
ZW
9669 inst.instruction |= inst.operands[0].reg << 12;
9670 inst.instruction |= Rm;
9671 if (inst.operands[2].isreg) /* Rd, {Rm,} Rs */
a737bd4d 9672 {
c19d1205
ZW
9673 inst.instruction |= inst.operands[2].reg << 8;
9674 inst.instruction |= SHIFT_BY_REG;
94342ec3
NC
9675 /* PR 12854: Error on extraneous shifts. */
9676 constraint (inst.operands[2].shifted,
9677 _("extraneous shift as part of operand to shift insn"));
a737bd4d
NC
9678 }
9679 else
e2b0ab59 9680 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
a737bd4d
NC
9681}
9682
09d92015 9683static void
3eb17e6b 9684do_smc (void)
09d92015 9685{
e2b0ab59
AV
9686 inst.relocs[0].type = BFD_RELOC_ARM_SMC;
9687 inst.relocs[0].pc_rel = 0;
09d92015
MM
9688}
9689
90ec0d68
MGD
9690static void
9691do_hvc (void)
9692{
e2b0ab59
AV
9693 inst.relocs[0].type = BFD_RELOC_ARM_HVC;
9694 inst.relocs[0].pc_rel = 0;
90ec0d68
MGD
9695}
9696
09d92015 9697static void
c19d1205 9698do_swi (void)
09d92015 9699{
e2b0ab59
AV
9700 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
9701 inst.relocs[0].pc_rel = 0;
09d92015
MM
9702}
9703
ddfded2f
MW
9704static void
9705do_setpan (void)
9706{
9707 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
9708 _("selected processor does not support SETPAN instruction"));
9709
9710 inst.instruction |= ((inst.operands[0].imm & 1) << 9);
9711}
9712
9713static void
9714do_t_setpan (void)
9715{
9716 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
9717 _("selected processor does not support SETPAN instruction"));
9718
9719 inst.instruction |= (inst.operands[0].imm << 3);
9720}
9721
c19d1205
ZW
9722/* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
9723 SMLAxy{cond} Rd,Rm,Rs,Rn
9724 SMLAWy{cond} Rd,Rm,Rs,Rn
9725 Error if any register is R15. */
e16bb312 9726
c19d1205
ZW
9727static void
9728do_smla (void)
e16bb312 9729{
c19d1205
ZW
9730 inst.instruction |= inst.operands[0].reg << 16;
9731 inst.instruction |= inst.operands[1].reg;
9732 inst.instruction |= inst.operands[2].reg << 8;
9733 inst.instruction |= inst.operands[3].reg << 12;
9734}
a737bd4d 9735
c19d1205
ZW
9736/* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
9737 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
9738 Error if any register is R15.
9739 Warning if Rdlo == Rdhi. */
a737bd4d 9740
c19d1205
ZW
9741static void
9742do_smlal (void)
9743{
9744 inst.instruction |= inst.operands[0].reg << 12;
9745 inst.instruction |= inst.operands[1].reg << 16;
9746 inst.instruction |= inst.operands[2].reg;
9747 inst.instruction |= inst.operands[3].reg << 8;
a737bd4d 9748
c19d1205
ZW
9749 if (inst.operands[0].reg == inst.operands[1].reg)
9750 as_tsktsk (_("rdhi and rdlo must be different"));
9751}
a737bd4d 9752
c19d1205
ZW
9753/* ARM V5E (El Segundo) signed-multiply (argument parse)
9754 SMULxy{cond} Rd,Rm,Rs
9755 Error if any register is R15. */
a737bd4d 9756
c19d1205
ZW
9757static void
9758do_smul (void)
9759{
9760 inst.instruction |= inst.operands[0].reg << 16;
9761 inst.instruction |= inst.operands[1].reg;
9762 inst.instruction |= inst.operands[2].reg << 8;
9763}
a737bd4d 9764
b6702015
PB
9765/* ARM V6 srs (argument parse). The variable fields in the encoding are
9766 the same for both ARM and Thumb-2. */
a737bd4d 9767
c19d1205
ZW
9768static void
9769do_srs (void)
9770{
b6702015
PB
9771 int reg;
9772
9773 if (inst.operands[0].present)
9774 {
9775 reg = inst.operands[0].reg;
fdfde340 9776 constraint (reg != REG_SP, _("SRS base register must be r13"));
b6702015
PB
9777 }
9778 else
fdfde340 9779 reg = REG_SP;
b6702015
PB
9780
9781 inst.instruction |= reg << 16;
9782 inst.instruction |= inst.operands[1].imm;
9783 if (inst.operands[0].writeback || inst.operands[1].writeback)
c19d1205
ZW
9784 inst.instruction |= WRITE_BACK;
9785}
a737bd4d 9786
c19d1205 9787/* ARM V6 strex (argument parse). */
a737bd4d 9788
c19d1205
ZW
9789static void
9790do_strex (void)
9791{
9792 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
9793 || inst.operands[2].postind || inst.operands[2].writeback
9794 || inst.operands[2].immisreg || inst.operands[2].shifted
01cfc07f
NC
9795 || inst.operands[2].negative
9796 /* See comment in do_ldrex(). */
9797 || (inst.operands[2].reg == REG_PC),
9798 BAD_ADDR_MODE);
a737bd4d 9799
c19d1205
ZW
9800 constraint (inst.operands[0].reg == inst.operands[1].reg
9801 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
a737bd4d 9802
e2b0ab59
AV
9803 constraint (inst.relocs[0].exp.X_op != O_constant
9804 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9805 _("offset must be zero in ARM encoding"));
a737bd4d 9806
c19d1205
ZW
9807 inst.instruction |= inst.operands[0].reg << 12;
9808 inst.instruction |= inst.operands[1].reg;
9809 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 9810 inst.relocs[0].type = BFD_RELOC_UNUSED;
e16bb312
NC
9811}
9812
877807f8
NC
9813static void
9814do_t_strexbh (void)
9815{
9816 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
9817 || inst.operands[2].postind || inst.operands[2].writeback
9818 || inst.operands[2].immisreg || inst.operands[2].shifted
9819 || inst.operands[2].negative,
9820 BAD_ADDR_MODE);
9821
9822 constraint (inst.operands[0].reg == inst.operands[1].reg
9823 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
9824
9825 do_rm_rd_rn ();
9826}
9827
e16bb312 9828static void
c19d1205 9829do_strexd (void)
e16bb312 9830{
c19d1205
ZW
9831 constraint (inst.operands[1].reg % 2 != 0,
9832 _("even register required"));
9833 constraint (inst.operands[2].present
9834 && inst.operands[2].reg != inst.operands[1].reg + 1,
9835 _("can only store two consecutive registers"));
9836 /* If op 2 were present and equal to PC, this function wouldn't
9837 have been called in the first place. */
9838 constraint (inst.operands[1].reg == REG_LR, _("r14 not allowed here"));
e16bb312 9839
c19d1205
ZW
9840 constraint (inst.operands[0].reg == inst.operands[1].reg
9841 || inst.operands[0].reg == inst.operands[1].reg + 1
9842 || inst.operands[0].reg == inst.operands[3].reg,
9843 BAD_OVERLAP);
e16bb312 9844
c19d1205
ZW
9845 inst.instruction |= inst.operands[0].reg << 12;
9846 inst.instruction |= inst.operands[1].reg;
9847 inst.instruction |= inst.operands[3].reg << 16;
e16bb312
NC
9848}
9849
9eb6c0f1
MGD
9850/* ARM V8 STRL. */
9851static void
4b8c8c02 9852do_stlex (void)
9eb6c0f1
MGD
9853{
9854 constraint (inst.operands[0].reg == inst.operands[1].reg
9855 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
9856
9857 do_rd_rm_rn ();
9858}
9859
9860static void
4b8c8c02 9861do_t_stlex (void)
9eb6c0f1
MGD
9862{
9863 constraint (inst.operands[0].reg == inst.operands[1].reg
9864 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
9865
9866 do_rm_rd_rn ();
9867}
9868
c19d1205
ZW
9869/* ARM V6 SXTAH extracts a 16-bit value from a register, sign
9870 extends it to 32-bits, and adds the result to a value in another
9871 register. You can specify a rotation by 0, 8, 16, or 24 bits
9872 before extracting the 16-bit value.
9873 SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
9874 Condition defaults to COND_ALWAYS.
9875 Error if any register uses R15. */
9876
e16bb312 9877static void
c19d1205 9878do_sxtah (void)
e16bb312 9879{
c19d1205
ZW
9880 inst.instruction |= inst.operands[0].reg << 12;
9881 inst.instruction |= inst.operands[1].reg << 16;
9882 inst.instruction |= inst.operands[2].reg;
9883 inst.instruction |= inst.operands[3].imm << 10;
9884}
e16bb312 9885
c19d1205 9886/* ARM V6 SXTH.
e16bb312 9887
c19d1205
ZW
9888 SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
9889 Condition defaults to COND_ALWAYS.
9890 Error if any register uses R15. */
e16bb312
NC
9891
9892static void
c19d1205 9893do_sxth (void)
e16bb312 9894{
c19d1205
ZW
9895 inst.instruction |= inst.operands[0].reg << 12;
9896 inst.instruction |= inst.operands[1].reg;
9897 inst.instruction |= inst.operands[2].imm << 10;
e16bb312 9898}
c19d1205
ZW
9899\f
9900/* VFP instructions. In a logical order: SP variant first, monad
9901 before dyad, arithmetic then move then load/store. */
e16bb312
NC
9902
9903static void
c19d1205 9904do_vfp_sp_monadic (void)
e16bb312 9905{
5287ad62
JB
9906 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
9907 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
9908}
9909
9910static void
c19d1205 9911do_vfp_sp_dyadic (void)
e16bb312 9912{
5287ad62
JB
9913 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
9914 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
9915 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
9916}
9917
9918static void
c19d1205 9919do_vfp_sp_compare_z (void)
e16bb312 9920{
5287ad62 9921 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
e16bb312
NC
9922}
9923
9924static void
c19d1205 9925do_vfp_dp_sp_cvt (void)
e16bb312 9926{
5287ad62
JB
9927 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
9928 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
9929}
9930
9931static void
c19d1205 9932do_vfp_sp_dp_cvt (void)
e16bb312 9933{
5287ad62
JB
9934 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
9935 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
e16bb312
NC
9936}
9937
9938static void
c19d1205 9939do_vfp_reg_from_sp (void)
e16bb312 9940{
c19d1205 9941 inst.instruction |= inst.operands[0].reg << 12;
5287ad62 9942 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
e16bb312
NC
9943}
9944
9945static void
c19d1205 9946do_vfp_reg2_from_sp2 (void)
e16bb312 9947{
c19d1205
ZW
9948 constraint (inst.operands[2].imm != 2,
9949 _("only two consecutive VFP SP registers allowed here"));
9950 inst.instruction |= inst.operands[0].reg << 12;
9951 inst.instruction |= inst.operands[1].reg << 16;
5287ad62 9952 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
9953}
9954
9955static void
c19d1205 9956do_vfp_sp_from_reg (void)
e16bb312 9957{
5287ad62 9958 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sn);
c19d1205 9959 inst.instruction |= inst.operands[1].reg << 12;
e16bb312
NC
9960}
9961
9962static void
c19d1205 9963do_vfp_sp2_from_reg2 (void)
e16bb312 9964{
c19d1205
ZW
9965 constraint (inst.operands[0].imm != 2,
9966 _("only two consecutive VFP SP registers allowed here"));
5287ad62 9967 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sm);
c19d1205
ZW
9968 inst.instruction |= inst.operands[1].reg << 12;
9969 inst.instruction |= inst.operands[2].reg << 16;
e16bb312
NC
9970}
9971
9972static void
c19d1205 9973do_vfp_sp_ldst (void)
e16bb312 9974{
5287ad62 9975 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
c19d1205 9976 encode_arm_cp_address (1, FALSE, TRUE, 0);
e16bb312
NC
9977}
9978
9979static void
c19d1205 9980do_vfp_dp_ldst (void)
e16bb312 9981{
5287ad62 9982 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
c19d1205 9983 encode_arm_cp_address (1, FALSE, TRUE, 0);
e16bb312
NC
9984}
9985
c19d1205 9986
e16bb312 9987static void
c19d1205 9988vfp_sp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 9989{
c19d1205
ZW
9990 if (inst.operands[0].writeback)
9991 inst.instruction |= WRITE_BACK;
9992 else
9993 constraint (ldstm_type != VFP_LDSTMIA,
9994 _("this addressing mode requires base-register writeback"));
9995 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 9996 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sd);
c19d1205 9997 inst.instruction |= inst.operands[1].imm;
e16bb312
NC
9998}
9999
10000static void
c19d1205 10001vfp_dp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 10002{
c19d1205 10003 int count;
e16bb312 10004
c19d1205
ZW
10005 if (inst.operands[0].writeback)
10006 inst.instruction |= WRITE_BACK;
10007 else
10008 constraint (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX,
10009 _("this addressing mode requires base-register writeback"));
e16bb312 10010
c19d1205 10011 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 10012 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
e16bb312 10013
c19d1205
ZW
10014 count = inst.operands[1].imm << 1;
10015 if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
10016 count += 1;
e16bb312 10017
c19d1205 10018 inst.instruction |= count;
e16bb312
NC
10019}
10020
10021static void
c19d1205 10022do_vfp_sp_ldstmia (void)
e16bb312 10023{
c19d1205 10024 vfp_sp_ldstm (VFP_LDSTMIA);
e16bb312
NC
10025}
10026
10027static void
c19d1205 10028do_vfp_sp_ldstmdb (void)
e16bb312 10029{
c19d1205 10030 vfp_sp_ldstm (VFP_LDSTMDB);
e16bb312
NC
10031}
10032
10033static void
c19d1205 10034do_vfp_dp_ldstmia (void)
e16bb312 10035{
c19d1205 10036 vfp_dp_ldstm (VFP_LDSTMIA);
e16bb312
NC
10037}
10038
10039static void
c19d1205 10040do_vfp_dp_ldstmdb (void)
e16bb312 10041{
c19d1205 10042 vfp_dp_ldstm (VFP_LDSTMDB);
e16bb312
NC
10043}
10044
10045static void
c19d1205 10046do_vfp_xp_ldstmia (void)
e16bb312 10047{
c19d1205
ZW
10048 vfp_dp_ldstm (VFP_LDSTMIAX);
10049}
e16bb312 10050
c19d1205
ZW
10051static void
10052do_vfp_xp_ldstmdb (void)
10053{
10054 vfp_dp_ldstm (VFP_LDSTMDBX);
e16bb312 10055}
5287ad62
JB
10056
10057static void
10058do_vfp_dp_rd_rm (void)
10059{
10060 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10061 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
10062}
10063
10064static void
10065do_vfp_dp_rn_rd (void)
10066{
10067 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dn);
10068 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10069}
10070
10071static void
10072do_vfp_dp_rd_rn (void)
10073{
10074 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10075 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10076}
10077
10078static void
10079do_vfp_dp_rd_rn_rm (void)
10080{
10081 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10082 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10083 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dm);
10084}
10085
10086static void
10087do_vfp_dp_rd (void)
10088{
10089 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10090}
10091
10092static void
10093do_vfp_dp_rm_rd_rn (void)
10094{
10095 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dm);
10096 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10097 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dn);
10098}
10099
10100/* VFPv3 instructions. */
10101static void
10102do_vfp_sp_const (void)
10103{
10104 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
00249aaa
PB
10105 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
10106 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
10107}
10108
10109static void
10110do_vfp_dp_const (void)
10111{
10112 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
00249aaa
PB
10113 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
10114 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
10115}
10116
10117static void
10118vfp_conv (int srcsize)
10119{
5f1af56b
MGD
10120 int immbits = srcsize - inst.operands[1].imm;
10121
fa94de6b
RM
10122 if (srcsize == 16 && !(immbits >= 0 && immbits <= srcsize))
10123 {
5f1af56b 10124 /* If srcsize is 16, inst.operands[1].imm must be in the range 0-16.
477330fc 10125 i.e. immbits must be in range 0 - 16. */
5f1af56b
MGD
10126 inst.error = _("immediate value out of range, expected range [0, 16]");
10127 return;
10128 }
fa94de6b 10129 else if (srcsize == 32 && !(immbits >= 0 && immbits < srcsize))
5f1af56b
MGD
10130 {
10131 /* If srcsize is 32, inst.operands[1].imm must be in the range 1-32.
477330fc 10132 i.e. immbits must be in range 0 - 31. */
5f1af56b
MGD
10133 inst.error = _("immediate value out of range, expected range [1, 32]");
10134 return;
10135 }
10136
5287ad62
JB
10137 inst.instruction |= (immbits & 1) << 5;
10138 inst.instruction |= (immbits >> 1);
10139}
10140
10141static void
10142do_vfp_sp_conv_16 (void)
10143{
10144 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10145 vfp_conv (16);
10146}
10147
10148static void
10149do_vfp_dp_conv_16 (void)
10150{
10151 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10152 vfp_conv (16);
10153}
10154
10155static void
10156do_vfp_sp_conv_32 (void)
10157{
10158 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10159 vfp_conv (32);
10160}
10161
10162static void
10163do_vfp_dp_conv_32 (void)
10164{
10165 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10166 vfp_conv (32);
10167}
c19d1205
ZW
10168\f
10169/* FPA instructions. Also in a logical order. */
e16bb312 10170
c19d1205
ZW
10171static void
10172do_fpa_cmp (void)
10173{
10174 inst.instruction |= inst.operands[0].reg << 16;
10175 inst.instruction |= inst.operands[1].reg;
10176}
b99bd4ef
NC
10177
10178static void
c19d1205 10179do_fpa_ldmstm (void)
b99bd4ef 10180{
c19d1205
ZW
10181 inst.instruction |= inst.operands[0].reg << 12;
10182 switch (inst.operands[1].imm)
10183 {
10184 case 1: inst.instruction |= CP_T_X; break;
10185 case 2: inst.instruction |= CP_T_Y; break;
10186 case 3: inst.instruction |= CP_T_Y | CP_T_X; break;
10187 case 4: break;
10188 default: abort ();
10189 }
b99bd4ef 10190
c19d1205
ZW
10191 if (inst.instruction & (PRE_INDEX | INDEX_UP))
10192 {
10193 /* The instruction specified "ea" or "fd", so we can only accept
10194 [Rn]{!}. The instruction does not really support stacking or
10195 unstacking, so we have to emulate these by setting appropriate
10196 bits and offsets. */
e2b0ab59
AV
10197 constraint (inst.relocs[0].exp.X_op != O_constant
10198 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 10199 _("this instruction does not support indexing"));
b99bd4ef 10200
c19d1205 10201 if ((inst.instruction & PRE_INDEX) || inst.operands[2].writeback)
e2b0ab59 10202 inst.relocs[0].exp.X_add_number = 12 * inst.operands[1].imm;
b99bd4ef 10203
c19d1205 10204 if (!(inst.instruction & INDEX_UP))
e2b0ab59 10205 inst.relocs[0].exp.X_add_number = -inst.relocs[0].exp.X_add_number;
b99bd4ef 10206
c19d1205
ZW
10207 if (!(inst.instruction & PRE_INDEX) && inst.operands[2].writeback)
10208 {
10209 inst.operands[2].preind = 0;
10210 inst.operands[2].postind = 1;
10211 }
10212 }
b99bd4ef 10213
c19d1205 10214 encode_arm_cp_address (2, TRUE, TRUE, 0);
b99bd4ef 10215}
c19d1205
ZW
10216\f
10217/* iWMMXt instructions: strictly in alphabetical order. */
b99bd4ef 10218
c19d1205
ZW
10219static void
10220do_iwmmxt_tandorc (void)
10221{
10222 constraint (inst.operands[0].reg != REG_PC, _("only r15 allowed here"));
10223}
b99bd4ef 10224
c19d1205
ZW
10225static void
10226do_iwmmxt_textrc (void)
10227{
10228 inst.instruction |= inst.operands[0].reg << 12;
10229 inst.instruction |= inst.operands[1].imm;
10230}
b99bd4ef
NC
10231
10232static void
c19d1205 10233do_iwmmxt_textrm (void)
b99bd4ef 10234{
c19d1205
ZW
10235 inst.instruction |= inst.operands[0].reg << 12;
10236 inst.instruction |= inst.operands[1].reg << 16;
10237 inst.instruction |= inst.operands[2].imm;
10238}
b99bd4ef 10239
c19d1205
ZW
10240static void
10241do_iwmmxt_tinsr (void)
10242{
10243 inst.instruction |= inst.operands[0].reg << 16;
10244 inst.instruction |= inst.operands[1].reg << 12;
10245 inst.instruction |= inst.operands[2].imm;
10246}
b99bd4ef 10247
c19d1205
ZW
10248static void
10249do_iwmmxt_tmia (void)
10250{
10251 inst.instruction |= inst.operands[0].reg << 5;
10252 inst.instruction |= inst.operands[1].reg;
10253 inst.instruction |= inst.operands[2].reg << 12;
10254}
b99bd4ef 10255
c19d1205
ZW
10256static void
10257do_iwmmxt_waligni (void)
10258{
10259 inst.instruction |= inst.operands[0].reg << 12;
10260 inst.instruction |= inst.operands[1].reg << 16;
10261 inst.instruction |= inst.operands[2].reg;
10262 inst.instruction |= inst.operands[3].imm << 20;
10263}
b99bd4ef 10264
2d447fca
JM
10265static void
10266do_iwmmxt_wmerge (void)
10267{
10268 inst.instruction |= inst.operands[0].reg << 12;
10269 inst.instruction |= inst.operands[1].reg << 16;
10270 inst.instruction |= inst.operands[2].reg;
10271 inst.instruction |= inst.operands[3].imm << 21;
10272}
10273
c19d1205
ZW
10274static void
10275do_iwmmxt_wmov (void)
10276{
10277 /* WMOV rD, rN is an alias for WOR rD, rN, rN. */
10278 inst.instruction |= inst.operands[0].reg << 12;
10279 inst.instruction |= inst.operands[1].reg << 16;
10280 inst.instruction |= inst.operands[1].reg;
10281}
b99bd4ef 10282
c19d1205
ZW
10283static void
10284do_iwmmxt_wldstbh (void)
10285{
8f06b2d8 10286 int reloc;
c19d1205 10287 inst.instruction |= inst.operands[0].reg << 12;
8f06b2d8
PB
10288 if (thumb_mode)
10289 reloc = BFD_RELOC_ARM_T32_CP_OFF_IMM_S2;
10290 else
10291 reloc = BFD_RELOC_ARM_CP_OFF_IMM_S2;
10292 encode_arm_cp_address (1, TRUE, FALSE, reloc);
b99bd4ef
NC
10293}
10294
c19d1205
ZW
10295static void
10296do_iwmmxt_wldstw (void)
10297{
10298 /* RIWR_RIWC clears .isreg for a control register. */
10299 if (!inst.operands[0].isreg)
10300 {
10301 constraint (inst.cond != COND_ALWAYS, BAD_COND);
10302 inst.instruction |= 0xf0000000;
10303 }
b99bd4ef 10304
c19d1205
ZW
10305 inst.instruction |= inst.operands[0].reg << 12;
10306 encode_arm_cp_address (1, TRUE, TRUE, 0);
10307}
b99bd4ef
NC
10308
10309static void
c19d1205 10310do_iwmmxt_wldstd (void)
b99bd4ef 10311{
c19d1205 10312 inst.instruction |= inst.operands[0].reg << 12;
2d447fca
JM
10313 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2)
10314 && inst.operands[1].immisreg)
10315 {
10316 inst.instruction &= ~0x1a000ff;
eff0bc54 10317 inst.instruction |= (0xfU << 28);
2d447fca
JM
10318 if (inst.operands[1].preind)
10319 inst.instruction |= PRE_INDEX;
10320 if (!inst.operands[1].negative)
10321 inst.instruction |= INDEX_UP;
10322 if (inst.operands[1].writeback)
10323 inst.instruction |= WRITE_BACK;
10324 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 10325 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
2d447fca
JM
10326 inst.instruction |= inst.operands[1].imm;
10327 }
10328 else
10329 encode_arm_cp_address (1, TRUE, FALSE, 0);
c19d1205 10330}
b99bd4ef 10331
c19d1205
ZW
10332static void
10333do_iwmmxt_wshufh (void)
10334{
10335 inst.instruction |= inst.operands[0].reg << 12;
10336 inst.instruction |= inst.operands[1].reg << 16;
10337 inst.instruction |= ((inst.operands[2].imm & 0xf0) << 16);
10338 inst.instruction |= (inst.operands[2].imm & 0x0f);
10339}
b99bd4ef 10340
c19d1205
ZW
10341static void
10342do_iwmmxt_wzero (void)
10343{
10344 /* WZERO reg is an alias for WANDN reg, reg, reg. */
10345 inst.instruction |= inst.operands[0].reg;
10346 inst.instruction |= inst.operands[0].reg << 12;
10347 inst.instruction |= inst.operands[0].reg << 16;
10348}
2d447fca
JM
10349
10350static void
10351do_iwmmxt_wrwrwr_or_imm5 (void)
10352{
10353 if (inst.operands[2].isreg)
10354 do_rd_rn_rm ();
10355 else {
10356 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2),
10357 _("immediate operand requires iWMMXt2"));
10358 do_rd_rn ();
10359 if (inst.operands[2].imm == 0)
10360 {
10361 switch ((inst.instruction >> 20) & 0xf)
10362 {
10363 case 4:
10364 case 5:
10365 case 6:
5f4273c7 10366 case 7:
2d447fca
JM
10367 /* w...h wrd, wrn, #0 -> wrorh wrd, wrn, #16. */
10368 inst.operands[2].imm = 16;
10369 inst.instruction = (inst.instruction & 0xff0fffff) | (0x7 << 20);
10370 break;
10371 case 8:
10372 case 9:
10373 case 10:
10374 case 11:
10375 /* w...w wrd, wrn, #0 -> wrorw wrd, wrn, #32. */
10376 inst.operands[2].imm = 32;
10377 inst.instruction = (inst.instruction & 0xff0fffff) | (0xb << 20);
10378 break;
10379 case 12:
10380 case 13:
10381 case 14:
10382 case 15:
10383 {
10384 /* w...d wrd, wrn, #0 -> wor wrd, wrn, wrn. */
10385 unsigned long wrn;
10386 wrn = (inst.instruction >> 16) & 0xf;
10387 inst.instruction &= 0xff0fff0f;
10388 inst.instruction |= wrn;
10389 /* Bail out here; the instruction is now assembled. */
10390 return;
10391 }
10392 }
10393 }
10394 /* Map 32 -> 0, etc. */
10395 inst.operands[2].imm &= 0x1f;
eff0bc54 10396 inst.instruction |= (0xfU << 28) | ((inst.operands[2].imm & 0x10) << 4) | (inst.operands[2].imm & 0xf);
2d447fca
JM
10397 }
10398}
c19d1205
ZW
10399\f
10400/* Cirrus Maverick instructions. Simple 2-, 3-, and 4-register
10401 operations first, then control, shift, and load/store. */
b99bd4ef 10402
c19d1205 10403/* Insns like "foo X,Y,Z". */
b99bd4ef 10404
c19d1205
ZW
10405static void
10406do_mav_triple (void)
10407{
10408 inst.instruction |= inst.operands[0].reg << 16;
10409 inst.instruction |= inst.operands[1].reg;
10410 inst.instruction |= inst.operands[2].reg << 12;
10411}
b99bd4ef 10412
c19d1205
ZW
10413/* Insns like "foo W,X,Y,Z".
10414 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
a737bd4d 10415
c19d1205
ZW
10416static void
10417do_mav_quad (void)
10418{
10419 inst.instruction |= inst.operands[0].reg << 5;
10420 inst.instruction |= inst.operands[1].reg << 12;
10421 inst.instruction |= inst.operands[2].reg << 16;
10422 inst.instruction |= inst.operands[3].reg;
a737bd4d
NC
10423}
10424
c19d1205
ZW
10425/* cfmvsc32<cond> DSPSC,MVDX[15:0]. */
10426static void
10427do_mav_dspsc (void)
a737bd4d 10428{
c19d1205
ZW
10429 inst.instruction |= inst.operands[1].reg << 12;
10430}
a737bd4d 10431
c19d1205
ZW
10432/* Maverick shift immediate instructions.
10433 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
10434 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
a737bd4d 10435
c19d1205
ZW
10436static void
10437do_mav_shift (void)
10438{
10439 int imm = inst.operands[2].imm;
a737bd4d 10440
c19d1205
ZW
10441 inst.instruction |= inst.operands[0].reg << 12;
10442 inst.instruction |= inst.operands[1].reg << 16;
a737bd4d 10443
c19d1205
ZW
10444 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
10445 Bits 5-7 of the insn should have bits 4-6 of the immediate.
10446 Bit 4 should be 0. */
10447 imm = (imm & 0xf) | ((imm & 0x70) << 1);
a737bd4d 10448
c19d1205
ZW
10449 inst.instruction |= imm;
10450}
10451\f
10452/* XScale instructions. Also sorted arithmetic before move. */
a737bd4d 10453
c19d1205
ZW
10454/* Xscale multiply-accumulate (argument parse)
10455 MIAcc acc0,Rm,Rs
10456 MIAPHcc acc0,Rm,Rs
10457 MIAxycc acc0,Rm,Rs. */
a737bd4d 10458
c19d1205
ZW
10459static void
10460do_xsc_mia (void)
10461{
10462 inst.instruction |= inst.operands[1].reg;
10463 inst.instruction |= inst.operands[2].reg << 12;
10464}
a737bd4d 10465
c19d1205 10466/* Xscale move-accumulator-register (argument parse)
a737bd4d 10467
c19d1205 10468 MARcc acc0,RdLo,RdHi. */
b99bd4ef 10469
c19d1205
ZW
10470static void
10471do_xsc_mar (void)
10472{
10473 inst.instruction |= inst.operands[1].reg << 12;
10474 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
10475}
10476
c19d1205 10477/* Xscale move-register-accumulator (argument parse)
b99bd4ef 10478
c19d1205 10479 MRAcc RdLo,RdHi,acc0. */
b99bd4ef
NC
10480
10481static void
c19d1205 10482do_xsc_mra (void)
b99bd4ef 10483{
c19d1205
ZW
10484 constraint (inst.operands[0].reg == inst.operands[1].reg, BAD_OVERLAP);
10485 inst.instruction |= inst.operands[0].reg << 12;
10486 inst.instruction |= inst.operands[1].reg << 16;
10487}
10488\f
10489/* Encoding functions relevant only to Thumb. */
b99bd4ef 10490
c19d1205
ZW
10491/* inst.operands[i] is a shifted-register operand; encode
10492 it into inst.instruction in the format used by Thumb32. */
10493
10494static void
10495encode_thumb32_shifted_operand (int i)
10496{
e2b0ab59 10497 unsigned int value = inst.relocs[0].exp.X_add_number;
c19d1205 10498 unsigned int shift = inst.operands[i].shift_kind;
b99bd4ef 10499
9c3c69f2
PB
10500 constraint (inst.operands[i].immisreg,
10501 _("shift by register not allowed in thumb mode"));
c19d1205
ZW
10502 inst.instruction |= inst.operands[i].reg;
10503 if (shift == SHIFT_RRX)
10504 inst.instruction |= SHIFT_ROR << 4;
10505 else
b99bd4ef 10506 {
e2b0ab59 10507 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
10508 _("expression too complex"));
10509
10510 constraint (value > 32
10511 || (value == 32 && (shift == SHIFT_LSL
10512 || shift == SHIFT_ROR)),
10513 _("shift expression is too large"));
10514
10515 if (value == 0)
10516 shift = SHIFT_LSL;
10517 else if (value == 32)
10518 value = 0;
10519
10520 inst.instruction |= shift << 4;
10521 inst.instruction |= (value & 0x1c) << 10;
10522 inst.instruction |= (value & 0x03) << 6;
b99bd4ef 10523 }
c19d1205 10524}
b99bd4ef 10525
b99bd4ef 10526
c19d1205
ZW
10527/* inst.operands[i] was set up by parse_address. Encode it into a
10528 Thumb32 format load or store instruction. Reject forms that cannot
10529 be used with such instructions. If is_t is true, reject forms that
10530 cannot be used with a T instruction; if is_d is true, reject forms
5be8be5d
DG
10531 that cannot be used with a D instruction. If it is a store insn,
10532 reject PC in Rn. */
b99bd4ef 10533
c19d1205
ZW
10534static void
10535encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
10536{
5be8be5d 10537 const bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
c19d1205
ZW
10538
10539 constraint (!inst.operands[i].isreg,
53365c0d 10540 _("Instruction does not support =N addresses"));
b99bd4ef 10541
c19d1205
ZW
10542 inst.instruction |= inst.operands[i].reg << 16;
10543 if (inst.operands[i].immisreg)
b99bd4ef 10544 {
5be8be5d 10545 constraint (is_pc, BAD_PC_ADDRESSING);
c19d1205
ZW
10546 constraint (is_t || is_d, _("cannot use register index with this instruction"));
10547 constraint (inst.operands[i].negative,
10548 _("Thumb does not support negative register indexing"));
10549 constraint (inst.operands[i].postind,
10550 _("Thumb does not support register post-indexing"));
10551 constraint (inst.operands[i].writeback,
10552 _("Thumb does not support register indexing with writeback"));
10553 constraint (inst.operands[i].shifted && inst.operands[i].shift_kind != SHIFT_LSL,
10554 _("Thumb supports only LSL in shifted register indexing"));
b99bd4ef 10555
f40d1643 10556 inst.instruction |= inst.operands[i].imm;
c19d1205 10557 if (inst.operands[i].shifted)
b99bd4ef 10558 {
e2b0ab59 10559 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 10560 _("expression too complex"));
e2b0ab59
AV
10561 constraint (inst.relocs[0].exp.X_add_number < 0
10562 || inst.relocs[0].exp.X_add_number > 3,
c19d1205 10563 _("shift out of range"));
e2b0ab59 10564 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
c19d1205 10565 }
e2b0ab59 10566 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205
ZW
10567 }
10568 else if (inst.operands[i].preind)
10569 {
5be8be5d 10570 constraint (is_pc && inst.operands[i].writeback, BAD_PC_WRITEBACK);
f40d1643 10571 constraint (is_t && inst.operands[i].writeback,
c19d1205 10572 _("cannot use writeback with this instruction"));
4755303e
WN
10573 constraint (is_pc && ((inst.instruction & THUMB2_LOAD_BIT) == 0),
10574 BAD_PC_ADDRESSING);
c19d1205
ZW
10575
10576 if (is_d)
10577 {
10578 inst.instruction |= 0x01000000;
10579 if (inst.operands[i].writeback)
10580 inst.instruction |= 0x00200000;
b99bd4ef 10581 }
c19d1205 10582 else
b99bd4ef 10583 {
c19d1205
ZW
10584 inst.instruction |= 0x00000c00;
10585 if (inst.operands[i].writeback)
10586 inst.instruction |= 0x00000100;
b99bd4ef 10587 }
e2b0ab59 10588 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
b99bd4ef 10589 }
c19d1205 10590 else if (inst.operands[i].postind)
b99bd4ef 10591 {
9c2799c2 10592 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
10593 constraint (is_pc, _("cannot use post-indexing with PC-relative addressing"));
10594 constraint (is_t, _("cannot use post-indexing with this instruction"));
10595
10596 if (is_d)
10597 inst.instruction |= 0x00200000;
10598 else
10599 inst.instruction |= 0x00000900;
e2b0ab59 10600 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
c19d1205
ZW
10601 }
10602 else /* unindexed - only for coprocessor */
10603 inst.error = _("instruction does not accept unindexed addressing");
10604}
10605
10606/* Table of Thumb instructions which exist in both 16- and 32-bit
10607 encodings (the latter only in post-V6T2 cores). The index is the
10608 value used in the insns table below. When there is more than one
10609 possible 16-bit encoding for the instruction, this table always
0110f2b8
PB
10610 holds variant (1).
10611 Also contains several pseudo-instructions used during relaxation. */
c19d1205 10612#define T16_32_TAB \
21d799b5
NC
10613 X(_adc, 4140, eb400000), \
10614 X(_adcs, 4140, eb500000), \
10615 X(_add, 1c00, eb000000), \
10616 X(_adds, 1c00, eb100000), \
10617 X(_addi, 0000, f1000000), \
10618 X(_addis, 0000, f1100000), \
10619 X(_add_pc,000f, f20f0000), \
10620 X(_add_sp,000d, f10d0000), \
10621 X(_adr, 000f, f20f0000), \
10622 X(_and, 4000, ea000000), \
10623 X(_ands, 4000, ea100000), \
10624 X(_asr, 1000, fa40f000), \
10625 X(_asrs, 1000, fa50f000), \
10626 X(_b, e000, f000b000), \
10627 X(_bcond, d000, f0008000), \
4389b29a 10628 X(_bf, 0000, f040e001), \
f6b2b12d 10629 X(_bfcsel,0000, f000e001), \
f1c7f421 10630 X(_bfx, 0000, f060e001), \
65d1bc05 10631 X(_bfl, 0000, f000c001), \
f1c7f421 10632 X(_bflx, 0000, f070e001), \
21d799b5
NC
10633 X(_bic, 4380, ea200000), \
10634 X(_bics, 4380, ea300000), \
10635 X(_cmn, 42c0, eb100f00), \
10636 X(_cmp, 2800, ebb00f00), \
10637 X(_cpsie, b660, f3af8400), \
10638 X(_cpsid, b670, f3af8600), \
10639 X(_cpy, 4600, ea4f0000), \
10640 X(_dec_sp,80dd, f1ad0d00), \
60f993ce 10641 X(_dls, 0000, f040e001), \
21d799b5
NC
10642 X(_eor, 4040, ea800000), \
10643 X(_eors, 4040, ea900000), \
10644 X(_inc_sp,00dd, f10d0d00), \
10645 X(_ldmia, c800, e8900000), \
10646 X(_ldr, 6800, f8500000), \
10647 X(_ldrb, 7800, f8100000), \
10648 X(_ldrh, 8800, f8300000), \
10649 X(_ldrsb, 5600, f9100000), \
10650 X(_ldrsh, 5e00, f9300000), \
10651 X(_ldr_pc,4800, f85f0000), \
10652 X(_ldr_pc2,4800, f85f0000), \
10653 X(_ldr_sp,9800, f85d0000), \
60f993ce 10654 X(_le, 0000, f00fc001), \
21d799b5
NC
10655 X(_lsl, 0000, fa00f000), \
10656 X(_lsls, 0000, fa10f000), \
10657 X(_lsr, 0800, fa20f000), \
10658 X(_lsrs, 0800, fa30f000), \
10659 X(_mov, 2000, ea4f0000), \
10660 X(_movs, 2000, ea5f0000), \
10661 X(_mul, 4340, fb00f000), \
10662 X(_muls, 4340, ffffffff), /* no 32b muls */ \
10663 X(_mvn, 43c0, ea6f0000), \
10664 X(_mvns, 43c0, ea7f0000), \
10665 X(_neg, 4240, f1c00000), /* rsb #0 */ \
10666 X(_negs, 4240, f1d00000), /* rsbs #0 */ \
10667 X(_orr, 4300, ea400000), \
10668 X(_orrs, 4300, ea500000), \
10669 X(_pop, bc00, e8bd0000), /* ldmia sp!,... */ \
10670 X(_push, b400, e92d0000), /* stmdb sp!,... */ \
10671 X(_rev, ba00, fa90f080), \
10672 X(_rev16, ba40, fa90f090), \
10673 X(_revsh, bac0, fa90f0b0), \
10674 X(_ror, 41c0, fa60f000), \
10675 X(_rors, 41c0, fa70f000), \
10676 X(_sbc, 4180, eb600000), \
10677 X(_sbcs, 4180, eb700000), \
10678 X(_stmia, c000, e8800000), \
10679 X(_str, 6000, f8400000), \
10680 X(_strb, 7000, f8000000), \
10681 X(_strh, 8000, f8200000), \
10682 X(_str_sp,9000, f84d0000), \
10683 X(_sub, 1e00, eba00000), \
10684 X(_subs, 1e00, ebb00000), \
10685 X(_subi, 8000, f1a00000), \
10686 X(_subis, 8000, f1b00000), \
10687 X(_sxtb, b240, fa4ff080), \
10688 X(_sxth, b200, fa0ff080), \
10689 X(_tst, 4200, ea100f00), \
10690 X(_uxtb, b2c0, fa5ff080), \
10691 X(_uxth, b280, fa1ff080), \
10692 X(_nop, bf00, f3af8000), \
10693 X(_yield, bf10, f3af8001), \
10694 X(_wfe, bf20, f3af8002), \
10695 X(_wfi, bf30, f3af8003), \
60f993ce 10696 X(_wls, 0000, f040c001), \
53c4b28b 10697 X(_sev, bf40, f3af8004), \
74db7efb
NC
10698 X(_sevl, bf50, f3af8005), \
10699 X(_udf, de00, f7f0a000)
c19d1205
ZW
10700
10701/* To catch errors in encoding functions, the codes are all offset by
10702 0xF800, putting them in one of the 32-bit prefix ranges, ergo undefined
10703 as 16-bit instructions. */
21d799b5 10704#define X(a,b,c) T_MNEM##a
c19d1205
ZW
10705enum t16_32_codes { T16_32_OFFSET = 0xF7FF, T16_32_TAB };
10706#undef X
10707
10708#define X(a,b,c) 0x##b
10709static const unsigned short thumb_op16[] = { T16_32_TAB };
10710#define THUMB_OP16(n) (thumb_op16[(n) - (T16_32_OFFSET + 1)])
10711#undef X
10712
10713#define X(a,b,c) 0x##c
10714static const unsigned int thumb_op32[] = { T16_32_TAB };
c921be7d
NC
10715#define THUMB_OP32(n) (thumb_op32[(n) - (T16_32_OFFSET + 1)])
10716#define THUMB_SETS_FLAGS(n) (THUMB_OP32 (n) & 0x00100000)
c19d1205
ZW
10717#undef X
10718#undef T16_32_TAB
10719
10720/* Thumb instruction encoders, in alphabetical order. */
10721
92e90b6e 10722/* ADDW or SUBW. */
c921be7d 10723
92e90b6e
PB
10724static void
10725do_t_add_sub_w (void)
10726{
10727 int Rd, Rn;
10728
10729 Rd = inst.operands[0].reg;
10730 Rn = inst.operands[1].reg;
10731
539d4391
NC
10732 /* If Rn is REG_PC, this is ADR; if Rn is REG_SP, then this
10733 is the SP-{plus,minus}-immediate form of the instruction. */
10734 if (Rn == REG_SP)
10735 constraint (Rd == REG_PC, BAD_PC);
10736 else
10737 reject_bad_reg (Rd);
fdfde340 10738
92e90b6e 10739 inst.instruction |= (Rn << 16) | (Rd << 8);
e2b0ab59 10740 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
92e90b6e
PB
10741}
10742
c19d1205 10743/* Parse an add or subtract instruction. We get here with inst.instruction
33eaf5de 10744 equaling any of THUMB_OPCODE_add, adds, sub, or subs. */
c19d1205
ZW
10745
10746static void
10747do_t_add_sub (void)
10748{
10749 int Rd, Rs, Rn;
10750
10751 Rd = inst.operands[0].reg;
10752 Rs = (inst.operands[1].present
10753 ? inst.operands[1].reg /* Rd, Rs, foo */
10754 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
10755
e07e6e58
NC
10756 if (Rd == REG_PC)
10757 set_it_insn_type_last ();
10758
c19d1205
ZW
10759 if (unified_syntax)
10760 {
0110f2b8
PB
10761 bfd_boolean flags;
10762 bfd_boolean narrow;
10763 int opcode;
10764
10765 flags = (inst.instruction == T_MNEM_adds
10766 || inst.instruction == T_MNEM_subs);
10767 if (flags)
e07e6e58 10768 narrow = !in_it_block ();
0110f2b8 10769 else
e07e6e58 10770 narrow = in_it_block ();
c19d1205 10771 if (!inst.operands[2].isreg)
b99bd4ef 10772 {
16805f35
PB
10773 int add;
10774
5c8ed6a4
JW
10775 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
10776 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340 10777
16805f35
PB
10778 add = (inst.instruction == T_MNEM_add
10779 || inst.instruction == T_MNEM_adds);
0110f2b8
PB
10780 opcode = 0;
10781 if (inst.size_req != 4)
10782 {
0110f2b8 10783 /* Attempt to use a narrow opcode, with relaxation if
477330fc 10784 appropriate. */
0110f2b8
PB
10785 if (Rd == REG_SP && Rs == REG_SP && !flags)
10786 opcode = add ? T_MNEM_inc_sp : T_MNEM_dec_sp;
10787 else if (Rd <= 7 && Rs == REG_SP && add && !flags)
10788 opcode = T_MNEM_add_sp;
10789 else if (Rd <= 7 && Rs == REG_PC && add && !flags)
10790 opcode = T_MNEM_add_pc;
10791 else if (Rd <= 7 && Rs <= 7 && narrow)
10792 {
10793 if (flags)
10794 opcode = add ? T_MNEM_addis : T_MNEM_subis;
10795 else
10796 opcode = add ? T_MNEM_addi : T_MNEM_subi;
10797 }
10798 if (opcode)
10799 {
10800 inst.instruction = THUMB_OP16(opcode);
10801 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59
AV
10802 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
10803 || (inst.relocs[0].type
10804 > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC))
a9f02af8
MG
10805 {
10806 if (inst.size_req == 2)
e2b0ab59 10807 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
a9f02af8
MG
10808 else
10809 inst.relax = opcode;
10810 }
0110f2b8
PB
10811 }
10812 else
10813 constraint (inst.size_req == 2, BAD_HIREG);
10814 }
10815 if (inst.size_req == 4
10816 || (inst.size_req != 2 && !opcode))
10817 {
e2b0ab59
AV
10818 constraint ((inst.relocs[0].type
10819 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
10820 && (inst.relocs[0].type
10821 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8 10822 THUMB1_RELOC_ONLY);
efd81785
PB
10823 if (Rd == REG_PC)
10824 {
fdfde340 10825 constraint (add, BAD_PC);
efd81785
PB
10826 constraint (Rs != REG_LR || inst.instruction != T_MNEM_subs,
10827 _("only SUBS PC, LR, #const allowed"));
e2b0ab59 10828 constraint (inst.relocs[0].exp.X_op != O_constant,
efd81785 10829 _("expression too complex"));
e2b0ab59
AV
10830 constraint (inst.relocs[0].exp.X_add_number < 0
10831 || inst.relocs[0].exp.X_add_number > 0xff,
efd81785
PB
10832 _("immediate value out of range"));
10833 inst.instruction = T2_SUBS_PC_LR
e2b0ab59
AV
10834 | inst.relocs[0].exp.X_add_number;
10835 inst.relocs[0].type = BFD_RELOC_UNUSED;
efd81785
PB
10836 return;
10837 }
10838 else if (Rs == REG_PC)
16805f35
PB
10839 {
10840 /* Always use addw/subw. */
10841 inst.instruction = add ? 0xf20f0000 : 0xf2af0000;
e2b0ab59 10842 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
16805f35
PB
10843 }
10844 else
10845 {
10846 inst.instruction = THUMB_OP32 (inst.instruction);
10847 inst.instruction = (inst.instruction & 0xe1ffffff)
10848 | 0x10000000;
10849 if (flags)
e2b0ab59 10850 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
16805f35 10851 else
e2b0ab59 10852 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_IMM;
16805f35 10853 }
dc4503c6
PB
10854 inst.instruction |= Rd << 8;
10855 inst.instruction |= Rs << 16;
0110f2b8 10856 }
b99bd4ef 10857 }
c19d1205
ZW
10858 else
10859 {
e2b0ab59 10860 unsigned int value = inst.relocs[0].exp.X_add_number;
5f4cb198
NC
10861 unsigned int shift = inst.operands[2].shift_kind;
10862
c19d1205
ZW
10863 Rn = inst.operands[2].reg;
10864 /* See if we can do this with a 16-bit instruction. */
10865 if (!inst.operands[2].shifted && inst.size_req != 4)
10866 {
e27ec89e
PB
10867 if (Rd > 7 || Rs > 7 || Rn > 7)
10868 narrow = FALSE;
10869
10870 if (narrow)
c19d1205 10871 {
e27ec89e
PB
10872 inst.instruction = ((inst.instruction == T_MNEM_adds
10873 || inst.instruction == T_MNEM_add)
c19d1205
ZW
10874 ? T_OPCODE_ADD_R3
10875 : T_OPCODE_SUB_R3);
10876 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
10877 return;
10878 }
b99bd4ef 10879
7e806470 10880 if (inst.instruction == T_MNEM_add && (Rd == Rs || Rd == Rn))
c19d1205 10881 {
7e806470
PB
10882 /* Thumb-1 cores (except v6-M) require at least one high
10883 register in a narrow non flag setting add. */
10884 if (Rd > 7 || Rn > 7
10885 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2)
10886 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_msr))
c19d1205 10887 {
7e806470
PB
10888 if (Rd == Rn)
10889 {
10890 Rn = Rs;
10891 Rs = Rd;
10892 }
c19d1205
ZW
10893 inst.instruction = T_OPCODE_ADD_HI;
10894 inst.instruction |= (Rd & 8) << 4;
10895 inst.instruction |= (Rd & 7);
10896 inst.instruction |= Rn << 3;
10897 return;
10898 }
c19d1205
ZW
10899 }
10900 }
c921be7d 10901
fdfde340 10902 constraint (Rd == REG_PC, BAD_PC);
5c8ed6a4
JW
10903 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
10904 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340
JM
10905 constraint (Rs == REG_PC, BAD_PC);
10906 reject_bad_reg (Rn);
10907
c19d1205
ZW
10908 /* If we get here, it can't be done in 16 bits. */
10909 constraint (inst.operands[2].shifted && inst.operands[2].immisreg,
10910 _("shift must be constant"));
10911 inst.instruction = THUMB_OP32 (inst.instruction);
10912 inst.instruction |= Rd << 8;
10913 inst.instruction |= Rs << 16;
5f4cb198
NC
10914 constraint (Rd == REG_SP && Rs == REG_SP && value > 3,
10915 _("shift value over 3 not allowed in thumb mode"));
10916 constraint (Rd == REG_SP && Rs == REG_SP && shift != SHIFT_LSL,
10917 _("only LSL shift allowed in thumb mode"));
c19d1205
ZW
10918 encode_thumb32_shifted_operand (2);
10919 }
10920 }
10921 else
10922 {
10923 constraint (inst.instruction == T_MNEM_adds
10924 || inst.instruction == T_MNEM_subs,
10925 BAD_THUMB32);
b99bd4ef 10926
c19d1205 10927 if (!inst.operands[2].isreg) /* Rd, Rs, #imm */
b99bd4ef 10928 {
c19d1205
ZW
10929 constraint ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
10930 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC),
10931 BAD_HIREG);
10932
10933 inst.instruction = (inst.instruction == T_MNEM_add
10934 ? 0x0000 : 0x8000);
10935 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59 10936 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
b99bd4ef
NC
10937 return;
10938 }
10939
c19d1205
ZW
10940 Rn = inst.operands[2].reg;
10941 constraint (inst.operands[2].shifted, _("unshifted register required"));
b99bd4ef 10942
c19d1205
ZW
10943 /* We now have Rd, Rs, and Rn set to registers. */
10944 if (Rd > 7 || Rs > 7 || Rn > 7)
b99bd4ef 10945 {
c19d1205
ZW
10946 /* Can't do this for SUB. */
10947 constraint (inst.instruction == T_MNEM_sub, BAD_HIREG);
10948 inst.instruction = T_OPCODE_ADD_HI;
10949 inst.instruction |= (Rd & 8) << 4;
10950 inst.instruction |= (Rd & 7);
10951 if (Rs == Rd)
10952 inst.instruction |= Rn << 3;
10953 else if (Rn == Rd)
10954 inst.instruction |= Rs << 3;
10955 else
10956 constraint (1, _("dest must overlap one source register"));
10957 }
10958 else
10959 {
10960 inst.instruction = (inst.instruction == T_MNEM_add
10961 ? T_OPCODE_ADD_R3 : T_OPCODE_SUB_R3);
10962 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
b99bd4ef 10963 }
b99bd4ef 10964 }
b99bd4ef
NC
10965}
10966
c19d1205
ZW
10967static void
10968do_t_adr (void)
10969{
fdfde340
JM
10970 unsigned Rd;
10971
10972 Rd = inst.operands[0].reg;
10973 reject_bad_reg (Rd);
10974
10975 if (unified_syntax && inst.size_req == 0 && Rd <= 7)
0110f2b8
PB
10976 {
10977 /* Defer to section relaxation. */
10978 inst.relax = inst.instruction;
10979 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 10980 inst.instruction |= Rd << 4;
0110f2b8
PB
10981 }
10982 else if (unified_syntax && inst.size_req != 2)
e9f89963 10983 {
0110f2b8 10984 /* Generate a 32-bit opcode. */
e9f89963 10985 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 10986 inst.instruction |= Rd << 8;
e2b0ab59
AV
10987 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_PC12;
10988 inst.relocs[0].pc_rel = 1;
e9f89963
PB
10989 }
10990 else
10991 {
0110f2b8 10992 /* Generate a 16-bit opcode. */
e9f89963 10993 inst.instruction = THUMB_OP16 (inst.instruction);
e2b0ab59
AV
10994 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
10995 inst.relocs[0].exp.X_add_number -= 4; /* PC relative adjust. */
10996 inst.relocs[0].pc_rel = 1;
fdfde340 10997 inst.instruction |= Rd << 4;
e9f89963 10998 }
52a86f84 10999
e2b0ab59
AV
11000 if (inst.relocs[0].exp.X_op == O_symbol
11001 && inst.relocs[0].exp.X_add_symbol != NULL
11002 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
11003 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
11004 inst.relocs[0].exp.X_add_number += 1;
c19d1205 11005}
b99bd4ef 11006
c19d1205
ZW
11007/* Arithmetic instructions for which there is just one 16-bit
11008 instruction encoding, and it allows only two low registers.
11009 For maximal compatibility with ARM syntax, we allow three register
11010 operands even when Thumb-32 instructions are not available, as long
11011 as the first two are identical. For instance, both "sbc r0,r1" and
11012 "sbc r0,r0,r1" are allowed. */
b99bd4ef 11013static void
c19d1205 11014do_t_arit3 (void)
b99bd4ef 11015{
c19d1205 11016 int Rd, Rs, Rn;
b99bd4ef 11017
c19d1205
ZW
11018 Rd = inst.operands[0].reg;
11019 Rs = (inst.operands[1].present
11020 ? inst.operands[1].reg /* Rd, Rs, foo */
11021 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11022 Rn = inst.operands[2].reg;
b99bd4ef 11023
fdfde340
JM
11024 reject_bad_reg (Rd);
11025 reject_bad_reg (Rs);
11026 if (inst.operands[2].isreg)
11027 reject_bad_reg (Rn);
11028
c19d1205 11029 if (unified_syntax)
b99bd4ef 11030 {
c19d1205
ZW
11031 if (!inst.operands[2].isreg)
11032 {
11033 /* For an immediate, we always generate a 32-bit opcode;
11034 section relaxation will shrink it later if possible. */
11035 inst.instruction = THUMB_OP32 (inst.instruction);
11036 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
11037 inst.instruction |= Rd << 8;
11038 inst.instruction |= Rs << 16;
e2b0ab59 11039 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
c19d1205
ZW
11040 }
11041 else
11042 {
e27ec89e
PB
11043 bfd_boolean narrow;
11044
c19d1205 11045 /* See if we can do this with a 16-bit instruction. */
e27ec89e 11046 if (THUMB_SETS_FLAGS (inst.instruction))
e07e6e58 11047 narrow = !in_it_block ();
e27ec89e 11048 else
e07e6e58 11049 narrow = in_it_block ();
e27ec89e
PB
11050
11051 if (Rd > 7 || Rn > 7 || Rs > 7)
11052 narrow = FALSE;
11053 if (inst.operands[2].shifted)
11054 narrow = FALSE;
11055 if (inst.size_req == 4)
11056 narrow = FALSE;
11057
11058 if (narrow
c19d1205
ZW
11059 && Rd == Rs)
11060 {
11061 inst.instruction = THUMB_OP16 (inst.instruction);
11062 inst.instruction |= Rd;
11063 inst.instruction |= Rn << 3;
11064 return;
11065 }
b99bd4ef 11066
c19d1205
ZW
11067 /* If we get here, it can't be done in 16 bits. */
11068 constraint (inst.operands[2].shifted
11069 && inst.operands[2].immisreg,
11070 _("shift must be constant"));
11071 inst.instruction = THUMB_OP32 (inst.instruction);
11072 inst.instruction |= Rd << 8;
11073 inst.instruction |= Rs << 16;
11074 encode_thumb32_shifted_operand (2);
11075 }
a737bd4d 11076 }
c19d1205 11077 else
b99bd4ef 11078 {
c19d1205
ZW
11079 /* On its face this is a lie - the instruction does set the
11080 flags. However, the only supported mnemonic in this mode
11081 says it doesn't. */
11082 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 11083
c19d1205
ZW
11084 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
11085 _("unshifted register required"));
11086 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
11087 constraint (Rd != Rs,
11088 _("dest and source1 must be the same register"));
a737bd4d 11089
c19d1205
ZW
11090 inst.instruction = THUMB_OP16 (inst.instruction);
11091 inst.instruction |= Rd;
11092 inst.instruction |= Rn << 3;
b99bd4ef 11093 }
a737bd4d 11094}
b99bd4ef 11095
c19d1205
ZW
11096/* Similarly, but for instructions where the arithmetic operation is
11097 commutative, so we can allow either of them to be different from
11098 the destination operand in a 16-bit instruction. For instance, all
11099 three of "adc r0,r1", "adc r0,r0,r1", and "adc r0,r1,r0" are
11100 accepted. */
11101static void
11102do_t_arit3c (void)
a737bd4d 11103{
c19d1205 11104 int Rd, Rs, Rn;
b99bd4ef 11105
c19d1205
ZW
11106 Rd = inst.operands[0].reg;
11107 Rs = (inst.operands[1].present
11108 ? inst.operands[1].reg /* Rd, Rs, foo */
11109 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11110 Rn = inst.operands[2].reg;
c921be7d 11111
fdfde340
JM
11112 reject_bad_reg (Rd);
11113 reject_bad_reg (Rs);
11114 if (inst.operands[2].isreg)
11115 reject_bad_reg (Rn);
a737bd4d 11116
c19d1205 11117 if (unified_syntax)
a737bd4d 11118 {
c19d1205 11119 if (!inst.operands[2].isreg)
b99bd4ef 11120 {
c19d1205
ZW
11121 /* For an immediate, we always generate a 32-bit opcode;
11122 section relaxation will shrink it later if possible. */
11123 inst.instruction = THUMB_OP32 (inst.instruction);
11124 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
11125 inst.instruction |= Rd << 8;
11126 inst.instruction |= Rs << 16;
e2b0ab59 11127 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 11128 }
c19d1205 11129 else
a737bd4d 11130 {
e27ec89e
PB
11131 bfd_boolean narrow;
11132
c19d1205 11133 /* See if we can do this with a 16-bit instruction. */
e27ec89e 11134 if (THUMB_SETS_FLAGS (inst.instruction))
e07e6e58 11135 narrow = !in_it_block ();
e27ec89e 11136 else
e07e6e58 11137 narrow = in_it_block ();
e27ec89e
PB
11138
11139 if (Rd > 7 || Rn > 7 || Rs > 7)
11140 narrow = FALSE;
11141 if (inst.operands[2].shifted)
11142 narrow = FALSE;
11143 if (inst.size_req == 4)
11144 narrow = FALSE;
11145
11146 if (narrow)
a737bd4d 11147 {
c19d1205 11148 if (Rd == Rs)
a737bd4d 11149 {
c19d1205
ZW
11150 inst.instruction = THUMB_OP16 (inst.instruction);
11151 inst.instruction |= Rd;
11152 inst.instruction |= Rn << 3;
11153 return;
a737bd4d 11154 }
c19d1205 11155 if (Rd == Rn)
a737bd4d 11156 {
c19d1205
ZW
11157 inst.instruction = THUMB_OP16 (inst.instruction);
11158 inst.instruction |= Rd;
11159 inst.instruction |= Rs << 3;
11160 return;
a737bd4d
NC
11161 }
11162 }
c19d1205
ZW
11163
11164 /* If we get here, it can't be done in 16 bits. */
11165 constraint (inst.operands[2].shifted
11166 && inst.operands[2].immisreg,
11167 _("shift must be constant"));
11168 inst.instruction = THUMB_OP32 (inst.instruction);
11169 inst.instruction |= Rd << 8;
11170 inst.instruction |= Rs << 16;
11171 encode_thumb32_shifted_operand (2);
a737bd4d 11172 }
b99bd4ef 11173 }
c19d1205
ZW
11174 else
11175 {
11176 /* On its face this is a lie - the instruction does set the
11177 flags. However, the only supported mnemonic in this mode
11178 says it doesn't. */
11179 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 11180
c19d1205
ZW
11181 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
11182 _("unshifted register required"));
11183 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
11184
11185 inst.instruction = THUMB_OP16 (inst.instruction);
11186 inst.instruction |= Rd;
11187
11188 if (Rd == Rs)
11189 inst.instruction |= Rn << 3;
11190 else if (Rd == Rn)
11191 inst.instruction |= Rs << 3;
11192 else
11193 constraint (1, _("dest must overlap one source register"));
11194 }
a737bd4d
NC
11195}
11196
c19d1205
ZW
11197static void
11198do_t_bfc (void)
a737bd4d 11199{
fdfde340 11200 unsigned Rd;
c19d1205
ZW
11201 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
11202 constraint (msb > 32, _("bit-field extends past end of register"));
11203 /* The instruction encoding stores the LSB and MSB,
11204 not the LSB and width. */
fdfde340
JM
11205 Rd = inst.operands[0].reg;
11206 reject_bad_reg (Rd);
11207 inst.instruction |= Rd << 8;
c19d1205
ZW
11208 inst.instruction |= (inst.operands[1].imm & 0x1c) << 10;
11209 inst.instruction |= (inst.operands[1].imm & 0x03) << 6;
11210 inst.instruction |= msb - 1;
b99bd4ef
NC
11211}
11212
c19d1205
ZW
11213static void
11214do_t_bfi (void)
b99bd4ef 11215{
fdfde340 11216 int Rd, Rn;
c19d1205 11217 unsigned int msb;
b99bd4ef 11218
fdfde340
JM
11219 Rd = inst.operands[0].reg;
11220 reject_bad_reg (Rd);
11221
c19d1205
ZW
11222 /* #0 in second position is alternative syntax for bfc, which is
11223 the same instruction but with REG_PC in the Rm field. */
11224 if (!inst.operands[1].isreg)
fdfde340
JM
11225 Rn = REG_PC;
11226 else
11227 {
11228 Rn = inst.operands[1].reg;
11229 reject_bad_reg (Rn);
11230 }
b99bd4ef 11231
c19d1205
ZW
11232 msb = inst.operands[2].imm + inst.operands[3].imm;
11233 constraint (msb > 32, _("bit-field extends past end of register"));
11234 /* The instruction encoding stores the LSB and MSB,
11235 not the LSB and width. */
fdfde340
JM
11236 inst.instruction |= Rd << 8;
11237 inst.instruction |= Rn << 16;
c19d1205
ZW
11238 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
11239 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
11240 inst.instruction |= msb - 1;
b99bd4ef
NC
11241}
11242
c19d1205
ZW
11243static void
11244do_t_bfx (void)
b99bd4ef 11245{
fdfde340
JM
11246 unsigned Rd, Rn;
11247
11248 Rd = inst.operands[0].reg;
11249 Rn = inst.operands[1].reg;
11250
11251 reject_bad_reg (Rd);
11252 reject_bad_reg (Rn);
11253
c19d1205
ZW
11254 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
11255 _("bit-field extends past end of register"));
fdfde340
JM
11256 inst.instruction |= Rd << 8;
11257 inst.instruction |= Rn << 16;
c19d1205
ZW
11258 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
11259 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
11260 inst.instruction |= inst.operands[3].imm - 1;
11261}
b99bd4ef 11262
c19d1205
ZW
11263/* ARM V5 Thumb BLX (argument parse)
11264 BLX <target_addr> which is BLX(1)
11265 BLX <Rm> which is BLX(2)
11266 Unfortunately, there are two different opcodes for this mnemonic.
11267 So, the insns[].value is not used, and the code here zaps values
11268 into inst.instruction.
b99bd4ef 11269
c19d1205
ZW
11270 ??? How to take advantage of the additional two bits of displacement
11271 available in Thumb32 mode? Need new relocation? */
b99bd4ef 11272
c19d1205
ZW
11273static void
11274do_t_blx (void)
11275{
e07e6e58
NC
11276 set_it_insn_type_last ();
11277
c19d1205 11278 if (inst.operands[0].isreg)
fdfde340
JM
11279 {
11280 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
11281 /* We have a register, so this is BLX(2). */
11282 inst.instruction |= inst.operands[0].reg << 3;
11283 }
b99bd4ef
NC
11284 else
11285 {
c19d1205 11286 /* No register. This must be BLX(1). */
2fc8bdac 11287 inst.instruction = 0xf000e800;
0855e32b 11288 encode_branch (BFD_RELOC_THUMB_PCREL_BLX);
b99bd4ef
NC
11289 }
11290}
11291
c19d1205
ZW
11292static void
11293do_t_branch (void)
b99bd4ef 11294{
0110f2b8 11295 int opcode;
dfa9f0d5 11296 int cond;
2fe88214 11297 bfd_reloc_code_real_type reloc;
dfa9f0d5 11298
e07e6e58
NC
11299 cond = inst.cond;
11300 set_it_insn_type (IF_INSIDE_IT_LAST_INSN);
11301
11302 if (in_it_block ())
dfa9f0d5
PB
11303 {
11304 /* Conditional branches inside IT blocks are encoded as unconditional
477330fc 11305 branches. */
dfa9f0d5 11306 cond = COND_ALWAYS;
dfa9f0d5
PB
11307 }
11308 else
11309 cond = inst.cond;
11310
11311 if (cond != COND_ALWAYS)
0110f2b8
PB
11312 opcode = T_MNEM_bcond;
11313 else
11314 opcode = inst.instruction;
11315
12d6b0b7
RS
11316 if (unified_syntax
11317 && (inst.size_req == 4
10960bfb
PB
11318 || (inst.size_req != 2
11319 && (inst.operands[0].hasreloc
e2b0ab59 11320 || inst.relocs[0].exp.X_op == O_constant))))
c19d1205 11321 {
0110f2b8 11322 inst.instruction = THUMB_OP32(opcode);
dfa9f0d5 11323 if (cond == COND_ALWAYS)
9ae92b05 11324 reloc = BFD_RELOC_THUMB_PCREL_BRANCH25;
c19d1205
ZW
11325 else
11326 {
ff8646ee
TP
11327 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2),
11328 _("selected architecture does not support "
11329 "wide conditional branch instruction"));
11330
9c2799c2 11331 gas_assert (cond != 0xF);
dfa9f0d5 11332 inst.instruction |= cond << 22;
9ae92b05 11333 reloc = BFD_RELOC_THUMB_PCREL_BRANCH20;
c19d1205
ZW
11334 }
11335 }
b99bd4ef
NC
11336 else
11337 {
0110f2b8 11338 inst.instruction = THUMB_OP16(opcode);
dfa9f0d5 11339 if (cond == COND_ALWAYS)
9ae92b05 11340 reloc = BFD_RELOC_THUMB_PCREL_BRANCH12;
c19d1205 11341 else
b99bd4ef 11342 {
dfa9f0d5 11343 inst.instruction |= cond << 8;
9ae92b05 11344 reloc = BFD_RELOC_THUMB_PCREL_BRANCH9;
b99bd4ef 11345 }
0110f2b8
PB
11346 /* Allow section relaxation. */
11347 if (unified_syntax && inst.size_req != 2)
11348 inst.relax = opcode;
b99bd4ef 11349 }
e2b0ab59
AV
11350 inst.relocs[0].type = reloc;
11351 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
11352}
11353
8884b720 11354/* Actually do the work for Thumb state bkpt and hlt. The only difference
bacebabc 11355 between the two is the maximum immediate allowed - which is passed in
8884b720 11356 RANGE. */
b99bd4ef 11357static void
8884b720 11358do_t_bkpt_hlt1 (int range)
b99bd4ef 11359{
dfa9f0d5
PB
11360 constraint (inst.cond != COND_ALWAYS,
11361 _("instruction is always unconditional"));
c19d1205 11362 if (inst.operands[0].present)
b99bd4ef 11363 {
8884b720 11364 constraint (inst.operands[0].imm > range,
c19d1205
ZW
11365 _("immediate value out of range"));
11366 inst.instruction |= inst.operands[0].imm;
b99bd4ef 11367 }
8884b720
MGD
11368
11369 set_it_insn_type (NEUTRAL_IT_INSN);
11370}
11371
11372static void
11373do_t_hlt (void)
11374{
11375 do_t_bkpt_hlt1 (63);
11376}
11377
11378static void
11379do_t_bkpt (void)
11380{
11381 do_t_bkpt_hlt1 (255);
b99bd4ef
NC
11382}
11383
11384static void
c19d1205 11385do_t_branch23 (void)
b99bd4ef 11386{
e07e6e58 11387 set_it_insn_type_last ();
0855e32b 11388 encode_branch (BFD_RELOC_THUMB_PCREL_BRANCH23);
fa94de6b 11389
0855e32b
NS
11390 /* md_apply_fix blows up with 'bl foo(PLT)' where foo is defined in
11391 this file. We used to simply ignore the PLT reloc type here --
11392 the branch encoding is now needed to deal with TLSCALL relocs.
11393 So if we see a PLT reloc now, put it back to how it used to be to
11394 keep the preexisting behaviour. */
e2b0ab59
AV
11395 if (inst.relocs[0].type == BFD_RELOC_ARM_PLT32)
11396 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH23;
90e4755a 11397
4343666d 11398#if defined(OBJ_COFF)
c19d1205
ZW
11399 /* If the destination of the branch is a defined symbol which does not have
11400 the THUMB_FUNC attribute, then we must be calling a function which has
11401 the (interfacearm) attribute. We look for the Thumb entry point to that
11402 function and change the branch to refer to that function instead. */
e2b0ab59
AV
11403 if ( inst.relocs[0].exp.X_op == O_symbol
11404 && inst.relocs[0].exp.X_add_symbol != NULL
11405 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
11406 && ! THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
11407 inst.relocs[0].exp.X_add_symbol
11408 = find_real_start (inst.relocs[0].exp.X_add_symbol);
4343666d 11409#endif
90e4755a
RE
11410}
11411
11412static void
c19d1205 11413do_t_bx (void)
90e4755a 11414{
e07e6e58 11415 set_it_insn_type_last ();
c19d1205
ZW
11416 inst.instruction |= inst.operands[0].reg << 3;
11417 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
11418 should cause the alignment to be checked once it is known. This is
11419 because BX PC only works if the instruction is word aligned. */
11420}
90e4755a 11421
c19d1205
ZW
11422static void
11423do_t_bxj (void)
11424{
fdfde340 11425 int Rm;
90e4755a 11426
e07e6e58 11427 set_it_insn_type_last ();
fdfde340
JM
11428 Rm = inst.operands[0].reg;
11429 reject_bad_reg (Rm);
11430 inst.instruction |= Rm << 16;
90e4755a
RE
11431}
11432
11433static void
c19d1205 11434do_t_clz (void)
90e4755a 11435{
fdfde340
JM
11436 unsigned Rd;
11437 unsigned Rm;
11438
11439 Rd = inst.operands[0].reg;
11440 Rm = inst.operands[1].reg;
11441
11442 reject_bad_reg (Rd);
11443 reject_bad_reg (Rm);
11444
11445 inst.instruction |= Rd << 8;
11446 inst.instruction |= Rm << 16;
11447 inst.instruction |= Rm;
c19d1205 11448}
90e4755a 11449
91d8b670
JG
11450static void
11451do_t_csdb (void)
11452{
11453 set_it_insn_type (OUTSIDE_IT_INSN);
11454}
11455
dfa9f0d5
PB
11456static void
11457do_t_cps (void)
11458{
e07e6e58 11459 set_it_insn_type (OUTSIDE_IT_INSN);
dfa9f0d5
PB
11460 inst.instruction |= inst.operands[0].imm;
11461}
11462
c19d1205
ZW
11463static void
11464do_t_cpsi (void)
11465{
e07e6e58 11466 set_it_insn_type (OUTSIDE_IT_INSN);
c19d1205 11467 if (unified_syntax
62b3e311
PB
11468 && (inst.operands[1].present || inst.size_req == 4)
11469 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6_notm))
90e4755a 11470 {
c19d1205
ZW
11471 unsigned int imod = (inst.instruction & 0x0030) >> 4;
11472 inst.instruction = 0xf3af8000;
11473 inst.instruction |= imod << 9;
11474 inst.instruction |= inst.operands[0].imm << 5;
11475 if (inst.operands[1].present)
11476 inst.instruction |= 0x100 | inst.operands[1].imm;
90e4755a 11477 }
c19d1205 11478 else
90e4755a 11479 {
62b3e311
PB
11480 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1)
11481 && (inst.operands[0].imm & 4),
11482 _("selected processor does not support 'A' form "
11483 "of this instruction"));
11484 constraint (inst.operands[1].present || inst.size_req == 4,
c19d1205
ZW
11485 _("Thumb does not support the 2-argument "
11486 "form of this instruction"));
11487 inst.instruction |= inst.operands[0].imm;
90e4755a 11488 }
90e4755a
RE
11489}
11490
c19d1205
ZW
11491/* THUMB CPY instruction (argument parse). */
11492
90e4755a 11493static void
c19d1205 11494do_t_cpy (void)
90e4755a 11495{
c19d1205 11496 if (inst.size_req == 4)
90e4755a 11497 {
c19d1205
ZW
11498 inst.instruction = THUMB_OP32 (T_MNEM_mov);
11499 inst.instruction |= inst.operands[0].reg << 8;
11500 inst.instruction |= inst.operands[1].reg;
90e4755a 11501 }
c19d1205 11502 else
90e4755a 11503 {
c19d1205
ZW
11504 inst.instruction |= (inst.operands[0].reg & 0x8) << 4;
11505 inst.instruction |= (inst.operands[0].reg & 0x7);
11506 inst.instruction |= inst.operands[1].reg << 3;
90e4755a 11507 }
90e4755a
RE
11508}
11509
90e4755a 11510static void
25fe350b 11511do_t_cbz (void)
90e4755a 11512{
e07e6e58 11513 set_it_insn_type (OUTSIDE_IT_INSN);
c19d1205
ZW
11514 constraint (inst.operands[0].reg > 7, BAD_HIREG);
11515 inst.instruction |= inst.operands[0].reg;
e2b0ab59
AV
11516 inst.relocs[0].pc_rel = 1;
11517 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH7;
c19d1205 11518}
90e4755a 11519
62b3e311
PB
11520static void
11521do_t_dbg (void)
11522{
11523 inst.instruction |= inst.operands[0].imm;
11524}
11525
11526static void
11527do_t_div (void)
11528{
fdfde340
JM
11529 unsigned Rd, Rn, Rm;
11530
11531 Rd = inst.operands[0].reg;
11532 Rn = (inst.operands[1].present
11533 ? inst.operands[1].reg : Rd);
11534 Rm = inst.operands[2].reg;
11535
11536 reject_bad_reg (Rd);
11537 reject_bad_reg (Rn);
11538 reject_bad_reg (Rm);
11539
11540 inst.instruction |= Rd << 8;
11541 inst.instruction |= Rn << 16;
11542 inst.instruction |= Rm;
62b3e311
PB
11543}
11544
c19d1205
ZW
11545static void
11546do_t_hint (void)
11547{
11548 if (unified_syntax && inst.size_req == 4)
11549 inst.instruction = THUMB_OP32 (inst.instruction);
11550 else
11551 inst.instruction = THUMB_OP16 (inst.instruction);
11552}
90e4755a 11553
c19d1205
ZW
11554static void
11555do_t_it (void)
11556{
11557 unsigned int cond = inst.operands[0].imm;
e27ec89e 11558
e07e6e58
NC
11559 set_it_insn_type (IT_INSN);
11560 now_it.mask = (inst.instruction & 0xf) | 0x10;
11561 now_it.cc = cond;
5a01bb1d 11562 now_it.warn_deprecated = FALSE;
e27ec89e
PB
11563
11564 /* If the condition is a negative condition, invert the mask. */
c19d1205 11565 if ((cond & 0x1) == 0x0)
90e4755a 11566 {
c19d1205 11567 unsigned int mask = inst.instruction & 0x000f;
90e4755a 11568
c19d1205 11569 if ((mask & 0x7) == 0)
5a01bb1d
MGD
11570 {
11571 /* No conversion needed. */
11572 now_it.block_length = 1;
11573 }
c19d1205 11574 else if ((mask & 0x3) == 0)
5a01bb1d
MGD
11575 {
11576 mask ^= 0x8;
11577 now_it.block_length = 2;
11578 }
e27ec89e 11579 else if ((mask & 0x1) == 0)
5a01bb1d
MGD
11580 {
11581 mask ^= 0xC;
11582 now_it.block_length = 3;
11583 }
c19d1205 11584 else
5a01bb1d
MGD
11585 {
11586 mask ^= 0xE;
11587 now_it.block_length = 4;
11588 }
90e4755a 11589
e27ec89e
PB
11590 inst.instruction &= 0xfff0;
11591 inst.instruction |= mask;
c19d1205 11592 }
90e4755a 11593
c19d1205
ZW
11594 inst.instruction |= cond << 4;
11595}
90e4755a 11596
3c707909
PB
11597/* Helper function used for both push/pop and ldm/stm. */
11598static void
4b5a202f
AV
11599encode_thumb2_multi (bfd_boolean do_io, int base, unsigned mask,
11600 bfd_boolean writeback)
3c707909 11601{
4b5a202f 11602 bfd_boolean load, store;
3c707909 11603
4b5a202f
AV
11604 gas_assert (base != -1 || !do_io);
11605 load = do_io && ((inst.instruction & (1 << 20)) != 0);
11606 store = do_io && !load;
3c707909
PB
11607
11608 if (mask & (1 << 13))
11609 inst.error = _("SP not allowed in register list");
1e5b0379 11610
4b5a202f 11611 if (do_io && (mask & (1 << base)) != 0
1e5b0379
NC
11612 && writeback)
11613 inst.error = _("having the base register in the register list when "
11614 "using write back is UNPREDICTABLE");
11615
3c707909
PB
11616 if (load)
11617 {
e07e6e58 11618 if (mask & (1 << 15))
477330fc
RM
11619 {
11620 if (mask & (1 << 14))
11621 inst.error = _("LR and PC should not both be in register list");
11622 else
11623 set_it_insn_type_last ();
11624 }
3c707909 11625 }
4b5a202f 11626 else if (store)
3c707909
PB
11627 {
11628 if (mask & (1 << 15))
11629 inst.error = _("PC not allowed in register list");
3c707909
PB
11630 }
11631
4b5a202f 11632 if (do_io && ((mask & (mask - 1)) == 0))
3c707909
PB
11633 {
11634 /* Single register transfers implemented as str/ldr. */
11635 if (writeback)
11636 {
11637 if (inst.instruction & (1 << 23))
11638 inst.instruction = 0x00000b04; /* ia! -> [base], #4 */
11639 else
11640 inst.instruction = 0x00000d04; /* db! -> [base, #-4]! */
11641 }
11642 else
11643 {
11644 if (inst.instruction & (1 << 23))
11645 inst.instruction = 0x00800000; /* ia -> [base] */
11646 else
11647 inst.instruction = 0x00000c04; /* db -> [base, #-4] */
11648 }
11649
11650 inst.instruction |= 0xf8400000;
11651 if (load)
11652 inst.instruction |= 0x00100000;
11653
5f4273c7 11654 mask = ffs (mask) - 1;
3c707909
PB
11655 mask <<= 12;
11656 }
11657 else if (writeback)
11658 inst.instruction |= WRITE_BACK;
11659
11660 inst.instruction |= mask;
4b5a202f
AV
11661 if (do_io)
11662 inst.instruction |= base << 16;
3c707909
PB
11663}
11664
c19d1205
ZW
11665static void
11666do_t_ldmstm (void)
11667{
11668 /* This really doesn't seem worth it. */
e2b0ab59 11669 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205
ZW
11670 _("expression too complex"));
11671 constraint (inst.operands[1].writeback,
11672 _("Thumb load/store multiple does not support {reglist}^"));
90e4755a 11673
c19d1205
ZW
11674 if (unified_syntax)
11675 {
3c707909
PB
11676 bfd_boolean narrow;
11677 unsigned mask;
11678
11679 narrow = FALSE;
c19d1205
ZW
11680 /* See if we can use a 16-bit instruction. */
11681 if (inst.instruction < 0xffff /* not ldmdb/stmdb */
11682 && inst.size_req != 4
3c707909 11683 && !(inst.operands[1].imm & ~0xff))
90e4755a 11684 {
3c707909 11685 mask = 1 << inst.operands[0].reg;
90e4755a 11686
eab4f823 11687 if (inst.operands[0].reg <= 7)
90e4755a 11688 {
3c707909 11689 if (inst.instruction == T_MNEM_stmia
eab4f823
MGD
11690 ? inst.operands[0].writeback
11691 : (inst.operands[0].writeback
11692 == !(inst.operands[1].imm & mask)))
477330fc 11693 {
eab4f823
MGD
11694 if (inst.instruction == T_MNEM_stmia
11695 && (inst.operands[1].imm & mask)
11696 && (inst.operands[1].imm & (mask - 1)))
11697 as_warn (_("value stored for r%d is UNKNOWN"),
11698 inst.operands[0].reg);
3c707909 11699
eab4f823
MGD
11700 inst.instruction = THUMB_OP16 (inst.instruction);
11701 inst.instruction |= inst.operands[0].reg << 8;
11702 inst.instruction |= inst.operands[1].imm;
11703 narrow = TRUE;
11704 }
11705 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
11706 {
11707 /* This means 1 register in reg list one of 3 situations:
11708 1. Instruction is stmia, but without writeback.
11709 2. lmdia without writeback, but with Rn not in
477330fc 11710 reglist.
eab4f823
MGD
11711 3. ldmia with writeback, but with Rn in reglist.
11712 Case 3 is UNPREDICTABLE behaviour, so we handle
11713 case 1 and 2 which can be converted into a 16-bit
11714 str or ldr. The SP cases are handled below. */
11715 unsigned long opcode;
11716 /* First, record an error for Case 3. */
11717 if (inst.operands[1].imm & mask
11718 && inst.operands[0].writeback)
fa94de6b 11719 inst.error =
eab4f823
MGD
11720 _("having the base register in the register list when "
11721 "using write back is UNPREDICTABLE");
fa94de6b
RM
11722
11723 opcode = (inst.instruction == T_MNEM_stmia ? T_MNEM_str
eab4f823
MGD
11724 : T_MNEM_ldr);
11725 inst.instruction = THUMB_OP16 (opcode);
11726 inst.instruction |= inst.operands[0].reg << 3;
11727 inst.instruction |= (ffs (inst.operands[1].imm)-1);
11728 narrow = TRUE;
11729 }
90e4755a 11730 }
eab4f823 11731 else if (inst.operands[0] .reg == REG_SP)
90e4755a 11732 {
eab4f823
MGD
11733 if (inst.operands[0].writeback)
11734 {
fa94de6b 11735 inst.instruction =
eab4f823 11736 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 11737 ? T_MNEM_push : T_MNEM_pop);
eab4f823 11738 inst.instruction |= inst.operands[1].imm;
477330fc 11739 narrow = TRUE;
eab4f823
MGD
11740 }
11741 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
11742 {
fa94de6b 11743 inst.instruction =
eab4f823 11744 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 11745 ? T_MNEM_str_sp : T_MNEM_ldr_sp);
eab4f823 11746 inst.instruction |= ((ffs (inst.operands[1].imm)-1) << 8);
477330fc 11747 narrow = TRUE;
eab4f823 11748 }
90e4755a 11749 }
3c707909
PB
11750 }
11751
11752 if (!narrow)
11753 {
c19d1205
ZW
11754 if (inst.instruction < 0xffff)
11755 inst.instruction = THUMB_OP32 (inst.instruction);
3c707909 11756
4b5a202f
AV
11757 encode_thumb2_multi (TRUE /* do_io */, inst.operands[0].reg,
11758 inst.operands[1].imm,
11759 inst.operands[0].writeback);
90e4755a
RE
11760 }
11761 }
c19d1205 11762 else
90e4755a 11763 {
c19d1205
ZW
11764 constraint (inst.operands[0].reg > 7
11765 || (inst.operands[1].imm & ~0xff), BAD_HIREG);
1198ca51
PB
11766 constraint (inst.instruction != T_MNEM_ldmia
11767 && inst.instruction != T_MNEM_stmia,
11768 _("Thumb-2 instruction only valid in unified syntax"));
c19d1205 11769 if (inst.instruction == T_MNEM_stmia)
f03698e6 11770 {
c19d1205
ZW
11771 if (!inst.operands[0].writeback)
11772 as_warn (_("this instruction will write back the base register"));
11773 if ((inst.operands[1].imm & (1 << inst.operands[0].reg))
11774 && (inst.operands[1].imm & ((1 << inst.operands[0].reg) - 1)))
1e5b0379 11775 as_warn (_("value stored for r%d is UNKNOWN"),
c19d1205 11776 inst.operands[0].reg);
f03698e6 11777 }
c19d1205 11778 else
90e4755a 11779 {
c19d1205
ZW
11780 if (!inst.operands[0].writeback
11781 && !(inst.operands[1].imm & (1 << inst.operands[0].reg)))
11782 as_warn (_("this instruction will write back the base register"));
11783 else if (inst.operands[0].writeback
11784 && (inst.operands[1].imm & (1 << inst.operands[0].reg)))
11785 as_warn (_("this instruction will not write back the base register"));
90e4755a
RE
11786 }
11787
c19d1205
ZW
11788 inst.instruction = THUMB_OP16 (inst.instruction);
11789 inst.instruction |= inst.operands[0].reg << 8;
11790 inst.instruction |= inst.operands[1].imm;
11791 }
11792}
e28cd48c 11793
c19d1205
ZW
11794static void
11795do_t_ldrex (void)
11796{
11797 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
11798 || inst.operands[1].postind || inst.operands[1].writeback
11799 || inst.operands[1].immisreg || inst.operands[1].shifted
11800 || inst.operands[1].negative,
01cfc07f 11801 BAD_ADDR_MODE);
e28cd48c 11802
5be8be5d
DG
11803 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
11804
c19d1205
ZW
11805 inst.instruction |= inst.operands[0].reg << 12;
11806 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 11807 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
c19d1205 11808}
e28cd48c 11809
c19d1205
ZW
11810static void
11811do_t_ldrexd (void)
11812{
11813 if (!inst.operands[1].present)
1cac9012 11814 {
c19d1205
ZW
11815 constraint (inst.operands[0].reg == REG_LR,
11816 _("r14 not allowed as first register "
11817 "when second register is omitted"));
11818 inst.operands[1].reg = inst.operands[0].reg + 1;
b99bd4ef 11819 }
c19d1205
ZW
11820 constraint (inst.operands[0].reg == inst.operands[1].reg,
11821 BAD_OVERLAP);
b99bd4ef 11822
c19d1205
ZW
11823 inst.instruction |= inst.operands[0].reg << 12;
11824 inst.instruction |= inst.operands[1].reg << 8;
11825 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
11826}
11827
11828static void
c19d1205 11829do_t_ldst (void)
b99bd4ef 11830{
0110f2b8
PB
11831 unsigned long opcode;
11832 int Rn;
11833
e07e6e58
NC
11834 if (inst.operands[0].isreg
11835 && !inst.operands[0].preind
11836 && inst.operands[0].reg == REG_PC)
11837 set_it_insn_type_last ();
11838
0110f2b8 11839 opcode = inst.instruction;
c19d1205 11840 if (unified_syntax)
b99bd4ef 11841 {
53365c0d
PB
11842 if (!inst.operands[1].isreg)
11843 {
11844 if (opcode <= 0xffff)
11845 inst.instruction = THUMB_OP32 (opcode);
8335d6aa 11846 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/FALSE))
53365c0d
PB
11847 return;
11848 }
0110f2b8
PB
11849 if (inst.operands[1].isreg
11850 && !inst.operands[1].writeback
c19d1205
ZW
11851 && !inst.operands[1].shifted && !inst.operands[1].postind
11852 && !inst.operands[1].negative && inst.operands[0].reg <= 7
0110f2b8
PB
11853 && opcode <= 0xffff
11854 && inst.size_req != 4)
c19d1205 11855 {
0110f2b8
PB
11856 /* Insn may have a 16-bit form. */
11857 Rn = inst.operands[1].reg;
11858 if (inst.operands[1].immisreg)
11859 {
11860 inst.instruction = THUMB_OP16 (opcode);
5f4273c7 11861 /* [Rn, Rik] */
0110f2b8
PB
11862 if (Rn <= 7 && inst.operands[1].imm <= 7)
11863 goto op16;
5be8be5d
DG
11864 else if (opcode != T_MNEM_ldr && opcode != T_MNEM_str)
11865 reject_bad_reg (inst.operands[1].imm);
0110f2b8
PB
11866 }
11867 else if ((Rn <= 7 && opcode != T_MNEM_ldrsh
11868 && opcode != T_MNEM_ldrsb)
11869 || ((Rn == REG_PC || Rn == REG_SP) && opcode == T_MNEM_ldr)
11870 || (Rn == REG_SP && opcode == T_MNEM_str))
11871 {
11872 /* [Rn, #const] */
11873 if (Rn > 7)
11874 {
11875 if (Rn == REG_PC)
11876 {
e2b0ab59 11877 if (inst.relocs[0].pc_rel)
0110f2b8
PB
11878 opcode = T_MNEM_ldr_pc2;
11879 else
11880 opcode = T_MNEM_ldr_pc;
11881 }
11882 else
11883 {
11884 if (opcode == T_MNEM_ldr)
11885 opcode = T_MNEM_ldr_sp;
11886 else
11887 opcode = T_MNEM_str_sp;
11888 }
11889 inst.instruction = inst.operands[0].reg << 8;
11890 }
11891 else
11892 {
11893 inst.instruction = inst.operands[0].reg;
11894 inst.instruction |= inst.operands[1].reg << 3;
11895 }
11896 inst.instruction |= THUMB_OP16 (opcode);
11897 if (inst.size_req == 2)
e2b0ab59 11898 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
0110f2b8
PB
11899 else
11900 inst.relax = opcode;
11901 return;
11902 }
c19d1205 11903 }
0110f2b8 11904 /* Definitely a 32-bit variant. */
5be8be5d 11905
8d67f500
NC
11906 /* Warning for Erratum 752419. */
11907 if (opcode == T_MNEM_ldr
11908 && inst.operands[0].reg == REG_SP
11909 && inst.operands[1].writeback == 1
11910 && !inst.operands[1].immisreg)
11911 {
11912 if (no_cpu_selected ()
11913 || (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7)
477330fc
RM
11914 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a)
11915 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7r)))
8d67f500
NC
11916 as_warn (_("This instruction may be unpredictable "
11917 "if executed on M-profile cores "
11918 "with interrupts enabled."));
11919 }
11920
5be8be5d 11921 /* Do some validations regarding addressing modes. */
1be5fd2e 11922 if (inst.operands[1].immisreg)
5be8be5d
DG
11923 reject_bad_reg (inst.operands[1].imm);
11924
1be5fd2e
NC
11925 constraint (inst.operands[1].writeback == 1
11926 && inst.operands[0].reg == inst.operands[1].reg,
11927 BAD_OVERLAP);
11928
0110f2b8 11929 inst.instruction = THUMB_OP32 (opcode);
c19d1205
ZW
11930 inst.instruction |= inst.operands[0].reg << 12;
11931 encode_thumb32_addr_mode (1, /*is_t=*/FALSE, /*is_d=*/FALSE);
1be5fd2e 11932 check_ldr_r15_aligned ();
b99bd4ef
NC
11933 return;
11934 }
11935
c19d1205
ZW
11936 constraint (inst.operands[0].reg > 7, BAD_HIREG);
11937
11938 if (inst.instruction == T_MNEM_ldrsh || inst.instruction == T_MNEM_ldrsb)
b99bd4ef 11939 {
c19d1205
ZW
11940 /* Only [Rn,Rm] is acceptable. */
11941 constraint (inst.operands[1].reg > 7 || inst.operands[1].imm > 7, BAD_HIREG);
11942 constraint (!inst.operands[1].isreg || !inst.operands[1].immisreg
11943 || inst.operands[1].postind || inst.operands[1].shifted
11944 || inst.operands[1].negative,
11945 _("Thumb does not support this addressing mode"));
11946 inst.instruction = THUMB_OP16 (inst.instruction);
11947 goto op16;
b99bd4ef 11948 }
5f4273c7 11949
c19d1205
ZW
11950 inst.instruction = THUMB_OP16 (inst.instruction);
11951 if (!inst.operands[1].isreg)
8335d6aa 11952 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/FALSE))
c19d1205 11953 return;
b99bd4ef 11954
c19d1205
ZW
11955 constraint (!inst.operands[1].preind
11956 || inst.operands[1].shifted
11957 || inst.operands[1].writeback,
11958 _("Thumb does not support this addressing mode"));
11959 if (inst.operands[1].reg == REG_PC || inst.operands[1].reg == REG_SP)
90e4755a 11960 {
c19d1205
ZW
11961 constraint (inst.instruction & 0x0600,
11962 _("byte or halfword not valid for base register"));
11963 constraint (inst.operands[1].reg == REG_PC
11964 && !(inst.instruction & THUMB_LOAD_BIT),
11965 _("r15 based store not allowed"));
11966 constraint (inst.operands[1].immisreg,
11967 _("invalid base register for register offset"));
b99bd4ef 11968
c19d1205
ZW
11969 if (inst.operands[1].reg == REG_PC)
11970 inst.instruction = T_OPCODE_LDR_PC;
11971 else if (inst.instruction & THUMB_LOAD_BIT)
11972 inst.instruction = T_OPCODE_LDR_SP;
11973 else
11974 inst.instruction = T_OPCODE_STR_SP;
b99bd4ef 11975
c19d1205 11976 inst.instruction |= inst.operands[0].reg << 8;
e2b0ab59 11977 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
11978 return;
11979 }
90e4755a 11980
c19d1205
ZW
11981 constraint (inst.operands[1].reg > 7, BAD_HIREG);
11982 if (!inst.operands[1].immisreg)
11983 {
11984 /* Immediate offset. */
11985 inst.instruction |= inst.operands[0].reg;
11986 inst.instruction |= inst.operands[1].reg << 3;
e2b0ab59 11987 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
11988 return;
11989 }
90e4755a 11990
c19d1205
ZW
11991 /* Register offset. */
11992 constraint (inst.operands[1].imm > 7, BAD_HIREG);
11993 constraint (inst.operands[1].negative,
11994 _("Thumb does not support this addressing mode"));
90e4755a 11995
c19d1205
ZW
11996 op16:
11997 switch (inst.instruction)
11998 {
11999 case T_OPCODE_STR_IW: inst.instruction = T_OPCODE_STR_RW; break;
12000 case T_OPCODE_STR_IH: inst.instruction = T_OPCODE_STR_RH; break;
12001 case T_OPCODE_STR_IB: inst.instruction = T_OPCODE_STR_RB; break;
12002 case T_OPCODE_LDR_IW: inst.instruction = T_OPCODE_LDR_RW; break;
12003 case T_OPCODE_LDR_IH: inst.instruction = T_OPCODE_LDR_RH; break;
12004 case T_OPCODE_LDR_IB: inst.instruction = T_OPCODE_LDR_RB; break;
12005 case 0x5600 /* ldrsb */:
12006 case 0x5e00 /* ldrsh */: break;
12007 default: abort ();
12008 }
90e4755a 12009
c19d1205
ZW
12010 inst.instruction |= inst.operands[0].reg;
12011 inst.instruction |= inst.operands[1].reg << 3;
12012 inst.instruction |= inst.operands[1].imm << 6;
12013}
90e4755a 12014
c19d1205
ZW
12015static void
12016do_t_ldstd (void)
12017{
12018 if (!inst.operands[1].present)
b99bd4ef 12019 {
c19d1205
ZW
12020 inst.operands[1].reg = inst.operands[0].reg + 1;
12021 constraint (inst.operands[0].reg == REG_LR,
12022 _("r14 not allowed here"));
bd340a04 12023 constraint (inst.operands[0].reg == REG_R12,
477330fc 12024 _("r12 not allowed here"));
b99bd4ef 12025 }
bd340a04
MGD
12026
12027 if (inst.operands[2].writeback
12028 && (inst.operands[0].reg == inst.operands[2].reg
12029 || inst.operands[1].reg == inst.operands[2].reg))
12030 as_warn (_("base register written back, and overlaps "
477330fc 12031 "one of transfer registers"));
bd340a04 12032
c19d1205
ZW
12033 inst.instruction |= inst.operands[0].reg << 12;
12034 inst.instruction |= inst.operands[1].reg << 8;
12035 encode_thumb32_addr_mode (2, /*is_t=*/FALSE, /*is_d=*/TRUE);
b99bd4ef
NC
12036}
12037
c19d1205
ZW
12038static void
12039do_t_ldstt (void)
12040{
12041 inst.instruction |= inst.operands[0].reg << 12;
12042 encode_thumb32_addr_mode (1, /*is_t=*/TRUE, /*is_d=*/FALSE);
12043}
a737bd4d 12044
b99bd4ef 12045static void
c19d1205 12046do_t_mla (void)
b99bd4ef 12047{
fdfde340 12048 unsigned Rd, Rn, Rm, Ra;
c921be7d 12049
fdfde340
JM
12050 Rd = inst.operands[0].reg;
12051 Rn = inst.operands[1].reg;
12052 Rm = inst.operands[2].reg;
12053 Ra = inst.operands[3].reg;
12054
12055 reject_bad_reg (Rd);
12056 reject_bad_reg (Rn);
12057 reject_bad_reg (Rm);
12058 reject_bad_reg (Ra);
12059
12060 inst.instruction |= Rd << 8;
12061 inst.instruction |= Rn << 16;
12062 inst.instruction |= Rm;
12063 inst.instruction |= Ra << 12;
c19d1205 12064}
b99bd4ef 12065
c19d1205
ZW
12066static void
12067do_t_mlal (void)
12068{
fdfde340
JM
12069 unsigned RdLo, RdHi, Rn, Rm;
12070
12071 RdLo = inst.operands[0].reg;
12072 RdHi = inst.operands[1].reg;
12073 Rn = inst.operands[2].reg;
12074 Rm = inst.operands[3].reg;
12075
12076 reject_bad_reg (RdLo);
12077 reject_bad_reg (RdHi);
12078 reject_bad_reg (Rn);
12079 reject_bad_reg (Rm);
12080
12081 inst.instruction |= RdLo << 12;
12082 inst.instruction |= RdHi << 8;
12083 inst.instruction |= Rn << 16;
12084 inst.instruction |= Rm;
c19d1205 12085}
b99bd4ef 12086
c19d1205
ZW
12087static void
12088do_t_mov_cmp (void)
12089{
fdfde340
JM
12090 unsigned Rn, Rm;
12091
12092 Rn = inst.operands[0].reg;
12093 Rm = inst.operands[1].reg;
12094
e07e6e58
NC
12095 if (Rn == REG_PC)
12096 set_it_insn_type_last ();
12097
c19d1205 12098 if (unified_syntax)
b99bd4ef 12099 {
c19d1205
ZW
12100 int r0off = (inst.instruction == T_MNEM_mov
12101 || inst.instruction == T_MNEM_movs) ? 8 : 16;
0110f2b8 12102 unsigned long opcode;
3d388997
PB
12103 bfd_boolean narrow;
12104 bfd_boolean low_regs;
12105
fdfde340 12106 low_regs = (Rn <= 7 && Rm <= 7);
0110f2b8 12107 opcode = inst.instruction;
e07e6e58 12108 if (in_it_block ())
0110f2b8 12109 narrow = opcode != T_MNEM_movs;
3d388997 12110 else
0110f2b8 12111 narrow = opcode != T_MNEM_movs || low_regs;
3d388997
PB
12112 if (inst.size_req == 4
12113 || inst.operands[1].shifted)
12114 narrow = FALSE;
12115
efd81785
PB
12116 /* MOVS PC, LR is encoded as SUBS PC, LR, #0. */
12117 if (opcode == T_MNEM_movs && inst.operands[1].isreg
12118 && !inst.operands[1].shifted
fdfde340
JM
12119 && Rn == REG_PC
12120 && Rm == REG_LR)
efd81785
PB
12121 {
12122 inst.instruction = T2_SUBS_PC_LR;
12123 return;
12124 }
12125
fdfde340
JM
12126 if (opcode == T_MNEM_cmp)
12127 {
12128 constraint (Rn == REG_PC, BAD_PC);
94206790
MM
12129 if (narrow)
12130 {
12131 /* In the Thumb-2 ISA, use of R13 as Rm is deprecated,
12132 but valid. */
12133 warn_deprecated_sp (Rm);
12134 /* R15 was documented as a valid choice for Rm in ARMv6,
12135 but as UNPREDICTABLE in ARMv7. ARM's proprietary
12136 tools reject R15, so we do too. */
12137 constraint (Rm == REG_PC, BAD_PC);
12138 }
12139 else
12140 reject_bad_reg (Rm);
fdfde340
JM
12141 }
12142 else if (opcode == T_MNEM_mov
12143 || opcode == T_MNEM_movs)
12144 {
12145 if (inst.operands[1].isreg)
12146 {
12147 if (opcode == T_MNEM_movs)
12148 {
12149 reject_bad_reg (Rn);
12150 reject_bad_reg (Rm);
12151 }
76fa04a4
MGD
12152 else if (narrow)
12153 {
12154 /* This is mov.n. */
12155 if ((Rn == REG_SP || Rn == REG_PC)
12156 && (Rm == REG_SP || Rm == REG_PC))
12157 {
5c3696f8 12158 as_tsktsk (_("Use of r%u as a source register is "
76fa04a4
MGD
12159 "deprecated when r%u is the destination "
12160 "register."), Rm, Rn);
12161 }
12162 }
12163 else
12164 {
12165 /* This is mov.w. */
12166 constraint (Rn == REG_PC, BAD_PC);
12167 constraint (Rm == REG_PC, BAD_PC);
5c8ed6a4
JW
12168 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
12169 constraint (Rn == REG_SP && Rm == REG_SP, BAD_SP);
76fa04a4 12170 }
fdfde340
JM
12171 }
12172 else
12173 reject_bad_reg (Rn);
12174 }
12175
c19d1205
ZW
12176 if (!inst.operands[1].isreg)
12177 {
0110f2b8 12178 /* Immediate operand. */
e07e6e58 12179 if (!in_it_block () && opcode == T_MNEM_mov)
0110f2b8
PB
12180 narrow = 0;
12181 if (low_regs && narrow)
12182 {
12183 inst.instruction = THUMB_OP16 (opcode);
fdfde340 12184 inst.instruction |= Rn << 8;
e2b0ab59
AV
12185 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
12186 || inst.relocs[0].type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
72d98d16 12187 {
a9f02af8 12188 if (inst.size_req == 2)
e2b0ab59 12189 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
a9f02af8
MG
12190 else
12191 inst.relax = opcode;
72d98d16 12192 }
0110f2b8
PB
12193 }
12194 else
12195 {
e2b0ab59
AV
12196 constraint ((inst.relocs[0].type
12197 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
12198 && (inst.relocs[0].type
12199 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8
MG
12200 THUMB1_RELOC_ONLY);
12201
0110f2b8
PB
12202 inst.instruction = THUMB_OP32 (inst.instruction);
12203 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 12204 inst.instruction |= Rn << r0off;
e2b0ab59 12205 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8 12206 }
c19d1205 12207 }
728ca7c9
PB
12208 else if (inst.operands[1].shifted && inst.operands[1].immisreg
12209 && (inst.instruction == T_MNEM_mov
12210 || inst.instruction == T_MNEM_movs))
12211 {
12212 /* Register shifts are encoded as separate shift instructions. */
12213 bfd_boolean flags = (inst.instruction == T_MNEM_movs);
12214
e07e6e58 12215 if (in_it_block ())
728ca7c9
PB
12216 narrow = !flags;
12217 else
12218 narrow = flags;
12219
12220 if (inst.size_req == 4)
12221 narrow = FALSE;
12222
12223 if (!low_regs || inst.operands[1].imm > 7)
12224 narrow = FALSE;
12225
fdfde340 12226 if (Rn != Rm)
728ca7c9
PB
12227 narrow = FALSE;
12228
12229 switch (inst.operands[1].shift_kind)
12230 {
12231 case SHIFT_LSL:
12232 opcode = narrow ? T_OPCODE_LSL_R : THUMB_OP32 (T_MNEM_lsl);
12233 break;
12234 case SHIFT_ASR:
12235 opcode = narrow ? T_OPCODE_ASR_R : THUMB_OP32 (T_MNEM_asr);
12236 break;
12237 case SHIFT_LSR:
12238 opcode = narrow ? T_OPCODE_LSR_R : THUMB_OP32 (T_MNEM_lsr);
12239 break;
12240 case SHIFT_ROR:
12241 opcode = narrow ? T_OPCODE_ROR_R : THUMB_OP32 (T_MNEM_ror);
12242 break;
12243 default:
5f4273c7 12244 abort ();
728ca7c9
PB
12245 }
12246
12247 inst.instruction = opcode;
12248 if (narrow)
12249 {
fdfde340 12250 inst.instruction |= Rn;
728ca7c9
PB
12251 inst.instruction |= inst.operands[1].imm << 3;
12252 }
12253 else
12254 {
12255 if (flags)
12256 inst.instruction |= CONDS_BIT;
12257
fdfde340
JM
12258 inst.instruction |= Rn << 8;
12259 inst.instruction |= Rm << 16;
728ca7c9
PB
12260 inst.instruction |= inst.operands[1].imm;
12261 }
12262 }
3d388997 12263 else if (!narrow)
c19d1205 12264 {
728ca7c9
PB
12265 /* Some mov with immediate shift have narrow variants.
12266 Register shifts are handled above. */
12267 if (low_regs && inst.operands[1].shifted
12268 && (inst.instruction == T_MNEM_mov
12269 || inst.instruction == T_MNEM_movs))
12270 {
e07e6e58 12271 if (in_it_block ())
728ca7c9
PB
12272 narrow = (inst.instruction == T_MNEM_mov);
12273 else
12274 narrow = (inst.instruction == T_MNEM_movs);
12275 }
12276
12277 if (narrow)
12278 {
12279 switch (inst.operands[1].shift_kind)
12280 {
12281 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
12282 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
12283 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
12284 default: narrow = FALSE; break;
12285 }
12286 }
12287
12288 if (narrow)
12289 {
fdfde340
JM
12290 inst.instruction |= Rn;
12291 inst.instruction |= Rm << 3;
e2b0ab59 12292 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
728ca7c9
PB
12293 }
12294 else
12295 {
12296 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 12297 inst.instruction |= Rn << r0off;
728ca7c9
PB
12298 encode_thumb32_shifted_operand (1);
12299 }
c19d1205
ZW
12300 }
12301 else
12302 switch (inst.instruction)
12303 {
12304 case T_MNEM_mov:
837b3435 12305 /* In v4t or v5t a move of two lowregs produces unpredictable
c6400f8a
MGD
12306 results. Don't allow this. */
12307 if (low_regs)
12308 {
12309 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6),
12310 "MOV Rd, Rs with two low registers is not "
12311 "permitted on this architecture");
fa94de6b 12312 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
c6400f8a
MGD
12313 arm_ext_v6);
12314 }
12315
c19d1205 12316 inst.instruction = T_OPCODE_MOV_HR;
fdfde340
JM
12317 inst.instruction |= (Rn & 0x8) << 4;
12318 inst.instruction |= (Rn & 0x7);
12319 inst.instruction |= Rm << 3;
c19d1205 12320 break;
b99bd4ef 12321
c19d1205
ZW
12322 case T_MNEM_movs:
12323 /* We know we have low registers at this point.
941a8a52
MGD
12324 Generate LSLS Rd, Rs, #0. */
12325 inst.instruction = T_OPCODE_LSL_I;
fdfde340
JM
12326 inst.instruction |= Rn;
12327 inst.instruction |= Rm << 3;
c19d1205
ZW
12328 break;
12329
12330 case T_MNEM_cmp:
3d388997 12331 if (low_regs)
c19d1205
ZW
12332 {
12333 inst.instruction = T_OPCODE_CMP_LR;
fdfde340
JM
12334 inst.instruction |= Rn;
12335 inst.instruction |= Rm << 3;
c19d1205
ZW
12336 }
12337 else
12338 {
12339 inst.instruction = T_OPCODE_CMP_HR;
fdfde340
JM
12340 inst.instruction |= (Rn & 0x8) << 4;
12341 inst.instruction |= (Rn & 0x7);
12342 inst.instruction |= Rm << 3;
c19d1205
ZW
12343 }
12344 break;
12345 }
b99bd4ef
NC
12346 return;
12347 }
12348
c19d1205 12349 inst.instruction = THUMB_OP16 (inst.instruction);
539d4391
NC
12350
12351 /* PR 10443: Do not silently ignore shifted operands. */
12352 constraint (inst.operands[1].shifted,
12353 _("shifts in CMP/MOV instructions are only supported in unified syntax"));
12354
c19d1205 12355 if (inst.operands[1].isreg)
b99bd4ef 12356 {
fdfde340 12357 if (Rn < 8 && Rm < 8)
b99bd4ef 12358 {
c19d1205
ZW
12359 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
12360 since a MOV instruction produces unpredictable results. */
12361 if (inst.instruction == T_OPCODE_MOV_I8)
12362 inst.instruction = T_OPCODE_ADD_I3;
b99bd4ef 12363 else
c19d1205 12364 inst.instruction = T_OPCODE_CMP_LR;
b99bd4ef 12365
fdfde340
JM
12366 inst.instruction |= Rn;
12367 inst.instruction |= Rm << 3;
b99bd4ef
NC
12368 }
12369 else
12370 {
c19d1205
ZW
12371 if (inst.instruction == T_OPCODE_MOV_I8)
12372 inst.instruction = T_OPCODE_MOV_HR;
12373 else
12374 inst.instruction = T_OPCODE_CMP_HR;
12375 do_t_cpy ();
b99bd4ef
NC
12376 }
12377 }
c19d1205 12378 else
b99bd4ef 12379 {
fdfde340 12380 constraint (Rn > 7,
c19d1205 12381 _("only lo regs allowed with immediate"));
fdfde340 12382 inst.instruction |= Rn << 8;
e2b0ab59 12383 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
c19d1205
ZW
12384 }
12385}
b99bd4ef 12386
c19d1205
ZW
12387static void
12388do_t_mov16 (void)
12389{
fdfde340 12390 unsigned Rd;
b6895b4f
PB
12391 bfd_vma imm;
12392 bfd_boolean top;
12393
12394 top = (inst.instruction & 0x00800000) != 0;
e2b0ab59 12395 if (inst.relocs[0].type == BFD_RELOC_ARM_MOVW)
b6895b4f 12396 {
33eaf5de 12397 constraint (top, _(":lower16: not allowed in this instruction"));
e2b0ab59 12398 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVW;
b6895b4f 12399 }
e2b0ab59 12400 else if (inst.relocs[0].type == BFD_RELOC_ARM_MOVT)
b6895b4f 12401 {
33eaf5de 12402 constraint (!top, _(":upper16: not allowed in this instruction"));
e2b0ab59 12403 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVT;
b6895b4f
PB
12404 }
12405
fdfde340
JM
12406 Rd = inst.operands[0].reg;
12407 reject_bad_reg (Rd);
12408
12409 inst.instruction |= Rd << 8;
e2b0ab59 12410 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 12411 {
e2b0ab59 12412 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
12413 inst.instruction |= (imm & 0xf000) << 4;
12414 inst.instruction |= (imm & 0x0800) << 15;
12415 inst.instruction |= (imm & 0x0700) << 4;
12416 inst.instruction |= (imm & 0x00ff);
12417 }
c19d1205 12418}
b99bd4ef 12419
c19d1205
ZW
12420static void
12421do_t_mvn_tst (void)
12422{
fdfde340 12423 unsigned Rn, Rm;
c921be7d 12424
fdfde340
JM
12425 Rn = inst.operands[0].reg;
12426 Rm = inst.operands[1].reg;
12427
12428 if (inst.instruction == T_MNEM_cmp
12429 || inst.instruction == T_MNEM_cmn)
12430 constraint (Rn == REG_PC, BAD_PC);
12431 else
12432 reject_bad_reg (Rn);
12433 reject_bad_reg (Rm);
12434
c19d1205
ZW
12435 if (unified_syntax)
12436 {
12437 int r0off = (inst.instruction == T_MNEM_mvn
12438 || inst.instruction == T_MNEM_mvns) ? 8 : 16;
3d388997
PB
12439 bfd_boolean narrow;
12440
12441 if (inst.size_req == 4
12442 || inst.instruction > 0xffff
12443 || inst.operands[1].shifted
fdfde340 12444 || Rn > 7 || Rm > 7)
3d388997 12445 narrow = FALSE;
fe8b4cc3
KT
12446 else if (inst.instruction == T_MNEM_cmn
12447 || inst.instruction == T_MNEM_tst)
3d388997
PB
12448 narrow = TRUE;
12449 else if (THUMB_SETS_FLAGS (inst.instruction))
e07e6e58 12450 narrow = !in_it_block ();
3d388997 12451 else
e07e6e58 12452 narrow = in_it_block ();
3d388997 12453
c19d1205 12454 if (!inst.operands[1].isreg)
b99bd4ef 12455 {
c19d1205
ZW
12456 /* For an immediate, we always generate a 32-bit opcode;
12457 section relaxation will shrink it later if possible. */
12458 if (inst.instruction < 0xffff)
12459 inst.instruction = THUMB_OP32 (inst.instruction);
12460 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 12461 inst.instruction |= Rn << r0off;
e2b0ab59 12462 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 12463 }
c19d1205 12464 else
b99bd4ef 12465 {
c19d1205 12466 /* See if we can do this with a 16-bit instruction. */
3d388997 12467 if (narrow)
b99bd4ef 12468 {
c19d1205 12469 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
12470 inst.instruction |= Rn;
12471 inst.instruction |= Rm << 3;
b99bd4ef 12472 }
c19d1205 12473 else
b99bd4ef 12474 {
c19d1205
ZW
12475 constraint (inst.operands[1].shifted
12476 && inst.operands[1].immisreg,
12477 _("shift must be constant"));
12478 if (inst.instruction < 0xffff)
12479 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 12480 inst.instruction |= Rn << r0off;
c19d1205 12481 encode_thumb32_shifted_operand (1);
b99bd4ef 12482 }
b99bd4ef
NC
12483 }
12484 }
12485 else
12486 {
c19d1205
ZW
12487 constraint (inst.instruction > 0xffff
12488 || inst.instruction == T_MNEM_mvns, BAD_THUMB32);
12489 constraint (!inst.operands[1].isreg || inst.operands[1].shifted,
12490 _("unshifted register required"));
fdfde340 12491 constraint (Rn > 7 || Rm > 7,
c19d1205 12492 BAD_HIREG);
b99bd4ef 12493
c19d1205 12494 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
12495 inst.instruction |= Rn;
12496 inst.instruction |= Rm << 3;
b99bd4ef 12497 }
b99bd4ef
NC
12498}
12499
b05fe5cf 12500static void
c19d1205 12501do_t_mrs (void)
b05fe5cf 12502{
fdfde340 12503 unsigned Rd;
037e8744
JB
12504
12505 if (do_vfp_nsyn_mrs () == SUCCESS)
12506 return;
12507
90ec0d68
MGD
12508 Rd = inst.operands[0].reg;
12509 reject_bad_reg (Rd);
12510 inst.instruction |= Rd << 8;
12511
12512 if (inst.operands[1].isreg)
62b3e311 12513 {
90ec0d68
MGD
12514 unsigned br = inst.operands[1].reg;
12515 if (((br & 0x200) == 0) && ((br & 0xf000) != 0xf000))
12516 as_bad (_("bad register for mrs"));
12517
12518 inst.instruction |= br & (0xf << 16);
12519 inst.instruction |= (br & 0x300) >> 4;
12520 inst.instruction |= (br & SPSR_BIT) >> 2;
62b3e311
PB
12521 }
12522 else
12523 {
90ec0d68 12524 int flags = inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
5f4273c7 12525
d2cd1205 12526 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
1a43faaf
NC
12527 {
12528 /* PR gas/12698: The constraint is only applied for m_profile.
12529 If the user has specified -march=all, we want to ignore it as
12530 we are building for any CPU type, including non-m variants. */
823d2571
TG
12531 bfd_boolean m_profile =
12532 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf
NC
12533 constraint ((flags != 0) && m_profile, _("selected processor does "
12534 "not support requested special purpose register"));
12535 }
90ec0d68 12536 else
d2cd1205
JB
12537 /* mrs only accepts APSR/CPSR/SPSR/CPSR_all/SPSR_all (for non-M profile
12538 devices). */
12539 constraint ((flags & ~SPSR_BIT) != (PSR_c|PSR_f),
12540 _("'APSR', 'CPSR' or 'SPSR' expected"));
fdfde340 12541
90ec0d68
MGD
12542 inst.instruction |= (flags & SPSR_BIT) >> 2;
12543 inst.instruction |= inst.operands[1].imm & 0xff;
12544 inst.instruction |= 0xf0000;
12545 }
c19d1205 12546}
b05fe5cf 12547
c19d1205
ZW
12548static void
12549do_t_msr (void)
12550{
62b3e311 12551 int flags;
fdfde340 12552 unsigned Rn;
62b3e311 12553
037e8744
JB
12554 if (do_vfp_nsyn_msr () == SUCCESS)
12555 return;
12556
c19d1205
ZW
12557 constraint (!inst.operands[1].isreg,
12558 _("Thumb encoding does not support an immediate here"));
90ec0d68
MGD
12559
12560 if (inst.operands[0].isreg)
12561 flags = (int)(inst.operands[0].reg);
12562 else
12563 flags = inst.operands[0].imm;
12564
d2cd1205 12565 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
62b3e311 12566 {
d2cd1205
JB
12567 int bits = inst.operands[0].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
12568
1a43faaf 12569 /* PR gas/12698: The constraint is only applied for m_profile.
477330fc
RM
12570 If the user has specified -march=all, we want to ignore it as
12571 we are building for any CPU type, including non-m variants. */
823d2571
TG
12572 bfd_boolean m_profile =
12573 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf 12574 constraint (((ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
477330fc
RM
12575 && (bits & ~(PSR_s | PSR_f)) != 0)
12576 || (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
12577 && bits != PSR_f)) && m_profile,
12578 _("selected processor does not support requested special "
12579 "purpose register"));
62b3e311
PB
12580 }
12581 else
d2cd1205
JB
12582 constraint ((flags & 0xff) != 0, _("selected processor does not support "
12583 "requested special purpose register"));
c921be7d 12584
fdfde340
JM
12585 Rn = inst.operands[1].reg;
12586 reject_bad_reg (Rn);
12587
62b3e311 12588 inst.instruction |= (flags & SPSR_BIT) >> 2;
90ec0d68
MGD
12589 inst.instruction |= (flags & 0xf0000) >> 8;
12590 inst.instruction |= (flags & 0x300) >> 4;
62b3e311 12591 inst.instruction |= (flags & 0xff);
fdfde340 12592 inst.instruction |= Rn << 16;
c19d1205 12593}
b05fe5cf 12594
c19d1205
ZW
12595static void
12596do_t_mul (void)
12597{
17828f45 12598 bfd_boolean narrow;
fdfde340 12599 unsigned Rd, Rn, Rm;
17828f45 12600
c19d1205
ZW
12601 if (!inst.operands[2].present)
12602 inst.operands[2].reg = inst.operands[0].reg;
b05fe5cf 12603
fdfde340
JM
12604 Rd = inst.operands[0].reg;
12605 Rn = inst.operands[1].reg;
12606 Rm = inst.operands[2].reg;
12607
17828f45 12608 if (unified_syntax)
b05fe5cf 12609 {
17828f45 12610 if (inst.size_req == 4
fdfde340
JM
12611 || (Rd != Rn
12612 && Rd != Rm)
12613 || Rn > 7
12614 || Rm > 7)
17828f45
JM
12615 narrow = FALSE;
12616 else if (inst.instruction == T_MNEM_muls)
e07e6e58 12617 narrow = !in_it_block ();
17828f45 12618 else
e07e6e58 12619 narrow = in_it_block ();
b05fe5cf 12620 }
c19d1205 12621 else
b05fe5cf 12622 {
17828f45 12623 constraint (inst.instruction == T_MNEM_muls, BAD_THUMB32);
fdfde340 12624 constraint (Rn > 7 || Rm > 7,
c19d1205 12625 BAD_HIREG);
17828f45
JM
12626 narrow = TRUE;
12627 }
b05fe5cf 12628
17828f45
JM
12629 if (narrow)
12630 {
12631 /* 16-bit MULS/Conditional MUL. */
c19d1205 12632 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 12633 inst.instruction |= Rd;
b05fe5cf 12634
fdfde340
JM
12635 if (Rd == Rn)
12636 inst.instruction |= Rm << 3;
12637 else if (Rd == Rm)
12638 inst.instruction |= Rn << 3;
c19d1205
ZW
12639 else
12640 constraint (1, _("dest must overlap one source register"));
12641 }
17828f45
JM
12642 else
12643 {
e07e6e58
NC
12644 constraint (inst.instruction != T_MNEM_mul,
12645 _("Thumb-2 MUL must not set flags"));
17828f45
JM
12646 /* 32-bit MUL. */
12647 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
12648 inst.instruction |= Rd << 8;
12649 inst.instruction |= Rn << 16;
12650 inst.instruction |= Rm << 0;
12651
12652 reject_bad_reg (Rd);
12653 reject_bad_reg (Rn);
12654 reject_bad_reg (Rm);
17828f45 12655 }
c19d1205 12656}
b05fe5cf 12657
c19d1205
ZW
12658static void
12659do_t_mull (void)
12660{
fdfde340 12661 unsigned RdLo, RdHi, Rn, Rm;
b05fe5cf 12662
fdfde340
JM
12663 RdLo = inst.operands[0].reg;
12664 RdHi = inst.operands[1].reg;
12665 Rn = inst.operands[2].reg;
12666 Rm = inst.operands[3].reg;
12667
12668 reject_bad_reg (RdLo);
12669 reject_bad_reg (RdHi);
12670 reject_bad_reg (Rn);
12671 reject_bad_reg (Rm);
12672
12673 inst.instruction |= RdLo << 12;
12674 inst.instruction |= RdHi << 8;
12675 inst.instruction |= Rn << 16;
12676 inst.instruction |= Rm;
12677
12678 if (RdLo == RdHi)
c19d1205
ZW
12679 as_tsktsk (_("rdhi and rdlo must be different"));
12680}
b05fe5cf 12681
c19d1205
ZW
12682static void
12683do_t_nop (void)
12684{
e07e6e58
NC
12685 set_it_insn_type (NEUTRAL_IT_INSN);
12686
c19d1205
ZW
12687 if (unified_syntax)
12688 {
12689 if (inst.size_req == 4 || inst.operands[0].imm > 15)
b05fe5cf 12690 {
c19d1205
ZW
12691 inst.instruction = THUMB_OP32 (inst.instruction);
12692 inst.instruction |= inst.operands[0].imm;
12693 }
12694 else
12695 {
bc2d1808
NC
12696 /* PR9722: Check for Thumb2 availability before
12697 generating a thumb2 nop instruction. */
afa62d5e 12698 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2))
bc2d1808
NC
12699 {
12700 inst.instruction = THUMB_OP16 (inst.instruction);
12701 inst.instruction |= inst.operands[0].imm << 4;
12702 }
12703 else
12704 inst.instruction = 0x46c0;
c19d1205
ZW
12705 }
12706 }
12707 else
12708 {
12709 constraint (inst.operands[0].present,
12710 _("Thumb does not support NOP with hints"));
12711 inst.instruction = 0x46c0;
12712 }
12713}
b05fe5cf 12714
c19d1205
ZW
12715static void
12716do_t_neg (void)
12717{
12718 if (unified_syntax)
12719 {
3d388997
PB
12720 bfd_boolean narrow;
12721
12722 if (THUMB_SETS_FLAGS (inst.instruction))
e07e6e58 12723 narrow = !in_it_block ();
3d388997 12724 else
e07e6e58 12725 narrow = in_it_block ();
3d388997
PB
12726 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
12727 narrow = FALSE;
12728 if (inst.size_req == 4)
12729 narrow = FALSE;
12730
12731 if (!narrow)
c19d1205
ZW
12732 {
12733 inst.instruction = THUMB_OP32 (inst.instruction);
12734 inst.instruction |= inst.operands[0].reg << 8;
12735 inst.instruction |= inst.operands[1].reg << 16;
b05fe5cf
ZW
12736 }
12737 else
12738 {
c19d1205
ZW
12739 inst.instruction = THUMB_OP16 (inst.instruction);
12740 inst.instruction |= inst.operands[0].reg;
12741 inst.instruction |= inst.operands[1].reg << 3;
b05fe5cf
ZW
12742 }
12743 }
12744 else
12745 {
c19d1205
ZW
12746 constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7,
12747 BAD_HIREG);
12748 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
12749
12750 inst.instruction = THUMB_OP16 (inst.instruction);
12751 inst.instruction |= inst.operands[0].reg;
12752 inst.instruction |= inst.operands[1].reg << 3;
12753 }
12754}
12755
1c444d06
JM
12756static void
12757do_t_orn (void)
12758{
12759 unsigned Rd, Rn;
12760
12761 Rd = inst.operands[0].reg;
12762 Rn = inst.operands[1].present ? inst.operands[1].reg : Rd;
12763
fdfde340
JM
12764 reject_bad_reg (Rd);
12765 /* Rn == REG_SP is unpredictable; Rn == REG_PC is MVN. */
12766 reject_bad_reg (Rn);
12767
1c444d06
JM
12768 inst.instruction |= Rd << 8;
12769 inst.instruction |= Rn << 16;
12770
12771 if (!inst.operands[2].isreg)
12772 {
12773 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 12774 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
1c444d06
JM
12775 }
12776 else
12777 {
12778 unsigned Rm;
12779
12780 Rm = inst.operands[2].reg;
fdfde340 12781 reject_bad_reg (Rm);
1c444d06
JM
12782
12783 constraint (inst.operands[2].shifted
12784 && inst.operands[2].immisreg,
12785 _("shift must be constant"));
12786 encode_thumb32_shifted_operand (2);
12787 }
12788}
12789
c19d1205
ZW
12790static void
12791do_t_pkhbt (void)
12792{
fdfde340
JM
12793 unsigned Rd, Rn, Rm;
12794
12795 Rd = inst.operands[0].reg;
12796 Rn = inst.operands[1].reg;
12797 Rm = inst.operands[2].reg;
12798
12799 reject_bad_reg (Rd);
12800 reject_bad_reg (Rn);
12801 reject_bad_reg (Rm);
12802
12803 inst.instruction |= Rd << 8;
12804 inst.instruction |= Rn << 16;
12805 inst.instruction |= Rm;
c19d1205
ZW
12806 if (inst.operands[3].present)
12807 {
e2b0ab59
AV
12808 unsigned int val = inst.relocs[0].exp.X_add_number;
12809 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
12810 _("expression too complex"));
12811 inst.instruction |= (val & 0x1c) << 10;
12812 inst.instruction |= (val & 0x03) << 6;
b05fe5cf 12813 }
c19d1205 12814}
b05fe5cf 12815
c19d1205
ZW
12816static void
12817do_t_pkhtb (void)
12818{
12819 if (!inst.operands[3].present)
1ef52f49
NC
12820 {
12821 unsigned Rtmp;
12822
12823 inst.instruction &= ~0x00000020;
12824
12825 /* PR 10168. Swap the Rm and Rn registers. */
12826 Rtmp = inst.operands[1].reg;
12827 inst.operands[1].reg = inst.operands[2].reg;
12828 inst.operands[2].reg = Rtmp;
12829 }
c19d1205 12830 do_t_pkhbt ();
b05fe5cf
ZW
12831}
12832
c19d1205
ZW
12833static void
12834do_t_pld (void)
12835{
fdfde340
JM
12836 if (inst.operands[0].immisreg)
12837 reject_bad_reg (inst.operands[0].imm);
12838
c19d1205
ZW
12839 encode_thumb32_addr_mode (0, /*is_t=*/FALSE, /*is_d=*/FALSE);
12840}
b05fe5cf 12841
c19d1205
ZW
12842static void
12843do_t_push_pop (void)
b99bd4ef 12844{
e9f89963 12845 unsigned mask;
5f4273c7 12846
c19d1205
ZW
12847 constraint (inst.operands[0].writeback,
12848 _("push/pop do not support {reglist}^"));
e2b0ab59 12849 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205 12850 _("expression too complex"));
b99bd4ef 12851
e9f89963 12852 mask = inst.operands[0].imm;
d3bfe16e 12853 if (inst.size_req != 4 && (mask & ~0xff) == 0)
3c707909 12854 inst.instruction = THUMB_OP16 (inst.instruction) | mask;
d3bfe16e 12855 else if (inst.size_req != 4
c6025a80 12856 && (mask & ~0xff) == (1U << (inst.instruction == T_MNEM_push
d3bfe16e 12857 ? REG_LR : REG_PC)))
b99bd4ef 12858 {
c19d1205
ZW
12859 inst.instruction = THUMB_OP16 (inst.instruction);
12860 inst.instruction |= THUMB_PP_PC_LR;
3c707909 12861 inst.instruction |= mask & 0xff;
c19d1205
ZW
12862 }
12863 else if (unified_syntax)
12864 {
3c707909 12865 inst.instruction = THUMB_OP32 (inst.instruction);
4b5a202f
AV
12866 encode_thumb2_multi (TRUE /* do_io */, 13, mask, TRUE);
12867 }
12868 else
12869 {
12870 inst.error = _("invalid register list to push/pop instruction");
12871 return;
c19d1205 12872 }
4b5a202f
AV
12873}
12874
12875static void
12876do_t_clrm (void)
12877{
12878 if (unified_syntax)
12879 encode_thumb2_multi (FALSE /* do_io */, -1, inst.operands[0].imm, FALSE);
c19d1205
ZW
12880 else
12881 {
12882 inst.error = _("invalid register list to push/pop instruction");
12883 return;
12884 }
c19d1205 12885}
b99bd4ef 12886
efd6b359
AV
12887static void
12888do_t_vscclrm (void)
12889{
12890 if (inst.operands[0].issingle)
12891 {
12892 inst.instruction |= (inst.operands[0].reg & 0x1) << 22;
12893 inst.instruction |= (inst.operands[0].reg & 0x1e) << 11;
12894 inst.instruction |= inst.operands[0].imm;
12895 }
12896 else
12897 {
12898 inst.instruction |= (inst.operands[0].reg & 0x10) << 18;
12899 inst.instruction |= (inst.operands[0].reg & 0xf) << 12;
12900 inst.instruction |= 1 << 8;
12901 inst.instruction |= inst.operands[0].imm << 1;
12902 }
12903}
12904
c19d1205
ZW
12905static void
12906do_t_rbit (void)
12907{
fdfde340
JM
12908 unsigned Rd, Rm;
12909
12910 Rd = inst.operands[0].reg;
12911 Rm = inst.operands[1].reg;
12912
12913 reject_bad_reg (Rd);
12914 reject_bad_reg (Rm);
12915
12916 inst.instruction |= Rd << 8;
12917 inst.instruction |= Rm << 16;
12918 inst.instruction |= Rm;
c19d1205 12919}
b99bd4ef 12920
c19d1205
ZW
12921static void
12922do_t_rev (void)
12923{
fdfde340
JM
12924 unsigned Rd, Rm;
12925
12926 Rd = inst.operands[0].reg;
12927 Rm = inst.operands[1].reg;
12928
12929 reject_bad_reg (Rd);
12930 reject_bad_reg (Rm);
12931
12932 if (Rd <= 7 && Rm <= 7
c19d1205
ZW
12933 && inst.size_req != 4)
12934 {
12935 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
12936 inst.instruction |= Rd;
12937 inst.instruction |= Rm << 3;
c19d1205
ZW
12938 }
12939 else if (unified_syntax)
12940 {
12941 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
12942 inst.instruction |= Rd << 8;
12943 inst.instruction |= Rm << 16;
12944 inst.instruction |= Rm;
c19d1205
ZW
12945 }
12946 else
12947 inst.error = BAD_HIREG;
12948}
b99bd4ef 12949
1c444d06
JM
12950static void
12951do_t_rrx (void)
12952{
12953 unsigned Rd, Rm;
12954
12955 Rd = inst.operands[0].reg;
12956 Rm = inst.operands[1].reg;
12957
fdfde340
JM
12958 reject_bad_reg (Rd);
12959 reject_bad_reg (Rm);
c921be7d 12960
1c444d06
JM
12961 inst.instruction |= Rd << 8;
12962 inst.instruction |= Rm;
12963}
12964
c19d1205
ZW
12965static void
12966do_t_rsb (void)
12967{
fdfde340 12968 unsigned Rd, Rs;
b99bd4ef 12969
c19d1205
ZW
12970 Rd = inst.operands[0].reg;
12971 Rs = (inst.operands[1].present
12972 ? inst.operands[1].reg /* Rd, Rs, foo */
12973 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
b99bd4ef 12974
fdfde340
JM
12975 reject_bad_reg (Rd);
12976 reject_bad_reg (Rs);
12977 if (inst.operands[2].isreg)
12978 reject_bad_reg (inst.operands[2].reg);
12979
c19d1205
ZW
12980 inst.instruction |= Rd << 8;
12981 inst.instruction |= Rs << 16;
12982 if (!inst.operands[2].isreg)
12983 {
026d3abb
PB
12984 bfd_boolean narrow;
12985
12986 if ((inst.instruction & 0x00100000) != 0)
e07e6e58 12987 narrow = !in_it_block ();
026d3abb 12988 else
e07e6e58 12989 narrow = in_it_block ();
026d3abb
PB
12990
12991 if (Rd > 7 || Rs > 7)
12992 narrow = FALSE;
12993
12994 if (inst.size_req == 4 || !unified_syntax)
12995 narrow = FALSE;
12996
e2b0ab59
AV
12997 if (inst.relocs[0].exp.X_op != O_constant
12998 || inst.relocs[0].exp.X_add_number != 0)
026d3abb
PB
12999 narrow = FALSE;
13000
13001 /* Turn rsb #0 into 16-bit neg. We should probably do this via
477330fc 13002 relaxation, but it doesn't seem worth the hassle. */
026d3abb
PB
13003 if (narrow)
13004 {
e2b0ab59 13005 inst.relocs[0].type = BFD_RELOC_UNUSED;
026d3abb
PB
13006 inst.instruction = THUMB_OP16 (T_MNEM_negs);
13007 inst.instruction |= Rs << 3;
13008 inst.instruction |= Rd;
13009 }
13010 else
13011 {
13012 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 13013 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
026d3abb 13014 }
c19d1205
ZW
13015 }
13016 else
13017 encode_thumb32_shifted_operand (2);
13018}
b99bd4ef 13019
c19d1205
ZW
13020static void
13021do_t_setend (void)
13022{
12e37cbc
MGD
13023 if (warn_on_deprecated
13024 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 13025 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 13026
e07e6e58 13027 set_it_insn_type (OUTSIDE_IT_INSN);
c19d1205
ZW
13028 if (inst.operands[0].imm)
13029 inst.instruction |= 0x8;
13030}
b99bd4ef 13031
c19d1205
ZW
13032static void
13033do_t_shift (void)
13034{
13035 if (!inst.operands[1].present)
13036 inst.operands[1].reg = inst.operands[0].reg;
13037
13038 if (unified_syntax)
13039 {
3d388997
PB
13040 bfd_boolean narrow;
13041 int shift_kind;
13042
13043 switch (inst.instruction)
13044 {
13045 case T_MNEM_asr:
13046 case T_MNEM_asrs: shift_kind = SHIFT_ASR; break;
13047 case T_MNEM_lsl:
13048 case T_MNEM_lsls: shift_kind = SHIFT_LSL; break;
13049 case T_MNEM_lsr:
13050 case T_MNEM_lsrs: shift_kind = SHIFT_LSR; break;
13051 case T_MNEM_ror:
13052 case T_MNEM_rors: shift_kind = SHIFT_ROR; break;
13053 default: abort ();
13054 }
13055
13056 if (THUMB_SETS_FLAGS (inst.instruction))
e07e6e58 13057 narrow = !in_it_block ();
3d388997 13058 else
e07e6e58 13059 narrow = in_it_block ();
3d388997
PB
13060 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
13061 narrow = FALSE;
13062 if (!inst.operands[2].isreg && shift_kind == SHIFT_ROR)
13063 narrow = FALSE;
13064 if (inst.operands[2].isreg
13065 && (inst.operands[1].reg != inst.operands[0].reg
13066 || inst.operands[2].reg > 7))
13067 narrow = FALSE;
13068 if (inst.size_req == 4)
13069 narrow = FALSE;
13070
fdfde340
JM
13071 reject_bad_reg (inst.operands[0].reg);
13072 reject_bad_reg (inst.operands[1].reg);
c921be7d 13073
3d388997 13074 if (!narrow)
c19d1205
ZW
13075 {
13076 if (inst.operands[2].isreg)
b99bd4ef 13077 {
fdfde340 13078 reject_bad_reg (inst.operands[2].reg);
c19d1205
ZW
13079 inst.instruction = THUMB_OP32 (inst.instruction);
13080 inst.instruction |= inst.operands[0].reg << 8;
13081 inst.instruction |= inst.operands[1].reg << 16;
13082 inst.instruction |= inst.operands[2].reg;
94342ec3
NC
13083
13084 /* PR 12854: Error on extraneous shifts. */
13085 constraint (inst.operands[2].shifted,
13086 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
13087 }
13088 else
13089 {
13090 inst.operands[1].shifted = 1;
3d388997 13091 inst.operands[1].shift_kind = shift_kind;
c19d1205
ZW
13092 inst.instruction = THUMB_OP32 (THUMB_SETS_FLAGS (inst.instruction)
13093 ? T_MNEM_movs : T_MNEM_mov);
13094 inst.instruction |= inst.operands[0].reg << 8;
13095 encode_thumb32_shifted_operand (1);
13096 /* Prevent the incorrect generation of an ARM_IMMEDIATE fixup. */
e2b0ab59 13097 inst.relocs[0].type = BFD_RELOC_UNUSED;
b99bd4ef
NC
13098 }
13099 }
13100 else
13101 {
c19d1205 13102 if (inst.operands[2].isreg)
b99bd4ef 13103 {
3d388997 13104 switch (shift_kind)
b99bd4ef 13105 {
3d388997
PB
13106 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_R; break;
13107 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_R; break;
13108 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_R; break;
13109 case SHIFT_ROR: inst.instruction = T_OPCODE_ROR_R; break;
c19d1205 13110 default: abort ();
b99bd4ef 13111 }
5f4273c7 13112
c19d1205
ZW
13113 inst.instruction |= inst.operands[0].reg;
13114 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
13115
13116 /* PR 12854: Error on extraneous shifts. */
13117 constraint (inst.operands[2].shifted,
13118 _("extraneous shift as part of operand to shift insn"));
b99bd4ef
NC
13119 }
13120 else
13121 {
3d388997 13122 switch (shift_kind)
b99bd4ef 13123 {
3d388997
PB
13124 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
13125 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
13126 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
c19d1205 13127 default: abort ();
b99bd4ef 13128 }
e2b0ab59 13129 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
13130 inst.instruction |= inst.operands[0].reg;
13131 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
13132 }
13133 }
c19d1205
ZW
13134 }
13135 else
13136 {
13137 constraint (inst.operands[0].reg > 7
13138 || inst.operands[1].reg > 7, BAD_HIREG);
13139 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
b99bd4ef 13140
c19d1205
ZW
13141 if (inst.operands[2].isreg) /* Rd, {Rs,} Rn */
13142 {
13143 constraint (inst.operands[2].reg > 7, BAD_HIREG);
13144 constraint (inst.operands[0].reg != inst.operands[1].reg,
13145 _("source1 and dest must be same register"));
b99bd4ef 13146
c19d1205
ZW
13147 switch (inst.instruction)
13148 {
13149 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_R; break;
13150 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_R; break;
13151 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_R; break;
13152 case T_MNEM_ror: inst.instruction = T_OPCODE_ROR_R; break;
13153 default: abort ();
13154 }
5f4273c7 13155
c19d1205
ZW
13156 inst.instruction |= inst.operands[0].reg;
13157 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
13158
13159 /* PR 12854: Error on extraneous shifts. */
13160 constraint (inst.operands[2].shifted,
13161 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
13162 }
13163 else
b99bd4ef 13164 {
c19d1205
ZW
13165 switch (inst.instruction)
13166 {
13167 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_I; break;
13168 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_I; break;
13169 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_I; break;
13170 case T_MNEM_ror: inst.error = _("ror #imm not supported"); return;
13171 default: abort ();
13172 }
e2b0ab59 13173 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
13174 inst.instruction |= inst.operands[0].reg;
13175 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
13176 }
13177 }
b99bd4ef
NC
13178}
13179
13180static void
c19d1205 13181do_t_simd (void)
b99bd4ef 13182{
fdfde340
JM
13183 unsigned Rd, Rn, Rm;
13184
13185 Rd = inst.operands[0].reg;
13186 Rn = inst.operands[1].reg;
13187 Rm = inst.operands[2].reg;
13188
13189 reject_bad_reg (Rd);
13190 reject_bad_reg (Rn);
13191 reject_bad_reg (Rm);
13192
13193 inst.instruction |= Rd << 8;
13194 inst.instruction |= Rn << 16;
13195 inst.instruction |= Rm;
c19d1205 13196}
b99bd4ef 13197
03ee1b7f
NC
13198static void
13199do_t_simd2 (void)
13200{
13201 unsigned Rd, Rn, Rm;
13202
13203 Rd = inst.operands[0].reg;
13204 Rm = inst.operands[1].reg;
13205 Rn = inst.operands[2].reg;
13206
13207 reject_bad_reg (Rd);
13208 reject_bad_reg (Rn);
13209 reject_bad_reg (Rm);
13210
13211 inst.instruction |= Rd << 8;
13212 inst.instruction |= Rn << 16;
13213 inst.instruction |= Rm;
13214}
13215
c19d1205 13216static void
3eb17e6b 13217do_t_smc (void)
c19d1205 13218{
e2b0ab59 13219 unsigned int value = inst.relocs[0].exp.X_add_number;
f4c65163
MGD
13220 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a),
13221 _("SMC is not permitted on this architecture"));
e2b0ab59 13222 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 13223 _("expression too complex"));
e2b0ab59 13224 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205
ZW
13225 inst.instruction |= (value & 0xf000) >> 12;
13226 inst.instruction |= (value & 0x0ff0);
13227 inst.instruction |= (value & 0x000f) << 16;
24382199
NC
13228 /* PR gas/15623: SMC instructions must be last in an IT block. */
13229 set_it_insn_type_last ();
c19d1205 13230}
b99bd4ef 13231
90ec0d68
MGD
13232static void
13233do_t_hvc (void)
13234{
e2b0ab59 13235 unsigned int value = inst.relocs[0].exp.X_add_number;
90ec0d68 13236
e2b0ab59 13237 inst.relocs[0].type = BFD_RELOC_UNUSED;
90ec0d68
MGD
13238 inst.instruction |= (value & 0x0fff);
13239 inst.instruction |= (value & 0xf000) << 4;
13240}
13241
c19d1205 13242static void
3a21c15a 13243do_t_ssat_usat (int bias)
c19d1205 13244{
fdfde340
JM
13245 unsigned Rd, Rn;
13246
13247 Rd = inst.operands[0].reg;
13248 Rn = inst.operands[2].reg;
13249
13250 reject_bad_reg (Rd);
13251 reject_bad_reg (Rn);
13252
13253 inst.instruction |= Rd << 8;
3a21c15a 13254 inst.instruction |= inst.operands[1].imm - bias;
fdfde340 13255 inst.instruction |= Rn << 16;
b99bd4ef 13256
c19d1205 13257 if (inst.operands[3].present)
b99bd4ef 13258 {
e2b0ab59 13259 offsetT shift_amount = inst.relocs[0].exp.X_add_number;
3a21c15a 13260
e2b0ab59 13261 inst.relocs[0].type = BFD_RELOC_UNUSED;
3a21c15a 13262
e2b0ab59 13263 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 13264 _("expression too complex"));
b99bd4ef 13265
3a21c15a 13266 if (shift_amount != 0)
6189168b 13267 {
3a21c15a
NC
13268 constraint (shift_amount > 31,
13269 _("shift expression is too large"));
13270
c19d1205 13271 if (inst.operands[3].shift_kind == SHIFT_ASR)
3a21c15a
NC
13272 inst.instruction |= 0x00200000; /* sh bit. */
13273
13274 inst.instruction |= (shift_amount & 0x1c) << 10;
13275 inst.instruction |= (shift_amount & 0x03) << 6;
6189168b
NC
13276 }
13277 }
b99bd4ef 13278}
c921be7d 13279
3a21c15a
NC
13280static void
13281do_t_ssat (void)
13282{
13283 do_t_ssat_usat (1);
13284}
b99bd4ef 13285
0dd132b6 13286static void
c19d1205 13287do_t_ssat16 (void)
0dd132b6 13288{
fdfde340
JM
13289 unsigned Rd, Rn;
13290
13291 Rd = inst.operands[0].reg;
13292 Rn = inst.operands[2].reg;
13293
13294 reject_bad_reg (Rd);
13295 reject_bad_reg (Rn);
13296
13297 inst.instruction |= Rd << 8;
c19d1205 13298 inst.instruction |= inst.operands[1].imm - 1;
fdfde340 13299 inst.instruction |= Rn << 16;
c19d1205 13300}
0dd132b6 13301
c19d1205
ZW
13302static void
13303do_t_strex (void)
13304{
13305 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
13306 || inst.operands[2].postind || inst.operands[2].writeback
13307 || inst.operands[2].immisreg || inst.operands[2].shifted
13308 || inst.operands[2].negative,
01cfc07f 13309 BAD_ADDR_MODE);
0dd132b6 13310
5be8be5d
DG
13311 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
13312
c19d1205
ZW
13313 inst.instruction |= inst.operands[0].reg << 8;
13314 inst.instruction |= inst.operands[1].reg << 12;
13315 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 13316 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
0dd132b6
NC
13317}
13318
b99bd4ef 13319static void
c19d1205 13320do_t_strexd (void)
b99bd4ef 13321{
c19d1205
ZW
13322 if (!inst.operands[2].present)
13323 inst.operands[2].reg = inst.operands[1].reg + 1;
b99bd4ef 13324
c19d1205
ZW
13325 constraint (inst.operands[0].reg == inst.operands[1].reg
13326 || inst.operands[0].reg == inst.operands[2].reg
f8a8e9d6 13327 || inst.operands[0].reg == inst.operands[3].reg,
c19d1205 13328 BAD_OVERLAP);
b99bd4ef 13329
c19d1205
ZW
13330 inst.instruction |= inst.operands[0].reg;
13331 inst.instruction |= inst.operands[1].reg << 12;
13332 inst.instruction |= inst.operands[2].reg << 8;
13333 inst.instruction |= inst.operands[3].reg << 16;
b99bd4ef
NC
13334}
13335
13336static void
c19d1205 13337do_t_sxtah (void)
b99bd4ef 13338{
fdfde340
JM
13339 unsigned Rd, Rn, Rm;
13340
13341 Rd = inst.operands[0].reg;
13342 Rn = inst.operands[1].reg;
13343 Rm = inst.operands[2].reg;
13344
13345 reject_bad_reg (Rd);
13346 reject_bad_reg (Rn);
13347 reject_bad_reg (Rm);
13348
13349 inst.instruction |= Rd << 8;
13350 inst.instruction |= Rn << 16;
13351 inst.instruction |= Rm;
c19d1205
ZW
13352 inst.instruction |= inst.operands[3].imm << 4;
13353}
b99bd4ef 13354
c19d1205
ZW
13355static void
13356do_t_sxth (void)
13357{
fdfde340
JM
13358 unsigned Rd, Rm;
13359
13360 Rd = inst.operands[0].reg;
13361 Rm = inst.operands[1].reg;
13362
13363 reject_bad_reg (Rd);
13364 reject_bad_reg (Rm);
c921be7d
NC
13365
13366 if (inst.instruction <= 0xffff
13367 && inst.size_req != 4
fdfde340 13368 && Rd <= 7 && Rm <= 7
c19d1205 13369 && (!inst.operands[2].present || inst.operands[2].imm == 0))
b99bd4ef 13370 {
c19d1205 13371 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13372 inst.instruction |= Rd;
13373 inst.instruction |= Rm << 3;
b99bd4ef 13374 }
c19d1205 13375 else if (unified_syntax)
b99bd4ef 13376 {
c19d1205
ZW
13377 if (inst.instruction <= 0xffff)
13378 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13379 inst.instruction |= Rd << 8;
13380 inst.instruction |= Rm;
c19d1205 13381 inst.instruction |= inst.operands[2].imm << 4;
b99bd4ef 13382 }
c19d1205 13383 else
b99bd4ef 13384 {
c19d1205
ZW
13385 constraint (inst.operands[2].present && inst.operands[2].imm != 0,
13386 _("Thumb encoding does not support rotation"));
13387 constraint (1, BAD_HIREG);
b99bd4ef 13388 }
c19d1205 13389}
b99bd4ef 13390
c19d1205
ZW
13391static void
13392do_t_swi (void)
13393{
e2b0ab59 13394 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
c19d1205 13395}
b99bd4ef 13396
92e90b6e
PB
13397static void
13398do_t_tb (void)
13399{
fdfde340 13400 unsigned Rn, Rm;
92e90b6e
PB
13401 int half;
13402
13403 half = (inst.instruction & 0x10) != 0;
e07e6e58 13404 set_it_insn_type_last ();
dfa9f0d5
PB
13405 constraint (inst.operands[0].immisreg,
13406 _("instruction requires register index"));
fdfde340
JM
13407
13408 Rn = inst.operands[0].reg;
13409 Rm = inst.operands[0].imm;
c921be7d 13410
5c8ed6a4
JW
13411 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
13412 constraint (Rn == REG_SP, BAD_SP);
fdfde340
JM
13413 reject_bad_reg (Rm);
13414
92e90b6e
PB
13415 constraint (!half && inst.operands[0].shifted,
13416 _("instruction does not allow shifted index"));
fdfde340 13417 inst.instruction |= (Rn << 16) | Rm;
92e90b6e
PB
13418}
13419
74db7efb
NC
13420static void
13421do_t_udf (void)
13422{
13423 if (!inst.operands[0].present)
13424 inst.operands[0].imm = 0;
13425
13426 if ((unsigned int) inst.operands[0].imm > 255 || inst.size_req == 4)
13427 {
13428 constraint (inst.size_req == 2,
13429 _("immediate value out of range"));
13430 inst.instruction = THUMB_OP32 (inst.instruction);
13431 inst.instruction |= (inst.operands[0].imm & 0xf000u) << 4;
13432 inst.instruction |= (inst.operands[0].imm & 0x0fffu) << 0;
13433 }
13434 else
13435 {
13436 inst.instruction = THUMB_OP16 (inst.instruction);
13437 inst.instruction |= inst.operands[0].imm;
13438 }
13439
13440 set_it_insn_type (NEUTRAL_IT_INSN);
13441}
13442
13443
c19d1205
ZW
13444static void
13445do_t_usat (void)
13446{
3a21c15a 13447 do_t_ssat_usat (0);
b99bd4ef
NC
13448}
13449
13450static void
c19d1205 13451do_t_usat16 (void)
b99bd4ef 13452{
fdfde340
JM
13453 unsigned Rd, Rn;
13454
13455 Rd = inst.operands[0].reg;
13456 Rn = inst.operands[2].reg;
13457
13458 reject_bad_reg (Rd);
13459 reject_bad_reg (Rn);
13460
13461 inst.instruction |= Rd << 8;
c19d1205 13462 inst.instruction |= inst.operands[1].imm;
fdfde340 13463 inst.instruction |= Rn << 16;
b99bd4ef 13464}
c19d1205 13465
e12437dc
AV
13466/* Checking the range of the branch offset (VAL) with NBITS bits
13467 and IS_SIGNED signedness. Also checks the LSB to be 0. */
13468static int
13469v8_1_branch_value_check (int val, int nbits, int is_signed)
13470{
13471 gas_assert (nbits > 0 && nbits <= 32);
13472 if (is_signed)
13473 {
13474 int cmp = (1 << (nbits - 1));
13475 if ((val < -cmp) || (val >= cmp) || (val & 0x01))
13476 return FAIL;
13477 }
13478 else
13479 {
13480 if ((val <= 0) || (val >= (1 << nbits)) || (val & 0x1))
13481 return FAIL;
13482 }
13483 return SUCCESS;
13484}
13485
4389b29a
AV
13486/* For branches in Armv8.1-M Mainline. */
13487static void
13488do_t_branch_future (void)
13489{
13490 unsigned long insn = inst.instruction;
13491
13492 inst.instruction = THUMB_OP32 (inst.instruction);
13493 if (inst.operands[0].hasreloc == 0)
13494 {
13495 if (v8_1_branch_value_check (inst.operands[0].imm, 5, FALSE) == FAIL)
13496 as_bad (BAD_BRANCH_OFF);
13497
13498 inst.instruction |= ((inst.operands[0].imm & 0x1f) >> 1) << 23;
13499 }
13500 else
13501 {
13502 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH5;
13503 inst.relocs[0].pc_rel = 1;
13504 }
13505
13506 switch (insn)
13507 {
13508 case T_MNEM_bf:
13509 if (inst.operands[1].hasreloc == 0)
13510 {
13511 int val = inst.operands[1].imm;
13512 if (v8_1_branch_value_check (inst.operands[1].imm, 17, TRUE) == FAIL)
13513 as_bad (BAD_BRANCH_OFF);
13514
13515 int immA = (val & 0x0001f000) >> 12;
13516 int immB = (val & 0x00000ffc) >> 2;
13517 int immC = (val & 0x00000002) >> 1;
13518 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
13519 }
13520 else
13521 {
13522 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF17;
13523 inst.relocs[1].pc_rel = 1;
13524 }
13525 break;
13526
65d1bc05
AV
13527 case T_MNEM_bfl:
13528 if (inst.operands[1].hasreloc == 0)
13529 {
13530 int val = inst.operands[1].imm;
13531 if (v8_1_branch_value_check (inst.operands[1].imm, 19, TRUE) == FAIL)
13532 as_bad (BAD_BRANCH_OFF);
13533
13534 int immA = (val & 0x0007f000) >> 12;
13535 int immB = (val & 0x00000ffc) >> 2;
13536 int immC = (val & 0x00000002) >> 1;
13537 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
13538 }
13539 else
13540 {
13541 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF19;
13542 inst.relocs[1].pc_rel = 1;
13543 }
13544 break;
13545
f6b2b12d
AV
13546 case T_MNEM_bfcsel:
13547 /* Operand 1. */
13548 if (inst.operands[1].hasreloc == 0)
13549 {
13550 int val = inst.operands[1].imm;
13551 int immA = (val & 0x00001000) >> 12;
13552 int immB = (val & 0x00000ffc) >> 2;
13553 int immC = (val & 0x00000002) >> 1;
13554 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
13555 }
13556 else
13557 {
13558 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF13;
13559 inst.relocs[1].pc_rel = 1;
13560 }
13561
13562 /* Operand 2. */
13563 if (inst.operands[2].hasreloc == 0)
13564 {
13565 constraint ((inst.operands[0].hasreloc != 0), BAD_ARGS);
13566 int val2 = inst.operands[2].imm;
13567 int val0 = inst.operands[0].imm & 0x1f;
13568 int diff = val2 - val0;
13569 if (diff == 4)
13570 inst.instruction |= 1 << 17; /* T bit. */
13571 else if (diff != 2)
13572 as_bad (_("out of range label-relative fixup value"));
13573 }
13574 else
13575 {
13576 constraint ((inst.operands[0].hasreloc == 0), BAD_ARGS);
13577 inst.relocs[2].type = BFD_RELOC_THUMB_PCREL_BFCSEL;
13578 inst.relocs[2].pc_rel = 1;
13579 }
13580
13581 /* Operand 3. */
13582 constraint (inst.cond != COND_ALWAYS, BAD_COND);
13583 inst.instruction |= (inst.operands[3].imm & 0xf) << 18;
13584 break;
13585
f1c7f421
AV
13586 case T_MNEM_bfx:
13587 case T_MNEM_bflx:
13588 inst.instruction |= inst.operands[1].reg << 16;
13589 break;
13590
4389b29a
AV
13591 default: abort ();
13592 }
13593}
13594
60f993ce
AV
13595/* Helper function for do_t_loloop to handle relocations. */
13596static void
13597v8_1_loop_reloc (int is_le)
13598{
13599 if (inst.relocs[0].exp.X_op == O_constant)
13600 {
13601 int value = inst.relocs[0].exp.X_add_number;
13602 value = (is_le) ? -value : value;
13603
13604 if (v8_1_branch_value_check (value, 12, FALSE) == FAIL)
13605 as_bad (BAD_BRANCH_OFF);
13606
13607 int imml, immh;
13608
13609 immh = (value & 0x00000ffc) >> 2;
13610 imml = (value & 0x00000002) >> 1;
13611
13612 inst.instruction |= (imml << 11) | (immh << 1);
13613 }
13614 else
13615 {
13616 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_LOOP12;
13617 inst.relocs[0].pc_rel = 1;
13618 }
13619}
13620
13621/* To handle the Scalar Low Overhead Loop instructions
13622 in Armv8.1-M Mainline. */
13623static void
13624do_t_loloop (void)
13625{
13626 unsigned long insn = inst.instruction;
13627
13628 set_it_insn_type (OUTSIDE_IT_INSN);
13629 inst.instruction = THUMB_OP32 (inst.instruction);
13630
13631 switch (insn)
13632 {
13633 case T_MNEM_le:
13634 /* le <label>. */
13635 if (!inst.operands[0].present)
13636 inst.instruction |= 1 << 21;
13637
13638 v8_1_loop_reloc (TRUE);
13639 break;
13640
13641 case T_MNEM_wls:
13642 v8_1_loop_reloc (FALSE);
13643 /* Fall through. */
13644 case T_MNEM_dls:
13645 constraint (inst.operands[1].isreg != 1, BAD_ARGS);
13646 inst.instruction |= (inst.operands[1].reg << 16);
13647 break;
13648
13649 default: abort();
13650 }
13651}
13652
5287ad62 13653/* Neon instruction encoder helpers. */
5f4273c7 13654
5287ad62 13655/* Encodings for the different types for various Neon opcodes. */
b99bd4ef 13656
5287ad62
JB
13657/* An "invalid" code for the following tables. */
13658#define N_INV -1u
13659
13660struct neon_tab_entry
b99bd4ef 13661{
5287ad62
JB
13662 unsigned integer;
13663 unsigned float_or_poly;
13664 unsigned scalar_or_imm;
13665};
5f4273c7 13666
5287ad62
JB
13667/* Map overloaded Neon opcodes to their respective encodings. */
13668#define NEON_ENC_TAB \
13669 X(vabd, 0x0000700, 0x1200d00, N_INV), \
13670 X(vmax, 0x0000600, 0x0000f00, N_INV), \
13671 X(vmin, 0x0000610, 0x0200f00, N_INV), \
13672 X(vpadd, 0x0000b10, 0x1000d00, N_INV), \
13673 X(vpmax, 0x0000a00, 0x1000f00, N_INV), \
13674 X(vpmin, 0x0000a10, 0x1200f00, N_INV), \
13675 X(vadd, 0x0000800, 0x0000d00, N_INV), \
13676 X(vsub, 0x1000800, 0x0200d00, N_INV), \
13677 X(vceq, 0x1000810, 0x0000e00, 0x1b10100), \
13678 X(vcge, 0x0000310, 0x1000e00, 0x1b10080), \
13679 X(vcgt, 0x0000300, 0x1200e00, 0x1b10000), \
13680 /* Register variants of the following two instructions are encoded as
e07e6e58 13681 vcge / vcgt with the operands reversed. */ \
92559b5b
PB
13682 X(vclt, 0x0000300, 0x1200e00, 0x1b10200), \
13683 X(vcle, 0x0000310, 0x1000e00, 0x1b10180), \
62f3b8c8
PB
13684 X(vfma, N_INV, 0x0000c10, N_INV), \
13685 X(vfms, N_INV, 0x0200c10, N_INV), \
5287ad62
JB
13686 X(vmla, 0x0000900, 0x0000d10, 0x0800040), \
13687 X(vmls, 0x1000900, 0x0200d10, 0x0800440), \
13688 X(vmul, 0x0000910, 0x1000d10, 0x0800840), \
13689 X(vmull, 0x0800c00, 0x0800e00, 0x0800a40), /* polynomial not float. */ \
13690 X(vmlal, 0x0800800, N_INV, 0x0800240), \
13691 X(vmlsl, 0x0800a00, N_INV, 0x0800640), \
13692 X(vqdmlal, 0x0800900, N_INV, 0x0800340), \
13693 X(vqdmlsl, 0x0800b00, N_INV, 0x0800740), \
13694 X(vqdmull, 0x0800d00, N_INV, 0x0800b40), \
13695 X(vqdmulh, 0x0000b00, N_INV, 0x0800c40), \
13696 X(vqrdmulh, 0x1000b00, N_INV, 0x0800d40), \
d6b4b13e
MW
13697 X(vqrdmlah, 0x3000b10, N_INV, 0x0800e40), \
13698 X(vqrdmlsh, 0x3000c10, N_INV, 0x0800f40), \
5287ad62
JB
13699 X(vshl, 0x0000400, N_INV, 0x0800510), \
13700 X(vqshl, 0x0000410, N_INV, 0x0800710), \
13701 X(vand, 0x0000110, N_INV, 0x0800030), \
13702 X(vbic, 0x0100110, N_INV, 0x0800030), \
13703 X(veor, 0x1000110, N_INV, N_INV), \
13704 X(vorn, 0x0300110, N_INV, 0x0800010), \
13705 X(vorr, 0x0200110, N_INV, 0x0800010), \
13706 X(vmvn, 0x1b00580, N_INV, 0x0800030), \
13707 X(vshll, 0x1b20300, N_INV, 0x0800a10), /* max shift, immediate. */ \
13708 X(vcvt, 0x1b30600, N_INV, 0x0800e10), /* integer, fixed-point. */ \
13709 X(vdup, 0xe800b10, N_INV, 0x1b00c00), /* arm, scalar. */ \
13710 X(vld1, 0x0200000, 0x0a00000, 0x0a00c00), /* interlv, lane, dup. */ \
13711 X(vst1, 0x0000000, 0x0800000, N_INV), \
13712 X(vld2, 0x0200100, 0x0a00100, 0x0a00d00), \
13713 X(vst2, 0x0000100, 0x0800100, N_INV), \
13714 X(vld3, 0x0200200, 0x0a00200, 0x0a00e00), \
13715 X(vst3, 0x0000200, 0x0800200, N_INV), \
13716 X(vld4, 0x0200300, 0x0a00300, 0x0a00f00), \
13717 X(vst4, 0x0000300, 0x0800300, N_INV), \
13718 X(vmovn, 0x1b20200, N_INV, N_INV), \
13719 X(vtrn, 0x1b20080, N_INV, N_INV), \
13720 X(vqmovn, 0x1b20200, N_INV, N_INV), \
037e8744
JB
13721 X(vqmovun, 0x1b20240, N_INV, N_INV), \
13722 X(vnmul, 0xe200a40, 0xe200b40, N_INV), \
e6655fda
PB
13723 X(vnmla, 0xe100a40, 0xe100b40, N_INV), \
13724 X(vnmls, 0xe100a00, 0xe100b00, N_INV), \
62f3b8c8
PB
13725 X(vfnma, 0xe900a40, 0xe900b40, N_INV), \
13726 X(vfnms, 0xe900a00, 0xe900b00, N_INV), \
037e8744
JB
13727 X(vcmp, 0xeb40a40, 0xeb40b40, N_INV), \
13728 X(vcmpz, 0xeb50a40, 0xeb50b40, N_INV), \
13729 X(vcmpe, 0xeb40ac0, 0xeb40bc0, N_INV), \
33399f07
MGD
13730 X(vcmpez, 0xeb50ac0, 0xeb50bc0, N_INV), \
13731 X(vseleq, 0xe000a00, N_INV, N_INV), \
13732 X(vselvs, 0xe100a00, N_INV, N_INV), \
13733 X(vselge, 0xe200a00, N_INV, N_INV), \
73924fbc
MGD
13734 X(vselgt, 0xe300a00, N_INV, N_INV), \
13735 X(vmaxnm, 0xe800a00, 0x3000f10, N_INV), \
7e8e6784 13736 X(vminnm, 0xe800a40, 0x3200f10, N_INV), \
30bdf752
MGD
13737 X(vcvta, 0xebc0a40, 0x3bb0000, N_INV), \
13738 X(vrintr, 0xeb60a40, 0x3ba0400, N_INV), \
91ff7894 13739 X(vrinta, 0xeb80a40, 0x3ba0400, N_INV), \
48adcd8e 13740 X(aes, 0x3b00300, N_INV, N_INV), \
3c9017d2
MGD
13741 X(sha3op, 0x2000c00, N_INV, N_INV), \
13742 X(sha1h, 0x3b902c0, N_INV, N_INV), \
13743 X(sha2op, 0x3ba0380, N_INV, N_INV)
5287ad62
JB
13744
13745enum neon_opc
13746{
13747#define X(OPC,I,F,S) N_MNEM_##OPC
13748NEON_ENC_TAB
13749#undef X
13750};
b99bd4ef 13751
5287ad62
JB
13752static const struct neon_tab_entry neon_enc_tab[] =
13753{
13754#define X(OPC,I,F,S) { (I), (F), (S) }
13755NEON_ENC_TAB
13756#undef X
13757};
b99bd4ef 13758
88714cb8
DG
13759/* Do not use these macros; instead, use NEON_ENCODE defined below. */
13760#define NEON_ENC_INTEGER_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
13761#define NEON_ENC_ARMREG_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
13762#define NEON_ENC_POLY_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
13763#define NEON_ENC_FLOAT_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
13764#define NEON_ENC_SCALAR_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
13765#define NEON_ENC_IMMED_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
13766#define NEON_ENC_INTERLV_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
13767#define NEON_ENC_LANE_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
13768#define NEON_ENC_DUP_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
13769#define NEON_ENC_SINGLE_(X) \
037e8744 13770 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf0000000))
88714cb8 13771#define NEON_ENC_DOUBLE_(X) \
037e8744 13772 ((neon_enc_tab[(X) & 0x0fffffff].float_or_poly) | ((X) & 0xf0000000))
33399f07
MGD
13773#define NEON_ENC_FPV8_(X) \
13774 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf000000))
5287ad62 13775
88714cb8
DG
13776#define NEON_ENCODE(type, inst) \
13777 do \
13778 { \
13779 inst.instruction = NEON_ENC_##type##_ (inst.instruction); \
13780 inst.is_neon = 1; \
13781 } \
13782 while (0)
13783
13784#define check_neon_suffixes \
13785 do \
13786 { \
13787 if (!inst.error && inst.vectype.elems > 0 && !inst.is_neon) \
13788 { \
13789 as_bad (_("invalid neon suffix for non neon instruction")); \
13790 return; \
13791 } \
13792 } \
13793 while (0)
13794
037e8744
JB
13795/* Define shapes for instruction operands. The following mnemonic characters
13796 are used in this table:
5287ad62 13797
037e8744 13798 F - VFP S<n> register
5287ad62
JB
13799 D - Neon D<n> register
13800 Q - Neon Q<n> register
13801 I - Immediate
13802 S - Scalar
13803 R - ARM register
13804 L - D<n> register list
5f4273c7 13805
037e8744
JB
13806 This table is used to generate various data:
13807 - enumerations of the form NS_DDR to be used as arguments to
13808 neon_select_shape.
13809 - a table classifying shapes into single, double, quad, mixed.
5f4273c7 13810 - a table used to drive neon_select_shape. */
b99bd4ef 13811
037e8744
JB
13812#define NEON_SHAPE_DEF \
13813 X(3, (D, D, D), DOUBLE), \
13814 X(3, (Q, Q, Q), QUAD), \
13815 X(3, (D, D, I), DOUBLE), \
13816 X(3, (Q, Q, I), QUAD), \
13817 X(3, (D, D, S), DOUBLE), \
13818 X(3, (Q, Q, S), QUAD), \
13819 X(2, (D, D), DOUBLE), \
13820 X(2, (Q, Q), QUAD), \
13821 X(2, (D, S), DOUBLE), \
13822 X(2, (Q, S), QUAD), \
13823 X(2, (D, R), DOUBLE), \
13824 X(2, (Q, R), QUAD), \
13825 X(2, (D, I), DOUBLE), \
13826 X(2, (Q, I), QUAD), \
13827 X(3, (D, L, D), DOUBLE), \
13828 X(2, (D, Q), MIXED), \
13829 X(2, (Q, D), MIXED), \
13830 X(3, (D, Q, I), MIXED), \
13831 X(3, (Q, D, I), MIXED), \
13832 X(3, (Q, D, D), MIXED), \
13833 X(3, (D, Q, Q), MIXED), \
13834 X(3, (Q, Q, D), MIXED), \
13835 X(3, (Q, D, S), MIXED), \
13836 X(3, (D, Q, S), MIXED), \
13837 X(4, (D, D, D, I), DOUBLE), \
13838 X(4, (Q, Q, Q, I), QUAD), \
c28eeff2
SN
13839 X(4, (D, D, S, I), DOUBLE), \
13840 X(4, (Q, Q, S, I), QUAD), \
037e8744
JB
13841 X(2, (F, F), SINGLE), \
13842 X(3, (F, F, F), SINGLE), \
13843 X(2, (F, I), SINGLE), \
13844 X(2, (F, D), MIXED), \
13845 X(2, (D, F), MIXED), \
13846 X(3, (F, F, I), MIXED), \
13847 X(4, (R, R, F, F), SINGLE), \
13848 X(4, (F, F, R, R), SINGLE), \
13849 X(3, (D, R, R), DOUBLE), \
13850 X(3, (R, R, D), DOUBLE), \
13851 X(2, (S, R), SINGLE), \
13852 X(2, (R, S), SINGLE), \
13853 X(2, (F, R), SINGLE), \
d54af2d0
RL
13854 X(2, (R, F), SINGLE), \
13855/* Half float shape supported so far. */\
13856 X (2, (H, D), MIXED), \
13857 X (2, (D, H), MIXED), \
13858 X (2, (H, F), MIXED), \
13859 X (2, (F, H), MIXED), \
13860 X (2, (H, H), HALF), \
13861 X (2, (H, R), HALF), \
13862 X (2, (R, H), HALF), \
13863 X (2, (H, I), HALF), \
13864 X (3, (H, H, H), HALF), \
13865 X (3, (H, F, I), MIXED), \
dec41383
JW
13866 X (3, (F, H, I), MIXED), \
13867 X (3, (D, H, H), MIXED), \
13868 X (3, (D, H, S), MIXED)
037e8744
JB
13869
13870#define S2(A,B) NS_##A##B
13871#define S3(A,B,C) NS_##A##B##C
13872#define S4(A,B,C,D) NS_##A##B##C##D
13873
13874#define X(N, L, C) S##N L
13875
5287ad62
JB
13876enum neon_shape
13877{
037e8744
JB
13878 NEON_SHAPE_DEF,
13879 NS_NULL
5287ad62 13880};
b99bd4ef 13881
037e8744
JB
13882#undef X
13883#undef S2
13884#undef S3
13885#undef S4
13886
13887enum neon_shape_class
13888{
d54af2d0 13889 SC_HALF,
037e8744
JB
13890 SC_SINGLE,
13891 SC_DOUBLE,
13892 SC_QUAD,
13893 SC_MIXED
13894};
13895
13896#define X(N, L, C) SC_##C
13897
13898static enum neon_shape_class neon_shape_class[] =
13899{
13900 NEON_SHAPE_DEF
13901};
13902
13903#undef X
13904
13905enum neon_shape_el
13906{
d54af2d0 13907 SE_H,
037e8744
JB
13908 SE_F,
13909 SE_D,
13910 SE_Q,
13911 SE_I,
13912 SE_S,
13913 SE_R,
13914 SE_L
13915};
13916
13917/* Register widths of above. */
13918static unsigned neon_shape_el_size[] =
13919{
d54af2d0 13920 16,
037e8744
JB
13921 32,
13922 64,
13923 128,
13924 0,
13925 32,
13926 32,
13927 0
13928};
13929
13930struct neon_shape_info
13931{
13932 unsigned els;
13933 enum neon_shape_el el[NEON_MAX_TYPE_ELS];
13934};
13935
13936#define S2(A,B) { SE_##A, SE_##B }
13937#define S3(A,B,C) { SE_##A, SE_##B, SE_##C }
13938#define S4(A,B,C,D) { SE_##A, SE_##B, SE_##C, SE_##D }
13939
13940#define X(N, L, C) { N, S##N L }
13941
13942static struct neon_shape_info neon_shape_tab[] =
13943{
13944 NEON_SHAPE_DEF
13945};
13946
13947#undef X
13948#undef S2
13949#undef S3
13950#undef S4
13951
5287ad62
JB
13952/* Bit masks used in type checking given instructions.
13953 'N_EQK' means the type must be the same as (or based on in some way) the key
13954 type, which itself is marked with the 'N_KEY' bit. If the 'N_EQK' bit is
13955 set, various other bits can be set as well in order to modify the meaning of
13956 the type constraint. */
13957
13958enum neon_type_mask
13959{
8e79c3df
CM
13960 N_S8 = 0x0000001,
13961 N_S16 = 0x0000002,
13962 N_S32 = 0x0000004,
13963 N_S64 = 0x0000008,
13964 N_U8 = 0x0000010,
13965 N_U16 = 0x0000020,
13966 N_U32 = 0x0000040,
13967 N_U64 = 0x0000080,
13968 N_I8 = 0x0000100,
13969 N_I16 = 0x0000200,
13970 N_I32 = 0x0000400,
13971 N_I64 = 0x0000800,
13972 N_8 = 0x0001000,
13973 N_16 = 0x0002000,
13974 N_32 = 0x0004000,
13975 N_64 = 0x0008000,
13976 N_P8 = 0x0010000,
13977 N_P16 = 0x0020000,
13978 N_F16 = 0x0040000,
13979 N_F32 = 0x0080000,
13980 N_F64 = 0x0100000,
4f51b4bd 13981 N_P64 = 0x0200000,
c921be7d
NC
13982 N_KEY = 0x1000000, /* Key element (main type specifier). */
13983 N_EQK = 0x2000000, /* Given operand has the same type & size as the key. */
8e79c3df 13984 N_VFP = 0x4000000, /* VFP mode: operand size must match register width. */
91ff7894 13985 N_UNT = 0x8000000, /* Must be explicitly untyped. */
c921be7d
NC
13986 N_DBL = 0x0000001, /* If N_EQK, this operand is twice the size. */
13987 N_HLF = 0x0000002, /* If N_EQK, this operand is half the size. */
13988 N_SGN = 0x0000004, /* If N_EQK, this operand is forced to be signed. */
13989 N_UNS = 0x0000008, /* If N_EQK, this operand is forced to be unsigned. */
13990 N_INT = 0x0000010, /* If N_EQK, this operand is forced to be integer. */
13991 N_FLT = 0x0000020, /* If N_EQK, this operand is forced to be float. */
13992 N_SIZ = 0x0000040, /* If N_EQK, this operand is forced to be size-only. */
5287ad62 13993 N_UTYP = 0,
4f51b4bd 13994 N_MAX_NONSPECIAL = N_P64
5287ad62
JB
13995};
13996
dcbf9037
JB
13997#define N_ALLMODS (N_DBL | N_HLF | N_SGN | N_UNS | N_INT | N_FLT | N_SIZ)
13998
5287ad62
JB
13999#define N_SU_ALL (N_S8 | N_S16 | N_S32 | N_S64 | N_U8 | N_U16 | N_U32 | N_U64)
14000#define N_SU_32 (N_S8 | N_S16 | N_S32 | N_U8 | N_U16 | N_U32)
14001#define N_SU_16_64 (N_S16 | N_S32 | N_S64 | N_U16 | N_U32 | N_U64)
cc933301
JW
14002#define N_S_32 (N_S8 | N_S16 | N_S32)
14003#define N_F_16_32 (N_F16 | N_F32)
14004#define N_SUF_32 (N_SU_32 | N_F_16_32)
5287ad62 14005#define N_I_ALL (N_I8 | N_I16 | N_I32 | N_I64)
cc933301 14006#define N_IF_32 (N_I8 | N_I16 | N_I32 | N_F16 | N_F32)
d54af2d0 14007#define N_F_ALL (N_F16 | N_F32 | N_F64)
5287ad62
JB
14008
14009/* Pass this as the first type argument to neon_check_type to ignore types
14010 altogether. */
14011#define N_IGNORE_TYPE (N_KEY | N_EQK)
14012
037e8744
JB
14013/* Select a "shape" for the current instruction (describing register types or
14014 sizes) from a list of alternatives. Return NS_NULL if the current instruction
14015 doesn't fit. For non-polymorphic shapes, checking is usually done as a
14016 function of operand parsing, so this function doesn't need to be called.
14017 Shapes should be listed in order of decreasing length. */
5287ad62
JB
14018
14019static enum neon_shape
037e8744 14020neon_select_shape (enum neon_shape shape, ...)
5287ad62 14021{
037e8744
JB
14022 va_list ap;
14023 enum neon_shape first_shape = shape;
5287ad62
JB
14024
14025 /* Fix missing optional operands. FIXME: we don't know at this point how
14026 many arguments we should have, so this makes the assumption that we have
14027 > 1. This is true of all current Neon opcodes, I think, but may not be
14028 true in the future. */
14029 if (!inst.operands[1].present)
14030 inst.operands[1] = inst.operands[0];
14031
037e8744 14032 va_start (ap, shape);
5f4273c7 14033
21d799b5 14034 for (; shape != NS_NULL; shape = (enum neon_shape) va_arg (ap, int))
037e8744
JB
14035 {
14036 unsigned j;
14037 int matches = 1;
14038
14039 for (j = 0; j < neon_shape_tab[shape].els; j++)
477330fc
RM
14040 {
14041 if (!inst.operands[j].present)
14042 {
14043 matches = 0;
14044 break;
14045 }
14046
14047 switch (neon_shape_tab[shape].el[j])
14048 {
d54af2d0
RL
14049 /* If a .f16, .16, .u16, .s16 type specifier is given over
14050 a VFP single precision register operand, it's essentially
14051 means only half of the register is used.
14052
14053 If the type specifier is given after the mnemonics, the
14054 information is stored in inst.vectype. If the type specifier
14055 is given after register operand, the information is stored
14056 in inst.operands[].vectype.
14057
14058 When there is only one type specifier, and all the register
14059 operands are the same type of hardware register, the type
14060 specifier applies to all register operands.
14061
14062 If no type specifier is given, the shape is inferred from
14063 operand information.
14064
14065 for example:
14066 vadd.f16 s0, s1, s2: NS_HHH
14067 vabs.f16 s0, s1: NS_HH
14068 vmov.f16 s0, r1: NS_HR
14069 vmov.f16 r0, s1: NS_RH
14070 vcvt.f16 r0, s1: NS_RH
14071 vcvt.f16.s32 s2, s2, #29: NS_HFI
14072 vcvt.f16.s32 s2, s2: NS_HF
14073 */
14074 case SE_H:
14075 if (!(inst.operands[j].isreg
14076 && inst.operands[j].isvec
14077 && inst.operands[j].issingle
14078 && !inst.operands[j].isquad
14079 && ((inst.vectype.elems == 1
14080 && inst.vectype.el[0].size == 16)
14081 || (inst.vectype.elems > 1
14082 && inst.vectype.el[j].size == 16)
14083 || (inst.vectype.elems == 0
14084 && inst.operands[j].vectype.type != NT_invtype
14085 && inst.operands[j].vectype.size == 16))))
14086 matches = 0;
14087 break;
14088
477330fc
RM
14089 case SE_F:
14090 if (!(inst.operands[j].isreg
14091 && inst.operands[j].isvec
14092 && inst.operands[j].issingle
d54af2d0
RL
14093 && !inst.operands[j].isquad
14094 && ((inst.vectype.elems == 1 && inst.vectype.el[0].size == 32)
14095 || (inst.vectype.elems > 1 && inst.vectype.el[j].size == 32)
14096 || (inst.vectype.elems == 0
14097 && (inst.operands[j].vectype.size == 32
14098 || inst.operands[j].vectype.type == NT_invtype)))))
477330fc
RM
14099 matches = 0;
14100 break;
14101
14102 case SE_D:
14103 if (!(inst.operands[j].isreg
14104 && inst.operands[j].isvec
14105 && !inst.operands[j].isquad
14106 && !inst.operands[j].issingle))
14107 matches = 0;
14108 break;
14109
14110 case SE_R:
14111 if (!(inst.operands[j].isreg
14112 && !inst.operands[j].isvec))
14113 matches = 0;
14114 break;
14115
14116 case SE_Q:
14117 if (!(inst.operands[j].isreg
14118 && inst.operands[j].isvec
14119 && inst.operands[j].isquad
14120 && !inst.operands[j].issingle))
14121 matches = 0;
14122 break;
14123
14124 case SE_I:
14125 if (!(!inst.operands[j].isreg
14126 && !inst.operands[j].isscalar))
14127 matches = 0;
14128 break;
14129
14130 case SE_S:
14131 if (!(!inst.operands[j].isreg
14132 && inst.operands[j].isscalar))
14133 matches = 0;
14134 break;
14135
14136 case SE_L:
14137 break;
14138 }
3fde54a2
JZ
14139 if (!matches)
14140 break;
477330fc 14141 }
ad6cec43
MGD
14142 if (matches && (j >= ARM_IT_MAX_OPERANDS || !inst.operands[j].present))
14143 /* We've matched all the entries in the shape table, and we don't
14144 have any left over operands which have not been matched. */
477330fc 14145 break;
037e8744 14146 }
5f4273c7 14147
037e8744 14148 va_end (ap);
5287ad62 14149
037e8744
JB
14150 if (shape == NS_NULL && first_shape != NS_NULL)
14151 first_error (_("invalid instruction shape"));
5287ad62 14152
037e8744
JB
14153 return shape;
14154}
5287ad62 14155
037e8744
JB
14156/* True if SHAPE is predominantly a quadword operation (most of the time, this
14157 means the Q bit should be set). */
14158
14159static int
14160neon_quad (enum neon_shape shape)
14161{
14162 return neon_shape_class[shape] == SC_QUAD;
5287ad62 14163}
037e8744 14164
5287ad62
JB
14165static void
14166neon_modify_type_size (unsigned typebits, enum neon_el_type *g_type,
477330fc 14167 unsigned *g_size)
5287ad62
JB
14168{
14169 /* Allow modification to be made to types which are constrained to be
14170 based on the key element, based on bits set alongside N_EQK. */
14171 if ((typebits & N_EQK) != 0)
14172 {
14173 if ((typebits & N_HLF) != 0)
14174 *g_size /= 2;
14175 else if ((typebits & N_DBL) != 0)
14176 *g_size *= 2;
14177 if ((typebits & N_SGN) != 0)
14178 *g_type = NT_signed;
14179 else if ((typebits & N_UNS) != 0)
477330fc 14180 *g_type = NT_unsigned;
5287ad62 14181 else if ((typebits & N_INT) != 0)
477330fc 14182 *g_type = NT_integer;
5287ad62 14183 else if ((typebits & N_FLT) != 0)
477330fc 14184 *g_type = NT_float;
dcbf9037 14185 else if ((typebits & N_SIZ) != 0)
477330fc 14186 *g_type = NT_untyped;
5287ad62
JB
14187 }
14188}
5f4273c7 14189
5287ad62
JB
14190/* Return operand OPNO promoted by bits set in THISARG. KEY should be the "key"
14191 operand type, i.e. the single type specified in a Neon instruction when it
14192 is the only one given. */
14193
14194static struct neon_type_el
14195neon_type_promote (struct neon_type_el *key, unsigned thisarg)
14196{
14197 struct neon_type_el dest = *key;
5f4273c7 14198
9c2799c2 14199 gas_assert ((thisarg & N_EQK) != 0);
5f4273c7 14200
5287ad62
JB
14201 neon_modify_type_size (thisarg, &dest.type, &dest.size);
14202
14203 return dest;
14204}
14205
14206/* Convert Neon type and size into compact bitmask representation. */
14207
14208static enum neon_type_mask
14209type_chk_of_el_type (enum neon_el_type type, unsigned size)
14210{
14211 switch (type)
14212 {
14213 case NT_untyped:
14214 switch (size)
477330fc
RM
14215 {
14216 case 8: return N_8;
14217 case 16: return N_16;
14218 case 32: return N_32;
14219 case 64: return N_64;
14220 default: ;
14221 }
5287ad62
JB
14222 break;
14223
14224 case NT_integer:
14225 switch (size)
477330fc
RM
14226 {
14227 case 8: return N_I8;
14228 case 16: return N_I16;
14229 case 32: return N_I32;
14230 case 64: return N_I64;
14231 default: ;
14232 }
5287ad62
JB
14233 break;
14234
14235 case NT_float:
037e8744 14236 switch (size)
477330fc 14237 {
8e79c3df 14238 case 16: return N_F16;
477330fc
RM
14239 case 32: return N_F32;
14240 case 64: return N_F64;
14241 default: ;
14242 }
5287ad62
JB
14243 break;
14244
14245 case NT_poly:
14246 switch (size)
477330fc
RM
14247 {
14248 case 8: return N_P8;
14249 case 16: return N_P16;
4f51b4bd 14250 case 64: return N_P64;
477330fc
RM
14251 default: ;
14252 }
5287ad62
JB
14253 break;
14254
14255 case NT_signed:
14256 switch (size)
477330fc
RM
14257 {
14258 case 8: return N_S8;
14259 case 16: return N_S16;
14260 case 32: return N_S32;
14261 case 64: return N_S64;
14262 default: ;
14263 }
5287ad62
JB
14264 break;
14265
14266 case NT_unsigned:
14267 switch (size)
477330fc
RM
14268 {
14269 case 8: return N_U8;
14270 case 16: return N_U16;
14271 case 32: return N_U32;
14272 case 64: return N_U64;
14273 default: ;
14274 }
5287ad62
JB
14275 break;
14276
14277 default: ;
14278 }
5f4273c7 14279
5287ad62
JB
14280 return N_UTYP;
14281}
14282
14283/* Convert compact Neon bitmask type representation to a type and size. Only
14284 handles the case where a single bit is set in the mask. */
14285
dcbf9037 14286static int
5287ad62 14287el_type_of_type_chk (enum neon_el_type *type, unsigned *size,
477330fc 14288 enum neon_type_mask mask)
5287ad62 14289{
dcbf9037
JB
14290 if ((mask & N_EQK) != 0)
14291 return FAIL;
14292
5287ad62
JB
14293 if ((mask & (N_S8 | N_U8 | N_I8 | N_8 | N_P8)) != 0)
14294 *size = 8;
c70a8987 14295 else if ((mask & (N_S16 | N_U16 | N_I16 | N_16 | N_F16 | N_P16)) != 0)
5287ad62 14296 *size = 16;
dcbf9037 14297 else if ((mask & (N_S32 | N_U32 | N_I32 | N_32 | N_F32)) != 0)
5287ad62 14298 *size = 32;
4f51b4bd 14299 else if ((mask & (N_S64 | N_U64 | N_I64 | N_64 | N_F64 | N_P64)) != 0)
5287ad62 14300 *size = 64;
dcbf9037
JB
14301 else
14302 return FAIL;
14303
5287ad62
JB
14304 if ((mask & (N_S8 | N_S16 | N_S32 | N_S64)) != 0)
14305 *type = NT_signed;
dcbf9037 14306 else if ((mask & (N_U8 | N_U16 | N_U32 | N_U64)) != 0)
5287ad62 14307 *type = NT_unsigned;
dcbf9037 14308 else if ((mask & (N_I8 | N_I16 | N_I32 | N_I64)) != 0)
5287ad62 14309 *type = NT_integer;
dcbf9037 14310 else if ((mask & (N_8 | N_16 | N_32 | N_64)) != 0)
5287ad62 14311 *type = NT_untyped;
4f51b4bd 14312 else if ((mask & (N_P8 | N_P16 | N_P64)) != 0)
5287ad62 14313 *type = NT_poly;
d54af2d0 14314 else if ((mask & (N_F_ALL)) != 0)
5287ad62 14315 *type = NT_float;
dcbf9037
JB
14316 else
14317 return FAIL;
5f4273c7 14318
dcbf9037 14319 return SUCCESS;
5287ad62
JB
14320}
14321
14322/* Modify a bitmask of allowed types. This is only needed for type
14323 relaxation. */
14324
14325static unsigned
14326modify_types_allowed (unsigned allowed, unsigned mods)
14327{
14328 unsigned size;
14329 enum neon_el_type type;
14330 unsigned destmask;
14331 int i;
5f4273c7 14332
5287ad62 14333 destmask = 0;
5f4273c7 14334
5287ad62
JB
14335 for (i = 1; i <= N_MAX_NONSPECIAL; i <<= 1)
14336 {
21d799b5 14337 if (el_type_of_type_chk (&type, &size,
477330fc
RM
14338 (enum neon_type_mask) (allowed & i)) == SUCCESS)
14339 {
14340 neon_modify_type_size (mods, &type, &size);
14341 destmask |= type_chk_of_el_type (type, size);
14342 }
5287ad62 14343 }
5f4273c7 14344
5287ad62
JB
14345 return destmask;
14346}
14347
14348/* Check type and return type classification.
14349 The manual states (paraphrase): If one datatype is given, it indicates the
14350 type given in:
14351 - the second operand, if there is one
14352 - the operand, if there is no second operand
14353 - the result, if there are no operands.
14354 This isn't quite good enough though, so we use a concept of a "key" datatype
14355 which is set on a per-instruction basis, which is the one which matters when
14356 only one data type is written.
14357 Note: this function has side-effects (e.g. filling in missing operands). All
037e8744 14358 Neon instructions should call it before performing bit encoding. */
5287ad62
JB
14359
14360static struct neon_type_el
14361neon_check_type (unsigned els, enum neon_shape ns, ...)
14362{
14363 va_list ap;
14364 unsigned i, pass, key_el = 0;
14365 unsigned types[NEON_MAX_TYPE_ELS];
14366 enum neon_el_type k_type = NT_invtype;
14367 unsigned k_size = -1u;
14368 struct neon_type_el badtype = {NT_invtype, -1};
14369 unsigned key_allowed = 0;
14370
14371 /* Optional registers in Neon instructions are always (not) in operand 1.
14372 Fill in the missing operand here, if it was omitted. */
14373 if (els > 1 && !inst.operands[1].present)
14374 inst.operands[1] = inst.operands[0];
14375
14376 /* Suck up all the varargs. */
14377 va_start (ap, ns);
14378 for (i = 0; i < els; i++)
14379 {
14380 unsigned thisarg = va_arg (ap, unsigned);
14381 if (thisarg == N_IGNORE_TYPE)
477330fc
RM
14382 {
14383 va_end (ap);
14384 return badtype;
14385 }
5287ad62
JB
14386 types[i] = thisarg;
14387 if ((thisarg & N_KEY) != 0)
477330fc 14388 key_el = i;
5287ad62
JB
14389 }
14390 va_end (ap);
14391
dcbf9037
JB
14392 if (inst.vectype.elems > 0)
14393 for (i = 0; i < els; i++)
14394 if (inst.operands[i].vectype.type != NT_invtype)
477330fc
RM
14395 {
14396 first_error (_("types specified in both the mnemonic and operands"));
14397 return badtype;
14398 }
dcbf9037 14399
5287ad62
JB
14400 /* Duplicate inst.vectype elements here as necessary.
14401 FIXME: No idea if this is exactly the same as the ARM assembler,
14402 particularly when an insn takes one register and one non-register
14403 operand. */
14404 if (inst.vectype.elems == 1 && els > 1)
14405 {
14406 unsigned j;
14407 inst.vectype.elems = els;
14408 inst.vectype.el[key_el] = inst.vectype.el[0];
14409 for (j = 0; j < els; j++)
477330fc
RM
14410 if (j != key_el)
14411 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
14412 types[j]);
dcbf9037
JB
14413 }
14414 else if (inst.vectype.elems == 0 && els > 0)
14415 {
14416 unsigned j;
14417 /* No types were given after the mnemonic, so look for types specified
477330fc
RM
14418 after each operand. We allow some flexibility here; as long as the
14419 "key" operand has a type, we can infer the others. */
dcbf9037 14420 for (j = 0; j < els; j++)
477330fc
RM
14421 if (inst.operands[j].vectype.type != NT_invtype)
14422 inst.vectype.el[j] = inst.operands[j].vectype;
dcbf9037
JB
14423
14424 if (inst.operands[key_el].vectype.type != NT_invtype)
477330fc
RM
14425 {
14426 for (j = 0; j < els; j++)
14427 if (inst.operands[j].vectype.type == NT_invtype)
14428 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
14429 types[j]);
14430 }
dcbf9037 14431 else
477330fc
RM
14432 {
14433 first_error (_("operand types can't be inferred"));
14434 return badtype;
14435 }
5287ad62
JB
14436 }
14437 else if (inst.vectype.elems != els)
14438 {
dcbf9037 14439 first_error (_("type specifier has the wrong number of parts"));
5287ad62
JB
14440 return badtype;
14441 }
14442
14443 for (pass = 0; pass < 2; pass++)
14444 {
14445 for (i = 0; i < els; i++)
477330fc
RM
14446 {
14447 unsigned thisarg = types[i];
14448 unsigned types_allowed = ((thisarg & N_EQK) != 0 && pass != 0)
14449 ? modify_types_allowed (key_allowed, thisarg) : thisarg;
14450 enum neon_el_type g_type = inst.vectype.el[i].type;
14451 unsigned g_size = inst.vectype.el[i].size;
14452
14453 /* Decay more-specific signed & unsigned types to sign-insensitive
5287ad62 14454 integer types if sign-specific variants are unavailable. */
477330fc 14455 if ((g_type == NT_signed || g_type == NT_unsigned)
5287ad62
JB
14456 && (types_allowed & N_SU_ALL) == 0)
14457 g_type = NT_integer;
14458
477330fc 14459 /* If only untyped args are allowed, decay any more specific types to
5287ad62
JB
14460 them. Some instructions only care about signs for some element
14461 sizes, so handle that properly. */
477330fc 14462 if (((types_allowed & N_UNT) == 0)
91ff7894
MGD
14463 && ((g_size == 8 && (types_allowed & N_8) != 0)
14464 || (g_size == 16 && (types_allowed & N_16) != 0)
14465 || (g_size == 32 && (types_allowed & N_32) != 0)
14466 || (g_size == 64 && (types_allowed & N_64) != 0)))
5287ad62
JB
14467 g_type = NT_untyped;
14468
477330fc
RM
14469 if (pass == 0)
14470 {
14471 if ((thisarg & N_KEY) != 0)
14472 {
14473 k_type = g_type;
14474 k_size = g_size;
14475 key_allowed = thisarg & ~N_KEY;
cc933301
JW
14476
14477 /* Check architecture constraint on FP16 extension. */
14478 if (k_size == 16
14479 && k_type == NT_float
14480 && ! ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
14481 {
14482 inst.error = _(BAD_FP16);
14483 return badtype;
14484 }
477330fc
RM
14485 }
14486 }
14487 else
14488 {
14489 if ((thisarg & N_VFP) != 0)
14490 {
14491 enum neon_shape_el regshape;
14492 unsigned regwidth, match;
99b253c5
NC
14493
14494 /* PR 11136: Catch the case where we are passed a shape of NS_NULL. */
14495 if (ns == NS_NULL)
14496 {
14497 first_error (_("invalid instruction shape"));
14498 return badtype;
14499 }
477330fc
RM
14500 regshape = neon_shape_tab[ns].el[i];
14501 regwidth = neon_shape_el_size[regshape];
14502
14503 /* In VFP mode, operands must match register widths. If we
14504 have a key operand, use its width, else use the width of
14505 the current operand. */
14506 if (k_size != -1u)
14507 match = k_size;
14508 else
14509 match = g_size;
14510
9db2f6b4
RL
14511 /* FP16 will use a single precision register. */
14512 if (regwidth == 32 && match == 16)
14513 {
14514 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
14515 match = regwidth;
14516 else
14517 {
14518 inst.error = _(BAD_FP16);
14519 return badtype;
14520 }
14521 }
14522
477330fc
RM
14523 if (regwidth != match)
14524 {
14525 first_error (_("operand size must match register width"));
14526 return badtype;
14527 }
14528 }
14529
14530 if ((thisarg & N_EQK) == 0)
14531 {
14532 unsigned given_type = type_chk_of_el_type (g_type, g_size);
14533
14534 if ((given_type & types_allowed) == 0)
14535 {
14536 first_error (_("bad type in Neon instruction"));
14537 return badtype;
14538 }
14539 }
14540 else
14541 {
14542 enum neon_el_type mod_k_type = k_type;
14543 unsigned mod_k_size = k_size;
14544 neon_modify_type_size (thisarg, &mod_k_type, &mod_k_size);
14545 if (g_type != mod_k_type || g_size != mod_k_size)
14546 {
14547 first_error (_("inconsistent types in Neon instruction"));
14548 return badtype;
14549 }
14550 }
14551 }
14552 }
5287ad62
JB
14553 }
14554
14555 return inst.vectype.el[key_el];
14556}
14557
037e8744 14558/* Neon-style VFP instruction forwarding. */
5287ad62 14559
037e8744
JB
14560/* Thumb VFP instructions have 0xE in the condition field. */
14561
14562static void
14563do_vfp_cond_or_thumb (void)
5287ad62 14564{
88714cb8
DG
14565 inst.is_neon = 1;
14566
5287ad62 14567 if (thumb_mode)
037e8744 14568 inst.instruction |= 0xe0000000;
5287ad62 14569 else
037e8744 14570 inst.instruction |= inst.cond << 28;
5287ad62
JB
14571}
14572
037e8744
JB
14573/* Look up and encode a simple mnemonic, for use as a helper function for the
14574 Neon-style VFP syntax. This avoids duplication of bits of the insns table,
14575 etc. It is assumed that operand parsing has already been done, and that the
14576 operands are in the form expected by the given opcode (this isn't necessarily
14577 the same as the form in which they were parsed, hence some massaging must
14578 take place before this function is called).
14579 Checks current arch version against that in the looked-up opcode. */
5287ad62 14580
037e8744
JB
14581static void
14582do_vfp_nsyn_opcode (const char *opname)
5287ad62 14583{
037e8744 14584 const struct asm_opcode *opcode;
5f4273c7 14585
21d799b5 14586 opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, opname);
5287ad62 14587
037e8744
JB
14588 if (!opcode)
14589 abort ();
5287ad62 14590
037e8744 14591 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant,
477330fc
RM
14592 thumb_mode ? *opcode->tvariant : *opcode->avariant),
14593 _(BAD_FPU));
5287ad62 14594
88714cb8
DG
14595 inst.is_neon = 1;
14596
037e8744
JB
14597 if (thumb_mode)
14598 {
14599 inst.instruction = opcode->tvalue;
14600 opcode->tencode ();
14601 }
14602 else
14603 {
14604 inst.instruction = (inst.cond << 28) | opcode->avalue;
14605 opcode->aencode ();
14606 }
14607}
5287ad62
JB
14608
14609static void
037e8744 14610do_vfp_nsyn_add_sub (enum neon_shape rs)
5287ad62 14611{
037e8744
JB
14612 int is_add = (inst.instruction & 0x0fffffff) == N_MNEM_vadd;
14613
9db2f6b4 14614 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
14615 {
14616 if (is_add)
477330fc 14617 do_vfp_nsyn_opcode ("fadds");
037e8744 14618 else
477330fc 14619 do_vfp_nsyn_opcode ("fsubs");
9db2f6b4
RL
14620
14621 /* ARMv8.2 fp16 instruction. */
14622 if (rs == NS_HHH)
14623 do_scalar_fp16_v82_encode ();
037e8744
JB
14624 }
14625 else
14626 {
14627 if (is_add)
477330fc 14628 do_vfp_nsyn_opcode ("faddd");
037e8744 14629 else
477330fc 14630 do_vfp_nsyn_opcode ("fsubd");
037e8744
JB
14631 }
14632}
14633
14634/* Check operand types to see if this is a VFP instruction, and if so call
14635 PFN (). */
14636
14637static int
14638try_vfp_nsyn (int args, void (*pfn) (enum neon_shape))
14639{
14640 enum neon_shape rs;
14641 struct neon_type_el et;
14642
14643 switch (args)
14644 {
14645 case 2:
9db2f6b4
RL
14646 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
14647 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
037e8744 14648 break;
5f4273c7 14649
037e8744 14650 case 3:
9db2f6b4
RL
14651 rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
14652 et = neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
14653 N_F_ALL | N_KEY | N_VFP);
037e8744
JB
14654 break;
14655
14656 default:
14657 abort ();
14658 }
14659
14660 if (et.type != NT_invtype)
14661 {
14662 pfn (rs);
14663 return SUCCESS;
14664 }
037e8744 14665
99b253c5 14666 inst.error = NULL;
037e8744
JB
14667 return FAIL;
14668}
14669
14670static void
14671do_vfp_nsyn_mla_mls (enum neon_shape rs)
14672{
14673 int is_mla = (inst.instruction & 0x0fffffff) == N_MNEM_vmla;
5f4273c7 14674
9db2f6b4 14675 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
14676 {
14677 if (is_mla)
477330fc 14678 do_vfp_nsyn_opcode ("fmacs");
037e8744 14679 else
477330fc 14680 do_vfp_nsyn_opcode ("fnmacs");
9db2f6b4
RL
14681
14682 /* ARMv8.2 fp16 instruction. */
14683 if (rs == NS_HHH)
14684 do_scalar_fp16_v82_encode ();
037e8744
JB
14685 }
14686 else
14687 {
14688 if (is_mla)
477330fc 14689 do_vfp_nsyn_opcode ("fmacd");
037e8744 14690 else
477330fc 14691 do_vfp_nsyn_opcode ("fnmacd");
037e8744
JB
14692 }
14693}
14694
62f3b8c8
PB
14695static void
14696do_vfp_nsyn_fma_fms (enum neon_shape rs)
14697{
14698 int is_fma = (inst.instruction & 0x0fffffff) == N_MNEM_vfma;
14699
9db2f6b4 14700 if (rs == NS_FFF || rs == NS_HHH)
62f3b8c8
PB
14701 {
14702 if (is_fma)
477330fc 14703 do_vfp_nsyn_opcode ("ffmas");
62f3b8c8 14704 else
477330fc 14705 do_vfp_nsyn_opcode ("ffnmas");
9db2f6b4
RL
14706
14707 /* ARMv8.2 fp16 instruction. */
14708 if (rs == NS_HHH)
14709 do_scalar_fp16_v82_encode ();
62f3b8c8
PB
14710 }
14711 else
14712 {
14713 if (is_fma)
477330fc 14714 do_vfp_nsyn_opcode ("ffmad");
62f3b8c8 14715 else
477330fc 14716 do_vfp_nsyn_opcode ("ffnmad");
62f3b8c8
PB
14717 }
14718}
14719
037e8744
JB
14720static void
14721do_vfp_nsyn_mul (enum neon_shape rs)
14722{
9db2f6b4
RL
14723 if (rs == NS_FFF || rs == NS_HHH)
14724 {
14725 do_vfp_nsyn_opcode ("fmuls");
14726
14727 /* ARMv8.2 fp16 instruction. */
14728 if (rs == NS_HHH)
14729 do_scalar_fp16_v82_encode ();
14730 }
037e8744
JB
14731 else
14732 do_vfp_nsyn_opcode ("fmuld");
14733}
14734
14735static void
14736do_vfp_nsyn_abs_neg (enum neon_shape rs)
14737{
14738 int is_neg = (inst.instruction & 0x80) != 0;
9db2f6b4 14739 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_VFP | N_KEY);
037e8744 14740
9db2f6b4 14741 if (rs == NS_FF || rs == NS_HH)
037e8744
JB
14742 {
14743 if (is_neg)
477330fc 14744 do_vfp_nsyn_opcode ("fnegs");
037e8744 14745 else
477330fc 14746 do_vfp_nsyn_opcode ("fabss");
9db2f6b4
RL
14747
14748 /* ARMv8.2 fp16 instruction. */
14749 if (rs == NS_HH)
14750 do_scalar_fp16_v82_encode ();
037e8744
JB
14751 }
14752 else
14753 {
14754 if (is_neg)
477330fc 14755 do_vfp_nsyn_opcode ("fnegd");
037e8744 14756 else
477330fc 14757 do_vfp_nsyn_opcode ("fabsd");
037e8744
JB
14758 }
14759}
14760
14761/* Encode single-precision (only!) VFP fldm/fstm instructions. Double precision
14762 insns belong to Neon, and are handled elsewhere. */
14763
14764static void
14765do_vfp_nsyn_ldm_stm (int is_dbmode)
14766{
14767 int is_ldm = (inst.instruction & (1 << 20)) != 0;
14768 if (is_ldm)
14769 {
14770 if (is_dbmode)
477330fc 14771 do_vfp_nsyn_opcode ("fldmdbs");
037e8744 14772 else
477330fc 14773 do_vfp_nsyn_opcode ("fldmias");
037e8744
JB
14774 }
14775 else
14776 {
14777 if (is_dbmode)
477330fc 14778 do_vfp_nsyn_opcode ("fstmdbs");
037e8744 14779 else
477330fc 14780 do_vfp_nsyn_opcode ("fstmias");
037e8744
JB
14781 }
14782}
14783
037e8744
JB
14784static void
14785do_vfp_nsyn_sqrt (void)
14786{
9db2f6b4
RL
14787 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
14788 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 14789
9db2f6b4
RL
14790 if (rs == NS_FF || rs == NS_HH)
14791 {
14792 do_vfp_nsyn_opcode ("fsqrts");
14793
14794 /* ARMv8.2 fp16 instruction. */
14795 if (rs == NS_HH)
14796 do_scalar_fp16_v82_encode ();
14797 }
037e8744
JB
14798 else
14799 do_vfp_nsyn_opcode ("fsqrtd");
14800}
14801
14802static void
14803do_vfp_nsyn_div (void)
14804{
9db2f6b4 14805 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 14806 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 14807 N_F_ALL | N_KEY | N_VFP);
5f4273c7 14808
9db2f6b4
RL
14809 if (rs == NS_FFF || rs == NS_HHH)
14810 {
14811 do_vfp_nsyn_opcode ("fdivs");
14812
14813 /* ARMv8.2 fp16 instruction. */
14814 if (rs == NS_HHH)
14815 do_scalar_fp16_v82_encode ();
14816 }
037e8744
JB
14817 else
14818 do_vfp_nsyn_opcode ("fdivd");
14819}
14820
14821static void
14822do_vfp_nsyn_nmul (void)
14823{
9db2f6b4 14824 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 14825 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 14826 N_F_ALL | N_KEY | N_VFP);
5f4273c7 14827
9db2f6b4 14828 if (rs == NS_FFF || rs == NS_HHH)
037e8744 14829 {
88714cb8 14830 NEON_ENCODE (SINGLE, inst);
037e8744 14831 do_vfp_sp_dyadic ();
9db2f6b4
RL
14832
14833 /* ARMv8.2 fp16 instruction. */
14834 if (rs == NS_HHH)
14835 do_scalar_fp16_v82_encode ();
037e8744
JB
14836 }
14837 else
14838 {
88714cb8 14839 NEON_ENCODE (DOUBLE, inst);
037e8744
JB
14840 do_vfp_dp_rd_rn_rm ();
14841 }
14842 do_vfp_cond_or_thumb ();
9db2f6b4 14843
037e8744
JB
14844}
14845
14846static void
14847do_vfp_nsyn_cmp (void)
14848{
9db2f6b4 14849 enum neon_shape rs;
037e8744
JB
14850 if (inst.operands[1].isreg)
14851 {
9db2f6b4
RL
14852 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
14853 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 14854
9db2f6b4 14855 if (rs == NS_FF || rs == NS_HH)
477330fc
RM
14856 {
14857 NEON_ENCODE (SINGLE, inst);
14858 do_vfp_sp_monadic ();
14859 }
037e8744 14860 else
477330fc
RM
14861 {
14862 NEON_ENCODE (DOUBLE, inst);
14863 do_vfp_dp_rd_rm ();
14864 }
037e8744
JB
14865 }
14866 else
14867 {
9db2f6b4
RL
14868 rs = neon_select_shape (NS_HI, NS_FI, NS_DI, NS_NULL);
14869 neon_check_type (2, rs, N_F_ALL | N_KEY | N_VFP, N_EQK);
037e8744
JB
14870
14871 switch (inst.instruction & 0x0fffffff)
477330fc
RM
14872 {
14873 case N_MNEM_vcmp:
14874 inst.instruction += N_MNEM_vcmpz - N_MNEM_vcmp;
14875 break;
14876 case N_MNEM_vcmpe:
14877 inst.instruction += N_MNEM_vcmpez - N_MNEM_vcmpe;
14878 break;
14879 default:
14880 abort ();
14881 }
5f4273c7 14882
9db2f6b4 14883 if (rs == NS_FI || rs == NS_HI)
477330fc
RM
14884 {
14885 NEON_ENCODE (SINGLE, inst);
14886 do_vfp_sp_compare_z ();
14887 }
037e8744 14888 else
477330fc
RM
14889 {
14890 NEON_ENCODE (DOUBLE, inst);
14891 do_vfp_dp_rd ();
14892 }
037e8744
JB
14893 }
14894 do_vfp_cond_or_thumb ();
9db2f6b4
RL
14895
14896 /* ARMv8.2 fp16 instruction. */
14897 if (rs == NS_HI || rs == NS_HH)
14898 do_scalar_fp16_v82_encode ();
037e8744
JB
14899}
14900
14901static void
14902nsyn_insert_sp (void)
14903{
14904 inst.operands[1] = inst.operands[0];
14905 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
fdfde340 14906 inst.operands[0].reg = REG_SP;
037e8744
JB
14907 inst.operands[0].isreg = 1;
14908 inst.operands[0].writeback = 1;
14909 inst.operands[0].present = 1;
14910}
14911
14912static void
14913do_vfp_nsyn_push (void)
14914{
14915 nsyn_insert_sp ();
b126985e
NC
14916
14917 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
14918 _("register list must contain at least 1 and at most 16 "
14919 "registers"));
14920
037e8744
JB
14921 if (inst.operands[1].issingle)
14922 do_vfp_nsyn_opcode ("fstmdbs");
14923 else
14924 do_vfp_nsyn_opcode ("fstmdbd");
14925}
14926
14927static void
14928do_vfp_nsyn_pop (void)
14929{
14930 nsyn_insert_sp ();
b126985e
NC
14931
14932 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
14933 _("register list must contain at least 1 and at most 16 "
14934 "registers"));
14935
037e8744 14936 if (inst.operands[1].issingle)
22b5b651 14937 do_vfp_nsyn_opcode ("fldmias");
037e8744 14938 else
22b5b651 14939 do_vfp_nsyn_opcode ("fldmiad");
037e8744
JB
14940}
14941
14942/* Fix up Neon data-processing instructions, ORing in the correct bits for
14943 ARM mode or Thumb mode and moving the encoded bit 24 to bit 28. */
14944
88714cb8
DG
14945static void
14946neon_dp_fixup (struct arm_it* insn)
037e8744 14947{
88714cb8
DG
14948 unsigned int i = insn->instruction;
14949 insn->is_neon = 1;
14950
037e8744
JB
14951 if (thumb_mode)
14952 {
14953 /* The U bit is at bit 24 by default. Move to bit 28 in Thumb mode. */
14954 if (i & (1 << 24))
477330fc 14955 i |= 1 << 28;
5f4273c7 14956
037e8744 14957 i &= ~(1 << 24);
5f4273c7 14958
037e8744
JB
14959 i |= 0xef000000;
14960 }
14961 else
14962 i |= 0xf2000000;
5f4273c7 14963
88714cb8 14964 insn->instruction = i;
037e8744
JB
14965}
14966
14967/* Turn a size (8, 16, 32, 64) into the respective bit number minus 3
14968 (0, 1, 2, 3). */
14969
14970static unsigned
14971neon_logbits (unsigned x)
14972{
14973 return ffs (x) - 4;
14974}
14975
14976#define LOW4(R) ((R) & 0xf)
14977#define HI1(R) (((R) >> 4) & 1)
14978
14979/* Encode insns with bit pattern:
14980
14981 |28/24|23|22 |21 20|19 16|15 12|11 8|7|6|5|4|3 0|
14982 | U |x |D |size | Rn | Rd |x x x x|N|Q|M|x| Rm |
5f4273c7 14983
037e8744
JB
14984 SIZE is passed in bits. -1 means size field isn't changed, in case it has a
14985 different meaning for some instruction. */
14986
14987static void
14988neon_three_same (int isquad, int ubit, int size)
14989{
14990 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
14991 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
14992 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
14993 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
14994 inst.instruction |= LOW4 (inst.operands[2].reg);
14995 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
14996 inst.instruction |= (isquad != 0) << 6;
14997 inst.instruction |= (ubit != 0) << 24;
14998 if (size != -1)
14999 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 15000
88714cb8 15001 neon_dp_fixup (&inst);
037e8744
JB
15002}
15003
15004/* Encode instructions of the form:
15005
15006 |28/24|23|22|21 20|19 18|17 16|15 12|11 7|6|5|4|3 0|
15007 | U |x |D |x x |size |x x | Rd |x x x x x|Q|M|x| Rm |
5287ad62
JB
15008
15009 Don't write size if SIZE == -1. */
15010
15011static void
15012neon_two_same (int qbit, int ubit, int size)
15013{
15014 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15015 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15016 inst.instruction |= LOW4 (inst.operands[1].reg);
15017 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
15018 inst.instruction |= (qbit != 0) << 6;
15019 inst.instruction |= (ubit != 0) << 24;
15020
15021 if (size != -1)
15022 inst.instruction |= neon_logbits (size) << 18;
15023
88714cb8 15024 neon_dp_fixup (&inst);
5287ad62
JB
15025}
15026
15027/* Neon instruction encoders, in approximate order of appearance. */
15028
15029static void
15030do_neon_dyadic_i_su (void)
15031{
037e8744 15032 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
15033 struct neon_type_el et = neon_check_type (3, rs,
15034 N_EQK, N_EQK, N_SU_32 | N_KEY);
037e8744 15035 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
15036}
15037
15038static void
15039do_neon_dyadic_i64_su (void)
15040{
037e8744 15041 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
15042 struct neon_type_el et = neon_check_type (3, rs,
15043 N_EQK, N_EQK, N_SU_ALL | N_KEY);
037e8744 15044 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
15045}
15046
15047static void
15048neon_imm_shift (int write_ubit, int uval, int isquad, struct neon_type_el et,
477330fc 15049 unsigned immbits)
5287ad62
JB
15050{
15051 unsigned size = et.size >> 3;
15052 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15053 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15054 inst.instruction |= LOW4 (inst.operands[1].reg);
15055 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
15056 inst.instruction |= (isquad != 0) << 6;
15057 inst.instruction |= immbits << 16;
15058 inst.instruction |= (size >> 3) << 7;
15059 inst.instruction |= (size & 0x7) << 19;
15060 if (write_ubit)
15061 inst.instruction |= (uval != 0) << 24;
15062
88714cb8 15063 neon_dp_fixup (&inst);
5287ad62
JB
15064}
15065
15066static void
15067do_neon_shl_imm (void)
15068{
15069 if (!inst.operands[2].isreg)
15070 {
037e8744 15071 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62 15072 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_KEY | N_I_ALL);
cb3b1e65
JB
15073 int imm = inst.operands[2].imm;
15074
15075 constraint (imm < 0 || (unsigned)imm >= et.size,
15076 _("immediate out of range for shift"));
88714cb8 15077 NEON_ENCODE (IMMED, inst);
cb3b1e65 15078 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
15079 }
15080 else
15081 {
037e8744 15082 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62 15083 struct neon_type_el et = neon_check_type (3, rs,
477330fc 15084 N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
627907b7
JB
15085 unsigned int tmp;
15086
15087 /* VSHL/VQSHL 3-register variants have syntax such as:
477330fc
RM
15088 vshl.xx Dd, Dm, Dn
15089 whereas other 3-register operations encoded by neon_three_same have
15090 syntax like:
15091 vadd.xx Dd, Dn, Dm
15092 (i.e. with Dn & Dm reversed). Swap operands[1].reg and operands[2].reg
15093 here. */
627907b7
JB
15094 tmp = inst.operands[2].reg;
15095 inst.operands[2].reg = inst.operands[1].reg;
15096 inst.operands[1].reg = tmp;
88714cb8 15097 NEON_ENCODE (INTEGER, inst);
037e8744 15098 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
15099 }
15100}
15101
15102static void
15103do_neon_qshl_imm (void)
15104{
15105 if (!inst.operands[2].isreg)
15106 {
037e8744 15107 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62 15108 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
cb3b1e65 15109 int imm = inst.operands[2].imm;
627907b7 15110
cb3b1e65
JB
15111 constraint (imm < 0 || (unsigned)imm >= et.size,
15112 _("immediate out of range for shift"));
88714cb8 15113 NEON_ENCODE (IMMED, inst);
cb3b1e65 15114 neon_imm_shift (TRUE, et.type == NT_unsigned, neon_quad (rs), et, imm);
5287ad62
JB
15115 }
15116 else
15117 {
037e8744 15118 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62 15119 struct neon_type_el et = neon_check_type (3, rs,
477330fc 15120 N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
627907b7
JB
15121 unsigned int tmp;
15122
15123 /* See note in do_neon_shl_imm. */
15124 tmp = inst.operands[2].reg;
15125 inst.operands[2].reg = inst.operands[1].reg;
15126 inst.operands[1].reg = tmp;
88714cb8 15127 NEON_ENCODE (INTEGER, inst);
037e8744 15128 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
15129 }
15130}
15131
627907b7
JB
15132static void
15133do_neon_rshl (void)
15134{
15135 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
15136 struct neon_type_el et = neon_check_type (3, rs,
15137 N_EQK, N_EQK, N_SU_ALL | N_KEY);
15138 unsigned int tmp;
15139
15140 tmp = inst.operands[2].reg;
15141 inst.operands[2].reg = inst.operands[1].reg;
15142 inst.operands[1].reg = tmp;
15143 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
15144}
15145
5287ad62
JB
15146static int
15147neon_cmode_for_logic_imm (unsigned immediate, unsigned *immbits, int size)
15148{
036dc3f7
PB
15149 /* Handle .I8 pseudo-instructions. */
15150 if (size == 8)
5287ad62 15151 {
5287ad62 15152 /* Unfortunately, this will make everything apart from zero out-of-range.
477330fc
RM
15153 FIXME is this the intended semantics? There doesn't seem much point in
15154 accepting .I8 if so. */
5287ad62
JB
15155 immediate |= immediate << 8;
15156 size = 16;
036dc3f7
PB
15157 }
15158
15159 if (size >= 32)
15160 {
15161 if (immediate == (immediate & 0x000000ff))
15162 {
15163 *immbits = immediate;
15164 return 0x1;
15165 }
15166 else if (immediate == (immediate & 0x0000ff00))
15167 {
15168 *immbits = immediate >> 8;
15169 return 0x3;
15170 }
15171 else if (immediate == (immediate & 0x00ff0000))
15172 {
15173 *immbits = immediate >> 16;
15174 return 0x5;
15175 }
15176 else if (immediate == (immediate & 0xff000000))
15177 {
15178 *immbits = immediate >> 24;
15179 return 0x7;
15180 }
15181 if ((immediate & 0xffff) != (immediate >> 16))
15182 goto bad_immediate;
15183 immediate &= 0xffff;
5287ad62
JB
15184 }
15185
15186 if (immediate == (immediate & 0x000000ff))
15187 {
15188 *immbits = immediate;
036dc3f7 15189 return 0x9;
5287ad62
JB
15190 }
15191 else if (immediate == (immediate & 0x0000ff00))
15192 {
15193 *immbits = immediate >> 8;
036dc3f7 15194 return 0xb;
5287ad62
JB
15195 }
15196
15197 bad_immediate:
dcbf9037 15198 first_error (_("immediate value out of range"));
5287ad62
JB
15199 return FAIL;
15200}
15201
5287ad62
JB
15202static void
15203do_neon_logic (void)
15204{
15205 if (inst.operands[2].present && inst.operands[2].isreg)
15206 {
037e8744 15207 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
15208 neon_check_type (3, rs, N_IGNORE_TYPE);
15209 /* U bit and size field were set as part of the bitmask. */
88714cb8 15210 NEON_ENCODE (INTEGER, inst);
037e8744 15211 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
15212 }
15213 else
15214 {
4316f0d2
DG
15215 const int three_ops_form = (inst.operands[2].present
15216 && !inst.operands[2].isreg);
15217 const int immoperand = (three_ops_form ? 2 : 1);
15218 enum neon_shape rs = (three_ops_form
15219 ? neon_select_shape (NS_DDI, NS_QQI, NS_NULL)
15220 : neon_select_shape (NS_DI, NS_QI, NS_NULL));
037e8744 15221 struct neon_type_el et = neon_check_type (2, rs,
477330fc 15222 N_I8 | N_I16 | N_I32 | N_I64 | N_F32 | N_KEY, N_EQK);
21d799b5 15223 enum neon_opc opcode = (enum neon_opc) inst.instruction & 0x0fffffff;
5287ad62
JB
15224 unsigned immbits;
15225 int cmode;
5f4273c7 15226
5287ad62 15227 if (et.type == NT_invtype)
477330fc 15228 return;
5f4273c7 15229
4316f0d2
DG
15230 if (three_ops_form)
15231 constraint (inst.operands[0].reg != inst.operands[1].reg,
15232 _("first and second operands shall be the same register"));
15233
88714cb8 15234 NEON_ENCODE (IMMED, inst);
5287ad62 15235
4316f0d2 15236 immbits = inst.operands[immoperand].imm;
036dc3f7
PB
15237 if (et.size == 64)
15238 {
15239 /* .i64 is a pseudo-op, so the immediate must be a repeating
15240 pattern. */
4316f0d2
DG
15241 if (immbits != (inst.operands[immoperand].regisimm ?
15242 inst.operands[immoperand].reg : 0))
036dc3f7
PB
15243 {
15244 /* Set immbits to an invalid constant. */
15245 immbits = 0xdeadbeef;
15246 }
15247 }
15248
5287ad62 15249 switch (opcode)
477330fc
RM
15250 {
15251 case N_MNEM_vbic:
15252 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
15253 break;
15254
15255 case N_MNEM_vorr:
15256 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
15257 break;
15258
15259 case N_MNEM_vand:
15260 /* Pseudo-instruction for VBIC. */
15261 neon_invert_size (&immbits, 0, et.size);
15262 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
15263 break;
15264
15265 case N_MNEM_vorn:
15266 /* Pseudo-instruction for VORR. */
15267 neon_invert_size (&immbits, 0, et.size);
15268 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
15269 break;
15270
15271 default:
15272 abort ();
15273 }
5287ad62
JB
15274
15275 if (cmode == FAIL)
477330fc 15276 return;
5287ad62 15277
037e8744 15278 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
15279 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15280 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15281 inst.instruction |= cmode << 8;
15282 neon_write_immbits (immbits);
5f4273c7 15283
88714cb8 15284 neon_dp_fixup (&inst);
5287ad62
JB
15285 }
15286}
15287
15288static void
15289do_neon_bitfield (void)
15290{
037e8744 15291 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
dcbf9037 15292 neon_check_type (3, rs, N_IGNORE_TYPE);
037e8744 15293 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
15294}
15295
15296static void
dcbf9037 15297neon_dyadic_misc (enum neon_el_type ubit_meaning, unsigned types,
477330fc 15298 unsigned destbits)
5287ad62 15299{
037e8744 15300 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
dcbf9037 15301 struct neon_type_el et = neon_check_type (3, rs, N_EQK | destbits, N_EQK,
477330fc 15302 types | N_KEY);
5287ad62
JB
15303 if (et.type == NT_float)
15304 {
88714cb8 15305 NEON_ENCODE (FLOAT, inst);
cc933301 15306 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
15307 }
15308 else
15309 {
88714cb8 15310 NEON_ENCODE (INTEGER, inst);
037e8744 15311 neon_three_same (neon_quad (rs), et.type == ubit_meaning, et.size);
5287ad62
JB
15312 }
15313}
15314
15315static void
15316do_neon_dyadic_if_su (void)
15317{
dcbf9037 15318 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
5287ad62
JB
15319}
15320
15321static void
15322do_neon_dyadic_if_su_d (void)
15323{
15324 /* This version only allow D registers, but that constraint is enforced during
15325 operand parsing so we don't need to do anything extra here. */
dcbf9037 15326 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
5287ad62
JB
15327}
15328
5287ad62
JB
15329static void
15330do_neon_dyadic_if_i_d (void)
15331{
428e3f1f
PB
15332 /* The "untyped" case can't happen. Do this to stop the "U" bit being
15333 affected if we specify unsigned args. */
15334 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
5287ad62
JB
15335}
15336
037e8744
JB
15337enum vfp_or_neon_is_neon_bits
15338{
15339 NEON_CHECK_CC = 1,
73924fbc
MGD
15340 NEON_CHECK_ARCH = 2,
15341 NEON_CHECK_ARCH8 = 4
037e8744
JB
15342};
15343
15344/* Call this function if an instruction which may have belonged to the VFP or
15345 Neon instruction sets, but turned out to be a Neon instruction (due to the
15346 operand types involved, etc.). We have to check and/or fix-up a couple of
15347 things:
15348
15349 - Make sure the user hasn't attempted to make a Neon instruction
15350 conditional.
15351 - Alter the value in the condition code field if necessary.
15352 - Make sure that the arch supports Neon instructions.
15353
15354 Which of these operations take place depends on bits from enum
15355 vfp_or_neon_is_neon_bits.
15356
15357 WARNING: This function has side effects! If NEON_CHECK_CC is used and the
15358 current instruction's condition is COND_ALWAYS, the condition field is
15359 changed to inst.uncond_value. This is necessary because instructions shared
15360 between VFP and Neon may be conditional for the VFP variants only, and the
15361 unconditional Neon version must have, e.g., 0xF in the condition field. */
15362
15363static int
15364vfp_or_neon_is_neon (unsigned check)
15365{
15366 /* Conditions are always legal in Thumb mode (IT blocks). */
15367 if (!thumb_mode && (check & NEON_CHECK_CC))
15368 {
15369 if (inst.cond != COND_ALWAYS)
477330fc
RM
15370 {
15371 first_error (_(BAD_COND));
15372 return FAIL;
15373 }
037e8744 15374 if (inst.uncond_value != -1)
477330fc 15375 inst.instruction |= inst.uncond_value << 28;
037e8744 15376 }
5f4273c7 15377
037e8744 15378 if ((check & NEON_CHECK_ARCH)
73924fbc
MGD
15379 && !mark_feature_used (&fpu_neon_ext_v1))
15380 {
15381 first_error (_(BAD_FPU));
15382 return FAIL;
15383 }
15384
15385 if ((check & NEON_CHECK_ARCH8)
15386 && !mark_feature_used (&fpu_neon_ext_armv8))
037e8744
JB
15387 {
15388 first_error (_(BAD_FPU));
15389 return FAIL;
15390 }
5f4273c7 15391
037e8744
JB
15392 return SUCCESS;
15393}
15394
5287ad62
JB
15395static void
15396do_neon_addsub_if_i (void)
15397{
037e8744
JB
15398 if (try_vfp_nsyn (3, do_vfp_nsyn_add_sub) == SUCCESS)
15399 return;
15400
15401 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
15402 return;
15403
5287ad62
JB
15404 /* The "untyped" case can't happen. Do this to stop the "U" bit being
15405 affected if we specify unsigned args. */
dcbf9037 15406 neon_dyadic_misc (NT_untyped, N_IF_32 | N_I64, 0);
5287ad62
JB
15407}
15408
15409/* Swaps operands 1 and 2. If operand 1 (optional arg) was omitted, we want the
15410 result to be:
15411 V<op> A,B (A is operand 0, B is operand 2)
15412 to mean:
15413 V<op> A,B,A
15414 not:
15415 V<op> A,B,B
15416 so handle that case specially. */
15417
15418static void
15419neon_exchange_operands (void)
15420{
5287ad62
JB
15421 if (inst.operands[1].present)
15422 {
e1fa0163
NC
15423 void *scratch = xmalloc (sizeof (inst.operands[0]));
15424
5287ad62
JB
15425 /* Swap operands[1] and operands[2]. */
15426 memcpy (scratch, &inst.operands[1], sizeof (inst.operands[0]));
15427 inst.operands[1] = inst.operands[2];
15428 memcpy (&inst.operands[2], scratch, sizeof (inst.operands[0]));
e1fa0163 15429 free (scratch);
5287ad62
JB
15430 }
15431 else
15432 {
15433 inst.operands[1] = inst.operands[2];
15434 inst.operands[2] = inst.operands[0];
15435 }
15436}
15437
15438static void
15439neon_compare (unsigned regtypes, unsigned immtypes, int invert)
15440{
15441 if (inst.operands[2].isreg)
15442 {
15443 if (invert)
477330fc 15444 neon_exchange_operands ();
dcbf9037 15445 neon_dyadic_misc (NT_unsigned, regtypes, N_SIZ);
5287ad62
JB
15446 }
15447 else
15448 {
037e8744 15449 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
dcbf9037 15450 struct neon_type_el et = neon_check_type (2, rs,
477330fc 15451 N_EQK | N_SIZ, immtypes | N_KEY);
5287ad62 15452
88714cb8 15453 NEON_ENCODE (IMMED, inst);
5287ad62
JB
15454 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15455 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15456 inst.instruction |= LOW4 (inst.operands[1].reg);
15457 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 15458 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
15459 inst.instruction |= (et.type == NT_float) << 10;
15460 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 15461
88714cb8 15462 neon_dp_fixup (&inst);
5287ad62
JB
15463 }
15464}
15465
15466static void
15467do_neon_cmp (void)
15468{
cc933301 15469 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, FALSE);
5287ad62
JB
15470}
15471
15472static void
15473do_neon_cmp_inv (void)
15474{
cc933301 15475 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, TRUE);
5287ad62
JB
15476}
15477
15478static void
15479do_neon_ceq (void)
15480{
15481 neon_compare (N_IF_32, N_IF_32, FALSE);
15482}
15483
15484/* For multiply instructions, we have the possibility of 16-bit or 32-bit
15485 scalars, which are encoded in 5 bits, M : Rm.
15486 For 16-bit scalars, the register is encoded in Rm[2:0] and the index in
15487 M:Rm[3], and for 32-bit scalars, the register is encoded in Rm[3:0] and the
c604a79a
JW
15488 index in M.
15489
15490 Dot Product instructions are similar to multiply instructions except elsize
15491 should always be 32.
15492
15493 This function translates SCALAR, which is GAS's internal encoding of indexed
15494 scalar register, to raw encoding. There is also register and index range
15495 check based on ELSIZE. */
5287ad62
JB
15496
15497static unsigned
15498neon_scalar_for_mul (unsigned scalar, unsigned elsize)
15499{
dcbf9037
JB
15500 unsigned regno = NEON_SCALAR_REG (scalar);
15501 unsigned elno = NEON_SCALAR_INDEX (scalar);
5287ad62
JB
15502
15503 switch (elsize)
15504 {
15505 case 16:
15506 if (regno > 7 || elno > 3)
477330fc 15507 goto bad_scalar;
5287ad62 15508 return regno | (elno << 3);
5f4273c7 15509
5287ad62
JB
15510 case 32:
15511 if (regno > 15 || elno > 1)
477330fc 15512 goto bad_scalar;
5287ad62
JB
15513 return regno | (elno << 4);
15514
15515 default:
15516 bad_scalar:
dcbf9037 15517 first_error (_("scalar out of range for multiply instruction"));
5287ad62
JB
15518 }
15519
15520 return 0;
15521}
15522
15523/* Encode multiply / multiply-accumulate scalar instructions. */
15524
15525static void
15526neon_mul_mac (struct neon_type_el et, int ubit)
15527{
dcbf9037
JB
15528 unsigned scalar;
15529
15530 /* Give a more helpful error message if we have an invalid type. */
15531 if (et.type == NT_invtype)
15532 return;
5f4273c7 15533
dcbf9037 15534 scalar = neon_scalar_for_mul (inst.operands[2].reg, et.size);
5287ad62
JB
15535 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15536 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15537 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15538 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
15539 inst.instruction |= LOW4 (scalar);
15540 inst.instruction |= HI1 (scalar) << 5;
15541 inst.instruction |= (et.type == NT_float) << 8;
15542 inst.instruction |= neon_logbits (et.size) << 20;
15543 inst.instruction |= (ubit != 0) << 24;
15544
88714cb8 15545 neon_dp_fixup (&inst);
5287ad62
JB
15546}
15547
15548static void
15549do_neon_mac_maybe_scalar (void)
15550{
037e8744
JB
15551 if (try_vfp_nsyn (3, do_vfp_nsyn_mla_mls) == SUCCESS)
15552 return;
15553
15554 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
15555 return;
15556
5287ad62
JB
15557 if (inst.operands[2].isscalar)
15558 {
037e8744 15559 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 15560 struct neon_type_el et = neon_check_type (3, rs,
589a7d88 15561 N_EQK, N_EQK, N_I16 | N_I32 | N_F_16_32 | N_KEY);
88714cb8 15562 NEON_ENCODE (SCALAR, inst);
037e8744 15563 neon_mul_mac (et, neon_quad (rs));
5287ad62
JB
15564 }
15565 else
428e3f1f
PB
15566 {
15567 /* The "untyped" case can't happen. Do this to stop the "U" bit being
15568 affected if we specify unsigned args. */
15569 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
15570 }
5287ad62
JB
15571}
15572
62f3b8c8
PB
15573static void
15574do_neon_fmac (void)
15575{
15576 if (try_vfp_nsyn (3, do_vfp_nsyn_fma_fms) == SUCCESS)
15577 return;
15578
15579 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
15580 return;
15581
15582 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
15583}
15584
5287ad62
JB
15585static void
15586do_neon_tst (void)
15587{
037e8744 15588 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
15589 struct neon_type_el et = neon_check_type (3, rs,
15590 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_KEY);
037e8744 15591 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
15592}
15593
15594/* VMUL with 3 registers allows the P8 type. The scalar version supports the
15595 same types as the MAC equivalents. The polynomial type for this instruction
15596 is encoded the same as the integer type. */
15597
15598static void
15599do_neon_mul (void)
15600{
037e8744
JB
15601 if (try_vfp_nsyn (3, do_vfp_nsyn_mul) == SUCCESS)
15602 return;
15603
15604 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
15605 return;
15606
5287ad62
JB
15607 if (inst.operands[2].isscalar)
15608 do_neon_mac_maybe_scalar ();
15609 else
cc933301 15610 neon_dyadic_misc (NT_poly, N_I8 | N_I16 | N_I32 | N_F16 | N_F32 | N_P8, 0);
5287ad62
JB
15611}
15612
15613static void
15614do_neon_qdmulh (void)
15615{
15616 if (inst.operands[2].isscalar)
15617 {
037e8744 15618 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 15619 struct neon_type_el et = neon_check_type (3, rs,
477330fc 15620 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
88714cb8 15621 NEON_ENCODE (SCALAR, inst);
037e8744 15622 neon_mul_mac (et, neon_quad (rs));
5287ad62
JB
15623 }
15624 else
15625 {
037e8744 15626 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62 15627 struct neon_type_el et = neon_check_type (3, rs,
477330fc 15628 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
88714cb8 15629 NEON_ENCODE (INTEGER, inst);
5287ad62 15630 /* The U bit (rounding) comes from bit mask. */
037e8744 15631 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
15632 }
15633}
15634
643afb90
MW
15635static void
15636do_neon_qrdmlah (void)
15637{
15638 /* Check we're on the correct architecture. */
15639 if (!mark_feature_used (&fpu_neon_ext_armv8))
15640 inst.error =
15641 _("instruction form not available on this architecture.");
15642 else if (!mark_feature_used (&fpu_neon_ext_v8_1))
15643 {
15644 as_warn (_("this instruction implies use of ARMv8.1 AdvSIMD."));
15645 record_feature_use (&fpu_neon_ext_v8_1);
15646 }
15647
15648 if (inst.operands[2].isscalar)
15649 {
15650 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
15651 struct neon_type_el et = neon_check_type (3, rs,
15652 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
15653 NEON_ENCODE (SCALAR, inst);
15654 neon_mul_mac (et, neon_quad (rs));
15655 }
15656 else
15657 {
15658 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
15659 struct neon_type_el et = neon_check_type (3, rs,
15660 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
15661 NEON_ENCODE (INTEGER, inst);
15662 /* The U bit (rounding) comes from bit mask. */
15663 neon_three_same (neon_quad (rs), 0, et.size);
15664 }
15665}
15666
5287ad62
JB
15667static void
15668do_neon_fcmp_absolute (void)
15669{
037e8744 15670 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
15671 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
15672 N_F_16_32 | N_KEY);
5287ad62 15673 /* Size field comes from bit mask. */
cc933301 15674 neon_three_same (neon_quad (rs), 1, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
15675}
15676
15677static void
15678do_neon_fcmp_absolute_inv (void)
15679{
15680 neon_exchange_operands ();
15681 do_neon_fcmp_absolute ();
15682}
15683
15684static void
15685do_neon_step (void)
15686{
037e8744 15687 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
15688 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
15689 N_F_16_32 | N_KEY);
15690 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
15691}
15692
15693static void
15694do_neon_abs_neg (void)
15695{
037e8744
JB
15696 enum neon_shape rs;
15697 struct neon_type_el et;
5f4273c7 15698
037e8744
JB
15699 if (try_vfp_nsyn (2, do_vfp_nsyn_abs_neg) == SUCCESS)
15700 return;
15701
15702 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
15703 return;
15704
15705 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
cc933301 15706 et = neon_check_type (2, rs, N_EQK, N_S_32 | N_F_16_32 | N_KEY);
5f4273c7 15707
5287ad62
JB
15708 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15709 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15710 inst.instruction |= LOW4 (inst.operands[1].reg);
15711 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 15712 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
15713 inst.instruction |= (et.type == NT_float) << 10;
15714 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 15715
88714cb8 15716 neon_dp_fixup (&inst);
5287ad62
JB
15717}
15718
15719static void
15720do_neon_sli (void)
15721{
037e8744 15722 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
15723 struct neon_type_el et = neon_check_type (2, rs,
15724 N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
15725 int imm = inst.operands[2].imm;
15726 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 15727 _("immediate out of range for insert"));
037e8744 15728 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
15729}
15730
15731static void
15732do_neon_sri (void)
15733{
037e8744 15734 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
15735 struct neon_type_el et = neon_check_type (2, rs,
15736 N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
15737 int imm = inst.operands[2].imm;
15738 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 15739 _("immediate out of range for insert"));
037e8744 15740 neon_imm_shift (FALSE, 0, neon_quad (rs), et, et.size - imm);
5287ad62
JB
15741}
15742
15743static void
15744do_neon_qshlu_imm (void)
15745{
037e8744 15746 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
15747 struct neon_type_el et = neon_check_type (2, rs,
15748 N_EQK | N_UNS, N_S8 | N_S16 | N_S32 | N_S64 | N_KEY);
15749 int imm = inst.operands[2].imm;
15750 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 15751 _("immediate out of range for shift"));
5287ad62
JB
15752 /* Only encodes the 'U present' variant of the instruction.
15753 In this case, signed types have OP (bit 8) set to 0.
15754 Unsigned types have OP set to 1. */
15755 inst.instruction |= (et.type == NT_unsigned) << 8;
15756 /* The rest of the bits are the same as other immediate shifts. */
037e8744 15757 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
15758}
15759
15760static void
15761do_neon_qmovn (void)
15762{
15763 struct neon_type_el et = neon_check_type (2, NS_DQ,
15764 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
15765 /* Saturating move where operands can be signed or unsigned, and the
15766 destination has the same signedness. */
88714cb8 15767 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
15768 if (et.type == NT_unsigned)
15769 inst.instruction |= 0xc0;
15770 else
15771 inst.instruction |= 0x80;
15772 neon_two_same (0, 1, et.size / 2);
15773}
15774
15775static void
15776do_neon_qmovun (void)
15777{
15778 struct neon_type_el et = neon_check_type (2, NS_DQ,
15779 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
15780 /* Saturating move with unsigned results. Operands must be signed. */
88714cb8 15781 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
15782 neon_two_same (0, 1, et.size / 2);
15783}
15784
15785static void
15786do_neon_rshift_sat_narrow (void)
15787{
15788 /* FIXME: Types for narrowing. If operands are signed, results can be signed
15789 or unsigned. If operands are unsigned, results must also be unsigned. */
15790 struct neon_type_el et = neon_check_type (2, NS_DQI,
15791 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
15792 int imm = inst.operands[2].imm;
15793 /* This gets the bounds check, size encoding and immediate bits calculation
15794 right. */
15795 et.size /= 2;
5f4273c7 15796
5287ad62
JB
15797 /* VQ{R}SHRN.I<size> <Dd>, <Qm>, #0 is a synonym for
15798 VQMOVN.I<size> <Dd>, <Qm>. */
15799 if (imm == 0)
15800 {
15801 inst.operands[2].present = 0;
15802 inst.instruction = N_MNEM_vqmovn;
15803 do_neon_qmovn ();
15804 return;
15805 }
5f4273c7 15806
5287ad62 15807 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 15808 _("immediate out of range"));
5287ad62
JB
15809 neon_imm_shift (TRUE, et.type == NT_unsigned, 0, et, et.size - imm);
15810}
15811
15812static void
15813do_neon_rshift_sat_narrow_u (void)
15814{
15815 /* FIXME: Types for narrowing. If operands are signed, results can be signed
15816 or unsigned. If operands are unsigned, results must also be unsigned. */
15817 struct neon_type_el et = neon_check_type (2, NS_DQI,
15818 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
15819 int imm = inst.operands[2].imm;
15820 /* This gets the bounds check, size encoding and immediate bits calculation
15821 right. */
15822 et.size /= 2;
15823
15824 /* VQSHRUN.I<size> <Dd>, <Qm>, #0 is a synonym for
15825 VQMOVUN.I<size> <Dd>, <Qm>. */
15826 if (imm == 0)
15827 {
15828 inst.operands[2].present = 0;
15829 inst.instruction = N_MNEM_vqmovun;
15830 do_neon_qmovun ();
15831 return;
15832 }
15833
15834 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 15835 _("immediate out of range"));
5287ad62
JB
15836 /* FIXME: The manual is kind of unclear about what value U should have in
15837 VQ{R}SHRUN instructions, but U=0, op=0 definitely encodes VRSHR, so it
15838 must be 1. */
15839 neon_imm_shift (TRUE, 1, 0, et, et.size - imm);
15840}
15841
15842static void
15843do_neon_movn (void)
15844{
15845 struct neon_type_el et = neon_check_type (2, NS_DQ,
15846 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
88714cb8 15847 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
15848 neon_two_same (0, 1, et.size / 2);
15849}
15850
15851static void
15852do_neon_rshift_narrow (void)
15853{
15854 struct neon_type_el et = neon_check_type (2, NS_DQI,
15855 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
15856 int imm = inst.operands[2].imm;
15857 /* This gets the bounds check, size encoding and immediate bits calculation
15858 right. */
15859 et.size /= 2;
5f4273c7 15860
5287ad62
JB
15861 /* If immediate is zero then we are a pseudo-instruction for
15862 VMOVN.I<size> <Dd>, <Qm> */
15863 if (imm == 0)
15864 {
15865 inst.operands[2].present = 0;
15866 inst.instruction = N_MNEM_vmovn;
15867 do_neon_movn ();
15868 return;
15869 }
5f4273c7 15870
5287ad62 15871 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 15872 _("immediate out of range for narrowing operation"));
5287ad62
JB
15873 neon_imm_shift (FALSE, 0, 0, et, et.size - imm);
15874}
15875
15876static void
15877do_neon_shll (void)
15878{
15879 /* FIXME: Type checking when lengthening. */
15880 struct neon_type_el et = neon_check_type (2, NS_QDI,
15881 N_EQK | N_DBL, N_I8 | N_I16 | N_I32 | N_KEY);
15882 unsigned imm = inst.operands[2].imm;
15883
15884 if (imm == et.size)
15885 {
15886 /* Maximum shift variant. */
88714cb8 15887 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
15888 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15889 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15890 inst.instruction |= LOW4 (inst.operands[1].reg);
15891 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
15892 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 15893
88714cb8 15894 neon_dp_fixup (&inst);
5287ad62
JB
15895 }
15896 else
15897 {
15898 /* A more-specific type check for non-max versions. */
15899 et = neon_check_type (2, NS_QDI,
477330fc 15900 N_EQK | N_DBL, N_SU_32 | N_KEY);
88714cb8 15901 NEON_ENCODE (IMMED, inst);
5287ad62
JB
15902 neon_imm_shift (TRUE, et.type == NT_unsigned, 0, et, imm);
15903 }
15904}
15905
037e8744 15906/* Check the various types for the VCVT instruction, and return which version
5287ad62
JB
15907 the current instruction is. */
15908
6b9a8b67
MGD
15909#define CVT_FLAVOUR_VAR \
15910 CVT_VAR (s32_f32, N_S32, N_F32, whole_reg, "ftosls", "ftosis", "ftosizs") \
15911 CVT_VAR (u32_f32, N_U32, N_F32, whole_reg, "ftouls", "ftouis", "ftouizs") \
15912 CVT_VAR (f32_s32, N_F32, N_S32, whole_reg, "fsltos", "fsitos", NULL) \
15913 CVT_VAR (f32_u32, N_F32, N_U32, whole_reg, "fultos", "fuitos", NULL) \
15914 /* Half-precision conversions. */ \
cc933301
JW
15915 CVT_VAR (s16_f16, N_S16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
15916 CVT_VAR (u16_f16, N_U16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
15917 CVT_VAR (f16_s16, N_F16 | N_KEY, N_S16, whole_reg, NULL, NULL, NULL) \
15918 CVT_VAR (f16_u16, N_F16 | N_KEY, N_U16, whole_reg, NULL, NULL, NULL) \
6b9a8b67
MGD
15919 CVT_VAR (f32_f16, N_F32, N_F16, whole_reg, NULL, NULL, NULL) \
15920 CVT_VAR (f16_f32, N_F16, N_F32, whole_reg, NULL, NULL, NULL) \
9db2f6b4
RL
15921 /* New VCVT instructions introduced by ARMv8.2 fp16 extension. \
15922 Compared with single/double precision variants, only the co-processor \
15923 field is different, so the encoding flow is reused here. */ \
15924 CVT_VAR (f16_s32, N_F16 | N_KEY, N_S32, N_VFP, "fsltos", "fsitos", NULL) \
15925 CVT_VAR (f16_u32, N_F16 | N_KEY, N_U32, N_VFP, "fultos", "fuitos", NULL) \
15926 CVT_VAR (u32_f16, N_U32, N_F16 | N_KEY, N_VFP, "ftouls", "ftouis", "ftouizs")\
15927 CVT_VAR (s32_f16, N_S32, N_F16 | N_KEY, N_VFP, "ftosls", "ftosis", "ftosizs")\
6b9a8b67
MGD
15928 /* VFP instructions. */ \
15929 CVT_VAR (f32_f64, N_F32, N_F64, N_VFP, NULL, "fcvtsd", NULL) \
15930 CVT_VAR (f64_f32, N_F64, N_F32, N_VFP, NULL, "fcvtds", NULL) \
15931 CVT_VAR (s32_f64, N_S32, N_F64 | key, N_VFP, "ftosld", "ftosid", "ftosizd") \
15932 CVT_VAR (u32_f64, N_U32, N_F64 | key, N_VFP, "ftould", "ftouid", "ftouizd") \
15933 CVT_VAR (f64_s32, N_F64 | key, N_S32, N_VFP, "fsltod", "fsitod", NULL) \
15934 CVT_VAR (f64_u32, N_F64 | key, N_U32, N_VFP, "fultod", "fuitod", NULL) \
15935 /* VFP instructions with bitshift. */ \
15936 CVT_VAR (f32_s16, N_F32 | key, N_S16, N_VFP, "fshtos", NULL, NULL) \
15937 CVT_VAR (f32_u16, N_F32 | key, N_U16, N_VFP, "fuhtos", NULL, NULL) \
15938 CVT_VAR (f64_s16, N_F64 | key, N_S16, N_VFP, "fshtod", NULL, NULL) \
15939 CVT_VAR (f64_u16, N_F64 | key, N_U16, N_VFP, "fuhtod", NULL, NULL) \
15940 CVT_VAR (s16_f32, N_S16, N_F32 | key, N_VFP, "ftoshs", NULL, NULL) \
15941 CVT_VAR (u16_f32, N_U16, N_F32 | key, N_VFP, "ftouhs", NULL, NULL) \
15942 CVT_VAR (s16_f64, N_S16, N_F64 | key, N_VFP, "ftoshd", NULL, NULL) \
15943 CVT_VAR (u16_f64, N_U16, N_F64 | key, N_VFP, "ftouhd", NULL, NULL)
15944
15945#define CVT_VAR(C, X, Y, R, BSN, CN, ZN) \
15946 neon_cvt_flavour_##C,
15947
15948/* The different types of conversions we can do. */
15949enum neon_cvt_flavour
15950{
15951 CVT_FLAVOUR_VAR
15952 neon_cvt_flavour_invalid,
15953 neon_cvt_flavour_first_fp = neon_cvt_flavour_f32_f64
15954};
15955
15956#undef CVT_VAR
15957
15958static enum neon_cvt_flavour
15959get_neon_cvt_flavour (enum neon_shape rs)
5287ad62 15960{
6b9a8b67
MGD
15961#define CVT_VAR(C,X,Y,R,BSN,CN,ZN) \
15962 et = neon_check_type (2, rs, (R) | (X), (R) | (Y)); \
15963 if (et.type != NT_invtype) \
15964 { \
15965 inst.error = NULL; \
15966 return (neon_cvt_flavour_##C); \
5287ad62 15967 }
6b9a8b67 15968
5287ad62 15969 struct neon_type_el et;
037e8744 15970 unsigned whole_reg = (rs == NS_FFI || rs == NS_FD || rs == NS_DF
477330fc 15971 || rs == NS_FF) ? N_VFP : 0;
037e8744
JB
15972 /* The instruction versions which take an immediate take one register
15973 argument, which is extended to the width of the full register. Thus the
15974 "source" and "destination" registers must have the same width. Hack that
15975 here by making the size equal to the key (wider, in this case) operand. */
15976 unsigned key = (rs == NS_QQI || rs == NS_DDI || rs == NS_FFI) ? N_KEY : 0;
5f4273c7 15977
6b9a8b67
MGD
15978 CVT_FLAVOUR_VAR;
15979
15980 return neon_cvt_flavour_invalid;
5287ad62
JB
15981#undef CVT_VAR
15982}
15983
7e8e6784
MGD
15984enum neon_cvt_mode
15985{
15986 neon_cvt_mode_a,
15987 neon_cvt_mode_n,
15988 neon_cvt_mode_p,
15989 neon_cvt_mode_m,
15990 neon_cvt_mode_z,
30bdf752
MGD
15991 neon_cvt_mode_x,
15992 neon_cvt_mode_r
7e8e6784
MGD
15993};
15994
037e8744
JB
15995/* Neon-syntax VFP conversions. */
15996
5287ad62 15997static void
6b9a8b67 15998do_vfp_nsyn_cvt (enum neon_shape rs, enum neon_cvt_flavour flavour)
5287ad62 15999{
037e8744 16000 const char *opname = 0;
5f4273c7 16001
d54af2d0
RL
16002 if (rs == NS_DDI || rs == NS_QQI || rs == NS_FFI
16003 || rs == NS_FHI || rs == NS_HFI)
5287ad62 16004 {
037e8744
JB
16005 /* Conversions with immediate bitshift. */
16006 const char *enc[] =
477330fc 16007 {
6b9a8b67
MGD
16008#define CVT_VAR(C,A,B,R,BSN,CN,ZN) BSN,
16009 CVT_FLAVOUR_VAR
16010 NULL
16011#undef CVT_VAR
477330fc 16012 };
037e8744 16013
6b9a8b67 16014 if (flavour < (int) ARRAY_SIZE (enc))
477330fc
RM
16015 {
16016 opname = enc[flavour];
16017 constraint (inst.operands[0].reg != inst.operands[1].reg,
16018 _("operands 0 and 1 must be the same register"));
16019 inst.operands[1] = inst.operands[2];
16020 memset (&inst.operands[2], '\0', sizeof (inst.operands[2]));
16021 }
5287ad62
JB
16022 }
16023 else
16024 {
037e8744
JB
16025 /* Conversions without bitshift. */
16026 const char *enc[] =
477330fc 16027 {
6b9a8b67
MGD
16028#define CVT_VAR(C,A,B,R,BSN,CN,ZN) CN,
16029 CVT_FLAVOUR_VAR
16030 NULL
16031#undef CVT_VAR
477330fc 16032 };
037e8744 16033
6b9a8b67 16034 if (flavour < (int) ARRAY_SIZE (enc))
477330fc 16035 opname = enc[flavour];
037e8744
JB
16036 }
16037
16038 if (opname)
16039 do_vfp_nsyn_opcode (opname);
9db2f6b4
RL
16040
16041 /* ARMv8.2 fp16 VCVT instruction. */
16042 if (flavour == neon_cvt_flavour_s32_f16
16043 || flavour == neon_cvt_flavour_u32_f16
16044 || flavour == neon_cvt_flavour_f16_u32
16045 || flavour == neon_cvt_flavour_f16_s32)
16046 do_scalar_fp16_v82_encode ();
037e8744
JB
16047}
16048
16049static void
16050do_vfp_nsyn_cvtz (void)
16051{
d54af2d0 16052 enum neon_shape rs = neon_select_shape (NS_FH, NS_FF, NS_FD, NS_NULL);
6b9a8b67 16053 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744
JB
16054 const char *enc[] =
16055 {
6b9a8b67
MGD
16056#define CVT_VAR(C,A,B,R,BSN,CN,ZN) ZN,
16057 CVT_FLAVOUR_VAR
16058 NULL
16059#undef CVT_VAR
037e8744
JB
16060 };
16061
6b9a8b67 16062 if (flavour < (int) ARRAY_SIZE (enc) && enc[flavour])
037e8744
JB
16063 do_vfp_nsyn_opcode (enc[flavour]);
16064}
f31fef98 16065
037e8744 16066static void
bacebabc 16067do_vfp_nsyn_cvt_fpv8 (enum neon_cvt_flavour flavour,
7e8e6784
MGD
16068 enum neon_cvt_mode mode)
16069{
16070 int sz, op;
16071 int rm;
16072
a715796b
TG
16073 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
16074 D register operands. */
16075 if (flavour == neon_cvt_flavour_s32_f64
16076 || flavour == neon_cvt_flavour_u32_f64)
16077 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
16078 _(BAD_FPU));
16079
9db2f6b4
RL
16080 if (flavour == neon_cvt_flavour_s32_f16
16081 || flavour == neon_cvt_flavour_u32_f16)
16082 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
16083 _(BAD_FP16));
16084
7e8e6784
MGD
16085 set_it_insn_type (OUTSIDE_IT_INSN);
16086
16087 switch (flavour)
16088 {
16089 case neon_cvt_flavour_s32_f64:
16090 sz = 1;
827f64ff 16091 op = 1;
7e8e6784
MGD
16092 break;
16093 case neon_cvt_flavour_s32_f32:
16094 sz = 0;
16095 op = 1;
16096 break;
9db2f6b4
RL
16097 case neon_cvt_flavour_s32_f16:
16098 sz = 0;
16099 op = 1;
16100 break;
7e8e6784
MGD
16101 case neon_cvt_flavour_u32_f64:
16102 sz = 1;
16103 op = 0;
16104 break;
16105 case neon_cvt_flavour_u32_f32:
16106 sz = 0;
16107 op = 0;
16108 break;
9db2f6b4
RL
16109 case neon_cvt_flavour_u32_f16:
16110 sz = 0;
16111 op = 0;
16112 break;
7e8e6784
MGD
16113 default:
16114 first_error (_("invalid instruction shape"));
16115 return;
16116 }
16117
16118 switch (mode)
16119 {
16120 case neon_cvt_mode_a: rm = 0; break;
16121 case neon_cvt_mode_n: rm = 1; break;
16122 case neon_cvt_mode_p: rm = 2; break;
16123 case neon_cvt_mode_m: rm = 3; break;
16124 default: first_error (_("invalid rounding mode")); return;
16125 }
16126
16127 NEON_ENCODE (FPV8, inst);
16128 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
16129 encode_arm_vfp_reg (inst.operands[1].reg, sz == 1 ? VFP_REG_Dm : VFP_REG_Sm);
16130 inst.instruction |= sz << 8;
9db2f6b4
RL
16131
16132 /* ARMv8.2 fp16 VCVT instruction. */
16133 if (flavour == neon_cvt_flavour_s32_f16
16134 ||flavour == neon_cvt_flavour_u32_f16)
16135 do_scalar_fp16_v82_encode ();
7e8e6784
MGD
16136 inst.instruction |= op << 7;
16137 inst.instruction |= rm << 16;
16138 inst.instruction |= 0xf0000000;
16139 inst.is_neon = TRUE;
16140}
16141
16142static void
16143do_neon_cvt_1 (enum neon_cvt_mode mode)
037e8744
JB
16144{
16145 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_FFI, NS_DD, NS_QQ,
d54af2d0
RL
16146 NS_FD, NS_DF, NS_FF, NS_QD, NS_DQ,
16147 NS_FH, NS_HF, NS_FHI, NS_HFI,
16148 NS_NULL);
6b9a8b67 16149 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744 16150
cc933301
JW
16151 if (flavour == neon_cvt_flavour_invalid)
16152 return;
16153
e3e535bc 16154 /* PR11109: Handle round-to-zero for VCVT conversions. */
7e8e6784 16155 if (mode == neon_cvt_mode_z
e3e535bc 16156 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_vfp_v2)
cc933301
JW
16157 && (flavour == neon_cvt_flavour_s16_f16
16158 || flavour == neon_cvt_flavour_u16_f16
16159 || flavour == neon_cvt_flavour_s32_f32
bacebabc
RM
16160 || flavour == neon_cvt_flavour_u32_f32
16161 || flavour == neon_cvt_flavour_s32_f64
6b9a8b67 16162 || flavour == neon_cvt_flavour_u32_f64)
e3e535bc
NC
16163 && (rs == NS_FD || rs == NS_FF))
16164 {
16165 do_vfp_nsyn_cvtz ();
16166 return;
16167 }
16168
9db2f6b4
RL
16169 /* ARMv8.2 fp16 VCVT conversions. */
16170 if (mode == neon_cvt_mode_z
16171 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16)
16172 && (flavour == neon_cvt_flavour_s32_f16
16173 || flavour == neon_cvt_flavour_u32_f16)
16174 && (rs == NS_FH))
16175 {
16176 do_vfp_nsyn_cvtz ();
16177 do_scalar_fp16_v82_encode ();
16178 return;
16179 }
16180
037e8744 16181 /* VFP rather than Neon conversions. */
6b9a8b67 16182 if (flavour >= neon_cvt_flavour_first_fp)
037e8744 16183 {
7e8e6784
MGD
16184 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
16185 do_vfp_nsyn_cvt (rs, flavour);
16186 else
16187 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
16188
037e8744
JB
16189 return;
16190 }
16191
16192 switch (rs)
16193 {
16194 case NS_DDI:
16195 case NS_QQI:
16196 {
477330fc 16197 unsigned immbits;
cc933301
JW
16198 unsigned enctab[] = {0x0000100, 0x1000100, 0x0, 0x1000000,
16199 0x0000100, 0x1000100, 0x0, 0x1000000};
35997600 16200
477330fc
RM
16201 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
16202 return;
037e8744 16203
477330fc
RM
16204 /* Fixed-point conversion with #0 immediate is encoded as an
16205 integer conversion. */
16206 if (inst.operands[2].present && inst.operands[2].imm == 0)
16207 goto int_encode;
477330fc
RM
16208 NEON_ENCODE (IMMED, inst);
16209 if (flavour != neon_cvt_flavour_invalid)
16210 inst.instruction |= enctab[flavour];
16211 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16212 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16213 inst.instruction |= LOW4 (inst.operands[1].reg);
16214 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16215 inst.instruction |= neon_quad (rs) << 6;
16216 inst.instruction |= 1 << 21;
cc933301
JW
16217 if (flavour < neon_cvt_flavour_s16_f16)
16218 {
16219 inst.instruction |= 1 << 21;
16220 immbits = 32 - inst.operands[2].imm;
16221 inst.instruction |= immbits << 16;
16222 }
16223 else
16224 {
16225 inst.instruction |= 3 << 20;
16226 immbits = 16 - inst.operands[2].imm;
16227 inst.instruction |= immbits << 16;
16228 inst.instruction &= ~(1 << 9);
16229 }
477330fc
RM
16230
16231 neon_dp_fixup (&inst);
037e8744
JB
16232 }
16233 break;
16234
16235 case NS_DD:
16236 case NS_QQ:
7e8e6784
MGD
16237 if (mode != neon_cvt_mode_x && mode != neon_cvt_mode_z)
16238 {
16239 NEON_ENCODE (FLOAT, inst);
16240 set_it_insn_type (OUTSIDE_IT_INSN);
16241
16242 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH8) == FAIL)
16243 return;
16244
16245 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16246 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16247 inst.instruction |= LOW4 (inst.operands[1].reg);
16248 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16249 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
16250 inst.instruction |= (flavour == neon_cvt_flavour_u16_f16
16251 || flavour == neon_cvt_flavour_u32_f32) << 7;
7e8e6784 16252 inst.instruction |= mode << 8;
cc933301
JW
16253 if (flavour == neon_cvt_flavour_u16_f16
16254 || flavour == neon_cvt_flavour_s16_f16)
16255 /* Mask off the original size bits and reencode them. */
16256 inst.instruction = ((inst.instruction & 0xfff3ffff) | (1 << 18));
16257
7e8e6784
MGD
16258 if (thumb_mode)
16259 inst.instruction |= 0xfc000000;
16260 else
16261 inst.instruction |= 0xf0000000;
16262 }
16263 else
16264 {
037e8744 16265 int_encode:
7e8e6784 16266 {
cc933301
JW
16267 unsigned enctab[] = { 0x100, 0x180, 0x0, 0x080,
16268 0x100, 0x180, 0x0, 0x080};
037e8744 16269
7e8e6784 16270 NEON_ENCODE (INTEGER, inst);
037e8744 16271
7e8e6784
MGD
16272 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
16273 return;
037e8744 16274
7e8e6784
MGD
16275 if (flavour != neon_cvt_flavour_invalid)
16276 inst.instruction |= enctab[flavour];
037e8744 16277
7e8e6784
MGD
16278 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16279 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16280 inst.instruction |= LOW4 (inst.operands[1].reg);
16281 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16282 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
16283 if (flavour >= neon_cvt_flavour_s16_f16
16284 && flavour <= neon_cvt_flavour_f16_u16)
16285 /* Half precision. */
16286 inst.instruction |= 1 << 18;
16287 else
16288 inst.instruction |= 2 << 18;
037e8744 16289
7e8e6784
MGD
16290 neon_dp_fixup (&inst);
16291 }
16292 }
16293 break;
037e8744 16294
8e79c3df
CM
16295 /* Half-precision conversions for Advanced SIMD -- neon. */
16296 case NS_QD:
16297 case NS_DQ:
bc52d49c
MM
16298 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
16299 return;
8e79c3df
CM
16300
16301 if ((rs == NS_DQ)
16302 && (inst.vectype.el[0].size != 16 || inst.vectype.el[1].size != 32))
16303 {
16304 as_bad (_("operand size must match register width"));
16305 break;
16306 }
16307
16308 if ((rs == NS_QD)
16309 && ((inst.vectype.el[0].size != 32 || inst.vectype.el[1].size != 16)))
16310 {
16311 as_bad (_("operand size must match register width"));
16312 break;
16313 }
16314
16315 if (rs == NS_DQ)
477330fc 16316 inst.instruction = 0x3b60600;
8e79c3df
CM
16317 else
16318 inst.instruction = 0x3b60700;
16319
16320 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16321 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16322 inst.instruction |= LOW4 (inst.operands[1].reg);
16323 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
88714cb8 16324 neon_dp_fixup (&inst);
8e79c3df
CM
16325 break;
16326
037e8744
JB
16327 default:
16328 /* Some VFP conversions go here (s32 <-> f32, u32 <-> f32). */
7e8e6784
MGD
16329 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
16330 do_vfp_nsyn_cvt (rs, flavour);
16331 else
16332 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
5287ad62 16333 }
5287ad62
JB
16334}
16335
e3e535bc
NC
16336static void
16337do_neon_cvtr (void)
16338{
7e8e6784 16339 do_neon_cvt_1 (neon_cvt_mode_x);
e3e535bc
NC
16340}
16341
16342static void
16343do_neon_cvt (void)
16344{
7e8e6784
MGD
16345 do_neon_cvt_1 (neon_cvt_mode_z);
16346}
16347
16348static void
16349do_neon_cvta (void)
16350{
16351 do_neon_cvt_1 (neon_cvt_mode_a);
16352}
16353
16354static void
16355do_neon_cvtn (void)
16356{
16357 do_neon_cvt_1 (neon_cvt_mode_n);
16358}
16359
16360static void
16361do_neon_cvtp (void)
16362{
16363 do_neon_cvt_1 (neon_cvt_mode_p);
16364}
16365
16366static void
16367do_neon_cvtm (void)
16368{
16369 do_neon_cvt_1 (neon_cvt_mode_m);
e3e535bc
NC
16370}
16371
8e79c3df 16372static void
c70a8987 16373do_neon_cvttb_2 (bfd_boolean t, bfd_boolean to, bfd_boolean is_double)
8e79c3df 16374{
c70a8987
MGD
16375 if (is_double)
16376 mark_feature_used (&fpu_vfp_ext_armv8);
8e79c3df 16377
c70a8987
MGD
16378 encode_arm_vfp_reg (inst.operands[0].reg,
16379 (is_double && !to) ? VFP_REG_Dd : VFP_REG_Sd);
16380 encode_arm_vfp_reg (inst.operands[1].reg,
16381 (is_double && to) ? VFP_REG_Dm : VFP_REG_Sm);
16382 inst.instruction |= to ? 0x10000 : 0;
16383 inst.instruction |= t ? 0x80 : 0;
16384 inst.instruction |= is_double ? 0x100 : 0;
16385 do_vfp_cond_or_thumb ();
16386}
8e79c3df 16387
c70a8987
MGD
16388static void
16389do_neon_cvttb_1 (bfd_boolean t)
16390{
d54af2d0
RL
16391 enum neon_shape rs = neon_select_shape (NS_HF, NS_HD, NS_FH, NS_FF, NS_FD,
16392 NS_DF, NS_DH, NS_NULL);
8e79c3df 16393
c70a8987
MGD
16394 if (rs == NS_NULL)
16395 return;
16396 else if (neon_check_type (2, rs, N_F16, N_F32 | N_VFP).type != NT_invtype)
16397 {
16398 inst.error = NULL;
16399 do_neon_cvttb_2 (t, /*to=*/TRUE, /*is_double=*/FALSE);
16400 }
16401 else if (neon_check_type (2, rs, N_F32 | N_VFP, N_F16).type != NT_invtype)
16402 {
16403 inst.error = NULL;
16404 do_neon_cvttb_2 (t, /*to=*/FALSE, /*is_double=*/FALSE);
16405 }
16406 else if (neon_check_type (2, rs, N_F16, N_F64 | N_VFP).type != NT_invtype)
16407 {
a715796b
TG
16408 /* The VCVTB and VCVTT instructions with D-register operands
16409 don't work for SP only targets. */
16410 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
16411 _(BAD_FPU));
16412
c70a8987
MGD
16413 inst.error = NULL;
16414 do_neon_cvttb_2 (t, /*to=*/TRUE, /*is_double=*/TRUE);
16415 }
16416 else if (neon_check_type (2, rs, N_F64 | N_VFP, N_F16).type != NT_invtype)
16417 {
a715796b
TG
16418 /* The VCVTB and VCVTT instructions with D-register operands
16419 don't work for SP only targets. */
16420 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
16421 _(BAD_FPU));
16422
c70a8987
MGD
16423 inst.error = NULL;
16424 do_neon_cvttb_2 (t, /*to=*/FALSE, /*is_double=*/TRUE);
16425 }
16426 else
16427 return;
16428}
16429
16430static void
16431do_neon_cvtb (void)
16432{
16433 do_neon_cvttb_1 (FALSE);
8e79c3df
CM
16434}
16435
16436
16437static void
16438do_neon_cvtt (void)
16439{
c70a8987 16440 do_neon_cvttb_1 (TRUE);
8e79c3df
CM
16441}
16442
5287ad62
JB
16443static void
16444neon_move_immediate (void)
16445{
037e8744
JB
16446 enum neon_shape rs = neon_select_shape (NS_DI, NS_QI, NS_NULL);
16447 struct neon_type_el et = neon_check_type (2, rs,
16448 N_I8 | N_I16 | N_I32 | N_I64 | N_F32 | N_KEY, N_EQK);
5287ad62 16449 unsigned immlo, immhi = 0, immbits;
c96612cc 16450 int op, cmode, float_p;
5287ad62 16451
037e8744 16452 constraint (et.type == NT_invtype,
477330fc 16453 _("operand size must be specified for immediate VMOV"));
037e8744 16454
5287ad62
JB
16455 /* We start out as an MVN instruction if OP = 1, MOV otherwise. */
16456 op = (inst.instruction & (1 << 5)) != 0;
16457
16458 immlo = inst.operands[1].imm;
16459 if (inst.operands[1].regisimm)
16460 immhi = inst.operands[1].reg;
16461
16462 constraint (et.size < 32 && (immlo & ~((1 << et.size) - 1)) != 0,
477330fc 16463 _("immediate has bits set outside the operand size"));
5287ad62 16464
c96612cc
JB
16465 float_p = inst.operands[1].immisfloat;
16466
16467 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits, &op,
477330fc 16468 et.size, et.type)) == FAIL)
5287ad62
JB
16469 {
16470 /* Invert relevant bits only. */
16471 neon_invert_size (&immlo, &immhi, et.size);
16472 /* Flip from VMOV/VMVN to VMVN/VMOV. Some immediate types are unavailable
477330fc
RM
16473 with one or the other; those cases are caught by
16474 neon_cmode_for_move_imm. */
5287ad62 16475 op = !op;
c96612cc
JB
16476 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits,
16477 &op, et.size, et.type)) == FAIL)
477330fc
RM
16478 {
16479 first_error (_("immediate out of range"));
16480 return;
16481 }
5287ad62
JB
16482 }
16483
16484 inst.instruction &= ~(1 << 5);
16485 inst.instruction |= op << 5;
16486
16487 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16488 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
037e8744 16489 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
16490 inst.instruction |= cmode << 8;
16491
16492 neon_write_immbits (immbits);
16493}
16494
16495static void
16496do_neon_mvn (void)
16497{
16498 if (inst.operands[1].isreg)
16499 {
037e8744 16500 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5f4273c7 16501
88714cb8 16502 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
16503 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16504 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16505 inst.instruction |= LOW4 (inst.operands[1].reg);
16506 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 16507 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
16508 }
16509 else
16510 {
88714cb8 16511 NEON_ENCODE (IMMED, inst);
5287ad62
JB
16512 neon_move_immediate ();
16513 }
16514
88714cb8 16515 neon_dp_fixup (&inst);
5287ad62
JB
16516}
16517
16518/* Encode instructions of form:
16519
16520 |28/24|23|22|21 20|19 16|15 12|11 8|7|6|5|4|3 0|
5f4273c7 16521 | U |x |D |size | Rn | Rd |x x x x|N|x|M|x| Rm | */
5287ad62
JB
16522
16523static void
16524neon_mixed_length (struct neon_type_el et, unsigned size)
16525{
16526 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16527 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16528 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16529 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16530 inst.instruction |= LOW4 (inst.operands[2].reg);
16531 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16532 inst.instruction |= (et.type == NT_unsigned) << 24;
16533 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 16534
88714cb8 16535 neon_dp_fixup (&inst);
5287ad62
JB
16536}
16537
16538static void
16539do_neon_dyadic_long (void)
16540{
16541 /* FIXME: Type checking for lengthening op. */
16542 struct neon_type_el et = neon_check_type (3, NS_QDD,
16543 N_EQK | N_DBL, N_EQK, N_SU_32 | N_KEY);
16544 neon_mixed_length (et, et.size);
16545}
16546
16547static void
16548do_neon_abal (void)
16549{
16550 struct neon_type_el et = neon_check_type (3, NS_QDD,
16551 N_EQK | N_INT | N_DBL, N_EQK, N_SU_32 | N_KEY);
16552 neon_mixed_length (et, et.size);
16553}
16554
16555static void
16556neon_mac_reg_scalar_long (unsigned regtypes, unsigned scalartypes)
16557{
16558 if (inst.operands[2].isscalar)
16559 {
dcbf9037 16560 struct neon_type_el et = neon_check_type (3, NS_QDS,
477330fc 16561 N_EQK | N_DBL, N_EQK, regtypes | N_KEY);
88714cb8 16562 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
16563 neon_mul_mac (et, et.type == NT_unsigned);
16564 }
16565 else
16566 {
16567 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 16568 N_EQK | N_DBL, N_EQK, scalartypes | N_KEY);
88714cb8 16569 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
16570 neon_mixed_length (et, et.size);
16571 }
16572}
16573
16574static void
16575do_neon_mac_maybe_scalar_long (void)
16576{
16577 neon_mac_reg_scalar_long (N_S16 | N_S32 | N_U16 | N_U32, N_SU_32);
16578}
16579
dec41383
JW
16580/* Like neon_scalar_for_mul, this function generate Rm encoding from GAS's
16581 internal SCALAR. QUAD_P is 1 if it's for Q format, otherwise it's 0. */
16582
16583static unsigned
16584neon_scalar_for_fmac_fp16_long (unsigned scalar, unsigned quad_p)
16585{
16586 unsigned regno = NEON_SCALAR_REG (scalar);
16587 unsigned elno = NEON_SCALAR_INDEX (scalar);
16588
16589 if (quad_p)
16590 {
16591 if (regno > 7 || elno > 3)
16592 goto bad_scalar;
16593
16594 return ((regno & 0x7)
16595 | ((elno & 0x1) << 3)
16596 | (((elno >> 1) & 0x1) << 5));
16597 }
16598 else
16599 {
16600 if (regno > 15 || elno > 1)
16601 goto bad_scalar;
16602
16603 return (((regno & 0x1) << 5)
16604 | ((regno >> 1) & 0x7)
16605 | ((elno & 0x1) << 3));
16606 }
16607
16608bad_scalar:
16609 first_error (_("scalar out of range for multiply instruction"));
16610 return 0;
16611}
16612
16613static void
16614do_neon_fmac_maybe_scalar_long (int subtype)
16615{
16616 enum neon_shape rs;
16617 int high8;
16618 /* NOTE: vfmal/vfmsl use slightly different NEON three-same encoding. 'size"
16619 field (bits[21:20]) has different meaning. For scalar index variant, it's
16620 used to differentiate add and subtract, otherwise it's with fixed value
16621 0x2. */
16622 int size = -1;
16623
16624 if (inst.cond != COND_ALWAYS)
16625 as_warn (_("vfmal/vfmsl with FP16 type cannot be conditional, the "
16626 "behaviour is UNPREDICTABLE"));
16627
01f48020 16628 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16_fml),
dec41383
JW
16629 _(BAD_FP16));
16630
16631 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
16632 _(BAD_FPU));
16633
16634 /* vfmal/vfmsl are in three-same D/Q register format or the third operand can
16635 be a scalar index register. */
16636 if (inst.operands[2].isscalar)
16637 {
16638 high8 = 0xfe000000;
16639 if (subtype)
16640 size = 16;
16641 rs = neon_select_shape (NS_DHS, NS_QDS, NS_NULL);
16642 }
16643 else
16644 {
16645 high8 = 0xfc000000;
16646 size = 32;
16647 if (subtype)
16648 inst.instruction |= (0x1 << 23);
16649 rs = neon_select_shape (NS_DHH, NS_QDD, NS_NULL);
16650 }
16651
16652 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16);
16653
16654 /* "opcode" from template has included "ubit", so simply pass 0 here. Also,
16655 the "S" bit in size field has been reused to differentiate vfmal and vfmsl,
16656 so we simply pass -1 as size. */
16657 unsigned quad_p = (rs == NS_QDD || rs == NS_QDS);
16658 neon_three_same (quad_p, 0, size);
16659
16660 /* Undo neon_dp_fixup. Redo the high eight bits. */
16661 inst.instruction &= 0x00ffffff;
16662 inst.instruction |= high8;
16663
16664#define LOW1(R) ((R) & 0x1)
16665#define HI4(R) (((R) >> 1) & 0xf)
16666 /* Unlike usually NEON three-same, encoding for Vn and Vm will depend on
16667 whether the instruction is in Q form and whether Vm is a scalar indexed
16668 operand. */
16669 if (inst.operands[2].isscalar)
16670 {
16671 unsigned rm
16672 = neon_scalar_for_fmac_fp16_long (inst.operands[2].reg, quad_p);
16673 inst.instruction &= 0xffffffd0;
16674 inst.instruction |= rm;
16675
16676 if (!quad_p)
16677 {
16678 /* Redo Rn as well. */
16679 inst.instruction &= 0xfff0ff7f;
16680 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
16681 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
16682 }
16683 }
16684 else if (!quad_p)
16685 {
16686 /* Redo Rn and Rm. */
16687 inst.instruction &= 0xfff0ff50;
16688 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
16689 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
16690 inst.instruction |= HI4 (inst.operands[2].reg);
16691 inst.instruction |= LOW1 (inst.operands[2].reg) << 5;
16692 }
16693}
16694
16695static void
16696do_neon_vfmal (void)
16697{
16698 return do_neon_fmac_maybe_scalar_long (0);
16699}
16700
16701static void
16702do_neon_vfmsl (void)
16703{
16704 return do_neon_fmac_maybe_scalar_long (1);
16705}
16706
5287ad62
JB
16707static void
16708do_neon_dyadic_wide (void)
16709{
16710 struct neon_type_el et = neon_check_type (3, NS_QQD,
16711 N_EQK | N_DBL, N_EQK | N_DBL, N_SU_32 | N_KEY);
16712 neon_mixed_length (et, et.size);
16713}
16714
16715static void
16716do_neon_dyadic_narrow (void)
16717{
16718 struct neon_type_el et = neon_check_type (3, NS_QDD,
16719 N_EQK | N_DBL, N_EQK, N_I16 | N_I32 | N_I64 | N_KEY);
428e3f1f
PB
16720 /* Operand sign is unimportant, and the U bit is part of the opcode,
16721 so force the operand type to integer. */
16722 et.type = NT_integer;
5287ad62
JB
16723 neon_mixed_length (et, et.size / 2);
16724}
16725
16726static void
16727do_neon_mul_sat_scalar_long (void)
16728{
16729 neon_mac_reg_scalar_long (N_S16 | N_S32, N_S16 | N_S32);
16730}
16731
16732static void
16733do_neon_vmull (void)
16734{
16735 if (inst.operands[2].isscalar)
16736 do_neon_mac_maybe_scalar_long ();
16737 else
16738 {
16739 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 16740 N_EQK | N_DBL, N_EQK, N_SU_32 | N_P8 | N_P64 | N_KEY);
4f51b4bd 16741
5287ad62 16742 if (et.type == NT_poly)
477330fc 16743 NEON_ENCODE (POLY, inst);
5287ad62 16744 else
477330fc 16745 NEON_ENCODE (INTEGER, inst);
4f51b4bd
MGD
16746
16747 /* For polynomial encoding the U bit must be zero, and the size must
16748 be 8 (encoded as 0b00) or, on ARMv8 or later 64 (encoded, non
16749 obviously, as 0b10). */
16750 if (et.size == 64)
16751 {
16752 /* Check we're on the correct architecture. */
16753 if (!mark_feature_used (&fpu_crypto_ext_armv8))
16754 inst.error =
16755 _("Instruction form not available on this architecture.");
16756
16757 et.size = 32;
16758 }
16759
5287ad62
JB
16760 neon_mixed_length (et, et.size);
16761 }
16762}
16763
16764static void
16765do_neon_ext (void)
16766{
037e8744 16767 enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
5287ad62
JB
16768 struct neon_type_el et = neon_check_type (3, rs,
16769 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
16770 unsigned imm = (inst.operands[3].imm * et.size) / 8;
35997600
NC
16771
16772 constraint (imm >= (unsigned) (neon_quad (rs) ? 16 : 8),
16773 _("shift out of range"));
5287ad62
JB
16774 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16775 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16776 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16777 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16778 inst.instruction |= LOW4 (inst.operands[2].reg);
16779 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
037e8744 16780 inst.instruction |= neon_quad (rs) << 6;
5287ad62 16781 inst.instruction |= imm << 8;
5f4273c7 16782
88714cb8 16783 neon_dp_fixup (&inst);
5287ad62
JB
16784}
16785
16786static void
16787do_neon_rev (void)
16788{
037e8744 16789 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
16790 struct neon_type_el et = neon_check_type (2, rs,
16791 N_EQK, N_8 | N_16 | N_32 | N_KEY);
16792 unsigned op = (inst.instruction >> 7) & 3;
16793 /* N (width of reversed regions) is encoded as part of the bitmask. We
16794 extract it here to check the elements to be reversed are smaller.
16795 Otherwise we'd get a reserved instruction. */
16796 unsigned elsize = (op == 2) ? 16 : (op == 1) ? 32 : (op == 0) ? 64 : 0;
9c2799c2 16797 gas_assert (elsize != 0);
5287ad62 16798 constraint (et.size >= elsize,
477330fc 16799 _("elements must be smaller than reversal region"));
037e8744 16800 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
16801}
16802
16803static void
16804do_neon_dup (void)
16805{
16806 if (inst.operands[1].isscalar)
16807 {
037e8744 16808 enum neon_shape rs = neon_select_shape (NS_DS, NS_QS, NS_NULL);
dcbf9037 16809 struct neon_type_el et = neon_check_type (2, rs,
477330fc 16810 N_EQK, N_8 | N_16 | N_32 | N_KEY);
5287ad62 16811 unsigned sizebits = et.size >> 3;
dcbf9037 16812 unsigned dm = NEON_SCALAR_REG (inst.operands[1].reg);
5287ad62 16813 int logsize = neon_logbits (et.size);
dcbf9037 16814 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg) << logsize;
037e8744
JB
16815
16816 if (vfp_or_neon_is_neon (NEON_CHECK_CC) == FAIL)
477330fc 16817 return;
037e8744 16818
88714cb8 16819 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
16820 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16821 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16822 inst.instruction |= LOW4 (dm);
16823 inst.instruction |= HI1 (dm) << 5;
037e8744 16824 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
16825 inst.instruction |= x << 17;
16826 inst.instruction |= sizebits << 16;
5f4273c7 16827
88714cb8 16828 neon_dp_fixup (&inst);
5287ad62
JB
16829 }
16830 else
16831 {
037e8744
JB
16832 enum neon_shape rs = neon_select_shape (NS_DR, NS_QR, NS_NULL);
16833 struct neon_type_el et = neon_check_type (2, rs,
477330fc 16834 N_8 | N_16 | N_32 | N_KEY, N_EQK);
5287ad62 16835 /* Duplicate ARM register to lanes of vector. */
88714cb8 16836 NEON_ENCODE (ARMREG, inst);
5287ad62 16837 switch (et.size)
477330fc
RM
16838 {
16839 case 8: inst.instruction |= 0x400000; break;
16840 case 16: inst.instruction |= 0x000020; break;
16841 case 32: inst.instruction |= 0x000000; break;
16842 default: break;
16843 }
5287ad62
JB
16844 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
16845 inst.instruction |= LOW4 (inst.operands[0].reg) << 16;
16846 inst.instruction |= HI1 (inst.operands[0].reg) << 7;
037e8744 16847 inst.instruction |= neon_quad (rs) << 21;
5287ad62 16848 /* The encoding for this instruction is identical for the ARM and Thumb
477330fc 16849 variants, except for the condition field. */
037e8744 16850 do_vfp_cond_or_thumb ();
5287ad62
JB
16851 }
16852}
16853
16854/* VMOV has particularly many variations. It can be one of:
16855 0. VMOV<c><q> <Qd>, <Qm>
16856 1. VMOV<c><q> <Dd>, <Dm>
16857 (Register operations, which are VORR with Rm = Rn.)
16858 2. VMOV<c><q>.<dt> <Qd>, #<imm>
16859 3. VMOV<c><q>.<dt> <Dd>, #<imm>
16860 (Immediate loads.)
16861 4. VMOV<c><q>.<size> <Dn[x]>, <Rd>
16862 (ARM register to scalar.)
16863 5. VMOV<c><q> <Dm>, <Rd>, <Rn>
16864 (Two ARM registers to vector.)
16865 6. VMOV<c><q>.<dt> <Rd>, <Dn[x]>
16866 (Scalar to ARM register.)
16867 7. VMOV<c><q> <Rd>, <Rn>, <Dm>
16868 (Vector to two ARM registers.)
037e8744
JB
16869 8. VMOV.F32 <Sd>, <Sm>
16870 9. VMOV.F64 <Dd>, <Dm>
16871 (VFP register moves.)
16872 10. VMOV.F32 <Sd>, #imm
16873 11. VMOV.F64 <Dd>, #imm
16874 (VFP float immediate load.)
16875 12. VMOV <Rd>, <Sm>
16876 (VFP single to ARM reg.)
16877 13. VMOV <Sd>, <Rm>
16878 (ARM reg to VFP single.)
16879 14. VMOV <Rd>, <Re>, <Sn>, <Sm>
16880 (Two ARM regs to two VFP singles.)
16881 15. VMOV <Sd>, <Se>, <Rn>, <Rm>
16882 (Two VFP singles to two ARM regs.)
5f4273c7 16883
037e8744
JB
16884 These cases can be disambiguated using neon_select_shape, except cases 1/9
16885 and 3/11 which depend on the operand type too.
5f4273c7 16886
5287ad62 16887 All the encoded bits are hardcoded by this function.
5f4273c7 16888
b7fc2769
JB
16889 Cases 4, 6 may be used with VFPv1 and above (only 32-bit transfers!).
16890 Cases 5, 7 may be used with VFPv2 and above.
5f4273c7 16891
5287ad62 16892 FIXME: Some of the checking may be a bit sloppy (in a couple of cases you
5f4273c7 16893 can specify a type where it doesn't make sense to, and is ignored). */
5287ad62
JB
16894
16895static void
16896do_neon_mov (void)
16897{
037e8744 16898 enum neon_shape rs = neon_select_shape (NS_RRFF, NS_FFRR, NS_DRR, NS_RRD,
9db2f6b4
RL
16899 NS_QQ, NS_DD, NS_QI, NS_DI, NS_SR,
16900 NS_RS, NS_FF, NS_FI, NS_RF, NS_FR,
16901 NS_HR, NS_RH, NS_HI, NS_NULL);
037e8744
JB
16902 struct neon_type_el et;
16903 const char *ldconst = 0;
5287ad62 16904
037e8744 16905 switch (rs)
5287ad62 16906 {
037e8744
JB
16907 case NS_DD: /* case 1/9. */
16908 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
16909 /* It is not an error here if no type is given. */
16910 inst.error = NULL;
16911 if (et.type == NT_float && et.size == 64)
477330fc
RM
16912 {
16913 do_vfp_nsyn_opcode ("fcpyd");
16914 break;
16915 }
037e8744 16916 /* fall through. */
5287ad62 16917
037e8744
JB
16918 case NS_QQ: /* case 0/1. */
16919 {
477330fc
RM
16920 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
16921 return;
16922 /* The architecture manual I have doesn't explicitly state which
16923 value the U bit should have for register->register moves, but
16924 the equivalent VORR instruction has U = 0, so do that. */
16925 inst.instruction = 0x0200110;
16926 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16927 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16928 inst.instruction |= LOW4 (inst.operands[1].reg);
16929 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16930 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16931 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16932 inst.instruction |= neon_quad (rs) << 6;
16933
16934 neon_dp_fixup (&inst);
037e8744
JB
16935 }
16936 break;
5f4273c7 16937
037e8744
JB
16938 case NS_DI: /* case 3/11. */
16939 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
16940 inst.error = NULL;
16941 if (et.type == NT_float && et.size == 64)
477330fc
RM
16942 {
16943 /* case 11 (fconstd). */
16944 ldconst = "fconstd";
16945 goto encode_fconstd;
16946 }
037e8744
JB
16947 /* fall through. */
16948
16949 case NS_QI: /* case 2/3. */
16950 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
477330fc 16951 return;
037e8744
JB
16952 inst.instruction = 0x0800010;
16953 neon_move_immediate ();
88714cb8 16954 neon_dp_fixup (&inst);
5287ad62 16955 break;
5f4273c7 16956
037e8744
JB
16957 case NS_SR: /* case 4. */
16958 {
477330fc
RM
16959 unsigned bcdebits = 0;
16960 int logsize;
16961 unsigned dn = NEON_SCALAR_REG (inst.operands[0].reg);
16962 unsigned x = NEON_SCALAR_INDEX (inst.operands[0].reg);
037e8744 16963
05ac0ffb
JB
16964 /* .<size> is optional here, defaulting to .32. */
16965 if (inst.vectype.elems == 0
16966 && inst.operands[0].vectype.type == NT_invtype
16967 && inst.operands[1].vectype.type == NT_invtype)
16968 {
16969 inst.vectype.el[0].type = NT_untyped;
16970 inst.vectype.el[0].size = 32;
16971 inst.vectype.elems = 1;
16972 }
16973
477330fc
RM
16974 et = neon_check_type (2, NS_NULL, N_8 | N_16 | N_32 | N_KEY, N_EQK);
16975 logsize = neon_logbits (et.size);
16976
16977 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1),
16978 _(BAD_FPU));
16979 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1)
16980 && et.size != 32, _(BAD_FPU));
16981 constraint (et.type == NT_invtype, _("bad type for scalar"));
16982 constraint (x >= 64 / et.size, _("scalar index out of range"));
16983
16984 switch (et.size)
16985 {
16986 case 8: bcdebits = 0x8; break;
16987 case 16: bcdebits = 0x1; break;
16988 case 32: bcdebits = 0x0; break;
16989 default: ;
16990 }
16991
16992 bcdebits |= x << logsize;
16993
16994 inst.instruction = 0xe000b10;
16995 do_vfp_cond_or_thumb ();
16996 inst.instruction |= LOW4 (dn) << 16;
16997 inst.instruction |= HI1 (dn) << 7;
16998 inst.instruction |= inst.operands[1].reg << 12;
16999 inst.instruction |= (bcdebits & 3) << 5;
17000 inst.instruction |= (bcdebits >> 2) << 21;
037e8744
JB
17001 }
17002 break;
5f4273c7 17003
037e8744 17004 case NS_DRR: /* case 5 (fmdrr). */
b7fc2769 17005 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2),
477330fc 17006 _(BAD_FPU));
b7fc2769 17007
037e8744
JB
17008 inst.instruction = 0xc400b10;
17009 do_vfp_cond_or_thumb ();
17010 inst.instruction |= LOW4 (inst.operands[0].reg);
17011 inst.instruction |= HI1 (inst.operands[0].reg) << 5;
17012 inst.instruction |= inst.operands[1].reg << 12;
17013 inst.instruction |= inst.operands[2].reg << 16;
17014 break;
5f4273c7 17015
037e8744
JB
17016 case NS_RS: /* case 6. */
17017 {
477330fc
RM
17018 unsigned logsize;
17019 unsigned dn = NEON_SCALAR_REG (inst.operands[1].reg);
17020 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg);
17021 unsigned abcdebits = 0;
037e8744 17022
05ac0ffb
JB
17023 /* .<dt> is optional here, defaulting to .32. */
17024 if (inst.vectype.elems == 0
17025 && inst.operands[0].vectype.type == NT_invtype
17026 && inst.operands[1].vectype.type == NT_invtype)
17027 {
17028 inst.vectype.el[0].type = NT_untyped;
17029 inst.vectype.el[0].size = 32;
17030 inst.vectype.elems = 1;
17031 }
17032
91d6fa6a
NC
17033 et = neon_check_type (2, NS_NULL,
17034 N_EQK, N_S8 | N_S16 | N_U8 | N_U16 | N_32 | N_KEY);
477330fc
RM
17035 logsize = neon_logbits (et.size);
17036
17037 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1),
17038 _(BAD_FPU));
17039 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1)
17040 && et.size != 32, _(BAD_FPU));
17041 constraint (et.type == NT_invtype, _("bad type for scalar"));
17042 constraint (x >= 64 / et.size, _("scalar index out of range"));
17043
17044 switch (et.size)
17045 {
17046 case 8: abcdebits = (et.type == NT_signed) ? 0x08 : 0x18; break;
17047 case 16: abcdebits = (et.type == NT_signed) ? 0x01 : 0x11; break;
17048 case 32: abcdebits = 0x00; break;
17049 default: ;
17050 }
17051
17052 abcdebits |= x << logsize;
17053 inst.instruction = 0xe100b10;
17054 do_vfp_cond_or_thumb ();
17055 inst.instruction |= LOW4 (dn) << 16;
17056 inst.instruction |= HI1 (dn) << 7;
17057 inst.instruction |= inst.operands[0].reg << 12;
17058 inst.instruction |= (abcdebits & 3) << 5;
17059 inst.instruction |= (abcdebits >> 2) << 21;
037e8744
JB
17060 }
17061 break;
5f4273c7 17062
037e8744
JB
17063 case NS_RRD: /* case 7 (fmrrd). */
17064 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2),
477330fc 17065 _(BAD_FPU));
037e8744
JB
17066
17067 inst.instruction = 0xc500b10;
17068 do_vfp_cond_or_thumb ();
17069 inst.instruction |= inst.operands[0].reg << 12;
17070 inst.instruction |= inst.operands[1].reg << 16;
17071 inst.instruction |= LOW4 (inst.operands[2].reg);
17072 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
17073 break;
5f4273c7 17074
037e8744
JB
17075 case NS_FF: /* case 8 (fcpys). */
17076 do_vfp_nsyn_opcode ("fcpys");
17077 break;
5f4273c7 17078
9db2f6b4 17079 case NS_HI:
037e8744
JB
17080 case NS_FI: /* case 10 (fconsts). */
17081 ldconst = "fconsts";
4ef4710f 17082 encode_fconstd:
58ed5c38
TC
17083 if (!inst.operands[1].immisfloat)
17084 {
4ef4710f 17085 unsigned new_imm;
58ed5c38 17086 /* Immediate has to fit in 8 bits so float is enough. */
4ef4710f
NC
17087 float imm = (float) inst.operands[1].imm;
17088 memcpy (&new_imm, &imm, sizeof (float));
17089 /* But the assembly may have been written to provide an integer
17090 bit pattern that equates to a float, so check that the
17091 conversion has worked. */
17092 if (is_quarter_float (new_imm))
17093 {
17094 if (is_quarter_float (inst.operands[1].imm))
17095 as_warn (_("immediate constant is valid both as a bit-pattern and a floating point value (using the fp value)"));
17096
17097 inst.operands[1].imm = new_imm;
17098 inst.operands[1].immisfloat = 1;
17099 }
58ed5c38
TC
17100 }
17101
037e8744 17102 if (is_quarter_float (inst.operands[1].imm))
477330fc
RM
17103 {
17104 inst.operands[1].imm = neon_qfloat_bits (inst.operands[1].imm);
17105 do_vfp_nsyn_opcode (ldconst);
9db2f6b4
RL
17106
17107 /* ARMv8.2 fp16 vmov.f16 instruction. */
17108 if (rs == NS_HI)
17109 do_scalar_fp16_v82_encode ();
477330fc 17110 }
5287ad62 17111 else
477330fc 17112 first_error (_("immediate out of range"));
037e8744 17113 break;
5f4273c7 17114
9db2f6b4 17115 case NS_RH:
037e8744
JB
17116 case NS_RF: /* case 12 (fmrs). */
17117 do_vfp_nsyn_opcode ("fmrs");
9db2f6b4
RL
17118 /* ARMv8.2 fp16 vmov.f16 instruction. */
17119 if (rs == NS_RH)
17120 do_scalar_fp16_v82_encode ();
037e8744 17121 break;
5f4273c7 17122
9db2f6b4 17123 case NS_HR:
037e8744
JB
17124 case NS_FR: /* case 13 (fmsr). */
17125 do_vfp_nsyn_opcode ("fmsr");
9db2f6b4
RL
17126 /* ARMv8.2 fp16 vmov.f16 instruction. */
17127 if (rs == NS_HR)
17128 do_scalar_fp16_v82_encode ();
037e8744 17129 break;
5f4273c7 17130
037e8744
JB
17131 /* The encoders for the fmrrs and fmsrr instructions expect three operands
17132 (one of which is a list), but we have parsed four. Do some fiddling to
17133 make the operands what do_vfp_reg2_from_sp2 and do_vfp_sp2_from_reg2
17134 expect. */
17135 case NS_RRFF: /* case 14 (fmrrs). */
17136 constraint (inst.operands[3].reg != inst.operands[2].reg + 1,
477330fc 17137 _("VFP registers must be adjacent"));
037e8744
JB
17138 inst.operands[2].imm = 2;
17139 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
17140 do_vfp_nsyn_opcode ("fmrrs");
17141 break;
5f4273c7 17142
037e8744
JB
17143 case NS_FFRR: /* case 15 (fmsrr). */
17144 constraint (inst.operands[1].reg != inst.operands[0].reg + 1,
477330fc 17145 _("VFP registers must be adjacent"));
037e8744
JB
17146 inst.operands[1] = inst.operands[2];
17147 inst.operands[2] = inst.operands[3];
17148 inst.operands[0].imm = 2;
17149 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
17150 do_vfp_nsyn_opcode ("fmsrr");
5287ad62 17151 break;
5f4273c7 17152
4c261dff
NC
17153 case NS_NULL:
17154 /* neon_select_shape has determined that the instruction
17155 shape is wrong and has already set the error message. */
17156 break;
17157
5287ad62
JB
17158 default:
17159 abort ();
17160 }
17161}
17162
17163static void
17164do_neon_rshift_round_imm (void)
17165{
037e8744 17166 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
17167 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
17168 int imm = inst.operands[2].imm;
17169
17170 /* imm == 0 case is encoded as VMOV for V{R}SHR. */
17171 if (imm == 0)
17172 {
17173 inst.operands[2].present = 0;
17174 do_neon_mov ();
17175 return;
17176 }
17177
17178 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 17179 _("immediate out of range for shift"));
037e8744 17180 neon_imm_shift (TRUE, et.type == NT_unsigned, neon_quad (rs), et,
477330fc 17181 et.size - imm);
5287ad62
JB
17182}
17183
9db2f6b4
RL
17184static void
17185do_neon_movhf (void)
17186{
17187 enum neon_shape rs = neon_select_shape (NS_HH, NS_NULL);
17188 constraint (rs != NS_HH, _("invalid suffix"));
17189
7bdf778b
ASDV
17190 if (inst.cond != COND_ALWAYS)
17191 {
17192 if (thumb_mode)
17193 {
17194 as_warn (_("ARMv8.2 scalar fp16 instruction cannot be conditional,"
17195 " the behaviour is UNPREDICTABLE"));
17196 }
17197 else
17198 {
17199 inst.error = BAD_COND;
17200 return;
17201 }
17202 }
17203
9db2f6b4
RL
17204 do_vfp_sp_monadic ();
17205
17206 inst.is_neon = 1;
17207 inst.instruction |= 0xf0000000;
17208}
17209
5287ad62
JB
17210static void
17211do_neon_movl (void)
17212{
17213 struct neon_type_el et = neon_check_type (2, NS_QD,
17214 N_EQK | N_DBL, N_SU_32 | N_KEY);
17215 unsigned sizebits = et.size >> 3;
17216 inst.instruction |= sizebits << 19;
17217 neon_two_same (0, et.type == NT_unsigned, -1);
17218}
17219
17220static void
17221do_neon_trn (void)
17222{
037e8744 17223 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17224 struct neon_type_el et = neon_check_type (2, rs,
17225 N_EQK, N_8 | N_16 | N_32 | N_KEY);
88714cb8 17226 NEON_ENCODE (INTEGER, inst);
037e8744 17227 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17228}
17229
17230static void
17231do_neon_zip_uzp (void)
17232{
037e8744 17233 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17234 struct neon_type_el et = neon_check_type (2, rs,
17235 N_EQK, N_8 | N_16 | N_32 | N_KEY);
17236 if (rs == NS_DD && et.size == 32)
17237 {
17238 /* Special case: encode as VTRN.32 <Dd>, <Dm>. */
17239 inst.instruction = N_MNEM_vtrn;
17240 do_neon_trn ();
17241 return;
17242 }
037e8744 17243 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17244}
17245
17246static void
17247do_neon_sat_abs_neg (void)
17248{
037e8744 17249 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17250 struct neon_type_el et = neon_check_type (2, rs,
17251 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 17252 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17253}
17254
17255static void
17256do_neon_pair_long (void)
17257{
037e8744 17258 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17259 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_32 | N_KEY);
17260 /* Unsigned is encoded in OP field (bit 7) for these instruction. */
17261 inst.instruction |= (et.type == NT_unsigned) << 7;
037e8744 17262 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17263}
17264
17265static void
17266do_neon_recip_est (void)
17267{
037e8744 17268 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62 17269 struct neon_type_el et = neon_check_type (2, rs,
cc933301 17270 N_EQK | N_FLT, N_F_16_32 | N_U32 | N_KEY);
5287ad62 17271 inst.instruction |= (et.type == NT_float) << 8;
037e8744 17272 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17273}
17274
17275static void
17276do_neon_cls (void)
17277{
037e8744 17278 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17279 struct neon_type_el et = neon_check_type (2, rs,
17280 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 17281 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17282}
17283
17284static void
17285do_neon_clz (void)
17286{
037e8744 17287 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17288 struct neon_type_el et = neon_check_type (2, rs,
17289 N_EQK, N_I8 | N_I16 | N_I32 | N_KEY);
037e8744 17290 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17291}
17292
17293static void
17294do_neon_cnt (void)
17295{
037e8744 17296 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17297 struct neon_type_el et = neon_check_type (2, rs,
17298 N_EQK | N_INT, N_8 | N_KEY);
037e8744 17299 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17300}
17301
17302static void
17303do_neon_swp (void)
17304{
037e8744
JB
17305 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
17306 neon_two_same (neon_quad (rs), 1, -1);
5287ad62
JB
17307}
17308
17309static void
17310do_neon_tbl_tbx (void)
17311{
17312 unsigned listlenbits;
dcbf9037 17313 neon_check_type (3, NS_DLD, N_EQK, N_EQK, N_8 | N_KEY);
5f4273c7 17314
5287ad62
JB
17315 if (inst.operands[1].imm < 1 || inst.operands[1].imm > 4)
17316 {
dcbf9037 17317 first_error (_("bad list length for table lookup"));
5287ad62
JB
17318 return;
17319 }
5f4273c7 17320
5287ad62
JB
17321 listlenbits = inst.operands[1].imm - 1;
17322 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17323 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17324 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17325 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
17326 inst.instruction |= LOW4 (inst.operands[2].reg);
17327 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
17328 inst.instruction |= listlenbits << 8;
5f4273c7 17329
88714cb8 17330 neon_dp_fixup (&inst);
5287ad62
JB
17331}
17332
17333static void
17334do_neon_ldm_stm (void)
17335{
17336 /* P, U and L bits are part of bitmask. */
17337 int is_dbmode = (inst.instruction & (1 << 24)) != 0;
17338 unsigned offsetbits = inst.operands[1].imm * 2;
17339
037e8744
JB
17340 if (inst.operands[1].issingle)
17341 {
17342 do_vfp_nsyn_ldm_stm (is_dbmode);
17343 return;
17344 }
17345
5287ad62 17346 constraint (is_dbmode && !inst.operands[0].writeback,
477330fc 17347 _("writeback (!) must be used for VLDMDB and VSTMDB"));
5287ad62
JB
17348
17349 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
477330fc
RM
17350 _("register list must contain at least 1 and at most 16 "
17351 "registers"));
5287ad62
JB
17352
17353 inst.instruction |= inst.operands[0].reg << 16;
17354 inst.instruction |= inst.operands[0].writeback << 21;
17355 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
17356 inst.instruction |= HI1 (inst.operands[1].reg) << 22;
17357
17358 inst.instruction |= offsetbits;
5f4273c7 17359
037e8744 17360 do_vfp_cond_or_thumb ();
5287ad62
JB
17361}
17362
17363static void
17364do_neon_ldr_str (void)
17365{
5287ad62 17366 int is_ldr = (inst.instruction & (1 << 20)) != 0;
5f4273c7 17367
6844b2c2
MGD
17368 /* Use of PC in vstr in ARM mode is deprecated in ARMv7.
17369 And is UNPREDICTABLE in thumb mode. */
fa94de6b 17370 if (!is_ldr
6844b2c2 17371 && inst.operands[1].reg == REG_PC
ba86b375 17372 && (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7) || thumb_mode))
6844b2c2 17373 {
94dcf8bf 17374 if (thumb_mode)
6844b2c2 17375 inst.error = _("Use of PC here is UNPREDICTABLE");
94dcf8bf 17376 else if (warn_on_deprecated)
5c3696f8 17377 as_tsktsk (_("Use of PC here is deprecated"));
6844b2c2
MGD
17378 }
17379
037e8744
JB
17380 if (inst.operands[0].issingle)
17381 {
cd2f129f 17382 if (is_ldr)
477330fc 17383 do_vfp_nsyn_opcode ("flds");
cd2f129f 17384 else
477330fc 17385 do_vfp_nsyn_opcode ("fsts");
9db2f6b4
RL
17386
17387 /* ARMv8.2 vldr.16/vstr.16 instruction. */
17388 if (inst.vectype.el[0].size == 16)
17389 do_scalar_fp16_v82_encode ();
5287ad62
JB
17390 }
17391 else
5287ad62 17392 {
cd2f129f 17393 if (is_ldr)
477330fc 17394 do_vfp_nsyn_opcode ("fldd");
5287ad62 17395 else
477330fc 17396 do_vfp_nsyn_opcode ("fstd");
5287ad62 17397 }
5287ad62
JB
17398}
17399
17400/* "interleave" version also handles non-interleaving register VLD1/VST1
17401 instructions. */
17402
17403static void
17404do_neon_ld_st_interleave (void)
17405{
037e8744 17406 struct neon_type_el et = neon_check_type (1, NS_NULL,
477330fc 17407 N_8 | N_16 | N_32 | N_64);
5287ad62
JB
17408 unsigned alignbits = 0;
17409 unsigned idx;
17410 /* The bits in this table go:
17411 0: register stride of one (0) or two (1)
17412 1,2: register list length, minus one (1, 2, 3, 4).
17413 3,4: <n> in instruction type, minus one (VLD<n> / VST<n>).
17414 We use -1 for invalid entries. */
17415 const int typetable[] =
17416 {
17417 0x7, -1, 0xa, -1, 0x6, -1, 0x2, -1, /* VLD1 / VST1. */
17418 -1, -1, 0x8, 0x9, -1, -1, 0x3, -1, /* VLD2 / VST2. */
17419 -1, -1, -1, -1, 0x4, 0x5, -1, -1, /* VLD3 / VST3. */
17420 -1, -1, -1, -1, -1, -1, 0x0, 0x1 /* VLD4 / VST4. */
17421 };
17422 int typebits;
17423
dcbf9037
JB
17424 if (et.type == NT_invtype)
17425 return;
17426
5287ad62
JB
17427 if (inst.operands[1].immisalign)
17428 switch (inst.operands[1].imm >> 8)
17429 {
17430 case 64: alignbits = 1; break;
17431 case 128:
477330fc 17432 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2
e23c0ad8 17433 && NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
477330fc
RM
17434 goto bad_alignment;
17435 alignbits = 2;
17436 break;
5287ad62 17437 case 256:
477330fc
RM
17438 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
17439 goto bad_alignment;
17440 alignbits = 3;
17441 break;
5287ad62
JB
17442 default:
17443 bad_alignment:
477330fc
RM
17444 first_error (_("bad alignment"));
17445 return;
5287ad62
JB
17446 }
17447
17448 inst.instruction |= alignbits << 4;
17449 inst.instruction |= neon_logbits (et.size) << 6;
17450
17451 /* Bits [4:6] of the immediate in a list specifier encode register stride
17452 (minus 1) in bit 4, and list length in bits [5:6]. We put the <n> of
17453 VLD<n>/VST<n> in bits [9:8] of the initial bitmask. Suck it out here, look
17454 up the right value for "type" in a table based on this value and the given
17455 list style, then stick it back. */
17456 idx = ((inst.operands[0].imm >> 4) & 7)
477330fc 17457 | (((inst.instruction >> 8) & 3) << 3);
5287ad62
JB
17458
17459 typebits = typetable[idx];
5f4273c7 17460
5287ad62 17461 constraint (typebits == -1, _("bad list type for instruction"));
1d50d57c
WN
17462 constraint (((inst.instruction >> 8) & 3) && et.size == 64,
17463 _("bad element type for instruction"));
5287ad62
JB
17464
17465 inst.instruction &= ~0xf00;
17466 inst.instruction |= typebits << 8;
17467}
17468
17469/* Check alignment is valid for do_neon_ld_st_lane and do_neon_ld_dup.
17470 *DO_ALIGN is set to 1 if the relevant alignment bit should be set, 0
17471 otherwise. The variable arguments are a list of pairs of legal (size, align)
17472 values, terminated with -1. */
17473
17474static int
aa8a0863 17475neon_alignment_bit (int size, int align, int *do_alignment, ...)
5287ad62
JB
17476{
17477 va_list ap;
17478 int result = FAIL, thissize, thisalign;
5f4273c7 17479
5287ad62
JB
17480 if (!inst.operands[1].immisalign)
17481 {
aa8a0863 17482 *do_alignment = 0;
5287ad62
JB
17483 return SUCCESS;
17484 }
5f4273c7 17485
aa8a0863 17486 va_start (ap, do_alignment);
5287ad62
JB
17487
17488 do
17489 {
17490 thissize = va_arg (ap, int);
17491 if (thissize == -1)
477330fc 17492 break;
5287ad62
JB
17493 thisalign = va_arg (ap, int);
17494
17495 if (size == thissize && align == thisalign)
477330fc 17496 result = SUCCESS;
5287ad62
JB
17497 }
17498 while (result != SUCCESS);
17499
17500 va_end (ap);
17501
17502 if (result == SUCCESS)
aa8a0863 17503 *do_alignment = 1;
5287ad62 17504 else
dcbf9037 17505 first_error (_("unsupported alignment for instruction"));
5f4273c7 17506
5287ad62
JB
17507 return result;
17508}
17509
17510static void
17511do_neon_ld_st_lane (void)
17512{
037e8744 17513 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 17514 int align_good, do_alignment = 0;
5287ad62
JB
17515 int logsize = neon_logbits (et.size);
17516 int align = inst.operands[1].imm >> 8;
17517 int n = (inst.instruction >> 8) & 3;
17518 int max_el = 64 / et.size;
5f4273c7 17519
dcbf9037
JB
17520 if (et.type == NT_invtype)
17521 return;
5f4273c7 17522
5287ad62 17523 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != n + 1,
477330fc 17524 _("bad list length"));
5287ad62 17525 constraint (NEON_LANE (inst.operands[0].imm) >= max_el,
477330fc 17526 _("scalar index out of range"));
5287ad62 17527 constraint (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2
477330fc
RM
17528 && et.size == 8,
17529 _("stride of 2 unavailable when element size is 8"));
5f4273c7 17530
5287ad62
JB
17531 switch (n)
17532 {
17533 case 0: /* VLD1 / VST1. */
aa8a0863 17534 align_good = neon_alignment_bit (et.size, align, &do_alignment, 16, 16,
477330fc 17535 32, 32, -1);
5287ad62 17536 if (align_good == FAIL)
477330fc 17537 return;
aa8a0863 17538 if (do_alignment)
477330fc
RM
17539 {
17540 unsigned alignbits = 0;
17541 switch (et.size)
17542 {
17543 case 16: alignbits = 0x1; break;
17544 case 32: alignbits = 0x3; break;
17545 default: ;
17546 }
17547 inst.instruction |= alignbits << 4;
17548 }
5287ad62
JB
17549 break;
17550
17551 case 1: /* VLD2 / VST2. */
aa8a0863
TS
17552 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 16,
17553 16, 32, 32, 64, -1);
5287ad62 17554 if (align_good == FAIL)
477330fc 17555 return;
aa8a0863 17556 if (do_alignment)
477330fc 17557 inst.instruction |= 1 << 4;
5287ad62
JB
17558 break;
17559
17560 case 2: /* VLD3 / VST3. */
17561 constraint (inst.operands[1].immisalign,
477330fc 17562 _("can't use alignment with this instruction"));
5287ad62
JB
17563 break;
17564
17565 case 3: /* VLD4 / VST4. */
aa8a0863 17566 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc 17567 16, 64, 32, 64, 32, 128, -1);
5287ad62 17568 if (align_good == FAIL)
477330fc 17569 return;
aa8a0863 17570 if (do_alignment)
477330fc
RM
17571 {
17572 unsigned alignbits = 0;
17573 switch (et.size)
17574 {
17575 case 8: alignbits = 0x1; break;
17576 case 16: alignbits = 0x1; break;
17577 case 32: alignbits = (align == 64) ? 0x1 : 0x2; break;
17578 default: ;
17579 }
17580 inst.instruction |= alignbits << 4;
17581 }
5287ad62
JB
17582 break;
17583
17584 default: ;
17585 }
17586
17587 /* Reg stride of 2 is encoded in bit 5 when size==16, bit 6 when size==32. */
17588 if (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2)
17589 inst.instruction |= 1 << (4 + logsize);
5f4273c7 17590
5287ad62
JB
17591 inst.instruction |= NEON_LANE (inst.operands[0].imm) << (logsize + 5);
17592 inst.instruction |= logsize << 10;
17593}
17594
17595/* Encode single n-element structure to all lanes VLD<n> instructions. */
17596
17597static void
17598do_neon_ld_dup (void)
17599{
037e8744 17600 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 17601 int align_good, do_alignment = 0;
5287ad62 17602
dcbf9037
JB
17603 if (et.type == NT_invtype)
17604 return;
17605
5287ad62
JB
17606 switch ((inst.instruction >> 8) & 3)
17607 {
17608 case 0: /* VLD1. */
9c2799c2 17609 gas_assert (NEON_REG_STRIDE (inst.operands[0].imm) != 2);
5287ad62 17610 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863 17611 &do_alignment, 16, 16, 32, 32, -1);
5287ad62 17612 if (align_good == FAIL)
477330fc 17613 return;
5287ad62 17614 switch (NEON_REGLIST_LENGTH (inst.operands[0].imm))
477330fc
RM
17615 {
17616 case 1: break;
17617 case 2: inst.instruction |= 1 << 5; break;
17618 default: first_error (_("bad list length")); return;
17619 }
5287ad62
JB
17620 inst.instruction |= neon_logbits (et.size) << 6;
17621 break;
17622
17623 case 1: /* VLD2. */
17624 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863
TS
17625 &do_alignment, 8, 16, 16, 32, 32, 64,
17626 -1);
5287ad62 17627 if (align_good == FAIL)
477330fc 17628 return;
5287ad62 17629 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2,
477330fc 17630 _("bad list length"));
5287ad62 17631 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 17632 inst.instruction |= 1 << 5;
5287ad62
JB
17633 inst.instruction |= neon_logbits (et.size) << 6;
17634 break;
17635
17636 case 2: /* VLD3. */
17637 constraint (inst.operands[1].immisalign,
477330fc 17638 _("can't use alignment with this instruction"));
5287ad62 17639 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 3,
477330fc 17640 _("bad list length"));
5287ad62 17641 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 17642 inst.instruction |= 1 << 5;
5287ad62
JB
17643 inst.instruction |= neon_logbits (et.size) << 6;
17644 break;
17645
17646 case 3: /* VLD4. */
17647 {
477330fc 17648 int align = inst.operands[1].imm >> 8;
aa8a0863 17649 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc
RM
17650 16, 64, 32, 64, 32, 128, -1);
17651 if (align_good == FAIL)
17652 return;
17653 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4,
17654 _("bad list length"));
17655 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
17656 inst.instruction |= 1 << 5;
17657 if (et.size == 32 && align == 128)
17658 inst.instruction |= 0x3 << 6;
17659 else
17660 inst.instruction |= neon_logbits (et.size) << 6;
5287ad62
JB
17661 }
17662 break;
17663
17664 default: ;
17665 }
17666
aa8a0863 17667 inst.instruction |= do_alignment << 4;
5287ad62
JB
17668}
17669
17670/* Disambiguate VLD<n> and VST<n> instructions, and fill in common bits (those
17671 apart from bits [11:4]. */
17672
17673static void
17674do_neon_ldx_stx (void)
17675{
b1a769ed
DG
17676 if (inst.operands[1].isreg)
17677 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
17678
5287ad62
JB
17679 switch (NEON_LANE (inst.operands[0].imm))
17680 {
17681 case NEON_INTERLEAVE_LANES:
88714cb8 17682 NEON_ENCODE (INTERLV, inst);
5287ad62
JB
17683 do_neon_ld_st_interleave ();
17684 break;
5f4273c7 17685
5287ad62 17686 case NEON_ALL_LANES:
88714cb8 17687 NEON_ENCODE (DUP, inst);
2d51fb74
JB
17688 if (inst.instruction == N_INV)
17689 {
17690 first_error ("only loads support such operands");
17691 break;
17692 }
5287ad62
JB
17693 do_neon_ld_dup ();
17694 break;
5f4273c7 17695
5287ad62 17696 default:
88714cb8 17697 NEON_ENCODE (LANE, inst);
5287ad62
JB
17698 do_neon_ld_st_lane ();
17699 }
17700
17701 /* L bit comes from bit mask. */
17702 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17703 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17704 inst.instruction |= inst.operands[1].reg << 16;
5f4273c7 17705
5287ad62
JB
17706 if (inst.operands[1].postind)
17707 {
17708 int postreg = inst.operands[1].imm & 0xf;
17709 constraint (!inst.operands[1].immisreg,
477330fc 17710 _("post-index must be a register"));
5287ad62 17711 constraint (postreg == 0xd || postreg == 0xf,
477330fc 17712 _("bad register for post-index"));
5287ad62
JB
17713 inst.instruction |= postreg;
17714 }
4f2374c7 17715 else
5287ad62 17716 {
4f2374c7 17717 constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
e2b0ab59
AV
17718 constraint (inst.relocs[0].exp.X_op != O_constant
17719 || inst.relocs[0].exp.X_add_number != 0,
4f2374c7
WN
17720 BAD_ADDR_MODE);
17721
17722 if (inst.operands[1].writeback)
17723 {
17724 inst.instruction |= 0xd;
17725 }
17726 else
17727 inst.instruction |= 0xf;
5287ad62 17728 }
5f4273c7 17729
5287ad62
JB
17730 if (thumb_mode)
17731 inst.instruction |= 0xf9000000;
17732 else
17733 inst.instruction |= 0xf4000000;
17734}
33399f07
MGD
17735
17736/* FP v8. */
17737static void
17738do_vfp_nsyn_fpv8 (enum neon_shape rs)
17739{
a715796b
TG
17740 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
17741 D register operands. */
17742 if (neon_shape_class[rs] == SC_DOUBLE)
17743 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
17744 _(BAD_FPU));
17745
33399f07
MGD
17746 NEON_ENCODE (FPV8, inst);
17747
9db2f6b4
RL
17748 if (rs == NS_FFF || rs == NS_HHH)
17749 {
17750 do_vfp_sp_dyadic ();
17751
17752 /* ARMv8.2 fp16 instruction. */
17753 if (rs == NS_HHH)
17754 do_scalar_fp16_v82_encode ();
17755 }
33399f07
MGD
17756 else
17757 do_vfp_dp_rd_rn_rm ();
17758
17759 if (rs == NS_DDD)
17760 inst.instruction |= 0x100;
17761
17762 inst.instruction |= 0xf0000000;
17763}
17764
17765static void
17766do_vsel (void)
17767{
17768 set_it_insn_type (OUTSIDE_IT_INSN);
17769
17770 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) != SUCCESS)
17771 first_error (_("invalid instruction shape"));
17772}
17773
73924fbc
MGD
17774static void
17775do_vmaxnm (void)
17776{
17777 set_it_insn_type (OUTSIDE_IT_INSN);
17778
17779 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) == SUCCESS)
17780 return;
17781
17782 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH8) == FAIL)
17783 return;
17784
cc933301 17785 neon_dyadic_misc (NT_untyped, N_F_16_32, 0);
73924fbc
MGD
17786}
17787
30bdf752
MGD
17788static void
17789do_vrint_1 (enum neon_cvt_mode mode)
17790{
9db2f6b4 17791 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_QQ, NS_NULL);
30bdf752
MGD
17792 struct neon_type_el et;
17793
17794 if (rs == NS_NULL)
17795 return;
17796
a715796b
TG
17797 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
17798 D register operands. */
17799 if (neon_shape_class[rs] == SC_DOUBLE)
17800 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
17801 _(BAD_FPU));
17802
9db2f6b4
RL
17803 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY
17804 | N_VFP);
30bdf752
MGD
17805 if (et.type != NT_invtype)
17806 {
17807 /* VFP encodings. */
17808 if (mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
17809 || mode == neon_cvt_mode_p || mode == neon_cvt_mode_m)
17810 set_it_insn_type (OUTSIDE_IT_INSN);
17811
17812 NEON_ENCODE (FPV8, inst);
9db2f6b4 17813 if (rs == NS_FF || rs == NS_HH)
30bdf752
MGD
17814 do_vfp_sp_monadic ();
17815 else
17816 do_vfp_dp_rd_rm ();
17817
17818 switch (mode)
17819 {
17820 case neon_cvt_mode_r: inst.instruction |= 0x00000000; break;
17821 case neon_cvt_mode_z: inst.instruction |= 0x00000080; break;
17822 case neon_cvt_mode_x: inst.instruction |= 0x00010000; break;
17823 case neon_cvt_mode_a: inst.instruction |= 0xf0000000; break;
17824 case neon_cvt_mode_n: inst.instruction |= 0xf0010000; break;
17825 case neon_cvt_mode_p: inst.instruction |= 0xf0020000; break;
17826 case neon_cvt_mode_m: inst.instruction |= 0xf0030000; break;
17827 default: abort ();
17828 }
17829
17830 inst.instruction |= (rs == NS_DD) << 8;
17831 do_vfp_cond_or_thumb ();
9db2f6b4
RL
17832
17833 /* ARMv8.2 fp16 vrint instruction. */
17834 if (rs == NS_HH)
17835 do_scalar_fp16_v82_encode ();
30bdf752
MGD
17836 }
17837 else
17838 {
17839 /* Neon encodings (or something broken...). */
17840 inst.error = NULL;
cc933301 17841 et = neon_check_type (2, rs, N_EQK, N_F_16_32 | N_KEY);
30bdf752
MGD
17842
17843 if (et.type == NT_invtype)
17844 return;
17845
17846 set_it_insn_type (OUTSIDE_IT_INSN);
17847 NEON_ENCODE (FLOAT, inst);
17848
17849 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH8) == FAIL)
17850 return;
17851
17852 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17853 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17854 inst.instruction |= LOW4 (inst.operands[1].reg);
17855 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
17856 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
17857 /* Mask off the original size bits and reencode them. */
17858 inst.instruction = ((inst.instruction & 0xfff3ffff)
17859 | neon_logbits (et.size) << 18);
17860
30bdf752
MGD
17861 switch (mode)
17862 {
17863 case neon_cvt_mode_z: inst.instruction |= 3 << 7; break;
17864 case neon_cvt_mode_x: inst.instruction |= 1 << 7; break;
17865 case neon_cvt_mode_a: inst.instruction |= 2 << 7; break;
17866 case neon_cvt_mode_n: inst.instruction |= 0 << 7; break;
17867 case neon_cvt_mode_p: inst.instruction |= 7 << 7; break;
17868 case neon_cvt_mode_m: inst.instruction |= 5 << 7; break;
17869 case neon_cvt_mode_r: inst.error = _("invalid rounding mode"); break;
17870 default: abort ();
17871 }
17872
17873 if (thumb_mode)
17874 inst.instruction |= 0xfc000000;
17875 else
17876 inst.instruction |= 0xf0000000;
17877 }
17878}
17879
17880static void
17881do_vrintx (void)
17882{
17883 do_vrint_1 (neon_cvt_mode_x);
17884}
17885
17886static void
17887do_vrintz (void)
17888{
17889 do_vrint_1 (neon_cvt_mode_z);
17890}
17891
17892static void
17893do_vrintr (void)
17894{
17895 do_vrint_1 (neon_cvt_mode_r);
17896}
17897
17898static void
17899do_vrinta (void)
17900{
17901 do_vrint_1 (neon_cvt_mode_a);
17902}
17903
17904static void
17905do_vrintn (void)
17906{
17907 do_vrint_1 (neon_cvt_mode_n);
17908}
17909
17910static void
17911do_vrintp (void)
17912{
17913 do_vrint_1 (neon_cvt_mode_p);
17914}
17915
17916static void
17917do_vrintm (void)
17918{
17919 do_vrint_1 (neon_cvt_mode_m);
17920}
17921
c28eeff2
SN
17922static unsigned
17923neon_scalar_for_vcmla (unsigned opnd, unsigned elsize)
17924{
17925 unsigned regno = NEON_SCALAR_REG (opnd);
17926 unsigned elno = NEON_SCALAR_INDEX (opnd);
17927
17928 if (elsize == 16 && elno < 2 && regno < 16)
17929 return regno | (elno << 4);
17930 else if (elsize == 32 && elno == 0)
17931 return regno;
17932
17933 first_error (_("scalar out of range"));
17934 return 0;
17935}
17936
17937static void
17938do_vcmla (void)
17939{
17940 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
17941 _(BAD_FPU));
e2b0ab59
AV
17942 constraint (inst.relocs[0].exp.X_op != O_constant,
17943 _("expression too complex"));
17944 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2
SN
17945 constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
17946 _("immediate out of range"));
17947 rot /= 90;
17948 if (inst.operands[2].isscalar)
17949 {
17950 enum neon_shape rs = neon_select_shape (NS_DDSI, NS_QQSI, NS_NULL);
17951 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
17952 N_KEY | N_F16 | N_F32).size;
17953 unsigned m = neon_scalar_for_vcmla (inst.operands[2].reg, size);
17954 inst.is_neon = 1;
17955 inst.instruction = 0xfe000800;
17956 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17957 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17958 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17959 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
17960 inst.instruction |= LOW4 (m);
17961 inst.instruction |= HI1 (m) << 5;
17962 inst.instruction |= neon_quad (rs) << 6;
17963 inst.instruction |= rot << 20;
17964 inst.instruction |= (size == 32) << 23;
17965 }
17966 else
17967 {
17968 enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
17969 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
17970 N_KEY | N_F16 | N_F32).size;
17971 neon_three_same (neon_quad (rs), 0, -1);
17972 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
17973 inst.instruction |= 0xfc200800;
17974 inst.instruction |= rot << 23;
17975 inst.instruction |= (size == 32) << 20;
17976 }
17977}
17978
17979static void
17980do_vcadd (void)
17981{
17982 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
17983 _(BAD_FPU));
e2b0ab59
AV
17984 constraint (inst.relocs[0].exp.X_op != O_constant,
17985 _("expression too complex"));
17986 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2
SN
17987 constraint (rot != 90 && rot != 270, _("immediate out of range"));
17988 enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
17989 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
17990 N_KEY | N_F16 | N_F32).size;
17991 neon_three_same (neon_quad (rs), 0, -1);
17992 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
17993 inst.instruction |= 0xfc800800;
17994 inst.instruction |= (rot == 270) << 24;
17995 inst.instruction |= (size == 32) << 20;
17996}
17997
c604a79a
JW
17998/* Dot Product instructions encoding support. */
17999
18000static void
18001do_neon_dotproduct (int unsigned_p)
18002{
18003 enum neon_shape rs;
18004 unsigned scalar_oprd2 = 0;
18005 int high8;
18006
18007 if (inst.cond != COND_ALWAYS)
18008 as_warn (_("Dot Product instructions cannot be conditional, the behaviour "
18009 "is UNPREDICTABLE"));
18010
18011 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
18012 _(BAD_FPU));
18013
18014 /* Dot Product instructions are in three-same D/Q register format or the third
18015 operand can be a scalar index register. */
18016 if (inst.operands[2].isscalar)
18017 {
18018 scalar_oprd2 = neon_scalar_for_mul (inst.operands[2].reg, 32);
18019 high8 = 0xfe000000;
18020 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
18021 }
18022 else
18023 {
18024 high8 = 0xfc000000;
18025 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
18026 }
18027
18028 if (unsigned_p)
18029 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_U8);
18030 else
18031 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_S8);
18032
18033 /* The "U" bit in traditional Three Same encoding is fixed to 0 for Dot
18034 Product instruction, so we pass 0 as the "ubit" parameter. And the
18035 "Size" field are fixed to 0x2, so we pass 32 as the "size" parameter. */
18036 neon_three_same (neon_quad (rs), 0, 32);
18037
18038 /* Undo neon_dp_fixup. Dot Product instructions are using a slightly
18039 different NEON three-same encoding. */
18040 inst.instruction &= 0x00ffffff;
18041 inst.instruction |= high8;
18042 /* Encode 'U' bit which indicates signedness. */
18043 inst.instruction |= (unsigned_p ? 1 : 0) << 4;
18044 /* Re-encode operand2 if it's indexed scalar operand. What has been encoded
18045 from inst.operand[2].reg in neon_three_same is GAS's internal encoding, not
18046 the instruction encoding. */
18047 if (inst.operands[2].isscalar)
18048 {
18049 inst.instruction &= 0xffffffd0;
18050 inst.instruction |= LOW4 (scalar_oprd2);
18051 inst.instruction |= HI1 (scalar_oprd2) << 5;
18052 }
18053}
18054
18055/* Dot Product instructions for signed integer. */
18056
18057static void
18058do_neon_dotproduct_s (void)
18059{
18060 return do_neon_dotproduct (0);
18061}
18062
18063/* Dot Product instructions for unsigned integer. */
18064
18065static void
18066do_neon_dotproduct_u (void)
18067{
18068 return do_neon_dotproduct (1);
18069}
18070
91ff7894
MGD
18071/* Crypto v1 instructions. */
18072static void
18073do_crypto_2op_1 (unsigned elttype, int op)
18074{
18075 set_it_insn_type (OUTSIDE_IT_INSN);
18076
18077 if (neon_check_type (2, NS_QQ, N_EQK | N_UNT, elttype | N_UNT | N_KEY).type
18078 == NT_invtype)
18079 return;
18080
18081 inst.error = NULL;
18082
18083 NEON_ENCODE (INTEGER, inst);
18084 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18085 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18086 inst.instruction |= LOW4 (inst.operands[1].reg);
18087 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18088 if (op != -1)
18089 inst.instruction |= op << 6;
18090
18091 if (thumb_mode)
18092 inst.instruction |= 0xfc000000;
18093 else
18094 inst.instruction |= 0xf0000000;
18095}
18096
48adcd8e
MGD
18097static void
18098do_crypto_3op_1 (int u, int op)
18099{
18100 set_it_insn_type (OUTSIDE_IT_INSN);
18101
18102 if (neon_check_type (3, NS_QQQ, N_EQK | N_UNT, N_EQK | N_UNT,
18103 N_32 | N_UNT | N_KEY).type == NT_invtype)
18104 return;
18105
18106 inst.error = NULL;
18107
18108 NEON_ENCODE (INTEGER, inst);
18109 neon_three_same (1, u, 8 << op);
18110}
18111
91ff7894
MGD
18112static void
18113do_aese (void)
18114{
18115 do_crypto_2op_1 (N_8, 0);
18116}
18117
18118static void
18119do_aesd (void)
18120{
18121 do_crypto_2op_1 (N_8, 1);
18122}
18123
18124static void
18125do_aesmc (void)
18126{
18127 do_crypto_2op_1 (N_8, 2);
18128}
18129
18130static void
18131do_aesimc (void)
18132{
18133 do_crypto_2op_1 (N_8, 3);
18134}
18135
48adcd8e
MGD
18136static void
18137do_sha1c (void)
18138{
18139 do_crypto_3op_1 (0, 0);
18140}
18141
18142static void
18143do_sha1p (void)
18144{
18145 do_crypto_3op_1 (0, 1);
18146}
18147
18148static void
18149do_sha1m (void)
18150{
18151 do_crypto_3op_1 (0, 2);
18152}
18153
18154static void
18155do_sha1su0 (void)
18156{
18157 do_crypto_3op_1 (0, 3);
18158}
91ff7894 18159
48adcd8e
MGD
18160static void
18161do_sha256h (void)
18162{
18163 do_crypto_3op_1 (1, 0);
18164}
18165
18166static void
18167do_sha256h2 (void)
18168{
18169 do_crypto_3op_1 (1, 1);
18170}
18171
18172static void
18173do_sha256su1 (void)
18174{
18175 do_crypto_3op_1 (1, 2);
18176}
3c9017d2
MGD
18177
18178static void
18179do_sha1h (void)
18180{
18181 do_crypto_2op_1 (N_32, -1);
18182}
18183
18184static void
18185do_sha1su1 (void)
18186{
18187 do_crypto_2op_1 (N_32, 0);
18188}
18189
18190static void
18191do_sha256su0 (void)
18192{
18193 do_crypto_2op_1 (N_32, 1);
18194}
dd5181d5
KT
18195
18196static void
18197do_crc32_1 (unsigned int poly, unsigned int sz)
18198{
18199 unsigned int Rd = inst.operands[0].reg;
18200 unsigned int Rn = inst.operands[1].reg;
18201 unsigned int Rm = inst.operands[2].reg;
18202
18203 set_it_insn_type (OUTSIDE_IT_INSN);
18204 inst.instruction |= LOW4 (Rd) << (thumb_mode ? 8 : 12);
18205 inst.instruction |= LOW4 (Rn) << 16;
18206 inst.instruction |= LOW4 (Rm);
18207 inst.instruction |= sz << (thumb_mode ? 4 : 21);
18208 inst.instruction |= poly << (thumb_mode ? 20 : 9);
18209
18210 if (Rd == REG_PC || Rn == REG_PC || Rm == REG_PC)
18211 as_warn (UNPRED_REG ("r15"));
dd5181d5
KT
18212}
18213
18214static void
18215do_crc32b (void)
18216{
18217 do_crc32_1 (0, 0);
18218}
18219
18220static void
18221do_crc32h (void)
18222{
18223 do_crc32_1 (0, 1);
18224}
18225
18226static void
18227do_crc32w (void)
18228{
18229 do_crc32_1 (0, 2);
18230}
18231
18232static void
18233do_crc32cb (void)
18234{
18235 do_crc32_1 (1, 0);
18236}
18237
18238static void
18239do_crc32ch (void)
18240{
18241 do_crc32_1 (1, 1);
18242}
18243
18244static void
18245do_crc32cw (void)
18246{
18247 do_crc32_1 (1, 2);
18248}
18249
49e8a725
SN
18250static void
18251do_vjcvt (void)
18252{
18253 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
18254 _(BAD_FPU));
18255 neon_check_type (2, NS_FD, N_S32, N_F64);
18256 do_vfp_sp_dp_cvt ();
18257 do_vfp_cond_or_thumb ();
18258}
18259
5287ad62
JB
18260\f
18261/* Overall per-instruction processing. */
18262
18263/* We need to be able to fix up arbitrary expressions in some statements.
18264 This is so that we can handle symbols that are an arbitrary distance from
18265 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
18266 which returns part of an address in a form which will be valid for
18267 a data instruction. We do this by pushing the expression into a symbol
18268 in the expr_section, and creating a fix for that. */
18269
18270static void
18271fix_new_arm (fragS * frag,
18272 int where,
18273 short int size,
18274 expressionS * exp,
18275 int pc_rel,
18276 int reloc)
18277{
18278 fixS * new_fix;
18279
18280 switch (exp->X_op)
18281 {
18282 case O_constant:
6e7ce2cd
PB
18283 if (pc_rel)
18284 {
18285 /* Create an absolute valued symbol, so we have something to
477330fc
RM
18286 refer to in the object file. Unfortunately for us, gas's
18287 generic expression parsing will already have folded out
18288 any use of .set foo/.type foo %function that may have
18289 been used to set type information of the target location,
18290 that's being specified symbolically. We have to presume
18291 the user knows what they are doing. */
6e7ce2cd
PB
18292 char name[16 + 8];
18293 symbolS *symbol;
18294
18295 sprintf (name, "*ABS*0x%lx", (unsigned long)exp->X_add_number);
18296
18297 symbol = symbol_find_or_make (name);
18298 S_SET_SEGMENT (symbol, absolute_section);
18299 symbol_set_frag (symbol, &zero_address_frag);
18300 S_SET_VALUE (symbol, exp->X_add_number);
18301 exp->X_op = O_symbol;
18302 exp->X_add_symbol = symbol;
18303 exp->X_add_number = 0;
18304 }
18305 /* FALLTHROUGH */
5287ad62
JB
18306 case O_symbol:
18307 case O_add:
18308 case O_subtract:
21d799b5 18309 new_fix = fix_new_exp (frag, where, size, exp, pc_rel,
477330fc 18310 (enum bfd_reloc_code_real) reloc);
5287ad62
JB
18311 break;
18312
18313 default:
21d799b5 18314 new_fix = (fixS *) fix_new (frag, where, size, make_expr_symbol (exp), 0,
477330fc 18315 pc_rel, (enum bfd_reloc_code_real) reloc);
5287ad62
JB
18316 break;
18317 }
18318
18319 /* Mark whether the fix is to a THUMB instruction, or an ARM
18320 instruction. */
18321 new_fix->tc_fix_data = thumb_mode;
18322}
18323
18324/* Create a frg for an instruction requiring relaxation. */
18325static void
18326output_relax_insn (void)
18327{
18328 char * to;
18329 symbolS *sym;
0110f2b8
PB
18330 int offset;
18331
6e1cb1a6
PB
18332 /* The size of the instruction is unknown, so tie the debug info to the
18333 start of the instruction. */
18334 dwarf2_emit_insn (0);
6e1cb1a6 18335
e2b0ab59 18336 switch (inst.relocs[0].exp.X_op)
0110f2b8
PB
18337 {
18338 case O_symbol:
e2b0ab59
AV
18339 sym = inst.relocs[0].exp.X_add_symbol;
18340 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
18341 break;
18342 case O_constant:
18343 sym = NULL;
e2b0ab59 18344 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
18345 break;
18346 default:
e2b0ab59 18347 sym = make_expr_symbol (&inst.relocs[0].exp);
0110f2b8
PB
18348 offset = 0;
18349 break;
18350 }
18351 to = frag_var (rs_machine_dependent, INSN_SIZE, THUMB_SIZE,
18352 inst.relax, sym, offset, NULL/*offset, opcode*/);
18353 md_number_to_chars (to, inst.instruction, THUMB_SIZE);
0110f2b8
PB
18354}
18355
18356/* Write a 32-bit thumb instruction to buf. */
18357static void
18358put_thumb32_insn (char * buf, unsigned long insn)
18359{
18360 md_number_to_chars (buf, insn >> 16, THUMB_SIZE);
18361 md_number_to_chars (buf + THUMB_SIZE, insn, THUMB_SIZE);
18362}
18363
b99bd4ef 18364static void
c19d1205 18365output_inst (const char * str)
b99bd4ef 18366{
c19d1205 18367 char * to = NULL;
b99bd4ef 18368
c19d1205 18369 if (inst.error)
b99bd4ef 18370 {
c19d1205 18371 as_bad ("%s -- `%s'", inst.error, str);
b99bd4ef
NC
18372 return;
18373 }
5f4273c7
NC
18374 if (inst.relax)
18375 {
18376 output_relax_insn ();
0110f2b8 18377 return;
5f4273c7 18378 }
c19d1205
ZW
18379 if (inst.size == 0)
18380 return;
b99bd4ef 18381
c19d1205 18382 to = frag_more (inst.size);
8dc2430f
NC
18383 /* PR 9814: Record the thumb mode into the current frag so that we know
18384 what type of NOP padding to use, if necessary. We override any previous
18385 setting so that if the mode has changed then the NOPS that we use will
18386 match the encoding of the last instruction in the frag. */
cd000bff 18387 frag_now->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
c19d1205
ZW
18388
18389 if (thumb_mode && (inst.size > THUMB_SIZE))
b99bd4ef 18390 {
9c2799c2 18391 gas_assert (inst.size == (2 * THUMB_SIZE));
0110f2b8 18392 put_thumb32_insn (to, inst.instruction);
b99bd4ef 18393 }
c19d1205 18394 else if (inst.size > INSN_SIZE)
b99bd4ef 18395 {
9c2799c2 18396 gas_assert (inst.size == (2 * INSN_SIZE));
c19d1205
ZW
18397 md_number_to_chars (to, inst.instruction, INSN_SIZE);
18398 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
b99bd4ef 18399 }
c19d1205
ZW
18400 else
18401 md_number_to_chars (to, inst.instruction, inst.size);
b99bd4ef 18402
e2b0ab59
AV
18403 int r;
18404 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
18405 {
18406 if (inst.relocs[r].type != BFD_RELOC_UNUSED)
18407 fix_new_arm (frag_now, to - frag_now->fr_literal,
18408 inst.size, & inst.relocs[r].exp, inst.relocs[r].pc_rel,
18409 inst.relocs[r].type);
18410 }
b99bd4ef 18411
c19d1205 18412 dwarf2_emit_insn (inst.size);
c19d1205 18413}
b99bd4ef 18414
e07e6e58
NC
18415static char *
18416output_it_inst (int cond, int mask, char * to)
18417{
18418 unsigned long instruction = 0xbf00;
18419
18420 mask &= 0xf;
18421 instruction |= mask;
18422 instruction |= cond << 4;
18423
18424 if (to == NULL)
18425 {
18426 to = frag_more (2);
18427#ifdef OBJ_ELF
18428 dwarf2_emit_insn (2);
18429#endif
18430 }
18431
18432 md_number_to_chars (to, instruction, 2);
18433
18434 return to;
18435}
18436
c19d1205
ZW
18437/* Tag values used in struct asm_opcode's tag field. */
18438enum opcode_tag
18439{
18440 OT_unconditional, /* Instruction cannot be conditionalized.
18441 The ARM condition field is still 0xE. */
18442 OT_unconditionalF, /* Instruction cannot be conditionalized
18443 and carries 0xF in its ARM condition field. */
18444 OT_csuffix, /* Instruction takes a conditional suffix. */
037e8744 18445 OT_csuffixF, /* Some forms of the instruction take a conditional
477330fc
RM
18446 suffix, others place 0xF where the condition field
18447 would be. */
c19d1205
ZW
18448 OT_cinfix3, /* Instruction takes a conditional infix,
18449 beginning at character index 3. (In
18450 unified mode, it becomes a suffix.) */
088fa78e
KH
18451 OT_cinfix3_deprecated, /* The same as OT_cinfix3. This is used for
18452 tsts, cmps, cmns, and teqs. */
e3cb604e
PB
18453 OT_cinfix3_legacy, /* Legacy instruction takes a conditional infix at
18454 character index 3, even in unified mode. Used for
18455 legacy instructions where suffix and infix forms
18456 may be ambiguous. */
c19d1205 18457 OT_csuf_or_in3, /* Instruction takes either a conditional
e3cb604e 18458 suffix or an infix at character index 3. */
c19d1205
ZW
18459 OT_odd_infix_unc, /* This is the unconditional variant of an
18460 instruction that takes a conditional infix
18461 at an unusual position. In unified mode,
18462 this variant will accept a suffix. */
18463 OT_odd_infix_0 /* Values greater than or equal to OT_odd_infix_0
18464 are the conditional variants of instructions that
18465 take conditional infixes in unusual positions.
18466 The infix appears at character index
18467 (tag - OT_odd_infix_0). These are not accepted
18468 in unified mode. */
18469};
b99bd4ef 18470
c19d1205
ZW
18471/* Subroutine of md_assemble, responsible for looking up the primary
18472 opcode from the mnemonic the user wrote. STR points to the
18473 beginning of the mnemonic.
18474
18475 This is not simply a hash table lookup, because of conditional
18476 variants. Most instructions have conditional variants, which are
18477 expressed with a _conditional affix_ to the mnemonic. If we were
18478 to encode each conditional variant as a literal string in the opcode
18479 table, it would have approximately 20,000 entries.
18480
18481 Most mnemonics take this affix as a suffix, and in unified syntax,
18482 'most' is upgraded to 'all'. However, in the divided syntax, some
18483 instructions take the affix as an infix, notably the s-variants of
18484 the arithmetic instructions. Of those instructions, all but six
18485 have the infix appear after the third character of the mnemonic.
18486
18487 Accordingly, the algorithm for looking up primary opcodes given
18488 an identifier is:
18489
18490 1. Look up the identifier in the opcode table.
18491 If we find a match, go to step U.
18492
18493 2. Look up the last two characters of the identifier in the
18494 conditions table. If we find a match, look up the first N-2
18495 characters of the identifier in the opcode table. If we
18496 find a match, go to step CE.
18497
18498 3. Look up the fourth and fifth characters of the identifier in
18499 the conditions table. If we find a match, extract those
18500 characters from the identifier, and look up the remaining
18501 characters in the opcode table. If we find a match, go
18502 to step CM.
18503
18504 4. Fail.
18505
18506 U. Examine the tag field of the opcode structure, in case this is
18507 one of the six instructions with its conditional infix in an
18508 unusual place. If it is, the tag tells us where to find the
18509 infix; look it up in the conditions table and set inst.cond
18510 accordingly. Otherwise, this is an unconditional instruction.
18511 Again set inst.cond accordingly. Return the opcode structure.
18512
18513 CE. Examine the tag field to make sure this is an instruction that
18514 should receive a conditional suffix. If it is not, fail.
18515 Otherwise, set inst.cond from the suffix we already looked up,
18516 and return the opcode structure.
18517
18518 CM. Examine the tag field to make sure this is an instruction that
18519 should receive a conditional infix after the third character.
18520 If it is not, fail. Otherwise, undo the edits to the current
18521 line of input and proceed as for case CE. */
18522
18523static const struct asm_opcode *
18524opcode_lookup (char **str)
18525{
18526 char *end, *base;
18527 char *affix;
18528 const struct asm_opcode *opcode;
18529 const struct asm_cond *cond;
e3cb604e 18530 char save[2];
c19d1205
ZW
18531
18532 /* Scan up to the end of the mnemonic, which must end in white space,
721a8186 18533 '.' (in unified mode, or for Neon/VFP instructions), or end of string. */
c19d1205 18534 for (base = end = *str; *end != '\0'; end++)
721a8186 18535 if (*end == ' ' || *end == '.')
c19d1205 18536 break;
b99bd4ef 18537
c19d1205 18538 if (end == base)
c921be7d 18539 return NULL;
b99bd4ef 18540
5287ad62 18541 /* Handle a possible width suffix and/or Neon type suffix. */
c19d1205 18542 if (end[0] == '.')
b99bd4ef 18543 {
5287ad62 18544 int offset = 2;
5f4273c7 18545
267d2029 18546 /* The .w and .n suffixes are only valid if the unified syntax is in
477330fc 18547 use. */
267d2029 18548 if (unified_syntax && end[1] == 'w')
c19d1205 18549 inst.size_req = 4;
267d2029 18550 else if (unified_syntax && end[1] == 'n')
c19d1205
ZW
18551 inst.size_req = 2;
18552 else
477330fc 18553 offset = 0;
5287ad62
JB
18554
18555 inst.vectype.elems = 0;
18556
18557 *str = end + offset;
b99bd4ef 18558
5f4273c7 18559 if (end[offset] == '.')
5287ad62 18560 {
267d2029 18561 /* See if we have a Neon type suffix (possible in either unified or
477330fc
RM
18562 non-unified ARM syntax mode). */
18563 if (parse_neon_type (&inst.vectype, str) == FAIL)
c921be7d 18564 return NULL;
477330fc 18565 }
5287ad62 18566 else if (end[offset] != '\0' && end[offset] != ' ')
477330fc 18567 return NULL;
b99bd4ef 18568 }
c19d1205
ZW
18569 else
18570 *str = end;
b99bd4ef 18571
c19d1205 18572 /* Look for unaffixed or special-case affixed mnemonic. */
21d799b5 18573 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
477330fc 18574 end - base);
c19d1205 18575 if (opcode)
b99bd4ef 18576 {
c19d1205
ZW
18577 /* step U */
18578 if (opcode->tag < OT_odd_infix_0)
b99bd4ef 18579 {
c19d1205
ZW
18580 inst.cond = COND_ALWAYS;
18581 return opcode;
b99bd4ef 18582 }
b99bd4ef 18583
278df34e 18584 if (warn_on_deprecated && unified_syntax)
5c3696f8 18585 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205 18586 affix = base + (opcode->tag - OT_odd_infix_0);
21d799b5 18587 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
9c2799c2 18588 gas_assert (cond);
b99bd4ef 18589
c19d1205
ZW
18590 inst.cond = cond->value;
18591 return opcode;
18592 }
b99bd4ef 18593
c19d1205
ZW
18594 /* Cannot have a conditional suffix on a mnemonic of less than two
18595 characters. */
18596 if (end - base < 3)
c921be7d 18597 return NULL;
b99bd4ef 18598
c19d1205
ZW
18599 /* Look for suffixed mnemonic. */
18600 affix = end - 2;
21d799b5
NC
18601 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
18602 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
477330fc 18603 affix - base);
c19d1205
ZW
18604 if (opcode && cond)
18605 {
18606 /* step CE */
18607 switch (opcode->tag)
18608 {
e3cb604e
PB
18609 case OT_cinfix3_legacy:
18610 /* Ignore conditional suffixes matched on infix only mnemonics. */
18611 break;
18612
c19d1205 18613 case OT_cinfix3:
088fa78e 18614 case OT_cinfix3_deprecated:
c19d1205
ZW
18615 case OT_odd_infix_unc:
18616 if (!unified_syntax)
0198d5e6 18617 return NULL;
1a0670f3 18618 /* Fall through. */
c19d1205
ZW
18619
18620 case OT_csuffix:
477330fc 18621 case OT_csuffixF:
c19d1205
ZW
18622 case OT_csuf_or_in3:
18623 inst.cond = cond->value;
18624 return opcode;
18625
18626 case OT_unconditional:
18627 case OT_unconditionalF:
dfa9f0d5 18628 if (thumb_mode)
c921be7d 18629 inst.cond = cond->value;
dfa9f0d5
PB
18630 else
18631 {
c921be7d 18632 /* Delayed diagnostic. */
dfa9f0d5
PB
18633 inst.error = BAD_COND;
18634 inst.cond = COND_ALWAYS;
18635 }
c19d1205 18636 return opcode;
b99bd4ef 18637
c19d1205 18638 default:
c921be7d 18639 return NULL;
c19d1205
ZW
18640 }
18641 }
b99bd4ef 18642
c19d1205
ZW
18643 /* Cannot have a usual-position infix on a mnemonic of less than
18644 six characters (five would be a suffix). */
18645 if (end - base < 6)
c921be7d 18646 return NULL;
b99bd4ef 18647
c19d1205
ZW
18648 /* Look for infixed mnemonic in the usual position. */
18649 affix = base + 3;
21d799b5 18650 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
e3cb604e 18651 if (!cond)
c921be7d 18652 return NULL;
e3cb604e
PB
18653
18654 memcpy (save, affix, 2);
18655 memmove (affix, affix + 2, (end - affix) - 2);
21d799b5 18656 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
477330fc 18657 (end - base) - 2);
e3cb604e
PB
18658 memmove (affix + 2, affix, (end - affix) - 2);
18659 memcpy (affix, save, 2);
18660
088fa78e
KH
18661 if (opcode
18662 && (opcode->tag == OT_cinfix3
18663 || opcode->tag == OT_cinfix3_deprecated
18664 || opcode->tag == OT_csuf_or_in3
18665 || opcode->tag == OT_cinfix3_legacy))
b99bd4ef 18666 {
c921be7d 18667 /* Step CM. */
278df34e 18668 if (warn_on_deprecated && unified_syntax
088fa78e
KH
18669 && (opcode->tag == OT_cinfix3
18670 || opcode->tag == OT_cinfix3_deprecated))
5c3696f8 18671 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205
ZW
18672
18673 inst.cond = cond->value;
18674 return opcode;
b99bd4ef
NC
18675 }
18676
c921be7d 18677 return NULL;
b99bd4ef
NC
18678}
18679
e07e6e58
NC
18680/* This function generates an initial IT instruction, leaving its block
18681 virtually open for the new instructions. Eventually,
18682 the mask will be updated by now_it_add_mask () each time
18683 a new instruction needs to be included in the IT block.
18684 Finally, the block is closed with close_automatic_it_block ().
18685 The block closure can be requested either from md_assemble (),
18686 a tencode (), or due to a label hook. */
18687
18688static void
18689new_automatic_it_block (int cond)
18690{
18691 now_it.state = AUTOMATIC_IT_BLOCK;
18692 now_it.mask = 0x18;
18693 now_it.cc = cond;
18694 now_it.block_length = 1;
cd000bff 18695 mapping_state (MAP_THUMB);
e07e6e58 18696 now_it.insn = output_it_inst (cond, now_it.mask, NULL);
5a01bb1d
MGD
18697 now_it.warn_deprecated = FALSE;
18698 now_it.insn_cond = TRUE;
e07e6e58
NC
18699}
18700
18701/* Close an automatic IT block.
18702 See comments in new_automatic_it_block (). */
18703
18704static void
18705close_automatic_it_block (void)
18706{
18707 now_it.mask = 0x10;
18708 now_it.block_length = 0;
18709}
18710
18711/* Update the mask of the current automatically-generated IT
18712 instruction. See comments in new_automatic_it_block (). */
18713
18714static void
18715now_it_add_mask (int cond)
18716{
18717#define CLEAR_BIT(value, nbit) ((value) & ~(1 << (nbit)))
18718#define SET_BIT_VALUE(value, bitvalue, nbit) (CLEAR_BIT (value, nbit) \
477330fc 18719 | ((bitvalue) << (nbit)))
e07e6e58 18720 const int resulting_bit = (cond & 1);
c921be7d 18721
e07e6e58
NC
18722 now_it.mask &= 0xf;
18723 now_it.mask = SET_BIT_VALUE (now_it.mask,
477330fc
RM
18724 resulting_bit,
18725 (5 - now_it.block_length));
e07e6e58 18726 now_it.mask = SET_BIT_VALUE (now_it.mask,
477330fc
RM
18727 1,
18728 ((5 - now_it.block_length) - 1) );
e07e6e58
NC
18729 output_it_inst (now_it.cc, now_it.mask, now_it.insn);
18730
18731#undef CLEAR_BIT
18732#undef SET_BIT_VALUE
e07e6e58
NC
18733}
18734
18735/* The IT blocks handling machinery is accessed through the these functions:
18736 it_fsm_pre_encode () from md_assemble ()
18737 set_it_insn_type () optional, from the tencode functions
18738 set_it_insn_type_last () ditto
18739 in_it_block () ditto
18740 it_fsm_post_encode () from md_assemble ()
33eaf5de 18741 force_automatic_it_block_close () from label handling functions
e07e6e58
NC
18742
18743 Rationale:
18744 1) md_assemble () calls it_fsm_pre_encode () before calling tencode (),
477330fc
RM
18745 initializing the IT insn type with a generic initial value depending
18746 on the inst.condition.
e07e6e58 18747 2) During the tencode function, two things may happen:
477330fc
RM
18748 a) The tencode function overrides the IT insn type by
18749 calling either set_it_insn_type (type) or set_it_insn_type_last ().
18750 b) The tencode function queries the IT block state by
18751 calling in_it_block () (i.e. to determine narrow/not narrow mode).
18752
18753 Both set_it_insn_type and in_it_block run the internal FSM state
18754 handling function (handle_it_state), because: a) setting the IT insn
18755 type may incur in an invalid state (exiting the function),
18756 and b) querying the state requires the FSM to be updated.
18757 Specifically we want to avoid creating an IT block for conditional
18758 branches, so it_fsm_pre_encode is actually a guess and we can't
18759 determine whether an IT block is required until the tencode () routine
18760 has decided what type of instruction this actually it.
18761 Because of this, if set_it_insn_type and in_it_block have to be used,
18762 set_it_insn_type has to be called first.
18763
18764 set_it_insn_type_last () is a wrapper of set_it_insn_type (type), that
18765 determines the insn IT type depending on the inst.cond code.
18766 When a tencode () routine encodes an instruction that can be
18767 either outside an IT block, or, in the case of being inside, has to be
18768 the last one, set_it_insn_type_last () will determine the proper
18769 IT instruction type based on the inst.cond code. Otherwise,
18770 set_it_insn_type can be called for overriding that logic or
18771 for covering other cases.
18772
18773 Calling handle_it_state () may not transition the IT block state to
2b0f3761 18774 OUTSIDE_IT_BLOCK immediately, since the (current) state could be
477330fc
RM
18775 still queried. Instead, if the FSM determines that the state should
18776 be transitioned to OUTSIDE_IT_BLOCK, a flag is marked to be closed
18777 after the tencode () function: that's what it_fsm_post_encode () does.
18778
18779 Since in_it_block () calls the state handling function to get an
18780 updated state, an error may occur (due to invalid insns combination).
18781 In that case, inst.error is set.
18782 Therefore, inst.error has to be checked after the execution of
18783 the tencode () routine.
e07e6e58
NC
18784
18785 3) Back in md_assemble(), it_fsm_post_encode () is called to commit
477330fc
RM
18786 any pending state change (if any) that didn't take place in
18787 handle_it_state () as explained above. */
e07e6e58
NC
18788
18789static void
18790it_fsm_pre_encode (void)
18791{
18792 if (inst.cond != COND_ALWAYS)
18793 inst.it_insn_type = INSIDE_IT_INSN;
18794 else
18795 inst.it_insn_type = OUTSIDE_IT_INSN;
18796
18797 now_it.state_handled = 0;
18798}
18799
18800/* IT state FSM handling function. */
18801
18802static int
18803handle_it_state (void)
18804{
18805 now_it.state_handled = 1;
5a01bb1d 18806 now_it.insn_cond = FALSE;
e07e6e58
NC
18807
18808 switch (now_it.state)
18809 {
18810 case OUTSIDE_IT_BLOCK:
18811 switch (inst.it_insn_type)
18812 {
18813 case OUTSIDE_IT_INSN:
18814 break;
18815
18816 case INSIDE_IT_INSN:
18817 case INSIDE_IT_LAST_INSN:
18818 if (thumb_mode == 0)
18819 {
c921be7d 18820 if (unified_syntax
e07e6e58
NC
18821 && !(implicit_it_mode & IMPLICIT_IT_MODE_ARM))
18822 as_tsktsk (_("Warning: conditional outside an IT block"\
18823 " for Thumb."));
18824 }
18825 else
18826 {
18827 if ((implicit_it_mode & IMPLICIT_IT_MODE_THUMB)
fc289b0a 18828 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
e07e6e58
NC
18829 {
18830 /* Automatically generate the IT instruction. */
18831 new_automatic_it_block (inst.cond);
18832 if (inst.it_insn_type == INSIDE_IT_LAST_INSN)
18833 close_automatic_it_block ();
18834 }
18835 else
18836 {
18837 inst.error = BAD_OUT_IT;
18838 return FAIL;
18839 }
18840 }
18841 break;
18842
18843 case IF_INSIDE_IT_LAST_INSN:
18844 case NEUTRAL_IT_INSN:
18845 break;
18846
18847 case IT_INSN:
18848 now_it.state = MANUAL_IT_BLOCK;
18849 now_it.block_length = 0;
18850 break;
18851 }
18852 break;
18853
18854 case AUTOMATIC_IT_BLOCK:
18855 /* Three things may happen now:
18856 a) We should increment current it block size;
18857 b) We should close current it block (closing insn or 4 insns);
18858 c) We should close current it block and start a new one (due
18859 to incompatible conditions or
18860 4 insns-length block reached). */
18861
18862 switch (inst.it_insn_type)
18863 {
18864 case OUTSIDE_IT_INSN:
2b0f3761 18865 /* The closure of the block shall happen immediately,
e07e6e58
NC
18866 so any in_it_block () call reports the block as closed. */
18867 force_automatic_it_block_close ();
18868 break;
18869
18870 case INSIDE_IT_INSN:
18871 case INSIDE_IT_LAST_INSN:
18872 case IF_INSIDE_IT_LAST_INSN:
18873 now_it.block_length++;
18874
18875 if (now_it.block_length > 4
18876 || !now_it_compatible (inst.cond))
18877 {
18878 force_automatic_it_block_close ();
18879 if (inst.it_insn_type != IF_INSIDE_IT_LAST_INSN)
18880 new_automatic_it_block (inst.cond);
18881 }
18882 else
18883 {
5a01bb1d 18884 now_it.insn_cond = TRUE;
e07e6e58
NC
18885 now_it_add_mask (inst.cond);
18886 }
18887
18888 if (now_it.state == AUTOMATIC_IT_BLOCK
18889 && (inst.it_insn_type == INSIDE_IT_LAST_INSN
18890 || inst.it_insn_type == IF_INSIDE_IT_LAST_INSN))
18891 close_automatic_it_block ();
18892 break;
18893
18894 case NEUTRAL_IT_INSN:
18895 now_it.block_length++;
5a01bb1d 18896 now_it.insn_cond = TRUE;
e07e6e58
NC
18897
18898 if (now_it.block_length > 4)
18899 force_automatic_it_block_close ();
18900 else
18901 now_it_add_mask (now_it.cc & 1);
18902 break;
18903
18904 case IT_INSN:
18905 close_automatic_it_block ();
18906 now_it.state = MANUAL_IT_BLOCK;
18907 break;
18908 }
18909 break;
18910
18911 case MANUAL_IT_BLOCK:
18912 {
18913 /* Check conditional suffixes. */
18914 const int cond = now_it.cc ^ ((now_it.mask >> 4) & 1) ^ 1;
18915 int is_last;
18916 now_it.mask <<= 1;
18917 now_it.mask &= 0x1f;
18918 is_last = (now_it.mask == 0x10);
5a01bb1d 18919 now_it.insn_cond = TRUE;
e07e6e58
NC
18920
18921 switch (inst.it_insn_type)
18922 {
18923 case OUTSIDE_IT_INSN:
18924 inst.error = BAD_NOT_IT;
18925 return FAIL;
18926
18927 case INSIDE_IT_INSN:
18928 if (cond != inst.cond)
18929 {
18930 inst.error = BAD_IT_COND;
18931 return FAIL;
18932 }
18933 break;
18934
18935 case INSIDE_IT_LAST_INSN:
18936 case IF_INSIDE_IT_LAST_INSN:
18937 if (cond != inst.cond)
18938 {
18939 inst.error = BAD_IT_COND;
18940 return FAIL;
18941 }
18942 if (!is_last)
18943 {
18944 inst.error = BAD_BRANCH;
18945 return FAIL;
18946 }
18947 break;
18948
18949 case NEUTRAL_IT_INSN:
18950 /* The BKPT instruction is unconditional even in an IT block. */
18951 break;
18952
18953 case IT_INSN:
18954 inst.error = BAD_IT_IT;
18955 return FAIL;
18956 }
18957 }
18958 break;
18959 }
18960
18961 return SUCCESS;
18962}
18963
5a01bb1d
MGD
18964struct depr_insn_mask
18965{
18966 unsigned long pattern;
18967 unsigned long mask;
18968 const char* description;
18969};
18970
18971/* List of 16-bit instruction patterns deprecated in an IT block in
18972 ARMv8. */
18973static const struct depr_insn_mask depr_it_insns[] = {
18974 { 0xc000, 0xc000, N_("Short branches, Undefined, SVC, LDM/STM") },
18975 { 0xb000, 0xb000, N_("Miscellaneous 16-bit instructions") },
18976 { 0xa000, 0xb800, N_("ADR") },
18977 { 0x4800, 0xf800, N_("Literal loads") },
18978 { 0x4478, 0xf478, N_("Hi-register ADD, MOV, CMP, BX, BLX using pc") },
18979 { 0x4487, 0xfc87, N_("Hi-register ADD, MOV, CMP using pc") },
c8de034b
JW
18980 /* NOTE: 0x00dd is not the real encoding, instead, it is the 'tvalue'
18981 field in asm_opcode. 'tvalue' is used at the stage this check happen. */
18982 { 0x00dd, 0x7fff, N_("ADD/SUB sp, sp #imm") },
5a01bb1d
MGD
18983 { 0, 0, NULL }
18984};
18985
e07e6e58
NC
18986static void
18987it_fsm_post_encode (void)
18988{
18989 int is_last;
18990
18991 if (!now_it.state_handled)
18992 handle_it_state ();
18993
5a01bb1d
MGD
18994 if (now_it.insn_cond
18995 && !now_it.warn_deprecated
18996 && warn_on_deprecated
df9909b8
TP
18997 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)
18998 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_m))
5a01bb1d
MGD
18999 {
19000 if (inst.instruction >= 0x10000)
19001 {
5c3696f8 19002 as_tsktsk (_("IT blocks containing 32-bit Thumb instructions are "
df9909b8 19003 "performance deprecated in ARMv8-A and ARMv8-R"));
5a01bb1d
MGD
19004 now_it.warn_deprecated = TRUE;
19005 }
19006 else
19007 {
19008 const struct depr_insn_mask *p = depr_it_insns;
19009
19010 while (p->mask != 0)
19011 {
19012 if ((inst.instruction & p->mask) == p->pattern)
19013 {
df9909b8
TP
19014 as_tsktsk (_("IT blocks containing 16-bit Thumb "
19015 "instructions of the following class are "
19016 "performance deprecated in ARMv8-A and "
19017 "ARMv8-R: %s"), p->description);
5a01bb1d
MGD
19018 now_it.warn_deprecated = TRUE;
19019 break;
19020 }
19021
19022 ++p;
19023 }
19024 }
19025
19026 if (now_it.block_length > 1)
19027 {
5c3696f8 19028 as_tsktsk (_("IT blocks containing more than one conditional "
df9909b8
TP
19029 "instruction are performance deprecated in ARMv8-A and "
19030 "ARMv8-R"));
5a01bb1d
MGD
19031 now_it.warn_deprecated = TRUE;
19032 }
19033 }
19034
e07e6e58
NC
19035 is_last = (now_it.mask == 0x10);
19036 if (is_last)
19037 {
19038 now_it.state = OUTSIDE_IT_BLOCK;
19039 now_it.mask = 0;
19040 }
19041}
19042
19043static void
19044force_automatic_it_block_close (void)
19045{
19046 if (now_it.state == AUTOMATIC_IT_BLOCK)
19047 {
19048 close_automatic_it_block ();
19049 now_it.state = OUTSIDE_IT_BLOCK;
19050 now_it.mask = 0;
19051 }
19052}
19053
19054static int
19055in_it_block (void)
19056{
19057 if (!now_it.state_handled)
19058 handle_it_state ();
19059
19060 return now_it.state != OUTSIDE_IT_BLOCK;
19061}
19062
ff8646ee
TP
19063/* Whether OPCODE only has T32 encoding. Since this function is only used by
19064 t32_insn_ok, OPCODE enabled by v6t2 extension bit do not need to be listed
19065 here, hence the "known" in the function name. */
fc289b0a
TP
19066
19067static bfd_boolean
ff8646ee 19068known_t32_only_insn (const struct asm_opcode *opcode)
fc289b0a
TP
19069{
19070 /* Original Thumb-1 wide instruction. */
19071 if (opcode->tencode == do_t_blx
19072 || opcode->tencode == do_t_branch23
19073 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_msr)
19074 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_barrier))
19075 return TRUE;
19076
16a1fa25
TP
19077 /* Wide-only instruction added to ARMv8-M Baseline. */
19078 if (ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v8m_m_only)
ff8646ee
TP
19079 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_atomics)
19080 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v6t2_v8m)
19081 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_div))
19082 return TRUE;
19083
19084 return FALSE;
19085}
19086
19087/* Whether wide instruction variant can be used if available for a valid OPCODE
19088 in ARCH. */
19089
19090static bfd_boolean
19091t32_insn_ok (arm_feature_set arch, const struct asm_opcode *opcode)
19092{
19093 if (known_t32_only_insn (opcode))
19094 return TRUE;
19095
19096 /* Instruction with narrow and wide encoding added to ARMv8-M. Availability
19097 of variant T3 of B.W is checked in do_t_branch. */
19098 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
19099 && opcode->tencode == do_t_branch)
19100 return TRUE;
19101
bada4342
JW
19102 /* MOV accepts T1/T3 encodings under Baseline, T3 encoding is 32bit. */
19103 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
19104 && opcode->tencode == do_t_mov_cmp
19105 /* Make sure CMP instruction is not affected. */
19106 && opcode->aencode == do_mov)
19107 return TRUE;
19108
ff8646ee
TP
19109 /* Wide instruction variants of all instructions with narrow *and* wide
19110 variants become available with ARMv6t2. Other opcodes are either
19111 narrow-only or wide-only and are thus available if OPCODE is valid. */
19112 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v6t2))
19113 return TRUE;
19114
19115 /* OPCODE with narrow only instruction variant or wide variant not
19116 available. */
fc289b0a
TP
19117 return FALSE;
19118}
19119
c19d1205
ZW
19120void
19121md_assemble (char *str)
b99bd4ef 19122{
c19d1205
ZW
19123 char *p = str;
19124 const struct asm_opcode * opcode;
b99bd4ef 19125
c19d1205
ZW
19126 /* Align the previous label if needed. */
19127 if (last_label_seen != NULL)
b99bd4ef 19128 {
c19d1205
ZW
19129 symbol_set_frag (last_label_seen, frag_now);
19130 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
19131 S_SET_SEGMENT (last_label_seen, now_seg);
b99bd4ef
NC
19132 }
19133
c19d1205 19134 memset (&inst, '\0', sizeof (inst));
e2b0ab59
AV
19135 int r;
19136 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
19137 inst.relocs[r].type = BFD_RELOC_UNUSED;
b99bd4ef 19138
c19d1205
ZW
19139 opcode = opcode_lookup (&p);
19140 if (!opcode)
b99bd4ef 19141 {
c19d1205 19142 /* It wasn't an instruction, but it might be a register alias of
dcbf9037 19143 the form alias .req reg, or a Neon .dn/.qn directive. */
c921be7d 19144 if (! create_register_alias (str, p)
477330fc 19145 && ! create_neon_reg_alias (str, p))
c19d1205 19146 as_bad (_("bad instruction `%s'"), str);
b99bd4ef 19147
b99bd4ef
NC
19148 return;
19149 }
19150
278df34e 19151 if (warn_on_deprecated && opcode->tag == OT_cinfix3_deprecated)
5c3696f8 19152 as_tsktsk (_("s suffix on comparison instruction is deprecated"));
088fa78e 19153
037e8744
JB
19154 /* The value which unconditional instructions should have in place of the
19155 condition field. */
19156 inst.uncond_value = (opcode->tag == OT_csuffixF) ? 0xf : -1;
19157
c19d1205 19158 if (thumb_mode)
b99bd4ef 19159 {
e74cfd16 19160 arm_feature_set variant;
8f06b2d8
PB
19161
19162 variant = cpu_variant;
19163 /* Only allow coprocessor instructions on Thumb-2 capable devices. */
e74cfd16
PB
19164 if (!ARM_CPU_HAS_FEATURE (variant, arm_arch_t2))
19165 ARM_CLEAR_FEATURE (variant, variant, fpu_any_hard);
c19d1205 19166 /* Check that this instruction is supported for this CPU. */
62b3e311
PB
19167 if (!opcode->tvariant
19168 || (thumb_mode == 1
19169 && !ARM_CPU_HAS_FEATURE (variant, *opcode->tvariant)))
b99bd4ef 19170 {
173205ca
TP
19171 if (opcode->tencode == do_t_swi)
19172 as_bad (_("SVC is not permitted on this architecture"));
19173 else
19174 as_bad (_("selected processor does not support `%s' in Thumb mode"), str);
b99bd4ef
NC
19175 return;
19176 }
c19d1205
ZW
19177 if (inst.cond != COND_ALWAYS && !unified_syntax
19178 && opcode->tencode != do_t_branch)
b99bd4ef 19179 {
c19d1205 19180 as_bad (_("Thumb does not support conditional execution"));
b99bd4ef
NC
19181 return;
19182 }
19183
fc289b0a
TP
19184 /* Two things are addressed here:
19185 1) Implicit require narrow instructions on Thumb-1.
19186 This avoids relaxation accidentally introducing Thumb-2
19187 instructions.
19188 2) Reject wide instructions in non Thumb-2 cores.
19189
19190 Only instructions with narrow and wide variants need to be handled
19191 but selecting all non wide-only instructions is easier. */
19192 if (!ARM_CPU_HAS_FEATURE (variant, arm_ext_v6t2)
ff8646ee 19193 && !t32_insn_ok (variant, opcode))
076d447c 19194 {
fc289b0a
TP
19195 if (inst.size_req == 0)
19196 inst.size_req = 2;
19197 else if (inst.size_req == 4)
752d5da4 19198 {
ff8646ee
TP
19199 if (ARM_CPU_HAS_FEATURE (variant, arm_ext_v8m))
19200 as_bad (_("selected processor does not support 32bit wide "
19201 "variant of instruction `%s'"), str);
19202 else
19203 as_bad (_("selected processor does not support `%s' in "
19204 "Thumb-2 mode"), str);
fc289b0a 19205 return;
752d5da4 19206 }
076d447c
PB
19207 }
19208
c19d1205
ZW
19209 inst.instruction = opcode->tvalue;
19210
5be8be5d 19211 if (!parse_operands (p, opcode->operands, /*thumb=*/TRUE))
477330fc
RM
19212 {
19213 /* Prepare the it_insn_type for those encodings that don't set
19214 it. */
19215 it_fsm_pre_encode ();
c19d1205 19216
477330fc 19217 opcode->tencode ();
e07e6e58 19218
477330fc
RM
19219 it_fsm_post_encode ();
19220 }
e27ec89e 19221
0110f2b8 19222 if (!(inst.error || inst.relax))
b99bd4ef 19223 {
9c2799c2 19224 gas_assert (inst.instruction < 0xe800 || inst.instruction > 0xffff);
c19d1205
ZW
19225 inst.size = (inst.instruction > 0xffff ? 4 : 2);
19226 if (inst.size_req && inst.size_req != inst.size)
b99bd4ef 19227 {
c19d1205 19228 as_bad (_("cannot honor width suffix -- `%s'"), str);
b99bd4ef
NC
19229 return;
19230 }
19231 }
076d447c
PB
19232
19233 /* Something has gone badly wrong if we try to relax a fixed size
477330fc 19234 instruction. */
9c2799c2 19235 gas_assert (inst.size_req == 0 || !inst.relax);
076d447c 19236
e74cfd16
PB
19237 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
19238 *opcode->tvariant);
ee065d83 19239 /* Many Thumb-2 instructions also have Thumb-1 variants, so explicitly
fc289b0a
TP
19240 set those bits when Thumb-2 32-bit instructions are seen. The impact
19241 of relaxable instructions will be considered later after we finish all
19242 relaxation. */
ff8646ee
TP
19243 if (ARM_FEATURE_CORE_EQUAL (cpu_variant, arm_arch_any))
19244 variant = arm_arch_none;
19245 else
19246 variant = cpu_variant;
19247 if (inst.size == 4 && !t32_insn_ok (variant, opcode))
e74cfd16
PB
19248 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
19249 arm_ext_v6t2);
cd000bff 19250
88714cb8
DG
19251 check_neon_suffixes;
19252
cd000bff 19253 if (!inst.error)
c877a2f2
NC
19254 {
19255 mapping_state (MAP_THUMB);
19256 }
c19d1205 19257 }
3e9e4fcf 19258 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
c19d1205 19259 {
845b51d6
PB
19260 bfd_boolean is_bx;
19261
19262 /* bx is allowed on v5 cores, and sometimes on v4 cores. */
19263 is_bx = (opcode->aencode == do_bx);
19264
c19d1205 19265 /* Check that this instruction is supported for this CPU. */
845b51d6
PB
19266 if (!(is_bx && fix_v4bx)
19267 && !(opcode->avariant &&
19268 ARM_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant)))
b99bd4ef 19269 {
84b52b66 19270 as_bad (_("selected processor does not support `%s' in ARM mode"), str);
c19d1205 19271 return;
b99bd4ef 19272 }
c19d1205 19273 if (inst.size_req)
b99bd4ef 19274 {
c19d1205
ZW
19275 as_bad (_("width suffixes are invalid in ARM mode -- `%s'"), str);
19276 return;
b99bd4ef
NC
19277 }
19278
c19d1205
ZW
19279 inst.instruction = opcode->avalue;
19280 if (opcode->tag == OT_unconditionalF)
eff0bc54 19281 inst.instruction |= 0xFU << 28;
c19d1205
ZW
19282 else
19283 inst.instruction |= inst.cond << 28;
19284 inst.size = INSN_SIZE;
5be8be5d 19285 if (!parse_operands (p, opcode->operands, /*thumb=*/FALSE))
477330fc
RM
19286 {
19287 it_fsm_pre_encode ();
19288 opcode->aencode ();
19289 it_fsm_post_encode ();
19290 }
ee065d83 19291 /* Arm mode bx is marked as both v4T and v5 because it's still required
477330fc 19292 on a hypothetical non-thumb v5 core. */
845b51d6 19293 if (is_bx)
e74cfd16 19294 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, arm_ext_v4t);
ee065d83 19295 else
e74cfd16
PB
19296 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
19297 *opcode->avariant);
88714cb8
DG
19298
19299 check_neon_suffixes;
19300
cd000bff 19301 if (!inst.error)
c877a2f2
NC
19302 {
19303 mapping_state (MAP_ARM);
19304 }
b99bd4ef 19305 }
3e9e4fcf
JB
19306 else
19307 {
19308 as_bad (_("attempt to use an ARM instruction on a Thumb-only processor "
19309 "-- `%s'"), str);
19310 return;
19311 }
c19d1205
ZW
19312 output_inst (str);
19313}
b99bd4ef 19314
e07e6e58
NC
19315static void
19316check_it_blocks_finished (void)
19317{
19318#ifdef OBJ_ELF
19319 asection *sect;
19320
19321 for (sect = stdoutput->sections; sect != NULL; sect = sect->next)
19322 if (seg_info (sect)->tc_segment_info_data.current_it.state
19323 == MANUAL_IT_BLOCK)
19324 {
19325 as_warn (_("section '%s' finished with an open IT block."),
19326 sect->name);
19327 }
19328#else
19329 if (now_it.state == MANUAL_IT_BLOCK)
19330 as_warn (_("file finished with an open IT block."));
19331#endif
19332}
19333
c19d1205
ZW
19334/* Various frobbings of labels and their addresses. */
19335
19336void
19337arm_start_line_hook (void)
19338{
19339 last_label_seen = NULL;
b99bd4ef
NC
19340}
19341
c19d1205
ZW
19342void
19343arm_frob_label (symbolS * sym)
b99bd4ef 19344{
c19d1205 19345 last_label_seen = sym;
b99bd4ef 19346
c19d1205 19347 ARM_SET_THUMB (sym, thumb_mode);
b99bd4ef 19348
c19d1205
ZW
19349#if defined OBJ_COFF || defined OBJ_ELF
19350 ARM_SET_INTERWORK (sym, support_interwork);
19351#endif
b99bd4ef 19352
e07e6e58
NC
19353 force_automatic_it_block_close ();
19354
5f4273c7 19355 /* Note - do not allow local symbols (.Lxxx) to be labelled
c19d1205
ZW
19356 as Thumb functions. This is because these labels, whilst
19357 they exist inside Thumb code, are not the entry points for
19358 possible ARM->Thumb calls. Also, these labels can be used
19359 as part of a computed goto or switch statement. eg gcc
19360 can generate code that looks like this:
b99bd4ef 19361
c19d1205
ZW
19362 ldr r2, [pc, .Laaa]
19363 lsl r3, r3, #2
19364 ldr r2, [r3, r2]
19365 mov pc, r2
b99bd4ef 19366
c19d1205
ZW
19367 .Lbbb: .word .Lxxx
19368 .Lccc: .word .Lyyy
19369 ..etc...
19370 .Laaa: .word Lbbb
b99bd4ef 19371
c19d1205
ZW
19372 The first instruction loads the address of the jump table.
19373 The second instruction converts a table index into a byte offset.
19374 The third instruction gets the jump address out of the table.
19375 The fourth instruction performs the jump.
b99bd4ef 19376
c19d1205
ZW
19377 If the address stored at .Laaa is that of a symbol which has the
19378 Thumb_Func bit set, then the linker will arrange for this address
19379 to have the bottom bit set, which in turn would mean that the
19380 address computation performed by the third instruction would end
19381 up with the bottom bit set. Since the ARM is capable of unaligned
19382 word loads, the instruction would then load the incorrect address
19383 out of the jump table, and chaos would ensue. */
19384 if (label_is_thumb_function_name
19385 && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
19386 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
b99bd4ef 19387 {
c19d1205
ZW
19388 /* When the address of a Thumb function is taken the bottom
19389 bit of that address should be set. This will allow
19390 interworking between Arm and Thumb functions to work
19391 correctly. */
b99bd4ef 19392
c19d1205 19393 THUMB_SET_FUNC (sym, 1);
b99bd4ef 19394
c19d1205 19395 label_is_thumb_function_name = FALSE;
b99bd4ef 19396 }
07a53e5c 19397
07a53e5c 19398 dwarf2_emit_label (sym);
b99bd4ef
NC
19399}
19400
c921be7d 19401bfd_boolean
c19d1205 19402arm_data_in_code (void)
b99bd4ef 19403{
c19d1205 19404 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
b99bd4ef 19405 {
c19d1205
ZW
19406 *input_line_pointer = '/';
19407 input_line_pointer += 5;
19408 *input_line_pointer = 0;
c921be7d 19409 return TRUE;
b99bd4ef
NC
19410 }
19411
c921be7d 19412 return FALSE;
b99bd4ef
NC
19413}
19414
c19d1205
ZW
19415char *
19416arm_canonicalize_symbol_name (char * name)
b99bd4ef 19417{
c19d1205 19418 int len;
b99bd4ef 19419
c19d1205
ZW
19420 if (thumb_mode && (len = strlen (name)) > 5
19421 && streq (name + len - 5, "/data"))
19422 *(name + len - 5) = 0;
b99bd4ef 19423
c19d1205 19424 return name;
b99bd4ef 19425}
c19d1205
ZW
19426\f
19427/* Table of all register names defined by default. The user can
19428 define additional names with .req. Note that all register names
19429 should appear in both upper and lowercase variants. Some registers
19430 also have mixed-case names. */
b99bd4ef 19431
dcbf9037 19432#define REGDEF(s,n,t) { #s, n, REG_TYPE_##t, TRUE, 0 }
c19d1205 19433#define REGNUM(p,n,t) REGDEF(p##n, n, t)
5287ad62 19434#define REGNUM2(p,n,t) REGDEF(p##n, 2 * n, t)
c19d1205
ZW
19435#define REGSET(p,t) \
19436 REGNUM(p, 0,t), REGNUM(p, 1,t), REGNUM(p, 2,t), REGNUM(p, 3,t), \
19437 REGNUM(p, 4,t), REGNUM(p, 5,t), REGNUM(p, 6,t), REGNUM(p, 7,t), \
19438 REGNUM(p, 8,t), REGNUM(p, 9,t), REGNUM(p,10,t), REGNUM(p,11,t), \
19439 REGNUM(p,12,t), REGNUM(p,13,t), REGNUM(p,14,t), REGNUM(p,15,t)
5287ad62
JB
19440#define REGSETH(p,t) \
19441 REGNUM(p,16,t), REGNUM(p,17,t), REGNUM(p,18,t), REGNUM(p,19,t), \
19442 REGNUM(p,20,t), REGNUM(p,21,t), REGNUM(p,22,t), REGNUM(p,23,t), \
19443 REGNUM(p,24,t), REGNUM(p,25,t), REGNUM(p,26,t), REGNUM(p,27,t), \
19444 REGNUM(p,28,t), REGNUM(p,29,t), REGNUM(p,30,t), REGNUM(p,31,t)
19445#define REGSET2(p,t) \
19446 REGNUM2(p, 0,t), REGNUM2(p, 1,t), REGNUM2(p, 2,t), REGNUM2(p, 3,t), \
19447 REGNUM2(p, 4,t), REGNUM2(p, 5,t), REGNUM2(p, 6,t), REGNUM2(p, 7,t), \
19448 REGNUM2(p, 8,t), REGNUM2(p, 9,t), REGNUM2(p,10,t), REGNUM2(p,11,t), \
19449 REGNUM2(p,12,t), REGNUM2(p,13,t), REGNUM2(p,14,t), REGNUM2(p,15,t)
90ec0d68
MGD
19450#define SPLRBANK(base,bank,t) \
19451 REGDEF(lr_##bank, 768|((base+0)<<16), t), \
19452 REGDEF(sp_##bank, 768|((base+1)<<16), t), \
19453 REGDEF(spsr_##bank, 768|(base<<16)|SPSR_BIT, t), \
19454 REGDEF(LR_##bank, 768|((base+0)<<16), t), \
19455 REGDEF(SP_##bank, 768|((base+1)<<16), t), \
19456 REGDEF(SPSR_##bank, 768|(base<<16)|SPSR_BIT, t)
7ed4c4c5 19457
c19d1205 19458static const struct reg_entry reg_names[] =
7ed4c4c5 19459{
c19d1205
ZW
19460 /* ARM integer registers. */
19461 REGSET(r, RN), REGSET(R, RN),
7ed4c4c5 19462
c19d1205
ZW
19463 /* ATPCS synonyms. */
19464 REGDEF(a1,0,RN), REGDEF(a2,1,RN), REGDEF(a3, 2,RN), REGDEF(a4, 3,RN),
19465 REGDEF(v1,4,RN), REGDEF(v2,5,RN), REGDEF(v3, 6,RN), REGDEF(v4, 7,RN),
19466 REGDEF(v5,8,RN), REGDEF(v6,9,RN), REGDEF(v7,10,RN), REGDEF(v8,11,RN),
7ed4c4c5 19467
c19d1205
ZW
19468 REGDEF(A1,0,RN), REGDEF(A2,1,RN), REGDEF(A3, 2,RN), REGDEF(A4, 3,RN),
19469 REGDEF(V1,4,RN), REGDEF(V2,5,RN), REGDEF(V3, 6,RN), REGDEF(V4, 7,RN),
19470 REGDEF(V5,8,RN), REGDEF(V6,9,RN), REGDEF(V7,10,RN), REGDEF(V8,11,RN),
7ed4c4c5 19471
c19d1205
ZW
19472 /* Well-known aliases. */
19473 REGDEF(wr, 7,RN), REGDEF(sb, 9,RN), REGDEF(sl,10,RN), REGDEF(fp,11,RN),
19474 REGDEF(ip,12,RN), REGDEF(sp,13,RN), REGDEF(lr,14,RN), REGDEF(pc,15,RN),
19475
19476 REGDEF(WR, 7,RN), REGDEF(SB, 9,RN), REGDEF(SL,10,RN), REGDEF(FP,11,RN),
19477 REGDEF(IP,12,RN), REGDEF(SP,13,RN), REGDEF(LR,14,RN), REGDEF(PC,15,RN),
19478
19479 /* Coprocessor numbers. */
19480 REGSET(p, CP), REGSET(P, CP),
19481
19482 /* Coprocessor register numbers. The "cr" variants are for backward
19483 compatibility. */
19484 REGSET(c, CN), REGSET(C, CN),
19485 REGSET(cr, CN), REGSET(CR, CN),
19486
90ec0d68
MGD
19487 /* ARM banked registers. */
19488 REGDEF(R8_usr,512|(0<<16),RNB), REGDEF(r8_usr,512|(0<<16),RNB),
19489 REGDEF(R9_usr,512|(1<<16),RNB), REGDEF(r9_usr,512|(1<<16),RNB),
19490 REGDEF(R10_usr,512|(2<<16),RNB), REGDEF(r10_usr,512|(2<<16),RNB),
19491 REGDEF(R11_usr,512|(3<<16),RNB), REGDEF(r11_usr,512|(3<<16),RNB),
19492 REGDEF(R12_usr,512|(4<<16),RNB), REGDEF(r12_usr,512|(4<<16),RNB),
19493 REGDEF(SP_usr,512|(5<<16),RNB), REGDEF(sp_usr,512|(5<<16),RNB),
19494 REGDEF(LR_usr,512|(6<<16),RNB), REGDEF(lr_usr,512|(6<<16),RNB),
19495
19496 REGDEF(R8_fiq,512|(8<<16),RNB), REGDEF(r8_fiq,512|(8<<16),RNB),
19497 REGDEF(R9_fiq,512|(9<<16),RNB), REGDEF(r9_fiq,512|(9<<16),RNB),
19498 REGDEF(R10_fiq,512|(10<<16),RNB), REGDEF(r10_fiq,512|(10<<16),RNB),
19499 REGDEF(R11_fiq,512|(11<<16),RNB), REGDEF(r11_fiq,512|(11<<16),RNB),
19500 REGDEF(R12_fiq,512|(12<<16),RNB), REGDEF(r12_fiq,512|(12<<16),RNB),
1472d06f 19501 REGDEF(SP_fiq,512|(13<<16),RNB), REGDEF(sp_fiq,512|(13<<16),RNB),
90ec0d68
MGD
19502 REGDEF(LR_fiq,512|(14<<16),RNB), REGDEF(lr_fiq,512|(14<<16),RNB),
19503 REGDEF(SPSR_fiq,512|(14<<16)|SPSR_BIT,RNB), REGDEF(spsr_fiq,512|(14<<16)|SPSR_BIT,RNB),
19504
19505 SPLRBANK(0,IRQ,RNB), SPLRBANK(0,irq,RNB),
19506 SPLRBANK(2,SVC,RNB), SPLRBANK(2,svc,RNB),
19507 SPLRBANK(4,ABT,RNB), SPLRBANK(4,abt,RNB),
19508 SPLRBANK(6,UND,RNB), SPLRBANK(6,und,RNB),
19509 SPLRBANK(12,MON,RNB), SPLRBANK(12,mon,RNB),
19510 REGDEF(elr_hyp,768|(14<<16),RNB), REGDEF(ELR_hyp,768|(14<<16),RNB),
19511 REGDEF(sp_hyp,768|(15<<16),RNB), REGDEF(SP_hyp,768|(15<<16),RNB),
fa94de6b 19512 REGDEF(spsr_hyp,768|(14<<16)|SPSR_BIT,RNB),
90ec0d68
MGD
19513 REGDEF(SPSR_hyp,768|(14<<16)|SPSR_BIT,RNB),
19514
c19d1205
ZW
19515 /* FPA registers. */
19516 REGNUM(f,0,FN), REGNUM(f,1,FN), REGNUM(f,2,FN), REGNUM(f,3,FN),
19517 REGNUM(f,4,FN), REGNUM(f,5,FN), REGNUM(f,6,FN), REGNUM(f,7, FN),
19518
19519 REGNUM(F,0,FN), REGNUM(F,1,FN), REGNUM(F,2,FN), REGNUM(F,3,FN),
19520 REGNUM(F,4,FN), REGNUM(F,5,FN), REGNUM(F,6,FN), REGNUM(F,7, FN),
19521
19522 /* VFP SP registers. */
5287ad62
JB
19523 REGSET(s,VFS), REGSET(S,VFS),
19524 REGSETH(s,VFS), REGSETH(S,VFS),
c19d1205
ZW
19525
19526 /* VFP DP Registers. */
5287ad62
JB
19527 REGSET(d,VFD), REGSET(D,VFD),
19528 /* Extra Neon DP registers. */
19529 REGSETH(d,VFD), REGSETH(D,VFD),
19530
19531 /* Neon QP registers. */
19532 REGSET2(q,NQ), REGSET2(Q,NQ),
c19d1205
ZW
19533
19534 /* VFP control registers. */
19535 REGDEF(fpsid,0,VFC), REGDEF(fpscr,1,VFC), REGDEF(fpexc,8,VFC),
19536 REGDEF(FPSID,0,VFC), REGDEF(FPSCR,1,VFC), REGDEF(FPEXC,8,VFC),
cd2cf30b
PB
19537 REGDEF(fpinst,9,VFC), REGDEF(fpinst2,10,VFC),
19538 REGDEF(FPINST,9,VFC), REGDEF(FPINST2,10,VFC),
19539 REGDEF(mvfr0,7,VFC), REGDEF(mvfr1,6,VFC),
19540 REGDEF(MVFR0,7,VFC), REGDEF(MVFR1,6,VFC),
40c7d507 19541 REGDEF(mvfr2,5,VFC), REGDEF(MVFR2,5,VFC),
c19d1205
ZW
19542
19543 /* Maverick DSP coprocessor registers. */
19544 REGSET(mvf,MVF), REGSET(mvd,MVD), REGSET(mvfx,MVFX), REGSET(mvdx,MVDX),
19545 REGSET(MVF,MVF), REGSET(MVD,MVD), REGSET(MVFX,MVFX), REGSET(MVDX,MVDX),
19546
19547 REGNUM(mvax,0,MVAX), REGNUM(mvax,1,MVAX),
19548 REGNUM(mvax,2,MVAX), REGNUM(mvax,3,MVAX),
19549 REGDEF(dspsc,0,DSPSC),
19550
19551 REGNUM(MVAX,0,MVAX), REGNUM(MVAX,1,MVAX),
19552 REGNUM(MVAX,2,MVAX), REGNUM(MVAX,3,MVAX),
19553 REGDEF(DSPSC,0,DSPSC),
19554
19555 /* iWMMXt data registers - p0, c0-15. */
19556 REGSET(wr,MMXWR), REGSET(wR,MMXWR), REGSET(WR, MMXWR),
19557
19558 /* iWMMXt control registers - p1, c0-3. */
19559 REGDEF(wcid, 0,MMXWC), REGDEF(wCID, 0,MMXWC), REGDEF(WCID, 0,MMXWC),
19560 REGDEF(wcon, 1,MMXWC), REGDEF(wCon, 1,MMXWC), REGDEF(WCON, 1,MMXWC),
19561 REGDEF(wcssf, 2,MMXWC), REGDEF(wCSSF, 2,MMXWC), REGDEF(WCSSF, 2,MMXWC),
19562 REGDEF(wcasf, 3,MMXWC), REGDEF(wCASF, 3,MMXWC), REGDEF(WCASF, 3,MMXWC),
19563
19564 /* iWMMXt scalar (constant/offset) registers - p1, c8-11. */
19565 REGDEF(wcgr0, 8,MMXWCG), REGDEF(wCGR0, 8,MMXWCG), REGDEF(WCGR0, 8,MMXWCG),
19566 REGDEF(wcgr1, 9,MMXWCG), REGDEF(wCGR1, 9,MMXWCG), REGDEF(WCGR1, 9,MMXWCG),
19567 REGDEF(wcgr2,10,MMXWCG), REGDEF(wCGR2,10,MMXWCG), REGDEF(WCGR2,10,MMXWCG),
19568 REGDEF(wcgr3,11,MMXWCG), REGDEF(wCGR3,11,MMXWCG), REGDEF(WCGR3,11,MMXWCG),
19569
19570 /* XScale accumulator registers. */
19571 REGNUM(acc,0,XSCALE), REGNUM(ACC,0,XSCALE),
19572};
19573#undef REGDEF
19574#undef REGNUM
19575#undef REGSET
7ed4c4c5 19576
c19d1205
ZW
19577/* Table of all PSR suffixes. Bare "CPSR" and "SPSR" are handled
19578 within psr_required_here. */
19579static const struct asm_psr psrs[] =
19580{
19581 /* Backward compatibility notation. Note that "all" is no longer
19582 truly all possible PSR bits. */
19583 {"all", PSR_c | PSR_f},
19584 {"flg", PSR_f},
19585 {"ctl", PSR_c},
19586
19587 /* Individual flags. */
19588 {"f", PSR_f},
19589 {"c", PSR_c},
19590 {"x", PSR_x},
19591 {"s", PSR_s},
59b42a0d 19592
c19d1205
ZW
19593 /* Combinations of flags. */
19594 {"fs", PSR_f | PSR_s},
19595 {"fx", PSR_f | PSR_x},
19596 {"fc", PSR_f | PSR_c},
19597 {"sf", PSR_s | PSR_f},
19598 {"sx", PSR_s | PSR_x},
19599 {"sc", PSR_s | PSR_c},
19600 {"xf", PSR_x | PSR_f},
19601 {"xs", PSR_x | PSR_s},
19602 {"xc", PSR_x | PSR_c},
19603 {"cf", PSR_c | PSR_f},
19604 {"cs", PSR_c | PSR_s},
19605 {"cx", PSR_c | PSR_x},
19606 {"fsx", PSR_f | PSR_s | PSR_x},
19607 {"fsc", PSR_f | PSR_s | PSR_c},
19608 {"fxs", PSR_f | PSR_x | PSR_s},
19609 {"fxc", PSR_f | PSR_x | PSR_c},
19610 {"fcs", PSR_f | PSR_c | PSR_s},
19611 {"fcx", PSR_f | PSR_c | PSR_x},
19612 {"sfx", PSR_s | PSR_f | PSR_x},
19613 {"sfc", PSR_s | PSR_f | PSR_c},
19614 {"sxf", PSR_s | PSR_x | PSR_f},
19615 {"sxc", PSR_s | PSR_x | PSR_c},
19616 {"scf", PSR_s | PSR_c | PSR_f},
19617 {"scx", PSR_s | PSR_c | PSR_x},
19618 {"xfs", PSR_x | PSR_f | PSR_s},
19619 {"xfc", PSR_x | PSR_f | PSR_c},
19620 {"xsf", PSR_x | PSR_s | PSR_f},
19621 {"xsc", PSR_x | PSR_s | PSR_c},
19622 {"xcf", PSR_x | PSR_c | PSR_f},
19623 {"xcs", PSR_x | PSR_c | PSR_s},
19624 {"cfs", PSR_c | PSR_f | PSR_s},
19625 {"cfx", PSR_c | PSR_f | PSR_x},
19626 {"csf", PSR_c | PSR_s | PSR_f},
19627 {"csx", PSR_c | PSR_s | PSR_x},
19628 {"cxf", PSR_c | PSR_x | PSR_f},
19629 {"cxs", PSR_c | PSR_x | PSR_s},
19630 {"fsxc", PSR_f | PSR_s | PSR_x | PSR_c},
19631 {"fscx", PSR_f | PSR_s | PSR_c | PSR_x},
19632 {"fxsc", PSR_f | PSR_x | PSR_s | PSR_c},
19633 {"fxcs", PSR_f | PSR_x | PSR_c | PSR_s},
19634 {"fcsx", PSR_f | PSR_c | PSR_s | PSR_x},
19635 {"fcxs", PSR_f | PSR_c | PSR_x | PSR_s},
19636 {"sfxc", PSR_s | PSR_f | PSR_x | PSR_c},
19637 {"sfcx", PSR_s | PSR_f | PSR_c | PSR_x},
19638 {"sxfc", PSR_s | PSR_x | PSR_f | PSR_c},
19639 {"sxcf", PSR_s | PSR_x | PSR_c | PSR_f},
19640 {"scfx", PSR_s | PSR_c | PSR_f | PSR_x},
19641 {"scxf", PSR_s | PSR_c | PSR_x | PSR_f},
19642 {"xfsc", PSR_x | PSR_f | PSR_s | PSR_c},
19643 {"xfcs", PSR_x | PSR_f | PSR_c | PSR_s},
19644 {"xsfc", PSR_x | PSR_s | PSR_f | PSR_c},
19645 {"xscf", PSR_x | PSR_s | PSR_c | PSR_f},
19646 {"xcfs", PSR_x | PSR_c | PSR_f | PSR_s},
19647 {"xcsf", PSR_x | PSR_c | PSR_s | PSR_f},
19648 {"cfsx", PSR_c | PSR_f | PSR_s | PSR_x},
19649 {"cfxs", PSR_c | PSR_f | PSR_x | PSR_s},
19650 {"csfx", PSR_c | PSR_s | PSR_f | PSR_x},
19651 {"csxf", PSR_c | PSR_s | PSR_x | PSR_f},
19652 {"cxfs", PSR_c | PSR_x | PSR_f | PSR_s},
19653 {"cxsf", PSR_c | PSR_x | PSR_s | PSR_f},
19654};
19655
62b3e311
PB
19656/* Table of V7M psr names. */
19657static const struct asm_psr v7m_psrs[] =
19658{
1a336194
TP
19659 {"apsr", 0x0 }, {"APSR", 0x0 },
19660 {"iapsr", 0x1 }, {"IAPSR", 0x1 },
19661 {"eapsr", 0x2 }, {"EAPSR", 0x2 },
19662 {"psr", 0x3 }, {"PSR", 0x3 },
19663 {"xpsr", 0x3 }, {"XPSR", 0x3 }, {"xPSR", 3 },
19664 {"ipsr", 0x5 }, {"IPSR", 0x5 },
19665 {"epsr", 0x6 }, {"EPSR", 0x6 },
19666 {"iepsr", 0x7 }, {"IEPSR", 0x7 },
19667 {"msp", 0x8 }, {"MSP", 0x8 },
19668 {"psp", 0x9 }, {"PSP", 0x9 },
19669 {"msplim", 0xa }, {"MSPLIM", 0xa },
19670 {"psplim", 0xb }, {"PSPLIM", 0xb },
19671 {"primask", 0x10}, {"PRIMASK", 0x10},
19672 {"basepri", 0x11}, {"BASEPRI", 0x11},
19673 {"basepri_max", 0x12}, {"BASEPRI_MAX", 0x12},
1a336194
TP
19674 {"faultmask", 0x13}, {"FAULTMASK", 0x13},
19675 {"control", 0x14}, {"CONTROL", 0x14},
19676 {"msp_ns", 0x88}, {"MSP_NS", 0x88},
19677 {"psp_ns", 0x89}, {"PSP_NS", 0x89},
19678 {"msplim_ns", 0x8a}, {"MSPLIM_NS", 0x8a},
19679 {"psplim_ns", 0x8b}, {"PSPLIM_NS", 0x8b},
19680 {"primask_ns", 0x90}, {"PRIMASK_NS", 0x90},
19681 {"basepri_ns", 0x91}, {"BASEPRI_NS", 0x91},
19682 {"faultmask_ns", 0x93}, {"FAULTMASK_NS", 0x93},
19683 {"control_ns", 0x94}, {"CONTROL_NS", 0x94},
19684 {"sp_ns", 0x98}, {"SP_NS", 0x98 }
62b3e311
PB
19685};
19686
c19d1205
ZW
19687/* Table of all shift-in-operand names. */
19688static const struct asm_shift_name shift_names [] =
b99bd4ef 19689{
c19d1205
ZW
19690 { "asl", SHIFT_LSL }, { "ASL", SHIFT_LSL },
19691 { "lsl", SHIFT_LSL }, { "LSL", SHIFT_LSL },
19692 { "lsr", SHIFT_LSR }, { "LSR", SHIFT_LSR },
19693 { "asr", SHIFT_ASR }, { "ASR", SHIFT_ASR },
19694 { "ror", SHIFT_ROR }, { "ROR", SHIFT_ROR },
19695 { "rrx", SHIFT_RRX }, { "RRX", SHIFT_RRX }
19696};
b99bd4ef 19697
c19d1205
ZW
19698/* Table of all explicit relocation names. */
19699#ifdef OBJ_ELF
19700static struct reloc_entry reloc_names[] =
19701{
19702 { "got", BFD_RELOC_ARM_GOT32 }, { "GOT", BFD_RELOC_ARM_GOT32 },
19703 { "gotoff", BFD_RELOC_ARM_GOTOFF }, { "GOTOFF", BFD_RELOC_ARM_GOTOFF },
19704 { "plt", BFD_RELOC_ARM_PLT32 }, { "PLT", BFD_RELOC_ARM_PLT32 },
19705 { "target1", BFD_RELOC_ARM_TARGET1 }, { "TARGET1", BFD_RELOC_ARM_TARGET1 },
19706 { "target2", BFD_RELOC_ARM_TARGET2 }, { "TARGET2", BFD_RELOC_ARM_TARGET2 },
19707 { "sbrel", BFD_RELOC_ARM_SBREL32 }, { "SBREL", BFD_RELOC_ARM_SBREL32 },
19708 { "tlsgd", BFD_RELOC_ARM_TLS_GD32}, { "TLSGD", BFD_RELOC_ARM_TLS_GD32},
19709 { "tlsldm", BFD_RELOC_ARM_TLS_LDM32}, { "TLSLDM", BFD_RELOC_ARM_TLS_LDM32},
19710 { "tlsldo", BFD_RELOC_ARM_TLS_LDO32}, { "TLSLDO", BFD_RELOC_ARM_TLS_LDO32},
19711 { "gottpoff",BFD_RELOC_ARM_TLS_IE32}, { "GOTTPOFF",BFD_RELOC_ARM_TLS_IE32},
b43420e6 19712 { "tpoff", BFD_RELOC_ARM_TLS_LE32}, { "TPOFF", BFD_RELOC_ARM_TLS_LE32},
0855e32b
NS
19713 { "got_prel", BFD_RELOC_ARM_GOT_PREL}, { "GOT_PREL", BFD_RELOC_ARM_GOT_PREL},
19714 { "tlsdesc", BFD_RELOC_ARM_TLS_GOTDESC},
477330fc 19715 { "TLSDESC", BFD_RELOC_ARM_TLS_GOTDESC},
0855e32b 19716 { "tlscall", BFD_RELOC_ARM_TLS_CALL},
477330fc 19717 { "TLSCALL", BFD_RELOC_ARM_TLS_CALL},
0855e32b 19718 { "tlsdescseq", BFD_RELOC_ARM_TLS_DESCSEQ},
188fd7ae
CL
19719 { "TLSDESCSEQ", BFD_RELOC_ARM_TLS_DESCSEQ},
19720 { "gotfuncdesc", BFD_RELOC_ARM_GOTFUNCDESC },
19721 { "GOTFUNCDESC", BFD_RELOC_ARM_GOTFUNCDESC },
19722 { "gotofffuncdesc", BFD_RELOC_ARM_GOTOFFFUNCDESC },
19723 { "GOTOFFFUNCDESC", BFD_RELOC_ARM_GOTOFFFUNCDESC },
19724 { "funcdesc", BFD_RELOC_ARM_FUNCDESC },
5c5a4843
CL
19725 { "FUNCDESC", BFD_RELOC_ARM_FUNCDESC },
19726 { "tlsgd_fdpic", BFD_RELOC_ARM_TLS_GD32_FDPIC }, { "TLSGD_FDPIC", BFD_RELOC_ARM_TLS_GD32_FDPIC },
19727 { "tlsldm_fdpic", BFD_RELOC_ARM_TLS_LDM32_FDPIC }, { "TLSLDM_FDPIC", BFD_RELOC_ARM_TLS_LDM32_FDPIC },
19728 { "gottpoff_fdpic", BFD_RELOC_ARM_TLS_IE32_FDPIC }, { "GOTTPOFF_FDIC", BFD_RELOC_ARM_TLS_IE32_FDPIC },
c19d1205
ZW
19729};
19730#endif
b99bd4ef 19731
c19d1205
ZW
19732/* Table of all conditional affixes. 0xF is not defined as a condition code. */
19733static const struct asm_cond conds[] =
19734{
19735 {"eq", 0x0},
19736 {"ne", 0x1},
19737 {"cs", 0x2}, {"hs", 0x2},
19738 {"cc", 0x3}, {"ul", 0x3}, {"lo", 0x3},
19739 {"mi", 0x4},
19740 {"pl", 0x5},
19741 {"vs", 0x6},
19742 {"vc", 0x7},
19743 {"hi", 0x8},
19744 {"ls", 0x9},
19745 {"ge", 0xa},
19746 {"lt", 0xb},
19747 {"gt", 0xc},
19748 {"le", 0xd},
19749 {"al", 0xe}
19750};
bfae80f2 19751
e797f7e0 19752#define UL_BARRIER(L,U,CODE,FEAT) \
823d2571
TG
19753 { L, CODE, ARM_FEATURE_CORE_LOW (FEAT) }, \
19754 { U, CODE, ARM_FEATURE_CORE_LOW (FEAT) }
e797f7e0 19755
62b3e311
PB
19756static struct asm_barrier_opt barrier_opt_names[] =
19757{
e797f7e0
MGD
19758 UL_BARRIER ("sy", "SY", 0xf, ARM_EXT_BARRIER),
19759 UL_BARRIER ("st", "ST", 0xe, ARM_EXT_BARRIER),
19760 UL_BARRIER ("ld", "LD", 0xd, ARM_EXT_V8),
19761 UL_BARRIER ("ish", "ISH", 0xb, ARM_EXT_BARRIER),
19762 UL_BARRIER ("sh", "SH", 0xb, ARM_EXT_BARRIER),
19763 UL_BARRIER ("ishst", "ISHST", 0xa, ARM_EXT_BARRIER),
19764 UL_BARRIER ("shst", "SHST", 0xa, ARM_EXT_BARRIER),
19765 UL_BARRIER ("ishld", "ISHLD", 0x9, ARM_EXT_V8),
19766 UL_BARRIER ("un", "UN", 0x7, ARM_EXT_BARRIER),
19767 UL_BARRIER ("nsh", "NSH", 0x7, ARM_EXT_BARRIER),
19768 UL_BARRIER ("unst", "UNST", 0x6, ARM_EXT_BARRIER),
19769 UL_BARRIER ("nshst", "NSHST", 0x6, ARM_EXT_BARRIER),
19770 UL_BARRIER ("nshld", "NSHLD", 0x5, ARM_EXT_V8),
19771 UL_BARRIER ("osh", "OSH", 0x3, ARM_EXT_BARRIER),
19772 UL_BARRIER ("oshst", "OSHST", 0x2, ARM_EXT_BARRIER),
19773 UL_BARRIER ("oshld", "OSHLD", 0x1, ARM_EXT_V8)
62b3e311
PB
19774};
19775
e797f7e0
MGD
19776#undef UL_BARRIER
19777
c19d1205
ZW
19778/* Table of ARM-format instructions. */
19779
19780/* Macros for gluing together operand strings. N.B. In all cases
19781 other than OPS0, the trailing OP_stop comes from default
19782 zero-initialization of the unspecified elements of the array. */
19783#define OPS0() { OP_stop, }
19784#define OPS1(a) { OP_##a, }
19785#define OPS2(a,b) { OP_##a,OP_##b, }
19786#define OPS3(a,b,c) { OP_##a,OP_##b,OP_##c, }
19787#define OPS4(a,b,c,d) { OP_##a,OP_##b,OP_##c,OP_##d, }
19788#define OPS5(a,b,c,d,e) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e, }
19789#define OPS6(a,b,c,d,e,f) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e,OP_##f, }
19790
5be8be5d
DG
19791/* These macros are similar to the OPSn, but do not prepend the OP_ prefix.
19792 This is useful when mixing operands for ARM and THUMB, i.e. using the
19793 MIX_ARM_THUMB_OPERANDS macro.
19794 In order to use these macros, prefix the number of operands with _
19795 e.g. _3. */
19796#define OPS_1(a) { a, }
19797#define OPS_2(a,b) { a,b, }
19798#define OPS_3(a,b,c) { a,b,c, }
19799#define OPS_4(a,b,c,d) { a,b,c,d, }
19800#define OPS_5(a,b,c,d,e) { a,b,c,d,e, }
19801#define OPS_6(a,b,c,d,e,f) { a,b,c,d,e,f, }
19802
c19d1205
ZW
19803/* These macros abstract out the exact format of the mnemonic table and
19804 save some repeated characters. */
19805
19806/* The normal sort of mnemonic; has a Thumb variant; takes a conditional suffix. */
19807#define TxCE(mnem, op, top, nops, ops, ae, te) \
21d799b5 19808 { mnem, OPS##nops ops, OT_csuffix, 0x##op, top, ARM_VARIANT, \
1887dd22 19809 THUMB_VARIANT, do_##ae, do_##te }
c19d1205
ZW
19810
19811/* Two variants of the above - TCE for a numeric Thumb opcode, tCE for
19812 a T_MNEM_xyz enumerator. */
19813#define TCE(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 19814 TxCE (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 19815#define tCE(mnem, aop, top, nops, ops, ae, te) \
21d799b5 19816 TxCE (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205
ZW
19817
19818/* Second most common sort of mnemonic: has a Thumb variant, takes a conditional
19819 infix after the third character. */
19820#define TxC3(mnem, op, top, nops, ops, ae, te) \
21d799b5 19821 { mnem, OPS##nops ops, OT_cinfix3, 0x##op, top, ARM_VARIANT, \
1887dd22 19822 THUMB_VARIANT, do_##ae, do_##te }
088fa78e 19823#define TxC3w(mnem, op, top, nops, ops, ae, te) \
21d799b5 19824 { mnem, OPS##nops ops, OT_cinfix3_deprecated, 0x##op, top, ARM_VARIANT, \
088fa78e 19825 THUMB_VARIANT, do_##ae, do_##te }
c19d1205 19826#define TC3(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 19827 TxC3 (mnem, aop, 0x##top, nops, ops, ae, te)
088fa78e 19828#define TC3w(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 19829 TxC3w (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 19830#define tC3(mnem, aop, top, nops, ops, ae, te) \
21d799b5 19831 TxC3 (mnem, aop, T_MNEM##top, nops, ops, ae, te)
088fa78e 19832#define tC3w(mnem, aop, top, nops, ops, ae, te) \
21d799b5 19833 TxC3w (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205 19834
c19d1205 19835/* Mnemonic that cannot be conditionalized. The ARM condition-code
dfa9f0d5
PB
19836 field is still 0xE. Many of the Thumb variants can be executed
19837 conditionally, so this is checked separately. */
c19d1205 19838#define TUE(mnem, op, top, nops, ops, ae, te) \
21d799b5 19839 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
1887dd22 19840 THUMB_VARIANT, do_##ae, do_##te }
c19d1205 19841
dd5181d5
KT
19842/* Same as TUE but the encoding function for ARM and Thumb modes is the same.
19843 Used by mnemonics that have very minimal differences in the encoding for
19844 ARM and Thumb variants and can be handled in a common function. */
19845#define TUEc(mnem, op, top, nops, ops, en) \
19846 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
19847 THUMB_VARIANT, do_##en, do_##en }
19848
c19d1205
ZW
19849/* Mnemonic that cannot be conditionalized, and bears 0xF in its ARM
19850 condition code field. */
19851#define TUF(mnem, op, top, nops, ops, ae, te) \
21d799b5 19852 { mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##top, ARM_VARIANT, \
1887dd22 19853 THUMB_VARIANT, do_##ae, do_##te }
c19d1205
ZW
19854
19855/* ARM-only variants of all the above. */
6a86118a 19856#define CE(mnem, op, nops, ops, ae) \
21d799b5 19857 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
6a86118a
NC
19858
19859#define C3(mnem, op, nops, ops, ae) \
19860 { #mnem, OPS##nops ops, OT_cinfix3, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
19861
cf3cf39d
TP
19862/* Thumb-only variants of TCE and TUE. */
19863#define ToC(mnem, top, nops, ops, te) \
19864 { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
19865 do_##te }
cf3cf39d
TP
19866
19867#define ToU(mnem, top, nops, ops, te) \
19868 { mnem, OPS##nops ops, OT_unconditional, 0x0, 0x##top, 0, THUMB_VARIANT, \
19869 NULL, do_##te }
cf3cf39d 19870
4389b29a
AV
19871/* T_MNEM_xyz enumerator variants of ToC. */
19872#define toC(mnem, top, nops, ops, te) \
19873 { mnem, OPS##nops ops, OT_csuffix, 0x0, T_MNEM##top, 0, THUMB_VARIANT, NULL, \
19874 do_##te }
19875
f6b2b12d
AV
19876/* T_MNEM_xyz enumerator variants of ToU. */
19877#define toU(mnem, top, nops, ops, te) \
19878 { mnem, OPS##nops ops, OT_unconditional, 0x0, T_MNEM##top, 0, THUMB_VARIANT, \
19879 NULL, do_##te }
19880
e3cb604e
PB
19881/* Legacy mnemonics that always have conditional infix after the third
19882 character. */
19883#define CL(mnem, op, nops, ops, ae) \
21d799b5 19884 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
e3cb604e
PB
19885 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
19886
8f06b2d8
PB
19887/* Coprocessor instructions. Isomorphic between Arm and Thumb-2. */
19888#define cCE(mnem, op, nops, ops, ae) \
21d799b5 19889 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae }
8f06b2d8 19890
e3cb604e
PB
19891/* Legacy coprocessor instructions where conditional infix and conditional
19892 suffix are ambiguous. For consistency this includes all FPA instructions,
19893 not just the potentially ambiguous ones. */
19894#define cCL(mnem, op, nops, ops, ae) \
21d799b5 19895 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
e3cb604e
PB
19896 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae }
19897
19898/* Coprocessor, takes either a suffix or a position-3 infix
19899 (for an FPA corner case). */
19900#define C3E(mnem, op, nops, ops, ae) \
21d799b5 19901 { mnem, OPS##nops ops, OT_csuf_or_in3, \
e3cb604e 19902 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae }
8f06b2d8 19903
6a86118a 19904#define xCM_(m1, m2, m3, op, nops, ops, ae) \
21d799b5
NC
19905 { m1 #m2 m3, OPS##nops ops, \
19906 sizeof (#m2) == 1 ? OT_odd_infix_unc : OT_odd_infix_0 + sizeof (m1) - 1, \
6a86118a
NC
19907 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
19908
19909#define CM(m1, m2, op, nops, ops, ae) \
e07e6e58
NC
19910 xCM_ (m1, , m2, op, nops, ops, ae), \
19911 xCM_ (m1, eq, m2, op, nops, ops, ae), \
19912 xCM_ (m1, ne, m2, op, nops, ops, ae), \
19913 xCM_ (m1, cs, m2, op, nops, ops, ae), \
19914 xCM_ (m1, hs, m2, op, nops, ops, ae), \
19915 xCM_ (m1, cc, m2, op, nops, ops, ae), \
19916 xCM_ (m1, ul, m2, op, nops, ops, ae), \
19917 xCM_ (m1, lo, m2, op, nops, ops, ae), \
19918 xCM_ (m1, mi, m2, op, nops, ops, ae), \
19919 xCM_ (m1, pl, m2, op, nops, ops, ae), \
19920 xCM_ (m1, vs, m2, op, nops, ops, ae), \
19921 xCM_ (m1, vc, m2, op, nops, ops, ae), \
19922 xCM_ (m1, hi, m2, op, nops, ops, ae), \
19923 xCM_ (m1, ls, m2, op, nops, ops, ae), \
19924 xCM_ (m1, ge, m2, op, nops, ops, ae), \
19925 xCM_ (m1, lt, m2, op, nops, ops, ae), \
19926 xCM_ (m1, gt, m2, op, nops, ops, ae), \
19927 xCM_ (m1, le, m2, op, nops, ops, ae), \
19928 xCM_ (m1, al, m2, op, nops, ops, ae)
6a86118a
NC
19929
19930#define UE(mnem, op, nops, ops, ae) \
19931 { #mnem, OPS##nops ops, OT_unconditional, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL }
19932
19933#define UF(mnem, op, nops, ops, ae) \
19934 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL }
19935
5287ad62
JB
19936/* Neon data-processing. ARM versions are unconditional with cond=0xf.
19937 The Thumb and ARM variants are mostly the same (bits 0-23 and 24/28), so we
19938 use the same encoding function for each. */
19939#define NUF(mnem, op, nops, ops, enc) \
19940 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op, \
19941 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc }
19942
19943/* Neon data processing, version which indirects through neon_enc_tab for
19944 the various overloaded versions of opcodes. */
19945#define nUF(mnem, op, nops, ops, enc) \
21d799b5 19946 { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op, \
5287ad62
JB
19947 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc }
19948
19949/* Neon insn with conditional suffix for the ARM version, non-overloaded
19950 version. */
037e8744
JB
19951#define NCE_tag(mnem, op, nops, ops, enc, tag) \
19952 { #mnem, OPS##nops ops, tag, 0x##op, 0x##op, ARM_VARIANT, \
5287ad62
JB
19953 THUMB_VARIANT, do_##enc, do_##enc }
19954
037e8744 19955#define NCE(mnem, op, nops, ops, enc) \
e07e6e58 19956 NCE_tag (mnem, op, nops, ops, enc, OT_csuffix)
037e8744
JB
19957
19958#define NCEF(mnem, op, nops, ops, enc) \
e07e6e58 19959 NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF)
037e8744 19960
5287ad62 19961/* Neon insn with conditional suffix for the ARM version, overloaded types. */
037e8744 19962#define nCE_tag(mnem, op, nops, ops, enc, tag) \
21d799b5 19963 { #mnem, OPS##nops ops, tag, N_MNEM##op, N_MNEM##op, \
5287ad62
JB
19964 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc }
19965
037e8744 19966#define nCE(mnem, op, nops, ops, enc) \
e07e6e58 19967 nCE_tag (mnem, op, nops, ops, enc, OT_csuffix)
037e8744
JB
19968
19969#define nCEF(mnem, op, nops, ops, enc) \
e07e6e58 19970 nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF)
037e8744 19971
c19d1205
ZW
19972#define do_0 0
19973
c19d1205 19974static const struct asm_opcode insns[] =
bfae80f2 19975{
74db7efb
NC
19976#define ARM_VARIANT & arm_ext_v1 /* Core ARM Instructions. */
19977#define THUMB_VARIANT & arm_ext_v4t
21d799b5
NC
19978 tCE("and", 0000000, _and, 3, (RR, oRR, SH), arit, t_arit3c),
19979 tC3("ands", 0100000, _ands, 3, (RR, oRR, SH), arit, t_arit3c),
19980 tCE("eor", 0200000, _eor, 3, (RR, oRR, SH), arit, t_arit3c),
19981 tC3("eors", 0300000, _eors, 3, (RR, oRR, SH), arit, t_arit3c),
19982 tCE("sub", 0400000, _sub, 3, (RR, oRR, SH), arit, t_add_sub),
19983 tC3("subs", 0500000, _subs, 3, (RR, oRR, SH), arit, t_add_sub),
19984 tCE("add", 0800000, _add, 3, (RR, oRR, SHG), arit, t_add_sub),
19985 tC3("adds", 0900000, _adds, 3, (RR, oRR, SHG), arit, t_add_sub),
19986 tCE("adc", 0a00000, _adc, 3, (RR, oRR, SH), arit, t_arit3c),
19987 tC3("adcs", 0b00000, _adcs, 3, (RR, oRR, SH), arit, t_arit3c),
19988 tCE("sbc", 0c00000, _sbc, 3, (RR, oRR, SH), arit, t_arit3),
19989 tC3("sbcs", 0d00000, _sbcs, 3, (RR, oRR, SH), arit, t_arit3),
19990 tCE("orr", 1800000, _orr, 3, (RR, oRR, SH), arit, t_arit3c),
19991 tC3("orrs", 1900000, _orrs, 3, (RR, oRR, SH), arit, t_arit3c),
19992 tCE("bic", 1c00000, _bic, 3, (RR, oRR, SH), arit, t_arit3),
19993 tC3("bics", 1d00000, _bics, 3, (RR, oRR, SH), arit, t_arit3),
c19d1205
ZW
19994
19995 /* The p-variants of tst/cmp/cmn/teq (below) are the pre-V6 mechanism
19996 for setting PSR flag bits. They are obsolete in V6 and do not
19997 have Thumb equivalents. */
21d799b5
NC
19998 tCE("tst", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
19999 tC3w("tsts", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
20000 CL("tstp", 110f000, 2, (RR, SH), cmp),
20001 tCE("cmp", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
20002 tC3w("cmps", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
20003 CL("cmpp", 150f000, 2, (RR, SH), cmp),
20004 tCE("cmn", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
20005 tC3w("cmns", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
20006 CL("cmnp", 170f000, 2, (RR, SH), cmp),
20007
20008 tCE("mov", 1a00000, _mov, 2, (RR, SH), mov, t_mov_cmp),
72d98d16 20009 tC3("movs", 1b00000, _movs, 2, (RR, SHG), mov, t_mov_cmp),
21d799b5
NC
20010 tCE("mvn", 1e00000, _mvn, 2, (RR, SH), mov, t_mvn_tst),
20011 tC3("mvns", 1f00000, _mvns, 2, (RR, SH), mov, t_mvn_tst),
20012
20013 tCE("ldr", 4100000, _ldr, 2, (RR, ADDRGLDR),ldst, t_ldst),
5be8be5d
DG
20014 tC3("ldrb", 4500000, _ldrb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
20015 tCE("str", 4000000, _str, _2, (MIX_ARM_THUMB_OPERANDS (OP_RR,
20016 OP_RRnpc),
20017 OP_ADDRGLDR),ldst, t_ldst),
20018 tC3("strb", 4400000, _strb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
21d799b5
NC
20019
20020 tCE("stm", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
20021 tC3("stmia", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
20022 tC3("stmea", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
20023 tCE("ldm", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
20024 tC3("ldmia", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
20025 tC3("ldmfd", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
20026
21d799b5
NC
20027 tCE("b", a000000, _b, 1, (EXPr), branch, t_branch),
20028 TCE("bl", b000000, f000f800, 1, (EXPr), bl, t_branch23),
bfae80f2 20029
c19d1205 20030 /* Pseudo ops. */
21d799b5 20031 tCE("adr", 28f0000, _adr, 2, (RR, EXP), adr, t_adr),
2fc8bdac 20032 C3(adrl, 28f0000, 2, (RR, EXP), adrl),
21d799b5 20033 tCE("nop", 1a00000, _nop, 1, (oI255c), nop, t_nop),
74db7efb 20034 tCE("udf", 7f000f0, _udf, 1, (oIffffb), bkpt, t_udf),
c19d1205
ZW
20035
20036 /* Thumb-compatibility pseudo ops. */
21d799b5
NC
20037 tCE("lsl", 1a00000, _lsl, 3, (RR, oRR, SH), shift, t_shift),
20038 tC3("lsls", 1b00000, _lsls, 3, (RR, oRR, SH), shift, t_shift),
20039 tCE("lsr", 1a00020, _lsr, 3, (RR, oRR, SH), shift, t_shift),
20040 tC3("lsrs", 1b00020, _lsrs, 3, (RR, oRR, SH), shift, t_shift),
20041 tCE("asr", 1a00040, _asr, 3, (RR, oRR, SH), shift, t_shift),
20042 tC3("asrs", 1b00040, _asrs, 3, (RR, oRR, SH), shift, t_shift),
20043 tCE("ror", 1a00060, _ror, 3, (RR, oRR, SH), shift, t_shift),
20044 tC3("rors", 1b00060, _rors, 3, (RR, oRR, SH), shift, t_shift),
20045 tCE("neg", 2600000, _neg, 2, (RR, RR), rd_rn, t_neg),
20046 tC3("negs", 2700000, _negs, 2, (RR, RR), rd_rn, t_neg),
20047 tCE("push", 92d0000, _push, 1, (REGLST), push_pop, t_push_pop),
20048 tCE("pop", 8bd0000, _pop, 1, (REGLST), push_pop, t_push_pop),
c19d1205 20049
16a4cf17 20050 /* These may simplify to neg. */
21d799b5
NC
20051 TCE("rsb", 0600000, ebc00000, 3, (RR, oRR, SH), arit, t_rsb),
20052 TC3("rsbs", 0700000, ebd00000, 3, (RR, oRR, SH), arit, t_rsb),
16a4cf17 20053
173205ca
TP
20054#undef THUMB_VARIANT
20055#define THUMB_VARIANT & arm_ext_os
20056
20057 TCE("swi", f000000, df00, 1, (EXPi), swi, t_swi),
20058 TCE("svc", f000000, df00, 1, (EXPi), swi, t_swi),
20059
c921be7d
NC
20060#undef THUMB_VARIANT
20061#define THUMB_VARIANT & arm_ext_v6
20062
21d799b5 20063 TCE("cpy", 1a00000, 4600, 2, (RR, RR), rd_rm, t_cpy),
c19d1205
ZW
20064
20065 /* V1 instructions with no Thumb analogue prior to V6T2. */
c921be7d
NC
20066#undef THUMB_VARIANT
20067#define THUMB_VARIANT & arm_ext_v6t2
20068
21d799b5
NC
20069 TCE("teq", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
20070 TC3w("teqs", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
20071 CL("teqp", 130f000, 2, (RR, SH), cmp),
c19d1205 20072
5be8be5d
DG
20073 TC3("ldrt", 4300000, f8500e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
20074 TC3("ldrbt", 4700000, f8100e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
20075 TC3("strt", 4200000, f8400e00, 2, (RR_npcsp, ADDR), ldstt, t_ldstt),
20076 TC3("strbt", 4600000, f8000e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
c19d1205 20077
21d799b5
NC
20078 TC3("stmdb", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
20079 TC3("stmfd", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205 20080
21d799b5
NC
20081 TC3("ldmdb", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
20082 TC3("ldmea", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205
ZW
20083
20084 /* V1 instructions with no Thumb analogue at all. */
21d799b5 20085 CE("rsc", 0e00000, 3, (RR, oRR, SH), arit),
c19d1205
ZW
20086 C3(rscs, 0f00000, 3, (RR, oRR, SH), arit),
20087
20088 C3(stmib, 9800000, 2, (RRw, REGLST), ldmstm),
20089 C3(stmfa, 9800000, 2, (RRw, REGLST), ldmstm),
20090 C3(stmda, 8000000, 2, (RRw, REGLST), ldmstm),
20091 C3(stmed, 8000000, 2, (RRw, REGLST), ldmstm),
20092 C3(ldmib, 9900000, 2, (RRw, REGLST), ldmstm),
20093 C3(ldmed, 9900000, 2, (RRw, REGLST), ldmstm),
20094 C3(ldmda, 8100000, 2, (RRw, REGLST), ldmstm),
20095 C3(ldmfa, 8100000, 2, (RRw, REGLST), ldmstm),
20096
c921be7d
NC
20097#undef ARM_VARIANT
20098#define ARM_VARIANT & arm_ext_v2 /* ARM 2 - multiplies. */
20099#undef THUMB_VARIANT
20100#define THUMB_VARIANT & arm_ext_v4t
20101
21d799b5
NC
20102 tCE("mul", 0000090, _mul, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
20103 tC3("muls", 0100090, _muls, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
c19d1205 20104
c921be7d
NC
20105#undef THUMB_VARIANT
20106#define THUMB_VARIANT & arm_ext_v6t2
20107
21d799b5 20108 TCE("mla", 0200090, fb000000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
c19d1205
ZW
20109 C3(mlas, 0300090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas),
20110
20111 /* Generic coprocessor instructions. */
21d799b5
NC
20112 TCE("cdp", e000000, ee000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
20113 TCE("ldc", c100000, ec100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20114 TC3("ldcl", c500000, ec500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20115 TCE("stc", c000000, ec000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20116 TC3("stcl", c400000, ec400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20117 TCE("mcr", e000010, ee000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
db472d6f 20118 TCE("mrc", e100010, ee100010, 6, (RCP, I7b, APSR_RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 20119
c921be7d
NC
20120#undef ARM_VARIANT
20121#define ARM_VARIANT & arm_ext_v2s /* ARM 3 - swp instructions. */
20122
21d799b5 20123 CE("swp", 1000090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
c19d1205
ZW
20124 C3(swpb, 1400090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
20125
c921be7d
NC
20126#undef ARM_VARIANT
20127#define ARM_VARIANT & arm_ext_v3 /* ARM 6 Status register instructions. */
20128#undef THUMB_VARIANT
20129#define THUMB_VARIANT & arm_ext_msr
20130
d2cd1205
JB
20131 TCE("mrs", 1000000, f3e08000, 2, (RRnpc, rPSR), mrs, t_mrs),
20132 TCE("msr", 120f000, f3808000, 2, (wPSR, RR_EXi), msr, t_msr),
c19d1205 20133
c921be7d
NC
20134#undef ARM_VARIANT
20135#define ARM_VARIANT & arm_ext_v3m /* ARM 7M long multiplies. */
20136#undef THUMB_VARIANT
20137#define THUMB_VARIANT & arm_ext_v6t2
20138
21d799b5
NC
20139 TCE("smull", 0c00090, fb800000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
20140 CM("smull","s", 0d00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
20141 TCE("umull", 0800090, fba00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
20142 CM("umull","s", 0900090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
20143 TCE("smlal", 0e00090, fbc00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
20144 CM("smlal","s", 0f00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
20145 TCE("umlal", 0a00090, fbe00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
20146 CM("umlal","s", 0b00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
c19d1205 20147
c921be7d
NC
20148#undef ARM_VARIANT
20149#define ARM_VARIANT & arm_ext_v4 /* ARM Architecture 4. */
20150#undef THUMB_VARIANT
20151#define THUMB_VARIANT & arm_ext_v4t
20152
5be8be5d
DG
20153 tC3("ldrh", 01000b0, _ldrh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
20154 tC3("strh", 00000b0, _strh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
20155 tC3("ldrsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
20156 tC3("ldrsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
56c0a61f
RE
20157 tC3("ldsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
20158 tC3("ldsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
c19d1205 20159
c921be7d
NC
20160#undef ARM_VARIANT
20161#define ARM_VARIANT & arm_ext_v4t_5
20162
c19d1205
ZW
20163 /* ARM Architecture 4T. */
20164 /* Note: bx (and blx) are required on V5, even if the processor does
20165 not support Thumb. */
21d799b5 20166 TCE("bx", 12fff10, 4700, 1, (RR), bx, t_bx),
c19d1205 20167
c921be7d
NC
20168#undef ARM_VARIANT
20169#define ARM_VARIANT & arm_ext_v5 /* ARM Architecture 5T. */
20170#undef THUMB_VARIANT
20171#define THUMB_VARIANT & arm_ext_v5t
20172
c19d1205
ZW
20173 /* Note: blx has 2 variants; the .value coded here is for
20174 BLX(2). Only this variant has conditional execution. */
21d799b5
NC
20175 TCE("blx", 12fff30, 4780, 1, (RR_EXr), blx, t_blx),
20176 TUE("bkpt", 1200070, be00, 1, (oIffffb), bkpt, t_bkpt),
c19d1205 20177
c921be7d
NC
20178#undef THUMB_VARIANT
20179#define THUMB_VARIANT & arm_ext_v6t2
20180
21d799b5
NC
20181 TCE("clz", 16f0f10, fab0f080, 2, (RRnpc, RRnpc), rd_rm, t_clz),
20182 TUF("ldc2", c100000, fc100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20183 TUF("ldc2l", c500000, fc500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20184 TUF("stc2", c000000, fc000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20185 TUF("stc2l", c400000, fc400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20186 TUF("cdp2", e000000, fe000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
20187 TUF("mcr2", e000010, fe000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
20188 TUF("mrc2", e100010, fe100010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 20189
c921be7d 20190#undef ARM_VARIANT
74db7efb
NC
20191#define ARM_VARIANT & arm_ext_v5exp /* ARM Architecture 5TExP. */
20192#undef THUMB_VARIANT
20193#define THUMB_VARIANT & arm_ext_v5exp
c921be7d 20194
21d799b5
NC
20195 TCE("smlabb", 1000080, fb100000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
20196 TCE("smlatb", 10000a0, fb100020, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
20197 TCE("smlabt", 10000c0, fb100010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
20198 TCE("smlatt", 10000e0, fb100030, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 20199
21d799b5
NC
20200 TCE("smlawb", 1200080, fb300000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
20201 TCE("smlawt", 12000c0, fb300010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 20202
21d799b5
NC
20203 TCE("smlalbb", 1400080, fbc00080, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
20204 TCE("smlaltb", 14000a0, fbc000a0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
20205 TCE("smlalbt", 14000c0, fbc00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
20206 TCE("smlaltt", 14000e0, fbc000b0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
c19d1205 20207
21d799b5
NC
20208 TCE("smulbb", 1600080, fb10f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20209 TCE("smultb", 16000a0, fb10f020, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20210 TCE("smulbt", 16000c0, fb10f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20211 TCE("smultt", 16000e0, fb10f030, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 20212
21d799b5
NC
20213 TCE("smulwb", 12000a0, fb30f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20214 TCE("smulwt", 12000e0, fb30f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 20215
03ee1b7f
NC
20216 TCE("qadd", 1000050, fa80f080, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
20217 TCE("qdadd", 1400050, fa80f090, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
20218 TCE("qsub", 1200050, fa80f0a0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
20219 TCE("qdsub", 1600050, fa80f0b0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
c19d1205 20220
c921be7d 20221#undef ARM_VARIANT
74db7efb
NC
20222#define ARM_VARIANT & arm_ext_v5e /* ARM Architecture 5TE. */
20223#undef THUMB_VARIANT
20224#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 20225
21d799b5 20226 TUF("pld", 450f000, f810f000, 1, (ADDR), pld, t_pld),
5be8be5d
DG
20227 TC3("ldrd", 00000d0, e8500000, 3, (RRnpc_npcsp, oRRnpc_npcsp, ADDRGLDRS),
20228 ldrd, t_ldstd),
20229 TC3("strd", 00000f0, e8400000, 3, (RRnpc_npcsp, oRRnpc_npcsp,
20230 ADDRGLDRS), ldrd, t_ldstd),
c19d1205 20231
21d799b5
NC
20232 TCE("mcrr", c400000, ec400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
20233 TCE("mrrc", c500000, ec500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
c19d1205 20234
c921be7d
NC
20235#undef ARM_VARIANT
20236#define ARM_VARIANT & arm_ext_v5j /* ARM Architecture 5TEJ. */
20237
21d799b5 20238 TCE("bxj", 12fff20, f3c08f00, 1, (RR), bxj, t_bxj),
c19d1205 20239
c921be7d
NC
20240#undef ARM_VARIANT
20241#define ARM_VARIANT & arm_ext_v6 /* ARM V6. */
20242#undef THUMB_VARIANT
20243#define THUMB_VARIANT & arm_ext_v6
20244
21d799b5
NC
20245 TUF("cpsie", 1080000, b660, 2, (CPSF, oI31b), cpsi, t_cpsi),
20246 TUF("cpsid", 10c0000, b670, 2, (CPSF, oI31b), cpsi, t_cpsi),
20247 tCE("rev", 6bf0f30, _rev, 2, (RRnpc, RRnpc), rd_rm, t_rev),
20248 tCE("rev16", 6bf0fb0, _rev16, 2, (RRnpc, RRnpc), rd_rm, t_rev),
20249 tCE("revsh", 6ff0fb0, _revsh, 2, (RRnpc, RRnpc), rd_rm, t_rev),
20250 tCE("sxth", 6bf0070, _sxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
20251 tCE("uxth", 6ff0070, _uxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
20252 tCE("sxtb", 6af0070, _sxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
20253 tCE("uxtb", 6ef0070, _uxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
20254 TUF("setend", 1010000, b650, 1, (ENDI), setend, t_setend),
c19d1205 20255
c921be7d 20256#undef THUMB_VARIANT
ff8646ee 20257#define THUMB_VARIANT & arm_ext_v6t2_v8m
c921be7d 20258
5be8be5d
DG
20259 TCE("ldrex", 1900f9f, e8500f00, 2, (RRnpc_npcsp, ADDR), ldrex, t_ldrex),
20260 TCE("strex", 1800f90, e8400000, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
20261 strex, t_strex),
ff8646ee
TP
20262#undef THUMB_VARIANT
20263#define THUMB_VARIANT & arm_ext_v6t2
20264
21d799b5
NC
20265 TUF("mcrr2", c400000, fc400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
20266 TUF("mrrc2", c500000, fc500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
62b3e311 20267
21d799b5
NC
20268 TCE("ssat", 6a00010, f3000000, 4, (RRnpc, I32, RRnpc, oSHllar),ssat, t_ssat),
20269 TCE("usat", 6e00010, f3800000, 4, (RRnpc, I31, RRnpc, oSHllar),usat, t_usat),
62b3e311 20270
9e3c6df6 20271/* ARM V6 not included in V7M. */
c921be7d
NC
20272#undef THUMB_VARIANT
20273#define THUMB_VARIANT & arm_ext_v6_notm
9e3c6df6 20274 TUF("rfeia", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6 20275 TUF("rfe", 8900a00, e990c000, 1, (RRw), rfe, rfe),
9e3c6df6
PB
20276 UF(rfeib, 9900a00, 1, (RRw), rfe),
20277 UF(rfeda, 8100a00, 1, (RRw), rfe),
20278 TUF("rfedb", 9100a00, e810c000, 1, (RRw), rfe, rfe),
20279 TUF("rfefd", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6
RE
20280 UF(rfefa, 8100a00, 1, (RRw), rfe),
20281 TUF("rfeea", 9100a00, e810c000, 1, (RRw), rfe, rfe),
20282 UF(rfeed, 9900a00, 1, (RRw), rfe),
9e3c6df6 20283 TUF("srsia", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
d709e4e6
RE
20284 TUF("srs", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
20285 TUF("srsea", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
9e3c6df6 20286 UF(srsib, 9c00500, 2, (oRRw, I31w), srs),
d709e4e6 20287 UF(srsfa, 9c00500, 2, (oRRw, I31w), srs),
9e3c6df6 20288 UF(srsda, 8400500, 2, (oRRw, I31w), srs),
d709e4e6 20289 UF(srsed, 8400500, 2, (oRRw, I31w), srs),
9e3c6df6 20290 TUF("srsdb", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
d709e4e6 20291 TUF("srsfd", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
941c9cad 20292 TUF("cps", 1020000, f3af8100, 1, (I31b), imm0, t_cps),
c921be7d 20293
9e3c6df6
PB
20294/* ARM V6 not included in V7M (eg. integer SIMD). */
20295#undef THUMB_VARIANT
20296#define THUMB_VARIANT & arm_ext_v6_dsp
21d799b5
NC
20297 TCE("pkhbt", 6800010, eac00000, 4, (RRnpc, RRnpc, RRnpc, oSHll), pkhbt, t_pkhbt),
20298 TCE("pkhtb", 6800050, eac00020, 4, (RRnpc, RRnpc, RRnpc, oSHar), pkhtb, t_pkhtb),
20299 TCE("qadd16", 6200f10, fa90f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20300 TCE("qadd8", 6200f90, fa80f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20301 TCE("qasx", 6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20302 /* Old name for QASX. */
74db7efb 20303 TCE("qaddsubx",6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 20304 TCE("qsax", 6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20305 /* Old name for QSAX. */
74db7efb 20306 TCE("qsubaddx",6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
20307 TCE("qsub16", 6200f70, fad0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20308 TCE("qsub8", 6200ff0, fac0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20309 TCE("sadd16", 6100f10, fa90f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20310 TCE("sadd8", 6100f90, fa80f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20311 TCE("sasx", 6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20312 /* Old name for SASX. */
74db7efb 20313 TCE("saddsubx",6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
20314 TCE("shadd16", 6300f10, fa90f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20315 TCE("shadd8", 6300f90, fa80f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 20316 TCE("shasx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20317 /* Old name for SHASX. */
21d799b5 20318 TCE("shaddsubx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 20319 TCE("shsax", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20320 /* Old name for SHSAX. */
21d799b5
NC
20321 TCE("shsubaddx", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20322 TCE("shsub16", 6300f70, fad0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20323 TCE("shsub8", 6300ff0, fac0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20324 TCE("ssax", 6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20325 /* Old name for SSAX. */
74db7efb 20326 TCE("ssubaddx",6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
20327 TCE("ssub16", 6100f70, fad0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20328 TCE("ssub8", 6100ff0, fac0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20329 TCE("uadd16", 6500f10, fa90f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20330 TCE("uadd8", 6500f90, fa80f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20331 TCE("uasx", 6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20332 /* Old name for UASX. */
74db7efb 20333 TCE("uaddsubx",6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
20334 TCE("uhadd16", 6700f10, fa90f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20335 TCE("uhadd8", 6700f90, fa80f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 20336 TCE("uhasx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20337 /* Old name for UHASX. */
21d799b5
NC
20338 TCE("uhaddsubx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20339 TCE("uhsax", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20340 /* Old name for UHSAX. */
21d799b5
NC
20341 TCE("uhsubaddx", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20342 TCE("uhsub16", 6700f70, fad0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20343 TCE("uhsub8", 6700ff0, fac0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20344 TCE("uqadd16", 6600f10, fa90f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20345 TCE("uqadd8", 6600f90, fa80f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 20346 TCE("uqasx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20347 /* Old name for UQASX. */
21d799b5
NC
20348 TCE("uqaddsubx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20349 TCE("uqsax", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20350 /* Old name for UQSAX. */
21d799b5
NC
20351 TCE("uqsubaddx", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20352 TCE("uqsub16", 6600f70, fad0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20353 TCE("uqsub8", 6600ff0, fac0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20354 TCE("usub16", 6500f70, fad0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20355 TCE("usax", 6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20356 /* Old name for USAX. */
74db7efb 20357 TCE("usubaddx",6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 20358 TCE("usub8", 6500ff0, fac0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
20359 TCE("sxtah", 6b00070, fa00f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
20360 TCE("sxtab16", 6800070, fa20f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
20361 TCE("sxtab", 6a00070, fa40f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
20362 TCE("sxtb16", 68f0070, fa2ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
20363 TCE("uxtah", 6f00070, fa10f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
20364 TCE("uxtab16", 6c00070, fa30f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
20365 TCE("uxtab", 6e00070, fa50f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
20366 TCE("uxtb16", 6cf0070, fa3ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
20367 TCE("sel", 6800fb0, faa0f080, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20368 TCE("smlad", 7000010, fb200000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20369 TCE("smladx", 7000030, fb200010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20370 TCE("smlald", 7400010, fbc000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
20371 TCE("smlaldx", 7400030, fbc000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
20372 TCE("smlsd", 7000050, fb400000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20373 TCE("smlsdx", 7000070, fb400010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20374 TCE("smlsld", 7400050, fbd000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
20375 TCE("smlsldx", 7400070, fbd000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
20376 TCE("smmla", 7500010, fb500000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20377 TCE("smmlar", 7500030, fb500010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20378 TCE("smmls", 75000d0, fb600000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20379 TCE("smmlsr", 75000f0, fb600010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20380 TCE("smmul", 750f010, fb50f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20381 TCE("smmulr", 750f030, fb50f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20382 TCE("smuad", 700f010, fb20f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20383 TCE("smuadx", 700f030, fb20f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20384 TCE("smusd", 700f050, fb40f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20385 TCE("smusdx", 700f070, fb40f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
21d799b5
NC
20386 TCE("ssat16", 6a00f30, f3200000, 3, (RRnpc, I16, RRnpc), ssat16, t_ssat16),
20387 TCE("umaal", 0400090, fbe00060, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal, t_mlal),
20388 TCE("usad8", 780f010, fb70f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20389 TCE("usada8", 7800010, fb700000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20390 TCE("usat16", 6e00f30, f3a00000, 3, (RRnpc, I15, RRnpc), usat16, t_usat16),
c19d1205 20391
c921be7d 20392#undef ARM_VARIANT
55e8aae7 20393#define ARM_VARIANT & arm_ext_v6k_v6t2
c921be7d 20394#undef THUMB_VARIANT
55e8aae7 20395#define THUMB_VARIANT & arm_ext_v6k_v6t2
c921be7d 20396
21d799b5
NC
20397 tCE("yield", 320f001, _yield, 0, (), noargs, t_hint),
20398 tCE("wfe", 320f002, _wfe, 0, (), noargs, t_hint),
20399 tCE("wfi", 320f003, _wfi, 0, (), noargs, t_hint),
20400 tCE("sev", 320f004, _sev, 0, (), noargs, t_hint),
c19d1205 20401
c921be7d
NC
20402#undef THUMB_VARIANT
20403#define THUMB_VARIANT & arm_ext_v6_notm
5be8be5d
DG
20404 TCE("ldrexd", 1b00f9f, e8d0007f, 3, (RRnpc_npcsp, oRRnpc_npcsp, RRnpcb),
20405 ldrexd, t_ldrexd),
20406 TCE("strexd", 1a00f90, e8c00070, 4, (RRnpc_npcsp, RRnpc_npcsp, oRRnpc_npcsp,
20407 RRnpcb), strexd, t_strexd),
ebdca51a 20408
c921be7d 20409#undef THUMB_VARIANT
ff8646ee 20410#define THUMB_VARIANT & arm_ext_v6t2_v8m
5be8be5d
DG
20411 TCE("ldrexb", 1d00f9f, e8d00f4f, 2, (RRnpc_npcsp,RRnpcb),
20412 rd_rn, rd_rn),
20413 TCE("ldrexh", 1f00f9f, e8d00f5f, 2, (RRnpc_npcsp, RRnpcb),
20414 rd_rn, rd_rn),
20415 TCE("strexb", 1c00f90, e8c00f40, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 20416 strex, t_strexbh),
5be8be5d 20417 TCE("strexh", 1e00f90, e8c00f50, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 20418 strex, t_strexbh),
21d799b5 20419 TUF("clrex", 57ff01f, f3bf8f2f, 0, (), noargs, noargs),
c19d1205 20420
c921be7d 20421#undef ARM_VARIANT
f4c65163 20422#define ARM_VARIANT & arm_ext_sec
74db7efb 20423#undef THUMB_VARIANT
f4c65163 20424#define THUMB_VARIANT & arm_ext_sec
c921be7d 20425
21d799b5 20426 TCE("smc", 1600070, f7f08000, 1, (EXPi), smc, t_smc),
c19d1205 20427
90ec0d68
MGD
20428#undef ARM_VARIANT
20429#define ARM_VARIANT & arm_ext_virt
20430#undef THUMB_VARIANT
20431#define THUMB_VARIANT & arm_ext_virt
20432
20433 TCE("hvc", 1400070, f7e08000, 1, (EXPi), hvc, t_hvc),
20434 TCE("eret", 160006e, f3de8f00, 0, (), noargs, noargs),
20435
ddfded2f
MW
20436#undef ARM_VARIANT
20437#define ARM_VARIANT & arm_ext_pan
20438#undef THUMB_VARIANT
20439#define THUMB_VARIANT & arm_ext_pan
20440
20441 TUF("setpan", 1100000, b610, 1, (I7), setpan, t_setpan),
20442
c921be7d 20443#undef ARM_VARIANT
74db7efb 20444#define ARM_VARIANT & arm_ext_v6t2
f4c65163
MGD
20445#undef THUMB_VARIANT
20446#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 20447
21d799b5
NC
20448 TCE("bfc", 7c0001f, f36f0000, 3, (RRnpc, I31, I32), bfc, t_bfc),
20449 TCE("bfi", 7c00010, f3600000, 4, (RRnpc, RRnpc_I0, I31, I32), bfi, t_bfi),
20450 TCE("sbfx", 7a00050, f3400000, 4, (RR, RR, I31, I32), bfx, t_bfx),
20451 TCE("ubfx", 7e00050, f3c00000, 4, (RR, RR, I31, I32), bfx, t_bfx),
c19d1205 20452
21d799b5 20453 TCE("mls", 0600090, fb000010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
21d799b5 20454 TCE("rbit", 6ff0f30, fa90f0a0, 2, (RR, RR), rd_rm, t_rbit),
c19d1205 20455
5be8be5d
DG
20456 TC3("ldrht", 03000b0, f8300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
20457 TC3("ldrsht", 03000f0, f9300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
20458 TC3("ldrsbt", 03000d0, f9100e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
20459 TC3("strht", 02000b0, f8200e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
c19d1205 20460
91d8b670
JG
20461#undef ARM_VARIANT
20462#define ARM_VARIANT & arm_ext_v3
20463#undef THUMB_VARIANT
20464#define THUMB_VARIANT & arm_ext_v6t2
20465
20466 TUE("csdb", 320f014, f3af8014, 0, (), noargs, t_csdb),
c597cc3d
SD
20467 TUF("ssbb", 57ff040, f3bf8f40, 0, (), noargs, t_csdb),
20468 TUF("pssbb", 57ff044, f3bf8f44, 0, (), noargs, t_csdb),
91d8b670
JG
20469
20470#undef ARM_VARIANT
20471#define ARM_VARIANT & arm_ext_v6t2
ff8646ee
TP
20472#undef THUMB_VARIANT
20473#define THUMB_VARIANT & arm_ext_v6t2_v8m
20474 TCE("movw", 3000000, f2400000, 2, (RRnpc, HALF), mov16, t_mov16),
20475 TCE("movt", 3400000, f2c00000, 2, (RRnpc, HALF), mov16, t_mov16),
20476
bf3eeda7 20477 /* Thumb-only instructions. */
74db7efb 20478#undef ARM_VARIANT
bf3eeda7
NS
20479#define ARM_VARIANT NULL
20480 TUE("cbnz", 0, b900, 2, (RR, EXP), 0, t_cbz),
20481 TUE("cbz", 0, b100, 2, (RR, EXP), 0, t_cbz),
c921be7d
NC
20482
20483 /* ARM does not really have an IT instruction, so always allow it.
20484 The opcode is copied from Thumb in order to allow warnings in
20485 -mimplicit-it=[never | arm] modes. */
20486#undef ARM_VARIANT
20487#define ARM_VARIANT & arm_ext_v1
ff8646ee
TP
20488#undef THUMB_VARIANT
20489#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 20490
21d799b5
NC
20491 TUE("it", bf08, bf08, 1, (COND), it, t_it),
20492 TUE("itt", bf0c, bf0c, 1, (COND), it, t_it),
20493 TUE("ite", bf04, bf04, 1, (COND), it, t_it),
20494 TUE("ittt", bf0e, bf0e, 1, (COND), it, t_it),
20495 TUE("itet", bf06, bf06, 1, (COND), it, t_it),
20496 TUE("itte", bf0a, bf0a, 1, (COND), it, t_it),
20497 TUE("itee", bf02, bf02, 1, (COND), it, t_it),
20498 TUE("itttt", bf0f, bf0f, 1, (COND), it, t_it),
20499 TUE("itett", bf07, bf07, 1, (COND), it, t_it),
20500 TUE("ittet", bf0b, bf0b, 1, (COND), it, t_it),
20501 TUE("iteet", bf03, bf03, 1, (COND), it, t_it),
20502 TUE("ittte", bf0d, bf0d, 1, (COND), it, t_it),
20503 TUE("itete", bf05, bf05, 1, (COND), it, t_it),
20504 TUE("ittee", bf09, bf09, 1, (COND), it, t_it),
20505 TUE("iteee", bf01, bf01, 1, (COND), it, t_it),
1c444d06 20506 /* ARM/Thumb-2 instructions with no Thumb-1 equivalent. */
21d799b5
NC
20507 TC3("rrx", 01a00060, ea4f0030, 2, (RR, RR), rd_rm, t_rrx),
20508 TC3("rrxs", 01b00060, ea5f0030, 2, (RR, RR), rd_rm, t_rrx),
c19d1205 20509
92e90b6e 20510 /* Thumb2 only instructions. */
c921be7d
NC
20511#undef ARM_VARIANT
20512#define ARM_VARIANT NULL
92e90b6e 20513
21d799b5
NC
20514 TCE("addw", 0, f2000000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
20515 TCE("subw", 0, f2a00000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
20516 TCE("orn", 0, ea600000, 3, (RR, oRR, SH), 0, t_orn),
20517 TCE("orns", 0, ea700000, 3, (RR, oRR, SH), 0, t_orn),
20518 TCE("tbb", 0, e8d0f000, 1, (TB), 0, t_tb),
20519 TCE("tbh", 0, e8d0f010, 1, (TB), 0, t_tb),
92e90b6e 20520
eea54501
MGD
20521 /* Hardware division instructions. */
20522#undef ARM_VARIANT
20523#define ARM_VARIANT & arm_ext_adiv
c921be7d
NC
20524#undef THUMB_VARIANT
20525#define THUMB_VARIANT & arm_ext_div
20526
eea54501
MGD
20527 TCE("sdiv", 710f010, fb90f0f0, 3, (RR, oRR, RR), div, t_div),
20528 TCE("udiv", 730f010, fbb0f0f0, 3, (RR, oRR, RR), div, t_div),
62b3e311 20529
7e806470 20530 /* ARM V6M/V7 instructions. */
c921be7d
NC
20531#undef ARM_VARIANT
20532#define ARM_VARIANT & arm_ext_barrier
20533#undef THUMB_VARIANT
20534#define THUMB_VARIANT & arm_ext_barrier
20535
ccb84d65
JB
20536 TUF("dmb", 57ff050, f3bf8f50, 1, (oBARRIER_I15), barrier, barrier),
20537 TUF("dsb", 57ff040, f3bf8f40, 1, (oBARRIER_I15), barrier, barrier),
20538 TUF("isb", 57ff060, f3bf8f60, 1, (oBARRIER_I15), barrier, barrier),
7e806470 20539
62b3e311 20540 /* ARM V7 instructions. */
c921be7d
NC
20541#undef ARM_VARIANT
20542#define ARM_VARIANT & arm_ext_v7
20543#undef THUMB_VARIANT
20544#define THUMB_VARIANT & arm_ext_v7
20545
21d799b5
NC
20546 TUF("pli", 450f000, f910f000, 1, (ADDR), pli, t_pld),
20547 TCE("dbg", 320f0f0, f3af80f0, 1, (I15), dbg, t_dbg),
62b3e311 20548
74db7efb 20549#undef ARM_VARIANT
60e5ef9f 20550#define ARM_VARIANT & arm_ext_mp
74db7efb 20551#undef THUMB_VARIANT
60e5ef9f
MGD
20552#define THUMB_VARIANT & arm_ext_mp
20553
20554 TUF("pldw", 410f000, f830f000, 1, (ADDR), pld, t_pld),
20555
53c4b28b
MGD
20556 /* AArchv8 instructions. */
20557#undef ARM_VARIANT
20558#define ARM_VARIANT & arm_ext_v8
4ed7ed8d
TP
20559
20560/* Instructions shared between armv8-a and armv8-m. */
53c4b28b 20561#undef THUMB_VARIANT
4ed7ed8d 20562#define THUMB_VARIANT & arm_ext_atomics
53c4b28b 20563
4ed7ed8d
TP
20564 TCE("lda", 1900c9f, e8d00faf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
20565 TCE("ldab", 1d00c9f, e8d00f8f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
20566 TCE("ldah", 1f00c9f, e8d00f9f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
20567 TCE("stl", 180fc90, e8c00faf, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
20568 TCE("stlb", 1c0fc90, e8c00f8f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
20569 TCE("stlh", 1e0fc90, e8c00f9f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
4b8c8c02 20570 TCE("ldaex", 1900e9f, e8d00fef, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
4b8c8c02
RE
20571 TCE("ldaexb", 1d00e9f, e8d00fcf, 2, (RRnpc,RRnpcb), rd_rn, rd_rn),
20572 TCE("ldaexh", 1f00e9f, e8d00fdf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
20573 TCE("stlex", 1800e90, e8c00fe0, 3, (RRnpc, RRnpc, RRnpcb),
20574 stlex, t_stlex),
4b8c8c02
RE
20575 TCE("stlexb", 1c00e90, e8c00fc0, 3, (RRnpc, RRnpc, RRnpcb),
20576 stlex, t_stlex),
20577 TCE("stlexh", 1e00e90, e8c00fd0, 3, (RRnpc, RRnpc, RRnpcb),
20578 stlex, t_stlex),
4ed7ed8d
TP
20579#undef THUMB_VARIANT
20580#define THUMB_VARIANT & arm_ext_v8
53c4b28b 20581
4ed7ed8d 20582 tCE("sevl", 320f005, _sevl, 0, (), noargs, t_hint),
4ed7ed8d
TP
20583 TCE("ldaexd", 1b00e9f, e8d000ff, 3, (RRnpc, oRRnpc, RRnpcb),
20584 ldrexd, t_ldrexd),
20585 TCE("stlexd", 1a00e90, e8c000f0, 4, (RRnpc, RRnpc, oRRnpc, RRnpcb),
20586 strexd, t_strexd),
f7dd2fb2
TC
20587
20588/* Defined in V8 but is in undefined encoding space for earlier
20589 architectures. However earlier architectures are required to treat
20590 this instuction as a semihosting trap as well. Hence while not explicitly
20591 defined as such, it is in fact correct to define the instruction for all
20592 architectures. */
20593#undef THUMB_VARIANT
20594#define THUMB_VARIANT & arm_ext_v1
20595#undef ARM_VARIANT
20596#define ARM_VARIANT & arm_ext_v1
20597 TUE("hlt", 1000070, ba80, 1, (oIffffb), bkpt, t_hlt),
20598
8884b720 20599 /* ARMv8 T32 only. */
74db7efb 20600#undef ARM_VARIANT
b79f7053
MGD
20601#define ARM_VARIANT NULL
20602 TUF("dcps1", 0, f78f8001, 0, (), noargs, noargs),
20603 TUF("dcps2", 0, f78f8002, 0, (), noargs, noargs),
20604 TUF("dcps3", 0, f78f8003, 0, (), noargs, noargs),
20605
33399f07
MGD
20606 /* FP for ARMv8. */
20607#undef ARM_VARIANT
a715796b 20608#define ARM_VARIANT & fpu_vfp_ext_armv8xd
33399f07 20609#undef THUMB_VARIANT
a715796b 20610#define THUMB_VARIANT & fpu_vfp_ext_armv8xd
33399f07
MGD
20611
20612 nUF(vseleq, _vseleq, 3, (RVSD, RVSD, RVSD), vsel),
20613 nUF(vselvs, _vselvs, 3, (RVSD, RVSD, RVSD), vsel),
20614 nUF(vselge, _vselge, 3, (RVSD, RVSD, RVSD), vsel),
20615 nUF(vselgt, _vselgt, 3, (RVSD, RVSD, RVSD), vsel),
73924fbc
MGD
20616 nUF(vmaxnm, _vmaxnm, 3, (RNSDQ, oRNSDQ, RNSDQ), vmaxnm),
20617 nUF(vminnm, _vminnm, 3, (RNSDQ, oRNSDQ, RNSDQ), vmaxnm),
7e8e6784
MGD
20618 nUF(vcvta, _vcvta, 2, (RNSDQ, oRNSDQ), neon_cvta),
20619 nUF(vcvtn, _vcvta, 2, (RNSDQ, oRNSDQ), neon_cvtn),
20620 nUF(vcvtp, _vcvta, 2, (RNSDQ, oRNSDQ), neon_cvtp),
20621 nUF(vcvtm, _vcvta, 2, (RNSDQ, oRNSDQ), neon_cvtm),
30bdf752
MGD
20622 nCE(vrintr, _vrintr, 2, (RNSDQ, oRNSDQ), vrintr),
20623 nCE(vrintz, _vrintr, 2, (RNSDQ, oRNSDQ), vrintz),
20624 nCE(vrintx, _vrintr, 2, (RNSDQ, oRNSDQ), vrintx),
20625 nUF(vrinta, _vrinta, 2, (RNSDQ, oRNSDQ), vrinta),
20626 nUF(vrintn, _vrinta, 2, (RNSDQ, oRNSDQ), vrintn),
20627 nUF(vrintp, _vrinta, 2, (RNSDQ, oRNSDQ), vrintp),
20628 nUF(vrintm, _vrinta, 2, (RNSDQ, oRNSDQ), vrintm),
33399f07 20629
91ff7894
MGD
20630 /* Crypto v1 extensions. */
20631#undef ARM_VARIANT
20632#define ARM_VARIANT & fpu_crypto_ext_armv8
20633#undef THUMB_VARIANT
20634#define THUMB_VARIANT & fpu_crypto_ext_armv8
20635
20636 nUF(aese, _aes, 2, (RNQ, RNQ), aese),
20637 nUF(aesd, _aes, 2, (RNQ, RNQ), aesd),
20638 nUF(aesmc, _aes, 2, (RNQ, RNQ), aesmc),
20639 nUF(aesimc, _aes, 2, (RNQ, RNQ), aesimc),
48adcd8e
MGD
20640 nUF(sha1c, _sha3op, 3, (RNQ, RNQ, RNQ), sha1c),
20641 nUF(sha1p, _sha3op, 3, (RNQ, RNQ, RNQ), sha1p),
20642 nUF(sha1m, _sha3op, 3, (RNQ, RNQ, RNQ), sha1m),
20643 nUF(sha1su0, _sha3op, 3, (RNQ, RNQ, RNQ), sha1su0),
20644 nUF(sha256h, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h),
20645 nUF(sha256h2, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h2),
20646 nUF(sha256su1, _sha3op, 3, (RNQ, RNQ, RNQ), sha256su1),
3c9017d2
MGD
20647 nUF(sha1h, _sha1h, 2, (RNQ, RNQ), sha1h),
20648 nUF(sha1su1, _sha2op, 2, (RNQ, RNQ), sha1su1),
20649 nUF(sha256su0, _sha2op, 2, (RNQ, RNQ), sha256su0),
91ff7894 20650
dd5181d5 20651#undef ARM_VARIANT
74db7efb 20652#define ARM_VARIANT & crc_ext_armv8
dd5181d5
KT
20653#undef THUMB_VARIANT
20654#define THUMB_VARIANT & crc_ext_armv8
20655 TUEc("crc32b", 1000040, fac0f080, 3, (RR, oRR, RR), crc32b),
20656 TUEc("crc32h", 1200040, fac0f090, 3, (RR, oRR, RR), crc32h),
20657 TUEc("crc32w", 1400040, fac0f0a0, 3, (RR, oRR, RR), crc32w),
20658 TUEc("crc32cb",1000240, fad0f080, 3, (RR, oRR, RR), crc32cb),
20659 TUEc("crc32ch",1200240, fad0f090, 3, (RR, oRR, RR), crc32ch),
20660 TUEc("crc32cw",1400240, fad0f0a0, 3, (RR, oRR, RR), crc32cw),
20661
105bde57
MW
20662 /* ARMv8.2 RAS extension. */
20663#undef ARM_VARIANT
4d1464f2 20664#define ARM_VARIANT & arm_ext_ras
105bde57 20665#undef THUMB_VARIANT
4d1464f2 20666#define THUMB_VARIANT & arm_ext_ras
105bde57
MW
20667 TUE ("esb", 320f010, f3af8010, 0, (), noargs, noargs),
20668
49e8a725
SN
20669#undef ARM_VARIANT
20670#define ARM_VARIANT & arm_ext_v8_3
20671#undef THUMB_VARIANT
20672#define THUMB_VARIANT & arm_ext_v8_3
20673 NCE (vjcvt, eb90bc0, 2, (RVS, RVD), vjcvt),
c28eeff2
SN
20674 NUF (vcmla, 0, 4, (RNDQ, RNDQ, RNDQ_RNSC, EXPi), vcmla),
20675 NUF (vcadd, 0, 4, (RNDQ, RNDQ, RNDQ, EXPi), vcadd),
49e8a725 20676
c604a79a
JW
20677#undef ARM_VARIANT
20678#define ARM_VARIANT & fpu_neon_ext_dotprod
20679#undef THUMB_VARIANT
20680#define THUMB_VARIANT & fpu_neon_ext_dotprod
20681 NUF (vsdot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_s),
20682 NUF (vudot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_u),
20683
c921be7d
NC
20684#undef ARM_VARIANT
20685#define ARM_VARIANT & fpu_fpa_ext_v1 /* Core FPA instruction set (V1). */
53c4b28b
MGD
20686#undef THUMB_VARIANT
20687#define THUMB_VARIANT NULL
c921be7d 20688
21d799b5
NC
20689 cCE("wfs", e200110, 1, (RR), rd),
20690 cCE("rfs", e300110, 1, (RR), rd),
20691 cCE("wfc", e400110, 1, (RR), rd),
20692 cCE("rfc", e500110, 1, (RR), rd),
20693
20694 cCL("ldfs", c100100, 2, (RF, ADDRGLDC), rd_cpaddr),
20695 cCL("ldfd", c108100, 2, (RF, ADDRGLDC), rd_cpaddr),
20696 cCL("ldfe", c500100, 2, (RF, ADDRGLDC), rd_cpaddr),
20697 cCL("ldfp", c508100, 2, (RF, ADDRGLDC), rd_cpaddr),
20698
20699 cCL("stfs", c000100, 2, (RF, ADDRGLDC), rd_cpaddr),
20700 cCL("stfd", c008100, 2, (RF, ADDRGLDC), rd_cpaddr),
20701 cCL("stfe", c400100, 2, (RF, ADDRGLDC), rd_cpaddr),
20702 cCL("stfp", c408100, 2, (RF, ADDRGLDC), rd_cpaddr),
20703
20704 cCL("mvfs", e008100, 2, (RF, RF_IF), rd_rm),
20705 cCL("mvfsp", e008120, 2, (RF, RF_IF), rd_rm),
20706 cCL("mvfsm", e008140, 2, (RF, RF_IF), rd_rm),
20707 cCL("mvfsz", e008160, 2, (RF, RF_IF), rd_rm),
20708 cCL("mvfd", e008180, 2, (RF, RF_IF), rd_rm),
20709 cCL("mvfdp", e0081a0, 2, (RF, RF_IF), rd_rm),
20710 cCL("mvfdm", e0081c0, 2, (RF, RF_IF), rd_rm),
20711 cCL("mvfdz", e0081e0, 2, (RF, RF_IF), rd_rm),
20712 cCL("mvfe", e088100, 2, (RF, RF_IF), rd_rm),
20713 cCL("mvfep", e088120, 2, (RF, RF_IF), rd_rm),
20714 cCL("mvfem", e088140, 2, (RF, RF_IF), rd_rm),
20715 cCL("mvfez", e088160, 2, (RF, RF_IF), rd_rm),
20716
20717 cCL("mnfs", e108100, 2, (RF, RF_IF), rd_rm),
20718 cCL("mnfsp", e108120, 2, (RF, RF_IF), rd_rm),
20719 cCL("mnfsm", e108140, 2, (RF, RF_IF), rd_rm),
20720 cCL("mnfsz", e108160, 2, (RF, RF_IF), rd_rm),
20721 cCL("mnfd", e108180, 2, (RF, RF_IF), rd_rm),
20722 cCL("mnfdp", e1081a0, 2, (RF, RF_IF), rd_rm),
20723 cCL("mnfdm", e1081c0, 2, (RF, RF_IF), rd_rm),
20724 cCL("mnfdz", e1081e0, 2, (RF, RF_IF), rd_rm),
20725 cCL("mnfe", e188100, 2, (RF, RF_IF), rd_rm),
20726 cCL("mnfep", e188120, 2, (RF, RF_IF), rd_rm),
20727 cCL("mnfem", e188140, 2, (RF, RF_IF), rd_rm),
20728 cCL("mnfez", e188160, 2, (RF, RF_IF), rd_rm),
20729
20730 cCL("abss", e208100, 2, (RF, RF_IF), rd_rm),
20731 cCL("abssp", e208120, 2, (RF, RF_IF), rd_rm),
20732 cCL("abssm", e208140, 2, (RF, RF_IF), rd_rm),
20733 cCL("abssz", e208160, 2, (RF, RF_IF), rd_rm),
20734 cCL("absd", e208180, 2, (RF, RF_IF), rd_rm),
20735 cCL("absdp", e2081a0, 2, (RF, RF_IF), rd_rm),
20736 cCL("absdm", e2081c0, 2, (RF, RF_IF), rd_rm),
20737 cCL("absdz", e2081e0, 2, (RF, RF_IF), rd_rm),
20738 cCL("abse", e288100, 2, (RF, RF_IF), rd_rm),
20739 cCL("absep", e288120, 2, (RF, RF_IF), rd_rm),
20740 cCL("absem", e288140, 2, (RF, RF_IF), rd_rm),
20741 cCL("absez", e288160, 2, (RF, RF_IF), rd_rm),
20742
20743 cCL("rnds", e308100, 2, (RF, RF_IF), rd_rm),
20744 cCL("rndsp", e308120, 2, (RF, RF_IF), rd_rm),
20745 cCL("rndsm", e308140, 2, (RF, RF_IF), rd_rm),
20746 cCL("rndsz", e308160, 2, (RF, RF_IF), rd_rm),
20747 cCL("rndd", e308180, 2, (RF, RF_IF), rd_rm),
20748 cCL("rnddp", e3081a0, 2, (RF, RF_IF), rd_rm),
20749 cCL("rnddm", e3081c0, 2, (RF, RF_IF), rd_rm),
20750 cCL("rnddz", e3081e0, 2, (RF, RF_IF), rd_rm),
20751 cCL("rnde", e388100, 2, (RF, RF_IF), rd_rm),
20752 cCL("rndep", e388120, 2, (RF, RF_IF), rd_rm),
20753 cCL("rndem", e388140, 2, (RF, RF_IF), rd_rm),
20754 cCL("rndez", e388160, 2, (RF, RF_IF), rd_rm),
20755
20756 cCL("sqts", e408100, 2, (RF, RF_IF), rd_rm),
20757 cCL("sqtsp", e408120, 2, (RF, RF_IF), rd_rm),
20758 cCL("sqtsm", e408140, 2, (RF, RF_IF), rd_rm),
20759 cCL("sqtsz", e408160, 2, (RF, RF_IF), rd_rm),
20760 cCL("sqtd", e408180, 2, (RF, RF_IF), rd_rm),
20761 cCL("sqtdp", e4081a0, 2, (RF, RF_IF), rd_rm),
20762 cCL("sqtdm", e4081c0, 2, (RF, RF_IF), rd_rm),
20763 cCL("sqtdz", e4081e0, 2, (RF, RF_IF), rd_rm),
20764 cCL("sqte", e488100, 2, (RF, RF_IF), rd_rm),
20765 cCL("sqtep", e488120, 2, (RF, RF_IF), rd_rm),
20766 cCL("sqtem", e488140, 2, (RF, RF_IF), rd_rm),
20767 cCL("sqtez", e488160, 2, (RF, RF_IF), rd_rm),
20768
20769 cCL("logs", e508100, 2, (RF, RF_IF), rd_rm),
20770 cCL("logsp", e508120, 2, (RF, RF_IF), rd_rm),
20771 cCL("logsm", e508140, 2, (RF, RF_IF), rd_rm),
20772 cCL("logsz", e508160, 2, (RF, RF_IF), rd_rm),
20773 cCL("logd", e508180, 2, (RF, RF_IF), rd_rm),
20774 cCL("logdp", e5081a0, 2, (RF, RF_IF), rd_rm),
20775 cCL("logdm", e5081c0, 2, (RF, RF_IF), rd_rm),
20776 cCL("logdz", e5081e0, 2, (RF, RF_IF), rd_rm),
20777 cCL("loge", e588100, 2, (RF, RF_IF), rd_rm),
20778 cCL("logep", e588120, 2, (RF, RF_IF), rd_rm),
20779 cCL("logem", e588140, 2, (RF, RF_IF), rd_rm),
20780 cCL("logez", e588160, 2, (RF, RF_IF), rd_rm),
20781
20782 cCL("lgns", e608100, 2, (RF, RF_IF), rd_rm),
20783 cCL("lgnsp", e608120, 2, (RF, RF_IF), rd_rm),
20784 cCL("lgnsm", e608140, 2, (RF, RF_IF), rd_rm),
20785 cCL("lgnsz", e608160, 2, (RF, RF_IF), rd_rm),
20786 cCL("lgnd", e608180, 2, (RF, RF_IF), rd_rm),
20787 cCL("lgndp", e6081a0, 2, (RF, RF_IF), rd_rm),
20788 cCL("lgndm", e6081c0, 2, (RF, RF_IF), rd_rm),
20789 cCL("lgndz", e6081e0, 2, (RF, RF_IF), rd_rm),
20790 cCL("lgne", e688100, 2, (RF, RF_IF), rd_rm),
20791 cCL("lgnep", e688120, 2, (RF, RF_IF), rd_rm),
20792 cCL("lgnem", e688140, 2, (RF, RF_IF), rd_rm),
20793 cCL("lgnez", e688160, 2, (RF, RF_IF), rd_rm),
20794
20795 cCL("exps", e708100, 2, (RF, RF_IF), rd_rm),
20796 cCL("expsp", e708120, 2, (RF, RF_IF), rd_rm),
20797 cCL("expsm", e708140, 2, (RF, RF_IF), rd_rm),
20798 cCL("expsz", e708160, 2, (RF, RF_IF), rd_rm),
20799 cCL("expd", e708180, 2, (RF, RF_IF), rd_rm),
20800 cCL("expdp", e7081a0, 2, (RF, RF_IF), rd_rm),
20801 cCL("expdm", e7081c0, 2, (RF, RF_IF), rd_rm),
20802 cCL("expdz", e7081e0, 2, (RF, RF_IF), rd_rm),
20803 cCL("expe", e788100, 2, (RF, RF_IF), rd_rm),
20804 cCL("expep", e788120, 2, (RF, RF_IF), rd_rm),
20805 cCL("expem", e788140, 2, (RF, RF_IF), rd_rm),
20806 cCL("expdz", e788160, 2, (RF, RF_IF), rd_rm),
20807
20808 cCL("sins", e808100, 2, (RF, RF_IF), rd_rm),
20809 cCL("sinsp", e808120, 2, (RF, RF_IF), rd_rm),
20810 cCL("sinsm", e808140, 2, (RF, RF_IF), rd_rm),
20811 cCL("sinsz", e808160, 2, (RF, RF_IF), rd_rm),
20812 cCL("sind", e808180, 2, (RF, RF_IF), rd_rm),
20813 cCL("sindp", e8081a0, 2, (RF, RF_IF), rd_rm),
20814 cCL("sindm", e8081c0, 2, (RF, RF_IF), rd_rm),
20815 cCL("sindz", e8081e0, 2, (RF, RF_IF), rd_rm),
20816 cCL("sine", e888100, 2, (RF, RF_IF), rd_rm),
20817 cCL("sinep", e888120, 2, (RF, RF_IF), rd_rm),
20818 cCL("sinem", e888140, 2, (RF, RF_IF), rd_rm),
20819 cCL("sinez", e888160, 2, (RF, RF_IF), rd_rm),
20820
20821 cCL("coss", e908100, 2, (RF, RF_IF), rd_rm),
20822 cCL("cossp", e908120, 2, (RF, RF_IF), rd_rm),
20823 cCL("cossm", e908140, 2, (RF, RF_IF), rd_rm),
20824 cCL("cossz", e908160, 2, (RF, RF_IF), rd_rm),
20825 cCL("cosd", e908180, 2, (RF, RF_IF), rd_rm),
20826 cCL("cosdp", e9081a0, 2, (RF, RF_IF), rd_rm),
20827 cCL("cosdm", e9081c0, 2, (RF, RF_IF), rd_rm),
20828 cCL("cosdz", e9081e0, 2, (RF, RF_IF), rd_rm),
20829 cCL("cose", e988100, 2, (RF, RF_IF), rd_rm),
20830 cCL("cosep", e988120, 2, (RF, RF_IF), rd_rm),
20831 cCL("cosem", e988140, 2, (RF, RF_IF), rd_rm),
20832 cCL("cosez", e988160, 2, (RF, RF_IF), rd_rm),
20833
20834 cCL("tans", ea08100, 2, (RF, RF_IF), rd_rm),
20835 cCL("tansp", ea08120, 2, (RF, RF_IF), rd_rm),
20836 cCL("tansm", ea08140, 2, (RF, RF_IF), rd_rm),
20837 cCL("tansz", ea08160, 2, (RF, RF_IF), rd_rm),
20838 cCL("tand", ea08180, 2, (RF, RF_IF), rd_rm),
20839 cCL("tandp", ea081a0, 2, (RF, RF_IF), rd_rm),
20840 cCL("tandm", ea081c0, 2, (RF, RF_IF), rd_rm),
20841 cCL("tandz", ea081e0, 2, (RF, RF_IF), rd_rm),
20842 cCL("tane", ea88100, 2, (RF, RF_IF), rd_rm),
20843 cCL("tanep", ea88120, 2, (RF, RF_IF), rd_rm),
20844 cCL("tanem", ea88140, 2, (RF, RF_IF), rd_rm),
20845 cCL("tanez", ea88160, 2, (RF, RF_IF), rd_rm),
20846
20847 cCL("asns", eb08100, 2, (RF, RF_IF), rd_rm),
20848 cCL("asnsp", eb08120, 2, (RF, RF_IF), rd_rm),
20849 cCL("asnsm", eb08140, 2, (RF, RF_IF), rd_rm),
20850 cCL("asnsz", eb08160, 2, (RF, RF_IF), rd_rm),
20851 cCL("asnd", eb08180, 2, (RF, RF_IF), rd_rm),
20852 cCL("asndp", eb081a0, 2, (RF, RF_IF), rd_rm),
20853 cCL("asndm", eb081c0, 2, (RF, RF_IF), rd_rm),
20854 cCL("asndz", eb081e0, 2, (RF, RF_IF), rd_rm),
20855 cCL("asne", eb88100, 2, (RF, RF_IF), rd_rm),
20856 cCL("asnep", eb88120, 2, (RF, RF_IF), rd_rm),
20857 cCL("asnem", eb88140, 2, (RF, RF_IF), rd_rm),
20858 cCL("asnez", eb88160, 2, (RF, RF_IF), rd_rm),
20859
20860 cCL("acss", ec08100, 2, (RF, RF_IF), rd_rm),
20861 cCL("acssp", ec08120, 2, (RF, RF_IF), rd_rm),
20862 cCL("acssm", ec08140, 2, (RF, RF_IF), rd_rm),
20863 cCL("acssz", ec08160, 2, (RF, RF_IF), rd_rm),
20864 cCL("acsd", ec08180, 2, (RF, RF_IF), rd_rm),
20865 cCL("acsdp", ec081a0, 2, (RF, RF_IF), rd_rm),
20866 cCL("acsdm", ec081c0, 2, (RF, RF_IF), rd_rm),
20867 cCL("acsdz", ec081e0, 2, (RF, RF_IF), rd_rm),
20868 cCL("acse", ec88100, 2, (RF, RF_IF), rd_rm),
20869 cCL("acsep", ec88120, 2, (RF, RF_IF), rd_rm),
20870 cCL("acsem", ec88140, 2, (RF, RF_IF), rd_rm),
20871 cCL("acsez", ec88160, 2, (RF, RF_IF), rd_rm),
20872
20873 cCL("atns", ed08100, 2, (RF, RF_IF), rd_rm),
20874 cCL("atnsp", ed08120, 2, (RF, RF_IF), rd_rm),
20875 cCL("atnsm", ed08140, 2, (RF, RF_IF), rd_rm),
20876 cCL("atnsz", ed08160, 2, (RF, RF_IF), rd_rm),
20877 cCL("atnd", ed08180, 2, (RF, RF_IF), rd_rm),
20878 cCL("atndp", ed081a0, 2, (RF, RF_IF), rd_rm),
20879 cCL("atndm", ed081c0, 2, (RF, RF_IF), rd_rm),
20880 cCL("atndz", ed081e0, 2, (RF, RF_IF), rd_rm),
20881 cCL("atne", ed88100, 2, (RF, RF_IF), rd_rm),
20882 cCL("atnep", ed88120, 2, (RF, RF_IF), rd_rm),
20883 cCL("atnem", ed88140, 2, (RF, RF_IF), rd_rm),
20884 cCL("atnez", ed88160, 2, (RF, RF_IF), rd_rm),
20885
20886 cCL("urds", ee08100, 2, (RF, RF_IF), rd_rm),
20887 cCL("urdsp", ee08120, 2, (RF, RF_IF), rd_rm),
20888 cCL("urdsm", ee08140, 2, (RF, RF_IF), rd_rm),
20889 cCL("urdsz", ee08160, 2, (RF, RF_IF), rd_rm),
20890 cCL("urdd", ee08180, 2, (RF, RF_IF), rd_rm),
20891 cCL("urddp", ee081a0, 2, (RF, RF_IF), rd_rm),
20892 cCL("urddm", ee081c0, 2, (RF, RF_IF), rd_rm),
20893 cCL("urddz", ee081e0, 2, (RF, RF_IF), rd_rm),
20894 cCL("urde", ee88100, 2, (RF, RF_IF), rd_rm),
20895 cCL("urdep", ee88120, 2, (RF, RF_IF), rd_rm),
20896 cCL("urdem", ee88140, 2, (RF, RF_IF), rd_rm),
20897 cCL("urdez", ee88160, 2, (RF, RF_IF), rd_rm),
20898
20899 cCL("nrms", ef08100, 2, (RF, RF_IF), rd_rm),
20900 cCL("nrmsp", ef08120, 2, (RF, RF_IF), rd_rm),
20901 cCL("nrmsm", ef08140, 2, (RF, RF_IF), rd_rm),
20902 cCL("nrmsz", ef08160, 2, (RF, RF_IF), rd_rm),
20903 cCL("nrmd", ef08180, 2, (RF, RF_IF), rd_rm),
20904 cCL("nrmdp", ef081a0, 2, (RF, RF_IF), rd_rm),
20905 cCL("nrmdm", ef081c0, 2, (RF, RF_IF), rd_rm),
20906 cCL("nrmdz", ef081e0, 2, (RF, RF_IF), rd_rm),
20907 cCL("nrme", ef88100, 2, (RF, RF_IF), rd_rm),
20908 cCL("nrmep", ef88120, 2, (RF, RF_IF), rd_rm),
20909 cCL("nrmem", ef88140, 2, (RF, RF_IF), rd_rm),
20910 cCL("nrmez", ef88160, 2, (RF, RF_IF), rd_rm),
20911
20912 cCL("adfs", e000100, 3, (RF, RF, RF_IF), rd_rn_rm),
20913 cCL("adfsp", e000120, 3, (RF, RF, RF_IF), rd_rn_rm),
20914 cCL("adfsm", e000140, 3, (RF, RF, RF_IF), rd_rn_rm),
20915 cCL("adfsz", e000160, 3, (RF, RF, RF_IF), rd_rn_rm),
20916 cCL("adfd", e000180, 3, (RF, RF, RF_IF), rd_rn_rm),
20917 cCL("adfdp", e0001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20918 cCL("adfdm", e0001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20919 cCL("adfdz", e0001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20920 cCL("adfe", e080100, 3, (RF, RF, RF_IF), rd_rn_rm),
20921 cCL("adfep", e080120, 3, (RF, RF, RF_IF), rd_rn_rm),
20922 cCL("adfem", e080140, 3, (RF, RF, RF_IF), rd_rn_rm),
20923 cCL("adfez", e080160, 3, (RF, RF, RF_IF), rd_rn_rm),
20924
20925 cCL("sufs", e200100, 3, (RF, RF, RF_IF), rd_rn_rm),
20926 cCL("sufsp", e200120, 3, (RF, RF, RF_IF), rd_rn_rm),
20927 cCL("sufsm", e200140, 3, (RF, RF, RF_IF), rd_rn_rm),
20928 cCL("sufsz", e200160, 3, (RF, RF, RF_IF), rd_rn_rm),
20929 cCL("sufd", e200180, 3, (RF, RF, RF_IF), rd_rn_rm),
20930 cCL("sufdp", e2001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20931 cCL("sufdm", e2001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20932 cCL("sufdz", e2001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20933 cCL("sufe", e280100, 3, (RF, RF, RF_IF), rd_rn_rm),
20934 cCL("sufep", e280120, 3, (RF, RF, RF_IF), rd_rn_rm),
20935 cCL("sufem", e280140, 3, (RF, RF, RF_IF), rd_rn_rm),
20936 cCL("sufez", e280160, 3, (RF, RF, RF_IF), rd_rn_rm),
20937
20938 cCL("rsfs", e300100, 3, (RF, RF, RF_IF), rd_rn_rm),
20939 cCL("rsfsp", e300120, 3, (RF, RF, RF_IF), rd_rn_rm),
20940 cCL("rsfsm", e300140, 3, (RF, RF, RF_IF), rd_rn_rm),
20941 cCL("rsfsz", e300160, 3, (RF, RF, RF_IF), rd_rn_rm),
20942 cCL("rsfd", e300180, 3, (RF, RF, RF_IF), rd_rn_rm),
20943 cCL("rsfdp", e3001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20944 cCL("rsfdm", e3001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20945 cCL("rsfdz", e3001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20946 cCL("rsfe", e380100, 3, (RF, RF, RF_IF), rd_rn_rm),
20947 cCL("rsfep", e380120, 3, (RF, RF, RF_IF), rd_rn_rm),
20948 cCL("rsfem", e380140, 3, (RF, RF, RF_IF), rd_rn_rm),
20949 cCL("rsfez", e380160, 3, (RF, RF, RF_IF), rd_rn_rm),
20950
20951 cCL("mufs", e100100, 3, (RF, RF, RF_IF), rd_rn_rm),
20952 cCL("mufsp", e100120, 3, (RF, RF, RF_IF), rd_rn_rm),
20953 cCL("mufsm", e100140, 3, (RF, RF, RF_IF), rd_rn_rm),
20954 cCL("mufsz", e100160, 3, (RF, RF, RF_IF), rd_rn_rm),
20955 cCL("mufd", e100180, 3, (RF, RF, RF_IF), rd_rn_rm),
20956 cCL("mufdp", e1001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20957 cCL("mufdm", e1001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20958 cCL("mufdz", e1001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20959 cCL("mufe", e180100, 3, (RF, RF, RF_IF), rd_rn_rm),
20960 cCL("mufep", e180120, 3, (RF, RF, RF_IF), rd_rn_rm),
20961 cCL("mufem", e180140, 3, (RF, RF, RF_IF), rd_rn_rm),
20962 cCL("mufez", e180160, 3, (RF, RF, RF_IF), rd_rn_rm),
20963
20964 cCL("dvfs", e400100, 3, (RF, RF, RF_IF), rd_rn_rm),
20965 cCL("dvfsp", e400120, 3, (RF, RF, RF_IF), rd_rn_rm),
20966 cCL("dvfsm", e400140, 3, (RF, RF, RF_IF), rd_rn_rm),
20967 cCL("dvfsz", e400160, 3, (RF, RF, RF_IF), rd_rn_rm),
20968 cCL("dvfd", e400180, 3, (RF, RF, RF_IF), rd_rn_rm),
20969 cCL("dvfdp", e4001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20970 cCL("dvfdm", e4001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20971 cCL("dvfdz", e4001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20972 cCL("dvfe", e480100, 3, (RF, RF, RF_IF), rd_rn_rm),
20973 cCL("dvfep", e480120, 3, (RF, RF, RF_IF), rd_rn_rm),
20974 cCL("dvfem", e480140, 3, (RF, RF, RF_IF), rd_rn_rm),
20975 cCL("dvfez", e480160, 3, (RF, RF, RF_IF), rd_rn_rm),
20976
20977 cCL("rdfs", e500100, 3, (RF, RF, RF_IF), rd_rn_rm),
20978 cCL("rdfsp", e500120, 3, (RF, RF, RF_IF), rd_rn_rm),
20979 cCL("rdfsm", e500140, 3, (RF, RF, RF_IF), rd_rn_rm),
20980 cCL("rdfsz", e500160, 3, (RF, RF, RF_IF), rd_rn_rm),
20981 cCL("rdfd", e500180, 3, (RF, RF, RF_IF), rd_rn_rm),
20982 cCL("rdfdp", e5001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20983 cCL("rdfdm", e5001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20984 cCL("rdfdz", e5001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20985 cCL("rdfe", e580100, 3, (RF, RF, RF_IF), rd_rn_rm),
20986 cCL("rdfep", e580120, 3, (RF, RF, RF_IF), rd_rn_rm),
20987 cCL("rdfem", e580140, 3, (RF, RF, RF_IF), rd_rn_rm),
20988 cCL("rdfez", e580160, 3, (RF, RF, RF_IF), rd_rn_rm),
20989
20990 cCL("pows", e600100, 3, (RF, RF, RF_IF), rd_rn_rm),
20991 cCL("powsp", e600120, 3, (RF, RF, RF_IF), rd_rn_rm),
20992 cCL("powsm", e600140, 3, (RF, RF, RF_IF), rd_rn_rm),
20993 cCL("powsz", e600160, 3, (RF, RF, RF_IF), rd_rn_rm),
20994 cCL("powd", e600180, 3, (RF, RF, RF_IF), rd_rn_rm),
20995 cCL("powdp", e6001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20996 cCL("powdm", e6001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20997 cCL("powdz", e6001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20998 cCL("powe", e680100, 3, (RF, RF, RF_IF), rd_rn_rm),
20999 cCL("powep", e680120, 3, (RF, RF, RF_IF), rd_rn_rm),
21000 cCL("powem", e680140, 3, (RF, RF, RF_IF), rd_rn_rm),
21001 cCL("powez", e680160, 3, (RF, RF, RF_IF), rd_rn_rm),
21002
21003 cCL("rpws", e700100, 3, (RF, RF, RF_IF), rd_rn_rm),
21004 cCL("rpwsp", e700120, 3, (RF, RF, RF_IF), rd_rn_rm),
21005 cCL("rpwsm", e700140, 3, (RF, RF, RF_IF), rd_rn_rm),
21006 cCL("rpwsz", e700160, 3, (RF, RF, RF_IF), rd_rn_rm),
21007 cCL("rpwd", e700180, 3, (RF, RF, RF_IF), rd_rn_rm),
21008 cCL("rpwdp", e7001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21009 cCL("rpwdm", e7001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21010 cCL("rpwdz", e7001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21011 cCL("rpwe", e780100, 3, (RF, RF, RF_IF), rd_rn_rm),
21012 cCL("rpwep", e780120, 3, (RF, RF, RF_IF), rd_rn_rm),
21013 cCL("rpwem", e780140, 3, (RF, RF, RF_IF), rd_rn_rm),
21014 cCL("rpwez", e780160, 3, (RF, RF, RF_IF), rd_rn_rm),
21015
21016 cCL("rmfs", e800100, 3, (RF, RF, RF_IF), rd_rn_rm),
21017 cCL("rmfsp", e800120, 3, (RF, RF, RF_IF), rd_rn_rm),
21018 cCL("rmfsm", e800140, 3, (RF, RF, RF_IF), rd_rn_rm),
21019 cCL("rmfsz", e800160, 3, (RF, RF, RF_IF), rd_rn_rm),
21020 cCL("rmfd", e800180, 3, (RF, RF, RF_IF), rd_rn_rm),
21021 cCL("rmfdp", e8001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21022 cCL("rmfdm", e8001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21023 cCL("rmfdz", e8001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21024 cCL("rmfe", e880100, 3, (RF, RF, RF_IF), rd_rn_rm),
21025 cCL("rmfep", e880120, 3, (RF, RF, RF_IF), rd_rn_rm),
21026 cCL("rmfem", e880140, 3, (RF, RF, RF_IF), rd_rn_rm),
21027 cCL("rmfez", e880160, 3, (RF, RF, RF_IF), rd_rn_rm),
21028
21029 cCL("fmls", e900100, 3, (RF, RF, RF_IF), rd_rn_rm),
21030 cCL("fmlsp", e900120, 3, (RF, RF, RF_IF), rd_rn_rm),
21031 cCL("fmlsm", e900140, 3, (RF, RF, RF_IF), rd_rn_rm),
21032 cCL("fmlsz", e900160, 3, (RF, RF, RF_IF), rd_rn_rm),
21033 cCL("fmld", e900180, 3, (RF, RF, RF_IF), rd_rn_rm),
21034 cCL("fmldp", e9001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21035 cCL("fmldm", e9001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21036 cCL("fmldz", e9001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21037 cCL("fmle", e980100, 3, (RF, RF, RF_IF), rd_rn_rm),
21038 cCL("fmlep", e980120, 3, (RF, RF, RF_IF), rd_rn_rm),
21039 cCL("fmlem", e980140, 3, (RF, RF, RF_IF), rd_rn_rm),
21040 cCL("fmlez", e980160, 3, (RF, RF, RF_IF), rd_rn_rm),
21041
21042 cCL("fdvs", ea00100, 3, (RF, RF, RF_IF), rd_rn_rm),
21043 cCL("fdvsp", ea00120, 3, (RF, RF, RF_IF), rd_rn_rm),
21044 cCL("fdvsm", ea00140, 3, (RF, RF, RF_IF), rd_rn_rm),
21045 cCL("fdvsz", ea00160, 3, (RF, RF, RF_IF), rd_rn_rm),
21046 cCL("fdvd", ea00180, 3, (RF, RF, RF_IF), rd_rn_rm),
21047 cCL("fdvdp", ea001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21048 cCL("fdvdm", ea001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21049 cCL("fdvdz", ea001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21050 cCL("fdve", ea80100, 3, (RF, RF, RF_IF), rd_rn_rm),
21051 cCL("fdvep", ea80120, 3, (RF, RF, RF_IF), rd_rn_rm),
21052 cCL("fdvem", ea80140, 3, (RF, RF, RF_IF), rd_rn_rm),
21053 cCL("fdvez", ea80160, 3, (RF, RF, RF_IF), rd_rn_rm),
21054
21055 cCL("frds", eb00100, 3, (RF, RF, RF_IF), rd_rn_rm),
21056 cCL("frdsp", eb00120, 3, (RF, RF, RF_IF), rd_rn_rm),
21057 cCL("frdsm", eb00140, 3, (RF, RF, RF_IF), rd_rn_rm),
21058 cCL("frdsz", eb00160, 3, (RF, RF, RF_IF), rd_rn_rm),
21059 cCL("frdd", eb00180, 3, (RF, RF, RF_IF), rd_rn_rm),
21060 cCL("frddp", eb001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21061 cCL("frddm", eb001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21062 cCL("frddz", eb001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21063 cCL("frde", eb80100, 3, (RF, RF, RF_IF), rd_rn_rm),
21064 cCL("frdep", eb80120, 3, (RF, RF, RF_IF), rd_rn_rm),
21065 cCL("frdem", eb80140, 3, (RF, RF, RF_IF), rd_rn_rm),
21066 cCL("frdez", eb80160, 3, (RF, RF, RF_IF), rd_rn_rm),
21067
21068 cCL("pols", ec00100, 3, (RF, RF, RF_IF), rd_rn_rm),
21069 cCL("polsp", ec00120, 3, (RF, RF, RF_IF), rd_rn_rm),
21070 cCL("polsm", ec00140, 3, (RF, RF, RF_IF), rd_rn_rm),
21071 cCL("polsz", ec00160, 3, (RF, RF, RF_IF), rd_rn_rm),
21072 cCL("pold", ec00180, 3, (RF, RF, RF_IF), rd_rn_rm),
21073 cCL("poldp", ec001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21074 cCL("poldm", ec001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21075 cCL("poldz", ec001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21076 cCL("pole", ec80100, 3, (RF, RF, RF_IF), rd_rn_rm),
21077 cCL("polep", ec80120, 3, (RF, RF, RF_IF), rd_rn_rm),
21078 cCL("polem", ec80140, 3, (RF, RF, RF_IF), rd_rn_rm),
21079 cCL("polez", ec80160, 3, (RF, RF, RF_IF), rd_rn_rm),
21080
21081 cCE("cmf", e90f110, 2, (RF, RF_IF), fpa_cmp),
21082 C3E("cmfe", ed0f110, 2, (RF, RF_IF), fpa_cmp),
21083 cCE("cnf", eb0f110, 2, (RF, RF_IF), fpa_cmp),
21084 C3E("cnfe", ef0f110, 2, (RF, RF_IF), fpa_cmp),
21085
21086 cCL("flts", e000110, 2, (RF, RR), rn_rd),
21087 cCL("fltsp", e000130, 2, (RF, RR), rn_rd),
21088 cCL("fltsm", e000150, 2, (RF, RR), rn_rd),
21089 cCL("fltsz", e000170, 2, (RF, RR), rn_rd),
21090 cCL("fltd", e000190, 2, (RF, RR), rn_rd),
21091 cCL("fltdp", e0001b0, 2, (RF, RR), rn_rd),
21092 cCL("fltdm", e0001d0, 2, (RF, RR), rn_rd),
21093 cCL("fltdz", e0001f0, 2, (RF, RR), rn_rd),
21094 cCL("flte", e080110, 2, (RF, RR), rn_rd),
21095 cCL("fltep", e080130, 2, (RF, RR), rn_rd),
21096 cCL("fltem", e080150, 2, (RF, RR), rn_rd),
21097 cCL("fltez", e080170, 2, (RF, RR), rn_rd),
b99bd4ef 21098
c19d1205
ZW
21099 /* The implementation of the FIX instruction is broken on some
21100 assemblers, in that it accepts a precision specifier as well as a
21101 rounding specifier, despite the fact that this is meaningless.
21102 To be more compatible, we accept it as well, though of course it
21103 does not set any bits. */
21d799b5
NC
21104 cCE("fix", e100110, 2, (RR, RF), rd_rm),
21105 cCL("fixp", e100130, 2, (RR, RF), rd_rm),
21106 cCL("fixm", e100150, 2, (RR, RF), rd_rm),
21107 cCL("fixz", e100170, 2, (RR, RF), rd_rm),
21108 cCL("fixsp", e100130, 2, (RR, RF), rd_rm),
21109 cCL("fixsm", e100150, 2, (RR, RF), rd_rm),
21110 cCL("fixsz", e100170, 2, (RR, RF), rd_rm),
21111 cCL("fixdp", e100130, 2, (RR, RF), rd_rm),
21112 cCL("fixdm", e100150, 2, (RR, RF), rd_rm),
21113 cCL("fixdz", e100170, 2, (RR, RF), rd_rm),
21114 cCL("fixep", e100130, 2, (RR, RF), rd_rm),
21115 cCL("fixem", e100150, 2, (RR, RF), rd_rm),
21116 cCL("fixez", e100170, 2, (RR, RF), rd_rm),
bfae80f2 21117
c19d1205 21118 /* Instructions that were new with the real FPA, call them V2. */
c921be7d
NC
21119#undef ARM_VARIANT
21120#define ARM_VARIANT & fpu_fpa_ext_v2
21121
21d799b5
NC
21122 cCE("lfm", c100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
21123 cCL("lfmfd", c900200, 3, (RF, I4b, ADDR), fpa_ldmstm),
21124 cCL("lfmea", d100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
21125 cCE("sfm", c000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
21126 cCL("sfmfd", d000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
21127 cCL("sfmea", c800200, 3, (RF, I4b, ADDR), fpa_ldmstm),
c19d1205 21128
c921be7d
NC
21129#undef ARM_VARIANT
21130#define ARM_VARIANT & fpu_vfp_ext_v1xd /* VFP V1xD (single precision). */
21131
c19d1205 21132 /* Moves and type conversions. */
21d799b5
NC
21133 cCE("fcpys", eb00a40, 2, (RVS, RVS), vfp_sp_monadic),
21134 cCE("fmrs", e100a10, 2, (RR, RVS), vfp_reg_from_sp),
21135 cCE("fmsr", e000a10, 2, (RVS, RR), vfp_sp_from_reg),
21136 cCE("fmstat", ef1fa10, 0, (), noargs),
7465e07a
NC
21137 cCE("vmrs", ef00a10, 2, (APSR_RR, RVC), vmrs),
21138 cCE("vmsr", ee00a10, 2, (RVC, RR), vmsr),
21d799b5
NC
21139 cCE("fsitos", eb80ac0, 2, (RVS, RVS), vfp_sp_monadic),
21140 cCE("fuitos", eb80a40, 2, (RVS, RVS), vfp_sp_monadic),
21141 cCE("ftosis", ebd0a40, 2, (RVS, RVS), vfp_sp_monadic),
21142 cCE("ftosizs", ebd0ac0, 2, (RVS, RVS), vfp_sp_monadic),
21143 cCE("ftouis", ebc0a40, 2, (RVS, RVS), vfp_sp_monadic),
21144 cCE("ftouizs", ebc0ac0, 2, (RVS, RVS), vfp_sp_monadic),
21145 cCE("fmrx", ef00a10, 2, (RR, RVC), rd_rn),
21146 cCE("fmxr", ee00a10, 2, (RVC, RR), rn_rd),
c19d1205
ZW
21147
21148 /* Memory operations. */
21d799b5
NC
21149 cCE("flds", d100a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
21150 cCE("fsts", d000a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
55881a11
MGD
21151 cCE("fldmias", c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
21152 cCE("fldmfds", c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
21153 cCE("fldmdbs", d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
21154 cCE("fldmeas", d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
21155 cCE("fldmiax", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
21156 cCE("fldmfdx", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
21157 cCE("fldmdbx", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
21158 cCE("fldmeax", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
21159 cCE("fstmias", c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
21160 cCE("fstmeas", c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
21161 cCE("fstmdbs", d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
21162 cCE("fstmfds", d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
21163 cCE("fstmiax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
21164 cCE("fstmeax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
21165 cCE("fstmdbx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
21166 cCE("fstmfdx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
bfae80f2 21167
c19d1205 21168 /* Monadic operations. */
21d799b5
NC
21169 cCE("fabss", eb00ac0, 2, (RVS, RVS), vfp_sp_monadic),
21170 cCE("fnegs", eb10a40, 2, (RVS, RVS), vfp_sp_monadic),
21171 cCE("fsqrts", eb10ac0, 2, (RVS, RVS), vfp_sp_monadic),
c19d1205
ZW
21172
21173 /* Dyadic operations. */
21d799b5
NC
21174 cCE("fadds", e300a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21175 cCE("fsubs", e300a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21176 cCE("fmuls", e200a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21177 cCE("fdivs", e800a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21178 cCE("fmacs", e000a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21179 cCE("fmscs", e100a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21180 cCE("fnmuls", e200a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21181 cCE("fnmacs", e000a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21182 cCE("fnmscs", e100a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
b99bd4ef 21183
c19d1205 21184 /* Comparisons. */
21d799b5
NC
21185 cCE("fcmps", eb40a40, 2, (RVS, RVS), vfp_sp_monadic),
21186 cCE("fcmpzs", eb50a40, 1, (RVS), vfp_sp_compare_z),
21187 cCE("fcmpes", eb40ac0, 2, (RVS, RVS), vfp_sp_monadic),
21188 cCE("fcmpezs", eb50ac0, 1, (RVS), vfp_sp_compare_z),
b99bd4ef 21189
62f3b8c8
PB
21190 /* Double precision load/store are still present on single precision
21191 implementations. */
21192 cCE("fldd", d100b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
21193 cCE("fstd", d000b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
55881a11
MGD
21194 cCE("fldmiad", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
21195 cCE("fldmfdd", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
21196 cCE("fldmdbd", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
21197 cCE("fldmead", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
21198 cCE("fstmiad", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
21199 cCE("fstmead", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
21200 cCE("fstmdbd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
21201 cCE("fstmfdd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
62f3b8c8 21202
c921be7d
NC
21203#undef ARM_VARIANT
21204#define ARM_VARIANT & fpu_vfp_ext_v1 /* VFP V1 (Double precision). */
21205
c19d1205 21206 /* Moves and type conversions. */
21d799b5
NC
21207 cCE("fcpyd", eb00b40, 2, (RVD, RVD), vfp_dp_rd_rm),
21208 cCE("fcvtds", eb70ac0, 2, (RVD, RVS), vfp_dp_sp_cvt),
21209 cCE("fcvtsd", eb70bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
21210 cCE("fmdhr", e200b10, 2, (RVD, RR), vfp_dp_rn_rd),
21211 cCE("fmdlr", e000b10, 2, (RVD, RR), vfp_dp_rn_rd),
21212 cCE("fmrdh", e300b10, 2, (RR, RVD), vfp_dp_rd_rn),
21213 cCE("fmrdl", e100b10, 2, (RR, RVD), vfp_dp_rd_rn),
21214 cCE("fsitod", eb80bc0, 2, (RVD, RVS), vfp_dp_sp_cvt),
21215 cCE("fuitod", eb80b40, 2, (RVD, RVS), vfp_dp_sp_cvt),
21216 cCE("ftosid", ebd0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
21217 cCE("ftosizd", ebd0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
21218 cCE("ftouid", ebc0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
21219 cCE("ftouizd", ebc0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
c19d1205 21220
c19d1205 21221 /* Monadic operations. */
21d799b5
NC
21222 cCE("fabsd", eb00bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
21223 cCE("fnegd", eb10b40, 2, (RVD, RVD), vfp_dp_rd_rm),
21224 cCE("fsqrtd", eb10bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
c19d1205
ZW
21225
21226 /* Dyadic operations. */
21d799b5
NC
21227 cCE("faddd", e300b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21228 cCE("fsubd", e300b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21229 cCE("fmuld", e200b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21230 cCE("fdivd", e800b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21231 cCE("fmacd", e000b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21232 cCE("fmscd", e100b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21233 cCE("fnmuld", e200b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21234 cCE("fnmacd", e000b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21235 cCE("fnmscd", e100b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
b99bd4ef 21236
c19d1205 21237 /* Comparisons. */
21d799b5
NC
21238 cCE("fcmpd", eb40b40, 2, (RVD, RVD), vfp_dp_rd_rm),
21239 cCE("fcmpzd", eb50b40, 1, (RVD), vfp_dp_rd),
21240 cCE("fcmped", eb40bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
21241 cCE("fcmpezd", eb50bc0, 1, (RVD), vfp_dp_rd),
c19d1205 21242
c921be7d
NC
21243#undef ARM_VARIANT
21244#define ARM_VARIANT & fpu_vfp_ext_v2
21245
21d799b5
NC
21246 cCE("fmsrr", c400a10, 3, (VRSLST, RR, RR), vfp_sp2_from_reg2),
21247 cCE("fmrrs", c500a10, 3, (RR, RR, VRSLST), vfp_reg2_from_sp2),
21248 cCE("fmdrr", c400b10, 3, (RVD, RR, RR), vfp_dp_rm_rd_rn),
21249 cCE("fmrrd", c500b10, 3, (RR, RR, RVD), vfp_dp_rd_rn_rm),
5287ad62 21250
037e8744
JB
21251/* Instructions which may belong to either the Neon or VFP instruction sets.
21252 Individual encoder functions perform additional architecture checks. */
c921be7d
NC
21253#undef ARM_VARIANT
21254#define ARM_VARIANT & fpu_vfp_ext_v1xd
21255#undef THUMB_VARIANT
21256#define THUMB_VARIANT & fpu_vfp_ext_v1xd
21257
037e8744
JB
21258 /* These mnemonics are unique to VFP. */
21259 NCE(vsqrt, 0, 2, (RVSD, RVSD), vfp_nsyn_sqrt),
21260 NCE(vdiv, 0, 3, (RVSD, RVSD, RVSD), vfp_nsyn_div),
21d799b5
NC
21261 nCE(vnmul, _vnmul, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
21262 nCE(vnmla, _vnmla, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
21263 nCE(vnmls, _vnmls, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
aacf0b33
KT
21264 nCE(vcmp, _vcmp, 2, (RVSD, RSVD_FI0), vfp_nsyn_cmp),
21265 nCE(vcmpe, _vcmpe, 2, (RVSD, RSVD_FI0), vfp_nsyn_cmp),
037e8744
JB
21266 NCE(vpush, 0, 1, (VRSDLST), vfp_nsyn_push),
21267 NCE(vpop, 0, 1, (VRSDLST), vfp_nsyn_pop),
21268 NCE(vcvtz, 0, 2, (RVSD, RVSD), vfp_nsyn_cvtz),
21269
21270 /* Mnemonics shared by Neon and VFP. */
21d799b5
NC
21271 nCEF(vmul, _vmul, 3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mul),
21272 nCEF(vmla, _vmla, 3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
21273 nCEF(vmls, _vmls, 3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
037e8744 21274
21d799b5
NC
21275 nCEF(vadd, _vadd, 3, (RNSDQ, oRNSDQ, RNSDQ), neon_addsub_if_i),
21276 nCEF(vsub, _vsub, 3, (RNSDQ, oRNSDQ, RNSDQ), neon_addsub_if_i),
037e8744
JB
21277
21278 NCEF(vabs, 1b10300, 2, (RNSDQ, RNSDQ), neon_abs_neg),
21279 NCEF(vneg, 1b10380, 2, (RNSDQ, RNSDQ), neon_abs_neg),
21280
55881a11
MGD
21281 NCE(vldm, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
21282 NCE(vldmia, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
21283 NCE(vldmdb, d100b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
21284 NCE(vstm, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
21285 NCE(vstmia, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
21286 NCE(vstmdb, d000b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
4962c51a
MS
21287 NCE(vldr, d100b00, 2, (RVSD, ADDRGLDC), neon_ldr_str),
21288 NCE(vstr, d000b00, 2, (RVSD, ADDRGLDC), neon_ldr_str),
037e8744 21289
5f1af56b 21290 nCEF(vcvt, _vcvt, 3, (RNSDQ, RNSDQ, oI32z), neon_cvt),
e3e535bc 21291 nCEF(vcvtr, _vcvt, 2, (RNSDQ, RNSDQ), neon_cvtr),
c70a8987
MGD
21292 NCEF(vcvtb, eb20a40, 2, (RVSD, RVSD), neon_cvtb),
21293 NCEF(vcvtt, eb20a40, 2, (RVSD, RVSD), neon_cvtt),
f31fef98 21294
037e8744
JB
21295
21296 /* NOTE: All VMOV encoding is special-cased! */
21297 NCE(vmov, 0, 1, (VMOV), neon_mov),
21298 NCE(vmovq, 0, 1, (VMOV), neon_mov),
21299
9db2f6b4
RL
21300#undef ARM_VARIANT
21301#define ARM_VARIANT & arm_ext_fp16
21302#undef THUMB_VARIANT
21303#define THUMB_VARIANT & arm_ext_fp16
21304 /* New instructions added from v8.2, allowing the extraction and insertion of
21305 the upper 16 bits of a 32-bit vector register. */
21306 NCE (vmovx, eb00a40, 2, (RVS, RVS), neon_movhf),
21307 NCE (vins, eb00ac0, 2, (RVS, RVS), neon_movhf),
21308
dec41383
JW
21309 /* New backported fma/fms instructions optional in v8.2. */
21310 NCE (vfmal, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmal),
21311 NCE (vfmsl, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmsl),
21312
c921be7d
NC
21313#undef THUMB_VARIANT
21314#define THUMB_VARIANT & fpu_neon_ext_v1
21315#undef ARM_VARIANT
21316#define ARM_VARIANT & fpu_neon_ext_v1
21317
5287ad62
JB
21318 /* Data processing with three registers of the same length. */
21319 /* integer ops, valid types S8 S16 S32 U8 U16 U32. */
21320 NUF(vaba, 0000710, 3, (RNDQ, RNDQ, RNDQ), neon_dyadic_i_su),
21321 NUF(vabaq, 0000710, 3, (RNQ, RNQ, RNQ), neon_dyadic_i_su),
21322 NUF(vhadd, 0000000, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i_su),
21323 NUF(vhaddq, 0000000, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
21324 NUF(vrhadd, 0000100, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i_su),
21325 NUF(vrhaddq, 0000100, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
21326 NUF(vhsub, 0000200, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i_su),
21327 NUF(vhsubq, 0000200, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
21328 /* integer ops, valid types S8 S16 S32 S64 U8 U16 U32 U64. */
21329 NUF(vqadd, 0000010, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i64_su),
21330 NUF(vqaddq, 0000010, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
21331 NUF(vqsub, 0000210, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i64_su),
21332 NUF(vqsubq, 0000210, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
627907b7
JB
21333 NUF(vrshl, 0000500, 3, (RNDQ, oRNDQ, RNDQ), neon_rshl),
21334 NUF(vrshlq, 0000500, 3, (RNQ, oRNQ, RNQ), neon_rshl),
21335 NUF(vqrshl, 0000510, 3, (RNDQ, oRNDQ, RNDQ), neon_rshl),
21336 NUF(vqrshlq, 0000510, 3, (RNQ, oRNQ, RNQ), neon_rshl),
5287ad62
JB
21337 /* If not immediate, fall back to neon_dyadic_i64_su.
21338 shl_imm should accept I8 I16 I32 I64,
21339 qshl_imm should accept S8 S16 S32 S64 U8 U16 U32 U64. */
21d799b5
NC
21340 nUF(vshl, _vshl, 3, (RNDQ, oRNDQ, RNDQ_I63b), neon_shl_imm),
21341 nUF(vshlq, _vshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_shl_imm),
21342 nUF(vqshl, _vqshl, 3, (RNDQ, oRNDQ, RNDQ_I63b), neon_qshl_imm),
21343 nUF(vqshlq, _vqshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_qshl_imm),
5287ad62 21344 /* Logic ops, types optional & ignored. */
4316f0d2
DG
21345 nUF(vand, _vand, 3, (RNDQ, oRNDQ, RNDQ_Ibig), neon_logic),
21346 nUF(vandq, _vand, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
21347 nUF(vbic, _vbic, 3, (RNDQ, oRNDQ, RNDQ_Ibig), neon_logic),
21348 nUF(vbicq, _vbic, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
21349 nUF(vorr, _vorr, 3, (RNDQ, oRNDQ, RNDQ_Ibig), neon_logic),
21350 nUF(vorrq, _vorr, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
21351 nUF(vorn, _vorn, 3, (RNDQ, oRNDQ, RNDQ_Ibig), neon_logic),
21352 nUF(vornq, _vorn, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
21353 nUF(veor, _veor, 3, (RNDQ, oRNDQ, RNDQ), neon_logic),
21354 nUF(veorq, _veor, 3, (RNQ, oRNQ, RNQ), neon_logic),
5287ad62
JB
21355 /* Bitfield ops, untyped. */
21356 NUF(vbsl, 1100110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
21357 NUF(vbslq, 1100110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
21358 NUF(vbit, 1200110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
21359 NUF(vbitq, 1200110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
21360 NUF(vbif, 1300110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
21361 NUF(vbifq, 1300110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
cc933301 21362 /* Int and float variants, types S8 S16 S32 U8 U16 U32 F16 F32. */
21d799b5
NC
21363 nUF(vabd, _vabd, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_if_su),
21364 nUF(vabdq, _vabd, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21365 nUF(vmax, _vmax, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_if_su),
21366 nUF(vmaxq, _vmax, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21367 nUF(vmin, _vmin, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_if_su),
21368 nUF(vminq, _vmin, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
5287ad62
JB
21369 /* Comparisons. Types S8 S16 S32 U8 U16 U32 F32. Non-immediate versions fall
21370 back to neon_dyadic_if_su. */
21d799b5
NC
21371 nUF(vcge, _vcge, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
21372 nUF(vcgeq, _vcge, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
21373 nUF(vcgt, _vcgt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
21374 nUF(vcgtq, _vcgt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
21375 nUF(vclt, _vclt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
21376 nUF(vcltq, _vclt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
21377 nUF(vcle, _vcle, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
21378 nUF(vcleq, _vcle, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
428e3f1f 21379 /* Comparison. Type I8 I16 I32 F32. */
21d799b5
NC
21380 nUF(vceq, _vceq, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_ceq),
21381 nUF(vceqq, _vceq, 3, (RNQ, oRNQ, RNDQ_I0), neon_ceq),
5287ad62 21382 /* As above, D registers only. */
21d799b5
NC
21383 nUF(vpmax, _vpmax, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
21384 nUF(vpmin, _vpmin, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
5287ad62 21385 /* Int and float variants, signedness unimportant. */
21d799b5
NC
21386 nUF(vmlaq, _vmla, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
21387 nUF(vmlsq, _vmls, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
21388 nUF(vpadd, _vpadd, 3, (RND, oRND, RND), neon_dyadic_if_i_d),
5287ad62 21389 /* Add/sub take types I8 I16 I32 I64 F32. */
21d799b5
NC
21390 nUF(vaddq, _vadd, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
21391 nUF(vsubq, _vsub, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
5287ad62
JB
21392 /* vtst takes sizes 8, 16, 32. */
21393 NUF(vtst, 0000810, 3, (RNDQ, oRNDQ, RNDQ), neon_tst),
21394 NUF(vtstq, 0000810, 3, (RNQ, oRNQ, RNQ), neon_tst),
21395 /* VMUL takes I8 I16 I32 F32 P8. */
21d799b5 21396 nUF(vmulq, _vmul, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mul),
5287ad62 21397 /* VQD{R}MULH takes S16 S32. */
21d799b5
NC
21398 nUF(vqdmulh, _vqdmulh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qdmulh),
21399 nUF(vqdmulhq, _vqdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
21400 nUF(vqrdmulh, _vqrdmulh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qdmulh),
21401 nUF(vqrdmulhq, _vqrdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
5287ad62
JB
21402 NUF(vacge, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
21403 NUF(vacgeq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
21404 NUF(vacgt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
21405 NUF(vacgtq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
92559b5b
PB
21406 NUF(vaclt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
21407 NUF(vacltq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
21408 NUF(vacle, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
21409 NUF(vacleq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
5287ad62
JB
21410 NUF(vrecps, 0000f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
21411 NUF(vrecpsq, 0000f10, 3, (RNQ, oRNQ, RNQ), neon_step),
21412 NUF(vrsqrts, 0200f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
21413 NUF(vrsqrtsq, 0200f10, 3, (RNQ, oRNQ, RNQ), neon_step),
d6b4b13e 21414 /* ARM v8.1 extension. */
643afb90
MW
21415 nUF (vqrdmlah, _vqrdmlah, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qrdmlah),
21416 nUF (vqrdmlahq, _vqrdmlah, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
21417 nUF (vqrdmlsh, _vqrdmlsh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qrdmlah),
21418 nUF (vqrdmlshq, _vqrdmlsh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
5287ad62
JB
21419
21420 /* Two address, int/float. Types S8 S16 S32 F32. */
5287ad62 21421 NUF(vabsq, 1b10300, 2, (RNQ, RNQ), neon_abs_neg),
5287ad62
JB
21422 NUF(vnegq, 1b10380, 2, (RNQ, RNQ), neon_abs_neg),
21423
21424 /* Data processing with two registers and a shift amount. */
21425 /* Right shifts, and variants with rounding.
21426 Types accepted S8 S16 S32 S64 U8 U16 U32 U64. */
21427 NUF(vshr, 0800010, 3, (RNDQ, oRNDQ, I64z), neon_rshift_round_imm),
21428 NUF(vshrq, 0800010, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
21429 NUF(vrshr, 0800210, 3, (RNDQ, oRNDQ, I64z), neon_rshift_round_imm),
21430 NUF(vrshrq, 0800210, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
21431 NUF(vsra, 0800110, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
21432 NUF(vsraq, 0800110, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
21433 NUF(vrsra, 0800310, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
21434 NUF(vrsraq, 0800310, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
21435 /* Shift and insert. Sizes accepted 8 16 32 64. */
21436 NUF(vsli, 1800510, 3, (RNDQ, oRNDQ, I63), neon_sli),
21437 NUF(vsliq, 1800510, 3, (RNQ, oRNQ, I63), neon_sli),
21438 NUF(vsri, 1800410, 3, (RNDQ, oRNDQ, I64), neon_sri),
21439 NUF(vsriq, 1800410, 3, (RNQ, oRNQ, I64), neon_sri),
21440 /* QSHL{U} immediate accepts S8 S16 S32 S64 U8 U16 U32 U64. */
21441 NUF(vqshlu, 1800610, 3, (RNDQ, oRNDQ, I63), neon_qshlu_imm),
21442 NUF(vqshluq, 1800610, 3, (RNQ, oRNQ, I63), neon_qshlu_imm),
21443 /* Right shift immediate, saturating & narrowing, with rounding variants.
21444 Types accepted S16 S32 S64 U16 U32 U64. */
21445 NUF(vqshrn, 0800910, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
21446 NUF(vqrshrn, 0800950, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
21447 /* As above, unsigned. Types accepted S16 S32 S64. */
21448 NUF(vqshrun, 0800810, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
21449 NUF(vqrshrun, 0800850, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
21450 /* Right shift narrowing. Types accepted I16 I32 I64. */
21451 NUF(vshrn, 0800810, 3, (RND, RNQ, I32z), neon_rshift_narrow),
21452 NUF(vrshrn, 0800850, 3, (RND, RNQ, I32z), neon_rshift_narrow),
21453 /* Special case. Types S8 S16 S32 U8 U16 U32. Handles max shift variant. */
21d799b5 21454 nUF(vshll, _vshll, 3, (RNQ, RND, I32), neon_shll),
5287ad62 21455 /* CVT with optional immediate for fixed-point variant. */
21d799b5 21456 nUF(vcvtq, _vcvt, 3, (RNQ, RNQ, oI32b), neon_cvt),
b7fc2769 21457
4316f0d2
DG
21458 nUF(vmvn, _vmvn, 2, (RNDQ, RNDQ_Ibig), neon_mvn),
21459 nUF(vmvnq, _vmvn, 2, (RNQ, RNDQ_Ibig), neon_mvn),
5287ad62
JB
21460
21461 /* Data processing, three registers of different lengths. */
21462 /* Dyadic, long insns. Types S8 S16 S32 U8 U16 U32. */
21463 NUF(vabal, 0800500, 3, (RNQ, RND, RND), neon_abal),
21464 NUF(vabdl, 0800700, 3, (RNQ, RND, RND), neon_dyadic_long),
21465 NUF(vaddl, 0800000, 3, (RNQ, RND, RND), neon_dyadic_long),
21466 NUF(vsubl, 0800200, 3, (RNQ, RND, RND), neon_dyadic_long),
21467 /* If not scalar, fall back to neon_dyadic_long.
21468 Vector types as above, scalar types S16 S32 U16 U32. */
21d799b5
NC
21469 nUF(vmlal, _vmlal, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
21470 nUF(vmlsl, _vmlsl, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
5287ad62
JB
21471 /* Dyadic, widening insns. Types S8 S16 S32 U8 U16 U32. */
21472 NUF(vaddw, 0800100, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
21473 NUF(vsubw, 0800300, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
21474 /* Dyadic, narrowing insns. Types I16 I32 I64. */
21475 NUF(vaddhn, 0800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
21476 NUF(vraddhn, 1800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
21477 NUF(vsubhn, 0800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
21478 NUF(vrsubhn, 1800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
21479 /* Saturating doubling multiplies. Types S16 S32. */
21d799b5
NC
21480 nUF(vqdmlal, _vqdmlal, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
21481 nUF(vqdmlsl, _vqdmlsl, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
21482 nUF(vqdmull, _vqdmull, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
5287ad62
JB
21483 /* VMULL. Vector types S8 S16 S32 U8 U16 U32 P8, scalar types
21484 S16 S32 U16 U32. */
21d799b5 21485 nUF(vmull, _vmull, 3, (RNQ, RND, RND_RNSC), neon_vmull),
5287ad62
JB
21486
21487 /* Extract. Size 8. */
3b8d421e
PB
21488 NUF(vext, 0b00000, 4, (RNDQ, oRNDQ, RNDQ, I15), neon_ext),
21489 NUF(vextq, 0b00000, 4, (RNQ, oRNQ, RNQ, I15), neon_ext),
5287ad62
JB
21490
21491 /* Two registers, miscellaneous. */
21492 /* Reverse. Sizes 8 16 32 (must be < size in opcode). */
21493 NUF(vrev64, 1b00000, 2, (RNDQ, RNDQ), neon_rev),
21494 NUF(vrev64q, 1b00000, 2, (RNQ, RNQ), neon_rev),
21495 NUF(vrev32, 1b00080, 2, (RNDQ, RNDQ), neon_rev),
21496 NUF(vrev32q, 1b00080, 2, (RNQ, RNQ), neon_rev),
21497 NUF(vrev16, 1b00100, 2, (RNDQ, RNDQ), neon_rev),
21498 NUF(vrev16q, 1b00100, 2, (RNQ, RNQ), neon_rev),
21499 /* Vector replicate. Sizes 8 16 32. */
21d799b5
NC
21500 nCE(vdup, _vdup, 2, (RNDQ, RR_RNSC), neon_dup),
21501 nCE(vdupq, _vdup, 2, (RNQ, RR_RNSC), neon_dup),
5287ad62
JB
21502 /* VMOVL. Types S8 S16 S32 U8 U16 U32. */
21503 NUF(vmovl, 0800a10, 2, (RNQ, RND), neon_movl),
21504 /* VMOVN. Types I16 I32 I64. */
21d799b5 21505 nUF(vmovn, _vmovn, 2, (RND, RNQ), neon_movn),
5287ad62 21506 /* VQMOVN. Types S16 S32 S64 U16 U32 U64. */
21d799b5 21507 nUF(vqmovn, _vqmovn, 2, (RND, RNQ), neon_qmovn),
5287ad62 21508 /* VQMOVUN. Types S16 S32 S64. */
21d799b5 21509 nUF(vqmovun, _vqmovun, 2, (RND, RNQ), neon_qmovun),
5287ad62
JB
21510 /* VZIP / VUZP. Sizes 8 16 32. */
21511 NUF(vzip, 1b20180, 2, (RNDQ, RNDQ), neon_zip_uzp),
21512 NUF(vzipq, 1b20180, 2, (RNQ, RNQ), neon_zip_uzp),
21513 NUF(vuzp, 1b20100, 2, (RNDQ, RNDQ), neon_zip_uzp),
21514 NUF(vuzpq, 1b20100, 2, (RNQ, RNQ), neon_zip_uzp),
21515 /* VQABS / VQNEG. Types S8 S16 S32. */
21516 NUF(vqabs, 1b00700, 2, (RNDQ, RNDQ), neon_sat_abs_neg),
21517 NUF(vqabsq, 1b00700, 2, (RNQ, RNQ), neon_sat_abs_neg),
21518 NUF(vqneg, 1b00780, 2, (RNDQ, RNDQ), neon_sat_abs_neg),
21519 NUF(vqnegq, 1b00780, 2, (RNQ, RNQ), neon_sat_abs_neg),
21520 /* Pairwise, lengthening. Types S8 S16 S32 U8 U16 U32. */
21521 NUF(vpadal, 1b00600, 2, (RNDQ, RNDQ), neon_pair_long),
21522 NUF(vpadalq, 1b00600, 2, (RNQ, RNQ), neon_pair_long),
21523 NUF(vpaddl, 1b00200, 2, (RNDQ, RNDQ), neon_pair_long),
21524 NUF(vpaddlq, 1b00200, 2, (RNQ, RNQ), neon_pair_long),
cc933301 21525 /* Reciprocal estimates. Types U32 F16 F32. */
5287ad62
JB
21526 NUF(vrecpe, 1b30400, 2, (RNDQ, RNDQ), neon_recip_est),
21527 NUF(vrecpeq, 1b30400, 2, (RNQ, RNQ), neon_recip_est),
21528 NUF(vrsqrte, 1b30480, 2, (RNDQ, RNDQ), neon_recip_est),
21529 NUF(vrsqrteq, 1b30480, 2, (RNQ, RNQ), neon_recip_est),
21530 /* VCLS. Types S8 S16 S32. */
21531 NUF(vcls, 1b00400, 2, (RNDQ, RNDQ), neon_cls),
21532 NUF(vclsq, 1b00400, 2, (RNQ, RNQ), neon_cls),
21533 /* VCLZ. Types I8 I16 I32. */
21534 NUF(vclz, 1b00480, 2, (RNDQ, RNDQ), neon_clz),
21535 NUF(vclzq, 1b00480, 2, (RNQ, RNQ), neon_clz),
21536 /* VCNT. Size 8. */
21537 NUF(vcnt, 1b00500, 2, (RNDQ, RNDQ), neon_cnt),
21538 NUF(vcntq, 1b00500, 2, (RNQ, RNQ), neon_cnt),
21539 /* Two address, untyped. */
21540 NUF(vswp, 1b20000, 2, (RNDQ, RNDQ), neon_swp),
21541 NUF(vswpq, 1b20000, 2, (RNQ, RNQ), neon_swp),
21542 /* VTRN. Sizes 8 16 32. */
21d799b5
NC
21543 nUF(vtrn, _vtrn, 2, (RNDQ, RNDQ), neon_trn),
21544 nUF(vtrnq, _vtrn, 2, (RNQ, RNQ), neon_trn),
5287ad62
JB
21545
21546 /* Table lookup. Size 8. */
21547 NUF(vtbl, 1b00800, 3, (RND, NRDLST, RND), neon_tbl_tbx),
21548 NUF(vtbx, 1b00840, 3, (RND, NRDLST, RND), neon_tbl_tbx),
21549
c921be7d
NC
21550#undef THUMB_VARIANT
21551#define THUMB_VARIANT & fpu_vfp_v3_or_neon_ext
21552#undef ARM_VARIANT
21553#define ARM_VARIANT & fpu_vfp_v3_or_neon_ext
21554
5287ad62 21555 /* Neon element/structure load/store. */
21d799b5
NC
21556 nUF(vld1, _vld1, 2, (NSTRLST, ADDR), neon_ldx_stx),
21557 nUF(vst1, _vst1, 2, (NSTRLST, ADDR), neon_ldx_stx),
21558 nUF(vld2, _vld2, 2, (NSTRLST, ADDR), neon_ldx_stx),
21559 nUF(vst2, _vst2, 2, (NSTRLST, ADDR), neon_ldx_stx),
21560 nUF(vld3, _vld3, 2, (NSTRLST, ADDR), neon_ldx_stx),
21561 nUF(vst3, _vst3, 2, (NSTRLST, ADDR), neon_ldx_stx),
21562 nUF(vld4, _vld4, 2, (NSTRLST, ADDR), neon_ldx_stx),
21563 nUF(vst4, _vst4, 2, (NSTRLST, ADDR), neon_ldx_stx),
5287ad62 21564
c921be7d 21565#undef THUMB_VARIANT
74db7efb
NC
21566#define THUMB_VARIANT & fpu_vfp_ext_v3xd
21567#undef ARM_VARIANT
21568#define ARM_VARIANT & fpu_vfp_ext_v3xd
62f3b8c8
PB
21569 cCE("fconsts", eb00a00, 2, (RVS, I255), vfp_sp_const),
21570 cCE("fshtos", eba0a40, 2, (RVS, I16z), vfp_sp_conv_16),
21571 cCE("fsltos", eba0ac0, 2, (RVS, I32), vfp_sp_conv_32),
21572 cCE("fuhtos", ebb0a40, 2, (RVS, I16z), vfp_sp_conv_16),
21573 cCE("fultos", ebb0ac0, 2, (RVS, I32), vfp_sp_conv_32),
21574 cCE("ftoshs", ebe0a40, 2, (RVS, I16z), vfp_sp_conv_16),
21575 cCE("ftosls", ebe0ac0, 2, (RVS, I32), vfp_sp_conv_32),
21576 cCE("ftouhs", ebf0a40, 2, (RVS, I16z), vfp_sp_conv_16),
21577 cCE("ftouls", ebf0ac0, 2, (RVS, I32), vfp_sp_conv_32),
21578
74db7efb 21579#undef THUMB_VARIANT
c921be7d
NC
21580#define THUMB_VARIANT & fpu_vfp_ext_v3
21581#undef ARM_VARIANT
21582#define ARM_VARIANT & fpu_vfp_ext_v3
21583
21d799b5 21584 cCE("fconstd", eb00b00, 2, (RVD, I255), vfp_dp_const),
21d799b5 21585 cCE("fshtod", eba0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 21586 cCE("fsltod", eba0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 21587 cCE("fuhtod", ebb0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 21588 cCE("fultod", ebb0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 21589 cCE("ftoshd", ebe0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 21590 cCE("ftosld", ebe0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 21591 cCE("ftouhd", ebf0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 21592 cCE("ftould", ebf0bc0, 2, (RVD, I32), vfp_dp_conv_32),
c19d1205 21593
74db7efb
NC
21594#undef ARM_VARIANT
21595#define ARM_VARIANT & fpu_vfp_ext_fma
21596#undef THUMB_VARIANT
21597#define THUMB_VARIANT & fpu_vfp_ext_fma
62f3b8c8
PB
21598 /* Mnemonics shared by Neon and VFP. These are included in the
21599 VFP FMA variant; NEON and VFP FMA always includes the NEON
21600 FMA instructions. */
21601 nCEF(vfma, _vfma, 3, (RNSDQ, oRNSDQ, RNSDQ), neon_fmac),
21602 nCEF(vfms, _vfms, 3, (RNSDQ, oRNSDQ, RNSDQ), neon_fmac),
21603 /* ffmas/ffmad/ffmss/ffmsd are dummy mnemonics to satisfy gas;
21604 the v form should always be used. */
21605 cCE("ffmas", ea00a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21606 cCE("ffnmas", ea00a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21607 cCE("ffmad", ea00b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21608 cCE("ffnmad", ea00b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21609 nCE(vfnma, _vfnma, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
21610 nCE(vfnms, _vfnms, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
21611
5287ad62 21612#undef THUMB_VARIANT
c921be7d
NC
21613#undef ARM_VARIANT
21614#define ARM_VARIANT & arm_cext_xscale /* Intel XScale extensions. */
21615
21d799b5
NC
21616 cCE("mia", e200010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
21617 cCE("miaph", e280010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
21618 cCE("miabb", e2c0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
21619 cCE("miabt", e2d0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
21620 cCE("miatb", e2e0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
21621 cCE("miatt", e2f0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
21622 cCE("mar", c400000, 3, (RXA, RRnpc, RRnpc), xsc_mar),
21623 cCE("mra", c500000, 3, (RRnpc, RRnpc, RXA), xsc_mra),
c19d1205 21624
c921be7d
NC
21625#undef ARM_VARIANT
21626#define ARM_VARIANT & arm_cext_iwmmxt /* Intel Wireless MMX technology. */
21627
21d799b5
NC
21628 cCE("tandcb", e13f130, 1, (RR), iwmmxt_tandorc),
21629 cCE("tandch", e53f130, 1, (RR), iwmmxt_tandorc),
21630 cCE("tandcw", e93f130, 1, (RR), iwmmxt_tandorc),
21631 cCE("tbcstb", e400010, 2, (RIWR, RR), rn_rd),
21632 cCE("tbcsth", e400050, 2, (RIWR, RR), rn_rd),
21633 cCE("tbcstw", e400090, 2, (RIWR, RR), rn_rd),
21634 cCE("textrcb", e130170, 2, (RR, I7), iwmmxt_textrc),
21635 cCE("textrch", e530170, 2, (RR, I7), iwmmxt_textrc),
21636 cCE("textrcw", e930170, 2, (RR, I7), iwmmxt_textrc),
74db7efb
NC
21637 cCE("textrmub",e100070, 3, (RR, RIWR, I7), iwmmxt_textrm),
21638 cCE("textrmuh",e500070, 3, (RR, RIWR, I7), iwmmxt_textrm),
21639 cCE("textrmuw",e900070, 3, (RR, RIWR, I7), iwmmxt_textrm),
21640 cCE("textrmsb",e100078, 3, (RR, RIWR, I7), iwmmxt_textrm),
21641 cCE("textrmsh",e500078, 3, (RR, RIWR, I7), iwmmxt_textrm),
21642 cCE("textrmsw",e900078, 3, (RR, RIWR, I7), iwmmxt_textrm),
21d799b5
NC
21643 cCE("tinsrb", e600010, 3, (RIWR, RR, I7), iwmmxt_tinsr),
21644 cCE("tinsrh", e600050, 3, (RIWR, RR, I7), iwmmxt_tinsr),
21645 cCE("tinsrw", e600090, 3, (RIWR, RR, I7), iwmmxt_tinsr),
21646 cCE("tmcr", e000110, 2, (RIWC_RIWG, RR), rn_rd),
21647 cCE("tmcrr", c400000, 3, (RIWR, RR, RR), rm_rd_rn),
21648 cCE("tmia", e200010, 3, (RIWR, RR, RR), iwmmxt_tmia),
21649 cCE("tmiaph", e280010, 3, (RIWR, RR, RR), iwmmxt_tmia),
21650 cCE("tmiabb", e2c0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
21651 cCE("tmiabt", e2d0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
21652 cCE("tmiatb", e2e0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
21653 cCE("tmiatt", e2f0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
74db7efb
NC
21654 cCE("tmovmskb",e100030, 2, (RR, RIWR), rd_rn),
21655 cCE("tmovmskh",e500030, 2, (RR, RIWR), rd_rn),
21656 cCE("tmovmskw",e900030, 2, (RR, RIWR), rd_rn),
21d799b5
NC
21657 cCE("tmrc", e100110, 2, (RR, RIWC_RIWG), rd_rn),
21658 cCE("tmrrc", c500000, 3, (RR, RR, RIWR), rd_rn_rm),
21659 cCE("torcb", e13f150, 1, (RR), iwmmxt_tandorc),
21660 cCE("torch", e53f150, 1, (RR), iwmmxt_tandorc),
21661 cCE("torcw", e93f150, 1, (RR), iwmmxt_tandorc),
21662 cCE("waccb", e0001c0, 2, (RIWR, RIWR), rd_rn),
21663 cCE("wacch", e4001c0, 2, (RIWR, RIWR), rd_rn),
21664 cCE("waccw", e8001c0, 2, (RIWR, RIWR), rd_rn),
21665 cCE("waddbss", e300180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21666 cCE("waddb", e000180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21667 cCE("waddbus", e100180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21668 cCE("waddhss", e700180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21669 cCE("waddh", e400180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21670 cCE("waddhus", e500180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21671 cCE("waddwss", eb00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21672 cCE("waddw", e800180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21673 cCE("waddwus", e900180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21674 cCE("waligni", e000020, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_waligni),
74db7efb
NC
21675 cCE("walignr0",e800020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21676 cCE("walignr1",e900020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21677 cCE("walignr2",ea00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21678 cCE("walignr3",eb00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
21679 cCE("wand", e200000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21680 cCE("wandn", e300000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21681 cCE("wavg2b", e800000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21682 cCE("wavg2br", e900000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21683 cCE("wavg2h", ec00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21684 cCE("wavg2hr", ed00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21685 cCE("wcmpeqb", e000060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21686 cCE("wcmpeqh", e400060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21687 cCE("wcmpeqw", e800060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
21688 cCE("wcmpgtub",e100060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21689 cCE("wcmpgtuh",e500060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21690 cCE("wcmpgtuw",e900060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21691 cCE("wcmpgtsb",e300060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21692 cCE("wcmpgtsh",e700060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21693 cCE("wcmpgtsw",eb00060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
21694 cCE("wldrb", c100000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
21695 cCE("wldrh", c500000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
21696 cCE("wldrw", c100100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
21697 cCE("wldrd", c500100, 2, (RIWR, ADDR), iwmmxt_wldstd),
21698 cCE("wmacs", e600100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21699 cCE("wmacsz", e700100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21700 cCE("wmacu", e400100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21701 cCE("wmacuz", e500100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21702 cCE("wmadds", ea00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21703 cCE("wmaddu", e800100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21704 cCE("wmaxsb", e200160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21705 cCE("wmaxsh", e600160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21706 cCE("wmaxsw", ea00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21707 cCE("wmaxub", e000160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21708 cCE("wmaxuh", e400160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21709 cCE("wmaxuw", e800160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21710 cCE("wminsb", e300160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21711 cCE("wminsh", e700160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21712 cCE("wminsw", eb00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21713 cCE("wminub", e100160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21714 cCE("wminuh", e500160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21715 cCE("wminuw", e900160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21716 cCE("wmov", e000000, 2, (RIWR, RIWR), iwmmxt_wmov),
21717 cCE("wmulsm", e300100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21718 cCE("wmulsl", e200100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21719 cCE("wmulum", e100100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21720 cCE("wmulul", e000100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21721 cCE("wor", e000000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
21722 cCE("wpackhss",e700080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21723 cCE("wpackhus",e500080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21724 cCE("wpackwss",eb00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21725 cCE("wpackwus",e900080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21726 cCE("wpackdss",ef00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21727 cCE("wpackdus",ed00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
21728 cCE("wrorh", e700040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21729 cCE("wrorhg", e700148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21730 cCE("wrorw", eb00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21731 cCE("wrorwg", eb00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21732 cCE("wrord", ef00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21733 cCE("wrordg", ef00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21734 cCE("wsadb", e000120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21735 cCE("wsadbz", e100120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21736 cCE("wsadh", e400120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21737 cCE("wsadhz", e500120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21738 cCE("wshufh", e0001e0, 3, (RIWR, RIWR, I255), iwmmxt_wshufh),
21739 cCE("wsllh", e500040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21740 cCE("wsllhg", e500148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21741 cCE("wsllw", e900040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21742 cCE("wsllwg", e900148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21743 cCE("wslld", ed00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21744 cCE("wslldg", ed00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21745 cCE("wsrah", e400040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21746 cCE("wsrahg", e400148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21747 cCE("wsraw", e800040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21748 cCE("wsrawg", e800148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21749 cCE("wsrad", ec00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21750 cCE("wsradg", ec00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21751 cCE("wsrlh", e600040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21752 cCE("wsrlhg", e600148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21753 cCE("wsrlw", ea00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21754 cCE("wsrlwg", ea00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21755 cCE("wsrld", ee00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21756 cCE("wsrldg", ee00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21757 cCE("wstrb", c000000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
21758 cCE("wstrh", c400000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
21759 cCE("wstrw", c000100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
21760 cCE("wstrd", c400100, 2, (RIWR, ADDR), iwmmxt_wldstd),
21761 cCE("wsubbss", e3001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21762 cCE("wsubb", e0001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21763 cCE("wsubbus", e1001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21764 cCE("wsubhss", e7001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21765 cCE("wsubh", e4001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21766 cCE("wsubhus", e5001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21767 cCE("wsubwss", eb001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21768 cCE("wsubw", e8001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21769 cCE("wsubwus", e9001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21770 cCE("wunpckehub",e0000c0, 2, (RIWR, RIWR), rd_rn),
21771 cCE("wunpckehuh",e4000c0, 2, (RIWR, RIWR), rd_rn),
21772 cCE("wunpckehuw",e8000c0, 2, (RIWR, RIWR), rd_rn),
21773 cCE("wunpckehsb",e2000c0, 2, (RIWR, RIWR), rd_rn),
21774 cCE("wunpckehsh",e6000c0, 2, (RIWR, RIWR), rd_rn),
21775 cCE("wunpckehsw",ea000c0, 2, (RIWR, RIWR), rd_rn),
21776 cCE("wunpckihb", e1000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21777 cCE("wunpckihh", e5000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21778 cCE("wunpckihw", e9000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21779 cCE("wunpckelub",e0000e0, 2, (RIWR, RIWR), rd_rn),
21780 cCE("wunpckeluh",e4000e0, 2, (RIWR, RIWR), rd_rn),
21781 cCE("wunpckeluw",e8000e0, 2, (RIWR, RIWR), rd_rn),
21782 cCE("wunpckelsb",e2000e0, 2, (RIWR, RIWR), rd_rn),
21783 cCE("wunpckelsh",e6000e0, 2, (RIWR, RIWR), rd_rn),
21784 cCE("wunpckelsw",ea000e0, 2, (RIWR, RIWR), rd_rn),
21785 cCE("wunpckilb", e1000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21786 cCE("wunpckilh", e5000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21787 cCE("wunpckilw", e9000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21788 cCE("wxor", e100000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21789 cCE("wzero", e300000, 1, (RIWR), iwmmxt_wzero),
c19d1205 21790
c921be7d
NC
21791#undef ARM_VARIANT
21792#define ARM_VARIANT & arm_cext_iwmmxt2 /* Intel Wireless MMX technology, version 2. */
21793
21d799b5
NC
21794 cCE("torvscb", e12f190, 1, (RR), iwmmxt_tandorc),
21795 cCE("torvsch", e52f190, 1, (RR), iwmmxt_tandorc),
21796 cCE("torvscw", e92f190, 1, (RR), iwmmxt_tandorc),
21797 cCE("wabsb", e2001c0, 2, (RIWR, RIWR), rd_rn),
21798 cCE("wabsh", e6001c0, 2, (RIWR, RIWR), rd_rn),
21799 cCE("wabsw", ea001c0, 2, (RIWR, RIWR), rd_rn),
21800 cCE("wabsdiffb", e1001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21801 cCE("wabsdiffh", e5001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21802 cCE("wabsdiffw", e9001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21803 cCE("waddbhusl", e2001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21804 cCE("waddbhusm", e6001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21805 cCE("waddhc", e600180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21806 cCE("waddwc", ea00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21807 cCE("waddsubhx", ea001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21808 cCE("wavg4", e400000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21809 cCE("wavg4r", e500000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21810 cCE("wmaddsn", ee00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21811 cCE("wmaddsx", eb00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21812 cCE("wmaddun", ec00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21813 cCE("wmaddux", e900100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21814 cCE("wmerge", e000080, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_wmerge),
21815 cCE("wmiabb", e0000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21816 cCE("wmiabt", e1000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21817 cCE("wmiatb", e2000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21818 cCE("wmiatt", e3000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21819 cCE("wmiabbn", e4000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21820 cCE("wmiabtn", e5000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21821 cCE("wmiatbn", e6000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21822 cCE("wmiattn", e7000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21823 cCE("wmiawbb", e800120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21824 cCE("wmiawbt", e900120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21825 cCE("wmiawtb", ea00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21826 cCE("wmiawtt", eb00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21827 cCE("wmiawbbn", ec00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21828 cCE("wmiawbtn", ed00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21829 cCE("wmiawtbn", ee00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21830 cCE("wmiawttn", ef00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21831 cCE("wmulsmr", ef00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21832 cCE("wmulumr", ed00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21833 cCE("wmulwumr", ec000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21834 cCE("wmulwsmr", ee000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21835 cCE("wmulwum", ed000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21836 cCE("wmulwsm", ef000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21837 cCE("wmulwl", eb000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21838 cCE("wqmiabb", e8000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21839 cCE("wqmiabt", e9000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21840 cCE("wqmiatb", ea000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21841 cCE("wqmiatt", eb000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21842 cCE("wqmiabbn", ec000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21843 cCE("wqmiabtn", ed000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21844 cCE("wqmiatbn", ee000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21845 cCE("wqmiattn", ef000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21846 cCE("wqmulm", e100080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21847 cCE("wqmulmr", e300080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21848 cCE("wqmulwm", ec000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21849 cCE("wqmulwmr", ee000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21850 cCE("wsubaddhx", ed001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
2d447fca 21851
c921be7d
NC
21852#undef ARM_VARIANT
21853#define ARM_VARIANT & arm_cext_maverick /* Cirrus Maverick instructions. */
21854
21d799b5
NC
21855 cCE("cfldrs", c100400, 2, (RMF, ADDRGLDC), rd_cpaddr),
21856 cCE("cfldrd", c500400, 2, (RMD, ADDRGLDC), rd_cpaddr),
21857 cCE("cfldr32", c100500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
21858 cCE("cfldr64", c500500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
21859 cCE("cfstrs", c000400, 2, (RMF, ADDRGLDC), rd_cpaddr),
21860 cCE("cfstrd", c400400, 2, (RMD, ADDRGLDC), rd_cpaddr),
21861 cCE("cfstr32", c000500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
21862 cCE("cfstr64", c400500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
21863 cCE("cfmvsr", e000450, 2, (RMF, RR), rn_rd),
21864 cCE("cfmvrs", e100450, 2, (RR, RMF), rd_rn),
21865 cCE("cfmvdlr", e000410, 2, (RMD, RR), rn_rd),
21866 cCE("cfmvrdl", e100410, 2, (RR, RMD), rd_rn),
21867 cCE("cfmvdhr", e000430, 2, (RMD, RR), rn_rd),
21868 cCE("cfmvrdh", e100430, 2, (RR, RMD), rd_rn),
74db7efb
NC
21869 cCE("cfmv64lr",e000510, 2, (RMDX, RR), rn_rd),
21870 cCE("cfmvr64l",e100510, 2, (RR, RMDX), rd_rn),
21871 cCE("cfmv64hr",e000530, 2, (RMDX, RR), rn_rd),
21872 cCE("cfmvr64h",e100530, 2, (RR, RMDX), rd_rn),
21873 cCE("cfmval32",e200440, 2, (RMAX, RMFX), rd_rn),
21874 cCE("cfmv32al",e100440, 2, (RMFX, RMAX), rd_rn),
21875 cCE("cfmvam32",e200460, 2, (RMAX, RMFX), rd_rn),
21876 cCE("cfmv32am",e100460, 2, (RMFX, RMAX), rd_rn),
21877 cCE("cfmvah32",e200480, 2, (RMAX, RMFX), rd_rn),
21878 cCE("cfmv32ah",e100480, 2, (RMFX, RMAX), rd_rn),
21d799b5
NC
21879 cCE("cfmva32", e2004a0, 2, (RMAX, RMFX), rd_rn),
21880 cCE("cfmv32a", e1004a0, 2, (RMFX, RMAX), rd_rn),
21881 cCE("cfmva64", e2004c0, 2, (RMAX, RMDX), rd_rn),
21882 cCE("cfmv64a", e1004c0, 2, (RMDX, RMAX), rd_rn),
74db7efb
NC
21883 cCE("cfmvsc32",e2004e0, 2, (RMDS, RMDX), mav_dspsc),
21884 cCE("cfmv32sc",e1004e0, 2, (RMDX, RMDS), rd),
21d799b5
NC
21885 cCE("cfcpys", e000400, 2, (RMF, RMF), rd_rn),
21886 cCE("cfcpyd", e000420, 2, (RMD, RMD), rd_rn),
21887 cCE("cfcvtsd", e000460, 2, (RMD, RMF), rd_rn),
21888 cCE("cfcvtds", e000440, 2, (RMF, RMD), rd_rn),
74db7efb
NC
21889 cCE("cfcvt32s",e000480, 2, (RMF, RMFX), rd_rn),
21890 cCE("cfcvt32d",e0004a0, 2, (RMD, RMFX), rd_rn),
21891 cCE("cfcvt64s",e0004c0, 2, (RMF, RMDX), rd_rn),
21892 cCE("cfcvt64d",e0004e0, 2, (RMD, RMDX), rd_rn),
21893 cCE("cfcvts32",e100580, 2, (RMFX, RMF), rd_rn),
21894 cCE("cfcvtd32",e1005a0, 2, (RMFX, RMD), rd_rn),
21d799b5
NC
21895 cCE("cftruncs32",e1005c0, 2, (RMFX, RMF), rd_rn),
21896 cCE("cftruncd32",e1005e0, 2, (RMFX, RMD), rd_rn),
74db7efb
NC
21897 cCE("cfrshl32",e000550, 3, (RMFX, RMFX, RR), mav_triple),
21898 cCE("cfrshl64",e000570, 3, (RMDX, RMDX, RR), mav_triple),
21d799b5
NC
21899 cCE("cfsh32", e000500, 3, (RMFX, RMFX, I63s), mav_shift),
21900 cCE("cfsh64", e200500, 3, (RMDX, RMDX, I63s), mav_shift),
21901 cCE("cfcmps", e100490, 3, (RR, RMF, RMF), rd_rn_rm),
21902 cCE("cfcmpd", e1004b0, 3, (RR, RMD, RMD), rd_rn_rm),
21903 cCE("cfcmp32", e100590, 3, (RR, RMFX, RMFX), rd_rn_rm),
21904 cCE("cfcmp64", e1005b0, 3, (RR, RMDX, RMDX), rd_rn_rm),
21905 cCE("cfabss", e300400, 2, (RMF, RMF), rd_rn),
21906 cCE("cfabsd", e300420, 2, (RMD, RMD), rd_rn),
21907 cCE("cfnegs", e300440, 2, (RMF, RMF), rd_rn),
21908 cCE("cfnegd", e300460, 2, (RMD, RMD), rd_rn),
21909 cCE("cfadds", e300480, 3, (RMF, RMF, RMF), rd_rn_rm),
21910 cCE("cfaddd", e3004a0, 3, (RMD, RMD, RMD), rd_rn_rm),
21911 cCE("cfsubs", e3004c0, 3, (RMF, RMF, RMF), rd_rn_rm),
21912 cCE("cfsubd", e3004e0, 3, (RMD, RMD, RMD), rd_rn_rm),
21913 cCE("cfmuls", e100400, 3, (RMF, RMF, RMF), rd_rn_rm),
21914 cCE("cfmuld", e100420, 3, (RMD, RMD, RMD), rd_rn_rm),
21915 cCE("cfabs32", e300500, 2, (RMFX, RMFX), rd_rn),
21916 cCE("cfabs64", e300520, 2, (RMDX, RMDX), rd_rn),
21917 cCE("cfneg32", e300540, 2, (RMFX, RMFX), rd_rn),
21918 cCE("cfneg64", e300560, 2, (RMDX, RMDX), rd_rn),
21919 cCE("cfadd32", e300580, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
21920 cCE("cfadd64", e3005a0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
21921 cCE("cfsub32", e3005c0, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
21922 cCE("cfsub64", e3005e0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
21923 cCE("cfmul32", e100500, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
21924 cCE("cfmul64", e100520, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
21925 cCE("cfmac32", e100540, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
21926 cCE("cfmsc32", e100560, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
74db7efb
NC
21927 cCE("cfmadd32",e000600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
21928 cCE("cfmsub32",e100600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
21d799b5
NC
21929 cCE("cfmadda32", e200600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
21930 cCE("cfmsuba32", e300600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
4ed7ed8d 21931
7fadb25d
SD
21932 /* ARMv8.5-A instructions. */
21933#undef ARM_VARIANT
21934#define ARM_VARIANT & arm_ext_sb
21935#undef THUMB_VARIANT
21936#define THUMB_VARIANT & arm_ext_sb
21937 TUF("sb", 57ff070, f3bf8f70, 0, (), noargs, noargs),
21938
dad0c3bf
SD
21939#undef ARM_VARIANT
21940#define ARM_VARIANT & arm_ext_predres
21941#undef THUMB_VARIANT
21942#define THUMB_VARIANT & arm_ext_predres
21943 CE("cfprctx", e070f93, 1, (RRnpc), rd),
21944 CE("dvprctx", e070fb3, 1, (RRnpc), rd),
21945 CE("cpprctx", e070ff3, 1, (RRnpc), rd),
21946
16a1fa25 21947 /* ARMv8-M instructions. */
4ed7ed8d
TP
21948#undef ARM_VARIANT
21949#define ARM_VARIANT NULL
21950#undef THUMB_VARIANT
21951#define THUMB_VARIANT & arm_ext_v8m
cf3cf39d
TP
21952 ToU("sg", e97fe97f, 0, (), noargs),
21953 ToC("blxns", 4784, 1, (RRnpc), t_blx),
21954 ToC("bxns", 4704, 1, (RRnpc), t_bx),
21955 ToC("tt", e840f000, 2, (RRnpc, RRnpc), tt),
21956 ToC("ttt", e840f040, 2, (RRnpc, RRnpc), tt),
21957 ToC("tta", e840f080, 2, (RRnpc, RRnpc), tt),
21958 ToC("ttat", e840f0c0, 2, (RRnpc, RRnpc), tt),
16a1fa25
TP
21959
21960 /* FP for ARMv8-M Mainline. Enabled for ARMv8-M Mainline because the
21961 instructions behave as nop if no VFP is present. */
21962#undef THUMB_VARIANT
21963#define THUMB_VARIANT & arm_ext_v8m_main
cf3cf39d
TP
21964 ToC("vlldm", ec300a00, 1, (RRnpc), rn),
21965 ToC("vlstm", ec200a00, 1, (RRnpc), rn),
4389b29a
AV
21966
21967 /* Armv8.1-M Mainline instructions. */
21968#undef THUMB_VARIANT
21969#define THUMB_VARIANT & arm_ext_v8_1m_main
21970 toC("bf", _bf, 2, (EXPs, EXPs), t_branch_future),
f6b2b12d 21971 toU("bfcsel", _bfcsel, 4, (EXPs, EXPs, EXPs, COND), t_branch_future),
f1c7f421 21972 toC("bfx", _bfx, 2, (EXPs, RRnpcsp), t_branch_future),
65d1bc05 21973 toC("bfl", _bfl, 2, (EXPs, EXPs), t_branch_future),
f1c7f421 21974 toC("bflx", _bflx, 2, (EXPs, RRnpcsp), t_branch_future),
60f993ce
AV
21975
21976 toU("dls", _dls, 2, (LR, RRnpcsp), t_loloop),
21977 toU("wls", _wls, 3, (LR, RRnpcsp, EXP), t_loloop),
21978 toU("le", _le, 2, (oLR, EXP), t_loloop),
4b5a202f 21979
efd6b359
AV
21980 ToC("clrm", e89f0000, 1, (CLRMLST), t_clrm),
21981 ToC("vscclrm", ec9f0a00, 1, (VRSDVLST), t_vscclrm)
c19d1205
ZW
21982};
21983#undef ARM_VARIANT
21984#undef THUMB_VARIANT
21985#undef TCE
c19d1205
ZW
21986#undef TUE
21987#undef TUF
21988#undef TCC
8f06b2d8 21989#undef cCE
e3cb604e
PB
21990#undef cCL
21991#undef C3E
4389b29a 21992#undef C3
c19d1205
ZW
21993#undef CE
21994#undef CM
4389b29a 21995#undef CL
c19d1205
ZW
21996#undef UE
21997#undef UF
21998#undef UT
5287ad62
JB
21999#undef NUF
22000#undef nUF
22001#undef NCE
22002#undef nCE
c19d1205
ZW
22003#undef OPS0
22004#undef OPS1
22005#undef OPS2
22006#undef OPS3
22007#undef OPS4
22008#undef OPS5
22009#undef OPS6
22010#undef do_0
4389b29a
AV
22011#undef ToC
22012#undef toC
22013#undef ToU
f6b2b12d 22014#undef toU
c19d1205
ZW
22015\f
22016/* MD interface: bits in the object file. */
bfae80f2 22017
c19d1205
ZW
22018/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
22019 for use in the a.out file, and stores them in the array pointed to by buf.
22020 This knows about the endian-ness of the target machine and does
22021 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
22022 2 (short) and 4 (long) Floating numbers are put out as a series of
22023 LITTLENUMS (shorts, here at least). */
b99bd4ef 22024
c19d1205
ZW
22025void
22026md_number_to_chars (char * buf, valueT val, int n)
22027{
22028 if (target_big_endian)
22029 number_to_chars_bigendian (buf, val, n);
22030 else
22031 number_to_chars_littleendian (buf, val, n);
bfae80f2
RE
22032}
22033
c19d1205
ZW
22034static valueT
22035md_chars_to_number (char * buf, int n)
bfae80f2 22036{
c19d1205
ZW
22037 valueT result = 0;
22038 unsigned char * where = (unsigned char *) buf;
bfae80f2 22039
c19d1205 22040 if (target_big_endian)
b99bd4ef 22041 {
c19d1205
ZW
22042 while (n--)
22043 {
22044 result <<= 8;
22045 result |= (*where++ & 255);
22046 }
b99bd4ef 22047 }
c19d1205 22048 else
b99bd4ef 22049 {
c19d1205
ZW
22050 while (n--)
22051 {
22052 result <<= 8;
22053 result |= (where[n] & 255);
22054 }
bfae80f2 22055 }
b99bd4ef 22056
c19d1205 22057 return result;
bfae80f2 22058}
b99bd4ef 22059
c19d1205 22060/* MD interface: Sections. */
b99bd4ef 22061
fa94de6b
RM
22062/* Calculate the maximum variable size (i.e., excluding fr_fix)
22063 that an rs_machine_dependent frag may reach. */
22064
22065unsigned int
22066arm_frag_max_var (fragS *fragp)
22067{
22068 /* We only use rs_machine_dependent for variable-size Thumb instructions,
22069 which are either THUMB_SIZE (2) or INSN_SIZE (4).
22070
22071 Note that we generate relaxable instructions even for cases that don't
22072 really need it, like an immediate that's a trivial constant. So we're
22073 overestimating the instruction size for some of those cases. Rather
22074 than putting more intelligence here, it would probably be better to
22075 avoid generating a relaxation frag in the first place when it can be
22076 determined up front that a short instruction will suffice. */
22077
22078 gas_assert (fragp->fr_type == rs_machine_dependent);
22079 return INSN_SIZE;
22080}
22081
0110f2b8
PB
22082/* Estimate the size of a frag before relaxing. Assume everything fits in
22083 2 bytes. */
22084
c19d1205 22085int
0110f2b8 22086md_estimate_size_before_relax (fragS * fragp,
c19d1205
ZW
22087 segT segtype ATTRIBUTE_UNUSED)
22088{
0110f2b8
PB
22089 fragp->fr_var = 2;
22090 return 2;
22091}
22092
22093/* Convert a machine dependent frag. */
22094
22095void
22096md_convert_frag (bfd *abfd, segT asec ATTRIBUTE_UNUSED, fragS *fragp)
22097{
22098 unsigned long insn;
22099 unsigned long old_op;
22100 char *buf;
22101 expressionS exp;
22102 fixS *fixp;
22103 int reloc_type;
22104 int pc_rel;
22105 int opcode;
22106
22107 buf = fragp->fr_literal + fragp->fr_fix;
22108
22109 old_op = bfd_get_16(abfd, buf);
5f4273c7
NC
22110 if (fragp->fr_symbol)
22111 {
0110f2b8
PB
22112 exp.X_op = O_symbol;
22113 exp.X_add_symbol = fragp->fr_symbol;
5f4273c7
NC
22114 }
22115 else
22116 {
0110f2b8 22117 exp.X_op = O_constant;
5f4273c7 22118 }
0110f2b8
PB
22119 exp.X_add_number = fragp->fr_offset;
22120 opcode = fragp->fr_subtype;
22121 switch (opcode)
22122 {
22123 case T_MNEM_ldr_pc:
22124 case T_MNEM_ldr_pc2:
22125 case T_MNEM_ldr_sp:
22126 case T_MNEM_str_sp:
22127 case T_MNEM_ldr:
22128 case T_MNEM_ldrb:
22129 case T_MNEM_ldrh:
22130 case T_MNEM_str:
22131 case T_MNEM_strb:
22132 case T_MNEM_strh:
22133 if (fragp->fr_var == 4)
22134 {
5f4273c7 22135 insn = THUMB_OP32 (opcode);
0110f2b8
PB
22136 if ((old_op >> 12) == 4 || (old_op >> 12) == 9)
22137 {
22138 insn |= (old_op & 0x700) << 4;
22139 }
22140 else
22141 {
22142 insn |= (old_op & 7) << 12;
22143 insn |= (old_op & 0x38) << 13;
22144 }
22145 insn |= 0x00000c00;
22146 put_thumb32_insn (buf, insn);
22147 reloc_type = BFD_RELOC_ARM_T32_OFFSET_IMM;
22148 }
22149 else
22150 {
22151 reloc_type = BFD_RELOC_ARM_THUMB_OFFSET;
22152 }
22153 pc_rel = (opcode == T_MNEM_ldr_pc2);
22154 break;
22155 case T_MNEM_adr:
22156 if (fragp->fr_var == 4)
22157 {
22158 insn = THUMB_OP32 (opcode);
22159 insn |= (old_op & 0xf0) << 4;
22160 put_thumb32_insn (buf, insn);
22161 reloc_type = BFD_RELOC_ARM_T32_ADD_PC12;
22162 }
22163 else
22164 {
22165 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
22166 exp.X_add_number -= 4;
22167 }
22168 pc_rel = 1;
22169 break;
22170 case T_MNEM_mov:
22171 case T_MNEM_movs:
22172 case T_MNEM_cmp:
22173 case T_MNEM_cmn:
22174 if (fragp->fr_var == 4)
22175 {
22176 int r0off = (opcode == T_MNEM_mov
22177 || opcode == T_MNEM_movs) ? 0 : 8;
22178 insn = THUMB_OP32 (opcode);
22179 insn = (insn & 0xe1ffffff) | 0x10000000;
22180 insn |= (old_op & 0x700) << r0off;
22181 put_thumb32_insn (buf, insn);
22182 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
22183 }
22184 else
22185 {
22186 reloc_type = BFD_RELOC_ARM_THUMB_IMM;
22187 }
22188 pc_rel = 0;
22189 break;
22190 case T_MNEM_b:
22191 if (fragp->fr_var == 4)
22192 {
22193 insn = THUMB_OP32(opcode);
22194 put_thumb32_insn (buf, insn);
22195 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH25;
22196 }
22197 else
22198 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH12;
22199 pc_rel = 1;
22200 break;
22201 case T_MNEM_bcond:
22202 if (fragp->fr_var == 4)
22203 {
22204 insn = THUMB_OP32(opcode);
22205 insn |= (old_op & 0xf00) << 14;
22206 put_thumb32_insn (buf, insn);
22207 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH20;
22208 }
22209 else
22210 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH9;
22211 pc_rel = 1;
22212 break;
22213 case T_MNEM_add_sp:
22214 case T_MNEM_add_pc:
22215 case T_MNEM_inc_sp:
22216 case T_MNEM_dec_sp:
22217 if (fragp->fr_var == 4)
22218 {
22219 /* ??? Choose between add and addw. */
22220 insn = THUMB_OP32 (opcode);
22221 insn |= (old_op & 0xf0) << 4;
22222 put_thumb32_insn (buf, insn);
16805f35
PB
22223 if (opcode == T_MNEM_add_pc)
22224 reloc_type = BFD_RELOC_ARM_T32_IMM12;
22225 else
22226 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
0110f2b8
PB
22227 }
22228 else
22229 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
22230 pc_rel = 0;
22231 break;
22232
22233 case T_MNEM_addi:
22234 case T_MNEM_addis:
22235 case T_MNEM_subi:
22236 case T_MNEM_subis:
22237 if (fragp->fr_var == 4)
22238 {
22239 insn = THUMB_OP32 (opcode);
22240 insn |= (old_op & 0xf0) << 4;
22241 insn |= (old_op & 0xf) << 16;
22242 put_thumb32_insn (buf, insn);
16805f35
PB
22243 if (insn & (1 << 20))
22244 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
22245 else
22246 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8
PB
22247 }
22248 else
22249 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
22250 pc_rel = 0;
22251 break;
22252 default:
5f4273c7 22253 abort ();
0110f2b8
PB
22254 }
22255 fixp = fix_new_exp (fragp, fragp->fr_fix, fragp->fr_var, &exp, pc_rel,
21d799b5 22256 (enum bfd_reloc_code_real) reloc_type);
0110f2b8
PB
22257 fixp->fx_file = fragp->fr_file;
22258 fixp->fx_line = fragp->fr_line;
22259 fragp->fr_fix += fragp->fr_var;
3cfdb781
TG
22260
22261 /* Set whether we use thumb-2 ISA based on final relaxation results. */
22262 if (thumb_mode && fragp->fr_var == 4 && no_cpu_selected ()
22263 && !ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_t2))
22264 ARM_MERGE_FEATURE_SETS (arm_arch_used, thumb_arch_used, arm_ext_v6t2);
0110f2b8
PB
22265}
22266
22267/* Return the size of a relaxable immediate operand instruction.
22268 SHIFT and SIZE specify the form of the allowable immediate. */
22269static int
22270relax_immediate (fragS *fragp, int size, int shift)
22271{
22272 offsetT offset;
22273 offsetT mask;
22274 offsetT low;
22275
22276 /* ??? Should be able to do better than this. */
22277 if (fragp->fr_symbol)
22278 return 4;
22279
22280 low = (1 << shift) - 1;
22281 mask = (1 << (shift + size)) - (1 << shift);
22282 offset = fragp->fr_offset;
22283 /* Force misaligned offsets to 32-bit variant. */
22284 if (offset & low)
5e77afaa 22285 return 4;
0110f2b8
PB
22286 if (offset & ~mask)
22287 return 4;
22288 return 2;
22289}
22290
5e77afaa
PB
22291/* Get the address of a symbol during relaxation. */
22292static addressT
5f4273c7 22293relaxed_symbol_addr (fragS *fragp, long stretch)
5e77afaa
PB
22294{
22295 fragS *sym_frag;
22296 addressT addr;
22297 symbolS *sym;
22298
22299 sym = fragp->fr_symbol;
22300 sym_frag = symbol_get_frag (sym);
22301 know (S_GET_SEGMENT (sym) != absolute_section
22302 || sym_frag == &zero_address_frag);
22303 addr = S_GET_VALUE (sym) + fragp->fr_offset;
22304
22305 /* If frag has yet to be reached on this pass, assume it will
22306 move by STRETCH just as we did. If this is not so, it will
22307 be because some frag between grows, and that will force
22308 another pass. */
22309
22310 if (stretch != 0
22311 && sym_frag->relax_marker != fragp->relax_marker)
4396b686
PB
22312 {
22313 fragS *f;
22314
22315 /* Adjust stretch for any alignment frag. Note that if have
22316 been expanding the earlier code, the symbol may be
22317 defined in what appears to be an earlier frag. FIXME:
22318 This doesn't handle the fr_subtype field, which specifies
22319 a maximum number of bytes to skip when doing an
22320 alignment. */
22321 for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next)
22322 {
22323 if (f->fr_type == rs_align || f->fr_type == rs_align_code)
22324 {
22325 if (stretch < 0)
22326 stretch = - ((- stretch)
22327 & ~ ((1 << (int) f->fr_offset) - 1));
22328 else
22329 stretch &= ~ ((1 << (int) f->fr_offset) - 1);
22330 if (stretch == 0)
22331 break;
22332 }
22333 }
22334 if (f != NULL)
22335 addr += stretch;
22336 }
5e77afaa
PB
22337
22338 return addr;
22339}
22340
0110f2b8
PB
22341/* Return the size of a relaxable adr pseudo-instruction or PC-relative
22342 load. */
22343static int
5e77afaa 22344relax_adr (fragS *fragp, asection *sec, long stretch)
0110f2b8
PB
22345{
22346 addressT addr;
22347 offsetT val;
22348
22349 /* Assume worst case for symbols not known to be in the same section. */
974da60d
NC
22350 if (fragp->fr_symbol == NULL
22351 || !S_IS_DEFINED (fragp->fr_symbol)
77db8e2e
NC
22352 || sec != S_GET_SEGMENT (fragp->fr_symbol)
22353 || S_IS_WEAK (fragp->fr_symbol))
0110f2b8
PB
22354 return 4;
22355
5f4273c7 22356 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
22357 addr = fragp->fr_address + fragp->fr_fix;
22358 addr = (addr + 4) & ~3;
5e77afaa 22359 /* Force misaligned targets to 32-bit variant. */
0110f2b8 22360 if (val & 3)
5e77afaa 22361 return 4;
0110f2b8
PB
22362 val -= addr;
22363 if (val < 0 || val > 1020)
22364 return 4;
22365 return 2;
22366}
22367
22368/* Return the size of a relaxable add/sub immediate instruction. */
22369static int
22370relax_addsub (fragS *fragp, asection *sec)
22371{
22372 char *buf;
22373 int op;
22374
22375 buf = fragp->fr_literal + fragp->fr_fix;
22376 op = bfd_get_16(sec->owner, buf);
22377 if ((op & 0xf) == ((op >> 4) & 0xf))
22378 return relax_immediate (fragp, 8, 0);
22379 else
22380 return relax_immediate (fragp, 3, 0);
22381}
22382
e83a675f
RE
22383/* Return TRUE iff the definition of symbol S could be pre-empted
22384 (overridden) at link or load time. */
22385static bfd_boolean
22386symbol_preemptible (symbolS *s)
22387{
22388 /* Weak symbols can always be pre-empted. */
22389 if (S_IS_WEAK (s))
22390 return TRUE;
22391
22392 /* Non-global symbols cannot be pre-empted. */
22393 if (! S_IS_EXTERNAL (s))
22394 return FALSE;
22395
22396#ifdef OBJ_ELF
22397 /* In ELF, a global symbol can be marked protected, or private. In that
22398 case it can't be pre-empted (other definitions in the same link unit
22399 would violate the ODR). */
22400 if (ELF_ST_VISIBILITY (S_GET_OTHER (s)) > STV_DEFAULT)
22401 return FALSE;
22402#endif
22403
22404 /* Other global symbols might be pre-empted. */
22405 return TRUE;
22406}
0110f2b8
PB
22407
22408/* Return the size of a relaxable branch instruction. BITS is the
22409 size of the offset field in the narrow instruction. */
22410
22411static int
5e77afaa 22412relax_branch (fragS *fragp, asection *sec, int bits, long stretch)
0110f2b8
PB
22413{
22414 addressT addr;
22415 offsetT val;
22416 offsetT limit;
22417
22418 /* Assume worst case for symbols not known to be in the same section. */
5f4273c7 22419 if (!S_IS_DEFINED (fragp->fr_symbol)
77db8e2e
NC
22420 || sec != S_GET_SEGMENT (fragp->fr_symbol)
22421 || S_IS_WEAK (fragp->fr_symbol))
0110f2b8
PB
22422 return 4;
22423
267bf995 22424#ifdef OBJ_ELF
e83a675f 22425 /* A branch to a function in ARM state will require interworking. */
267bf995
RR
22426 if (S_IS_DEFINED (fragp->fr_symbol)
22427 && ARM_IS_FUNC (fragp->fr_symbol))
22428 return 4;
e83a675f 22429#endif
0d9b4b55 22430
e83a675f 22431 if (symbol_preemptible (fragp->fr_symbol))
0d9b4b55 22432 return 4;
267bf995 22433
5f4273c7 22434 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
22435 addr = fragp->fr_address + fragp->fr_fix + 4;
22436 val -= addr;
22437
22438 /* Offset is a signed value *2 */
22439 limit = 1 << bits;
22440 if (val >= limit || val < -limit)
22441 return 4;
22442 return 2;
22443}
22444
22445
22446/* Relax a machine dependent frag. This returns the amount by which
22447 the current size of the frag should change. */
22448
22449int
5e77afaa 22450arm_relax_frag (asection *sec, fragS *fragp, long stretch)
0110f2b8
PB
22451{
22452 int oldsize;
22453 int newsize;
22454
22455 oldsize = fragp->fr_var;
22456 switch (fragp->fr_subtype)
22457 {
22458 case T_MNEM_ldr_pc2:
5f4273c7 22459 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
22460 break;
22461 case T_MNEM_ldr_pc:
22462 case T_MNEM_ldr_sp:
22463 case T_MNEM_str_sp:
5f4273c7 22464 newsize = relax_immediate (fragp, 8, 2);
0110f2b8
PB
22465 break;
22466 case T_MNEM_ldr:
22467 case T_MNEM_str:
5f4273c7 22468 newsize = relax_immediate (fragp, 5, 2);
0110f2b8
PB
22469 break;
22470 case T_MNEM_ldrh:
22471 case T_MNEM_strh:
5f4273c7 22472 newsize = relax_immediate (fragp, 5, 1);
0110f2b8
PB
22473 break;
22474 case T_MNEM_ldrb:
22475 case T_MNEM_strb:
5f4273c7 22476 newsize = relax_immediate (fragp, 5, 0);
0110f2b8
PB
22477 break;
22478 case T_MNEM_adr:
5f4273c7 22479 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
22480 break;
22481 case T_MNEM_mov:
22482 case T_MNEM_movs:
22483 case T_MNEM_cmp:
22484 case T_MNEM_cmn:
5f4273c7 22485 newsize = relax_immediate (fragp, 8, 0);
0110f2b8
PB
22486 break;
22487 case T_MNEM_b:
5f4273c7 22488 newsize = relax_branch (fragp, sec, 11, stretch);
0110f2b8
PB
22489 break;
22490 case T_MNEM_bcond:
5f4273c7 22491 newsize = relax_branch (fragp, sec, 8, stretch);
0110f2b8
PB
22492 break;
22493 case T_MNEM_add_sp:
22494 case T_MNEM_add_pc:
22495 newsize = relax_immediate (fragp, 8, 2);
22496 break;
22497 case T_MNEM_inc_sp:
22498 case T_MNEM_dec_sp:
22499 newsize = relax_immediate (fragp, 7, 2);
22500 break;
22501 case T_MNEM_addi:
22502 case T_MNEM_addis:
22503 case T_MNEM_subi:
22504 case T_MNEM_subis:
22505 newsize = relax_addsub (fragp, sec);
22506 break;
22507 default:
5f4273c7 22508 abort ();
0110f2b8 22509 }
5e77afaa
PB
22510
22511 fragp->fr_var = newsize;
22512 /* Freeze wide instructions that are at or before the same location as
22513 in the previous pass. This avoids infinite loops.
5f4273c7
NC
22514 Don't freeze them unconditionally because targets may be artificially
22515 misaligned by the expansion of preceding frags. */
5e77afaa 22516 if (stretch <= 0 && newsize > 2)
0110f2b8 22517 {
0110f2b8 22518 md_convert_frag (sec->owner, sec, fragp);
5f4273c7 22519 frag_wane (fragp);
0110f2b8 22520 }
5e77afaa 22521
0110f2b8 22522 return newsize - oldsize;
c19d1205 22523}
b99bd4ef 22524
c19d1205 22525/* Round up a section size to the appropriate boundary. */
b99bd4ef 22526
c19d1205
ZW
22527valueT
22528md_section_align (segT segment ATTRIBUTE_UNUSED,
22529 valueT size)
22530{
6844c0cc 22531 return size;
bfae80f2 22532}
b99bd4ef 22533
c19d1205
ZW
22534/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
22535 of an rs_align_code fragment. */
22536
22537void
22538arm_handle_align (fragS * fragP)
bfae80f2 22539{
d9235011 22540 static unsigned char const arm_noop[2][2][4] =
e7495e45
NS
22541 {
22542 { /* ARMv1 */
22543 {0x00, 0x00, 0xa0, 0xe1}, /* LE */
22544 {0xe1, 0xa0, 0x00, 0x00}, /* BE */
22545 },
22546 { /* ARMv6k */
22547 {0x00, 0xf0, 0x20, 0xe3}, /* LE */
22548 {0xe3, 0x20, 0xf0, 0x00}, /* BE */
22549 },
22550 };
d9235011 22551 static unsigned char const thumb_noop[2][2][2] =
e7495e45
NS
22552 {
22553 { /* Thumb-1 */
22554 {0xc0, 0x46}, /* LE */
22555 {0x46, 0xc0}, /* BE */
22556 },
22557 { /* Thumb-2 */
22558 {0x00, 0xbf}, /* LE */
22559 {0xbf, 0x00} /* BE */
22560 }
22561 };
d9235011 22562 static unsigned char const wide_thumb_noop[2][4] =
e7495e45
NS
22563 { /* Wide Thumb-2 */
22564 {0xaf, 0xf3, 0x00, 0x80}, /* LE */
22565 {0xf3, 0xaf, 0x80, 0x00}, /* BE */
22566 };
c921be7d 22567
e7495e45 22568 unsigned bytes, fix, noop_size;
c19d1205 22569 char * p;
d9235011
TS
22570 const unsigned char * noop;
22571 const unsigned char *narrow_noop = NULL;
cd000bff
DJ
22572#ifdef OBJ_ELF
22573 enum mstate state;
22574#endif
bfae80f2 22575
c19d1205 22576 if (fragP->fr_type != rs_align_code)
bfae80f2
RE
22577 return;
22578
c19d1205
ZW
22579 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
22580 p = fragP->fr_literal + fragP->fr_fix;
22581 fix = 0;
bfae80f2 22582
c19d1205
ZW
22583 if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
22584 bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
bfae80f2 22585
cd000bff 22586 gas_assert ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) != 0);
8dc2430f 22587
cd000bff 22588 if (fragP->tc_frag_data.thumb_mode & (~ MODE_RECORDED))
a737bd4d 22589 {
7f78eb34
JW
22590 if (ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
22591 ? selected_cpu : arm_arch_none, arm_ext_v6t2))
e7495e45
NS
22592 {
22593 narrow_noop = thumb_noop[1][target_big_endian];
22594 noop = wide_thumb_noop[target_big_endian];
22595 }
c19d1205 22596 else
e7495e45
NS
22597 noop = thumb_noop[0][target_big_endian];
22598 noop_size = 2;
cd000bff
DJ
22599#ifdef OBJ_ELF
22600 state = MAP_THUMB;
22601#endif
7ed4c4c5
NC
22602 }
22603 else
22604 {
7f78eb34
JW
22605 noop = arm_noop[ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
22606 ? selected_cpu : arm_arch_none,
22607 arm_ext_v6k) != 0]
e7495e45
NS
22608 [target_big_endian];
22609 noop_size = 4;
cd000bff
DJ
22610#ifdef OBJ_ELF
22611 state = MAP_ARM;
22612#endif
7ed4c4c5 22613 }
c921be7d 22614
e7495e45 22615 fragP->fr_var = noop_size;
c921be7d 22616
c19d1205 22617 if (bytes & (noop_size - 1))
7ed4c4c5 22618 {
c19d1205 22619 fix = bytes & (noop_size - 1);
cd000bff
DJ
22620#ifdef OBJ_ELF
22621 insert_data_mapping_symbol (state, fragP->fr_fix, fragP, fix);
22622#endif
c19d1205
ZW
22623 memset (p, 0, fix);
22624 p += fix;
22625 bytes -= fix;
a737bd4d 22626 }
a737bd4d 22627
e7495e45
NS
22628 if (narrow_noop)
22629 {
22630 if (bytes & noop_size)
22631 {
22632 /* Insert a narrow noop. */
22633 memcpy (p, narrow_noop, noop_size);
22634 p += noop_size;
22635 bytes -= noop_size;
22636 fix += noop_size;
22637 }
22638
22639 /* Use wide noops for the remainder */
22640 noop_size = 4;
22641 }
22642
c19d1205 22643 while (bytes >= noop_size)
a737bd4d 22644 {
c19d1205
ZW
22645 memcpy (p, noop, noop_size);
22646 p += noop_size;
22647 bytes -= noop_size;
22648 fix += noop_size;
a737bd4d
NC
22649 }
22650
c19d1205 22651 fragP->fr_fix += fix;
a737bd4d
NC
22652}
22653
c19d1205
ZW
22654/* Called from md_do_align. Used to create an alignment
22655 frag in a code section. */
22656
22657void
22658arm_frag_align_code (int n, int max)
bfae80f2 22659{
c19d1205 22660 char * p;
7ed4c4c5 22661
c19d1205 22662 /* We assume that there will never be a requirement
6ec8e702 22663 to support alignments greater than MAX_MEM_FOR_RS_ALIGN_CODE bytes. */
c19d1205 22664 if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
6ec8e702
NC
22665 {
22666 char err_msg[128];
22667
fa94de6b 22668 sprintf (err_msg,
477330fc
RM
22669 _("alignments greater than %d bytes not supported in .text sections."),
22670 MAX_MEM_FOR_RS_ALIGN_CODE + 1);
20203fb9 22671 as_fatal ("%s", err_msg);
6ec8e702 22672 }
bfae80f2 22673
c19d1205
ZW
22674 p = frag_var (rs_align_code,
22675 MAX_MEM_FOR_RS_ALIGN_CODE,
22676 1,
22677 (relax_substateT) max,
22678 (symbolS *) NULL,
22679 (offsetT) n,
22680 (char *) NULL);
22681 *p = 0;
22682}
bfae80f2 22683
8dc2430f
NC
22684/* Perform target specific initialisation of a frag.
22685 Note - despite the name this initialisation is not done when the frag
22686 is created, but only when its type is assigned. A frag can be created
22687 and used a long time before its type is set, so beware of assuming that
33eaf5de 22688 this initialisation is performed first. */
bfae80f2 22689
cd000bff
DJ
22690#ifndef OBJ_ELF
22691void
22692arm_init_frag (fragS * fragP, int max_chars ATTRIBUTE_UNUSED)
22693{
22694 /* Record whether this frag is in an ARM or a THUMB area. */
2e98972e 22695 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
cd000bff
DJ
22696}
22697
22698#else /* OBJ_ELF is defined. */
c19d1205 22699void
cd000bff 22700arm_init_frag (fragS * fragP, int max_chars)
c19d1205 22701{
e8d84ca1 22702 bfd_boolean frag_thumb_mode;
b968d18a 22703
8dc2430f
NC
22704 /* If the current ARM vs THUMB mode has not already
22705 been recorded into this frag then do so now. */
cd000bff 22706 if ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) == 0)
b968d18a
JW
22707 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
22708
e8d84ca1
NC
22709 /* PR 21809: Do not set a mapping state for debug sections
22710 - it just confuses other tools. */
22711 if (bfd_get_section_flags (NULL, now_seg) & SEC_DEBUGGING)
22712 return;
22713
b968d18a 22714 frag_thumb_mode = fragP->tc_frag_data.thumb_mode ^ MODE_RECORDED;
cd000bff 22715
f9c1b181
RL
22716 /* Record a mapping symbol for alignment frags. We will delete this
22717 later if the alignment ends up empty. */
22718 switch (fragP->fr_type)
22719 {
22720 case rs_align:
22721 case rs_align_test:
22722 case rs_fill:
22723 mapping_state_2 (MAP_DATA, max_chars);
22724 break;
22725 case rs_align_code:
b968d18a 22726 mapping_state_2 (frag_thumb_mode ? MAP_THUMB : MAP_ARM, max_chars);
f9c1b181
RL
22727 break;
22728 default:
22729 break;
cd000bff 22730 }
bfae80f2
RE
22731}
22732
c19d1205
ZW
22733/* When we change sections we need to issue a new mapping symbol. */
22734
22735void
22736arm_elf_change_section (void)
bfae80f2 22737{
c19d1205
ZW
22738 /* Link an unlinked unwind index table section to the .text section. */
22739 if (elf_section_type (now_seg) == SHT_ARM_EXIDX
22740 && elf_linked_to_section (now_seg) == NULL)
22741 elf_linked_to_section (now_seg) = text_section;
bfae80f2
RE
22742}
22743
c19d1205
ZW
22744int
22745arm_elf_section_type (const char * str, size_t len)
e45d0630 22746{
c19d1205
ZW
22747 if (len == 5 && strncmp (str, "exidx", 5) == 0)
22748 return SHT_ARM_EXIDX;
e45d0630 22749
c19d1205
ZW
22750 return -1;
22751}
22752\f
22753/* Code to deal with unwinding tables. */
e45d0630 22754
c19d1205 22755static void add_unwind_adjustsp (offsetT);
e45d0630 22756
5f4273c7 22757/* Generate any deferred unwind frame offset. */
e45d0630 22758
bfae80f2 22759static void
c19d1205 22760flush_pending_unwind (void)
bfae80f2 22761{
c19d1205 22762 offsetT offset;
bfae80f2 22763
c19d1205
ZW
22764 offset = unwind.pending_offset;
22765 unwind.pending_offset = 0;
22766 if (offset != 0)
22767 add_unwind_adjustsp (offset);
bfae80f2
RE
22768}
22769
c19d1205
ZW
22770/* Add an opcode to this list for this function. Two-byte opcodes should
22771 be passed as op[0] << 8 | op[1]. The list of opcodes is built in reverse
22772 order. */
22773
bfae80f2 22774static void
c19d1205 22775add_unwind_opcode (valueT op, int length)
bfae80f2 22776{
c19d1205
ZW
22777 /* Add any deferred stack adjustment. */
22778 if (unwind.pending_offset)
22779 flush_pending_unwind ();
bfae80f2 22780
c19d1205 22781 unwind.sp_restored = 0;
bfae80f2 22782
c19d1205 22783 if (unwind.opcode_count + length > unwind.opcode_alloc)
bfae80f2 22784 {
c19d1205
ZW
22785 unwind.opcode_alloc += ARM_OPCODE_CHUNK_SIZE;
22786 if (unwind.opcodes)
325801bd
TS
22787 unwind.opcodes = XRESIZEVEC (unsigned char, unwind.opcodes,
22788 unwind.opcode_alloc);
c19d1205 22789 else
325801bd 22790 unwind.opcodes = XNEWVEC (unsigned char, unwind.opcode_alloc);
bfae80f2 22791 }
c19d1205 22792 while (length > 0)
bfae80f2 22793 {
c19d1205
ZW
22794 length--;
22795 unwind.opcodes[unwind.opcode_count] = op & 0xff;
22796 op >>= 8;
22797 unwind.opcode_count++;
bfae80f2 22798 }
bfae80f2
RE
22799}
22800
c19d1205
ZW
22801/* Add unwind opcodes to adjust the stack pointer. */
22802
bfae80f2 22803static void
c19d1205 22804add_unwind_adjustsp (offsetT offset)
bfae80f2 22805{
c19d1205 22806 valueT op;
bfae80f2 22807
c19d1205 22808 if (offset > 0x200)
bfae80f2 22809 {
c19d1205
ZW
22810 /* We need at most 5 bytes to hold a 32-bit value in a uleb128. */
22811 char bytes[5];
22812 int n;
22813 valueT o;
bfae80f2 22814
c19d1205
ZW
22815 /* Long form: 0xb2, uleb128. */
22816 /* This might not fit in a word so add the individual bytes,
22817 remembering the list is built in reverse order. */
22818 o = (valueT) ((offset - 0x204) >> 2);
22819 if (o == 0)
22820 add_unwind_opcode (0, 1);
bfae80f2 22821
c19d1205
ZW
22822 /* Calculate the uleb128 encoding of the offset. */
22823 n = 0;
22824 while (o)
22825 {
22826 bytes[n] = o & 0x7f;
22827 o >>= 7;
22828 if (o)
22829 bytes[n] |= 0x80;
22830 n++;
22831 }
22832 /* Add the insn. */
22833 for (; n; n--)
22834 add_unwind_opcode (bytes[n - 1], 1);
22835 add_unwind_opcode (0xb2, 1);
22836 }
22837 else if (offset > 0x100)
bfae80f2 22838 {
c19d1205
ZW
22839 /* Two short opcodes. */
22840 add_unwind_opcode (0x3f, 1);
22841 op = (offset - 0x104) >> 2;
22842 add_unwind_opcode (op, 1);
bfae80f2 22843 }
c19d1205
ZW
22844 else if (offset > 0)
22845 {
22846 /* Short opcode. */
22847 op = (offset - 4) >> 2;
22848 add_unwind_opcode (op, 1);
22849 }
22850 else if (offset < 0)
bfae80f2 22851 {
c19d1205
ZW
22852 offset = -offset;
22853 while (offset > 0x100)
bfae80f2 22854 {
c19d1205
ZW
22855 add_unwind_opcode (0x7f, 1);
22856 offset -= 0x100;
bfae80f2 22857 }
c19d1205
ZW
22858 op = ((offset - 4) >> 2) | 0x40;
22859 add_unwind_opcode (op, 1);
bfae80f2 22860 }
bfae80f2
RE
22861}
22862
c19d1205 22863/* Finish the list of unwind opcodes for this function. */
0198d5e6 22864
c19d1205
ZW
22865static void
22866finish_unwind_opcodes (void)
bfae80f2 22867{
c19d1205 22868 valueT op;
bfae80f2 22869
c19d1205 22870 if (unwind.fp_used)
bfae80f2 22871 {
708587a4 22872 /* Adjust sp as necessary. */
c19d1205
ZW
22873 unwind.pending_offset += unwind.fp_offset - unwind.frame_size;
22874 flush_pending_unwind ();
bfae80f2 22875
c19d1205
ZW
22876 /* After restoring sp from the frame pointer. */
22877 op = 0x90 | unwind.fp_reg;
22878 add_unwind_opcode (op, 1);
22879 }
22880 else
22881 flush_pending_unwind ();
bfae80f2
RE
22882}
22883
bfae80f2 22884
c19d1205
ZW
22885/* Start an exception table entry. If idx is nonzero this is an index table
22886 entry. */
bfae80f2
RE
22887
22888static void
c19d1205 22889start_unwind_section (const segT text_seg, int idx)
bfae80f2 22890{
c19d1205
ZW
22891 const char * text_name;
22892 const char * prefix;
22893 const char * prefix_once;
22894 const char * group_name;
c19d1205 22895 char * sec_name;
c19d1205
ZW
22896 int type;
22897 int flags;
22898 int linkonce;
bfae80f2 22899
c19d1205 22900 if (idx)
bfae80f2 22901 {
c19d1205
ZW
22902 prefix = ELF_STRING_ARM_unwind;
22903 prefix_once = ELF_STRING_ARM_unwind_once;
22904 type = SHT_ARM_EXIDX;
bfae80f2 22905 }
c19d1205 22906 else
bfae80f2 22907 {
c19d1205
ZW
22908 prefix = ELF_STRING_ARM_unwind_info;
22909 prefix_once = ELF_STRING_ARM_unwind_info_once;
22910 type = SHT_PROGBITS;
bfae80f2
RE
22911 }
22912
c19d1205
ZW
22913 text_name = segment_name (text_seg);
22914 if (streq (text_name, ".text"))
22915 text_name = "";
22916
22917 if (strncmp (text_name, ".gnu.linkonce.t.",
22918 strlen (".gnu.linkonce.t.")) == 0)
bfae80f2 22919 {
c19d1205
ZW
22920 prefix = prefix_once;
22921 text_name += strlen (".gnu.linkonce.t.");
bfae80f2
RE
22922 }
22923
29a2809e 22924 sec_name = concat (prefix, text_name, (char *) NULL);
bfae80f2 22925
c19d1205
ZW
22926 flags = SHF_ALLOC;
22927 linkonce = 0;
22928 group_name = 0;
bfae80f2 22929
c19d1205
ZW
22930 /* Handle COMDAT group. */
22931 if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
bfae80f2 22932 {
c19d1205
ZW
22933 group_name = elf_group_name (text_seg);
22934 if (group_name == NULL)
22935 {
bd3ba5d1 22936 as_bad (_("Group section `%s' has no group signature"),
c19d1205
ZW
22937 segment_name (text_seg));
22938 ignore_rest_of_line ();
22939 return;
22940 }
22941 flags |= SHF_GROUP;
22942 linkonce = 1;
bfae80f2
RE
22943 }
22944
a91e1603
L
22945 obj_elf_change_section (sec_name, type, 0, flags, 0, group_name,
22946 linkonce, 0);
bfae80f2 22947
5f4273c7 22948 /* Set the section link for index tables. */
c19d1205
ZW
22949 if (idx)
22950 elf_linked_to_section (now_seg) = text_seg;
bfae80f2
RE
22951}
22952
bfae80f2 22953
c19d1205
ZW
22954/* Start an unwind table entry. HAVE_DATA is nonzero if we have additional
22955 personality routine data. Returns zero, or the index table value for
cad0da33 22956 an inline entry. */
c19d1205
ZW
22957
22958static valueT
22959create_unwind_entry (int have_data)
bfae80f2 22960{
c19d1205
ZW
22961 int size;
22962 addressT where;
22963 char *ptr;
22964 /* The current word of data. */
22965 valueT data;
22966 /* The number of bytes left in this word. */
22967 int n;
bfae80f2 22968
c19d1205 22969 finish_unwind_opcodes ();
bfae80f2 22970
c19d1205
ZW
22971 /* Remember the current text section. */
22972 unwind.saved_seg = now_seg;
22973 unwind.saved_subseg = now_subseg;
bfae80f2 22974
c19d1205 22975 start_unwind_section (now_seg, 0);
bfae80f2 22976
c19d1205 22977 if (unwind.personality_routine == NULL)
bfae80f2 22978 {
c19d1205
ZW
22979 if (unwind.personality_index == -2)
22980 {
22981 if (have_data)
5f4273c7 22982 as_bad (_("handlerdata in cantunwind frame"));
c19d1205
ZW
22983 return 1; /* EXIDX_CANTUNWIND. */
22984 }
bfae80f2 22985
c19d1205
ZW
22986 /* Use a default personality routine if none is specified. */
22987 if (unwind.personality_index == -1)
22988 {
22989 if (unwind.opcode_count > 3)
22990 unwind.personality_index = 1;
22991 else
22992 unwind.personality_index = 0;
22993 }
bfae80f2 22994
c19d1205
ZW
22995 /* Space for the personality routine entry. */
22996 if (unwind.personality_index == 0)
22997 {
22998 if (unwind.opcode_count > 3)
22999 as_bad (_("too many unwind opcodes for personality routine 0"));
bfae80f2 23000
c19d1205
ZW
23001 if (!have_data)
23002 {
23003 /* All the data is inline in the index table. */
23004 data = 0x80;
23005 n = 3;
23006 while (unwind.opcode_count > 0)
23007 {
23008 unwind.opcode_count--;
23009 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
23010 n--;
23011 }
bfae80f2 23012
c19d1205
ZW
23013 /* Pad with "finish" opcodes. */
23014 while (n--)
23015 data = (data << 8) | 0xb0;
bfae80f2 23016
c19d1205
ZW
23017 return data;
23018 }
23019 size = 0;
23020 }
23021 else
23022 /* We get two opcodes "free" in the first word. */
23023 size = unwind.opcode_count - 2;
23024 }
23025 else
5011093d 23026 {
cad0da33
NC
23027 /* PR 16765: Missing or misplaced unwind directives can trigger this. */
23028 if (unwind.personality_index != -1)
23029 {
23030 as_bad (_("attempt to recreate an unwind entry"));
23031 return 1;
23032 }
5011093d
NC
23033
23034 /* An extra byte is required for the opcode count. */
23035 size = unwind.opcode_count + 1;
23036 }
bfae80f2 23037
c19d1205
ZW
23038 size = (size + 3) >> 2;
23039 if (size > 0xff)
23040 as_bad (_("too many unwind opcodes"));
bfae80f2 23041
c19d1205
ZW
23042 frag_align (2, 0, 0);
23043 record_alignment (now_seg, 2);
23044 unwind.table_entry = expr_build_dot ();
23045
23046 /* Allocate the table entry. */
23047 ptr = frag_more ((size << 2) + 4);
74929e7b
NC
23048 /* PR 13449: Zero the table entries in case some of them are not used. */
23049 memset (ptr, 0, (size << 2) + 4);
c19d1205 23050 where = frag_now_fix () - ((size << 2) + 4);
bfae80f2 23051
c19d1205 23052 switch (unwind.personality_index)
bfae80f2 23053 {
c19d1205
ZW
23054 case -1:
23055 /* ??? Should this be a PLT generating relocation? */
23056 /* Custom personality routine. */
23057 fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1,
23058 BFD_RELOC_ARM_PREL31);
bfae80f2 23059
c19d1205
ZW
23060 where += 4;
23061 ptr += 4;
bfae80f2 23062
c19d1205 23063 /* Set the first byte to the number of additional words. */
5011093d 23064 data = size > 0 ? size - 1 : 0;
c19d1205
ZW
23065 n = 3;
23066 break;
bfae80f2 23067
c19d1205
ZW
23068 /* ABI defined personality routines. */
23069 case 0:
23070 /* Three opcodes bytes are packed into the first word. */
23071 data = 0x80;
23072 n = 3;
23073 break;
bfae80f2 23074
c19d1205
ZW
23075 case 1:
23076 case 2:
23077 /* The size and first two opcode bytes go in the first word. */
23078 data = ((0x80 + unwind.personality_index) << 8) | size;
23079 n = 2;
23080 break;
bfae80f2 23081
c19d1205
ZW
23082 default:
23083 /* Should never happen. */
23084 abort ();
23085 }
bfae80f2 23086
c19d1205
ZW
23087 /* Pack the opcodes into words (MSB first), reversing the list at the same
23088 time. */
23089 while (unwind.opcode_count > 0)
23090 {
23091 if (n == 0)
23092 {
23093 md_number_to_chars (ptr, data, 4);
23094 ptr += 4;
23095 n = 4;
23096 data = 0;
23097 }
23098 unwind.opcode_count--;
23099 n--;
23100 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
23101 }
23102
23103 /* Finish off the last word. */
23104 if (n < 4)
23105 {
23106 /* Pad with "finish" opcodes. */
23107 while (n--)
23108 data = (data << 8) | 0xb0;
23109
23110 md_number_to_chars (ptr, data, 4);
23111 }
23112
23113 if (!have_data)
23114 {
23115 /* Add an empty descriptor if there is no user-specified data. */
23116 ptr = frag_more (4);
23117 md_number_to_chars (ptr, 0, 4);
23118 }
23119
23120 return 0;
bfae80f2
RE
23121}
23122
f0927246
NC
23123
23124/* Initialize the DWARF-2 unwind information for this procedure. */
23125
23126void
23127tc_arm_frame_initial_instructions (void)
23128{
23129 cfi_add_CFA_def_cfa (REG_SP, 0);
23130}
23131#endif /* OBJ_ELF */
23132
c19d1205
ZW
23133/* Convert REGNAME to a DWARF-2 register number. */
23134
23135int
1df69f4f 23136tc_arm_regname_to_dw2regnum (char *regname)
bfae80f2 23137{
1df69f4f 23138 int reg = arm_reg_parse (&regname, REG_TYPE_RN);
1f5afe1c
NC
23139 if (reg != FAIL)
23140 return reg;
c19d1205 23141
1f5afe1c
NC
23142 /* PR 16694: Allow VFP registers as well. */
23143 reg = arm_reg_parse (&regname, REG_TYPE_VFS);
23144 if (reg != FAIL)
23145 return 64 + reg;
c19d1205 23146
1f5afe1c
NC
23147 reg = arm_reg_parse (&regname, REG_TYPE_VFD);
23148 if (reg != FAIL)
23149 return reg + 256;
23150
0198d5e6 23151 return FAIL;
bfae80f2
RE
23152}
23153
f0927246 23154#ifdef TE_PE
c19d1205 23155void
f0927246 23156tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
bfae80f2 23157{
91d6fa6a 23158 expressionS exp;
bfae80f2 23159
91d6fa6a
NC
23160 exp.X_op = O_secrel;
23161 exp.X_add_symbol = symbol;
23162 exp.X_add_number = 0;
23163 emit_expr (&exp, size);
f0927246
NC
23164}
23165#endif
bfae80f2 23166
c19d1205 23167/* MD interface: Symbol and relocation handling. */
bfae80f2 23168
2fc8bdac
ZW
23169/* Return the address within the segment that a PC-relative fixup is
23170 relative to. For ARM, PC-relative fixups applied to instructions
23171 are generally relative to the location of the fixup plus 8 bytes.
23172 Thumb branches are offset by 4, and Thumb loads relative to PC
23173 require special handling. */
bfae80f2 23174
c19d1205 23175long
2fc8bdac 23176md_pcrel_from_section (fixS * fixP, segT seg)
bfae80f2 23177{
2fc8bdac
ZW
23178 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
23179
23180 /* If this is pc-relative and we are going to emit a relocation
23181 then we just want to put out any pipeline compensation that the linker
53baae48
NC
23182 will need. Otherwise we want to use the calculated base.
23183 For WinCE we skip the bias for externals as well, since this
23184 is how the MS ARM-CE assembler behaves and we want to be compatible. */
5f4273c7 23185 if (fixP->fx_pcrel
2fc8bdac 23186 && ((fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != seg)
53baae48
NC
23187 || (arm_force_relocation (fixP)
23188#ifdef TE_WINCE
23189 && !S_IS_EXTERNAL (fixP->fx_addsy)
23190#endif
23191 )))
2fc8bdac 23192 base = 0;
bfae80f2 23193
267bf995 23194
c19d1205 23195 switch (fixP->fx_r_type)
bfae80f2 23196 {
2fc8bdac
ZW
23197 /* PC relative addressing on the Thumb is slightly odd as the
23198 bottom two bits of the PC are forced to zero for the
23199 calculation. This happens *after* application of the
23200 pipeline offset. However, Thumb adrl already adjusts for
23201 this, so we need not do it again. */
c19d1205 23202 case BFD_RELOC_ARM_THUMB_ADD:
2fc8bdac 23203 return base & ~3;
c19d1205
ZW
23204
23205 case BFD_RELOC_ARM_THUMB_OFFSET:
23206 case BFD_RELOC_ARM_T32_OFFSET_IMM:
e9f89963 23207 case BFD_RELOC_ARM_T32_ADD_PC12:
8f06b2d8 23208 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
2fc8bdac 23209 return (base + 4) & ~3;
c19d1205 23210
2fc8bdac 23211 /* Thumb branches are simply offset by +4. */
e12437dc 23212 case BFD_RELOC_THUMB_PCREL_BRANCH5:
2fc8bdac
ZW
23213 case BFD_RELOC_THUMB_PCREL_BRANCH7:
23214 case BFD_RELOC_THUMB_PCREL_BRANCH9:
23215 case BFD_RELOC_THUMB_PCREL_BRANCH12:
23216 case BFD_RELOC_THUMB_PCREL_BRANCH20:
2fc8bdac 23217 case BFD_RELOC_THUMB_PCREL_BRANCH25:
f6b2b12d 23218 case BFD_RELOC_THUMB_PCREL_BFCSEL:
e5d6e09e 23219 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 23220 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 23221 case BFD_RELOC_ARM_THUMB_BF13:
60f993ce 23222 case BFD_RELOC_ARM_THUMB_LOOP12:
2fc8bdac 23223 return base + 4;
bfae80f2 23224
267bf995 23225 case BFD_RELOC_THUMB_PCREL_BRANCH23:
486499d0
CL
23226 if (fixP->fx_addsy
23227 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 23228 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995 23229 && ARM_IS_FUNC (fixP->fx_addsy)
477330fc
RM
23230 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
23231 base = fixP->fx_where + fixP->fx_frag->fr_address;
267bf995
RR
23232 return base + 4;
23233
00adf2d4
JB
23234 /* BLX is like branches above, but forces the low two bits of PC to
23235 zero. */
486499d0
CL
23236 case BFD_RELOC_THUMB_PCREL_BLX:
23237 if (fixP->fx_addsy
23238 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 23239 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
23240 && THUMB_IS_FUNC (fixP->fx_addsy)
23241 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
23242 base = fixP->fx_where + fixP->fx_frag->fr_address;
00adf2d4
JB
23243 return (base + 4) & ~3;
23244
2fc8bdac
ZW
23245 /* ARM mode branches are offset by +8. However, the Windows CE
23246 loader expects the relocation not to take this into account. */
267bf995 23247 case BFD_RELOC_ARM_PCREL_BLX:
486499d0
CL
23248 if (fixP->fx_addsy
23249 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 23250 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
23251 && ARM_IS_FUNC (fixP->fx_addsy)
23252 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
23253 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 23254 return base + 8;
267bf995 23255
486499d0
CL
23256 case BFD_RELOC_ARM_PCREL_CALL:
23257 if (fixP->fx_addsy
23258 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 23259 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
23260 && THUMB_IS_FUNC (fixP->fx_addsy)
23261 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
23262 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 23263 return base + 8;
267bf995 23264
2fc8bdac 23265 case BFD_RELOC_ARM_PCREL_BRANCH:
39b41c9c 23266 case BFD_RELOC_ARM_PCREL_JUMP:
2fc8bdac 23267 case BFD_RELOC_ARM_PLT32:
c19d1205 23268#ifdef TE_WINCE
5f4273c7 23269 /* When handling fixups immediately, because we have already
477330fc 23270 discovered the value of a symbol, or the address of the frag involved
53baae48 23271 we must account for the offset by +8, as the OS loader will never see the reloc.
477330fc
RM
23272 see fixup_segment() in write.c
23273 The S_IS_EXTERNAL test handles the case of global symbols.
23274 Those need the calculated base, not just the pipe compensation the linker will need. */
53baae48
NC
23275 if (fixP->fx_pcrel
23276 && fixP->fx_addsy != NULL
23277 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
23278 && (S_IS_EXTERNAL (fixP->fx_addsy) || !arm_force_relocation (fixP)))
23279 return base + 8;
2fc8bdac 23280 return base;
c19d1205 23281#else
2fc8bdac 23282 return base + 8;
c19d1205 23283#endif
2fc8bdac 23284
267bf995 23285
2fc8bdac
ZW
23286 /* ARM mode loads relative to PC are also offset by +8. Unlike
23287 branches, the Windows CE loader *does* expect the relocation
23288 to take this into account. */
23289 case BFD_RELOC_ARM_OFFSET_IMM:
23290 case BFD_RELOC_ARM_OFFSET_IMM8:
23291 case BFD_RELOC_ARM_HWLITERAL:
23292 case BFD_RELOC_ARM_LITERAL:
23293 case BFD_RELOC_ARM_CP_OFF_IMM:
23294 return base + 8;
23295
23296
23297 /* Other PC-relative relocations are un-offset. */
23298 default:
23299 return base;
23300 }
bfae80f2
RE
23301}
23302
8b2d793c
NC
23303static bfd_boolean flag_warn_syms = TRUE;
23304
ae8714c2
NC
23305bfd_boolean
23306arm_tc_equal_in_insn (int c ATTRIBUTE_UNUSED, char * name)
bfae80f2 23307{
8b2d793c
NC
23308 /* PR 18347 - Warn if the user attempts to create a symbol with the same
23309 name as an ARM instruction. Whilst strictly speaking it is allowed, it
23310 does mean that the resulting code might be very confusing to the reader.
23311 Also this warning can be triggered if the user omits an operand before
23312 an immediate address, eg:
23313
23314 LDR =foo
23315
23316 GAS treats this as an assignment of the value of the symbol foo to a
23317 symbol LDR, and so (without this code) it will not issue any kind of
23318 warning or error message.
23319
23320 Note - ARM instructions are case-insensitive but the strings in the hash
23321 table are all stored in lower case, so we must first ensure that name is
ae8714c2
NC
23322 lower case too. */
23323 if (flag_warn_syms && arm_ops_hsh)
8b2d793c
NC
23324 {
23325 char * nbuf = strdup (name);
23326 char * p;
23327
23328 for (p = nbuf; *p; p++)
23329 *p = TOLOWER (*p);
23330 if (hash_find (arm_ops_hsh, nbuf) != NULL)
23331 {
23332 static struct hash_control * already_warned = NULL;
23333
23334 if (already_warned == NULL)
23335 already_warned = hash_new ();
23336 /* Only warn about the symbol once. To keep the code
23337 simple we let hash_insert do the lookup for us. */
23338 if (hash_insert (already_warned, name, NULL) == NULL)
ae8714c2 23339 as_warn (_("[-mwarn-syms]: Assignment makes a symbol match an ARM instruction: %s"), name);
8b2d793c
NC
23340 }
23341 else
23342 free (nbuf);
23343 }
3739860c 23344
ae8714c2
NC
23345 return FALSE;
23346}
23347
23348/* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
23349 Otherwise we have no need to default values of symbols. */
23350
23351symbolS *
23352md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
23353{
23354#ifdef OBJ_ELF
23355 if (name[0] == '_' && name[1] == 'G'
23356 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
23357 {
23358 if (!GOT_symbol)
23359 {
23360 if (symbol_find (name))
23361 as_bad (_("GOT already in the symbol table"));
23362
23363 GOT_symbol = symbol_new (name, undefined_section,
23364 (valueT) 0, & zero_address_frag);
23365 }
23366
23367 return GOT_symbol;
23368 }
23369#endif
23370
c921be7d 23371 return NULL;
bfae80f2
RE
23372}
23373
55cf6793 23374/* Subroutine of md_apply_fix. Check to see if an immediate can be
c19d1205
ZW
23375 computed as two separate immediate values, added together. We
23376 already know that this value cannot be computed by just one ARM
23377 instruction. */
23378
23379static unsigned int
23380validate_immediate_twopart (unsigned int val,
23381 unsigned int * highpart)
bfae80f2 23382{
c19d1205
ZW
23383 unsigned int a;
23384 unsigned int i;
bfae80f2 23385
c19d1205
ZW
23386 for (i = 0; i < 32; i += 2)
23387 if (((a = rotate_left (val, i)) & 0xff) != 0)
23388 {
23389 if (a & 0xff00)
23390 {
23391 if (a & ~ 0xffff)
23392 continue;
23393 * highpart = (a >> 8) | ((i + 24) << 7);
23394 }
23395 else if (a & 0xff0000)
23396 {
23397 if (a & 0xff000000)
23398 continue;
23399 * highpart = (a >> 16) | ((i + 16) << 7);
23400 }
23401 else
23402 {
9c2799c2 23403 gas_assert (a & 0xff000000);
c19d1205
ZW
23404 * highpart = (a >> 24) | ((i + 8) << 7);
23405 }
bfae80f2 23406
c19d1205
ZW
23407 return (a & 0xff) | (i << 7);
23408 }
bfae80f2 23409
c19d1205 23410 return FAIL;
bfae80f2
RE
23411}
23412
c19d1205
ZW
23413static int
23414validate_offset_imm (unsigned int val, int hwse)
23415{
23416 if ((hwse && val > 255) || val > 4095)
23417 return FAIL;
23418 return val;
23419}
bfae80f2 23420
55cf6793 23421/* Subroutine of md_apply_fix. Do those data_ops which can take a
c19d1205
ZW
23422 negative immediate constant by altering the instruction. A bit of
23423 a hack really.
23424 MOV <-> MVN
23425 AND <-> BIC
23426 ADC <-> SBC
23427 by inverting the second operand, and
23428 ADD <-> SUB
23429 CMP <-> CMN
23430 by negating the second operand. */
bfae80f2 23431
c19d1205
ZW
23432static int
23433negate_data_op (unsigned long * instruction,
23434 unsigned long value)
bfae80f2 23435{
c19d1205
ZW
23436 int op, new_inst;
23437 unsigned long negated, inverted;
bfae80f2 23438
c19d1205
ZW
23439 negated = encode_arm_immediate (-value);
23440 inverted = encode_arm_immediate (~value);
bfae80f2 23441
c19d1205
ZW
23442 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
23443 switch (op)
bfae80f2 23444 {
c19d1205
ZW
23445 /* First negates. */
23446 case OPCODE_SUB: /* ADD <-> SUB */
23447 new_inst = OPCODE_ADD;
23448 value = negated;
23449 break;
bfae80f2 23450
c19d1205
ZW
23451 case OPCODE_ADD:
23452 new_inst = OPCODE_SUB;
23453 value = negated;
23454 break;
bfae80f2 23455
c19d1205
ZW
23456 case OPCODE_CMP: /* CMP <-> CMN */
23457 new_inst = OPCODE_CMN;
23458 value = negated;
23459 break;
bfae80f2 23460
c19d1205
ZW
23461 case OPCODE_CMN:
23462 new_inst = OPCODE_CMP;
23463 value = negated;
23464 break;
bfae80f2 23465
c19d1205
ZW
23466 /* Now Inverted ops. */
23467 case OPCODE_MOV: /* MOV <-> MVN */
23468 new_inst = OPCODE_MVN;
23469 value = inverted;
23470 break;
bfae80f2 23471
c19d1205
ZW
23472 case OPCODE_MVN:
23473 new_inst = OPCODE_MOV;
23474 value = inverted;
23475 break;
bfae80f2 23476
c19d1205
ZW
23477 case OPCODE_AND: /* AND <-> BIC */
23478 new_inst = OPCODE_BIC;
23479 value = inverted;
23480 break;
bfae80f2 23481
c19d1205
ZW
23482 case OPCODE_BIC:
23483 new_inst = OPCODE_AND;
23484 value = inverted;
23485 break;
bfae80f2 23486
c19d1205
ZW
23487 case OPCODE_ADC: /* ADC <-> SBC */
23488 new_inst = OPCODE_SBC;
23489 value = inverted;
23490 break;
bfae80f2 23491
c19d1205
ZW
23492 case OPCODE_SBC:
23493 new_inst = OPCODE_ADC;
23494 value = inverted;
23495 break;
bfae80f2 23496
c19d1205
ZW
23497 /* We cannot do anything. */
23498 default:
23499 return FAIL;
b99bd4ef
NC
23500 }
23501
c19d1205
ZW
23502 if (value == (unsigned) FAIL)
23503 return FAIL;
23504
23505 *instruction &= OPCODE_MASK;
23506 *instruction |= new_inst << DATA_OP_SHIFT;
23507 return value;
b99bd4ef
NC
23508}
23509
ef8d22e6
PB
23510/* Like negate_data_op, but for Thumb-2. */
23511
23512static unsigned int
16dd5e42 23513thumb32_negate_data_op (offsetT *instruction, unsigned int value)
ef8d22e6
PB
23514{
23515 int op, new_inst;
23516 int rd;
16dd5e42 23517 unsigned int negated, inverted;
ef8d22e6
PB
23518
23519 negated = encode_thumb32_immediate (-value);
23520 inverted = encode_thumb32_immediate (~value);
23521
23522 rd = (*instruction >> 8) & 0xf;
23523 op = (*instruction >> T2_DATA_OP_SHIFT) & 0xf;
23524 switch (op)
23525 {
23526 /* ADD <-> SUB. Includes CMP <-> CMN. */
23527 case T2_OPCODE_SUB:
23528 new_inst = T2_OPCODE_ADD;
23529 value = negated;
23530 break;
23531
23532 case T2_OPCODE_ADD:
23533 new_inst = T2_OPCODE_SUB;
23534 value = negated;
23535 break;
23536
23537 /* ORR <-> ORN. Includes MOV <-> MVN. */
23538 case T2_OPCODE_ORR:
23539 new_inst = T2_OPCODE_ORN;
23540 value = inverted;
23541 break;
23542
23543 case T2_OPCODE_ORN:
23544 new_inst = T2_OPCODE_ORR;
23545 value = inverted;
23546 break;
23547
23548 /* AND <-> BIC. TST has no inverted equivalent. */
23549 case T2_OPCODE_AND:
23550 new_inst = T2_OPCODE_BIC;
23551 if (rd == 15)
23552 value = FAIL;
23553 else
23554 value = inverted;
23555 break;
23556
23557 case T2_OPCODE_BIC:
23558 new_inst = T2_OPCODE_AND;
23559 value = inverted;
23560 break;
23561
23562 /* ADC <-> SBC */
23563 case T2_OPCODE_ADC:
23564 new_inst = T2_OPCODE_SBC;
23565 value = inverted;
23566 break;
23567
23568 case T2_OPCODE_SBC:
23569 new_inst = T2_OPCODE_ADC;
23570 value = inverted;
23571 break;
23572
23573 /* We cannot do anything. */
23574 default:
23575 return FAIL;
23576 }
23577
16dd5e42 23578 if (value == (unsigned int)FAIL)
ef8d22e6
PB
23579 return FAIL;
23580
23581 *instruction &= T2_OPCODE_MASK;
23582 *instruction |= new_inst << T2_DATA_OP_SHIFT;
23583 return value;
23584}
23585
8f06b2d8 23586/* Read a 32-bit thumb instruction from buf. */
0198d5e6 23587
8f06b2d8
PB
23588static unsigned long
23589get_thumb32_insn (char * buf)
23590{
23591 unsigned long insn;
23592 insn = md_chars_to_number (buf, THUMB_SIZE) << 16;
23593 insn |= md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
23594
23595 return insn;
23596}
23597
a8bc6c78
PB
23598/* We usually want to set the low bit on the address of thumb function
23599 symbols. In particular .word foo - . should have the low bit set.
23600 Generic code tries to fold the difference of two symbols to
23601 a constant. Prevent this and force a relocation when the first symbols
23602 is a thumb function. */
c921be7d
NC
23603
23604bfd_boolean
a8bc6c78
PB
23605arm_optimize_expr (expressionS *l, operatorT op, expressionS *r)
23606{
23607 if (op == O_subtract
23608 && l->X_op == O_symbol
23609 && r->X_op == O_symbol
23610 && THUMB_IS_FUNC (l->X_add_symbol))
23611 {
23612 l->X_op = O_subtract;
23613 l->X_op_symbol = r->X_add_symbol;
23614 l->X_add_number -= r->X_add_number;
c921be7d 23615 return TRUE;
a8bc6c78 23616 }
c921be7d 23617
a8bc6c78 23618 /* Process as normal. */
c921be7d 23619 return FALSE;
a8bc6c78
PB
23620}
23621
4a42ebbc
RR
23622/* Encode Thumb2 unconditional branches and calls. The encoding
23623 for the 2 are identical for the immediate values. */
23624
23625static void
23626encode_thumb2_b_bl_offset (char * buf, offsetT value)
23627{
23628#define T2I1I2MASK ((1 << 13) | (1 << 11))
23629 offsetT newval;
23630 offsetT newval2;
23631 addressT S, I1, I2, lo, hi;
23632
23633 S = (value >> 24) & 0x01;
23634 I1 = (value >> 23) & 0x01;
23635 I2 = (value >> 22) & 0x01;
23636 hi = (value >> 12) & 0x3ff;
fa94de6b 23637 lo = (value >> 1) & 0x7ff;
4a42ebbc
RR
23638 newval = md_chars_to_number (buf, THUMB_SIZE);
23639 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
23640 newval |= (S << 10) | hi;
23641 newval2 &= ~T2I1I2MASK;
23642 newval2 |= (((I1 ^ S) << 13) | ((I2 ^ S) << 11) | lo) ^ T2I1I2MASK;
23643 md_number_to_chars (buf, newval, THUMB_SIZE);
23644 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
23645}
23646
c19d1205 23647void
55cf6793 23648md_apply_fix (fixS * fixP,
c19d1205
ZW
23649 valueT * valP,
23650 segT seg)
23651{
23652 offsetT value = * valP;
23653 offsetT newval;
23654 unsigned int newimm;
23655 unsigned long temp;
23656 int sign;
23657 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
b99bd4ef 23658
9c2799c2 23659 gas_assert (fixP->fx_r_type <= BFD_RELOC_UNUSED);
b99bd4ef 23660
c19d1205 23661 /* Note whether this will delete the relocation. */
4962c51a 23662
c19d1205
ZW
23663 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
23664 fixP->fx_done = 1;
b99bd4ef 23665
adbaf948 23666 /* On a 64-bit host, silently truncate 'value' to 32 bits for
5f4273c7 23667 consistency with the behaviour on 32-bit hosts. Remember value
adbaf948
ZW
23668 for emit_reloc. */
23669 value &= 0xffffffff;
23670 value ^= 0x80000000;
5f4273c7 23671 value -= 0x80000000;
adbaf948
ZW
23672
23673 *valP = value;
c19d1205 23674 fixP->fx_addnumber = value;
b99bd4ef 23675
adbaf948
ZW
23676 /* Same treatment for fixP->fx_offset. */
23677 fixP->fx_offset &= 0xffffffff;
23678 fixP->fx_offset ^= 0x80000000;
23679 fixP->fx_offset -= 0x80000000;
23680
c19d1205 23681 switch (fixP->fx_r_type)
b99bd4ef 23682 {
c19d1205
ZW
23683 case BFD_RELOC_NONE:
23684 /* This will need to go in the object file. */
23685 fixP->fx_done = 0;
23686 break;
b99bd4ef 23687
c19d1205
ZW
23688 case BFD_RELOC_ARM_IMMEDIATE:
23689 /* We claim that this fixup has been processed here,
23690 even if in fact we generate an error because we do
23691 not have a reloc for it, so tc_gen_reloc will reject it. */
23692 fixP->fx_done = 1;
b99bd4ef 23693
77db8e2e 23694 if (fixP->fx_addsy)
b99bd4ef 23695 {
77db8e2e 23696 const char *msg = 0;
b99bd4ef 23697
77db8e2e
NC
23698 if (! S_IS_DEFINED (fixP->fx_addsy))
23699 msg = _("undefined symbol %s used as an immediate value");
23700 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
23701 msg = _("symbol %s is in a different section");
23702 else if (S_IS_WEAK (fixP->fx_addsy))
23703 msg = _("symbol %s is weak and may be overridden later");
23704
23705 if (msg)
23706 {
23707 as_bad_where (fixP->fx_file, fixP->fx_line,
23708 msg, S_GET_NAME (fixP->fx_addsy));
23709 break;
23710 }
42e5fcbf
AS
23711 }
23712
c19d1205
ZW
23713 temp = md_chars_to_number (buf, INSN_SIZE);
23714
5e73442d
SL
23715 /* If the offset is negative, we should use encoding A2 for ADR. */
23716 if ((temp & 0xfff0000) == 0x28f0000 && value < 0)
23717 newimm = negate_data_op (&temp, value);
23718 else
23719 {
23720 newimm = encode_arm_immediate (value);
23721
23722 /* If the instruction will fail, see if we can fix things up by
23723 changing the opcode. */
23724 if (newimm == (unsigned int) FAIL)
23725 newimm = negate_data_op (&temp, value);
bada4342
JW
23726 /* MOV accepts both ARM modified immediate (A1 encoding) and
23727 UINT16 (A2 encoding) when possible, MOVW only accepts UINT16.
23728 When disassembling, MOV is preferred when there is no encoding
23729 overlap. */
23730 if (newimm == (unsigned int) FAIL
23731 && ((temp >> DATA_OP_SHIFT) & 0xf) == OPCODE_MOV
23732 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
23733 && !((temp >> SBIT_SHIFT) & 0x1)
23734 && value >= 0 && value <= 0xffff)
23735 {
23736 /* Clear bits[23:20] to change encoding from A1 to A2. */
23737 temp &= 0xff0fffff;
23738 /* Encoding high 4bits imm. Code below will encode the remaining
23739 low 12bits. */
23740 temp |= (value & 0x0000f000) << 4;
23741 newimm = value & 0x00000fff;
23742 }
5e73442d
SL
23743 }
23744
23745 if (newimm == (unsigned int) FAIL)
b99bd4ef 23746 {
c19d1205
ZW
23747 as_bad_where (fixP->fx_file, fixP->fx_line,
23748 _("invalid constant (%lx) after fixup"),
23749 (unsigned long) value);
23750 break;
b99bd4ef 23751 }
b99bd4ef 23752
c19d1205
ZW
23753 newimm |= (temp & 0xfffff000);
23754 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
23755 break;
b99bd4ef 23756
c19d1205
ZW
23757 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
23758 {
23759 unsigned int highpart = 0;
23760 unsigned int newinsn = 0xe1a00000; /* nop. */
b99bd4ef 23761
77db8e2e 23762 if (fixP->fx_addsy)
42e5fcbf 23763 {
77db8e2e 23764 const char *msg = 0;
42e5fcbf 23765
77db8e2e
NC
23766 if (! S_IS_DEFINED (fixP->fx_addsy))
23767 msg = _("undefined symbol %s used as an immediate value");
23768 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
23769 msg = _("symbol %s is in a different section");
23770 else if (S_IS_WEAK (fixP->fx_addsy))
23771 msg = _("symbol %s is weak and may be overridden later");
42e5fcbf 23772
77db8e2e
NC
23773 if (msg)
23774 {
23775 as_bad_where (fixP->fx_file, fixP->fx_line,
23776 msg, S_GET_NAME (fixP->fx_addsy));
23777 break;
23778 }
23779 }
fa94de6b 23780
c19d1205
ZW
23781 newimm = encode_arm_immediate (value);
23782 temp = md_chars_to_number (buf, INSN_SIZE);
b99bd4ef 23783
c19d1205
ZW
23784 /* If the instruction will fail, see if we can fix things up by
23785 changing the opcode. */
23786 if (newimm == (unsigned int) FAIL
23787 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
23788 {
23789 /* No ? OK - try using two ADD instructions to generate
23790 the value. */
23791 newimm = validate_immediate_twopart (value, & highpart);
b99bd4ef 23792
c19d1205
ZW
23793 /* Yes - then make sure that the second instruction is
23794 also an add. */
23795 if (newimm != (unsigned int) FAIL)
23796 newinsn = temp;
23797 /* Still No ? Try using a negated value. */
23798 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
23799 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
23800 /* Otherwise - give up. */
23801 else
23802 {
23803 as_bad_where (fixP->fx_file, fixP->fx_line,
23804 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
23805 (long) value);
23806 break;
23807 }
b99bd4ef 23808
c19d1205
ZW
23809 /* Replace the first operand in the 2nd instruction (which
23810 is the PC) with the destination register. We have
23811 already added in the PC in the first instruction and we
23812 do not want to do it again. */
23813 newinsn &= ~ 0xf0000;
23814 newinsn |= ((newinsn & 0x0f000) << 4);
23815 }
b99bd4ef 23816
c19d1205
ZW
23817 newimm |= (temp & 0xfffff000);
23818 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
b99bd4ef 23819
c19d1205
ZW
23820 highpart |= (newinsn & 0xfffff000);
23821 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
23822 }
23823 break;
b99bd4ef 23824
c19d1205 23825 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
23826 if (!fixP->fx_done && seg->use_rela_p)
23827 value = 0;
1a0670f3 23828 /* Fall through. */
00a97672 23829
c19d1205 23830 case BFD_RELOC_ARM_LITERAL:
26d97720 23831 sign = value > 0;
b99bd4ef 23832
c19d1205
ZW
23833 if (value < 0)
23834 value = - value;
b99bd4ef 23835
c19d1205 23836 if (validate_offset_imm (value, 0) == FAIL)
f03698e6 23837 {
c19d1205
ZW
23838 if (fixP->fx_r_type == BFD_RELOC_ARM_LITERAL)
23839 as_bad_where (fixP->fx_file, fixP->fx_line,
23840 _("invalid literal constant: pool needs to be closer"));
23841 else
23842 as_bad_where (fixP->fx_file, fixP->fx_line,
23843 _("bad immediate value for offset (%ld)"),
23844 (long) value);
23845 break;
f03698e6
RE
23846 }
23847
c19d1205 23848 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
23849 if (value == 0)
23850 newval &= 0xfffff000;
23851 else
23852 {
23853 newval &= 0xff7ff000;
23854 newval |= value | (sign ? INDEX_UP : 0);
23855 }
c19d1205
ZW
23856 md_number_to_chars (buf, newval, INSN_SIZE);
23857 break;
b99bd4ef 23858
c19d1205
ZW
23859 case BFD_RELOC_ARM_OFFSET_IMM8:
23860 case BFD_RELOC_ARM_HWLITERAL:
26d97720 23861 sign = value > 0;
b99bd4ef 23862
c19d1205
ZW
23863 if (value < 0)
23864 value = - value;
b99bd4ef 23865
c19d1205 23866 if (validate_offset_imm (value, 1) == FAIL)
b99bd4ef 23867 {
c19d1205
ZW
23868 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
23869 as_bad_where (fixP->fx_file, fixP->fx_line,
23870 _("invalid literal constant: pool needs to be closer"));
23871 else
427d0db6
RM
23872 as_bad_where (fixP->fx_file, fixP->fx_line,
23873 _("bad immediate value for 8-bit offset (%ld)"),
23874 (long) value);
c19d1205 23875 break;
b99bd4ef
NC
23876 }
23877
c19d1205 23878 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
23879 if (value == 0)
23880 newval &= 0xfffff0f0;
23881 else
23882 {
23883 newval &= 0xff7ff0f0;
23884 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
23885 }
c19d1205
ZW
23886 md_number_to_chars (buf, newval, INSN_SIZE);
23887 break;
b99bd4ef 23888
c19d1205
ZW
23889 case BFD_RELOC_ARM_T32_OFFSET_U8:
23890 if (value < 0 || value > 1020 || value % 4 != 0)
23891 as_bad_where (fixP->fx_file, fixP->fx_line,
23892 _("bad immediate value for offset (%ld)"), (long) value);
23893 value /= 4;
b99bd4ef 23894
c19d1205 23895 newval = md_chars_to_number (buf+2, THUMB_SIZE);
c19d1205
ZW
23896 newval |= value;
23897 md_number_to_chars (buf+2, newval, THUMB_SIZE);
23898 break;
b99bd4ef 23899
c19d1205
ZW
23900 case BFD_RELOC_ARM_T32_OFFSET_IMM:
23901 /* This is a complicated relocation used for all varieties of Thumb32
23902 load/store instruction with immediate offset:
23903
23904 1110 100P u1WL NNNN XXXX YYYY iiii iiii - +/-(U) pre/post(P) 8-bit,
477330fc 23905 *4, optional writeback(W)
c19d1205
ZW
23906 (doubleword load/store)
23907
23908 1111 100S uTTL 1111 XXXX iiii iiii iiii - +/-(U) 12-bit PC-rel
23909 1111 100S 0TTL NNNN XXXX 1Pu1 iiii iiii - +/-(U) pre/post(P) 8-bit
23910 1111 100S 0TTL NNNN XXXX 1110 iiii iiii - positive 8-bit (T instruction)
23911 1111 100S 1TTL NNNN XXXX iiii iiii iiii - positive 12-bit
23912 1111 100S 0TTL NNNN XXXX 1100 iiii iiii - negative 8-bit
23913
23914 Uppercase letters indicate bits that are already encoded at
23915 this point. Lowercase letters are our problem. For the
23916 second block of instructions, the secondary opcode nybble
23917 (bits 8..11) is present, and bit 23 is zero, even if this is
23918 a PC-relative operation. */
23919 newval = md_chars_to_number (buf, THUMB_SIZE);
23920 newval <<= 16;
23921 newval |= md_chars_to_number (buf+THUMB_SIZE, THUMB_SIZE);
b99bd4ef 23922
c19d1205 23923 if ((newval & 0xf0000000) == 0xe0000000)
b99bd4ef 23924 {
c19d1205
ZW
23925 /* Doubleword load/store: 8-bit offset, scaled by 4. */
23926 if (value >= 0)
23927 newval |= (1 << 23);
23928 else
23929 value = -value;
23930 if (value % 4 != 0)
23931 {
23932 as_bad_where (fixP->fx_file, fixP->fx_line,
23933 _("offset not a multiple of 4"));
23934 break;
23935 }
23936 value /= 4;
216d22bc 23937 if (value > 0xff)
c19d1205
ZW
23938 {
23939 as_bad_where (fixP->fx_file, fixP->fx_line,
23940 _("offset out of range"));
23941 break;
23942 }
23943 newval &= ~0xff;
b99bd4ef 23944 }
c19d1205 23945 else if ((newval & 0x000f0000) == 0x000f0000)
b99bd4ef 23946 {
c19d1205
ZW
23947 /* PC-relative, 12-bit offset. */
23948 if (value >= 0)
23949 newval |= (1 << 23);
23950 else
23951 value = -value;
216d22bc 23952 if (value > 0xfff)
c19d1205
ZW
23953 {
23954 as_bad_where (fixP->fx_file, fixP->fx_line,
23955 _("offset out of range"));
23956 break;
23957 }
23958 newval &= ~0xfff;
b99bd4ef 23959 }
c19d1205 23960 else if ((newval & 0x00000100) == 0x00000100)
b99bd4ef 23961 {
c19d1205
ZW
23962 /* Writeback: 8-bit, +/- offset. */
23963 if (value >= 0)
23964 newval |= (1 << 9);
23965 else
23966 value = -value;
216d22bc 23967 if (value > 0xff)
c19d1205
ZW
23968 {
23969 as_bad_where (fixP->fx_file, fixP->fx_line,
23970 _("offset out of range"));
23971 break;
23972 }
23973 newval &= ~0xff;
b99bd4ef 23974 }
c19d1205 23975 else if ((newval & 0x00000f00) == 0x00000e00)
b99bd4ef 23976 {
c19d1205 23977 /* T-instruction: positive 8-bit offset. */
216d22bc 23978 if (value < 0 || value > 0xff)
b99bd4ef 23979 {
c19d1205
ZW
23980 as_bad_where (fixP->fx_file, fixP->fx_line,
23981 _("offset out of range"));
23982 break;
b99bd4ef 23983 }
c19d1205
ZW
23984 newval &= ~0xff;
23985 newval |= value;
b99bd4ef
NC
23986 }
23987 else
b99bd4ef 23988 {
c19d1205
ZW
23989 /* Positive 12-bit or negative 8-bit offset. */
23990 int limit;
23991 if (value >= 0)
b99bd4ef 23992 {
c19d1205
ZW
23993 newval |= (1 << 23);
23994 limit = 0xfff;
23995 }
23996 else
23997 {
23998 value = -value;
23999 limit = 0xff;
24000 }
24001 if (value > limit)
24002 {
24003 as_bad_where (fixP->fx_file, fixP->fx_line,
24004 _("offset out of range"));
24005 break;
b99bd4ef 24006 }
c19d1205 24007 newval &= ~limit;
b99bd4ef 24008 }
b99bd4ef 24009
c19d1205
ZW
24010 newval |= value;
24011 md_number_to_chars (buf, (newval >> 16) & 0xffff, THUMB_SIZE);
24012 md_number_to_chars (buf + THUMB_SIZE, newval & 0xffff, THUMB_SIZE);
24013 break;
404ff6b5 24014
c19d1205
ZW
24015 case BFD_RELOC_ARM_SHIFT_IMM:
24016 newval = md_chars_to_number (buf, INSN_SIZE);
24017 if (((unsigned long) value) > 32
24018 || (value == 32
24019 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
24020 {
24021 as_bad_where (fixP->fx_file, fixP->fx_line,
24022 _("shift expression is too large"));
24023 break;
24024 }
404ff6b5 24025
c19d1205
ZW
24026 if (value == 0)
24027 /* Shifts of zero must be done as lsl. */
24028 newval &= ~0x60;
24029 else if (value == 32)
24030 value = 0;
24031 newval &= 0xfffff07f;
24032 newval |= (value & 0x1f) << 7;
24033 md_number_to_chars (buf, newval, INSN_SIZE);
24034 break;
404ff6b5 24035
c19d1205 24036 case BFD_RELOC_ARM_T32_IMMEDIATE:
16805f35 24037 case BFD_RELOC_ARM_T32_ADD_IMM:
92e90b6e 24038 case BFD_RELOC_ARM_T32_IMM12:
e9f89963 24039 case BFD_RELOC_ARM_T32_ADD_PC12:
c19d1205
ZW
24040 /* We claim that this fixup has been processed here,
24041 even if in fact we generate an error because we do
24042 not have a reloc for it, so tc_gen_reloc will reject it. */
24043 fixP->fx_done = 1;
404ff6b5 24044
c19d1205
ZW
24045 if (fixP->fx_addsy
24046 && ! S_IS_DEFINED (fixP->fx_addsy))
24047 {
24048 as_bad_where (fixP->fx_file, fixP->fx_line,
24049 _("undefined symbol %s used as an immediate value"),
24050 S_GET_NAME (fixP->fx_addsy));
24051 break;
24052 }
404ff6b5 24053
c19d1205
ZW
24054 newval = md_chars_to_number (buf, THUMB_SIZE);
24055 newval <<= 16;
24056 newval |= md_chars_to_number (buf+2, THUMB_SIZE);
404ff6b5 24057
16805f35 24058 newimm = FAIL;
bada4342
JW
24059 if ((fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
24060 /* ARMv8-M Baseline MOV will reach here, but it doesn't support
24061 Thumb2 modified immediate encoding (T2). */
24062 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
16805f35 24063 || fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
ef8d22e6
PB
24064 {
24065 newimm = encode_thumb32_immediate (value);
24066 if (newimm == (unsigned int) FAIL)
24067 newimm = thumb32_negate_data_op (&newval, value);
24068 }
bada4342 24069 if (newimm == (unsigned int) FAIL)
92e90b6e 24070 {
bada4342 24071 if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE)
e9f89963 24072 {
bada4342
JW
24073 /* Turn add/sum into addw/subw. */
24074 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
24075 newval = (newval & 0xfeffffff) | 0x02000000;
24076 /* No flat 12-bit imm encoding for addsw/subsw. */
24077 if ((newval & 0x00100000) == 0)
40f246e3 24078 {
bada4342
JW
24079 /* 12 bit immediate for addw/subw. */
24080 if (value < 0)
24081 {
24082 value = -value;
24083 newval ^= 0x00a00000;
24084 }
24085 if (value > 0xfff)
24086 newimm = (unsigned int) FAIL;
24087 else
24088 newimm = value;
24089 }
24090 }
24091 else
24092 {
24093 /* MOV accepts both Thumb2 modified immediate (T2 encoding) and
24094 UINT16 (T3 encoding), MOVW only accepts UINT16. When
24095 disassembling, MOV is preferred when there is no encoding
db7bf105 24096 overlap. */
bada4342 24097 if (((newval >> T2_DATA_OP_SHIFT) & 0xf) == T2_OPCODE_ORR
db7bf105
NC
24098 /* NOTE: MOV uses the ORR opcode in Thumb 2 mode
24099 but with the Rn field [19:16] set to 1111. */
24100 && (((newval >> 16) & 0xf) == 0xf)
bada4342
JW
24101 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m)
24102 && !((newval >> T2_SBIT_SHIFT) & 0x1)
db7bf105 24103 && value >= 0 && value <= 0xffff)
bada4342
JW
24104 {
24105 /* Toggle bit[25] to change encoding from T2 to T3. */
24106 newval ^= 1 << 25;
24107 /* Clear bits[19:16]. */
24108 newval &= 0xfff0ffff;
24109 /* Encoding high 4bits imm. Code below will encode the
24110 remaining low 12bits. */
24111 newval |= (value & 0x0000f000) << 4;
24112 newimm = value & 0x00000fff;
40f246e3 24113 }
e9f89963 24114 }
92e90b6e 24115 }
cc8a6dd0 24116
c19d1205 24117 if (newimm == (unsigned int)FAIL)
3631a3c8 24118 {
c19d1205
ZW
24119 as_bad_where (fixP->fx_file, fixP->fx_line,
24120 _("invalid constant (%lx) after fixup"),
24121 (unsigned long) value);
24122 break;
3631a3c8
NC
24123 }
24124
c19d1205
ZW
24125 newval |= (newimm & 0x800) << 15;
24126 newval |= (newimm & 0x700) << 4;
24127 newval |= (newimm & 0x0ff);
cc8a6dd0 24128
c19d1205
ZW
24129 md_number_to_chars (buf, (valueT) ((newval >> 16) & 0xffff), THUMB_SIZE);
24130 md_number_to_chars (buf+2, (valueT) (newval & 0xffff), THUMB_SIZE);
24131 break;
a737bd4d 24132
3eb17e6b 24133 case BFD_RELOC_ARM_SMC:
c19d1205
ZW
24134 if (((unsigned long) value) > 0xffff)
24135 as_bad_where (fixP->fx_file, fixP->fx_line,
3eb17e6b 24136 _("invalid smc expression"));
2fc8bdac 24137 newval = md_chars_to_number (buf, INSN_SIZE);
c19d1205
ZW
24138 newval |= (value & 0xf) | ((value & 0xfff0) << 4);
24139 md_number_to_chars (buf, newval, INSN_SIZE);
24140 break;
a737bd4d 24141
90ec0d68
MGD
24142 case BFD_RELOC_ARM_HVC:
24143 if (((unsigned long) value) > 0xffff)
24144 as_bad_where (fixP->fx_file, fixP->fx_line,
24145 _("invalid hvc expression"));
24146 newval = md_chars_to_number (buf, INSN_SIZE);
24147 newval |= (value & 0xf) | ((value & 0xfff0) << 4);
24148 md_number_to_chars (buf, newval, INSN_SIZE);
24149 break;
24150
c19d1205 24151 case BFD_RELOC_ARM_SWI:
adbaf948 24152 if (fixP->tc_fix_data != 0)
c19d1205
ZW
24153 {
24154 if (((unsigned long) value) > 0xff)
24155 as_bad_where (fixP->fx_file, fixP->fx_line,
24156 _("invalid swi expression"));
2fc8bdac 24157 newval = md_chars_to_number (buf, THUMB_SIZE);
c19d1205
ZW
24158 newval |= value;
24159 md_number_to_chars (buf, newval, THUMB_SIZE);
24160 }
24161 else
24162 {
24163 if (((unsigned long) value) > 0x00ffffff)
24164 as_bad_where (fixP->fx_file, fixP->fx_line,
24165 _("invalid swi expression"));
2fc8bdac 24166 newval = md_chars_to_number (buf, INSN_SIZE);
c19d1205
ZW
24167 newval |= value;
24168 md_number_to_chars (buf, newval, INSN_SIZE);
24169 }
24170 break;
a737bd4d 24171
c19d1205
ZW
24172 case BFD_RELOC_ARM_MULTI:
24173 if (((unsigned long) value) > 0xffff)
24174 as_bad_where (fixP->fx_file, fixP->fx_line,
24175 _("invalid expression in load/store multiple"));
24176 newval = value | md_chars_to_number (buf, INSN_SIZE);
24177 md_number_to_chars (buf, newval, INSN_SIZE);
24178 break;
a737bd4d 24179
c19d1205 24180#ifdef OBJ_ELF
39b41c9c 24181 case BFD_RELOC_ARM_PCREL_CALL:
267bf995
RR
24182
24183 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
24184 && fixP->fx_addsy
34e77a92 24185 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
24186 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
24187 && THUMB_IS_FUNC (fixP->fx_addsy))
24188 /* Flip the bl to blx. This is a simple flip
24189 bit here because we generate PCREL_CALL for
24190 unconditional bls. */
24191 {
24192 newval = md_chars_to_number (buf, INSN_SIZE);
24193 newval = newval | 0x10000000;
24194 md_number_to_chars (buf, newval, INSN_SIZE);
24195 temp = 1;
24196 fixP->fx_done = 1;
24197 }
39b41c9c
PB
24198 else
24199 temp = 3;
24200 goto arm_branch_common;
24201
24202 case BFD_RELOC_ARM_PCREL_JUMP:
267bf995
RR
24203 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
24204 && fixP->fx_addsy
34e77a92 24205 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
24206 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
24207 && THUMB_IS_FUNC (fixP->fx_addsy))
24208 {
24209 /* This would map to a bl<cond>, b<cond>,
24210 b<always> to a Thumb function. We
24211 need to force a relocation for this particular
24212 case. */
24213 newval = md_chars_to_number (buf, INSN_SIZE);
24214 fixP->fx_done = 0;
24215 }
1a0670f3 24216 /* Fall through. */
267bf995 24217
2fc8bdac 24218 case BFD_RELOC_ARM_PLT32:
c19d1205 24219#endif
39b41c9c
PB
24220 case BFD_RELOC_ARM_PCREL_BRANCH:
24221 temp = 3;
24222 goto arm_branch_common;
a737bd4d 24223
39b41c9c 24224 case BFD_RELOC_ARM_PCREL_BLX:
267bf995 24225
39b41c9c 24226 temp = 1;
267bf995
RR
24227 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
24228 && fixP->fx_addsy
34e77a92 24229 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
24230 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
24231 && ARM_IS_FUNC (fixP->fx_addsy))
24232 {
24233 /* Flip the blx to a bl and warn. */
24234 const char *name = S_GET_NAME (fixP->fx_addsy);
24235 newval = 0xeb000000;
24236 as_warn_where (fixP->fx_file, fixP->fx_line,
24237 _("blx to '%s' an ARM ISA state function changed to bl"),
24238 name);
24239 md_number_to_chars (buf, newval, INSN_SIZE);
24240 temp = 3;
24241 fixP->fx_done = 1;
24242 }
24243
24244#ifdef OBJ_ELF
24245 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
477330fc 24246 fixP->fx_r_type = BFD_RELOC_ARM_PCREL_CALL;
267bf995
RR
24247#endif
24248
39b41c9c 24249 arm_branch_common:
c19d1205 24250 /* We are going to store value (shifted right by two) in the
39b41c9c
PB
24251 instruction, in a 24 bit, signed field. Bits 26 through 32 either
24252 all clear or all set and bit 0 must be clear. For B/BL bit 1 must
de194d85 24253 also be clear. */
39b41c9c 24254 if (value & temp)
c19d1205 24255 as_bad_where (fixP->fx_file, fixP->fx_line,
2fc8bdac
ZW
24256 _("misaligned branch destination"));
24257 if ((value & (offsetT)0xfe000000) != (offsetT)0
24258 && (value & (offsetT)0xfe000000) != (offsetT)0xfe000000)
08f10d51 24259 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 24260
2fc8bdac 24261 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 24262 {
2fc8bdac
ZW
24263 newval = md_chars_to_number (buf, INSN_SIZE);
24264 newval |= (value >> 2) & 0x00ffffff;
7ae2971b
PB
24265 /* Set the H bit on BLX instructions. */
24266 if (temp == 1)
24267 {
24268 if (value & 2)
24269 newval |= 0x01000000;
24270 else
24271 newval &= ~0x01000000;
24272 }
2fc8bdac 24273 md_number_to_chars (buf, newval, INSN_SIZE);
c19d1205 24274 }
c19d1205 24275 break;
a737bd4d 24276
25fe350b
MS
24277 case BFD_RELOC_THUMB_PCREL_BRANCH7: /* CBZ */
24278 /* CBZ can only branch forward. */
a737bd4d 24279
738755b0 24280 /* Attempts to use CBZ to branch to the next instruction
477330fc
RM
24281 (which, strictly speaking, are prohibited) will be turned into
24282 no-ops.
738755b0
MS
24283
24284 FIXME: It may be better to remove the instruction completely and
24285 perform relaxation. */
24286 if (value == -2)
2fc8bdac
ZW
24287 {
24288 newval = md_chars_to_number (buf, THUMB_SIZE);
738755b0 24289 newval = 0xbf00; /* NOP encoding T1 */
2fc8bdac
ZW
24290 md_number_to_chars (buf, newval, THUMB_SIZE);
24291 }
738755b0
MS
24292 else
24293 {
24294 if (value & ~0x7e)
08f10d51 24295 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
738755b0 24296
477330fc 24297 if (fixP->fx_done || !seg->use_rela_p)
738755b0
MS
24298 {
24299 newval = md_chars_to_number (buf, THUMB_SIZE);
24300 newval |= ((value & 0x3e) << 2) | ((value & 0x40) << 3);
24301 md_number_to_chars (buf, newval, THUMB_SIZE);
24302 }
24303 }
c19d1205 24304 break;
a737bd4d 24305
c19d1205 24306 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
2fc8bdac 24307 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
08f10d51 24308 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 24309
2fc8bdac
ZW
24310 if (fixP->fx_done || !seg->use_rela_p)
24311 {
24312 newval = md_chars_to_number (buf, THUMB_SIZE);
24313 newval |= (value & 0x1ff) >> 1;
24314 md_number_to_chars (buf, newval, THUMB_SIZE);
24315 }
c19d1205 24316 break;
a737bd4d 24317
c19d1205 24318 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
2fc8bdac 24319 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
08f10d51 24320 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 24321
2fc8bdac
ZW
24322 if (fixP->fx_done || !seg->use_rela_p)
24323 {
24324 newval = md_chars_to_number (buf, THUMB_SIZE);
24325 newval |= (value & 0xfff) >> 1;
24326 md_number_to_chars (buf, newval, THUMB_SIZE);
24327 }
c19d1205 24328 break;
a737bd4d 24329
c19d1205 24330 case BFD_RELOC_THUMB_PCREL_BRANCH20:
267bf995
RR
24331 if (fixP->fx_addsy
24332 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 24333 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
24334 && ARM_IS_FUNC (fixP->fx_addsy)
24335 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
24336 {
24337 /* Force a relocation for a branch 20 bits wide. */
24338 fixP->fx_done = 0;
24339 }
08f10d51 24340 if ((value & ~0x1fffff) && ((value & ~0x0fffff) != ~0x0fffff))
2fc8bdac
ZW
24341 as_bad_where (fixP->fx_file, fixP->fx_line,
24342 _("conditional branch out of range"));
404ff6b5 24343
2fc8bdac
ZW
24344 if (fixP->fx_done || !seg->use_rela_p)
24345 {
24346 offsetT newval2;
24347 addressT S, J1, J2, lo, hi;
404ff6b5 24348
2fc8bdac
ZW
24349 S = (value & 0x00100000) >> 20;
24350 J2 = (value & 0x00080000) >> 19;
24351 J1 = (value & 0x00040000) >> 18;
24352 hi = (value & 0x0003f000) >> 12;
24353 lo = (value & 0x00000ffe) >> 1;
6c43fab6 24354
2fc8bdac
ZW
24355 newval = md_chars_to_number (buf, THUMB_SIZE);
24356 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
24357 newval |= (S << 10) | hi;
24358 newval2 |= (J1 << 13) | (J2 << 11) | lo;
24359 md_number_to_chars (buf, newval, THUMB_SIZE);
24360 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
24361 }
c19d1205 24362 break;
6c43fab6 24363
c19d1205 24364 case BFD_RELOC_THUMB_PCREL_BLX:
267bf995
RR
24365 /* If there is a blx from a thumb state function to
24366 another thumb function flip this to a bl and warn
24367 about it. */
24368
24369 if (fixP->fx_addsy
34e77a92 24370 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
24371 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
24372 && THUMB_IS_FUNC (fixP->fx_addsy))
24373 {
24374 const char *name = S_GET_NAME (fixP->fx_addsy);
24375 as_warn_where (fixP->fx_file, fixP->fx_line,
24376 _("blx to Thumb func '%s' from Thumb ISA state changed to bl"),
24377 name);
24378 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
24379 newval = newval | 0x1000;
24380 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
24381 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
24382 fixP->fx_done = 1;
24383 }
24384
24385
24386 goto thumb_bl_common;
24387
c19d1205 24388 case BFD_RELOC_THUMB_PCREL_BRANCH23:
267bf995
RR
24389 /* A bl from Thumb state ISA to an internal ARM state function
24390 is converted to a blx. */
24391 if (fixP->fx_addsy
24392 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 24393 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
24394 && ARM_IS_FUNC (fixP->fx_addsy)
24395 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
24396 {
24397 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
24398 newval = newval & ~0x1000;
24399 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
24400 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BLX;
24401 fixP->fx_done = 1;
24402 }
24403
24404 thumb_bl_common:
24405
2fc8bdac
ZW
24406 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
24407 /* For a BLX instruction, make sure that the relocation is rounded up
24408 to a word boundary. This follows the semantics of the instruction
24409 which specifies that bit 1 of the target address will come from bit
24410 1 of the base address. */
d406f3e4
JB
24411 value = (value + 3) & ~ 3;
24412
24413#ifdef OBJ_ELF
24414 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4
24415 && fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
24416 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
24417#endif
404ff6b5 24418
2b2f5df9
NC
24419 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
24420 {
fc289b0a 24421 if (!(ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)))
2b2f5df9
NC
24422 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
24423 else if ((value & ~0x1ffffff)
24424 && ((value & ~0x1ffffff) != ~0x1ffffff))
24425 as_bad_where (fixP->fx_file, fixP->fx_line,
24426 _("Thumb2 branch out of range"));
24427 }
4a42ebbc
RR
24428
24429 if (fixP->fx_done || !seg->use_rela_p)
24430 encode_thumb2_b_bl_offset (buf, value);
24431
c19d1205 24432 break;
404ff6b5 24433
c19d1205 24434 case BFD_RELOC_THUMB_PCREL_BRANCH25:
08f10d51
NC
24435 if ((value & ~0x0ffffff) && ((value & ~0x0ffffff) != ~0x0ffffff))
24436 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
6c43fab6 24437
2fc8bdac 24438 if (fixP->fx_done || !seg->use_rela_p)
4a42ebbc 24439 encode_thumb2_b_bl_offset (buf, value);
6c43fab6 24440
2fc8bdac 24441 break;
a737bd4d 24442
2fc8bdac
ZW
24443 case BFD_RELOC_8:
24444 if (fixP->fx_done || !seg->use_rela_p)
4b1a927e 24445 *buf = value;
c19d1205 24446 break;
a737bd4d 24447
c19d1205 24448 case BFD_RELOC_16:
2fc8bdac 24449 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 24450 md_number_to_chars (buf, value, 2);
c19d1205 24451 break;
a737bd4d 24452
c19d1205 24453#ifdef OBJ_ELF
0855e32b
NS
24454 case BFD_RELOC_ARM_TLS_CALL:
24455 case BFD_RELOC_ARM_THM_TLS_CALL:
24456 case BFD_RELOC_ARM_TLS_DESCSEQ:
24457 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
0855e32b 24458 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205
ZW
24459 case BFD_RELOC_ARM_TLS_GD32:
24460 case BFD_RELOC_ARM_TLS_LE32:
24461 case BFD_RELOC_ARM_TLS_IE32:
24462 case BFD_RELOC_ARM_TLS_LDM32:
24463 case BFD_RELOC_ARM_TLS_LDO32:
24464 S_SET_THREAD_LOCAL (fixP->fx_addsy);
4b1a927e 24465 break;
6c43fab6 24466
5c5a4843
CL
24467 /* Same handling as above, but with the arm_fdpic guard. */
24468 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
24469 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
24470 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
24471 if (arm_fdpic)
24472 {
24473 S_SET_THREAD_LOCAL (fixP->fx_addsy);
24474 }
24475 else
24476 {
24477 as_bad_where (fixP->fx_file, fixP->fx_line,
24478 _("Relocation supported only in FDPIC mode"));
24479 }
24480 break;
24481
c19d1205
ZW
24482 case BFD_RELOC_ARM_GOT32:
24483 case BFD_RELOC_ARM_GOTOFF:
c19d1205 24484 break;
b43420e6
NC
24485
24486 case BFD_RELOC_ARM_GOT_PREL:
24487 if (fixP->fx_done || !seg->use_rela_p)
477330fc 24488 md_number_to_chars (buf, value, 4);
b43420e6
NC
24489 break;
24490
9a6f4e97
NS
24491 case BFD_RELOC_ARM_TARGET2:
24492 /* TARGET2 is not partial-inplace, so we need to write the
477330fc
RM
24493 addend here for REL targets, because it won't be written out
24494 during reloc processing later. */
9a6f4e97
NS
24495 if (fixP->fx_done || !seg->use_rela_p)
24496 md_number_to_chars (buf, fixP->fx_offset, 4);
24497 break;
188fd7ae
CL
24498
24499 /* Relocations for FDPIC. */
24500 case BFD_RELOC_ARM_GOTFUNCDESC:
24501 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
24502 case BFD_RELOC_ARM_FUNCDESC:
24503 if (arm_fdpic)
24504 {
24505 if (fixP->fx_done || !seg->use_rela_p)
24506 md_number_to_chars (buf, 0, 4);
24507 }
24508 else
24509 {
24510 as_bad_where (fixP->fx_file, fixP->fx_line,
24511 _("Relocation supported only in FDPIC mode"));
24512 }
24513 break;
c19d1205 24514#endif
6c43fab6 24515
c19d1205
ZW
24516 case BFD_RELOC_RVA:
24517 case BFD_RELOC_32:
24518 case BFD_RELOC_ARM_TARGET1:
24519 case BFD_RELOC_ARM_ROSEGREL32:
24520 case BFD_RELOC_ARM_SBREL32:
24521 case BFD_RELOC_32_PCREL:
f0927246
NC
24522#ifdef TE_PE
24523 case BFD_RELOC_32_SECREL:
24524#endif
2fc8bdac 24525 if (fixP->fx_done || !seg->use_rela_p)
53baae48
NC
24526#ifdef TE_WINCE
24527 /* For WinCE we only do this for pcrel fixups. */
24528 if (fixP->fx_done || fixP->fx_pcrel)
24529#endif
24530 md_number_to_chars (buf, value, 4);
c19d1205 24531 break;
6c43fab6 24532
c19d1205
ZW
24533#ifdef OBJ_ELF
24534 case BFD_RELOC_ARM_PREL31:
2fc8bdac 24535 if (fixP->fx_done || !seg->use_rela_p)
c19d1205
ZW
24536 {
24537 newval = md_chars_to_number (buf, 4) & 0x80000000;
24538 if ((value ^ (value >> 1)) & 0x40000000)
24539 {
24540 as_bad_where (fixP->fx_file, fixP->fx_line,
24541 _("rel31 relocation overflow"));
24542 }
24543 newval |= value & 0x7fffffff;
24544 md_number_to_chars (buf, newval, 4);
24545 }
24546 break;
c19d1205 24547#endif
a737bd4d 24548
c19d1205 24549 case BFD_RELOC_ARM_CP_OFF_IMM:
8f06b2d8 24550 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
9db2f6b4
RL
24551 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM)
24552 newval = md_chars_to_number (buf, INSN_SIZE);
24553 else
24554 newval = get_thumb32_insn (buf);
24555 if ((newval & 0x0f200f00) == 0x0d000900)
24556 {
24557 /* This is a fp16 vstr/vldr. The immediate offset in the mnemonic
24558 has permitted values that are multiples of 2, in the range 0
24559 to 510. */
24560 if (value < -510 || value > 510 || (value & 1))
24561 as_bad_where (fixP->fx_file, fixP->fx_line,
24562 _("co-processor offset out of range"));
24563 }
24564 else if (value < -1023 || value > 1023 || (value & 3))
c19d1205
ZW
24565 as_bad_where (fixP->fx_file, fixP->fx_line,
24566 _("co-processor offset out of range"));
24567 cp_off_common:
26d97720 24568 sign = value > 0;
c19d1205
ZW
24569 if (value < 0)
24570 value = -value;
8f06b2d8
PB
24571 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
24572 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
24573 newval = md_chars_to_number (buf, INSN_SIZE);
24574 else
24575 newval = get_thumb32_insn (buf);
26d97720
NS
24576 if (value == 0)
24577 newval &= 0xffffff00;
24578 else
24579 {
24580 newval &= 0xff7fff00;
9db2f6b4
RL
24581 if ((newval & 0x0f200f00) == 0x0d000900)
24582 {
24583 /* This is a fp16 vstr/vldr.
24584
24585 It requires the immediate offset in the instruction is shifted
24586 left by 1 to be a half-word offset.
24587
24588 Here, left shift by 1 first, and later right shift by 2
24589 should get the right offset. */
24590 value <<= 1;
24591 }
26d97720
NS
24592 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
24593 }
8f06b2d8
PB
24594 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
24595 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
24596 md_number_to_chars (buf, newval, INSN_SIZE);
24597 else
24598 put_thumb32_insn (buf, newval);
c19d1205 24599 break;
a737bd4d 24600
c19d1205 24601 case BFD_RELOC_ARM_CP_OFF_IMM_S2:
8f06b2d8 24602 case BFD_RELOC_ARM_T32_CP_OFF_IMM_S2:
c19d1205
ZW
24603 if (value < -255 || value > 255)
24604 as_bad_where (fixP->fx_file, fixP->fx_line,
24605 _("co-processor offset out of range"));
df7849c5 24606 value *= 4;
c19d1205 24607 goto cp_off_common;
6c43fab6 24608
c19d1205
ZW
24609 case BFD_RELOC_ARM_THUMB_OFFSET:
24610 newval = md_chars_to_number (buf, THUMB_SIZE);
24611 /* Exactly what ranges, and where the offset is inserted depends
24612 on the type of instruction, we can establish this from the
24613 top 4 bits. */
24614 switch (newval >> 12)
24615 {
24616 case 4: /* PC load. */
24617 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
24618 forced to zero for these loads; md_pcrel_from has already
24619 compensated for this. */
24620 if (value & 3)
24621 as_bad_where (fixP->fx_file, fixP->fx_line,
24622 _("invalid offset, target not word aligned (0x%08lX)"),
0359e808
NC
24623 (((unsigned long) fixP->fx_frag->fr_address
24624 + (unsigned long) fixP->fx_where) & ~3)
24625 + (unsigned long) value);
a737bd4d 24626
c19d1205
ZW
24627 if (value & ~0x3fc)
24628 as_bad_where (fixP->fx_file, fixP->fx_line,
24629 _("invalid offset, value too big (0x%08lX)"),
24630 (long) value);
a737bd4d 24631
c19d1205
ZW
24632 newval |= value >> 2;
24633 break;
a737bd4d 24634
c19d1205
ZW
24635 case 9: /* SP load/store. */
24636 if (value & ~0x3fc)
24637 as_bad_where (fixP->fx_file, fixP->fx_line,
24638 _("invalid offset, value too big (0x%08lX)"),
24639 (long) value);
24640 newval |= value >> 2;
24641 break;
6c43fab6 24642
c19d1205
ZW
24643 case 6: /* Word load/store. */
24644 if (value & ~0x7c)
24645 as_bad_where (fixP->fx_file, fixP->fx_line,
24646 _("invalid offset, value too big (0x%08lX)"),
24647 (long) value);
24648 newval |= value << 4; /* 6 - 2. */
24649 break;
a737bd4d 24650
c19d1205
ZW
24651 case 7: /* Byte load/store. */
24652 if (value & ~0x1f)
24653 as_bad_where (fixP->fx_file, fixP->fx_line,
24654 _("invalid offset, value too big (0x%08lX)"),
24655 (long) value);
24656 newval |= value << 6;
24657 break;
a737bd4d 24658
c19d1205
ZW
24659 case 8: /* Halfword load/store. */
24660 if (value & ~0x3e)
24661 as_bad_where (fixP->fx_file, fixP->fx_line,
24662 _("invalid offset, value too big (0x%08lX)"),
24663 (long) value);
24664 newval |= value << 5; /* 6 - 1. */
24665 break;
a737bd4d 24666
c19d1205
ZW
24667 default:
24668 as_bad_where (fixP->fx_file, fixP->fx_line,
24669 "Unable to process relocation for thumb opcode: %lx",
24670 (unsigned long) newval);
24671 break;
24672 }
24673 md_number_to_chars (buf, newval, THUMB_SIZE);
24674 break;
a737bd4d 24675
c19d1205
ZW
24676 case BFD_RELOC_ARM_THUMB_ADD:
24677 /* This is a complicated relocation, since we use it for all of
24678 the following immediate relocations:
a737bd4d 24679
c19d1205
ZW
24680 3bit ADD/SUB
24681 8bit ADD/SUB
24682 9bit ADD/SUB SP word-aligned
24683 10bit ADD PC/SP word-aligned
a737bd4d 24684
c19d1205
ZW
24685 The type of instruction being processed is encoded in the
24686 instruction field:
a737bd4d 24687
c19d1205
ZW
24688 0x8000 SUB
24689 0x00F0 Rd
24690 0x000F Rs
24691 */
24692 newval = md_chars_to_number (buf, THUMB_SIZE);
24693 {
24694 int rd = (newval >> 4) & 0xf;
24695 int rs = newval & 0xf;
24696 int subtract = !!(newval & 0x8000);
a737bd4d 24697
c19d1205
ZW
24698 /* Check for HI regs, only very restricted cases allowed:
24699 Adjusting SP, and using PC or SP to get an address. */
24700 if ((rd > 7 && (rd != REG_SP || rs != REG_SP))
24701 || (rs > 7 && rs != REG_SP && rs != REG_PC))
24702 as_bad_where (fixP->fx_file, fixP->fx_line,
24703 _("invalid Hi register with immediate"));
a737bd4d 24704
c19d1205
ZW
24705 /* If value is negative, choose the opposite instruction. */
24706 if (value < 0)
24707 {
24708 value = -value;
24709 subtract = !subtract;
24710 if (value < 0)
24711 as_bad_where (fixP->fx_file, fixP->fx_line,
24712 _("immediate value out of range"));
24713 }
a737bd4d 24714
c19d1205
ZW
24715 if (rd == REG_SP)
24716 {
75c11999 24717 if (value & ~0x1fc)
c19d1205
ZW
24718 as_bad_where (fixP->fx_file, fixP->fx_line,
24719 _("invalid immediate for stack address calculation"));
24720 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
24721 newval |= value >> 2;
24722 }
24723 else if (rs == REG_PC || rs == REG_SP)
24724 {
c12d2c9d
NC
24725 /* PR gas/18541. If the addition is for a defined symbol
24726 within range of an ADR instruction then accept it. */
24727 if (subtract
24728 && value == 4
24729 && fixP->fx_addsy != NULL)
24730 {
24731 subtract = 0;
24732
24733 if (! S_IS_DEFINED (fixP->fx_addsy)
24734 || S_GET_SEGMENT (fixP->fx_addsy) != seg
24735 || S_IS_WEAK (fixP->fx_addsy))
24736 {
24737 as_bad_where (fixP->fx_file, fixP->fx_line,
24738 _("address calculation needs a strongly defined nearby symbol"));
24739 }
24740 else
24741 {
24742 offsetT v = fixP->fx_where + fixP->fx_frag->fr_address;
24743
24744 /* Round up to the next 4-byte boundary. */
24745 if (v & 3)
24746 v = (v + 3) & ~ 3;
24747 else
24748 v += 4;
24749 v = S_GET_VALUE (fixP->fx_addsy) - v;
24750
24751 if (v & ~0x3fc)
24752 {
24753 as_bad_where (fixP->fx_file, fixP->fx_line,
24754 _("symbol too far away"));
24755 }
24756 else
24757 {
24758 fixP->fx_done = 1;
24759 value = v;
24760 }
24761 }
24762 }
24763
c19d1205
ZW
24764 if (subtract || value & ~0x3fc)
24765 as_bad_where (fixP->fx_file, fixP->fx_line,
24766 _("invalid immediate for address calculation (value = 0x%08lX)"),
5fc177c8 24767 (unsigned long) (subtract ? - value : value));
c19d1205
ZW
24768 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
24769 newval |= rd << 8;
24770 newval |= value >> 2;
24771 }
24772 else if (rs == rd)
24773 {
24774 if (value & ~0xff)
24775 as_bad_where (fixP->fx_file, fixP->fx_line,
24776 _("immediate value out of range"));
24777 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
24778 newval |= (rd << 8) | value;
24779 }
24780 else
24781 {
24782 if (value & ~0x7)
24783 as_bad_where (fixP->fx_file, fixP->fx_line,
24784 _("immediate value out of range"));
24785 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
24786 newval |= rd | (rs << 3) | (value << 6);
24787 }
24788 }
24789 md_number_to_chars (buf, newval, THUMB_SIZE);
24790 break;
a737bd4d 24791
c19d1205
ZW
24792 case BFD_RELOC_ARM_THUMB_IMM:
24793 newval = md_chars_to_number (buf, THUMB_SIZE);
24794 if (value < 0 || value > 255)
24795 as_bad_where (fixP->fx_file, fixP->fx_line,
4e6e072b 24796 _("invalid immediate: %ld is out of range"),
c19d1205
ZW
24797 (long) value);
24798 newval |= value;
24799 md_number_to_chars (buf, newval, THUMB_SIZE);
24800 break;
a737bd4d 24801
c19d1205
ZW
24802 case BFD_RELOC_ARM_THUMB_SHIFT:
24803 /* 5bit shift value (0..32). LSL cannot take 32. */
24804 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf83f;
24805 temp = newval & 0xf800;
24806 if (value < 0 || value > 32 || (value == 32 && temp == T_OPCODE_LSL_I))
24807 as_bad_where (fixP->fx_file, fixP->fx_line,
24808 _("invalid shift value: %ld"), (long) value);
24809 /* Shifts of zero must be encoded as LSL. */
24810 if (value == 0)
24811 newval = (newval & 0x003f) | T_OPCODE_LSL_I;
24812 /* Shifts of 32 are encoded as zero. */
24813 else if (value == 32)
24814 value = 0;
24815 newval |= value << 6;
24816 md_number_to_chars (buf, newval, THUMB_SIZE);
24817 break;
a737bd4d 24818
c19d1205
ZW
24819 case BFD_RELOC_VTABLE_INHERIT:
24820 case BFD_RELOC_VTABLE_ENTRY:
24821 fixP->fx_done = 0;
24822 return;
6c43fab6 24823
b6895b4f
PB
24824 case BFD_RELOC_ARM_MOVW:
24825 case BFD_RELOC_ARM_MOVT:
24826 case BFD_RELOC_ARM_THUMB_MOVW:
24827 case BFD_RELOC_ARM_THUMB_MOVT:
24828 if (fixP->fx_done || !seg->use_rela_p)
24829 {
24830 /* REL format relocations are limited to a 16-bit addend. */
24831 if (!fixP->fx_done)
24832 {
39623e12 24833 if (value < -0x8000 || value > 0x7fff)
b6895b4f 24834 as_bad_where (fixP->fx_file, fixP->fx_line,
ff5075ca 24835 _("offset out of range"));
b6895b4f
PB
24836 }
24837 else if (fixP->fx_r_type == BFD_RELOC_ARM_MOVT
24838 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
24839 {
24840 value >>= 16;
24841 }
24842
24843 if (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
24844 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
24845 {
24846 newval = get_thumb32_insn (buf);
24847 newval &= 0xfbf08f00;
24848 newval |= (value & 0xf000) << 4;
24849 newval |= (value & 0x0800) << 15;
24850 newval |= (value & 0x0700) << 4;
24851 newval |= (value & 0x00ff);
24852 put_thumb32_insn (buf, newval);
24853 }
24854 else
24855 {
24856 newval = md_chars_to_number (buf, 4);
24857 newval &= 0xfff0f000;
24858 newval |= value & 0x0fff;
24859 newval |= (value & 0xf000) << 4;
24860 md_number_to_chars (buf, newval, 4);
24861 }
24862 }
24863 return;
24864
72d98d16
MG
24865 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
24866 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
24867 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
24868 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
24869 gas_assert (!fixP->fx_done);
24870 {
24871 bfd_vma insn;
24872 bfd_boolean is_mov;
24873 bfd_vma encoded_addend = value;
24874
24875 /* Check that addend can be encoded in instruction. */
24876 if (!seg->use_rela_p && (value < 0 || value > 255))
24877 as_bad_where (fixP->fx_file, fixP->fx_line,
24878 _("the offset 0x%08lX is not representable"),
24879 (unsigned long) encoded_addend);
24880
24881 /* Extract the instruction. */
24882 insn = md_chars_to_number (buf, THUMB_SIZE);
24883 is_mov = (insn & 0xf800) == 0x2000;
24884
24885 /* Encode insn. */
24886 if (is_mov)
24887 {
24888 if (!seg->use_rela_p)
24889 insn |= encoded_addend;
24890 }
24891 else
24892 {
24893 int rd, rs;
24894
24895 /* Extract the instruction. */
24896 /* Encoding is the following
24897 0x8000 SUB
24898 0x00F0 Rd
24899 0x000F Rs
24900 */
24901 /* The following conditions must be true :
24902 - ADD
24903 - Rd == Rs
24904 - Rd <= 7
24905 */
24906 rd = (insn >> 4) & 0xf;
24907 rs = insn & 0xf;
24908 if ((insn & 0x8000) || (rd != rs) || rd > 7)
24909 as_bad_where (fixP->fx_file, fixP->fx_line,
24910 _("Unable to process relocation for thumb opcode: %lx"),
24911 (unsigned long) insn);
24912
24913 /* Encode as ADD immediate8 thumb 1 code. */
24914 insn = 0x3000 | (rd << 8);
24915
24916 /* Place the encoded addend into the first 8 bits of the
24917 instruction. */
24918 if (!seg->use_rela_p)
24919 insn |= encoded_addend;
24920 }
24921
24922 /* Update the instruction. */
24923 md_number_to_chars (buf, insn, THUMB_SIZE);
24924 }
24925 break;
24926
4962c51a
MS
24927 case BFD_RELOC_ARM_ALU_PC_G0_NC:
24928 case BFD_RELOC_ARM_ALU_PC_G0:
24929 case BFD_RELOC_ARM_ALU_PC_G1_NC:
24930 case BFD_RELOC_ARM_ALU_PC_G1:
24931 case BFD_RELOC_ARM_ALU_PC_G2:
24932 case BFD_RELOC_ARM_ALU_SB_G0_NC:
24933 case BFD_RELOC_ARM_ALU_SB_G0:
24934 case BFD_RELOC_ARM_ALU_SB_G1_NC:
24935 case BFD_RELOC_ARM_ALU_SB_G1:
24936 case BFD_RELOC_ARM_ALU_SB_G2:
9c2799c2 24937 gas_assert (!fixP->fx_done);
4962c51a
MS
24938 if (!seg->use_rela_p)
24939 {
477330fc
RM
24940 bfd_vma insn;
24941 bfd_vma encoded_addend;
3ca4a8ec 24942 bfd_vma addend_abs = llabs (value);
477330fc
RM
24943
24944 /* Check that the absolute value of the addend can be
24945 expressed as an 8-bit constant plus a rotation. */
24946 encoded_addend = encode_arm_immediate (addend_abs);
24947 if (encoded_addend == (unsigned int) FAIL)
4962c51a 24948 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
24949 _("the offset 0x%08lX is not representable"),
24950 (unsigned long) addend_abs);
24951
24952 /* Extract the instruction. */
24953 insn = md_chars_to_number (buf, INSN_SIZE);
24954
24955 /* If the addend is positive, use an ADD instruction.
24956 Otherwise use a SUB. Take care not to destroy the S bit. */
24957 insn &= 0xff1fffff;
24958 if (value < 0)
24959 insn |= 1 << 22;
24960 else
24961 insn |= 1 << 23;
24962
24963 /* Place the encoded addend into the first 12 bits of the
24964 instruction. */
24965 insn &= 0xfffff000;
24966 insn |= encoded_addend;
24967
24968 /* Update the instruction. */
24969 md_number_to_chars (buf, insn, INSN_SIZE);
4962c51a
MS
24970 }
24971 break;
24972
24973 case BFD_RELOC_ARM_LDR_PC_G0:
24974 case BFD_RELOC_ARM_LDR_PC_G1:
24975 case BFD_RELOC_ARM_LDR_PC_G2:
24976 case BFD_RELOC_ARM_LDR_SB_G0:
24977 case BFD_RELOC_ARM_LDR_SB_G1:
24978 case BFD_RELOC_ARM_LDR_SB_G2:
9c2799c2 24979 gas_assert (!fixP->fx_done);
4962c51a 24980 if (!seg->use_rela_p)
477330fc
RM
24981 {
24982 bfd_vma insn;
3ca4a8ec 24983 bfd_vma addend_abs = llabs (value);
4962c51a 24984
477330fc
RM
24985 /* Check that the absolute value of the addend can be
24986 encoded in 12 bits. */
24987 if (addend_abs >= 0x1000)
4962c51a 24988 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
24989 _("bad offset 0x%08lX (only 12 bits available for the magnitude)"),
24990 (unsigned long) addend_abs);
24991
24992 /* Extract the instruction. */
24993 insn = md_chars_to_number (buf, INSN_SIZE);
24994
24995 /* If the addend is negative, clear bit 23 of the instruction.
24996 Otherwise set it. */
24997 if (value < 0)
24998 insn &= ~(1 << 23);
24999 else
25000 insn |= 1 << 23;
25001
25002 /* Place the absolute value of the addend into the first 12 bits
25003 of the instruction. */
25004 insn &= 0xfffff000;
25005 insn |= addend_abs;
25006
25007 /* Update the instruction. */
25008 md_number_to_chars (buf, insn, INSN_SIZE);
25009 }
4962c51a
MS
25010 break;
25011
25012 case BFD_RELOC_ARM_LDRS_PC_G0:
25013 case BFD_RELOC_ARM_LDRS_PC_G1:
25014 case BFD_RELOC_ARM_LDRS_PC_G2:
25015 case BFD_RELOC_ARM_LDRS_SB_G0:
25016 case BFD_RELOC_ARM_LDRS_SB_G1:
25017 case BFD_RELOC_ARM_LDRS_SB_G2:
9c2799c2 25018 gas_assert (!fixP->fx_done);
4962c51a 25019 if (!seg->use_rela_p)
477330fc
RM
25020 {
25021 bfd_vma insn;
3ca4a8ec 25022 bfd_vma addend_abs = llabs (value);
4962c51a 25023
477330fc
RM
25024 /* Check that the absolute value of the addend can be
25025 encoded in 8 bits. */
25026 if (addend_abs >= 0x100)
4962c51a 25027 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
25028 _("bad offset 0x%08lX (only 8 bits available for the magnitude)"),
25029 (unsigned long) addend_abs);
25030
25031 /* Extract the instruction. */
25032 insn = md_chars_to_number (buf, INSN_SIZE);
25033
25034 /* If the addend is negative, clear bit 23 of the instruction.
25035 Otherwise set it. */
25036 if (value < 0)
25037 insn &= ~(1 << 23);
25038 else
25039 insn |= 1 << 23;
25040
25041 /* Place the first four bits of the absolute value of the addend
25042 into the first 4 bits of the instruction, and the remaining
25043 four into bits 8 .. 11. */
25044 insn &= 0xfffff0f0;
25045 insn |= (addend_abs & 0xf) | ((addend_abs & 0xf0) << 4);
25046
25047 /* Update the instruction. */
25048 md_number_to_chars (buf, insn, INSN_SIZE);
25049 }
4962c51a
MS
25050 break;
25051
25052 case BFD_RELOC_ARM_LDC_PC_G0:
25053 case BFD_RELOC_ARM_LDC_PC_G1:
25054 case BFD_RELOC_ARM_LDC_PC_G2:
25055 case BFD_RELOC_ARM_LDC_SB_G0:
25056 case BFD_RELOC_ARM_LDC_SB_G1:
25057 case BFD_RELOC_ARM_LDC_SB_G2:
9c2799c2 25058 gas_assert (!fixP->fx_done);
4962c51a 25059 if (!seg->use_rela_p)
477330fc
RM
25060 {
25061 bfd_vma insn;
3ca4a8ec 25062 bfd_vma addend_abs = llabs (value);
4962c51a 25063
477330fc
RM
25064 /* Check that the absolute value of the addend is a multiple of
25065 four and, when divided by four, fits in 8 bits. */
25066 if (addend_abs & 0x3)
4962c51a 25067 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
25068 _("bad offset 0x%08lX (must be word-aligned)"),
25069 (unsigned long) addend_abs);
4962c51a 25070
477330fc 25071 if ((addend_abs >> 2) > 0xff)
4962c51a 25072 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
25073 _("bad offset 0x%08lX (must be an 8-bit number of words)"),
25074 (unsigned long) addend_abs);
25075
25076 /* Extract the instruction. */
25077 insn = md_chars_to_number (buf, INSN_SIZE);
25078
25079 /* If the addend is negative, clear bit 23 of the instruction.
25080 Otherwise set it. */
25081 if (value < 0)
25082 insn &= ~(1 << 23);
25083 else
25084 insn |= 1 << 23;
25085
25086 /* Place the addend (divided by four) into the first eight
25087 bits of the instruction. */
25088 insn &= 0xfffffff0;
25089 insn |= addend_abs >> 2;
25090
25091 /* Update the instruction. */
25092 md_number_to_chars (buf, insn, INSN_SIZE);
25093 }
4962c51a
MS
25094 break;
25095
e12437dc
AV
25096 case BFD_RELOC_THUMB_PCREL_BRANCH5:
25097 if (fixP->fx_addsy
25098 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25099 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
25100 && ARM_IS_FUNC (fixP->fx_addsy)
25101 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
25102 {
25103 /* Force a relocation for a branch 5 bits wide. */
25104 fixP->fx_done = 0;
25105 }
25106 if (v8_1_branch_value_check (value, 5, FALSE) == FAIL)
25107 as_bad_where (fixP->fx_file, fixP->fx_line,
25108 BAD_BRANCH_OFF);
25109
25110 if (fixP->fx_done || !seg->use_rela_p)
25111 {
25112 addressT boff = value >> 1;
25113
25114 newval = md_chars_to_number (buf, THUMB_SIZE);
25115 newval |= (boff << 7);
25116 md_number_to_chars (buf, newval, THUMB_SIZE);
25117 }
25118 break;
25119
f6b2b12d
AV
25120 case BFD_RELOC_THUMB_PCREL_BFCSEL:
25121 if (fixP->fx_addsy
25122 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25123 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
25124 && ARM_IS_FUNC (fixP->fx_addsy)
25125 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
25126 {
25127 fixP->fx_done = 0;
25128 }
25129 if ((value & ~0x7f) && ((value & ~0x3f) != ~0x3f))
25130 as_bad_where (fixP->fx_file, fixP->fx_line,
25131 _("branch out of range"));
25132
25133 if (fixP->fx_done || !seg->use_rela_p)
25134 {
25135 newval = md_chars_to_number (buf, THUMB_SIZE);
25136
25137 addressT boff = ((newval & 0x0780) >> 7) << 1;
25138 addressT diff = value - boff;
25139
25140 if (diff == 4)
25141 {
25142 newval |= 1 << 1; /* T bit. */
25143 }
25144 else if (diff != 2)
25145 {
25146 as_bad_where (fixP->fx_file, fixP->fx_line,
25147 _("out of range label-relative fixup value"));
25148 }
25149 md_number_to_chars (buf, newval, THUMB_SIZE);
25150 }
25151 break;
25152
e5d6e09e
AV
25153 case BFD_RELOC_ARM_THUMB_BF17:
25154 if (fixP->fx_addsy
25155 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25156 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
25157 && ARM_IS_FUNC (fixP->fx_addsy)
25158 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
25159 {
25160 /* Force a relocation for a branch 17 bits wide. */
25161 fixP->fx_done = 0;
25162 }
25163
25164 if (v8_1_branch_value_check (value, 17, TRUE) == FAIL)
25165 as_bad_where (fixP->fx_file, fixP->fx_line,
25166 BAD_BRANCH_OFF);
25167
25168 if (fixP->fx_done || !seg->use_rela_p)
25169 {
25170 offsetT newval2;
25171 addressT immA, immB, immC;
25172
25173 immA = (value & 0x0001f000) >> 12;
25174 immB = (value & 0x00000ffc) >> 2;
25175 immC = (value & 0x00000002) >> 1;
25176
25177 newval = md_chars_to_number (buf, THUMB_SIZE);
25178 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
25179 newval |= immA;
25180 newval2 |= (immC << 11) | (immB << 1);
25181 md_number_to_chars (buf, newval, THUMB_SIZE);
25182 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
25183 }
25184 break;
25185
1caf72a5
AV
25186 case BFD_RELOC_ARM_THUMB_BF19:
25187 if (fixP->fx_addsy
25188 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25189 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
25190 && ARM_IS_FUNC (fixP->fx_addsy)
25191 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
25192 {
25193 /* Force a relocation for a branch 19 bits wide. */
25194 fixP->fx_done = 0;
25195 }
25196
25197 if (v8_1_branch_value_check (value, 19, TRUE) == FAIL)
25198 as_bad_where (fixP->fx_file, fixP->fx_line,
25199 BAD_BRANCH_OFF);
25200
25201 if (fixP->fx_done || !seg->use_rela_p)
25202 {
25203 offsetT newval2;
25204 addressT immA, immB, immC;
25205
25206 immA = (value & 0x0007f000) >> 12;
25207 immB = (value & 0x00000ffc) >> 2;
25208 immC = (value & 0x00000002) >> 1;
25209
25210 newval = md_chars_to_number (buf, THUMB_SIZE);
25211 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
25212 newval |= immA;
25213 newval2 |= (immC << 11) | (immB << 1);
25214 md_number_to_chars (buf, newval, THUMB_SIZE);
25215 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
25216 }
25217 break;
25218
1889da70
AV
25219 case BFD_RELOC_ARM_THUMB_BF13:
25220 if (fixP->fx_addsy
25221 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25222 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
25223 && ARM_IS_FUNC (fixP->fx_addsy)
25224 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
25225 {
25226 /* Force a relocation for a branch 13 bits wide. */
25227 fixP->fx_done = 0;
25228 }
25229
25230 if (v8_1_branch_value_check (value, 13, TRUE) == FAIL)
25231 as_bad_where (fixP->fx_file, fixP->fx_line,
25232 BAD_BRANCH_OFF);
25233
25234 if (fixP->fx_done || !seg->use_rela_p)
25235 {
25236 offsetT newval2;
25237 addressT immA, immB, immC;
25238
25239 immA = (value & 0x00001000) >> 12;
25240 immB = (value & 0x00000ffc) >> 2;
25241 immC = (value & 0x00000002) >> 1;
25242
25243 newval = md_chars_to_number (buf, THUMB_SIZE);
25244 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
25245 newval |= immA;
25246 newval2 |= (immC << 11) | (immB << 1);
25247 md_number_to_chars (buf, newval, THUMB_SIZE);
25248 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
25249 }
25250 break;
25251
60f993ce
AV
25252 case BFD_RELOC_ARM_THUMB_LOOP12:
25253 if (fixP->fx_addsy
25254 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25255 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
25256 && ARM_IS_FUNC (fixP->fx_addsy)
25257 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
25258 {
25259 /* Force a relocation for a branch 12 bits wide. */
25260 fixP->fx_done = 0;
25261 }
25262
25263 bfd_vma insn = get_thumb32_insn (buf);
25264 /* le lr, <label> or le <label> */
25265 if (((insn & 0xffffffff) == 0xf00fc001)
25266 || ((insn & 0xffffffff) == 0xf02fc001))
25267 value = -value;
25268
25269 if (v8_1_branch_value_check (value, 12, FALSE) == FAIL)
25270 as_bad_where (fixP->fx_file, fixP->fx_line,
25271 BAD_BRANCH_OFF);
25272 if (fixP->fx_done || !seg->use_rela_p)
25273 {
25274 addressT imml, immh;
25275
25276 immh = (value & 0x00000ffc) >> 2;
25277 imml = (value & 0x00000002) >> 1;
25278
25279 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
25280 newval |= (imml << 11) | (immh << 1);
25281 md_number_to_chars (buf + THUMB_SIZE, newval, THUMB_SIZE);
25282 }
25283 break;
25284
845b51d6
PB
25285 case BFD_RELOC_ARM_V4BX:
25286 /* This will need to go in the object file. */
25287 fixP->fx_done = 0;
25288 break;
25289
c19d1205
ZW
25290 case BFD_RELOC_UNUSED:
25291 default:
25292 as_bad_where (fixP->fx_file, fixP->fx_line,
25293 _("bad relocation fixup type (%d)"), fixP->fx_r_type);
25294 }
6c43fab6
RE
25295}
25296
c19d1205
ZW
25297/* Translate internal representation of relocation info to BFD target
25298 format. */
a737bd4d 25299
c19d1205 25300arelent *
00a97672 25301tc_gen_reloc (asection *section, fixS *fixp)
a737bd4d 25302{
c19d1205
ZW
25303 arelent * reloc;
25304 bfd_reloc_code_real_type code;
a737bd4d 25305
325801bd 25306 reloc = XNEW (arelent);
a737bd4d 25307
325801bd 25308 reloc->sym_ptr_ptr = XNEW (asymbol *);
c19d1205
ZW
25309 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
25310 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
a737bd4d 25311
2fc8bdac 25312 if (fixp->fx_pcrel)
00a97672
RS
25313 {
25314 if (section->use_rela_p)
25315 fixp->fx_offset -= md_pcrel_from_section (fixp, section);
25316 else
25317 fixp->fx_offset = reloc->address;
25318 }
c19d1205 25319 reloc->addend = fixp->fx_offset;
a737bd4d 25320
c19d1205 25321 switch (fixp->fx_r_type)
a737bd4d 25322 {
c19d1205
ZW
25323 case BFD_RELOC_8:
25324 if (fixp->fx_pcrel)
25325 {
25326 code = BFD_RELOC_8_PCREL;
25327 break;
25328 }
1a0670f3 25329 /* Fall through. */
a737bd4d 25330
c19d1205
ZW
25331 case BFD_RELOC_16:
25332 if (fixp->fx_pcrel)
25333 {
25334 code = BFD_RELOC_16_PCREL;
25335 break;
25336 }
1a0670f3 25337 /* Fall through. */
6c43fab6 25338
c19d1205
ZW
25339 case BFD_RELOC_32:
25340 if (fixp->fx_pcrel)
25341 {
25342 code = BFD_RELOC_32_PCREL;
25343 break;
25344 }
1a0670f3 25345 /* Fall through. */
a737bd4d 25346
b6895b4f
PB
25347 case BFD_RELOC_ARM_MOVW:
25348 if (fixp->fx_pcrel)
25349 {
25350 code = BFD_RELOC_ARM_MOVW_PCREL;
25351 break;
25352 }
1a0670f3 25353 /* Fall through. */
b6895b4f
PB
25354
25355 case BFD_RELOC_ARM_MOVT:
25356 if (fixp->fx_pcrel)
25357 {
25358 code = BFD_RELOC_ARM_MOVT_PCREL;
25359 break;
25360 }
1a0670f3 25361 /* Fall through. */
b6895b4f
PB
25362
25363 case BFD_RELOC_ARM_THUMB_MOVW:
25364 if (fixp->fx_pcrel)
25365 {
25366 code = BFD_RELOC_ARM_THUMB_MOVW_PCREL;
25367 break;
25368 }
1a0670f3 25369 /* Fall through. */
b6895b4f
PB
25370
25371 case BFD_RELOC_ARM_THUMB_MOVT:
25372 if (fixp->fx_pcrel)
25373 {
25374 code = BFD_RELOC_ARM_THUMB_MOVT_PCREL;
25375 break;
25376 }
1a0670f3 25377 /* Fall through. */
b6895b4f 25378
c19d1205
ZW
25379 case BFD_RELOC_NONE:
25380 case BFD_RELOC_ARM_PCREL_BRANCH:
25381 case BFD_RELOC_ARM_PCREL_BLX:
25382 case BFD_RELOC_RVA:
25383 case BFD_RELOC_THUMB_PCREL_BRANCH7:
25384 case BFD_RELOC_THUMB_PCREL_BRANCH9:
25385 case BFD_RELOC_THUMB_PCREL_BRANCH12:
25386 case BFD_RELOC_THUMB_PCREL_BRANCH20:
25387 case BFD_RELOC_THUMB_PCREL_BRANCH23:
25388 case BFD_RELOC_THUMB_PCREL_BRANCH25:
c19d1205
ZW
25389 case BFD_RELOC_VTABLE_ENTRY:
25390 case BFD_RELOC_VTABLE_INHERIT:
f0927246
NC
25391#ifdef TE_PE
25392 case BFD_RELOC_32_SECREL:
25393#endif
c19d1205
ZW
25394 code = fixp->fx_r_type;
25395 break;
a737bd4d 25396
00adf2d4
JB
25397 case BFD_RELOC_THUMB_PCREL_BLX:
25398#ifdef OBJ_ELF
25399 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
25400 code = BFD_RELOC_THUMB_PCREL_BRANCH23;
25401 else
25402#endif
25403 code = BFD_RELOC_THUMB_PCREL_BLX;
25404 break;
25405
c19d1205
ZW
25406 case BFD_RELOC_ARM_LITERAL:
25407 case BFD_RELOC_ARM_HWLITERAL:
25408 /* If this is called then the a literal has
25409 been referenced across a section boundary. */
25410 as_bad_where (fixp->fx_file, fixp->fx_line,
25411 _("literal referenced across section boundary"));
25412 return NULL;
a737bd4d 25413
c19d1205 25414#ifdef OBJ_ELF
0855e32b
NS
25415 case BFD_RELOC_ARM_TLS_CALL:
25416 case BFD_RELOC_ARM_THM_TLS_CALL:
25417 case BFD_RELOC_ARM_TLS_DESCSEQ:
25418 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
c19d1205
ZW
25419 case BFD_RELOC_ARM_GOT32:
25420 case BFD_RELOC_ARM_GOTOFF:
b43420e6 25421 case BFD_RELOC_ARM_GOT_PREL:
c19d1205
ZW
25422 case BFD_RELOC_ARM_PLT32:
25423 case BFD_RELOC_ARM_TARGET1:
25424 case BFD_RELOC_ARM_ROSEGREL32:
25425 case BFD_RELOC_ARM_SBREL32:
25426 case BFD_RELOC_ARM_PREL31:
25427 case BFD_RELOC_ARM_TARGET2:
c19d1205 25428 case BFD_RELOC_ARM_TLS_LDO32:
39b41c9c
PB
25429 case BFD_RELOC_ARM_PCREL_CALL:
25430 case BFD_RELOC_ARM_PCREL_JUMP:
4962c51a
MS
25431 case BFD_RELOC_ARM_ALU_PC_G0_NC:
25432 case BFD_RELOC_ARM_ALU_PC_G0:
25433 case BFD_RELOC_ARM_ALU_PC_G1_NC:
25434 case BFD_RELOC_ARM_ALU_PC_G1:
25435 case BFD_RELOC_ARM_ALU_PC_G2:
25436 case BFD_RELOC_ARM_LDR_PC_G0:
25437 case BFD_RELOC_ARM_LDR_PC_G1:
25438 case BFD_RELOC_ARM_LDR_PC_G2:
25439 case BFD_RELOC_ARM_LDRS_PC_G0:
25440 case BFD_RELOC_ARM_LDRS_PC_G1:
25441 case BFD_RELOC_ARM_LDRS_PC_G2:
25442 case BFD_RELOC_ARM_LDC_PC_G0:
25443 case BFD_RELOC_ARM_LDC_PC_G1:
25444 case BFD_RELOC_ARM_LDC_PC_G2:
25445 case BFD_RELOC_ARM_ALU_SB_G0_NC:
25446 case BFD_RELOC_ARM_ALU_SB_G0:
25447 case BFD_RELOC_ARM_ALU_SB_G1_NC:
25448 case BFD_RELOC_ARM_ALU_SB_G1:
25449 case BFD_RELOC_ARM_ALU_SB_G2:
25450 case BFD_RELOC_ARM_LDR_SB_G0:
25451 case BFD_RELOC_ARM_LDR_SB_G1:
25452 case BFD_RELOC_ARM_LDR_SB_G2:
25453 case BFD_RELOC_ARM_LDRS_SB_G0:
25454 case BFD_RELOC_ARM_LDRS_SB_G1:
25455 case BFD_RELOC_ARM_LDRS_SB_G2:
25456 case BFD_RELOC_ARM_LDC_SB_G0:
25457 case BFD_RELOC_ARM_LDC_SB_G1:
25458 case BFD_RELOC_ARM_LDC_SB_G2:
845b51d6 25459 case BFD_RELOC_ARM_V4BX:
72d98d16
MG
25460 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
25461 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
25462 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
25463 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
188fd7ae
CL
25464 case BFD_RELOC_ARM_GOTFUNCDESC:
25465 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
25466 case BFD_RELOC_ARM_FUNCDESC:
e5d6e09e 25467 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 25468 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 25469 case BFD_RELOC_ARM_THUMB_BF13:
c19d1205
ZW
25470 code = fixp->fx_r_type;
25471 break;
a737bd4d 25472
0855e32b 25473 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205 25474 case BFD_RELOC_ARM_TLS_GD32:
5c5a4843 25475 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
75c11999 25476 case BFD_RELOC_ARM_TLS_LE32:
c19d1205 25477 case BFD_RELOC_ARM_TLS_IE32:
5c5a4843 25478 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
c19d1205 25479 case BFD_RELOC_ARM_TLS_LDM32:
5c5a4843 25480 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
c19d1205
ZW
25481 /* BFD will include the symbol's address in the addend.
25482 But we don't want that, so subtract it out again here. */
25483 if (!S_IS_COMMON (fixp->fx_addsy))
25484 reloc->addend -= (*reloc->sym_ptr_ptr)->value;
25485 code = fixp->fx_r_type;
25486 break;
25487#endif
a737bd4d 25488
c19d1205
ZW
25489 case BFD_RELOC_ARM_IMMEDIATE:
25490 as_bad_where (fixp->fx_file, fixp->fx_line,
25491 _("internal relocation (type: IMMEDIATE) not fixed up"));
25492 return NULL;
a737bd4d 25493
c19d1205
ZW
25494 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
25495 as_bad_where (fixp->fx_file, fixp->fx_line,
25496 _("ADRL used for a symbol not defined in the same file"));
25497 return NULL;
a737bd4d 25498
e12437dc 25499 case BFD_RELOC_THUMB_PCREL_BRANCH5:
f6b2b12d 25500 case BFD_RELOC_THUMB_PCREL_BFCSEL:
60f993ce 25501 case BFD_RELOC_ARM_THUMB_LOOP12:
e12437dc
AV
25502 as_bad_where (fixp->fx_file, fixp->fx_line,
25503 _("%s used for a symbol not defined in the same file"),
25504 bfd_get_reloc_code_name (fixp->fx_r_type));
25505 return NULL;
25506
c19d1205 25507 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
25508 if (section->use_rela_p)
25509 {
25510 code = fixp->fx_r_type;
25511 break;
25512 }
25513
c19d1205
ZW
25514 if (fixp->fx_addsy != NULL
25515 && !S_IS_DEFINED (fixp->fx_addsy)
25516 && S_IS_LOCAL (fixp->fx_addsy))
a737bd4d 25517 {
c19d1205
ZW
25518 as_bad_where (fixp->fx_file, fixp->fx_line,
25519 _("undefined local label `%s'"),
25520 S_GET_NAME (fixp->fx_addsy));
25521 return NULL;
a737bd4d
NC
25522 }
25523
c19d1205
ZW
25524 as_bad_where (fixp->fx_file, fixp->fx_line,
25525 _("internal_relocation (type: OFFSET_IMM) not fixed up"));
25526 return NULL;
a737bd4d 25527
c19d1205
ZW
25528 default:
25529 {
e0471c16 25530 const char * type;
6c43fab6 25531
c19d1205
ZW
25532 switch (fixp->fx_r_type)
25533 {
25534 case BFD_RELOC_NONE: type = "NONE"; break;
25535 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
25536 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
3eb17e6b 25537 case BFD_RELOC_ARM_SMC: type = "SMC"; break;
c19d1205
ZW
25538 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
25539 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
25540 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
db187cb9 25541 case BFD_RELOC_ARM_T32_OFFSET_IMM: type = "T32_OFFSET_IMM"; break;
8f06b2d8 25542 case BFD_RELOC_ARM_T32_CP_OFF_IMM: type = "T32_CP_OFF_IMM"; break;
c19d1205
ZW
25543 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
25544 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
25545 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
25546 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
25547 default: type = _("<unknown>"); break;
25548 }
25549 as_bad_where (fixp->fx_file, fixp->fx_line,
25550 _("cannot represent %s relocation in this object file format"),
25551 type);
25552 return NULL;
25553 }
a737bd4d 25554 }
6c43fab6 25555
c19d1205
ZW
25556#ifdef OBJ_ELF
25557 if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
25558 && GOT_symbol
25559 && fixp->fx_addsy == GOT_symbol)
25560 {
25561 code = BFD_RELOC_ARM_GOTPC;
25562 reloc->addend = fixp->fx_offset = reloc->address;
25563 }
25564#endif
6c43fab6 25565
c19d1205 25566 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
6c43fab6 25567
c19d1205
ZW
25568 if (reloc->howto == NULL)
25569 {
25570 as_bad_where (fixp->fx_file, fixp->fx_line,
25571 _("cannot represent %s relocation in this object file format"),
25572 bfd_get_reloc_code_name (code));
25573 return NULL;
25574 }
6c43fab6 25575
c19d1205
ZW
25576 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
25577 vtable entry to be used in the relocation's section offset. */
25578 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
25579 reloc->address = fixp->fx_offset;
6c43fab6 25580
c19d1205 25581 return reloc;
6c43fab6
RE
25582}
25583
c19d1205 25584/* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6c43fab6 25585
c19d1205
ZW
25586void
25587cons_fix_new_arm (fragS * frag,
25588 int where,
25589 int size,
62ebcb5c
AM
25590 expressionS * exp,
25591 bfd_reloc_code_real_type reloc)
6c43fab6 25592{
c19d1205 25593 int pcrel = 0;
6c43fab6 25594
c19d1205
ZW
25595 /* Pick a reloc.
25596 FIXME: @@ Should look at CPU word size. */
25597 switch (size)
25598 {
25599 case 1:
62ebcb5c 25600 reloc = BFD_RELOC_8;
c19d1205
ZW
25601 break;
25602 case 2:
62ebcb5c 25603 reloc = BFD_RELOC_16;
c19d1205
ZW
25604 break;
25605 case 4:
25606 default:
62ebcb5c 25607 reloc = BFD_RELOC_32;
c19d1205
ZW
25608 break;
25609 case 8:
62ebcb5c 25610 reloc = BFD_RELOC_64;
c19d1205
ZW
25611 break;
25612 }
6c43fab6 25613
f0927246
NC
25614#ifdef TE_PE
25615 if (exp->X_op == O_secrel)
25616 {
25617 exp->X_op = O_symbol;
62ebcb5c 25618 reloc = BFD_RELOC_32_SECREL;
f0927246
NC
25619 }
25620#endif
25621
62ebcb5c 25622 fix_new_exp (frag, where, size, exp, pcrel, reloc);
c19d1205 25623}
6c43fab6 25624
4343666d 25625#if defined (OBJ_COFF)
c19d1205
ZW
25626void
25627arm_validate_fix (fixS * fixP)
6c43fab6 25628{
c19d1205
ZW
25629 /* If the destination of the branch is a defined symbol which does not have
25630 the THUMB_FUNC attribute, then we must be calling a function which has
25631 the (interfacearm) attribute. We look for the Thumb entry point to that
25632 function and change the branch to refer to that function instead. */
25633 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
25634 && fixP->fx_addsy != NULL
25635 && S_IS_DEFINED (fixP->fx_addsy)
25636 && ! THUMB_IS_FUNC (fixP->fx_addsy))
6c43fab6 25637 {
c19d1205 25638 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
6c43fab6 25639 }
c19d1205
ZW
25640}
25641#endif
6c43fab6 25642
267bf995 25643
c19d1205
ZW
25644int
25645arm_force_relocation (struct fix * fixp)
25646{
25647#if defined (OBJ_COFF) && defined (TE_PE)
25648 if (fixp->fx_r_type == BFD_RELOC_RVA)
25649 return 1;
25650#endif
6c43fab6 25651
267bf995
RR
25652 /* In case we have a call or a branch to a function in ARM ISA mode from
25653 a thumb function or vice-versa force the relocation. These relocations
25654 are cleared off for some cores that might have blx and simple transformations
25655 are possible. */
25656
25657#ifdef OBJ_ELF
25658 switch (fixp->fx_r_type)
25659 {
25660 case BFD_RELOC_ARM_PCREL_JUMP:
25661 case BFD_RELOC_ARM_PCREL_CALL:
25662 case BFD_RELOC_THUMB_PCREL_BLX:
25663 if (THUMB_IS_FUNC (fixp->fx_addsy))
25664 return 1;
25665 break;
25666
25667 case BFD_RELOC_ARM_PCREL_BLX:
25668 case BFD_RELOC_THUMB_PCREL_BRANCH25:
25669 case BFD_RELOC_THUMB_PCREL_BRANCH20:
25670 case BFD_RELOC_THUMB_PCREL_BRANCH23:
25671 if (ARM_IS_FUNC (fixp->fx_addsy))
25672 return 1;
25673 break;
25674
25675 default:
25676 break;
25677 }
25678#endif
25679
b5884301
PB
25680 /* Resolve these relocations even if the symbol is extern or weak.
25681 Technically this is probably wrong due to symbol preemption.
25682 In practice these relocations do not have enough range to be useful
25683 at dynamic link time, and some code (e.g. in the Linux kernel)
25684 expects these references to be resolved. */
c19d1205
ZW
25685 if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
25686 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
b5884301 25687 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM8
0110f2b8 25688 || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE
b5884301
PB
25689 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
25690 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2
25691 || fixp->fx_r_type == BFD_RELOC_ARM_THUMB_OFFSET
16805f35 25692 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM
0110f2b8
PB
25693 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
25694 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMM12
b5884301
PB
25695 || fixp->fx_r_type == BFD_RELOC_ARM_T32_OFFSET_IMM
25696 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_PC12
25697 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM
25698 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM_S2)
c19d1205 25699 return 0;
a737bd4d 25700
4962c51a
MS
25701 /* Always leave these relocations for the linker. */
25702 if ((fixp->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
25703 && fixp->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
25704 || fixp->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
25705 return 1;
25706
f0291e4c
PB
25707 /* Always generate relocations against function symbols. */
25708 if (fixp->fx_r_type == BFD_RELOC_32
25709 && fixp->fx_addsy
25710 && (symbol_get_bfdsym (fixp->fx_addsy)->flags & BSF_FUNCTION))
25711 return 1;
25712
c19d1205 25713 return generic_force_reloc (fixp);
404ff6b5
AH
25714}
25715
0ffdc86c 25716#if defined (OBJ_ELF) || defined (OBJ_COFF)
e28387c3
PB
25717/* Relocations against function names must be left unadjusted,
25718 so that the linker can use this information to generate interworking
25719 stubs. The MIPS version of this function
c19d1205
ZW
25720 also prevents relocations that are mips-16 specific, but I do not
25721 know why it does this.
404ff6b5 25722
c19d1205
ZW
25723 FIXME:
25724 There is one other problem that ought to be addressed here, but
25725 which currently is not: Taking the address of a label (rather
25726 than a function) and then later jumping to that address. Such
25727 addresses also ought to have their bottom bit set (assuming that
25728 they reside in Thumb code), but at the moment they will not. */
404ff6b5 25729
c19d1205
ZW
25730bfd_boolean
25731arm_fix_adjustable (fixS * fixP)
404ff6b5 25732{
c19d1205
ZW
25733 if (fixP->fx_addsy == NULL)
25734 return 1;
404ff6b5 25735
e28387c3
PB
25736 /* Preserve relocations against symbols with function type. */
25737 if (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_FUNCTION)
c921be7d 25738 return FALSE;
e28387c3 25739
c19d1205
ZW
25740 if (THUMB_IS_FUNC (fixP->fx_addsy)
25741 && fixP->fx_subsy == NULL)
c921be7d 25742 return FALSE;
a737bd4d 25743
c19d1205
ZW
25744 /* We need the symbol name for the VTABLE entries. */
25745 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
25746 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
c921be7d 25747 return FALSE;
404ff6b5 25748
c19d1205
ZW
25749 /* Don't allow symbols to be discarded on GOT related relocs. */
25750 if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
25751 || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
25752 || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
25753 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32
5c5a4843 25754 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32_FDPIC
c19d1205
ZW
25755 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LE32
25756 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32
5c5a4843 25757 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32_FDPIC
c19d1205 25758 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32
5c5a4843 25759 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32_FDPIC
c19d1205 25760 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDO32
0855e32b
NS
25761 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GOTDESC
25762 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_CALL
25763 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_CALL
25764 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_DESCSEQ
25765 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_DESCSEQ
c19d1205 25766 || fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
c921be7d 25767 return FALSE;
a737bd4d 25768
4962c51a
MS
25769 /* Similarly for group relocations. */
25770 if ((fixP->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
25771 && fixP->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
25772 || fixP->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
c921be7d 25773 return FALSE;
4962c51a 25774
79947c54
CD
25775 /* MOVW/MOVT REL relocations have limited offsets, so keep the symbols. */
25776 if (fixP->fx_r_type == BFD_RELOC_ARM_MOVW
25777 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT
25778 || fixP->fx_r_type == BFD_RELOC_ARM_MOVW_PCREL
25779 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT_PCREL
25780 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
25781 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT
25782 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW_PCREL
25783 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT_PCREL)
c921be7d 25784 return FALSE;
79947c54 25785
72d98d16
MG
25786 /* BFD_RELOC_ARM_THUMB_ALU_ABS_Gx_NC relocations have VERY limited
25787 offsets, so keep these symbols. */
25788 if (fixP->fx_r_type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
25789 && fixP->fx_r_type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
25790 return FALSE;
25791
c921be7d 25792 return TRUE;
a737bd4d 25793}
0ffdc86c
NC
25794#endif /* defined (OBJ_ELF) || defined (OBJ_COFF) */
25795
25796#ifdef OBJ_ELF
c19d1205
ZW
25797const char *
25798elf32_arm_target_format (void)
404ff6b5 25799{
c19d1205
ZW
25800#ifdef TE_SYMBIAN
25801 return (target_big_endian
25802 ? "elf32-bigarm-symbian"
25803 : "elf32-littlearm-symbian");
25804#elif defined (TE_VXWORKS)
25805 return (target_big_endian
25806 ? "elf32-bigarm-vxworks"
25807 : "elf32-littlearm-vxworks");
b38cadfb
NC
25808#elif defined (TE_NACL)
25809 return (target_big_endian
25810 ? "elf32-bigarm-nacl"
25811 : "elf32-littlearm-nacl");
c19d1205 25812#else
18a20338
CL
25813 if (arm_fdpic)
25814 {
25815 if (target_big_endian)
25816 return "elf32-bigarm-fdpic";
25817 else
25818 return "elf32-littlearm-fdpic";
25819 }
c19d1205 25820 else
18a20338
CL
25821 {
25822 if (target_big_endian)
25823 return "elf32-bigarm";
25824 else
25825 return "elf32-littlearm";
25826 }
c19d1205 25827#endif
404ff6b5
AH
25828}
25829
c19d1205
ZW
25830void
25831armelf_frob_symbol (symbolS * symp,
25832 int * puntp)
404ff6b5 25833{
c19d1205
ZW
25834 elf_frob_symbol (symp, puntp);
25835}
25836#endif
404ff6b5 25837
c19d1205 25838/* MD interface: Finalization. */
a737bd4d 25839
c19d1205
ZW
25840void
25841arm_cleanup (void)
25842{
25843 literal_pool * pool;
a737bd4d 25844
e07e6e58
NC
25845 /* Ensure that all the IT blocks are properly closed. */
25846 check_it_blocks_finished ();
25847
c19d1205
ZW
25848 for (pool = list_of_pools; pool; pool = pool->next)
25849 {
5f4273c7 25850 /* Put it at the end of the relevant section. */
c19d1205
ZW
25851 subseg_set (pool->section, pool->sub_section);
25852#ifdef OBJ_ELF
25853 arm_elf_change_section ();
25854#endif
25855 s_ltorg (0);
25856 }
404ff6b5
AH
25857}
25858
cd000bff
DJ
25859#ifdef OBJ_ELF
25860/* Remove any excess mapping symbols generated for alignment frags in
25861 SEC. We may have created a mapping symbol before a zero byte
25862 alignment; remove it if there's a mapping symbol after the
25863 alignment. */
25864static void
25865check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
25866 void *dummy ATTRIBUTE_UNUSED)
25867{
25868 segment_info_type *seginfo = seg_info (sec);
25869 fragS *fragp;
25870
25871 if (seginfo == NULL || seginfo->frchainP == NULL)
25872 return;
25873
25874 for (fragp = seginfo->frchainP->frch_root;
25875 fragp != NULL;
25876 fragp = fragp->fr_next)
25877 {
25878 symbolS *sym = fragp->tc_frag_data.last_map;
25879 fragS *next = fragp->fr_next;
25880
25881 /* Variable-sized frags have been converted to fixed size by
25882 this point. But if this was variable-sized to start with,
25883 there will be a fixed-size frag after it. So don't handle
25884 next == NULL. */
25885 if (sym == NULL || next == NULL)
25886 continue;
25887
25888 if (S_GET_VALUE (sym) < next->fr_address)
25889 /* Not at the end of this frag. */
25890 continue;
25891 know (S_GET_VALUE (sym) == next->fr_address);
25892
25893 do
25894 {
25895 if (next->tc_frag_data.first_map != NULL)
25896 {
25897 /* Next frag starts with a mapping symbol. Discard this
25898 one. */
25899 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
25900 break;
25901 }
25902
25903 if (next->fr_next == NULL)
25904 {
25905 /* This mapping symbol is at the end of the section. Discard
25906 it. */
25907 know (next->fr_fix == 0 && next->fr_var == 0);
25908 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
25909 break;
25910 }
25911
25912 /* As long as we have empty frags without any mapping symbols,
25913 keep looking. */
25914 /* If the next frag is non-empty and does not start with a
25915 mapping symbol, then this mapping symbol is required. */
25916 if (next->fr_address != next->fr_next->fr_address)
25917 break;
25918
25919 next = next->fr_next;
25920 }
25921 while (next != NULL);
25922 }
25923}
25924#endif
25925
c19d1205
ZW
25926/* Adjust the symbol table. This marks Thumb symbols as distinct from
25927 ARM ones. */
404ff6b5 25928
c19d1205
ZW
25929void
25930arm_adjust_symtab (void)
404ff6b5 25931{
c19d1205
ZW
25932#ifdef OBJ_COFF
25933 symbolS * sym;
404ff6b5 25934
c19d1205
ZW
25935 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
25936 {
25937 if (ARM_IS_THUMB (sym))
25938 {
25939 if (THUMB_IS_FUNC (sym))
25940 {
25941 /* Mark the symbol as a Thumb function. */
25942 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
25943 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
25944 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
404ff6b5 25945
c19d1205
ZW
25946 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
25947 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
25948 else
25949 as_bad (_("%s: unexpected function type: %d"),
25950 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
25951 }
25952 else switch (S_GET_STORAGE_CLASS (sym))
25953 {
25954 case C_EXT:
25955 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
25956 break;
25957 case C_STAT:
25958 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
25959 break;
25960 case C_LABEL:
25961 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
25962 break;
25963 default:
25964 /* Do nothing. */
25965 break;
25966 }
25967 }
a737bd4d 25968
c19d1205
ZW
25969 if (ARM_IS_INTERWORK (sym))
25970 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
404ff6b5 25971 }
c19d1205
ZW
25972#endif
25973#ifdef OBJ_ELF
25974 symbolS * sym;
25975 char bind;
404ff6b5 25976
c19d1205 25977 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
404ff6b5 25978 {
c19d1205
ZW
25979 if (ARM_IS_THUMB (sym))
25980 {
25981 elf_symbol_type * elf_sym;
404ff6b5 25982
c19d1205
ZW
25983 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
25984 bind = ELF_ST_BIND (elf_sym->internal_elf_sym.st_info);
404ff6b5 25985
b0796911
PB
25986 if (! bfd_is_arm_special_symbol_name (elf_sym->symbol.name,
25987 BFD_ARM_SPECIAL_SYM_TYPE_ANY))
c19d1205
ZW
25988 {
25989 /* If it's a .thumb_func, declare it as so,
25990 otherwise tag label as .code 16. */
25991 if (THUMB_IS_FUNC (sym))
39d911fc
TP
25992 ARM_SET_SYM_BRANCH_TYPE (elf_sym->internal_elf_sym.st_target_internal,
25993 ST_BRANCH_TO_THUMB);
3ba67470 25994 else if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
c19d1205
ZW
25995 elf_sym->internal_elf_sym.st_info =
25996 ELF_ST_INFO (bind, STT_ARM_16BIT);
25997 }
25998 }
25999 }
cd000bff
DJ
26000
26001 /* Remove any overlapping mapping symbols generated by alignment frags. */
26002 bfd_map_over_sections (stdoutput, check_mapping_symbols, (char *) 0);
709001e9
MM
26003 /* Now do generic ELF adjustments. */
26004 elf_adjust_symtab ();
c19d1205 26005#endif
404ff6b5
AH
26006}
26007
c19d1205 26008/* MD interface: Initialization. */
404ff6b5 26009
a737bd4d 26010static void
c19d1205 26011set_constant_flonums (void)
a737bd4d 26012{
c19d1205 26013 int i;
404ff6b5 26014
c19d1205
ZW
26015 for (i = 0; i < NUM_FLOAT_VALS; i++)
26016 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
26017 abort ();
a737bd4d 26018}
404ff6b5 26019
3e9e4fcf
JB
26020/* Auto-select Thumb mode if it's the only available instruction set for the
26021 given architecture. */
26022
26023static void
26024autoselect_thumb_from_cpu_variant (void)
26025{
26026 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
26027 opcode_select (16);
26028}
26029
c19d1205
ZW
26030void
26031md_begin (void)
a737bd4d 26032{
c19d1205
ZW
26033 unsigned mach;
26034 unsigned int i;
404ff6b5 26035
c19d1205
ZW
26036 if ( (arm_ops_hsh = hash_new ()) == NULL
26037 || (arm_cond_hsh = hash_new ()) == NULL
26038 || (arm_shift_hsh = hash_new ()) == NULL
26039 || (arm_psr_hsh = hash_new ()) == NULL
62b3e311 26040 || (arm_v7m_psr_hsh = hash_new ()) == NULL
c19d1205 26041 || (arm_reg_hsh = hash_new ()) == NULL
62b3e311
PB
26042 || (arm_reloc_hsh = hash_new ()) == NULL
26043 || (arm_barrier_opt_hsh = hash_new ()) == NULL)
c19d1205
ZW
26044 as_fatal (_("virtual memory exhausted"));
26045
26046 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
d3ce72d0 26047 hash_insert (arm_ops_hsh, insns[i].template_name, (void *) (insns + i));
c19d1205 26048 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
d3ce72d0 26049 hash_insert (arm_cond_hsh, conds[i].template_name, (void *) (conds + i));
c19d1205 26050 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
5a49b8ac 26051 hash_insert (arm_shift_hsh, shift_names[i].name, (void *) (shift_names + i));
c19d1205 26052 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
d3ce72d0 26053 hash_insert (arm_psr_hsh, psrs[i].template_name, (void *) (psrs + i));
62b3e311 26054 for (i = 0; i < sizeof (v7m_psrs) / sizeof (struct asm_psr); i++)
d3ce72d0 26055 hash_insert (arm_v7m_psr_hsh, v7m_psrs[i].template_name,
477330fc 26056 (void *) (v7m_psrs + i));
c19d1205 26057 for (i = 0; i < sizeof (reg_names) / sizeof (struct reg_entry); i++)
5a49b8ac 26058 hash_insert (arm_reg_hsh, reg_names[i].name, (void *) (reg_names + i));
62b3e311
PB
26059 for (i = 0;
26060 i < sizeof (barrier_opt_names) / sizeof (struct asm_barrier_opt);
26061 i++)
d3ce72d0 26062 hash_insert (arm_barrier_opt_hsh, barrier_opt_names[i].template_name,
5a49b8ac 26063 (void *) (barrier_opt_names + i));
c19d1205 26064#ifdef OBJ_ELF
3da1d841
NC
26065 for (i = 0; i < ARRAY_SIZE (reloc_names); i++)
26066 {
26067 struct reloc_entry * entry = reloc_names + i;
26068
26069 if (arm_is_eabi() && entry->reloc == BFD_RELOC_ARM_PLT32)
26070 /* This makes encode_branch() use the EABI versions of this relocation. */
26071 entry->reloc = BFD_RELOC_UNUSED;
26072
26073 hash_insert (arm_reloc_hsh, entry->name, (void *) entry);
26074 }
c19d1205
ZW
26075#endif
26076
26077 set_constant_flonums ();
404ff6b5 26078
c19d1205
ZW
26079 /* Set the cpu variant based on the command-line options. We prefer
26080 -mcpu= over -march= if both are set (as for GCC); and we prefer
26081 -mfpu= over any other way of setting the floating point unit.
26082 Use of legacy options with new options are faulted. */
e74cfd16 26083 if (legacy_cpu)
404ff6b5 26084 {
e74cfd16 26085 if (mcpu_cpu_opt || march_cpu_opt)
c19d1205
ZW
26086 as_bad (_("use of old and new-style options to set CPU type"));
26087
4d354d8b 26088 selected_arch = *legacy_cpu;
404ff6b5 26089 }
4d354d8b
TP
26090 else if (mcpu_cpu_opt)
26091 {
26092 selected_arch = *mcpu_cpu_opt;
26093 selected_ext = *mcpu_ext_opt;
26094 }
26095 else if (march_cpu_opt)
c168ce07 26096 {
4d354d8b
TP
26097 selected_arch = *march_cpu_opt;
26098 selected_ext = *march_ext_opt;
c168ce07 26099 }
4d354d8b 26100 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
404ff6b5 26101
e74cfd16 26102 if (legacy_fpu)
c19d1205 26103 {
e74cfd16 26104 if (mfpu_opt)
c19d1205 26105 as_bad (_("use of old and new-style options to set FPU type"));
03b1477f 26106
4d354d8b 26107 selected_fpu = *legacy_fpu;
03b1477f 26108 }
4d354d8b
TP
26109 else if (mfpu_opt)
26110 selected_fpu = *mfpu_opt;
26111 else
03b1477f 26112 {
45eb4c1b
NS
26113#if !(defined (EABI_DEFAULT) || defined (TE_LINUX) \
26114 || defined (TE_NetBSD) || defined (TE_VXWORKS))
39c2da32
RE
26115 /* Some environments specify a default FPU. If they don't, infer it
26116 from the processor. */
e74cfd16 26117 if (mcpu_fpu_opt)
4d354d8b 26118 selected_fpu = *mcpu_fpu_opt;
e7da50fa 26119 else if (march_fpu_opt)
4d354d8b 26120 selected_fpu = *march_fpu_opt;
39c2da32 26121#else
4d354d8b 26122 selected_fpu = fpu_default;
39c2da32 26123#endif
03b1477f
RE
26124 }
26125
4d354d8b 26126 if (ARM_FEATURE_ZERO (selected_fpu))
03b1477f 26127 {
4d354d8b
TP
26128 if (!no_cpu_selected ())
26129 selected_fpu = fpu_default;
03b1477f 26130 else
4d354d8b 26131 selected_fpu = fpu_arch_fpa;
03b1477f
RE
26132 }
26133
ee065d83 26134#ifdef CPU_DEFAULT
4d354d8b 26135 if (ARM_FEATURE_ZERO (selected_arch))
ee065d83 26136 {
4d354d8b
TP
26137 selected_arch = cpu_default;
26138 selected_cpu = selected_arch;
ee065d83 26139 }
4d354d8b 26140 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
e74cfd16 26141#else
4d354d8b
TP
26142 /* Autodection of feature mode: allow all features in cpu_variant but leave
26143 selected_cpu unset. It will be set in aeabi_set_public_attributes ()
26144 after all instruction have been processed and we can decide what CPU
26145 should be selected. */
26146 if (ARM_FEATURE_ZERO (selected_arch))
26147 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
ee065d83 26148 else
4d354d8b 26149 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83 26150#endif
03b1477f 26151
3e9e4fcf
JB
26152 autoselect_thumb_from_cpu_variant ();
26153
e74cfd16 26154 arm_arch_used = thumb_arch_used = arm_arch_none;
ee065d83 26155
f17c130b 26156#if defined OBJ_COFF || defined OBJ_ELF
b99bd4ef 26157 {
7cc69913
NC
26158 unsigned int flags = 0;
26159
26160#if defined OBJ_ELF
26161 flags = meabi_flags;
d507cf36
PB
26162
26163 switch (meabi_flags)
33a392fb 26164 {
d507cf36 26165 case EF_ARM_EABI_UNKNOWN:
7cc69913 26166#endif
d507cf36
PB
26167 /* Set the flags in the private structure. */
26168 if (uses_apcs_26) flags |= F_APCS26;
26169 if (support_interwork) flags |= F_INTERWORK;
26170 if (uses_apcs_float) flags |= F_APCS_FLOAT;
c19d1205 26171 if (pic_code) flags |= F_PIC;
e74cfd16 26172 if (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_any_hard))
7cc69913
NC
26173 flags |= F_SOFT_FLOAT;
26174
d507cf36
PB
26175 switch (mfloat_abi_opt)
26176 {
26177 case ARM_FLOAT_ABI_SOFT:
26178 case ARM_FLOAT_ABI_SOFTFP:
26179 flags |= F_SOFT_FLOAT;
26180 break;
33a392fb 26181
d507cf36
PB
26182 case ARM_FLOAT_ABI_HARD:
26183 if (flags & F_SOFT_FLOAT)
26184 as_bad (_("hard-float conflicts with specified fpu"));
26185 break;
26186 }
03b1477f 26187
e74cfd16
PB
26188 /* Using pure-endian doubles (even if soft-float). */
26189 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_endian_pure))
7cc69913 26190 flags |= F_VFP_FLOAT;
f17c130b 26191
fde78edd 26192#if defined OBJ_ELF
e74cfd16 26193 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_maverick))
d507cf36 26194 flags |= EF_ARM_MAVERICK_FLOAT;
d507cf36
PB
26195 break;
26196
8cb51566 26197 case EF_ARM_EABI_VER4:
3a4a14e9 26198 case EF_ARM_EABI_VER5:
c19d1205 26199 /* No additional flags to set. */
d507cf36
PB
26200 break;
26201
26202 default:
26203 abort ();
26204 }
7cc69913 26205#endif
b99bd4ef
NC
26206 bfd_set_private_flags (stdoutput, flags);
26207
26208 /* We have run out flags in the COFF header to encode the
26209 status of ATPCS support, so instead we create a dummy,
c19d1205 26210 empty, debug section called .arm.atpcs. */
b99bd4ef
NC
26211 if (atpcs)
26212 {
26213 asection * sec;
26214
26215 sec = bfd_make_section (stdoutput, ".arm.atpcs");
26216
26217 if (sec != NULL)
26218 {
26219 bfd_set_section_flags
26220 (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
26221 bfd_set_section_size (stdoutput, sec, 0);
26222 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
26223 }
26224 }
7cc69913 26225 }
f17c130b 26226#endif
b99bd4ef
NC
26227
26228 /* Record the CPU type as well. */
2d447fca
JM
26229 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2))
26230 mach = bfd_mach_arm_iWMMXt2;
26231 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt))
e16bb312 26232 mach = bfd_mach_arm_iWMMXt;
e74cfd16 26233 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_xscale))
b99bd4ef 26234 mach = bfd_mach_arm_XScale;
e74cfd16 26235 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_maverick))
fde78edd 26236 mach = bfd_mach_arm_ep9312;
e74cfd16 26237 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5e))
b99bd4ef 26238 mach = bfd_mach_arm_5TE;
e74cfd16 26239 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5))
b99bd4ef 26240 {
e74cfd16 26241 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
26242 mach = bfd_mach_arm_5T;
26243 else
26244 mach = bfd_mach_arm_5;
26245 }
e74cfd16 26246 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4))
b99bd4ef 26247 {
e74cfd16 26248 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
26249 mach = bfd_mach_arm_4T;
26250 else
26251 mach = bfd_mach_arm_4;
26252 }
e74cfd16 26253 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3m))
b99bd4ef 26254 mach = bfd_mach_arm_3M;
e74cfd16
PB
26255 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3))
26256 mach = bfd_mach_arm_3;
26257 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2s))
26258 mach = bfd_mach_arm_2a;
26259 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2))
26260 mach = bfd_mach_arm_2;
26261 else
26262 mach = bfd_mach_arm_unknown;
b99bd4ef
NC
26263
26264 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
26265}
26266
c19d1205 26267/* Command line processing. */
b99bd4ef 26268
c19d1205
ZW
26269/* md_parse_option
26270 Invocation line includes a switch not recognized by the base assembler.
26271 See if it's a processor-specific option.
b99bd4ef 26272
c19d1205
ZW
26273 This routine is somewhat complicated by the need for backwards
26274 compatibility (since older releases of gcc can't be changed).
26275 The new options try to make the interface as compatible as
26276 possible with GCC.
b99bd4ef 26277
c19d1205 26278 New options (supported) are:
b99bd4ef 26279
c19d1205
ZW
26280 -mcpu=<cpu name> Assemble for selected processor
26281 -march=<architecture name> Assemble for selected architecture
26282 -mfpu=<fpu architecture> Assemble for selected FPU.
26283 -EB/-mbig-endian Big-endian
26284 -EL/-mlittle-endian Little-endian
26285 -k Generate PIC code
26286 -mthumb Start in Thumb mode
26287 -mthumb-interwork Code supports ARM/Thumb interworking
b99bd4ef 26288
278df34e 26289 -m[no-]warn-deprecated Warn about deprecated features
8b2d793c 26290 -m[no-]warn-syms Warn when symbols match instructions
267bf995 26291
c19d1205 26292 For now we will also provide support for:
b99bd4ef 26293
c19d1205
ZW
26294 -mapcs-32 32-bit Program counter
26295 -mapcs-26 26-bit Program counter
26296 -macps-float Floats passed in FP registers
26297 -mapcs-reentrant Reentrant code
26298 -matpcs
26299 (sometime these will probably be replaced with -mapcs=<list of options>
26300 and -matpcs=<list of options>)
b99bd4ef 26301
c19d1205
ZW
26302 The remaining options are only supported for back-wards compatibility.
26303 Cpu variants, the arm part is optional:
26304 -m[arm]1 Currently not supported.
26305 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
26306 -m[arm]3 Arm 3 processor
26307 -m[arm]6[xx], Arm 6 processors
26308 -m[arm]7[xx][t][[d]m] Arm 7 processors
26309 -m[arm]8[10] Arm 8 processors
26310 -m[arm]9[20][tdmi] Arm 9 processors
26311 -mstrongarm[110[0]] StrongARM processors
26312 -mxscale XScale processors
26313 -m[arm]v[2345[t[e]]] Arm architectures
26314 -mall All (except the ARM1)
26315 FP variants:
26316 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
26317 -mfpe-old (No float load/store multiples)
26318 -mvfpxd VFP Single precision
26319 -mvfp All VFP
26320 -mno-fpu Disable all floating point instructions
b99bd4ef 26321
c19d1205
ZW
26322 The following CPU names are recognized:
26323 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
26324 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
26325 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
26326 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
26327 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
26328 arm10t arm10e, arm1020t, arm1020e, arm10200e,
26329 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
b99bd4ef 26330
c19d1205 26331 */
b99bd4ef 26332
c19d1205 26333const char * md_shortopts = "m:k";
b99bd4ef 26334
c19d1205
ZW
26335#ifdef ARM_BI_ENDIAN
26336#define OPTION_EB (OPTION_MD_BASE + 0)
26337#define OPTION_EL (OPTION_MD_BASE + 1)
b99bd4ef 26338#else
c19d1205
ZW
26339#if TARGET_BYTES_BIG_ENDIAN
26340#define OPTION_EB (OPTION_MD_BASE + 0)
b99bd4ef 26341#else
c19d1205
ZW
26342#define OPTION_EL (OPTION_MD_BASE + 1)
26343#endif
b99bd4ef 26344#endif
845b51d6 26345#define OPTION_FIX_V4BX (OPTION_MD_BASE + 2)
18a20338 26346#define OPTION_FDPIC (OPTION_MD_BASE + 3)
b99bd4ef 26347
c19d1205 26348struct option md_longopts[] =
b99bd4ef 26349{
c19d1205
ZW
26350#ifdef OPTION_EB
26351 {"EB", no_argument, NULL, OPTION_EB},
26352#endif
26353#ifdef OPTION_EL
26354 {"EL", no_argument, NULL, OPTION_EL},
b99bd4ef 26355#endif
845b51d6 26356 {"fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX},
18a20338
CL
26357#ifdef OBJ_ELF
26358 {"fdpic", no_argument, NULL, OPTION_FDPIC},
26359#endif
c19d1205
ZW
26360 {NULL, no_argument, NULL, 0}
26361};
b99bd4ef 26362
c19d1205 26363size_t md_longopts_size = sizeof (md_longopts);
b99bd4ef 26364
c19d1205 26365struct arm_option_table
b99bd4ef 26366{
0198d5e6
TC
26367 const char * option; /* Option name to match. */
26368 const char * help; /* Help information. */
26369 int * var; /* Variable to change. */
26370 int value; /* What to change it to. */
26371 const char * deprecated; /* If non-null, print this message. */
c19d1205 26372};
b99bd4ef 26373
c19d1205
ZW
26374struct arm_option_table arm_opts[] =
26375{
26376 {"k", N_("generate PIC code"), &pic_code, 1, NULL},
26377 {"mthumb", N_("assemble Thumb code"), &thumb_mode, 1, NULL},
26378 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
26379 &support_interwork, 1, NULL},
26380 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
26381 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
26382 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
26383 1, NULL},
26384 {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
26385 {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
26386 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
26387 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 0,
26388 NULL},
b99bd4ef 26389
c19d1205
ZW
26390 /* These are recognized by the assembler, but have no affect on code. */
26391 {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
26392 {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
278df34e
NS
26393
26394 {"mwarn-deprecated", NULL, &warn_on_deprecated, 1, NULL},
26395 {"mno-warn-deprecated", N_("do not warn on use of deprecated feature"),
26396 &warn_on_deprecated, 0, NULL},
8b2d793c
NC
26397 {"mwarn-syms", N_("warn about symbols that match instruction names [default]"), (int *) (& flag_warn_syms), TRUE, NULL},
26398 {"mno-warn-syms", N_("disable warnings about symobls that match instructions"), (int *) (& flag_warn_syms), FALSE, NULL},
e74cfd16
PB
26399 {NULL, NULL, NULL, 0, NULL}
26400};
26401
26402struct arm_legacy_option_table
26403{
0198d5e6
TC
26404 const char * option; /* Option name to match. */
26405 const arm_feature_set ** var; /* Variable to change. */
26406 const arm_feature_set value; /* What to change it to. */
26407 const char * deprecated; /* If non-null, print this message. */
e74cfd16 26408};
b99bd4ef 26409
e74cfd16
PB
26410const struct arm_legacy_option_table arm_legacy_opts[] =
26411{
c19d1205
ZW
26412 /* DON'T add any new processors to this list -- we want the whole list
26413 to go away... Add them to the processors table instead. */
e74cfd16
PB
26414 {"marm1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
26415 {"m1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
26416 {"marm2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
26417 {"m2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
26418 {"marm250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
26419 {"m250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
26420 {"marm3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
26421 {"m3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
26422 {"marm6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
26423 {"m6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
26424 {"marm600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
26425 {"m600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
26426 {"marm610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
26427 {"m610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
26428 {"marm620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
26429 {"m620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
26430 {"marm7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
26431 {"m7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
26432 {"marm70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
26433 {"m70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
26434 {"marm700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
26435 {"m700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
26436 {"marm700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
26437 {"m700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
26438 {"marm710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
26439 {"m710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
26440 {"marm710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
26441 {"m710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
26442 {"marm720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
26443 {"m720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
26444 {"marm7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
26445 {"m7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
26446 {"marm7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
26447 {"m7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
26448 {"marm7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
26449 {"m7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
26450 {"marm7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
26451 {"m7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
26452 {"marm7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
26453 {"m7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
26454 {"marm7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
26455 {"m7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
26456 {"marm7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
26457 {"m7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
26458 {"marm7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
26459 {"m7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
26460 {"marm7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
26461 {"m7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
26462 {"marm7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
26463 {"m7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
26464 {"marm710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
26465 {"m710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
26466 {"marm720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
26467 {"m720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
26468 {"marm740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
26469 {"m740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
26470 {"marm8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
26471 {"m8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
26472 {"marm810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
26473 {"m810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
26474 {"marm9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
26475 {"m9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
26476 {"marm9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
26477 {"m9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
26478 {"marm920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
26479 {"m920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
26480 {"marm940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
26481 {"m940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
26482 {"mstrongarm", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")},
26483 {"mstrongarm110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 26484 N_("use -mcpu=strongarm110")},
e74cfd16 26485 {"mstrongarm1100", &legacy_cpu, ARM_ARCH_V4,
c19d1205 26486 N_("use -mcpu=strongarm1100")},
e74cfd16 26487 {"mstrongarm1110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 26488 N_("use -mcpu=strongarm1110")},
e74cfd16
PB
26489 {"mxscale", &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
26490 {"miwmmxt", &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
26491 {"mall", &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
7ed4c4c5 26492
c19d1205 26493 /* Architecture variants -- don't add any more to this list either. */
e74cfd16
PB
26494 {"mv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
26495 {"marmv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
26496 {"mv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
26497 {"marmv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
26498 {"mv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
26499 {"marmv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
26500 {"mv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
26501 {"marmv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
26502 {"mv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
26503 {"marmv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
26504 {"mv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
26505 {"marmv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
26506 {"mv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
26507 {"marmv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
26508 {"mv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
26509 {"marmv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
26510 {"mv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
26511 {"marmv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
7ed4c4c5 26512
c19d1205 26513 /* Floating point variants -- don't add any more to this list either. */
0198d5e6
TC
26514 {"mfpe-old", &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
26515 {"mfpa10", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
26516 {"mfpa11", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
26517 {"mno-fpu", &legacy_fpu, ARM_ARCH_NONE,
c19d1205 26518 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
7ed4c4c5 26519
e74cfd16 26520 {NULL, NULL, ARM_ARCH_NONE, NULL}
c19d1205 26521};
7ed4c4c5 26522
c19d1205 26523struct arm_cpu_option_table
7ed4c4c5 26524{
0198d5e6
TC
26525 const char * name;
26526 size_t name_len;
26527 const arm_feature_set value;
26528 const arm_feature_set ext;
c19d1205
ZW
26529 /* For some CPUs we assume an FPU unless the user explicitly sets
26530 -mfpu=... */
0198d5e6 26531 const arm_feature_set default_fpu;
ee065d83
PB
26532 /* The canonical name of the CPU, or NULL to use NAME converted to upper
26533 case. */
0198d5e6 26534 const char * canonical_name;
c19d1205 26535};
7ed4c4c5 26536
c19d1205
ZW
26537/* This list should, at a minimum, contain all the cpu names
26538 recognized by GCC. */
996b5569 26539#define ARM_CPU_OPT(N, CN, V, E, DF) { N, sizeof (N) - 1, V, E, DF, CN }
0198d5e6 26540
e74cfd16 26541static const struct arm_cpu_option_table arm_cpus[] =
c19d1205 26542{
996b5569
TP
26543 ARM_CPU_OPT ("all", NULL, ARM_ANY,
26544 ARM_ARCH_NONE,
26545 FPU_ARCH_FPA),
26546 ARM_CPU_OPT ("arm1", NULL, ARM_ARCH_V1,
26547 ARM_ARCH_NONE,
26548 FPU_ARCH_FPA),
26549 ARM_CPU_OPT ("arm2", NULL, ARM_ARCH_V2,
26550 ARM_ARCH_NONE,
26551 FPU_ARCH_FPA),
26552 ARM_CPU_OPT ("arm250", NULL, ARM_ARCH_V2S,
26553 ARM_ARCH_NONE,
26554 FPU_ARCH_FPA),
26555 ARM_CPU_OPT ("arm3", NULL, ARM_ARCH_V2S,
26556 ARM_ARCH_NONE,
26557 FPU_ARCH_FPA),
26558 ARM_CPU_OPT ("arm6", NULL, ARM_ARCH_V3,
26559 ARM_ARCH_NONE,
26560 FPU_ARCH_FPA),
26561 ARM_CPU_OPT ("arm60", NULL, ARM_ARCH_V3,
26562 ARM_ARCH_NONE,
26563 FPU_ARCH_FPA),
26564 ARM_CPU_OPT ("arm600", NULL, ARM_ARCH_V3,
26565 ARM_ARCH_NONE,
26566 FPU_ARCH_FPA),
26567 ARM_CPU_OPT ("arm610", NULL, ARM_ARCH_V3,
26568 ARM_ARCH_NONE,
26569 FPU_ARCH_FPA),
26570 ARM_CPU_OPT ("arm620", NULL, ARM_ARCH_V3,
26571 ARM_ARCH_NONE,
26572 FPU_ARCH_FPA),
26573 ARM_CPU_OPT ("arm7", NULL, ARM_ARCH_V3,
26574 ARM_ARCH_NONE,
26575 FPU_ARCH_FPA),
26576 ARM_CPU_OPT ("arm7m", NULL, ARM_ARCH_V3M,
26577 ARM_ARCH_NONE,
26578 FPU_ARCH_FPA),
26579 ARM_CPU_OPT ("arm7d", NULL, ARM_ARCH_V3,
26580 ARM_ARCH_NONE,
26581 FPU_ARCH_FPA),
26582 ARM_CPU_OPT ("arm7dm", NULL, ARM_ARCH_V3M,
26583 ARM_ARCH_NONE,
26584 FPU_ARCH_FPA),
26585 ARM_CPU_OPT ("arm7di", NULL, ARM_ARCH_V3,
26586 ARM_ARCH_NONE,
26587 FPU_ARCH_FPA),
26588 ARM_CPU_OPT ("arm7dmi", NULL, ARM_ARCH_V3M,
26589 ARM_ARCH_NONE,
26590 FPU_ARCH_FPA),
26591 ARM_CPU_OPT ("arm70", NULL, ARM_ARCH_V3,
26592 ARM_ARCH_NONE,
26593 FPU_ARCH_FPA),
26594 ARM_CPU_OPT ("arm700", NULL, ARM_ARCH_V3,
26595 ARM_ARCH_NONE,
26596 FPU_ARCH_FPA),
26597 ARM_CPU_OPT ("arm700i", NULL, ARM_ARCH_V3,
26598 ARM_ARCH_NONE,
26599 FPU_ARCH_FPA),
26600 ARM_CPU_OPT ("arm710", NULL, ARM_ARCH_V3,
26601 ARM_ARCH_NONE,
26602 FPU_ARCH_FPA),
26603 ARM_CPU_OPT ("arm710t", NULL, ARM_ARCH_V4T,
26604 ARM_ARCH_NONE,
26605 FPU_ARCH_FPA),
26606 ARM_CPU_OPT ("arm720", NULL, ARM_ARCH_V3,
26607 ARM_ARCH_NONE,
26608 FPU_ARCH_FPA),
26609 ARM_CPU_OPT ("arm720t", NULL, ARM_ARCH_V4T,
26610 ARM_ARCH_NONE,
26611 FPU_ARCH_FPA),
26612 ARM_CPU_OPT ("arm740t", NULL, ARM_ARCH_V4T,
26613 ARM_ARCH_NONE,
26614 FPU_ARCH_FPA),
26615 ARM_CPU_OPT ("arm710c", NULL, ARM_ARCH_V3,
26616 ARM_ARCH_NONE,
26617 FPU_ARCH_FPA),
26618 ARM_CPU_OPT ("arm7100", NULL, ARM_ARCH_V3,
26619 ARM_ARCH_NONE,
26620 FPU_ARCH_FPA),
26621 ARM_CPU_OPT ("arm7500", NULL, ARM_ARCH_V3,
26622 ARM_ARCH_NONE,
26623 FPU_ARCH_FPA),
26624 ARM_CPU_OPT ("arm7500fe", NULL, ARM_ARCH_V3,
26625 ARM_ARCH_NONE,
26626 FPU_ARCH_FPA),
26627 ARM_CPU_OPT ("arm7t", NULL, ARM_ARCH_V4T,
26628 ARM_ARCH_NONE,
26629 FPU_ARCH_FPA),
26630 ARM_CPU_OPT ("arm7tdmi", NULL, ARM_ARCH_V4T,
26631 ARM_ARCH_NONE,
26632 FPU_ARCH_FPA),
26633 ARM_CPU_OPT ("arm7tdmi-s", NULL, ARM_ARCH_V4T,
26634 ARM_ARCH_NONE,
26635 FPU_ARCH_FPA),
26636 ARM_CPU_OPT ("arm8", NULL, ARM_ARCH_V4,
26637 ARM_ARCH_NONE,
26638 FPU_ARCH_FPA),
26639 ARM_CPU_OPT ("arm810", NULL, ARM_ARCH_V4,
26640 ARM_ARCH_NONE,
26641 FPU_ARCH_FPA),
26642 ARM_CPU_OPT ("strongarm", NULL, ARM_ARCH_V4,
26643 ARM_ARCH_NONE,
26644 FPU_ARCH_FPA),
26645 ARM_CPU_OPT ("strongarm1", NULL, ARM_ARCH_V4,
26646 ARM_ARCH_NONE,
26647 FPU_ARCH_FPA),
26648 ARM_CPU_OPT ("strongarm110", NULL, ARM_ARCH_V4,
26649 ARM_ARCH_NONE,
26650 FPU_ARCH_FPA),
26651 ARM_CPU_OPT ("strongarm1100", NULL, ARM_ARCH_V4,
26652 ARM_ARCH_NONE,
26653 FPU_ARCH_FPA),
26654 ARM_CPU_OPT ("strongarm1110", NULL, ARM_ARCH_V4,
26655 ARM_ARCH_NONE,
26656 FPU_ARCH_FPA),
26657 ARM_CPU_OPT ("arm9", NULL, ARM_ARCH_V4T,
26658 ARM_ARCH_NONE,
26659 FPU_ARCH_FPA),
26660 ARM_CPU_OPT ("arm920", "ARM920T", ARM_ARCH_V4T,
26661 ARM_ARCH_NONE,
26662 FPU_ARCH_FPA),
26663 ARM_CPU_OPT ("arm920t", NULL, ARM_ARCH_V4T,
26664 ARM_ARCH_NONE,
26665 FPU_ARCH_FPA),
26666 ARM_CPU_OPT ("arm922t", NULL, ARM_ARCH_V4T,
26667 ARM_ARCH_NONE,
26668 FPU_ARCH_FPA),
26669 ARM_CPU_OPT ("arm940t", NULL, ARM_ARCH_V4T,
26670 ARM_ARCH_NONE,
26671 FPU_ARCH_FPA),
26672 ARM_CPU_OPT ("arm9tdmi", NULL, ARM_ARCH_V4T,
26673 ARM_ARCH_NONE,
26674 FPU_ARCH_FPA),
26675 ARM_CPU_OPT ("fa526", NULL, ARM_ARCH_V4,
26676 ARM_ARCH_NONE,
26677 FPU_ARCH_FPA),
26678 ARM_CPU_OPT ("fa626", NULL, ARM_ARCH_V4,
26679 ARM_ARCH_NONE,
26680 FPU_ARCH_FPA),
26681
c19d1205
ZW
26682 /* For V5 or later processors we default to using VFP; but the user
26683 should really set the FPU type explicitly. */
996b5569
TP
26684 ARM_CPU_OPT ("arm9e-r0", NULL, ARM_ARCH_V5TExP,
26685 ARM_ARCH_NONE,
26686 FPU_ARCH_VFP_V2),
26687 ARM_CPU_OPT ("arm9e", NULL, ARM_ARCH_V5TE,
26688 ARM_ARCH_NONE,
26689 FPU_ARCH_VFP_V2),
26690 ARM_CPU_OPT ("arm926ej", "ARM926EJ-S", ARM_ARCH_V5TEJ,
26691 ARM_ARCH_NONE,
26692 FPU_ARCH_VFP_V2),
26693 ARM_CPU_OPT ("arm926ejs", "ARM926EJ-S", ARM_ARCH_V5TEJ,
26694 ARM_ARCH_NONE,
26695 FPU_ARCH_VFP_V2),
26696 ARM_CPU_OPT ("arm926ej-s", NULL, ARM_ARCH_V5TEJ,
26697 ARM_ARCH_NONE,
26698 FPU_ARCH_VFP_V2),
26699 ARM_CPU_OPT ("arm946e-r0", NULL, ARM_ARCH_V5TExP,
26700 ARM_ARCH_NONE,
26701 FPU_ARCH_VFP_V2),
26702 ARM_CPU_OPT ("arm946e", "ARM946E-S", ARM_ARCH_V5TE,
26703 ARM_ARCH_NONE,
26704 FPU_ARCH_VFP_V2),
26705 ARM_CPU_OPT ("arm946e-s", NULL, ARM_ARCH_V5TE,
26706 ARM_ARCH_NONE,
26707 FPU_ARCH_VFP_V2),
26708 ARM_CPU_OPT ("arm966e-r0", NULL, ARM_ARCH_V5TExP,
26709 ARM_ARCH_NONE,
26710 FPU_ARCH_VFP_V2),
26711 ARM_CPU_OPT ("arm966e", "ARM966E-S", ARM_ARCH_V5TE,
26712 ARM_ARCH_NONE,
26713 FPU_ARCH_VFP_V2),
26714 ARM_CPU_OPT ("arm966e-s", NULL, ARM_ARCH_V5TE,
26715 ARM_ARCH_NONE,
26716 FPU_ARCH_VFP_V2),
26717 ARM_CPU_OPT ("arm968e-s", NULL, ARM_ARCH_V5TE,
26718 ARM_ARCH_NONE,
26719 FPU_ARCH_VFP_V2),
26720 ARM_CPU_OPT ("arm10t", NULL, ARM_ARCH_V5T,
26721 ARM_ARCH_NONE,
26722 FPU_ARCH_VFP_V1),
26723 ARM_CPU_OPT ("arm10tdmi", NULL, ARM_ARCH_V5T,
26724 ARM_ARCH_NONE,
26725 FPU_ARCH_VFP_V1),
26726 ARM_CPU_OPT ("arm10e", NULL, ARM_ARCH_V5TE,
26727 ARM_ARCH_NONE,
26728 FPU_ARCH_VFP_V2),
26729 ARM_CPU_OPT ("arm1020", "ARM1020E", ARM_ARCH_V5TE,
26730 ARM_ARCH_NONE,
26731 FPU_ARCH_VFP_V2),
26732 ARM_CPU_OPT ("arm1020t", NULL, ARM_ARCH_V5T,
26733 ARM_ARCH_NONE,
26734 FPU_ARCH_VFP_V1),
26735 ARM_CPU_OPT ("arm1020e", NULL, ARM_ARCH_V5TE,
26736 ARM_ARCH_NONE,
26737 FPU_ARCH_VFP_V2),
26738 ARM_CPU_OPT ("arm1022e", NULL, ARM_ARCH_V5TE,
26739 ARM_ARCH_NONE,
26740 FPU_ARCH_VFP_V2),
26741 ARM_CPU_OPT ("arm1026ejs", "ARM1026EJ-S", ARM_ARCH_V5TEJ,
26742 ARM_ARCH_NONE,
26743 FPU_ARCH_VFP_V2),
26744 ARM_CPU_OPT ("arm1026ej-s", NULL, ARM_ARCH_V5TEJ,
26745 ARM_ARCH_NONE,
26746 FPU_ARCH_VFP_V2),
26747 ARM_CPU_OPT ("fa606te", NULL, ARM_ARCH_V5TE,
26748 ARM_ARCH_NONE,
26749 FPU_ARCH_VFP_V2),
26750 ARM_CPU_OPT ("fa616te", NULL, ARM_ARCH_V5TE,
26751 ARM_ARCH_NONE,
26752 FPU_ARCH_VFP_V2),
26753 ARM_CPU_OPT ("fa626te", NULL, ARM_ARCH_V5TE,
26754 ARM_ARCH_NONE,
26755 FPU_ARCH_VFP_V2),
26756 ARM_CPU_OPT ("fmp626", NULL, ARM_ARCH_V5TE,
26757 ARM_ARCH_NONE,
26758 FPU_ARCH_VFP_V2),
26759 ARM_CPU_OPT ("fa726te", NULL, ARM_ARCH_V5TE,
26760 ARM_ARCH_NONE,
26761 FPU_ARCH_VFP_V2),
26762 ARM_CPU_OPT ("arm1136js", "ARM1136J-S", ARM_ARCH_V6,
26763 ARM_ARCH_NONE,
26764 FPU_NONE),
26765 ARM_CPU_OPT ("arm1136j-s", NULL, ARM_ARCH_V6,
26766 ARM_ARCH_NONE,
26767 FPU_NONE),
26768 ARM_CPU_OPT ("arm1136jfs", "ARM1136JF-S", ARM_ARCH_V6,
26769 ARM_ARCH_NONE,
26770 FPU_ARCH_VFP_V2),
26771 ARM_CPU_OPT ("arm1136jf-s", NULL, ARM_ARCH_V6,
26772 ARM_ARCH_NONE,
26773 FPU_ARCH_VFP_V2),
26774 ARM_CPU_OPT ("mpcore", "MPCore", ARM_ARCH_V6K,
26775 ARM_ARCH_NONE,
26776 FPU_ARCH_VFP_V2),
26777 ARM_CPU_OPT ("mpcorenovfp", "MPCore", ARM_ARCH_V6K,
26778 ARM_ARCH_NONE,
26779 FPU_NONE),
26780 ARM_CPU_OPT ("arm1156t2-s", NULL, ARM_ARCH_V6T2,
26781 ARM_ARCH_NONE,
26782 FPU_NONE),
26783 ARM_CPU_OPT ("arm1156t2f-s", NULL, ARM_ARCH_V6T2,
26784 ARM_ARCH_NONE,
26785 FPU_ARCH_VFP_V2),
26786 ARM_CPU_OPT ("arm1176jz-s", NULL, ARM_ARCH_V6KZ,
26787 ARM_ARCH_NONE,
26788 FPU_NONE),
26789 ARM_CPU_OPT ("arm1176jzf-s", NULL, ARM_ARCH_V6KZ,
26790 ARM_ARCH_NONE,
26791 FPU_ARCH_VFP_V2),
26792 ARM_CPU_OPT ("cortex-a5", "Cortex-A5", ARM_ARCH_V7A,
26793 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
26794 FPU_NONE),
26795 ARM_CPU_OPT ("cortex-a7", "Cortex-A7", ARM_ARCH_V7VE,
26796 ARM_ARCH_NONE,
26797 FPU_ARCH_NEON_VFP_V4),
26798 ARM_CPU_OPT ("cortex-a8", "Cortex-A8", ARM_ARCH_V7A,
26799 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
26800 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
26801 ARM_CPU_OPT ("cortex-a9", "Cortex-A9", ARM_ARCH_V7A,
26802 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
26803 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
26804 ARM_CPU_OPT ("cortex-a12", "Cortex-A12", ARM_ARCH_V7VE,
26805 ARM_ARCH_NONE,
26806 FPU_ARCH_NEON_VFP_V4),
26807 ARM_CPU_OPT ("cortex-a15", "Cortex-A15", ARM_ARCH_V7VE,
26808 ARM_ARCH_NONE,
26809 FPU_ARCH_NEON_VFP_V4),
26810 ARM_CPU_OPT ("cortex-a17", "Cortex-A17", ARM_ARCH_V7VE,
26811 ARM_ARCH_NONE,
26812 FPU_ARCH_NEON_VFP_V4),
26813 ARM_CPU_OPT ("cortex-a32", "Cortex-A32", ARM_ARCH_V8A,
26814 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26815 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
26816 ARM_CPU_OPT ("cortex-a35", "Cortex-A35", ARM_ARCH_V8A,
26817 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26818 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
26819 ARM_CPU_OPT ("cortex-a53", "Cortex-A53", ARM_ARCH_V8A,
26820 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26821 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
26822 ARM_CPU_OPT ("cortex-a55", "Cortex-A55", ARM_ARCH_V8_2A,
26823 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 26824 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569
TP
26825 ARM_CPU_OPT ("cortex-a57", "Cortex-A57", ARM_ARCH_V8A,
26826 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26827 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
26828 ARM_CPU_OPT ("cortex-a72", "Cortex-A72", ARM_ARCH_V8A,
26829 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26830 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
26831 ARM_CPU_OPT ("cortex-a73", "Cortex-A73", ARM_ARCH_V8A,
26832 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26833 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
26834 ARM_CPU_OPT ("cortex-a75", "Cortex-A75", ARM_ARCH_V8_2A,
26835 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 26836 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
7ebd1359 26837 ARM_CPU_OPT ("cortex-a76", "Cortex-A76", ARM_ARCH_V8_2A,
26838 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
26839 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
ef8df4ca
KT
26840 ARM_CPU_OPT ("ares", "Ares", ARM_ARCH_V8_2A,
26841 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
26842 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569
TP
26843 ARM_CPU_OPT ("cortex-r4", "Cortex-R4", ARM_ARCH_V7R,
26844 ARM_ARCH_NONE,
26845 FPU_NONE),
26846 ARM_CPU_OPT ("cortex-r4f", "Cortex-R4F", ARM_ARCH_V7R,
26847 ARM_ARCH_NONE,
26848 FPU_ARCH_VFP_V3D16),
26849 ARM_CPU_OPT ("cortex-r5", "Cortex-R5", ARM_ARCH_V7R,
26850 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
26851 FPU_NONE),
26852 ARM_CPU_OPT ("cortex-r7", "Cortex-R7", ARM_ARCH_V7R,
26853 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
26854 FPU_ARCH_VFP_V3D16),
26855 ARM_CPU_OPT ("cortex-r8", "Cortex-R8", ARM_ARCH_V7R,
26856 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
26857 FPU_ARCH_VFP_V3D16),
0cda1e19
TP
26858 ARM_CPU_OPT ("cortex-r52", "Cortex-R52", ARM_ARCH_V8R,
26859 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26860 FPU_ARCH_NEON_VFP_ARMV8),
996b5569
TP
26861 ARM_CPU_OPT ("cortex-m33", "Cortex-M33", ARM_ARCH_V8M_MAIN,
26862 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
26863 FPU_NONE),
26864 ARM_CPU_OPT ("cortex-m23", "Cortex-M23", ARM_ARCH_V8M_BASE,
26865 ARM_ARCH_NONE,
26866 FPU_NONE),
26867 ARM_CPU_OPT ("cortex-m7", "Cortex-M7", ARM_ARCH_V7EM,
26868 ARM_ARCH_NONE,
26869 FPU_NONE),
26870 ARM_CPU_OPT ("cortex-m4", "Cortex-M4", ARM_ARCH_V7EM,
26871 ARM_ARCH_NONE,
26872 FPU_NONE),
26873 ARM_CPU_OPT ("cortex-m3", "Cortex-M3", ARM_ARCH_V7M,
26874 ARM_ARCH_NONE,
26875 FPU_NONE),
26876 ARM_CPU_OPT ("cortex-m1", "Cortex-M1", ARM_ARCH_V6SM,
26877 ARM_ARCH_NONE,
26878 FPU_NONE),
26879 ARM_CPU_OPT ("cortex-m0", "Cortex-M0", ARM_ARCH_V6SM,
26880 ARM_ARCH_NONE,
26881 FPU_NONE),
26882 ARM_CPU_OPT ("cortex-m0plus", "Cortex-M0+", ARM_ARCH_V6SM,
26883 ARM_ARCH_NONE,
26884 FPU_NONE),
26885 ARM_CPU_OPT ("exynos-m1", "Samsung Exynos M1", ARM_ARCH_V8A,
26886 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26887 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
83f43c83
KT
26888 ARM_CPU_OPT ("neoverse-n1", "Neoverse N1", ARM_ARCH_V8_2A,
26889 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
26890 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
c19d1205 26891 /* ??? XSCALE is really an architecture. */
996b5569
TP
26892 ARM_CPU_OPT ("xscale", NULL, ARM_ARCH_XSCALE,
26893 ARM_ARCH_NONE,
26894 FPU_ARCH_VFP_V2),
26895
c19d1205 26896 /* ??? iwmmxt is not a processor. */
996b5569
TP
26897 ARM_CPU_OPT ("iwmmxt", NULL, ARM_ARCH_IWMMXT,
26898 ARM_ARCH_NONE,
26899 FPU_ARCH_VFP_V2),
26900 ARM_CPU_OPT ("iwmmxt2", NULL, ARM_ARCH_IWMMXT2,
26901 ARM_ARCH_NONE,
26902 FPU_ARCH_VFP_V2),
26903 ARM_CPU_OPT ("i80200", NULL, ARM_ARCH_XSCALE,
26904 ARM_ARCH_NONE,
26905 FPU_ARCH_VFP_V2),
26906
0198d5e6 26907 /* Maverick. */
996b5569
TP
26908 ARM_CPU_OPT ("ep9312", "ARM920T",
26909 ARM_FEATURE_LOW (ARM_AEXT_V4T, ARM_CEXT_MAVERICK),
26910 ARM_ARCH_NONE, FPU_ARCH_MAVERICK),
26911
da4339ed 26912 /* Marvell processors. */
996b5569
TP
26913 ARM_CPU_OPT ("marvell-pj4", NULL, ARM_ARCH_V7A,
26914 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
26915 FPU_ARCH_VFP_V3D16),
26916 ARM_CPU_OPT ("marvell-whitney", NULL, ARM_ARCH_V7A,
26917 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
26918 FPU_ARCH_NEON_VFP_V4),
da4339ed 26919
996b5569
TP
26920 /* APM X-Gene family. */
26921 ARM_CPU_OPT ("xgene1", "APM X-Gene 1", ARM_ARCH_V8A,
26922 ARM_ARCH_NONE,
26923 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
26924 ARM_CPU_OPT ("xgene2", "APM X-Gene 2", ARM_ARCH_V8A,
26925 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26926 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
26927
26928 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 26929};
f3bad469 26930#undef ARM_CPU_OPT
7ed4c4c5 26931
34ef62f4
AV
26932struct arm_ext_table
26933{
26934 const char * name;
26935 size_t name_len;
26936 const arm_feature_set merge;
26937 const arm_feature_set clear;
26938};
26939
c19d1205 26940struct arm_arch_option_table
7ed4c4c5 26941{
34ef62f4
AV
26942 const char * name;
26943 size_t name_len;
26944 const arm_feature_set value;
26945 const arm_feature_set default_fpu;
26946 const struct arm_ext_table * ext_table;
26947};
26948
26949/* Used to add support for +E and +noE extension. */
26950#define ARM_EXT(E, M, C) { E, sizeof (E) - 1, M, C }
26951/* Used to add support for a +E extension. */
26952#define ARM_ADD(E, M) { E, sizeof(E) - 1, M, ARM_ARCH_NONE }
26953/* Used to add support for a +noE extension. */
26954#define ARM_REMOVE(E, C) { E, sizeof(E) -1, ARM_ARCH_NONE, C }
26955
26956#define ALL_FP ARM_FEATURE (0, ARM_EXT2_FP16_INST | ARM_EXT2_FP16_FML, \
26957 ~0 & ~FPU_ENDIAN_PURE)
26958
26959static const struct arm_ext_table armv5te_ext_table[] =
26960{
26961 ARM_EXT ("fp", FPU_ARCH_VFP_V2, ALL_FP),
26962 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
26963};
26964
26965static const struct arm_ext_table armv7_ext_table[] =
26966{
26967 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
26968 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
26969};
26970
26971static const struct arm_ext_table armv7ve_ext_table[] =
26972{
26973 ARM_EXT ("fp", FPU_ARCH_VFP_V4D16, ALL_FP),
26974 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16),
26975 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
26976 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
26977 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
26978 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16), /* Alias for +fp. */
26979 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
26980
26981 ARM_EXT ("simd", FPU_ARCH_NEON_VFP_V4,
26982 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
26983
26984 /* Aliases for +simd. */
26985 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
26986
26987 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
26988 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
26989 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
26990
26991 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
26992};
26993
26994static const struct arm_ext_table armv7a_ext_table[] =
26995{
26996 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
26997 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
26998 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
26999 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
27000 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
27001 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16),
27002 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
27003
27004 ARM_EXT ("simd", FPU_ARCH_VFP_V3_PLUS_NEON_V1,
27005 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
27006
27007 /* Aliases for +simd. */
27008 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
27009 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
27010
27011 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
27012 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
27013
27014 ARM_ADD ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP)),
27015 ARM_ADD ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC)),
27016 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27017};
27018
27019static const struct arm_ext_table armv7r_ext_table[] =
27020{
27021 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V3xD),
27022 ARM_ADD ("vfpv3xd", FPU_ARCH_VFP_V3xD), /* Alias for +fp.sp. */
27023 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
27024 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
27025 ARM_ADD ("vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16),
27026 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
27027 ARM_EXT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
27028 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV)),
27029 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27030};
27031
27032static const struct arm_ext_table armv7em_ext_table[] =
27033{
27034 ARM_EXT ("fp", FPU_ARCH_VFP_V4_SP_D16, ALL_FP),
27035 /* Alias for +fp, used to be known as fpv4-sp-d16. */
27036 ARM_ADD ("vfpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16),
27037 ARM_ADD ("fpv5", FPU_ARCH_VFP_V5_SP_D16),
27038 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
27039 ARM_ADD ("fpv5-d16", FPU_ARCH_VFP_V5D16),
27040 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27041};
27042
27043static const struct arm_ext_table armv8a_ext_table[] =
27044{
27045 ARM_ADD ("crc", ARCH_CRC_ARMV8),
27046 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
27047 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
27048 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
27049
27050 /* Armv8-a does not allow an FP implementation without SIMD, so the user
27051 should use the +simd option to turn on FP. */
27052 ARM_REMOVE ("fp", ALL_FP),
27053 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
27054 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
27055 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27056};
27057
27058
27059static const struct arm_ext_table armv81a_ext_table[] =
27060{
27061 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
27062 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
27063 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
27064
27065 /* Armv8-a does not allow an FP implementation without SIMD, so the user
27066 should use the +simd option to turn on FP. */
27067 ARM_REMOVE ("fp", ALL_FP),
27068 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
27069 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
27070 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27071};
27072
27073static const struct arm_ext_table armv82a_ext_table[] =
27074{
27075 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
27076 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_2_FP16),
27077 ARM_ADD ("fp16fml", FPU_ARCH_NEON_VFP_ARMV8_2_FP16FML),
27078 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
27079 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
27080 ARM_ADD ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
27081
27082 /* Armv8-a does not allow an FP implementation without SIMD, so the user
27083 should use the +simd option to turn on FP. */
27084 ARM_REMOVE ("fp", ALL_FP),
27085 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
27086 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
27087 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27088};
27089
27090static const struct arm_ext_table armv84a_ext_table[] =
27091{
27092 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
27093 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
27094 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
27095 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
27096
27097 /* Armv8-a does not allow an FP implementation without SIMD, so the user
27098 should use the +simd option to turn on FP. */
27099 ARM_REMOVE ("fp", ALL_FP),
27100 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
27101 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
27102 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27103};
27104
27105static const struct arm_ext_table armv85a_ext_table[] =
27106{
27107 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
27108 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
27109 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
27110 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
27111
27112 /* Armv8-a does not allow an FP implementation without SIMD, so the user
27113 should use the +simd option to turn on FP. */
27114 ARM_REMOVE ("fp", ALL_FP),
27115 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27116};
27117
27118static const struct arm_ext_table armv8m_main_ext_table[] =
27119{
27120 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
27121 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP)),
27122 ARM_EXT ("fp", FPU_ARCH_VFP_V5_SP_D16, ALL_FP),
27123 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
27124 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27125};
27126
e0991585
AV
27127static const struct arm_ext_table armv8_1m_main_ext_table[] =
27128{
27129 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
27130 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP)),
27131 ARM_EXT ("fp",
27132 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
27133 FPU_VFP_V5_SP_D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA),
27134 ALL_FP),
27135 ARM_ADD ("fp.dp",
27136 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
27137 FPU_VFP_V5D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
27138 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27139};
27140
34ef62f4
AV
27141static const struct arm_ext_table armv8r_ext_table[] =
27142{
27143 ARM_ADD ("crc", ARCH_CRC_ARMV8),
27144 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
27145 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
27146 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
27147 ARM_REMOVE ("fp", ALL_FP),
27148 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V5_SP_D16),
27149 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
c19d1205 27150};
7ed4c4c5 27151
c19d1205
ZW
27152/* This list should, at a minimum, contain all the architecture names
27153 recognized by GCC. */
34ef62f4
AV
27154#define ARM_ARCH_OPT(N, V, DF) { N, sizeof (N) - 1, V, DF, NULL }
27155#define ARM_ARCH_OPT2(N, V, DF, ext) \
27156 { N, sizeof (N) - 1, V, DF, ext##_ext_table }
0198d5e6 27157
e74cfd16 27158static const struct arm_arch_option_table arm_archs[] =
c19d1205 27159{
497d849d
TP
27160 ARM_ARCH_OPT ("all", ARM_ANY, FPU_ARCH_FPA),
27161 ARM_ARCH_OPT ("armv1", ARM_ARCH_V1, FPU_ARCH_FPA),
27162 ARM_ARCH_OPT ("armv2", ARM_ARCH_V2, FPU_ARCH_FPA),
27163 ARM_ARCH_OPT ("armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA),
27164 ARM_ARCH_OPT ("armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA),
27165 ARM_ARCH_OPT ("armv3", ARM_ARCH_V3, FPU_ARCH_FPA),
27166 ARM_ARCH_OPT ("armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA),
27167 ARM_ARCH_OPT ("armv4", ARM_ARCH_V4, FPU_ARCH_FPA),
27168 ARM_ARCH_OPT ("armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA),
27169 ARM_ARCH_OPT ("armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA),
27170 ARM_ARCH_OPT ("armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA),
27171 ARM_ARCH_OPT ("armv5", ARM_ARCH_V5, FPU_ARCH_VFP),
27172 ARM_ARCH_OPT ("armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP),
27173 ARM_ARCH_OPT ("armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP),
34ef62f4
AV
27174 ARM_ARCH_OPT2 ("armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP, armv5te),
27175 ARM_ARCH_OPT2 ("armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP, armv5te),
27176 ARM_ARCH_OPT2 ("armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP, armv5te),
27177 ARM_ARCH_OPT2 ("armv6", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
27178 ARM_ARCH_OPT2 ("armv6j", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
27179 ARM_ARCH_OPT2 ("armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP, armv5te),
27180 ARM_ARCH_OPT2 ("armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP, armv5te),
f33026a9
MW
27181 /* The official spelling of this variant is ARMv6KZ, the name "armv6zk" is
27182 kept to preserve existing behaviour. */
34ef62f4
AV
27183 ARM_ARCH_OPT2 ("armv6kz", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
27184 ARM_ARCH_OPT2 ("armv6zk", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
27185 ARM_ARCH_OPT2 ("armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP, armv5te),
27186 ARM_ARCH_OPT2 ("armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP, armv5te),
27187 ARM_ARCH_OPT2 ("armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP, armv5te),
f33026a9
MW
27188 /* The official spelling of this variant is ARMv6KZ, the name "armv6zkt2" is
27189 kept to preserve existing behaviour. */
34ef62f4
AV
27190 ARM_ARCH_OPT2 ("armv6kzt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
27191 ARM_ARCH_OPT2 ("armv6zkt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
497d849d
TP
27192 ARM_ARCH_OPT ("armv6-m", ARM_ARCH_V6M, FPU_ARCH_VFP),
27193 ARM_ARCH_OPT ("armv6s-m", ARM_ARCH_V6SM, FPU_ARCH_VFP),
34ef62f4 27194 ARM_ARCH_OPT2 ("armv7", ARM_ARCH_V7, FPU_ARCH_VFP, armv7),
c450d570
PB
27195 /* The official spelling of the ARMv7 profile variants is the dashed form.
27196 Accept the non-dashed form for compatibility with old toolchains. */
34ef62f4
AV
27197 ARM_ARCH_OPT2 ("armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
27198 ARM_ARCH_OPT2 ("armv7ve", ARM_ARCH_V7VE, FPU_ARCH_VFP, armv7ve),
27199 ARM_ARCH_OPT2 ("armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 27200 ARM_ARCH_OPT ("armv7m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4
AV
27201 ARM_ARCH_OPT2 ("armv7-a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
27202 ARM_ARCH_OPT2 ("armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 27203 ARM_ARCH_OPT ("armv7-m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4 27204 ARM_ARCH_OPT2 ("armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP, armv7em),
497d849d 27205 ARM_ARCH_OPT ("armv8-m.base", ARM_ARCH_V8M_BASE, FPU_ARCH_VFP),
34ef62f4
AV
27206 ARM_ARCH_OPT2 ("armv8-m.main", ARM_ARCH_V8M_MAIN, FPU_ARCH_VFP,
27207 armv8m_main),
e0991585
AV
27208 ARM_ARCH_OPT2 ("armv8.1-m.main", ARM_ARCH_V8_1M_MAIN, FPU_ARCH_VFP,
27209 armv8_1m_main),
34ef62f4
AV
27210 ARM_ARCH_OPT2 ("armv8-a", ARM_ARCH_V8A, FPU_ARCH_VFP, armv8a),
27211 ARM_ARCH_OPT2 ("armv8.1-a", ARM_ARCH_V8_1A, FPU_ARCH_VFP, armv81a),
27212 ARM_ARCH_OPT2 ("armv8.2-a", ARM_ARCH_V8_2A, FPU_ARCH_VFP, armv82a),
27213 ARM_ARCH_OPT2 ("armv8.3-a", ARM_ARCH_V8_3A, FPU_ARCH_VFP, armv82a),
27214 ARM_ARCH_OPT2 ("armv8-r", ARM_ARCH_V8R, FPU_ARCH_VFP, armv8r),
27215 ARM_ARCH_OPT2 ("armv8.4-a", ARM_ARCH_V8_4A, FPU_ARCH_VFP, armv84a),
27216 ARM_ARCH_OPT2 ("armv8.5-a", ARM_ARCH_V8_5A, FPU_ARCH_VFP, armv85a),
497d849d
TP
27217 ARM_ARCH_OPT ("xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP),
27218 ARM_ARCH_OPT ("iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP),
27219 ARM_ARCH_OPT ("iwmmxt2", ARM_ARCH_IWMMXT2, FPU_ARCH_VFP),
34ef62f4 27220 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 27221};
f3bad469 27222#undef ARM_ARCH_OPT
7ed4c4c5 27223
69133863 27224/* ISA extensions in the co-processor and main instruction set space. */
0198d5e6 27225
69133863 27226struct arm_option_extension_value_table
c19d1205 27227{
0198d5e6
TC
27228 const char * name;
27229 size_t name_len;
27230 const arm_feature_set merge_value;
27231 const arm_feature_set clear_value;
d942732e
TP
27232 /* List of architectures for which an extension is available. ARM_ARCH_NONE
27233 indicates that an extension is available for all architectures while
27234 ARM_ANY marks an empty entry. */
0198d5e6 27235 const arm_feature_set allowed_archs[2];
c19d1205 27236};
7ed4c4c5 27237
0198d5e6
TC
27238/* The following table must be in alphabetical order with a NULL last entry. */
27239
d942732e
TP
27240#define ARM_EXT_OPT(N, M, C, AA) { N, sizeof (N) - 1, M, C, { AA, ARM_ANY } }
27241#define ARM_EXT_OPT2(N, M, C, AA1, AA2) { N, sizeof (N) - 1, M, C, {AA1, AA2} }
0198d5e6 27242
34ef62f4
AV
27243/* DEPRECATED: Refrain from using this table to add any new extensions, instead
27244 use the context sensitive approach using arm_ext_table's. */
69133863 27245static const struct arm_option_extension_value_table arm_extensions[] =
c19d1205 27246{
823d2571
TG
27247 ARM_EXT_OPT ("crc", ARCH_CRC_ARMV8, ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
27248 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
bca38921 27249 ARM_EXT_OPT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
823d2571
TG
27250 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8),
27251 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
c604a79a
JW
27252 ARM_EXT_OPT ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8,
27253 ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD),
27254 ARM_ARCH_V8_2A),
15afaa63
TP
27255 ARM_EXT_OPT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
27256 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
27257 ARM_FEATURE_CORE (ARM_EXT_V7M, ARM_EXT2_V8M)),
823d2571
TG
27258 ARM_EXT_OPT ("fp", FPU_ARCH_VFP_ARMV8, ARM_FEATURE_COPROC (FPU_VFP_ARMV8),
27259 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
b8ec4e87
JW
27260 ARM_EXT_OPT ("fp16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
27261 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
27262 ARM_ARCH_V8_2A),
01f48020
TC
27263 ARM_EXT_OPT ("fp16fml", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
27264 | ARM_EXT2_FP16_FML),
27265 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
27266 | ARM_EXT2_FP16_FML),
27267 ARM_ARCH_V8_2A),
d942732e 27268 ARM_EXT_OPT2 ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
823d2571 27269 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
d942732e
TP
27270 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
27271 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
3d030cdb
TP
27272 /* Duplicate entry for the purpose of allowing ARMv7 to match in presence of
27273 Thumb divide instruction. Due to this having the same name as the
27274 previous entry, this will be ignored when doing command-line parsing and
27275 only considered by build attribute selection code. */
27276 ARM_EXT_OPT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
27277 ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
27278 ARM_FEATURE_CORE_LOW (ARM_EXT_V7)),
823d2571 27279 ARM_EXT_OPT ("iwmmxt",ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT),
d942732e 27280 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT), ARM_ARCH_NONE),
823d2571 27281 ARM_EXT_OPT ("iwmmxt2", ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2),
d942732e 27282 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2), ARM_ARCH_NONE),
823d2571 27283 ARM_EXT_OPT ("maverick", ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK),
d942732e
TP
27284 ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK), ARM_ARCH_NONE),
27285 ARM_EXT_OPT2 ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
823d2571 27286 ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
d942732e
TP
27287 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
27288 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
823d2571
TG
27289 ARM_EXT_OPT ("os", ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
27290 ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
27291 ARM_FEATURE_CORE_LOW (ARM_EXT_V6M)),
ddfded2f
MW
27292 ARM_EXT_OPT ("pan", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN),
27293 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_PAN, 0),
ced40572 27294 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
dad0c3bf
SD
27295 ARM_EXT_OPT ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
27296 ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
27297 ARM_ARCH_V8A),
4d1464f2
MW
27298 ARM_EXT_OPT ("ras", ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS),
27299 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_RAS, 0),
ced40572 27300 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
643afb90
MW
27301 ARM_EXT_OPT ("rdma", FPU_ARCH_NEON_VFP_ARMV8_1,
27302 ARM_FEATURE_COPROC (FPU_NEON_ARMV8 | FPU_NEON_EXT_RDMA),
ced40572 27303 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
7fadb25d
SD
27304 ARM_EXT_OPT ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
27305 ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
27306 ARM_ARCH_V8A),
d942732e 27307 ARM_EXT_OPT2 ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
823d2571 27308 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
d942732e
TP
27309 ARM_FEATURE_CORE_LOW (ARM_EXT_V6K),
27310 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
643afb90
MW
27311 ARM_EXT_OPT ("simd", FPU_ARCH_NEON_VFP_ARMV8,
27312 ARM_FEATURE_COPROC (FPU_NEON_ARMV8),
27313 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
823d2571
TG
27314 ARM_EXT_OPT ("virt", ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT | ARM_EXT_ADIV
27315 | ARM_EXT_DIV),
27316 ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT),
27317 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
27318 ARM_EXT_OPT ("xscale",ARM_FEATURE_COPROC (ARM_CEXT_XSCALE),
d942732e
TP
27319 ARM_FEATURE_COPROC (ARM_CEXT_XSCALE), ARM_ARCH_NONE),
27320 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, { ARM_ARCH_NONE, ARM_ARCH_NONE } }
69133863 27321};
f3bad469 27322#undef ARM_EXT_OPT
69133863
MGD
27323
27324/* ISA floating-point and Advanced SIMD extensions. */
27325struct arm_option_fpu_value_table
27326{
0198d5e6
TC
27327 const char * name;
27328 const arm_feature_set value;
c19d1205 27329};
7ed4c4c5 27330
c19d1205
ZW
27331/* This list should, at a minimum, contain all the fpu names
27332 recognized by GCC. */
69133863 27333static const struct arm_option_fpu_value_table arm_fpus[] =
c19d1205
ZW
27334{
27335 {"softfpa", FPU_NONE},
27336 {"fpe", FPU_ARCH_FPE},
27337 {"fpe2", FPU_ARCH_FPE},
27338 {"fpe3", FPU_ARCH_FPA}, /* Third release supports LFM/SFM. */
27339 {"fpa", FPU_ARCH_FPA},
27340 {"fpa10", FPU_ARCH_FPA},
27341 {"fpa11", FPU_ARCH_FPA},
27342 {"arm7500fe", FPU_ARCH_FPA},
27343 {"softvfp", FPU_ARCH_VFP},
27344 {"softvfp+vfp", FPU_ARCH_VFP_V2},
27345 {"vfp", FPU_ARCH_VFP_V2},
27346 {"vfp9", FPU_ARCH_VFP_V2},
d5e0ba9c 27347 {"vfp3", FPU_ARCH_VFP_V3}, /* Undocumented, use vfpv3. */
c19d1205
ZW
27348 {"vfp10", FPU_ARCH_VFP_V2},
27349 {"vfp10-r0", FPU_ARCH_VFP_V1},
27350 {"vfpxd", FPU_ARCH_VFP_V1xD},
b1cc4aeb
PB
27351 {"vfpv2", FPU_ARCH_VFP_V2},
27352 {"vfpv3", FPU_ARCH_VFP_V3},
62f3b8c8 27353 {"vfpv3-fp16", FPU_ARCH_VFP_V3_FP16},
b1cc4aeb 27354 {"vfpv3-d16", FPU_ARCH_VFP_V3D16},
62f3b8c8
PB
27355 {"vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16},
27356 {"vfpv3xd", FPU_ARCH_VFP_V3xD},
27357 {"vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16},
c19d1205
ZW
27358 {"arm1020t", FPU_ARCH_VFP_V1},
27359 {"arm1020e", FPU_ARCH_VFP_V2},
d5e0ba9c 27360 {"arm1136jfs", FPU_ARCH_VFP_V2}, /* Undocumented, use arm1136jf-s. */
c19d1205
ZW
27361 {"arm1136jf-s", FPU_ARCH_VFP_V2},
27362 {"maverick", FPU_ARCH_MAVERICK},
d5e0ba9c 27363 {"neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
d3375ddd 27364 {"neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
8e79c3df 27365 {"neon-fp16", FPU_ARCH_NEON_FP16},
62f3b8c8
PB
27366 {"vfpv4", FPU_ARCH_VFP_V4},
27367 {"vfpv4-d16", FPU_ARCH_VFP_V4D16},
ada65aa3 27368 {"fpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16},
a715796b
TG
27369 {"fpv5-d16", FPU_ARCH_VFP_V5D16},
27370 {"fpv5-sp-d16", FPU_ARCH_VFP_V5_SP_D16},
62f3b8c8 27371 {"neon-vfpv4", FPU_ARCH_NEON_VFP_V4},
bca38921
MGD
27372 {"fp-armv8", FPU_ARCH_VFP_ARMV8},
27373 {"neon-fp-armv8", FPU_ARCH_NEON_VFP_ARMV8},
27374 {"crypto-neon-fp-armv8",
27375 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8},
d6b4b13e 27376 {"neon-fp-armv8.1", FPU_ARCH_NEON_VFP_ARMV8_1},
081e4c7d
MW
27377 {"crypto-neon-fp-armv8.1",
27378 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1},
e74cfd16
PB
27379 {NULL, ARM_ARCH_NONE}
27380};
27381
27382struct arm_option_value_table
27383{
e0471c16 27384 const char *name;
e74cfd16 27385 long value;
c19d1205 27386};
7ed4c4c5 27387
e74cfd16 27388static const struct arm_option_value_table arm_float_abis[] =
c19d1205
ZW
27389{
27390 {"hard", ARM_FLOAT_ABI_HARD},
27391 {"softfp", ARM_FLOAT_ABI_SOFTFP},
27392 {"soft", ARM_FLOAT_ABI_SOFT},
e74cfd16 27393 {NULL, 0}
c19d1205 27394};
7ed4c4c5 27395
c19d1205 27396#ifdef OBJ_ELF
3a4a14e9 27397/* We only know how to output GNU and ver 4/5 (AAELF) formats. */
e74cfd16 27398static const struct arm_option_value_table arm_eabis[] =
c19d1205
ZW
27399{
27400 {"gnu", EF_ARM_EABI_UNKNOWN},
27401 {"4", EF_ARM_EABI_VER4},
3a4a14e9 27402 {"5", EF_ARM_EABI_VER5},
e74cfd16 27403 {NULL, 0}
c19d1205
ZW
27404};
27405#endif
7ed4c4c5 27406
c19d1205
ZW
27407struct arm_long_option_table
27408{
0198d5e6 27409 const char * option; /* Substring to match. */
e0471c16 27410 const char * help; /* Help information. */
17b9d67d 27411 int (* func) (const char * subopt); /* Function to decode sub-option. */
e0471c16 27412 const char * deprecated; /* If non-null, print this message. */
c19d1205 27413};
7ed4c4c5 27414
c921be7d 27415static bfd_boolean
c168ce07 27416arm_parse_extension (const char *str, const arm_feature_set *opt_set,
34ef62f4
AV
27417 arm_feature_set *ext_set,
27418 const struct arm_ext_table *ext_table)
7ed4c4c5 27419{
69133863 27420 /* We insist on extensions being specified in alphabetical order, and with
fa94de6b
RM
27421 extensions being added before being removed. We achieve this by having
27422 the global ARM_EXTENSIONS table in alphabetical order, and using the
69133863 27423 ADDING_VALUE variable to indicate whether we are adding an extension (1)
fa94de6b 27424 or removing it (0) and only allowing it to change in the order
69133863
MGD
27425 -1 -> 1 -> 0. */
27426 const struct arm_option_extension_value_table * opt = NULL;
d942732e 27427 const arm_feature_set arm_any = ARM_ANY;
69133863
MGD
27428 int adding_value = -1;
27429
c19d1205 27430 while (str != NULL && *str != 0)
7ed4c4c5 27431 {
82b8a785 27432 const char *ext;
f3bad469 27433 size_t len;
7ed4c4c5 27434
c19d1205
ZW
27435 if (*str != '+')
27436 {
27437 as_bad (_("invalid architectural extension"));
c921be7d 27438 return FALSE;
c19d1205 27439 }
7ed4c4c5 27440
c19d1205
ZW
27441 str++;
27442 ext = strchr (str, '+');
7ed4c4c5 27443
c19d1205 27444 if (ext != NULL)
f3bad469 27445 len = ext - str;
c19d1205 27446 else
f3bad469 27447 len = strlen (str);
7ed4c4c5 27448
f3bad469 27449 if (len >= 2 && strncmp (str, "no", 2) == 0)
69133863
MGD
27450 {
27451 if (adding_value != 0)
27452 {
27453 adding_value = 0;
27454 opt = arm_extensions;
27455 }
27456
f3bad469 27457 len -= 2;
69133863
MGD
27458 str += 2;
27459 }
f3bad469 27460 else if (len > 0)
69133863
MGD
27461 {
27462 if (adding_value == -1)
27463 {
27464 adding_value = 1;
27465 opt = arm_extensions;
27466 }
27467 else if (adding_value != 1)
27468 {
27469 as_bad (_("must specify extensions to add before specifying "
27470 "those to remove"));
27471 return FALSE;
27472 }
27473 }
27474
f3bad469 27475 if (len == 0)
c19d1205
ZW
27476 {
27477 as_bad (_("missing architectural extension"));
c921be7d 27478 return FALSE;
c19d1205 27479 }
7ed4c4c5 27480
69133863
MGD
27481 gas_assert (adding_value != -1);
27482 gas_assert (opt != NULL);
27483
34ef62f4
AV
27484 if (ext_table != NULL)
27485 {
27486 const struct arm_ext_table * ext_opt = ext_table;
27487 bfd_boolean found = FALSE;
27488 for (; ext_opt->name != NULL; ext_opt++)
27489 if (ext_opt->name_len == len
27490 && strncmp (ext_opt->name, str, len) == 0)
27491 {
27492 if (adding_value)
27493 {
27494 if (ARM_FEATURE_ZERO (ext_opt->merge))
27495 /* TODO: Option not supported. When we remove the
27496 legacy table this case should error out. */
27497 continue;
27498
27499 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, ext_opt->merge);
27500 }
27501 else
27502 {
27503 if (ARM_FEATURE_ZERO (ext_opt->clear))
27504 /* TODO: Option not supported. When we remove the
27505 legacy table this case should error out. */
27506 continue;
27507 ARM_CLEAR_FEATURE (*ext_set, *ext_set, ext_opt->clear);
27508 }
27509 found = TRUE;
27510 break;
27511 }
27512 if (found)
27513 {
27514 str = ext;
27515 continue;
27516 }
27517 }
27518
69133863
MGD
27519 /* Scan over the options table trying to find an exact match. */
27520 for (; opt->name != NULL; opt++)
f3bad469 27521 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 27522 {
d942732e
TP
27523 int i, nb_allowed_archs =
27524 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
69133863 27525 /* Check we can apply the extension to this architecture. */
d942732e
TP
27526 for (i = 0; i < nb_allowed_archs; i++)
27527 {
27528 /* Empty entry. */
27529 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_any))
27530 continue;
c168ce07 27531 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *opt_set))
d942732e
TP
27532 break;
27533 }
27534 if (i == nb_allowed_archs)
69133863
MGD
27535 {
27536 as_bad (_("extension does not apply to the base architecture"));
27537 return FALSE;
27538 }
27539
27540 /* Add or remove the extension. */
27541 if (adding_value)
4d354d8b 27542 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, opt->merge_value);
69133863 27543 else
4d354d8b 27544 ARM_CLEAR_FEATURE (*ext_set, *ext_set, opt->clear_value);
69133863 27545
3d030cdb
TP
27546 /* Allowing Thumb division instructions for ARMv7 in autodetection
27547 rely on this break so that duplicate extensions (extensions
27548 with the same name as a previous extension in the list) are not
27549 considered for command-line parsing. */
c19d1205
ZW
27550 break;
27551 }
7ed4c4c5 27552
c19d1205
ZW
27553 if (opt->name == NULL)
27554 {
69133863
MGD
27555 /* Did we fail to find an extension because it wasn't specified in
27556 alphabetical order, or because it does not exist? */
27557
27558 for (opt = arm_extensions; opt->name != NULL; opt++)
f3bad469 27559 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
69133863
MGD
27560 break;
27561
27562 if (opt->name == NULL)
27563 as_bad (_("unknown architectural extension `%s'"), str);
27564 else
27565 as_bad (_("architectural extensions must be specified in "
27566 "alphabetical order"));
27567
c921be7d 27568 return FALSE;
c19d1205 27569 }
69133863
MGD
27570 else
27571 {
27572 /* We should skip the extension we've just matched the next time
27573 round. */
27574 opt++;
27575 }
7ed4c4c5 27576
c19d1205
ZW
27577 str = ext;
27578 };
7ed4c4c5 27579
c921be7d 27580 return TRUE;
c19d1205 27581}
7ed4c4c5 27582
c921be7d 27583static bfd_boolean
17b9d67d 27584arm_parse_cpu (const char *str)
7ed4c4c5 27585{
f3bad469 27586 const struct arm_cpu_option_table *opt;
82b8a785 27587 const char *ext = strchr (str, '+');
f3bad469 27588 size_t len;
7ed4c4c5 27589
c19d1205 27590 if (ext != NULL)
f3bad469 27591 len = ext - str;
7ed4c4c5 27592 else
f3bad469 27593 len = strlen (str);
7ed4c4c5 27594
f3bad469 27595 if (len == 0)
7ed4c4c5 27596 {
c19d1205 27597 as_bad (_("missing cpu name `%s'"), str);
c921be7d 27598 return FALSE;
7ed4c4c5
NC
27599 }
27600
c19d1205 27601 for (opt = arm_cpus; opt->name != NULL; opt++)
f3bad469 27602 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 27603 {
c168ce07 27604 mcpu_cpu_opt = &opt->value;
4d354d8b
TP
27605 if (mcpu_ext_opt == NULL)
27606 mcpu_ext_opt = XNEW (arm_feature_set);
27607 *mcpu_ext_opt = opt->ext;
e74cfd16 27608 mcpu_fpu_opt = &opt->default_fpu;
ee065d83 27609 if (opt->canonical_name)
ef8e6722
JW
27610 {
27611 gas_assert (sizeof selected_cpu_name > strlen (opt->canonical_name));
27612 strcpy (selected_cpu_name, opt->canonical_name);
27613 }
ee065d83
PB
27614 else
27615 {
f3bad469 27616 size_t i;
c921be7d 27617
ef8e6722
JW
27618 if (len >= sizeof selected_cpu_name)
27619 len = (sizeof selected_cpu_name) - 1;
27620
f3bad469 27621 for (i = 0; i < len; i++)
ee065d83
PB
27622 selected_cpu_name[i] = TOUPPER (opt->name[i]);
27623 selected_cpu_name[i] = 0;
27624 }
7ed4c4c5 27625
c19d1205 27626 if (ext != NULL)
34ef62f4 27627 return arm_parse_extension (ext, mcpu_cpu_opt, mcpu_ext_opt, NULL);
7ed4c4c5 27628
c921be7d 27629 return TRUE;
c19d1205 27630 }
7ed4c4c5 27631
c19d1205 27632 as_bad (_("unknown cpu `%s'"), str);
c921be7d 27633 return FALSE;
7ed4c4c5
NC
27634}
27635
c921be7d 27636static bfd_boolean
17b9d67d 27637arm_parse_arch (const char *str)
7ed4c4c5 27638{
e74cfd16 27639 const struct arm_arch_option_table *opt;
82b8a785 27640 const char *ext = strchr (str, '+');
f3bad469 27641 size_t len;
7ed4c4c5 27642
c19d1205 27643 if (ext != NULL)
f3bad469 27644 len = ext - str;
7ed4c4c5 27645 else
f3bad469 27646 len = strlen (str);
7ed4c4c5 27647
f3bad469 27648 if (len == 0)
7ed4c4c5 27649 {
c19d1205 27650 as_bad (_("missing architecture name `%s'"), str);
c921be7d 27651 return FALSE;
7ed4c4c5
NC
27652 }
27653
c19d1205 27654 for (opt = arm_archs; opt->name != NULL; opt++)
f3bad469 27655 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 27656 {
e74cfd16 27657 march_cpu_opt = &opt->value;
4d354d8b
TP
27658 if (march_ext_opt == NULL)
27659 march_ext_opt = XNEW (arm_feature_set);
27660 *march_ext_opt = arm_arch_none;
e74cfd16 27661 march_fpu_opt = &opt->default_fpu;
5f4273c7 27662 strcpy (selected_cpu_name, opt->name);
7ed4c4c5 27663
c19d1205 27664 if (ext != NULL)
34ef62f4
AV
27665 return arm_parse_extension (ext, march_cpu_opt, march_ext_opt,
27666 opt->ext_table);
7ed4c4c5 27667
c921be7d 27668 return TRUE;
c19d1205
ZW
27669 }
27670
27671 as_bad (_("unknown architecture `%s'\n"), str);
c921be7d 27672 return FALSE;
7ed4c4c5 27673}
eb043451 27674
c921be7d 27675static bfd_boolean
17b9d67d 27676arm_parse_fpu (const char * str)
c19d1205 27677{
69133863 27678 const struct arm_option_fpu_value_table * opt;
b99bd4ef 27679
c19d1205
ZW
27680 for (opt = arm_fpus; opt->name != NULL; opt++)
27681 if (streq (opt->name, str))
27682 {
e74cfd16 27683 mfpu_opt = &opt->value;
c921be7d 27684 return TRUE;
c19d1205 27685 }
b99bd4ef 27686
c19d1205 27687 as_bad (_("unknown floating point format `%s'\n"), str);
c921be7d 27688 return FALSE;
c19d1205
ZW
27689}
27690
c921be7d 27691static bfd_boolean
17b9d67d 27692arm_parse_float_abi (const char * str)
b99bd4ef 27693{
e74cfd16 27694 const struct arm_option_value_table * opt;
b99bd4ef 27695
c19d1205
ZW
27696 for (opt = arm_float_abis; opt->name != NULL; opt++)
27697 if (streq (opt->name, str))
27698 {
27699 mfloat_abi_opt = opt->value;
c921be7d 27700 return TRUE;
c19d1205 27701 }
cc8a6dd0 27702
c19d1205 27703 as_bad (_("unknown floating point abi `%s'\n"), str);
c921be7d 27704 return FALSE;
c19d1205 27705}
b99bd4ef 27706
c19d1205 27707#ifdef OBJ_ELF
c921be7d 27708static bfd_boolean
17b9d67d 27709arm_parse_eabi (const char * str)
c19d1205 27710{
e74cfd16 27711 const struct arm_option_value_table *opt;
cc8a6dd0 27712
c19d1205
ZW
27713 for (opt = arm_eabis; opt->name != NULL; opt++)
27714 if (streq (opt->name, str))
27715 {
27716 meabi_flags = opt->value;
c921be7d 27717 return TRUE;
c19d1205
ZW
27718 }
27719 as_bad (_("unknown EABI `%s'\n"), str);
c921be7d 27720 return FALSE;
c19d1205
ZW
27721}
27722#endif
cc8a6dd0 27723
c921be7d 27724static bfd_boolean
17b9d67d 27725arm_parse_it_mode (const char * str)
e07e6e58 27726{
c921be7d 27727 bfd_boolean ret = TRUE;
e07e6e58
NC
27728
27729 if (streq ("arm", str))
27730 implicit_it_mode = IMPLICIT_IT_MODE_ARM;
27731 else if (streq ("thumb", str))
27732 implicit_it_mode = IMPLICIT_IT_MODE_THUMB;
27733 else if (streq ("always", str))
27734 implicit_it_mode = IMPLICIT_IT_MODE_ALWAYS;
27735 else if (streq ("never", str))
27736 implicit_it_mode = IMPLICIT_IT_MODE_NEVER;
27737 else
27738 {
27739 as_bad (_("unknown implicit IT mode `%s', should be "\
477330fc 27740 "arm, thumb, always, or never."), str);
c921be7d 27741 ret = FALSE;
e07e6e58
NC
27742 }
27743
27744 return ret;
27745}
27746
2e6976a8 27747static bfd_boolean
17b9d67d 27748arm_ccs_mode (const char * unused ATTRIBUTE_UNUSED)
2e6976a8
DG
27749{
27750 codecomposer_syntax = TRUE;
27751 arm_comment_chars[0] = ';';
27752 arm_line_separator_chars[0] = 0;
27753 return TRUE;
27754}
27755
c19d1205
ZW
27756struct arm_long_option_table arm_long_opts[] =
27757{
27758 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
27759 arm_parse_cpu, NULL},
27760 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
27761 arm_parse_arch, NULL},
27762 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
27763 arm_parse_fpu, NULL},
27764 {"mfloat-abi=", N_("<abi>\t assemble for floating point ABI <abi>"),
27765 arm_parse_float_abi, NULL},
27766#ifdef OBJ_ELF
7fac0536 27767 {"meabi=", N_("<ver>\t\t assemble for eabi version <ver>"),
c19d1205
ZW
27768 arm_parse_eabi, NULL},
27769#endif
e07e6e58
NC
27770 {"mimplicit-it=", N_("<mode>\t controls implicit insertion of IT instructions"),
27771 arm_parse_it_mode, NULL},
2e6976a8
DG
27772 {"mccs", N_("\t\t\t TI CodeComposer Studio syntax compatibility mode"),
27773 arm_ccs_mode, NULL},
c19d1205
ZW
27774 {NULL, NULL, 0, NULL}
27775};
cc8a6dd0 27776
c19d1205 27777int
17b9d67d 27778md_parse_option (int c, const char * arg)
c19d1205
ZW
27779{
27780 struct arm_option_table *opt;
e74cfd16 27781 const struct arm_legacy_option_table *fopt;
c19d1205 27782 struct arm_long_option_table *lopt;
b99bd4ef 27783
c19d1205 27784 switch (c)
b99bd4ef 27785 {
c19d1205
ZW
27786#ifdef OPTION_EB
27787 case OPTION_EB:
27788 target_big_endian = 1;
27789 break;
27790#endif
cc8a6dd0 27791
c19d1205
ZW
27792#ifdef OPTION_EL
27793 case OPTION_EL:
27794 target_big_endian = 0;
27795 break;
27796#endif
b99bd4ef 27797
845b51d6
PB
27798 case OPTION_FIX_V4BX:
27799 fix_v4bx = TRUE;
27800 break;
27801
18a20338
CL
27802#ifdef OBJ_ELF
27803 case OPTION_FDPIC:
27804 arm_fdpic = TRUE;
27805 break;
27806#endif /* OBJ_ELF */
27807
c19d1205
ZW
27808 case 'a':
27809 /* Listing option. Just ignore these, we don't support additional
27810 ones. */
27811 return 0;
b99bd4ef 27812
c19d1205
ZW
27813 default:
27814 for (opt = arm_opts; opt->option != NULL; opt++)
27815 {
27816 if (c == opt->option[0]
27817 && ((arg == NULL && opt->option[1] == 0)
27818 || streq (arg, opt->option + 1)))
27819 {
c19d1205 27820 /* If the option is deprecated, tell the user. */
278df34e 27821 if (warn_on_deprecated && opt->deprecated != NULL)
c19d1205
ZW
27822 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
27823 arg ? arg : "", _(opt->deprecated));
b99bd4ef 27824
c19d1205
ZW
27825 if (opt->var != NULL)
27826 *opt->var = opt->value;
cc8a6dd0 27827
c19d1205
ZW
27828 return 1;
27829 }
27830 }
b99bd4ef 27831
e74cfd16
PB
27832 for (fopt = arm_legacy_opts; fopt->option != NULL; fopt++)
27833 {
27834 if (c == fopt->option[0]
27835 && ((arg == NULL && fopt->option[1] == 0)
27836 || streq (arg, fopt->option + 1)))
27837 {
e74cfd16 27838 /* If the option is deprecated, tell the user. */
278df34e 27839 if (warn_on_deprecated && fopt->deprecated != NULL)
e74cfd16
PB
27840 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
27841 arg ? arg : "", _(fopt->deprecated));
e74cfd16
PB
27842
27843 if (fopt->var != NULL)
27844 *fopt->var = &fopt->value;
27845
27846 return 1;
27847 }
27848 }
27849
c19d1205
ZW
27850 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
27851 {
27852 /* These options are expected to have an argument. */
27853 if (c == lopt->option[0]
27854 && arg != NULL
27855 && strncmp (arg, lopt->option + 1,
27856 strlen (lopt->option + 1)) == 0)
27857 {
c19d1205 27858 /* If the option is deprecated, tell the user. */
278df34e 27859 if (warn_on_deprecated && lopt->deprecated != NULL)
c19d1205
ZW
27860 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
27861 _(lopt->deprecated));
b99bd4ef 27862
c19d1205
ZW
27863 /* Call the sup-option parser. */
27864 return lopt->func (arg + strlen (lopt->option) - 1);
27865 }
27866 }
a737bd4d 27867
c19d1205
ZW
27868 return 0;
27869 }
a394c00f 27870
c19d1205
ZW
27871 return 1;
27872}
a394c00f 27873
c19d1205
ZW
27874void
27875md_show_usage (FILE * fp)
a394c00f 27876{
c19d1205
ZW
27877 struct arm_option_table *opt;
27878 struct arm_long_option_table *lopt;
a394c00f 27879
c19d1205 27880 fprintf (fp, _(" ARM-specific assembler options:\n"));
a394c00f 27881
c19d1205
ZW
27882 for (opt = arm_opts; opt->option != NULL; opt++)
27883 if (opt->help != NULL)
27884 fprintf (fp, " -%-23s%s\n", opt->option, _(opt->help));
a394c00f 27885
c19d1205
ZW
27886 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
27887 if (lopt->help != NULL)
27888 fprintf (fp, " -%s%s\n", lopt->option, _(lopt->help));
a394c00f 27889
c19d1205
ZW
27890#ifdef OPTION_EB
27891 fprintf (fp, _("\
27892 -EB assemble code for a big-endian cpu\n"));
a394c00f
NC
27893#endif
27894
c19d1205
ZW
27895#ifdef OPTION_EL
27896 fprintf (fp, _("\
27897 -EL assemble code for a little-endian cpu\n"));
a737bd4d 27898#endif
845b51d6
PB
27899
27900 fprintf (fp, _("\
27901 --fix-v4bx Allow BX in ARMv4 code\n"));
18a20338
CL
27902
27903#ifdef OBJ_ELF
27904 fprintf (fp, _("\
27905 --fdpic generate an FDPIC object file\n"));
27906#endif /* OBJ_ELF */
c19d1205 27907}
ee065d83 27908
ee065d83 27909#ifdef OBJ_ELF
0198d5e6 27910
62b3e311
PB
27911typedef struct
27912{
27913 int val;
27914 arm_feature_set flags;
27915} cpu_arch_ver_table;
27916
2c6b98ea
TP
27917/* Mapping from CPU features to EABI CPU arch values. Table must be sorted
27918 chronologically for architectures, with an exception for ARMv6-M and
27919 ARMv6S-M due to legacy reasons. No new architecture should have a
27920 special case. This allows for build attribute selection results to be
27921 stable when new architectures are added. */
62b3e311
PB
27922static const cpu_arch_ver_table cpu_arch_ver[] =
27923{
031254f2
AV
27924 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V1},
27925 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2},
27926 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2S},
27927 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3},
27928 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3M},
27929 {TAG_CPU_ARCH_V4, ARM_ARCH_V4xM},
27930 {TAG_CPU_ARCH_V4, ARM_ARCH_V4},
27931 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4TxM},
27932 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4T},
27933 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5xM},
27934 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5},
27935 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5TxM},
27936 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5T},
27937 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TExP},
27938 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TE},
27939 {TAG_CPU_ARCH_V5TEJ, ARM_ARCH_V5TEJ},
27940 {TAG_CPU_ARCH_V6, ARM_ARCH_V6},
27941 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6Z},
27942 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6KZ},
27943 {TAG_CPU_ARCH_V6K, ARM_ARCH_V6K},
27944 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6T2},
27945 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KT2},
27946 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6ZT2},
27947 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KZT2},
2c6b98ea
TP
27948
27949 /* When assembling a file with only ARMv6-M or ARMv6S-M instruction, GNU as
27950 always selected build attributes to match those of ARMv6-M
27951 (resp. ARMv6S-M). However, due to these architectures being a strict
27952 subset of ARMv7-M in terms of instructions available, ARMv7-M attributes
27953 would be selected when fully respecting chronology of architectures.
27954 It is thus necessary to make a special case of ARMv6-M and ARMv6S-M and
27955 move them before ARMv7 architectures. */
031254f2
AV
27956 {TAG_CPU_ARCH_V6_M, ARM_ARCH_V6M},
27957 {TAG_CPU_ARCH_V6S_M, ARM_ARCH_V6SM},
27958
27959 {TAG_CPU_ARCH_V7, ARM_ARCH_V7},
27960 {TAG_CPU_ARCH_V7, ARM_ARCH_V7A},
27961 {TAG_CPU_ARCH_V7, ARM_ARCH_V7R},
27962 {TAG_CPU_ARCH_V7, ARM_ARCH_V7M},
27963 {TAG_CPU_ARCH_V7, ARM_ARCH_V7VE},
27964 {TAG_CPU_ARCH_V7E_M, ARM_ARCH_V7EM},
27965 {TAG_CPU_ARCH_V8, ARM_ARCH_V8A},
27966 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_1A},
27967 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_2A},
27968 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_3A},
27969 {TAG_CPU_ARCH_V8M_BASE, ARM_ARCH_V8M_BASE},
27970 {TAG_CPU_ARCH_V8M_MAIN, ARM_ARCH_V8M_MAIN},
27971 {TAG_CPU_ARCH_V8R, ARM_ARCH_V8R},
27972 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_4A},
27973 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_5A},
27974 {TAG_CPU_ARCH_V8_1M_MAIN, ARM_ARCH_V8_1M_MAIN},
27975 {-1, ARM_ARCH_NONE}
62b3e311
PB
27976};
27977
ee3c0378 27978/* Set an attribute if it has not already been set by the user. */
0198d5e6 27979
ee3c0378
AS
27980static void
27981aeabi_set_attribute_int (int tag, int value)
27982{
27983 if (tag < 1
27984 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
27985 || !attributes_set_explicitly[tag])
27986 bfd_elf_add_proc_attr_int (stdoutput, tag, value);
27987}
27988
27989static void
27990aeabi_set_attribute_string (int tag, const char *value)
27991{
27992 if (tag < 1
27993 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
27994 || !attributes_set_explicitly[tag])
27995 bfd_elf_add_proc_attr_string (stdoutput, tag, value);
27996}
27997
2c6b98ea
TP
27998/* Return whether features in the *NEEDED feature set are available via
27999 extensions for the architecture whose feature set is *ARCH_FSET. */
0198d5e6 28000
2c6b98ea
TP
28001static bfd_boolean
28002have_ext_for_needed_feat_p (const arm_feature_set *arch_fset,
28003 const arm_feature_set *needed)
28004{
28005 int i, nb_allowed_archs;
28006 arm_feature_set ext_fset;
28007 const struct arm_option_extension_value_table *opt;
28008
28009 ext_fset = arm_arch_none;
28010 for (opt = arm_extensions; opt->name != NULL; opt++)
28011 {
28012 /* Extension does not provide any feature we need. */
28013 if (!ARM_CPU_HAS_FEATURE (*needed, opt->merge_value))
28014 continue;
28015
28016 nb_allowed_archs =
28017 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
28018 for (i = 0; i < nb_allowed_archs; i++)
28019 {
28020 /* Empty entry. */
28021 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_arch_any))
28022 break;
28023
28024 /* Extension is available, add it. */
28025 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *arch_fset))
28026 ARM_MERGE_FEATURE_SETS (ext_fset, ext_fset, opt->merge_value);
28027 }
28028 }
28029
28030 /* Can we enable all features in *needed? */
28031 return ARM_FSET_CPU_SUBSET (*needed, ext_fset);
28032}
28033
28034/* Select value for Tag_CPU_arch and Tag_CPU_arch_profile build attributes for
28035 a given architecture feature set *ARCH_EXT_FSET including extension feature
28036 set *EXT_FSET. Selection logic used depend on EXACT_MATCH:
28037 - if true, check for an exact match of the architecture modulo extensions;
28038 - otherwise, select build attribute value of the first superset
28039 architecture released so that results remains stable when new architectures
28040 are added.
28041 For -march/-mcpu=all the build attribute value of the most featureful
28042 architecture is returned. Tag_CPU_arch_profile result is returned in
28043 PROFILE. */
0198d5e6 28044
2c6b98ea
TP
28045static int
28046get_aeabi_cpu_arch_from_fset (const arm_feature_set *arch_ext_fset,
28047 const arm_feature_set *ext_fset,
28048 char *profile, int exact_match)
28049{
28050 arm_feature_set arch_fset;
28051 const cpu_arch_ver_table *p_ver, *p_ver_ret = NULL;
28052
28053 /* Select most featureful architecture with all its extensions if building
28054 for -march=all as the feature sets used to set build attributes. */
28055 if (ARM_FEATURE_EQUAL (*arch_ext_fset, arm_arch_any))
28056 {
28057 /* Force revisiting of decision for each new architecture. */
031254f2 28058 gas_assert (MAX_TAG_CPU_ARCH <= TAG_CPU_ARCH_V8_1M_MAIN);
2c6b98ea
TP
28059 *profile = 'A';
28060 return TAG_CPU_ARCH_V8;
28061 }
28062
28063 ARM_CLEAR_FEATURE (arch_fset, *arch_ext_fset, *ext_fset);
28064
28065 for (p_ver = cpu_arch_ver; p_ver->val != -1; p_ver++)
28066 {
28067 arm_feature_set known_arch_fset;
28068
28069 ARM_CLEAR_FEATURE (known_arch_fset, p_ver->flags, fpu_any);
28070 if (exact_match)
28071 {
28072 /* Base architecture match user-specified architecture and
28073 extensions, eg. ARMv6S-M matching -march=armv6-m+os. */
28074 if (ARM_FEATURE_EQUAL (*arch_ext_fset, known_arch_fset))
28075 {
28076 p_ver_ret = p_ver;
28077 goto found;
28078 }
28079 /* Base architecture match user-specified architecture only
28080 (eg. ARMv6-M in the same case as above). Record it in case we
28081 find a match with above condition. */
28082 else if (p_ver_ret == NULL
28083 && ARM_FEATURE_EQUAL (arch_fset, known_arch_fset))
28084 p_ver_ret = p_ver;
28085 }
28086 else
28087 {
28088
28089 /* Architecture has all features wanted. */
28090 if (ARM_FSET_CPU_SUBSET (arch_fset, known_arch_fset))
28091 {
28092 arm_feature_set added_fset;
28093
28094 /* Compute features added by this architecture over the one
28095 recorded in p_ver_ret. */
28096 if (p_ver_ret != NULL)
28097 ARM_CLEAR_FEATURE (added_fset, known_arch_fset,
28098 p_ver_ret->flags);
28099 /* First architecture that match incl. with extensions, or the
28100 only difference in features over the recorded match is
28101 features that were optional and are now mandatory. */
28102 if (p_ver_ret == NULL
28103 || ARM_FSET_CPU_SUBSET (added_fset, arch_fset))
28104 {
28105 p_ver_ret = p_ver;
28106 goto found;
28107 }
28108 }
28109 else if (p_ver_ret == NULL)
28110 {
28111 arm_feature_set needed_ext_fset;
28112
28113 ARM_CLEAR_FEATURE (needed_ext_fset, arch_fset, known_arch_fset);
28114
28115 /* Architecture has all features needed when using some
28116 extensions. Record it and continue searching in case there
28117 exist an architecture providing all needed features without
28118 the need for extensions (eg. ARMv6S-M Vs ARMv6-M with
28119 OS extension). */
28120 if (have_ext_for_needed_feat_p (&known_arch_fset,
28121 &needed_ext_fset))
28122 p_ver_ret = p_ver;
28123 }
28124 }
28125 }
28126
28127 if (p_ver_ret == NULL)
28128 return -1;
28129
28130found:
28131 /* Tag_CPU_arch_profile. */
28132 if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7a)
28133 || ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8)
28134 || (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_atomics)
28135 && !ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8m_m_only)))
28136 *profile = 'A';
28137 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7r))
28138 *profile = 'R';
28139 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_m))
28140 *profile = 'M';
28141 else
28142 *profile = '\0';
28143 return p_ver_ret->val;
28144}
28145
ee065d83 28146/* Set the public EABI object attributes. */
0198d5e6 28147
c168ce07 28148static void
ee065d83
PB
28149aeabi_set_public_attributes (void)
28150{
b90d5ba0 28151 char profile = '\0';
2c6b98ea 28152 int arch = -1;
90ec0d68 28153 int virt_sec = 0;
bca38921 28154 int fp16_optional = 0;
2c6b98ea
TP
28155 int skip_exact_match = 0;
28156 arm_feature_set flags, flags_arch, flags_ext;
ee065d83 28157
54bab281
TP
28158 /* Autodetection mode, choose the architecture based the instructions
28159 actually used. */
28160 if (no_cpu_selected ())
28161 {
28162 ARM_MERGE_FEATURE_SETS (flags, arm_arch_used, thumb_arch_used);
ddd7f988 28163
54bab281
TP
28164 if (ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any))
28165 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v1);
ddd7f988 28166
54bab281
TP
28167 if (ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_any))
28168 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v4t);
ddd7f988 28169
54bab281 28170 /* Code run during relaxation relies on selected_cpu being set. */
4d354d8b
TP
28171 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
28172 flags_ext = arm_arch_none;
28173 ARM_CLEAR_FEATURE (selected_arch, flags_arch, flags_ext);
28174 selected_ext = flags_ext;
54bab281
TP
28175 selected_cpu = flags;
28176 }
28177 /* Otherwise, choose the architecture based on the capabilities of the
28178 requested cpu. */
28179 else
4d354d8b
TP
28180 {
28181 ARM_MERGE_FEATURE_SETS (flags_arch, selected_arch, selected_ext);
28182 ARM_CLEAR_FEATURE (flags_arch, flags_arch, fpu_any);
28183 flags_ext = selected_ext;
28184 flags = selected_cpu;
28185 }
28186 ARM_MERGE_FEATURE_SETS (flags, flags, selected_fpu);
7f78eb34 28187
ddd7f988 28188 /* Allow the user to override the reported architecture. */
4d354d8b 28189 if (!ARM_FEATURE_ZERO (selected_object_arch))
7a1d4c38 28190 {
4d354d8b 28191 ARM_CLEAR_FEATURE (flags_arch, selected_object_arch, fpu_any);
2c6b98ea 28192 flags_ext = arm_arch_none;
7a1d4c38 28193 }
2c6b98ea 28194 else
4d354d8b 28195 skip_exact_match = ARM_FEATURE_EQUAL (selected_cpu, arm_arch_any);
2c6b98ea
TP
28196
28197 /* When this function is run again after relaxation has happened there is no
28198 way to determine whether an architecture or CPU was specified by the user:
28199 - selected_cpu is set above for relaxation to work;
28200 - march_cpu_opt is not set if only -mcpu or .cpu is used;
28201 - mcpu_cpu_opt is set to arm_arch_any for autodetection.
28202 Therefore, if not in -march=all case we first try an exact match and fall
28203 back to autodetection. */
28204 if (!skip_exact_match)
28205 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 1);
28206 if (arch == -1)
28207 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 0);
28208 if (arch == -1)
28209 as_bad (_("no architecture contains all the instructions used\n"));
9e3c6df6 28210
ee065d83
PB
28211 /* Tag_CPU_name. */
28212 if (selected_cpu_name[0])
28213 {
91d6fa6a 28214 char *q;
ee065d83 28215
91d6fa6a
NC
28216 q = selected_cpu_name;
28217 if (strncmp (q, "armv", 4) == 0)
ee065d83
PB
28218 {
28219 int i;
5f4273c7 28220
91d6fa6a
NC
28221 q += 4;
28222 for (i = 0; q[i]; i++)
28223 q[i] = TOUPPER (q[i]);
ee065d83 28224 }
91d6fa6a 28225 aeabi_set_attribute_string (Tag_CPU_name, q);
ee065d83 28226 }
62f3b8c8 28227
ee065d83 28228 /* Tag_CPU_arch. */
ee3c0378 28229 aeabi_set_attribute_int (Tag_CPU_arch, arch);
62f3b8c8 28230
62b3e311 28231 /* Tag_CPU_arch_profile. */
69239280
MGD
28232 if (profile != '\0')
28233 aeabi_set_attribute_int (Tag_CPU_arch_profile, profile);
62f3b8c8 28234
15afaa63 28235 /* Tag_DSP_extension. */
4d354d8b 28236 if (ARM_CPU_HAS_FEATURE (selected_ext, arm_ext_dsp))
6c290d53 28237 aeabi_set_attribute_int (Tag_DSP_extension, 1);
15afaa63 28238
2c6b98ea 28239 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
ee065d83 28240 /* Tag_ARM_ISA_use. */
ee3c0378 28241 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v1)
2c6b98ea 28242 || ARM_FEATURE_ZERO (flags_arch))
ee3c0378 28243 aeabi_set_attribute_int (Tag_ARM_ISA_use, 1);
62f3b8c8 28244
ee065d83 28245 /* Tag_THUMB_ISA_use. */
ee3c0378 28246 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v4t)
2c6b98ea 28247 || ARM_FEATURE_ZERO (flags_arch))
4ed7ed8d
TP
28248 {
28249 int thumb_isa_use;
28250
28251 if (!ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
16a1fa25 28252 && ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m_m_only))
4ed7ed8d
TP
28253 thumb_isa_use = 3;
28254 else if (ARM_CPU_HAS_FEATURE (flags, arm_arch_t2))
28255 thumb_isa_use = 2;
28256 else
28257 thumb_isa_use = 1;
28258 aeabi_set_attribute_int (Tag_THUMB_ISA_use, thumb_isa_use);
28259 }
62f3b8c8 28260
ee065d83 28261 /* Tag_VFP_arch. */
a715796b
TG
28262 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_armv8xd))
28263 aeabi_set_attribute_int (Tag_VFP_arch,
28264 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
28265 ? 7 : 8);
bca38921 28266 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_fma))
62f3b8c8
PB
28267 aeabi_set_attribute_int (Tag_VFP_arch,
28268 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
28269 ? 5 : 6);
28270 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32))
bca38921
MGD
28271 {
28272 fp16_optional = 1;
28273 aeabi_set_attribute_int (Tag_VFP_arch, 3);
28274 }
ada65aa3 28275 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v3xd))
bca38921
MGD
28276 {
28277 aeabi_set_attribute_int (Tag_VFP_arch, 4);
28278 fp16_optional = 1;
28279 }
ee3c0378
AS
28280 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v2))
28281 aeabi_set_attribute_int (Tag_VFP_arch, 2);
28282 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1)
477330fc 28283 || ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd))
ee3c0378 28284 aeabi_set_attribute_int (Tag_VFP_arch, 1);
62f3b8c8 28285
4547cb56
NC
28286 /* Tag_ABI_HardFP_use. */
28287 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd)
28288 && !ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1))
28289 aeabi_set_attribute_int (Tag_ABI_HardFP_use, 1);
28290
ee065d83 28291 /* Tag_WMMX_arch. */
ee3c0378
AS
28292 if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt2))
28293 aeabi_set_attribute_int (Tag_WMMX_arch, 2);
28294 else if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt))
28295 aeabi_set_attribute_int (Tag_WMMX_arch, 1);
62f3b8c8 28296
ee3c0378 28297 /* Tag_Advanced_SIMD_arch (formerly Tag_NEON_arch). */
9411fd44
MW
28298 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v8_1))
28299 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 4);
28300 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_armv8))
bca38921
MGD
28301 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 3);
28302 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v1))
28303 {
28304 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_fma))
28305 {
28306 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 2);
28307 }
28308 else
28309 {
28310 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 1);
28311 fp16_optional = 1;
28312 }
28313 }
fa94de6b 28314
ee3c0378 28315 /* Tag_VFP_HP_extension (formerly Tag_NEON_FP16_arch). */
bca38921 28316 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_fp16) && fp16_optional)
ee3c0378 28317 aeabi_set_attribute_int (Tag_VFP_HP_extension, 1);
4547cb56 28318
69239280
MGD
28319 /* Tag_DIV_use.
28320
28321 We set Tag_DIV_use to two when integer divide instructions have been used
28322 in ARM state, or when Thumb integer divide instructions have been used,
28323 but we have no architecture profile set, nor have we any ARM instructions.
28324
4ed7ed8d
TP
28325 For ARMv8-A and ARMv8-M we set the tag to 0 as integer divide is implied
28326 by the base architecture.
bca38921 28327
69239280 28328 For new architectures we will have to check these tests. */
031254f2 28329 gas_assert (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
4ed7ed8d
TP
28330 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
28331 || ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m))
bca38921
MGD
28332 aeabi_set_attribute_int (Tag_DIV_use, 0);
28333 else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_adiv)
28334 || (profile == '\0'
28335 && ARM_CPU_HAS_FEATURE (flags, arm_ext_div)
28336 && !ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any)))
eea54501 28337 aeabi_set_attribute_int (Tag_DIV_use, 2);
60e5ef9f
MGD
28338
28339 /* Tag_MP_extension_use. */
28340 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_mp))
28341 aeabi_set_attribute_int (Tag_MPextension_use, 1);
f4c65163
MGD
28342
28343 /* Tag Virtualization_use. */
28344 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_sec))
90ec0d68
MGD
28345 virt_sec |= 1;
28346 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_virt))
28347 virt_sec |= 2;
28348 if (virt_sec != 0)
28349 aeabi_set_attribute_int (Tag_Virtualization_use, virt_sec);
ee065d83
PB
28350}
28351
c168ce07
TP
28352/* Post relaxation hook. Recompute ARM attributes now that relaxation is
28353 finished and free extension feature bits which will not be used anymore. */
0198d5e6 28354
c168ce07
TP
28355void
28356arm_md_post_relax (void)
28357{
28358 aeabi_set_public_attributes ();
4d354d8b
TP
28359 XDELETE (mcpu_ext_opt);
28360 mcpu_ext_opt = NULL;
28361 XDELETE (march_ext_opt);
28362 march_ext_opt = NULL;
c168ce07
TP
28363}
28364
104d59d1 28365/* Add the default contents for the .ARM.attributes section. */
0198d5e6 28366
ee065d83
PB
28367void
28368arm_md_end (void)
28369{
ee065d83
PB
28370 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
28371 return;
28372
28373 aeabi_set_public_attributes ();
ee065d83 28374}
8463be01 28375#endif /* OBJ_ELF */
ee065d83 28376
ee065d83
PB
28377/* Parse a .cpu directive. */
28378
28379static void
28380s_arm_cpu (int ignored ATTRIBUTE_UNUSED)
28381{
e74cfd16 28382 const struct arm_cpu_option_table *opt;
ee065d83
PB
28383 char *name;
28384 char saved_char;
28385
28386 name = input_line_pointer;
5f4273c7 28387 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
28388 input_line_pointer++;
28389 saved_char = *input_line_pointer;
28390 *input_line_pointer = 0;
28391
28392 /* Skip the first "all" entry. */
28393 for (opt = arm_cpus + 1; opt->name != NULL; opt++)
28394 if (streq (opt->name, name))
28395 {
4d354d8b
TP
28396 selected_arch = opt->value;
28397 selected_ext = opt->ext;
28398 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
ee065d83 28399 if (opt->canonical_name)
5f4273c7 28400 strcpy (selected_cpu_name, opt->canonical_name);
ee065d83
PB
28401 else
28402 {
28403 int i;
28404 for (i = 0; opt->name[i]; i++)
28405 selected_cpu_name[i] = TOUPPER (opt->name[i]);
f3bad469 28406
ee065d83
PB
28407 selected_cpu_name[i] = 0;
28408 }
4d354d8b
TP
28409 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
28410
ee065d83
PB
28411 *input_line_pointer = saved_char;
28412 demand_empty_rest_of_line ();
28413 return;
28414 }
28415 as_bad (_("unknown cpu `%s'"), name);
28416 *input_line_pointer = saved_char;
28417 ignore_rest_of_line ();
28418}
28419
ee065d83
PB
28420/* Parse a .arch directive. */
28421
28422static void
28423s_arm_arch (int ignored ATTRIBUTE_UNUSED)
28424{
e74cfd16 28425 const struct arm_arch_option_table *opt;
ee065d83
PB
28426 char saved_char;
28427 char *name;
28428
28429 name = input_line_pointer;
5f4273c7 28430 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
28431 input_line_pointer++;
28432 saved_char = *input_line_pointer;
28433 *input_line_pointer = 0;
28434
28435 /* Skip the first "all" entry. */
28436 for (opt = arm_archs + 1; opt->name != NULL; opt++)
28437 if (streq (opt->name, name))
28438 {
4d354d8b
TP
28439 selected_arch = opt->value;
28440 selected_ext = arm_arch_none;
28441 selected_cpu = selected_arch;
5f4273c7 28442 strcpy (selected_cpu_name, opt->name);
4d354d8b 28443 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83
PB
28444 *input_line_pointer = saved_char;
28445 demand_empty_rest_of_line ();
28446 return;
28447 }
28448
28449 as_bad (_("unknown architecture `%s'\n"), name);
28450 *input_line_pointer = saved_char;
28451 ignore_rest_of_line ();
28452}
28453
7a1d4c38
PB
28454/* Parse a .object_arch directive. */
28455
28456static void
28457s_arm_object_arch (int ignored ATTRIBUTE_UNUSED)
28458{
28459 const struct arm_arch_option_table *opt;
28460 char saved_char;
28461 char *name;
28462
28463 name = input_line_pointer;
5f4273c7 28464 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
7a1d4c38
PB
28465 input_line_pointer++;
28466 saved_char = *input_line_pointer;
28467 *input_line_pointer = 0;
28468
28469 /* Skip the first "all" entry. */
28470 for (opt = arm_archs + 1; opt->name != NULL; opt++)
28471 if (streq (opt->name, name))
28472 {
4d354d8b 28473 selected_object_arch = opt->value;
7a1d4c38
PB
28474 *input_line_pointer = saved_char;
28475 demand_empty_rest_of_line ();
28476 return;
28477 }
28478
28479 as_bad (_("unknown architecture `%s'\n"), name);
28480 *input_line_pointer = saved_char;
28481 ignore_rest_of_line ();
28482}
28483
69133863
MGD
28484/* Parse a .arch_extension directive. */
28485
28486static void
28487s_arm_arch_extension (int ignored ATTRIBUTE_UNUSED)
28488{
28489 const struct arm_option_extension_value_table *opt;
28490 char saved_char;
28491 char *name;
28492 int adding_value = 1;
28493
28494 name = input_line_pointer;
28495 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
28496 input_line_pointer++;
28497 saved_char = *input_line_pointer;
28498 *input_line_pointer = 0;
28499
28500 if (strlen (name) >= 2
28501 && strncmp (name, "no", 2) == 0)
28502 {
28503 adding_value = 0;
28504 name += 2;
28505 }
28506
28507 for (opt = arm_extensions; opt->name != NULL; opt++)
28508 if (streq (opt->name, name))
28509 {
d942732e
TP
28510 int i, nb_allowed_archs =
28511 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[i]);
28512 for (i = 0; i < nb_allowed_archs; i++)
28513 {
28514 /* Empty entry. */
4d354d8b 28515 if (ARM_CPU_IS_ANY (opt->allowed_archs[i]))
d942732e 28516 continue;
4d354d8b 28517 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], selected_arch))
d942732e
TP
28518 break;
28519 }
28520
28521 if (i == nb_allowed_archs)
69133863
MGD
28522 {
28523 as_bad (_("architectural extension `%s' is not allowed for the "
28524 "current base architecture"), name);
28525 break;
28526 }
28527
28528 if (adding_value)
4d354d8b 28529 ARM_MERGE_FEATURE_SETS (selected_ext, selected_ext,
5a70a223 28530 opt->merge_value);
69133863 28531 else
4d354d8b 28532 ARM_CLEAR_FEATURE (selected_ext, selected_ext, opt->clear_value);
69133863 28533
4d354d8b
TP
28534 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
28535 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
69133863
MGD
28536 *input_line_pointer = saved_char;
28537 demand_empty_rest_of_line ();
3d030cdb
TP
28538 /* Allowing Thumb division instructions for ARMv7 in autodetection rely
28539 on this return so that duplicate extensions (extensions with the
28540 same name as a previous extension in the list) are not considered
28541 for command-line parsing. */
69133863
MGD
28542 return;
28543 }
28544
28545 if (opt->name == NULL)
e673710a 28546 as_bad (_("unknown architecture extension `%s'\n"), name);
69133863
MGD
28547
28548 *input_line_pointer = saved_char;
28549 ignore_rest_of_line ();
28550}
28551
ee065d83
PB
28552/* Parse a .fpu directive. */
28553
28554static void
28555s_arm_fpu (int ignored ATTRIBUTE_UNUSED)
28556{
69133863 28557 const struct arm_option_fpu_value_table *opt;
ee065d83
PB
28558 char saved_char;
28559 char *name;
28560
28561 name = input_line_pointer;
5f4273c7 28562 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
28563 input_line_pointer++;
28564 saved_char = *input_line_pointer;
28565 *input_line_pointer = 0;
5f4273c7 28566
ee065d83
PB
28567 for (opt = arm_fpus; opt->name != NULL; opt++)
28568 if (streq (opt->name, name))
28569 {
4d354d8b
TP
28570 selected_fpu = opt->value;
28571#ifndef CPU_DEFAULT
28572 if (no_cpu_selected ())
28573 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
28574 else
28575#endif
28576 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83
PB
28577 *input_line_pointer = saved_char;
28578 demand_empty_rest_of_line ();
28579 return;
28580 }
28581
28582 as_bad (_("unknown floating point format `%s'\n"), name);
28583 *input_line_pointer = saved_char;
28584 ignore_rest_of_line ();
28585}
ee065d83 28586
794ba86a 28587/* Copy symbol information. */
f31fef98 28588
794ba86a
DJ
28589void
28590arm_copy_symbol_attributes (symbolS *dest, symbolS *src)
28591{
28592 ARM_GET_FLAG (dest) = ARM_GET_FLAG (src);
28593}
e04befd0 28594
f31fef98 28595#ifdef OBJ_ELF
e04befd0
AS
28596/* Given a symbolic attribute NAME, return the proper integer value.
28597 Returns -1 if the attribute is not known. */
f31fef98 28598
e04befd0
AS
28599int
28600arm_convert_symbolic_attribute (const char *name)
28601{
f31fef98
NC
28602 static const struct
28603 {
28604 const char * name;
28605 const int tag;
28606 }
28607 attribute_table[] =
28608 {
28609 /* When you modify this table you should
28610 also modify the list in doc/c-arm.texi. */
e04befd0 28611#define T(tag) {#tag, tag}
f31fef98
NC
28612 T (Tag_CPU_raw_name),
28613 T (Tag_CPU_name),
28614 T (Tag_CPU_arch),
28615 T (Tag_CPU_arch_profile),
28616 T (Tag_ARM_ISA_use),
28617 T (Tag_THUMB_ISA_use),
75375b3e 28618 T (Tag_FP_arch),
f31fef98
NC
28619 T (Tag_VFP_arch),
28620 T (Tag_WMMX_arch),
28621 T (Tag_Advanced_SIMD_arch),
28622 T (Tag_PCS_config),
28623 T (Tag_ABI_PCS_R9_use),
28624 T (Tag_ABI_PCS_RW_data),
28625 T (Tag_ABI_PCS_RO_data),
28626 T (Tag_ABI_PCS_GOT_use),
28627 T (Tag_ABI_PCS_wchar_t),
28628 T (Tag_ABI_FP_rounding),
28629 T (Tag_ABI_FP_denormal),
28630 T (Tag_ABI_FP_exceptions),
28631 T (Tag_ABI_FP_user_exceptions),
28632 T (Tag_ABI_FP_number_model),
75375b3e 28633 T (Tag_ABI_align_needed),
f31fef98 28634 T (Tag_ABI_align8_needed),
75375b3e 28635 T (Tag_ABI_align_preserved),
f31fef98
NC
28636 T (Tag_ABI_align8_preserved),
28637 T (Tag_ABI_enum_size),
28638 T (Tag_ABI_HardFP_use),
28639 T (Tag_ABI_VFP_args),
28640 T (Tag_ABI_WMMX_args),
28641 T (Tag_ABI_optimization_goals),
28642 T (Tag_ABI_FP_optimization_goals),
28643 T (Tag_compatibility),
28644 T (Tag_CPU_unaligned_access),
75375b3e 28645 T (Tag_FP_HP_extension),
f31fef98
NC
28646 T (Tag_VFP_HP_extension),
28647 T (Tag_ABI_FP_16bit_format),
cd21e546
MGD
28648 T (Tag_MPextension_use),
28649 T (Tag_DIV_use),
f31fef98
NC
28650 T (Tag_nodefaults),
28651 T (Tag_also_compatible_with),
28652 T (Tag_conformance),
28653 T (Tag_T2EE_use),
28654 T (Tag_Virtualization_use),
15afaa63 28655 T (Tag_DSP_extension),
cd21e546 28656 /* We deliberately do not include Tag_MPextension_use_legacy. */
e04befd0 28657#undef T
f31fef98 28658 };
e04befd0
AS
28659 unsigned int i;
28660
28661 if (name == NULL)
28662 return -1;
28663
f31fef98 28664 for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
c921be7d 28665 if (streq (name, attribute_table[i].name))
e04befd0
AS
28666 return attribute_table[i].tag;
28667
28668 return -1;
28669}
267bf995 28670
93ef582d
NC
28671/* Apply sym value for relocations only in the case that they are for
28672 local symbols in the same segment as the fixup and you have the
28673 respective architectural feature for blx and simple switches. */
0198d5e6 28674
267bf995 28675int
93ef582d 28676arm_apply_sym_value (struct fix * fixP, segT this_seg)
267bf995
RR
28677{
28678 if (fixP->fx_addsy
28679 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
93ef582d
NC
28680 /* PR 17444: If the local symbol is in a different section then a reloc
28681 will always be generated for it, so applying the symbol value now
28682 will result in a double offset being stored in the relocation. */
28683 && (S_GET_SEGMENT (fixP->fx_addsy) == this_seg)
34e77a92 28684 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE))
267bf995
RR
28685 {
28686 switch (fixP->fx_r_type)
28687 {
28688 case BFD_RELOC_ARM_PCREL_BLX:
28689 case BFD_RELOC_THUMB_PCREL_BRANCH23:
28690 if (ARM_IS_FUNC (fixP->fx_addsy))
28691 return 1;
28692 break;
28693
28694 case BFD_RELOC_ARM_PCREL_CALL:
28695 case BFD_RELOC_THUMB_PCREL_BLX:
28696 if (THUMB_IS_FUNC (fixP->fx_addsy))
93ef582d 28697 return 1;
267bf995
RR
28698 break;
28699
28700 default:
28701 break;
28702 }
28703
28704 }
28705 return 0;
28706}
f31fef98 28707#endif /* OBJ_ELF */