]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-arm.c
[opcodes, ARM, 14/16] Add mode availability to coprocessor table entries
[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
1612/* Like arm_reg_parse, but allow allow the following extra features:
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,
1698 REGLIST_VFP_D,
1699 REGLIST_NEON_D
1700};
1701
c19d1205 1702/* Parse an ARM register list. Returns the bitmask, or FAIL. */
e07e6e58 1703
c19d1205 1704static long
4b5a202f 1705parse_reg_list (char ** strp, enum reg_list_els etype)
c19d1205 1706{
4b5a202f
AV
1707 char *str = *strp;
1708 long range = 0;
1709 int another_range;
1710
1711 gas_assert (etype == REGLIST_RN || etype == REGLIST_CLRM);
a737bd4d 1712
c19d1205
ZW
1713 /* We come back here if we get ranges concatenated by '+' or '|'. */
1714 do
6057a28f 1715 {
477330fc
RM
1716 skip_whitespace (str);
1717
c19d1205 1718 another_range = 0;
a737bd4d 1719
c19d1205
ZW
1720 if (*str == '{')
1721 {
1722 int in_range = 0;
1723 int cur_reg = -1;
a737bd4d 1724
c19d1205
ZW
1725 str++;
1726 do
1727 {
1728 int reg;
4b5a202f
AV
1729 const char apsr_str[] = "apsr";
1730 int apsr_str_len = strlen (apsr_str);
6057a28f 1731
4b5a202f
AV
1732 reg = arm_reg_parse (&str, REGLIST_RN);
1733 if (etype == REGLIST_CLRM)
c19d1205 1734 {
4b5a202f
AV
1735 if (reg == REG_SP || reg == REG_PC)
1736 reg = FAIL;
1737 else if (reg == FAIL
1738 && !strncasecmp (str, apsr_str, apsr_str_len)
1739 && !ISALPHA (*(str + apsr_str_len)))
1740 {
1741 reg = 15;
1742 str += apsr_str_len;
1743 }
1744
1745 if (reg == FAIL)
1746 {
1747 first_error (_("r0-r12, lr or APSR expected"));
1748 return FAIL;
1749 }
1750 }
1751 else /* etype == REGLIST_RN. */
1752 {
1753 if (reg == FAIL)
1754 {
1755 first_error (_(reg_expected_msgs[REGLIST_RN]));
1756 return FAIL;
1757 }
c19d1205 1758 }
a737bd4d 1759
c19d1205
ZW
1760 if (in_range)
1761 {
1762 int i;
a737bd4d 1763
c19d1205
ZW
1764 if (reg <= cur_reg)
1765 {
dcbf9037 1766 first_error (_("bad range in register list"));
c19d1205
ZW
1767 return FAIL;
1768 }
40a18ebd 1769
c19d1205
ZW
1770 for (i = cur_reg + 1; i < reg; i++)
1771 {
1772 if (range & (1 << i))
1773 as_tsktsk
1774 (_("Warning: duplicated register (r%d) in register list"),
1775 i);
1776 else
1777 range |= 1 << i;
1778 }
1779 in_range = 0;
1780 }
a737bd4d 1781
c19d1205
ZW
1782 if (range & (1 << reg))
1783 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
1784 reg);
1785 else if (reg <= cur_reg)
1786 as_tsktsk (_("Warning: register range not in ascending order"));
a737bd4d 1787
c19d1205
ZW
1788 range |= 1 << reg;
1789 cur_reg = reg;
1790 }
1791 while (skip_past_comma (&str) != FAIL
1792 || (in_range = 1, *str++ == '-'));
1793 str--;
a737bd4d 1794
d996d970 1795 if (skip_past_char (&str, '}') == FAIL)
c19d1205 1796 {
dcbf9037 1797 first_error (_("missing `}'"));
c19d1205
ZW
1798 return FAIL;
1799 }
1800 }
4b5a202f 1801 else if (etype == REGLIST_RN)
c19d1205 1802 {
91d6fa6a 1803 expressionS exp;
40a18ebd 1804
91d6fa6a 1805 if (my_get_expression (&exp, &str, GE_NO_PREFIX))
c19d1205 1806 return FAIL;
40a18ebd 1807
91d6fa6a 1808 if (exp.X_op == O_constant)
c19d1205 1809 {
91d6fa6a
NC
1810 if (exp.X_add_number
1811 != (exp.X_add_number & 0x0000ffff))
c19d1205
ZW
1812 {
1813 inst.error = _("invalid register mask");
1814 return FAIL;
1815 }
a737bd4d 1816
91d6fa6a 1817 if ((range & exp.X_add_number) != 0)
c19d1205 1818 {
91d6fa6a 1819 int regno = range & exp.X_add_number;
a737bd4d 1820
c19d1205
ZW
1821 regno &= -regno;
1822 regno = (1 << regno) - 1;
1823 as_tsktsk
1824 (_("Warning: duplicated register (r%d) in register list"),
1825 regno);
1826 }
a737bd4d 1827
91d6fa6a 1828 range |= exp.X_add_number;
c19d1205
ZW
1829 }
1830 else
1831 {
e2b0ab59 1832 if (inst.relocs[0].type != 0)
c19d1205
ZW
1833 {
1834 inst.error = _("expression too complex");
1835 return FAIL;
1836 }
a737bd4d 1837
e2b0ab59
AV
1838 memcpy (&inst.relocs[0].exp, &exp, sizeof (expressionS));
1839 inst.relocs[0].type = BFD_RELOC_ARM_MULTI;
1840 inst.relocs[0].pc_rel = 0;
c19d1205
ZW
1841 }
1842 }
a737bd4d 1843
c19d1205
ZW
1844 if (*str == '|' || *str == '+')
1845 {
1846 str++;
1847 another_range = 1;
1848 }
a737bd4d 1849 }
c19d1205 1850 while (another_range);
a737bd4d 1851
c19d1205
ZW
1852 *strp = str;
1853 return range;
a737bd4d
NC
1854}
1855
c19d1205
ZW
1856/* Parse a VFP register list. If the string is invalid return FAIL.
1857 Otherwise return the number of registers, and set PBASE to the first
5287ad62
JB
1858 register. Parses registers of type ETYPE.
1859 If REGLIST_NEON_D is used, several syntax enhancements are enabled:
1860 - Q registers can be used to specify pairs of D registers
1861 - { } can be omitted from around a singleton register list
477330fc
RM
1862 FIXME: This is not implemented, as it would require backtracking in
1863 some cases, e.g.:
1864 vtbl.8 d3,d4,d5
1865 This could be done (the meaning isn't really ambiguous), but doesn't
1866 fit in well with the current parsing framework.
dcbf9037
JB
1867 - 32 D registers may be used (also true for VFPv3).
1868 FIXME: Types are ignored in these register lists, which is probably a
1869 bug. */
6057a28f 1870
c19d1205 1871static int
037e8744 1872parse_vfp_reg_list (char **ccp, unsigned int *pbase, enum reg_list_els etype)
6057a28f 1873{
037e8744 1874 char *str = *ccp;
c19d1205
ZW
1875 int base_reg;
1876 int new_base;
21d799b5 1877 enum arm_reg_type regtype = (enum arm_reg_type) 0;
5287ad62 1878 int max_regs = 0;
c19d1205
ZW
1879 int count = 0;
1880 int warned = 0;
1881 unsigned long mask = 0;
a737bd4d 1882 int i;
6057a28f 1883
477330fc 1884 if (skip_past_char (&str, '{') == FAIL)
5287ad62
JB
1885 {
1886 inst.error = _("expecting {");
1887 return FAIL;
1888 }
6057a28f 1889
5287ad62 1890 switch (etype)
c19d1205 1891 {
5287ad62 1892 case REGLIST_VFP_S:
c19d1205
ZW
1893 regtype = REG_TYPE_VFS;
1894 max_regs = 32;
5287ad62 1895 break;
5f4273c7 1896
5287ad62
JB
1897 case REGLIST_VFP_D:
1898 regtype = REG_TYPE_VFD;
b7fc2769 1899 break;
5f4273c7 1900
b7fc2769
JB
1901 case REGLIST_NEON_D:
1902 regtype = REG_TYPE_NDQ;
1903 break;
4b5a202f
AV
1904
1905 default:
1906 gas_assert (0);
b7fc2769
JB
1907 }
1908
1909 if (etype != REGLIST_VFP_S)
1910 {
b1cc4aeb
PB
1911 /* VFPv3 allows 32 D registers, except for the VFPv3-D16 variant. */
1912 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
477330fc
RM
1913 {
1914 max_regs = 32;
1915 if (thumb_mode)
1916 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
1917 fpu_vfp_ext_d32);
1918 else
1919 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
1920 fpu_vfp_ext_d32);
1921 }
5287ad62 1922 else
477330fc 1923 max_regs = 16;
c19d1205 1924 }
6057a28f 1925
c19d1205 1926 base_reg = max_regs;
a737bd4d 1927
c19d1205
ZW
1928 do
1929 {
5287ad62 1930 int setmask = 1, addregs = 1;
dcbf9037 1931
037e8744 1932 new_base = arm_typed_reg_parse (&str, regtype, &regtype, NULL);
dcbf9037 1933
c19d1205 1934 if (new_base == FAIL)
a737bd4d 1935 {
dcbf9037 1936 first_error (_(reg_expected_msgs[regtype]));
c19d1205
ZW
1937 return FAIL;
1938 }
5f4273c7 1939
b7fc2769 1940 if (new_base >= max_regs)
477330fc
RM
1941 {
1942 first_error (_("register out of range in list"));
1943 return FAIL;
1944 }
5f4273c7 1945
5287ad62
JB
1946 /* Note: a value of 2 * n is returned for the register Q<n>. */
1947 if (regtype == REG_TYPE_NQ)
477330fc
RM
1948 {
1949 setmask = 3;
1950 addregs = 2;
1951 }
5287ad62 1952
c19d1205
ZW
1953 if (new_base < base_reg)
1954 base_reg = new_base;
a737bd4d 1955
5287ad62 1956 if (mask & (setmask << new_base))
c19d1205 1957 {
dcbf9037 1958 first_error (_("invalid register list"));
c19d1205 1959 return FAIL;
a737bd4d 1960 }
a737bd4d 1961
c19d1205
ZW
1962 if ((mask >> new_base) != 0 && ! warned)
1963 {
1964 as_tsktsk (_("register list not in ascending order"));
1965 warned = 1;
1966 }
0bbf2aa4 1967
5287ad62
JB
1968 mask |= setmask << new_base;
1969 count += addregs;
0bbf2aa4 1970
037e8744 1971 if (*str == '-') /* We have the start of a range expression */
c19d1205
ZW
1972 {
1973 int high_range;
0bbf2aa4 1974
037e8744 1975 str++;
0bbf2aa4 1976
037e8744 1977 if ((high_range = arm_typed_reg_parse (&str, regtype, NULL, NULL))
477330fc 1978 == FAIL)
c19d1205
ZW
1979 {
1980 inst.error = gettext (reg_expected_msgs[regtype]);
1981 return FAIL;
1982 }
0bbf2aa4 1983
477330fc
RM
1984 if (high_range >= max_regs)
1985 {
1986 first_error (_("register out of range in list"));
1987 return FAIL;
1988 }
b7fc2769 1989
477330fc
RM
1990 if (regtype == REG_TYPE_NQ)
1991 high_range = high_range + 1;
5287ad62 1992
c19d1205
ZW
1993 if (high_range <= new_base)
1994 {
1995 inst.error = _("register range not in ascending order");
1996 return FAIL;
1997 }
0bbf2aa4 1998
5287ad62 1999 for (new_base += addregs; new_base <= high_range; new_base += addregs)
0bbf2aa4 2000 {
5287ad62 2001 if (mask & (setmask << new_base))
0bbf2aa4 2002 {
c19d1205
ZW
2003 inst.error = _("invalid register list");
2004 return FAIL;
0bbf2aa4 2005 }
c19d1205 2006
5287ad62
JB
2007 mask |= setmask << new_base;
2008 count += addregs;
0bbf2aa4 2009 }
0bbf2aa4 2010 }
0bbf2aa4 2011 }
037e8744 2012 while (skip_past_comma (&str) != FAIL);
0bbf2aa4 2013
037e8744 2014 str++;
0bbf2aa4 2015
c19d1205
ZW
2016 /* Sanity check -- should have raised a parse error above. */
2017 if (count == 0 || count > max_regs)
2018 abort ();
2019
2020 *pbase = base_reg;
2021
2022 /* Final test -- the registers must be consecutive. */
2023 mask >>= base_reg;
2024 for (i = 0; i < count; i++)
2025 {
2026 if ((mask & (1u << i)) == 0)
2027 {
2028 inst.error = _("non-contiguous register range");
2029 return FAIL;
2030 }
2031 }
2032
037e8744
JB
2033 *ccp = str;
2034
c19d1205 2035 return count;
b99bd4ef
NC
2036}
2037
dcbf9037
JB
2038/* True if two alias types are the same. */
2039
c921be7d 2040static bfd_boolean
dcbf9037
JB
2041neon_alias_types_same (struct neon_typed_alias *a, struct neon_typed_alias *b)
2042{
2043 if (!a && !b)
c921be7d 2044 return TRUE;
5f4273c7 2045
dcbf9037 2046 if (!a || !b)
c921be7d 2047 return FALSE;
dcbf9037
JB
2048
2049 if (a->defined != b->defined)
c921be7d 2050 return FALSE;
5f4273c7 2051
dcbf9037
JB
2052 if ((a->defined & NTA_HASTYPE) != 0
2053 && (a->eltype.type != b->eltype.type
477330fc 2054 || a->eltype.size != b->eltype.size))
c921be7d 2055 return FALSE;
dcbf9037
JB
2056
2057 if ((a->defined & NTA_HASINDEX) != 0
2058 && (a->index != b->index))
c921be7d 2059 return FALSE;
5f4273c7 2060
c921be7d 2061 return TRUE;
dcbf9037
JB
2062}
2063
5287ad62
JB
2064/* Parse element/structure lists for Neon VLD<n> and VST<n> instructions.
2065 The base register is put in *PBASE.
dcbf9037 2066 The lane (or one of the NEON_*_LANES constants) is placed in bits [3:0] of
5287ad62
JB
2067 the return value.
2068 The register stride (minus one) is put in bit 4 of the return value.
dcbf9037
JB
2069 Bits [6:5] encode the list length (minus one).
2070 The type of the list elements is put in *ELTYPE, if non-NULL. */
5287ad62 2071
5287ad62 2072#define NEON_LANE(X) ((X) & 0xf)
dcbf9037 2073#define NEON_REG_STRIDE(X) ((((X) >> 4) & 1) + 1)
5287ad62
JB
2074#define NEON_REGLIST_LENGTH(X) ((((X) >> 5) & 3) + 1)
2075
2076static int
dcbf9037 2077parse_neon_el_struct_list (char **str, unsigned *pbase,
477330fc 2078 struct neon_type_el *eltype)
5287ad62
JB
2079{
2080 char *ptr = *str;
2081 int base_reg = -1;
2082 int reg_incr = -1;
2083 int count = 0;
2084 int lane = -1;
2085 int leading_brace = 0;
2086 enum arm_reg_type rtype = REG_TYPE_NDQ;
20203fb9
NC
2087 const char *const incr_error = _("register stride must be 1 or 2");
2088 const char *const type_error = _("mismatched element/structure types in list");
dcbf9037 2089 struct neon_typed_alias firsttype;
f85d59c3
KT
2090 firsttype.defined = 0;
2091 firsttype.eltype.type = NT_invtype;
2092 firsttype.eltype.size = -1;
2093 firsttype.index = -1;
5f4273c7 2094
5287ad62
JB
2095 if (skip_past_char (&ptr, '{') == SUCCESS)
2096 leading_brace = 1;
5f4273c7 2097
5287ad62
JB
2098 do
2099 {
dcbf9037
JB
2100 struct neon_typed_alias atype;
2101 int getreg = parse_typed_reg_or_scalar (&ptr, rtype, &rtype, &atype);
2102
5287ad62 2103 if (getreg == FAIL)
477330fc
RM
2104 {
2105 first_error (_(reg_expected_msgs[rtype]));
2106 return FAIL;
2107 }
5f4273c7 2108
5287ad62 2109 if (base_reg == -1)
477330fc
RM
2110 {
2111 base_reg = getreg;
2112 if (rtype == REG_TYPE_NQ)
2113 {
2114 reg_incr = 1;
2115 }
2116 firsttype = atype;
2117 }
5287ad62 2118 else if (reg_incr == -1)
477330fc
RM
2119 {
2120 reg_incr = getreg - base_reg;
2121 if (reg_incr < 1 || reg_incr > 2)
2122 {
2123 first_error (_(incr_error));
2124 return FAIL;
2125 }
2126 }
5287ad62 2127 else if (getreg != base_reg + reg_incr * count)
477330fc
RM
2128 {
2129 first_error (_(incr_error));
2130 return FAIL;
2131 }
dcbf9037 2132
c921be7d 2133 if (! neon_alias_types_same (&atype, &firsttype))
477330fc
RM
2134 {
2135 first_error (_(type_error));
2136 return FAIL;
2137 }
5f4273c7 2138
5287ad62 2139 /* Handle Dn-Dm or Qn-Qm syntax. Can only be used with non-indexed list
477330fc 2140 modes. */
5287ad62 2141 if (ptr[0] == '-')
477330fc
RM
2142 {
2143 struct neon_typed_alias htype;
2144 int hireg, dregs = (rtype == REG_TYPE_NQ) ? 2 : 1;
2145 if (lane == -1)
2146 lane = NEON_INTERLEAVE_LANES;
2147 else if (lane != NEON_INTERLEAVE_LANES)
2148 {
2149 first_error (_(type_error));
2150 return FAIL;
2151 }
2152 if (reg_incr == -1)
2153 reg_incr = 1;
2154 else if (reg_incr != 1)
2155 {
2156 first_error (_("don't use Rn-Rm syntax with non-unit stride"));
2157 return FAIL;
2158 }
2159 ptr++;
2160 hireg = parse_typed_reg_or_scalar (&ptr, rtype, NULL, &htype);
2161 if (hireg == FAIL)
2162 {
2163 first_error (_(reg_expected_msgs[rtype]));
2164 return FAIL;
2165 }
2166 if (! neon_alias_types_same (&htype, &firsttype))
2167 {
2168 first_error (_(type_error));
2169 return FAIL;
2170 }
2171 count += hireg + dregs - getreg;
2172 continue;
2173 }
5f4273c7 2174
5287ad62
JB
2175 /* If we're using Q registers, we can't use [] or [n] syntax. */
2176 if (rtype == REG_TYPE_NQ)
477330fc
RM
2177 {
2178 count += 2;
2179 continue;
2180 }
5f4273c7 2181
dcbf9037 2182 if ((atype.defined & NTA_HASINDEX) != 0)
477330fc
RM
2183 {
2184 if (lane == -1)
2185 lane = atype.index;
2186 else if (lane != atype.index)
2187 {
2188 first_error (_(type_error));
2189 return FAIL;
2190 }
2191 }
5287ad62 2192 else if (lane == -1)
477330fc 2193 lane = NEON_INTERLEAVE_LANES;
5287ad62 2194 else if (lane != NEON_INTERLEAVE_LANES)
477330fc
RM
2195 {
2196 first_error (_(type_error));
2197 return FAIL;
2198 }
5287ad62
JB
2199 count++;
2200 }
2201 while ((count != 1 || leading_brace) && skip_past_comma (&ptr) != FAIL);
5f4273c7 2202
5287ad62
JB
2203 /* No lane set by [x]. We must be interleaving structures. */
2204 if (lane == -1)
2205 lane = NEON_INTERLEAVE_LANES;
5f4273c7 2206
5287ad62
JB
2207 /* Sanity check. */
2208 if (lane == -1 || base_reg == -1 || count < 1 || count > 4
2209 || (count > 1 && reg_incr == -1))
2210 {
dcbf9037 2211 first_error (_("error parsing element/structure list"));
5287ad62
JB
2212 return FAIL;
2213 }
2214
2215 if ((count > 1 || leading_brace) && skip_past_char (&ptr, '}') == FAIL)
2216 {
dcbf9037 2217 first_error (_("expected }"));
5287ad62
JB
2218 return FAIL;
2219 }
5f4273c7 2220
5287ad62
JB
2221 if (reg_incr == -1)
2222 reg_incr = 1;
2223
dcbf9037
JB
2224 if (eltype)
2225 *eltype = firsttype.eltype;
2226
5287ad62
JB
2227 *pbase = base_reg;
2228 *str = ptr;
5f4273c7 2229
5287ad62
JB
2230 return lane | ((reg_incr - 1) << 4) | ((count - 1) << 5);
2231}
2232
c19d1205
ZW
2233/* Parse an explicit relocation suffix on an expression. This is
2234 either nothing, or a word in parentheses. Note that if !OBJ_ELF,
2235 arm_reloc_hsh contains no entries, so this function can only
2236 succeed if there is no () after the word. Returns -1 on error,
2237 BFD_RELOC_UNUSED if there wasn't any suffix. */
3da1d841 2238
c19d1205
ZW
2239static int
2240parse_reloc (char **str)
b99bd4ef 2241{
c19d1205
ZW
2242 struct reloc_entry *r;
2243 char *p, *q;
b99bd4ef 2244
c19d1205
ZW
2245 if (**str != '(')
2246 return BFD_RELOC_UNUSED;
b99bd4ef 2247
c19d1205
ZW
2248 p = *str + 1;
2249 q = p;
2250
2251 while (*q && *q != ')' && *q != ',')
2252 q++;
2253 if (*q != ')')
2254 return -1;
2255
21d799b5
NC
2256 if ((r = (struct reloc_entry *)
2257 hash_find_n (arm_reloc_hsh, p, q - p)) == NULL)
c19d1205
ZW
2258 return -1;
2259
2260 *str = q + 1;
2261 return r->reloc;
b99bd4ef
NC
2262}
2263
c19d1205
ZW
2264/* Directives: register aliases. */
2265
dcbf9037 2266static struct reg_entry *
90ec0d68 2267insert_reg_alias (char *str, unsigned number, int type)
b99bd4ef 2268{
d3ce72d0 2269 struct reg_entry *new_reg;
c19d1205 2270 const char *name;
b99bd4ef 2271
d3ce72d0 2272 if ((new_reg = (struct reg_entry *) hash_find (arm_reg_hsh, str)) != 0)
c19d1205 2273 {
d3ce72d0 2274 if (new_reg->builtin)
c19d1205 2275 as_warn (_("ignoring attempt to redefine built-in register '%s'"), str);
b99bd4ef 2276
c19d1205
ZW
2277 /* Only warn about a redefinition if it's not defined as the
2278 same register. */
d3ce72d0 2279 else if (new_reg->number != number || new_reg->type != type)
c19d1205 2280 as_warn (_("ignoring redefinition of register alias '%s'"), str);
69b97547 2281
d929913e 2282 return NULL;
c19d1205 2283 }
b99bd4ef 2284
c19d1205 2285 name = xstrdup (str);
325801bd 2286 new_reg = XNEW (struct reg_entry);
b99bd4ef 2287
d3ce72d0
NC
2288 new_reg->name = name;
2289 new_reg->number = number;
2290 new_reg->type = type;
2291 new_reg->builtin = FALSE;
2292 new_reg->neon = NULL;
b99bd4ef 2293
d3ce72d0 2294 if (hash_insert (arm_reg_hsh, name, (void *) new_reg))
c19d1205 2295 abort ();
5f4273c7 2296
d3ce72d0 2297 return new_reg;
dcbf9037
JB
2298}
2299
2300static void
2301insert_neon_reg_alias (char *str, int number, int type,
477330fc 2302 struct neon_typed_alias *atype)
dcbf9037
JB
2303{
2304 struct reg_entry *reg = insert_reg_alias (str, number, type);
5f4273c7 2305
dcbf9037
JB
2306 if (!reg)
2307 {
2308 first_error (_("attempt to redefine typed alias"));
2309 return;
2310 }
5f4273c7 2311
dcbf9037
JB
2312 if (atype)
2313 {
325801bd 2314 reg->neon = XNEW (struct neon_typed_alias);
dcbf9037
JB
2315 *reg->neon = *atype;
2316 }
c19d1205 2317}
b99bd4ef 2318
c19d1205 2319/* Look for the .req directive. This is of the form:
b99bd4ef 2320
c19d1205 2321 new_register_name .req existing_register_name
b99bd4ef 2322
c19d1205 2323 If we find one, or if it looks sufficiently like one that we want to
d929913e 2324 handle any error here, return TRUE. Otherwise return FALSE. */
b99bd4ef 2325
d929913e 2326static bfd_boolean
c19d1205
ZW
2327create_register_alias (char * newname, char *p)
2328{
2329 struct reg_entry *old;
2330 char *oldname, *nbuf;
2331 size_t nlen;
b99bd4ef 2332
c19d1205
ZW
2333 /* The input scrubber ensures that whitespace after the mnemonic is
2334 collapsed to single spaces. */
2335 oldname = p;
2336 if (strncmp (oldname, " .req ", 6) != 0)
d929913e 2337 return FALSE;
b99bd4ef 2338
c19d1205
ZW
2339 oldname += 6;
2340 if (*oldname == '\0')
d929913e 2341 return FALSE;
b99bd4ef 2342
21d799b5 2343 old = (struct reg_entry *) hash_find (arm_reg_hsh, oldname);
c19d1205 2344 if (!old)
b99bd4ef 2345 {
c19d1205 2346 as_warn (_("unknown register '%s' -- .req ignored"), oldname);
d929913e 2347 return TRUE;
b99bd4ef
NC
2348 }
2349
c19d1205
ZW
2350 /* If TC_CASE_SENSITIVE is defined, then newname already points to
2351 the desired alias name, and p points to its end. If not, then
2352 the desired alias name is in the global original_case_string. */
2353#ifdef TC_CASE_SENSITIVE
2354 nlen = p - newname;
2355#else
2356 newname = original_case_string;
2357 nlen = strlen (newname);
2358#endif
b99bd4ef 2359
29a2809e 2360 nbuf = xmemdup0 (newname, nlen);
b99bd4ef 2361
c19d1205
ZW
2362 /* Create aliases under the new name as stated; an all-lowercase
2363 version of the new name; and an all-uppercase version of the new
2364 name. */
d929913e
NC
2365 if (insert_reg_alias (nbuf, old->number, old->type) != NULL)
2366 {
2367 for (p = nbuf; *p; p++)
2368 *p = TOUPPER (*p);
c19d1205 2369
d929913e
NC
2370 if (strncmp (nbuf, newname, nlen))
2371 {
2372 /* If this attempt to create an additional alias fails, do not bother
2373 trying to create the all-lower case alias. We will fail and issue
2374 a second, duplicate error message. This situation arises when the
2375 programmer does something like:
2376 foo .req r0
2377 Foo .req r1
2378 The second .req creates the "Foo" alias but then fails to create
5f4273c7 2379 the artificial FOO alias because it has already been created by the
d929913e
NC
2380 first .req. */
2381 if (insert_reg_alias (nbuf, old->number, old->type) == NULL)
e1fa0163
NC
2382 {
2383 free (nbuf);
2384 return TRUE;
2385 }
d929913e 2386 }
c19d1205 2387
d929913e
NC
2388 for (p = nbuf; *p; p++)
2389 *p = TOLOWER (*p);
c19d1205 2390
d929913e
NC
2391 if (strncmp (nbuf, newname, nlen))
2392 insert_reg_alias (nbuf, old->number, old->type);
2393 }
c19d1205 2394
e1fa0163 2395 free (nbuf);
d929913e 2396 return TRUE;
b99bd4ef
NC
2397}
2398
dcbf9037
JB
2399/* Create a Neon typed/indexed register alias using directives, e.g.:
2400 X .dn d5.s32[1]
2401 Y .qn 6.s16
2402 Z .dn d7
2403 T .dn Z[0]
2404 These typed registers can be used instead of the types specified after the
2405 Neon mnemonic, so long as all operands given have types. Types can also be
2406 specified directly, e.g.:
5f4273c7 2407 vadd d0.s32, d1.s32, d2.s32 */
dcbf9037 2408
c921be7d 2409static bfd_boolean
dcbf9037
JB
2410create_neon_reg_alias (char *newname, char *p)
2411{
2412 enum arm_reg_type basetype;
2413 struct reg_entry *basereg;
2414 struct reg_entry mybasereg;
2415 struct neon_type ntype;
2416 struct neon_typed_alias typeinfo;
12d6b0b7 2417 char *namebuf, *nameend ATTRIBUTE_UNUSED;
dcbf9037 2418 int namelen;
5f4273c7 2419
dcbf9037
JB
2420 typeinfo.defined = 0;
2421 typeinfo.eltype.type = NT_invtype;
2422 typeinfo.eltype.size = -1;
2423 typeinfo.index = -1;
5f4273c7 2424
dcbf9037 2425 nameend = p;
5f4273c7 2426
dcbf9037
JB
2427 if (strncmp (p, " .dn ", 5) == 0)
2428 basetype = REG_TYPE_VFD;
2429 else if (strncmp (p, " .qn ", 5) == 0)
2430 basetype = REG_TYPE_NQ;
2431 else
c921be7d 2432 return FALSE;
5f4273c7 2433
dcbf9037 2434 p += 5;
5f4273c7 2435
dcbf9037 2436 if (*p == '\0')
c921be7d 2437 return FALSE;
5f4273c7 2438
dcbf9037
JB
2439 basereg = arm_reg_parse_multi (&p);
2440
2441 if (basereg && basereg->type != basetype)
2442 {
2443 as_bad (_("bad type for register"));
c921be7d 2444 return FALSE;
dcbf9037
JB
2445 }
2446
2447 if (basereg == NULL)
2448 {
2449 expressionS exp;
2450 /* Try parsing as an integer. */
2451 my_get_expression (&exp, &p, GE_NO_PREFIX);
2452 if (exp.X_op != O_constant)
477330fc
RM
2453 {
2454 as_bad (_("expression must be constant"));
2455 return FALSE;
2456 }
dcbf9037
JB
2457 basereg = &mybasereg;
2458 basereg->number = (basetype == REG_TYPE_NQ) ? exp.X_add_number * 2
477330fc 2459 : exp.X_add_number;
dcbf9037
JB
2460 basereg->neon = 0;
2461 }
2462
2463 if (basereg->neon)
2464 typeinfo = *basereg->neon;
2465
2466 if (parse_neon_type (&ntype, &p) == SUCCESS)
2467 {
2468 /* We got a type. */
2469 if (typeinfo.defined & NTA_HASTYPE)
477330fc
RM
2470 {
2471 as_bad (_("can't redefine the type of a register alias"));
2472 return FALSE;
2473 }
5f4273c7 2474
dcbf9037
JB
2475 typeinfo.defined |= NTA_HASTYPE;
2476 if (ntype.elems != 1)
477330fc
RM
2477 {
2478 as_bad (_("you must specify a single type only"));
2479 return FALSE;
2480 }
dcbf9037
JB
2481 typeinfo.eltype = ntype.el[0];
2482 }
5f4273c7 2483
dcbf9037
JB
2484 if (skip_past_char (&p, '[') == SUCCESS)
2485 {
2486 expressionS exp;
2487 /* We got a scalar index. */
5f4273c7 2488
dcbf9037 2489 if (typeinfo.defined & NTA_HASINDEX)
477330fc
RM
2490 {
2491 as_bad (_("can't redefine the index of a scalar alias"));
2492 return FALSE;
2493 }
5f4273c7 2494
dcbf9037 2495 my_get_expression (&exp, &p, GE_NO_PREFIX);
5f4273c7 2496
dcbf9037 2497 if (exp.X_op != O_constant)
477330fc
RM
2498 {
2499 as_bad (_("scalar index must be constant"));
2500 return FALSE;
2501 }
5f4273c7 2502
dcbf9037
JB
2503 typeinfo.defined |= NTA_HASINDEX;
2504 typeinfo.index = exp.X_add_number;
5f4273c7 2505
dcbf9037 2506 if (skip_past_char (&p, ']') == FAIL)
477330fc
RM
2507 {
2508 as_bad (_("expecting ]"));
2509 return FALSE;
2510 }
dcbf9037
JB
2511 }
2512
15735687
NS
2513 /* If TC_CASE_SENSITIVE is defined, then newname already points to
2514 the desired alias name, and p points to its end. If not, then
2515 the desired alias name is in the global original_case_string. */
2516#ifdef TC_CASE_SENSITIVE
dcbf9037 2517 namelen = nameend - newname;
15735687
NS
2518#else
2519 newname = original_case_string;
2520 namelen = strlen (newname);
2521#endif
2522
29a2809e 2523 namebuf = xmemdup0 (newname, namelen);
5f4273c7 2524
dcbf9037 2525 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2526 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2527
dcbf9037
JB
2528 /* Insert name in all uppercase. */
2529 for (p = namebuf; *p; p++)
2530 *p = TOUPPER (*p);
5f4273c7 2531
dcbf9037
JB
2532 if (strncmp (namebuf, newname, namelen))
2533 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2534 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2535
dcbf9037
JB
2536 /* Insert name in all lowercase. */
2537 for (p = namebuf; *p; p++)
2538 *p = TOLOWER (*p);
5f4273c7 2539
dcbf9037
JB
2540 if (strncmp (namebuf, newname, namelen))
2541 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2542 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2543
e1fa0163 2544 free (namebuf);
c921be7d 2545 return TRUE;
dcbf9037
JB
2546}
2547
c19d1205
ZW
2548/* Should never be called, as .req goes between the alias and the
2549 register name, not at the beginning of the line. */
c921be7d 2550
b99bd4ef 2551static void
c19d1205 2552s_req (int a ATTRIBUTE_UNUSED)
b99bd4ef 2553{
c19d1205
ZW
2554 as_bad (_("invalid syntax for .req directive"));
2555}
b99bd4ef 2556
dcbf9037
JB
2557static void
2558s_dn (int a ATTRIBUTE_UNUSED)
2559{
2560 as_bad (_("invalid syntax for .dn directive"));
2561}
2562
2563static void
2564s_qn (int a ATTRIBUTE_UNUSED)
2565{
2566 as_bad (_("invalid syntax for .qn directive"));
2567}
2568
c19d1205
ZW
2569/* The .unreq directive deletes an alias which was previously defined
2570 by .req. For example:
b99bd4ef 2571
c19d1205
ZW
2572 my_alias .req r11
2573 .unreq my_alias */
b99bd4ef
NC
2574
2575static void
c19d1205 2576s_unreq (int a ATTRIBUTE_UNUSED)
b99bd4ef 2577{
c19d1205
ZW
2578 char * name;
2579 char saved_char;
b99bd4ef 2580
c19d1205
ZW
2581 name = input_line_pointer;
2582
2583 while (*input_line_pointer != 0
2584 && *input_line_pointer != ' '
2585 && *input_line_pointer != '\n')
2586 ++input_line_pointer;
2587
2588 saved_char = *input_line_pointer;
2589 *input_line_pointer = 0;
2590
2591 if (!*name)
2592 as_bad (_("invalid syntax for .unreq directive"));
2593 else
2594 {
21d799b5 2595 struct reg_entry *reg = (struct reg_entry *) hash_find (arm_reg_hsh,
477330fc 2596 name);
c19d1205
ZW
2597
2598 if (!reg)
2599 as_bad (_("unknown register alias '%s'"), name);
2600 else if (reg->builtin)
a1727c1a 2601 as_warn (_("ignoring attempt to use .unreq on fixed register name: '%s'"),
c19d1205
ZW
2602 name);
2603 else
2604 {
d929913e
NC
2605 char * p;
2606 char * nbuf;
2607
db0bc284 2608 hash_delete (arm_reg_hsh, name, FALSE);
c19d1205 2609 free ((char *) reg->name);
477330fc
RM
2610 if (reg->neon)
2611 free (reg->neon);
c19d1205 2612 free (reg);
d929913e
NC
2613
2614 /* Also locate the all upper case and all lower case versions.
2615 Do not complain if we cannot find one or the other as it
2616 was probably deleted above. */
5f4273c7 2617
d929913e
NC
2618 nbuf = strdup (name);
2619 for (p = nbuf; *p; p++)
2620 *p = TOUPPER (*p);
21d799b5 2621 reg = (struct reg_entry *) hash_find (arm_reg_hsh, nbuf);
d929913e
NC
2622 if (reg)
2623 {
db0bc284 2624 hash_delete (arm_reg_hsh, nbuf, FALSE);
d929913e
NC
2625 free ((char *) reg->name);
2626 if (reg->neon)
2627 free (reg->neon);
2628 free (reg);
2629 }
2630
2631 for (p = nbuf; *p; p++)
2632 *p = TOLOWER (*p);
21d799b5 2633 reg = (struct reg_entry *) hash_find (arm_reg_hsh, nbuf);
d929913e
NC
2634 if (reg)
2635 {
db0bc284 2636 hash_delete (arm_reg_hsh, nbuf, FALSE);
d929913e
NC
2637 free ((char *) reg->name);
2638 if (reg->neon)
2639 free (reg->neon);
2640 free (reg);
2641 }
2642
2643 free (nbuf);
c19d1205
ZW
2644 }
2645 }
b99bd4ef 2646
c19d1205 2647 *input_line_pointer = saved_char;
b99bd4ef
NC
2648 demand_empty_rest_of_line ();
2649}
2650
c19d1205
ZW
2651/* Directives: Instruction set selection. */
2652
2653#ifdef OBJ_ELF
2654/* This code is to handle mapping symbols as defined in the ARM ELF spec.
2655 (See "Mapping symbols", section 4.5.5, ARM AAELF version 1.0).
2656 Note that previously, $a and $t has type STT_FUNC (BSF_OBJECT flag),
2657 and $d has type STT_OBJECT (BSF_OBJECT flag). Now all three are untyped. */
2658
cd000bff
DJ
2659/* Create a new mapping symbol for the transition to STATE. */
2660
2661static void
2662make_mapping_symbol (enum mstate state, valueT value, fragS *frag)
b99bd4ef 2663{
a737bd4d 2664 symbolS * symbolP;
c19d1205
ZW
2665 const char * symname;
2666 int type;
b99bd4ef 2667
c19d1205 2668 switch (state)
b99bd4ef 2669 {
c19d1205
ZW
2670 case MAP_DATA:
2671 symname = "$d";
2672 type = BSF_NO_FLAGS;
2673 break;
2674 case MAP_ARM:
2675 symname = "$a";
2676 type = BSF_NO_FLAGS;
2677 break;
2678 case MAP_THUMB:
2679 symname = "$t";
2680 type = BSF_NO_FLAGS;
2681 break;
c19d1205
ZW
2682 default:
2683 abort ();
2684 }
2685
cd000bff 2686 symbolP = symbol_new (symname, now_seg, value, frag);
c19d1205
ZW
2687 symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
2688
2689 switch (state)
2690 {
2691 case MAP_ARM:
2692 THUMB_SET_FUNC (symbolP, 0);
2693 ARM_SET_THUMB (symbolP, 0);
2694 ARM_SET_INTERWORK (symbolP, support_interwork);
2695 break;
2696
2697 case MAP_THUMB:
2698 THUMB_SET_FUNC (symbolP, 1);
2699 ARM_SET_THUMB (symbolP, 1);
2700 ARM_SET_INTERWORK (symbolP, support_interwork);
2701 break;
2702
2703 case MAP_DATA:
2704 default:
cd000bff
DJ
2705 break;
2706 }
2707
2708 /* Save the mapping symbols for future reference. Also check that
2709 we do not place two mapping symbols at the same offset within a
2710 frag. We'll handle overlap between frags in
2de7820f
JZ
2711 check_mapping_symbols.
2712
2713 If .fill or other data filling directive generates zero sized data,
2714 the mapping symbol for the following code will have the same value
2715 as the one generated for the data filling directive. In this case,
2716 we replace the old symbol with the new one at the same address. */
cd000bff
DJ
2717 if (value == 0)
2718 {
2de7820f
JZ
2719 if (frag->tc_frag_data.first_map != NULL)
2720 {
2721 know (S_GET_VALUE (frag->tc_frag_data.first_map) == 0);
2722 symbol_remove (frag->tc_frag_data.first_map, &symbol_rootP, &symbol_lastP);
2723 }
cd000bff
DJ
2724 frag->tc_frag_data.first_map = symbolP;
2725 }
2726 if (frag->tc_frag_data.last_map != NULL)
0f020cef
JZ
2727 {
2728 know (S_GET_VALUE (frag->tc_frag_data.last_map) <= S_GET_VALUE (symbolP));
0f020cef
JZ
2729 if (S_GET_VALUE (frag->tc_frag_data.last_map) == S_GET_VALUE (symbolP))
2730 symbol_remove (frag->tc_frag_data.last_map, &symbol_rootP, &symbol_lastP);
2731 }
cd000bff
DJ
2732 frag->tc_frag_data.last_map = symbolP;
2733}
2734
2735/* We must sometimes convert a region marked as code to data during
2736 code alignment, if an odd number of bytes have to be padded. The
2737 code mapping symbol is pushed to an aligned address. */
2738
2739static void
2740insert_data_mapping_symbol (enum mstate state,
2741 valueT value, fragS *frag, offsetT bytes)
2742{
2743 /* If there was already a mapping symbol, remove it. */
2744 if (frag->tc_frag_data.last_map != NULL
2745 && S_GET_VALUE (frag->tc_frag_data.last_map) == frag->fr_address + value)
2746 {
2747 symbolS *symp = frag->tc_frag_data.last_map;
2748
2749 if (value == 0)
2750 {
2751 know (frag->tc_frag_data.first_map == symp);
2752 frag->tc_frag_data.first_map = NULL;
2753 }
2754 frag->tc_frag_data.last_map = NULL;
2755 symbol_remove (symp, &symbol_rootP, &symbol_lastP);
c19d1205 2756 }
cd000bff
DJ
2757
2758 make_mapping_symbol (MAP_DATA, value, frag);
2759 make_mapping_symbol (state, value + bytes, frag);
2760}
2761
2762static void mapping_state_2 (enum mstate state, int max_chars);
2763
2764/* Set the mapping state to STATE. Only call this when about to
2765 emit some STATE bytes to the file. */
2766
4e9aaefb 2767#define TRANSITION(from, to) (mapstate == (from) && state == (to))
cd000bff
DJ
2768void
2769mapping_state (enum mstate state)
2770{
940b5ce0
DJ
2771 enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate;
2772
cd000bff
DJ
2773 if (mapstate == state)
2774 /* The mapping symbol has already been emitted.
2775 There is nothing else to do. */
2776 return;
49c62a33
NC
2777
2778 if (state == MAP_ARM || state == MAP_THUMB)
2779 /* PR gas/12931
2780 All ARM instructions require 4-byte alignment.
2781 (Almost) all Thumb instructions require 2-byte alignment.
2782
2783 When emitting instructions into any section, mark the section
2784 appropriately.
2785
2786 Some Thumb instructions are alignment-sensitive modulo 4 bytes,
2787 but themselves require 2-byte alignment; this applies to some
33eaf5de 2788 PC- relative forms. However, these cases will involve implicit
49c62a33
NC
2789 literal pool generation or an explicit .align >=2, both of
2790 which will cause the section to me marked with sufficient
2791 alignment. Thus, we don't handle those cases here. */
2792 record_alignment (now_seg, state == MAP_ARM ? 2 : 1);
2793
2794 if (TRANSITION (MAP_UNDEFINED, MAP_DATA))
4e9aaefb 2795 /* This case will be evaluated later. */
cd000bff 2796 return;
cd000bff
DJ
2797
2798 mapping_state_2 (state, 0);
cd000bff
DJ
2799}
2800
2801/* Same as mapping_state, but MAX_CHARS bytes have already been
2802 allocated. Put the mapping symbol that far back. */
2803
2804static void
2805mapping_state_2 (enum mstate state, int max_chars)
2806{
940b5ce0
DJ
2807 enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate;
2808
2809 if (!SEG_NORMAL (now_seg))
2810 return;
2811
cd000bff
DJ
2812 if (mapstate == state)
2813 /* The mapping symbol has already been emitted.
2814 There is nothing else to do. */
2815 return;
2816
4e9aaefb
SA
2817 if (TRANSITION (MAP_UNDEFINED, MAP_ARM)
2818 || TRANSITION (MAP_UNDEFINED, MAP_THUMB))
2819 {
2820 struct frag * const frag_first = seg_info (now_seg)->frchainP->frch_root;
2821 const int add_symbol = (frag_now != frag_first) || (frag_now_fix () > 0);
2822
2823 if (add_symbol)
2824 make_mapping_symbol (MAP_DATA, (valueT) 0, frag_first);
2825 }
2826
cd000bff
DJ
2827 seg_info (now_seg)->tc_segment_info_data.mapstate = state;
2828 make_mapping_symbol (state, (valueT) frag_now_fix () - max_chars, frag_now);
c19d1205 2829}
4e9aaefb 2830#undef TRANSITION
c19d1205 2831#else
d3106081
NS
2832#define mapping_state(x) ((void)0)
2833#define mapping_state_2(x, y) ((void)0)
c19d1205
ZW
2834#endif
2835
2836/* Find the real, Thumb encoded start of a Thumb function. */
2837
4343666d 2838#ifdef OBJ_COFF
c19d1205
ZW
2839static symbolS *
2840find_real_start (symbolS * symbolP)
2841{
2842 char * real_start;
2843 const char * name = S_GET_NAME (symbolP);
2844 symbolS * new_target;
2845
2846 /* This definition must agree with the one in gcc/config/arm/thumb.c. */
2847#define STUB_NAME ".real_start_of"
2848
2849 if (name == NULL)
2850 abort ();
2851
37f6032b
ZW
2852 /* The compiler may generate BL instructions to local labels because
2853 it needs to perform a branch to a far away location. These labels
2854 do not have a corresponding ".real_start_of" label. We check
2855 both for S_IS_LOCAL and for a leading dot, to give a way to bypass
2856 the ".real_start_of" convention for nonlocal branches. */
2857 if (S_IS_LOCAL (symbolP) || name[0] == '.')
c19d1205
ZW
2858 return symbolP;
2859
e1fa0163 2860 real_start = concat (STUB_NAME, name, NULL);
c19d1205 2861 new_target = symbol_find (real_start);
e1fa0163 2862 free (real_start);
c19d1205
ZW
2863
2864 if (new_target == NULL)
2865 {
bd3ba5d1 2866 as_warn (_("Failed to find real start of function: %s\n"), name);
c19d1205
ZW
2867 new_target = symbolP;
2868 }
2869
c19d1205
ZW
2870 return new_target;
2871}
4343666d 2872#endif
c19d1205
ZW
2873
2874static void
2875opcode_select (int width)
2876{
2877 switch (width)
2878 {
2879 case 16:
2880 if (! thumb_mode)
2881 {
e74cfd16 2882 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
c19d1205
ZW
2883 as_bad (_("selected processor does not support THUMB opcodes"));
2884
2885 thumb_mode = 1;
2886 /* No need to force the alignment, since we will have been
2887 coming from ARM mode, which is word-aligned. */
2888 record_alignment (now_seg, 1);
2889 }
c19d1205
ZW
2890 break;
2891
2892 case 32:
2893 if (thumb_mode)
2894 {
e74cfd16 2895 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
c19d1205
ZW
2896 as_bad (_("selected processor does not support ARM opcodes"));
2897
2898 thumb_mode = 0;
2899
2900 if (!need_pass_2)
2901 frag_align (2, 0, 0);
2902
2903 record_alignment (now_seg, 1);
2904 }
c19d1205
ZW
2905 break;
2906
2907 default:
2908 as_bad (_("invalid instruction size selected (%d)"), width);
2909 }
2910}
2911
2912static void
2913s_arm (int ignore ATTRIBUTE_UNUSED)
2914{
2915 opcode_select (32);
2916 demand_empty_rest_of_line ();
2917}
2918
2919static void
2920s_thumb (int ignore ATTRIBUTE_UNUSED)
2921{
2922 opcode_select (16);
2923 demand_empty_rest_of_line ();
2924}
2925
2926static void
2927s_code (int unused ATTRIBUTE_UNUSED)
2928{
2929 int temp;
2930
2931 temp = get_absolute_expression ();
2932 switch (temp)
2933 {
2934 case 16:
2935 case 32:
2936 opcode_select (temp);
2937 break;
2938
2939 default:
2940 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
2941 }
2942}
2943
2944static void
2945s_force_thumb (int ignore ATTRIBUTE_UNUSED)
2946{
2947 /* If we are not already in thumb mode go into it, EVEN if
2948 the target processor does not support thumb instructions.
2949 This is used by gcc/config/arm/lib1funcs.asm for example
2950 to compile interworking support functions even if the
2951 target processor should not support interworking. */
2952 if (! thumb_mode)
2953 {
2954 thumb_mode = 2;
2955 record_alignment (now_seg, 1);
2956 }
2957
2958 demand_empty_rest_of_line ();
2959}
2960
2961static void
2962s_thumb_func (int ignore ATTRIBUTE_UNUSED)
2963{
2964 s_thumb (0);
2965
2966 /* The following label is the name/address of the start of a Thumb function.
2967 We need to know this for the interworking support. */
2968 label_is_thumb_function_name = TRUE;
2969}
2970
2971/* Perform a .set directive, but also mark the alias as
2972 being a thumb function. */
2973
2974static void
2975s_thumb_set (int equiv)
2976{
2977 /* XXX the following is a duplicate of the code for s_set() in read.c
2978 We cannot just call that code as we need to get at the symbol that
2979 is created. */
2980 char * name;
2981 char delim;
2982 char * end_name;
2983 symbolS * symbolP;
2984
2985 /* Especial apologies for the random logic:
2986 This just grew, and could be parsed much more simply!
2987 Dean - in haste. */
d02603dc 2988 delim = get_symbol_name (& name);
c19d1205 2989 end_name = input_line_pointer;
d02603dc 2990 (void) restore_line_pointer (delim);
c19d1205
ZW
2991
2992 if (*input_line_pointer != ',')
2993 {
2994 *end_name = 0;
2995 as_bad (_("expected comma after name \"%s\""), name);
b99bd4ef
NC
2996 *end_name = delim;
2997 ignore_rest_of_line ();
2998 return;
2999 }
3000
3001 input_line_pointer++;
3002 *end_name = 0;
3003
3004 if (name[0] == '.' && name[1] == '\0')
3005 {
3006 /* XXX - this should not happen to .thumb_set. */
3007 abort ();
3008 }
3009
3010 if ((symbolP = symbol_find (name)) == NULL
3011 && (symbolP = md_undefined_symbol (name)) == NULL)
3012 {
3013#ifndef NO_LISTING
3014 /* When doing symbol listings, play games with dummy fragments living
3015 outside the normal fragment chain to record the file and line info
c19d1205 3016 for this symbol. */
b99bd4ef
NC
3017 if (listing & LISTING_SYMBOLS)
3018 {
3019 extern struct list_info_struct * listing_tail;
21d799b5 3020 fragS * dummy_frag = (fragS * ) xmalloc (sizeof (fragS));
b99bd4ef
NC
3021
3022 memset (dummy_frag, 0, sizeof (fragS));
3023 dummy_frag->fr_type = rs_fill;
3024 dummy_frag->line = listing_tail;
3025 symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
3026 dummy_frag->fr_symbol = symbolP;
3027 }
3028 else
3029#endif
3030 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
3031
3032#ifdef OBJ_COFF
3033 /* "set" symbols are local unless otherwise specified. */
3034 SF_SET_LOCAL (symbolP);
3035#endif /* OBJ_COFF */
3036 } /* Make a new symbol. */
3037
3038 symbol_table_insert (symbolP);
3039
3040 * end_name = delim;
3041
3042 if (equiv
3043 && S_IS_DEFINED (symbolP)
3044 && S_GET_SEGMENT (symbolP) != reg_section)
3045 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
3046
3047 pseudo_set (symbolP);
3048
3049 demand_empty_rest_of_line ();
3050
c19d1205 3051 /* XXX Now we come to the Thumb specific bit of code. */
b99bd4ef
NC
3052
3053 THUMB_SET_FUNC (symbolP, 1);
3054 ARM_SET_THUMB (symbolP, 1);
3055#if defined OBJ_ELF || defined OBJ_COFF
3056 ARM_SET_INTERWORK (symbolP, support_interwork);
3057#endif
3058}
3059
c19d1205 3060/* Directives: Mode selection. */
b99bd4ef 3061
c19d1205
ZW
3062/* .syntax [unified|divided] - choose the new unified syntax
3063 (same for Arm and Thumb encoding, modulo slight differences in what
3064 can be represented) or the old divergent syntax for each mode. */
b99bd4ef 3065static void
c19d1205 3066s_syntax (int unused ATTRIBUTE_UNUSED)
b99bd4ef 3067{
c19d1205
ZW
3068 char *name, delim;
3069
d02603dc 3070 delim = get_symbol_name (& name);
c19d1205
ZW
3071
3072 if (!strcasecmp (name, "unified"))
3073 unified_syntax = TRUE;
3074 else if (!strcasecmp (name, "divided"))
3075 unified_syntax = FALSE;
3076 else
3077 {
3078 as_bad (_("unrecognized syntax mode \"%s\""), name);
3079 return;
3080 }
d02603dc 3081 (void) restore_line_pointer (delim);
b99bd4ef
NC
3082 demand_empty_rest_of_line ();
3083}
3084
c19d1205
ZW
3085/* Directives: sectioning and alignment. */
3086
c19d1205
ZW
3087static void
3088s_bss (int ignore ATTRIBUTE_UNUSED)
b99bd4ef 3089{
c19d1205
ZW
3090 /* We don't support putting frags in the BSS segment, we fake it by
3091 marking in_bss, then looking at s_skip for clues. */
3092 subseg_set (bss_section, 0);
3093 demand_empty_rest_of_line ();
cd000bff
DJ
3094
3095#ifdef md_elf_section_change_hook
3096 md_elf_section_change_hook ();
3097#endif
c19d1205 3098}
b99bd4ef 3099
c19d1205
ZW
3100static void
3101s_even (int ignore ATTRIBUTE_UNUSED)
3102{
3103 /* Never make frag if expect extra pass. */
3104 if (!need_pass_2)
3105 frag_align (1, 0, 0);
b99bd4ef 3106
c19d1205 3107 record_alignment (now_seg, 1);
b99bd4ef 3108
c19d1205 3109 demand_empty_rest_of_line ();
b99bd4ef
NC
3110}
3111
2e6976a8
DG
3112/* Directives: CodeComposer Studio. */
3113
3114/* .ref (for CodeComposer Studio syntax only). */
3115static void
3116s_ccs_ref (int unused ATTRIBUTE_UNUSED)
3117{
3118 if (codecomposer_syntax)
3119 ignore_rest_of_line ();
3120 else
3121 as_bad (_(".ref pseudo-op only available with -mccs flag."));
3122}
3123
3124/* If name is not NULL, then it is used for marking the beginning of a
2b0f3761 3125 function, whereas if it is NULL then it means the function end. */
2e6976a8
DG
3126static void
3127asmfunc_debug (const char * name)
3128{
3129 static const char * last_name = NULL;
3130
3131 if (name != NULL)
3132 {
3133 gas_assert (last_name == NULL);
3134 last_name = name;
3135
3136 if (debug_type == DEBUG_STABS)
3137 stabs_generate_asm_func (name, name);
3138 }
3139 else
3140 {
3141 gas_assert (last_name != NULL);
3142
3143 if (debug_type == DEBUG_STABS)
3144 stabs_generate_asm_endfunc (last_name, last_name);
3145
3146 last_name = NULL;
3147 }
3148}
3149
3150static void
3151s_ccs_asmfunc (int unused ATTRIBUTE_UNUSED)
3152{
3153 if (codecomposer_syntax)
3154 {
3155 switch (asmfunc_state)
3156 {
3157 case OUTSIDE_ASMFUNC:
3158 asmfunc_state = WAITING_ASMFUNC_NAME;
3159 break;
3160
3161 case WAITING_ASMFUNC_NAME:
3162 as_bad (_(".asmfunc repeated."));
3163 break;
3164
3165 case WAITING_ENDASMFUNC:
3166 as_bad (_(".asmfunc without function."));
3167 break;
3168 }
3169 demand_empty_rest_of_line ();
3170 }
3171 else
3172 as_bad (_(".asmfunc pseudo-op only available with -mccs flag."));
3173}
3174
3175static void
3176s_ccs_endasmfunc (int unused ATTRIBUTE_UNUSED)
3177{
3178 if (codecomposer_syntax)
3179 {
3180 switch (asmfunc_state)
3181 {
3182 case OUTSIDE_ASMFUNC:
3183 as_bad (_(".endasmfunc without a .asmfunc."));
3184 break;
3185
3186 case WAITING_ASMFUNC_NAME:
3187 as_bad (_(".endasmfunc without function."));
3188 break;
3189
3190 case WAITING_ENDASMFUNC:
3191 asmfunc_state = OUTSIDE_ASMFUNC;
3192 asmfunc_debug (NULL);
3193 break;
3194 }
3195 demand_empty_rest_of_line ();
3196 }
3197 else
3198 as_bad (_(".endasmfunc pseudo-op only available with -mccs flag."));
3199}
3200
3201static void
3202s_ccs_def (int name)
3203{
3204 if (codecomposer_syntax)
3205 s_globl (name);
3206 else
3207 as_bad (_(".def pseudo-op only available with -mccs flag."));
3208}
3209
c19d1205 3210/* Directives: Literal pools. */
a737bd4d 3211
c19d1205
ZW
3212static literal_pool *
3213find_literal_pool (void)
a737bd4d 3214{
c19d1205 3215 literal_pool * pool;
a737bd4d 3216
c19d1205 3217 for (pool = list_of_pools; pool != NULL; pool = pool->next)
a737bd4d 3218 {
c19d1205
ZW
3219 if (pool->section == now_seg
3220 && pool->sub_section == now_subseg)
3221 break;
a737bd4d
NC
3222 }
3223
c19d1205 3224 return pool;
a737bd4d
NC
3225}
3226
c19d1205
ZW
3227static literal_pool *
3228find_or_make_literal_pool (void)
a737bd4d 3229{
c19d1205
ZW
3230 /* Next literal pool ID number. */
3231 static unsigned int latest_pool_num = 1;
3232 literal_pool * pool;
a737bd4d 3233
c19d1205 3234 pool = find_literal_pool ();
a737bd4d 3235
c19d1205 3236 if (pool == NULL)
a737bd4d 3237 {
c19d1205 3238 /* Create a new pool. */
325801bd 3239 pool = XNEW (literal_pool);
c19d1205
ZW
3240 if (! pool)
3241 return NULL;
a737bd4d 3242
c19d1205
ZW
3243 pool->next_free_entry = 0;
3244 pool->section = now_seg;
3245 pool->sub_section = now_subseg;
3246 pool->next = list_of_pools;
3247 pool->symbol = NULL;
8335d6aa 3248 pool->alignment = 2;
c19d1205
ZW
3249
3250 /* Add it to the list. */
3251 list_of_pools = pool;
a737bd4d 3252 }
a737bd4d 3253
c19d1205
ZW
3254 /* New pools, and emptied pools, will have a NULL symbol. */
3255 if (pool->symbol == NULL)
a737bd4d 3256 {
c19d1205
ZW
3257 pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
3258 (valueT) 0, &zero_address_frag);
3259 pool->id = latest_pool_num ++;
a737bd4d
NC
3260 }
3261
c19d1205
ZW
3262 /* Done. */
3263 return pool;
a737bd4d
NC
3264}
3265
c19d1205 3266/* Add the literal in the global 'inst'
5f4273c7 3267 structure to the relevant literal pool. */
b99bd4ef
NC
3268
3269static int
8335d6aa 3270add_to_lit_pool (unsigned int nbytes)
b99bd4ef 3271{
8335d6aa
JW
3272#define PADDING_SLOT 0x1
3273#define LIT_ENTRY_SIZE_MASK 0xFF
c19d1205 3274 literal_pool * pool;
8335d6aa
JW
3275 unsigned int entry, pool_size = 0;
3276 bfd_boolean padding_slot_p = FALSE;
e56c722b 3277 unsigned imm1 = 0;
8335d6aa
JW
3278 unsigned imm2 = 0;
3279
3280 if (nbytes == 8)
3281 {
3282 imm1 = inst.operands[1].imm;
3283 imm2 = (inst.operands[1].regisimm ? inst.operands[1].reg
e2b0ab59 3284 : inst.relocs[0].exp.X_unsigned ? 0
2569ceb0 3285 : ((bfd_int64_t) inst.operands[1].imm) >> 32);
8335d6aa
JW
3286 if (target_big_endian)
3287 {
3288 imm1 = imm2;
3289 imm2 = inst.operands[1].imm;
3290 }
3291 }
b99bd4ef 3292
c19d1205
ZW
3293 pool = find_or_make_literal_pool ();
3294
3295 /* Check if this literal value is already in the pool. */
3296 for (entry = 0; entry < pool->next_free_entry; entry ++)
b99bd4ef 3297 {
8335d6aa
JW
3298 if (nbytes == 4)
3299 {
e2b0ab59
AV
3300 if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
3301 && (inst.relocs[0].exp.X_op == O_constant)
8335d6aa 3302 && (pool->literals[entry].X_add_number
e2b0ab59 3303 == inst.relocs[0].exp.X_add_number)
8335d6aa
JW
3304 && (pool->literals[entry].X_md == nbytes)
3305 && (pool->literals[entry].X_unsigned
e2b0ab59 3306 == inst.relocs[0].exp.X_unsigned))
8335d6aa
JW
3307 break;
3308
e2b0ab59
AV
3309 if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
3310 && (inst.relocs[0].exp.X_op == O_symbol)
8335d6aa 3311 && (pool->literals[entry].X_add_number
e2b0ab59 3312 == inst.relocs[0].exp.X_add_number)
8335d6aa 3313 && (pool->literals[entry].X_add_symbol
e2b0ab59 3314 == inst.relocs[0].exp.X_add_symbol)
8335d6aa 3315 && (pool->literals[entry].X_op_symbol
e2b0ab59 3316 == inst.relocs[0].exp.X_op_symbol)
8335d6aa
JW
3317 && (pool->literals[entry].X_md == nbytes))
3318 break;
3319 }
3320 else if ((nbytes == 8)
3321 && !(pool_size & 0x7)
3322 && ((entry + 1) != pool->next_free_entry)
3323 && (pool->literals[entry].X_op == O_constant)
19f2f6a9 3324 && (pool->literals[entry].X_add_number == (offsetT) imm1)
8335d6aa 3325 && (pool->literals[entry].X_unsigned
e2b0ab59 3326 == inst.relocs[0].exp.X_unsigned)
8335d6aa 3327 && (pool->literals[entry + 1].X_op == O_constant)
19f2f6a9 3328 && (pool->literals[entry + 1].X_add_number == (offsetT) imm2)
8335d6aa 3329 && (pool->literals[entry + 1].X_unsigned
e2b0ab59 3330 == inst.relocs[0].exp.X_unsigned))
c19d1205
ZW
3331 break;
3332
8335d6aa
JW
3333 padding_slot_p = ((pool->literals[entry].X_md >> 8) == PADDING_SLOT);
3334 if (padding_slot_p && (nbytes == 4))
c19d1205 3335 break;
8335d6aa
JW
3336
3337 pool_size += 4;
b99bd4ef
NC
3338 }
3339
c19d1205
ZW
3340 /* Do we need to create a new entry? */
3341 if (entry == pool->next_free_entry)
3342 {
3343 if (entry >= MAX_LITERAL_POOL_SIZE)
3344 {
3345 inst.error = _("literal pool overflow");
3346 return FAIL;
3347 }
3348
8335d6aa
JW
3349 if (nbytes == 8)
3350 {
3351 /* For 8-byte entries, we align to an 8-byte boundary,
3352 and split it into two 4-byte entries, because on 32-bit
3353 host, 8-byte constants are treated as big num, thus
3354 saved in "generic_bignum" which will be overwritten
3355 by later assignments.
3356
3357 We also need to make sure there is enough space for
3358 the split.
3359
3360 We also check to make sure the literal operand is a
3361 constant number. */
e2b0ab59
AV
3362 if (!(inst.relocs[0].exp.X_op == O_constant
3363 || inst.relocs[0].exp.X_op == O_big))
8335d6aa
JW
3364 {
3365 inst.error = _("invalid type for literal pool");
3366 return FAIL;
3367 }
3368 else if (pool_size & 0x7)
3369 {
3370 if ((entry + 2) >= MAX_LITERAL_POOL_SIZE)
3371 {
3372 inst.error = _("literal pool overflow");
3373 return FAIL;
3374 }
3375
e2b0ab59 3376 pool->literals[entry] = inst.relocs[0].exp;
a6684f0d 3377 pool->literals[entry].X_op = O_constant;
8335d6aa
JW
3378 pool->literals[entry].X_add_number = 0;
3379 pool->literals[entry++].X_md = (PADDING_SLOT << 8) | 4;
3380 pool->next_free_entry += 1;
3381 pool_size += 4;
3382 }
3383 else if ((entry + 1) >= MAX_LITERAL_POOL_SIZE)
3384 {
3385 inst.error = _("literal pool overflow");
3386 return FAIL;
3387 }
3388
e2b0ab59 3389 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3390 pool->literals[entry].X_op = O_constant;
3391 pool->literals[entry].X_add_number = imm1;
e2b0ab59 3392 pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
8335d6aa 3393 pool->literals[entry++].X_md = 4;
e2b0ab59 3394 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3395 pool->literals[entry].X_op = O_constant;
3396 pool->literals[entry].X_add_number = imm2;
e2b0ab59 3397 pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
8335d6aa
JW
3398 pool->literals[entry].X_md = 4;
3399 pool->alignment = 3;
3400 pool->next_free_entry += 1;
3401 }
3402 else
3403 {
e2b0ab59 3404 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3405 pool->literals[entry].X_md = 4;
3406 }
3407
a8040cf2
NC
3408#ifdef OBJ_ELF
3409 /* PR ld/12974: Record the location of the first source line to reference
3410 this entry in the literal pool. If it turns out during linking that the
3411 symbol does not exist we will be able to give an accurate line number for
3412 the (first use of the) missing reference. */
3413 if (debug_type == DEBUG_DWARF2)
3414 dwarf2_where (pool->locs + entry);
3415#endif
c19d1205
ZW
3416 pool->next_free_entry += 1;
3417 }
8335d6aa
JW
3418 else if (padding_slot_p)
3419 {
e2b0ab59 3420 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3421 pool->literals[entry].X_md = nbytes;
3422 }
b99bd4ef 3423
e2b0ab59
AV
3424 inst.relocs[0].exp.X_op = O_symbol;
3425 inst.relocs[0].exp.X_add_number = pool_size;
3426 inst.relocs[0].exp.X_add_symbol = pool->symbol;
b99bd4ef 3427
c19d1205 3428 return SUCCESS;
b99bd4ef
NC
3429}
3430
2e6976a8 3431bfd_boolean
2e57ce7b 3432tc_start_label_without_colon (void)
2e6976a8
DG
3433{
3434 bfd_boolean ret = TRUE;
3435
3436 if (codecomposer_syntax && asmfunc_state == WAITING_ASMFUNC_NAME)
3437 {
2e57ce7b 3438 const char *label = input_line_pointer;
2e6976a8
DG
3439
3440 while (!is_end_of_line[(int) label[-1]])
3441 --label;
3442
3443 if (*label == '.')
3444 {
3445 as_bad (_("Invalid label '%s'"), label);
3446 ret = FALSE;
3447 }
3448
3449 asmfunc_debug (label);
3450
3451 asmfunc_state = WAITING_ENDASMFUNC;
3452 }
3453
3454 return ret;
3455}
3456
c19d1205 3457/* Can't use symbol_new here, so have to create a symbol and then at
33eaf5de 3458 a later date assign it a value. That's what these functions do. */
e16bb312 3459
c19d1205
ZW
3460static void
3461symbol_locate (symbolS * symbolP,
3462 const char * name, /* It is copied, the caller can modify. */
3463 segT segment, /* Segment identifier (SEG_<something>). */
3464 valueT valu, /* Symbol value. */
3465 fragS * frag) /* Associated fragment. */
3466{
e57e6ddc 3467 size_t name_length;
c19d1205 3468 char * preserved_copy_of_name;
e16bb312 3469
c19d1205
ZW
3470 name_length = strlen (name) + 1; /* +1 for \0. */
3471 obstack_grow (&notes, name, name_length);
21d799b5 3472 preserved_copy_of_name = (char *) obstack_finish (&notes);
e16bb312 3473
c19d1205
ZW
3474#ifdef tc_canonicalize_symbol_name
3475 preserved_copy_of_name =
3476 tc_canonicalize_symbol_name (preserved_copy_of_name);
3477#endif
b99bd4ef 3478
c19d1205 3479 S_SET_NAME (symbolP, preserved_copy_of_name);
b99bd4ef 3480
c19d1205
ZW
3481 S_SET_SEGMENT (symbolP, segment);
3482 S_SET_VALUE (symbolP, valu);
3483 symbol_clear_list_pointers (symbolP);
b99bd4ef 3484
c19d1205 3485 symbol_set_frag (symbolP, frag);
b99bd4ef 3486
c19d1205
ZW
3487 /* Link to end of symbol chain. */
3488 {
3489 extern int symbol_table_frozen;
b99bd4ef 3490
c19d1205
ZW
3491 if (symbol_table_frozen)
3492 abort ();
3493 }
b99bd4ef 3494
c19d1205 3495 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
b99bd4ef 3496
c19d1205 3497 obj_symbol_new_hook (symbolP);
b99bd4ef 3498
c19d1205
ZW
3499#ifdef tc_symbol_new_hook
3500 tc_symbol_new_hook (symbolP);
3501#endif
3502
3503#ifdef DEBUG_SYMS
3504 verify_symbol_chain (symbol_rootP, symbol_lastP);
3505#endif /* DEBUG_SYMS */
b99bd4ef
NC
3506}
3507
c19d1205
ZW
3508static void
3509s_ltorg (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 3510{
c19d1205
ZW
3511 unsigned int entry;
3512 literal_pool * pool;
3513 char sym_name[20];
b99bd4ef 3514
c19d1205
ZW
3515 pool = find_literal_pool ();
3516 if (pool == NULL
3517 || pool->symbol == NULL
3518 || pool->next_free_entry == 0)
3519 return;
b99bd4ef 3520
c19d1205
ZW
3521 /* Align pool as you have word accesses.
3522 Only make a frag if we have to. */
3523 if (!need_pass_2)
8335d6aa 3524 frag_align (pool->alignment, 0, 0);
b99bd4ef 3525
c19d1205 3526 record_alignment (now_seg, 2);
b99bd4ef 3527
aaca88ef 3528#ifdef OBJ_ELF
47fc6e36
WN
3529 seg_info (now_seg)->tc_segment_info_data.mapstate = MAP_DATA;
3530 make_mapping_symbol (MAP_DATA, (valueT) frag_now_fix (), frag_now);
aaca88ef 3531#endif
c19d1205 3532 sprintf (sym_name, "$$lit_\002%x", pool->id);
b99bd4ef 3533
c19d1205
ZW
3534 symbol_locate (pool->symbol, sym_name, now_seg,
3535 (valueT) frag_now_fix (), frag_now);
3536 symbol_table_insert (pool->symbol);
b99bd4ef 3537
c19d1205 3538 ARM_SET_THUMB (pool->symbol, thumb_mode);
b99bd4ef 3539
c19d1205
ZW
3540#if defined OBJ_COFF || defined OBJ_ELF
3541 ARM_SET_INTERWORK (pool->symbol, support_interwork);
3542#endif
6c43fab6 3543
c19d1205 3544 for (entry = 0; entry < pool->next_free_entry; entry ++)
a8040cf2
NC
3545 {
3546#ifdef OBJ_ELF
3547 if (debug_type == DEBUG_DWARF2)
3548 dwarf2_gen_line_info (frag_now_fix (), pool->locs + entry);
3549#endif
3550 /* First output the expression in the instruction to the pool. */
8335d6aa
JW
3551 emit_expr (&(pool->literals[entry]),
3552 pool->literals[entry].X_md & LIT_ENTRY_SIZE_MASK);
a8040cf2 3553 }
b99bd4ef 3554
c19d1205
ZW
3555 /* Mark the pool as empty. */
3556 pool->next_free_entry = 0;
3557 pool->symbol = NULL;
b99bd4ef
NC
3558}
3559
c19d1205
ZW
3560#ifdef OBJ_ELF
3561/* Forward declarations for functions below, in the MD interface
3562 section. */
3563static void fix_new_arm (fragS *, int, short, expressionS *, int, int);
3564static valueT create_unwind_entry (int);
3565static void start_unwind_section (const segT, int);
3566static void add_unwind_opcode (valueT, int);
3567static void flush_pending_unwind (void);
b99bd4ef 3568
c19d1205 3569/* Directives: Data. */
b99bd4ef 3570
c19d1205
ZW
3571static void
3572s_arm_elf_cons (int nbytes)
3573{
3574 expressionS exp;
b99bd4ef 3575
c19d1205
ZW
3576#ifdef md_flush_pending_output
3577 md_flush_pending_output ();
3578#endif
b99bd4ef 3579
c19d1205 3580 if (is_it_end_of_statement ())
b99bd4ef 3581 {
c19d1205
ZW
3582 demand_empty_rest_of_line ();
3583 return;
b99bd4ef
NC
3584 }
3585
c19d1205
ZW
3586#ifdef md_cons_align
3587 md_cons_align (nbytes);
3588#endif
b99bd4ef 3589
c19d1205
ZW
3590 mapping_state (MAP_DATA);
3591 do
b99bd4ef 3592 {
c19d1205
ZW
3593 int reloc;
3594 char *base = input_line_pointer;
b99bd4ef 3595
c19d1205 3596 expression (& exp);
b99bd4ef 3597
c19d1205
ZW
3598 if (exp.X_op != O_symbol)
3599 emit_expr (&exp, (unsigned int) nbytes);
3600 else
3601 {
3602 char *before_reloc = input_line_pointer;
3603 reloc = parse_reloc (&input_line_pointer);
3604 if (reloc == -1)
3605 {
3606 as_bad (_("unrecognized relocation suffix"));
3607 ignore_rest_of_line ();
3608 return;
3609 }
3610 else if (reloc == BFD_RELOC_UNUSED)
3611 emit_expr (&exp, (unsigned int) nbytes);
3612 else
3613 {
21d799b5 3614 reloc_howto_type *howto = (reloc_howto_type *)
477330fc
RM
3615 bfd_reloc_type_lookup (stdoutput,
3616 (bfd_reloc_code_real_type) reloc);
c19d1205 3617 int size = bfd_get_reloc_size (howto);
b99bd4ef 3618
2fc8bdac
ZW
3619 if (reloc == BFD_RELOC_ARM_PLT32)
3620 {
3621 as_bad (_("(plt) is only valid on branch targets"));
3622 reloc = BFD_RELOC_UNUSED;
3623 size = 0;
3624 }
3625
c19d1205 3626 if (size > nbytes)
992a06ee
AM
3627 as_bad (ngettext ("%s relocations do not fit in %d byte",
3628 "%s relocations do not fit in %d bytes",
3629 nbytes),
c19d1205
ZW
3630 howto->name, nbytes);
3631 else
3632 {
3633 /* We've parsed an expression stopping at O_symbol.
3634 But there may be more expression left now that we
3635 have parsed the relocation marker. Parse it again.
3636 XXX Surely there is a cleaner way to do this. */
3637 char *p = input_line_pointer;
3638 int offset;
325801bd 3639 char *save_buf = XNEWVEC (char, input_line_pointer - base);
e1fa0163 3640
c19d1205
ZW
3641 memcpy (save_buf, base, input_line_pointer - base);
3642 memmove (base + (input_line_pointer - before_reloc),
3643 base, before_reloc - base);
3644
3645 input_line_pointer = base + (input_line_pointer-before_reloc);
3646 expression (&exp);
3647 memcpy (base, save_buf, p - base);
3648
3649 offset = nbytes - size;
4b1a927e
AM
3650 p = frag_more (nbytes);
3651 memset (p, 0, nbytes);
c19d1205 3652 fix_new_exp (frag_now, p - frag_now->fr_literal + offset,
21d799b5 3653 size, &exp, 0, (enum bfd_reloc_code_real) reloc);
e1fa0163 3654 free (save_buf);
c19d1205
ZW
3655 }
3656 }
3657 }
b99bd4ef 3658 }
c19d1205 3659 while (*input_line_pointer++ == ',');
b99bd4ef 3660
c19d1205
ZW
3661 /* Put terminator back into stream. */
3662 input_line_pointer --;
3663 demand_empty_rest_of_line ();
b99bd4ef
NC
3664}
3665
c921be7d
NC
3666/* Emit an expression containing a 32-bit thumb instruction.
3667 Implementation based on put_thumb32_insn. */
3668
3669static void
3670emit_thumb32_expr (expressionS * exp)
3671{
3672 expressionS exp_high = *exp;
3673
3674 exp_high.X_add_number = (unsigned long)exp_high.X_add_number >> 16;
3675 emit_expr (& exp_high, (unsigned int) THUMB_SIZE);
3676 exp->X_add_number &= 0xffff;
3677 emit_expr (exp, (unsigned int) THUMB_SIZE);
3678}
3679
3680/* Guess the instruction size based on the opcode. */
3681
3682static int
3683thumb_insn_size (int opcode)
3684{
3685 if ((unsigned int) opcode < 0xe800u)
3686 return 2;
3687 else if ((unsigned int) opcode >= 0xe8000000u)
3688 return 4;
3689 else
3690 return 0;
3691}
3692
3693static bfd_boolean
3694emit_insn (expressionS *exp, int nbytes)
3695{
3696 int size = 0;
3697
3698 if (exp->X_op == O_constant)
3699 {
3700 size = nbytes;
3701
3702 if (size == 0)
3703 size = thumb_insn_size (exp->X_add_number);
3704
3705 if (size != 0)
3706 {
3707 if (size == 2 && (unsigned int)exp->X_add_number > 0xffffu)
3708 {
3709 as_bad (_(".inst.n operand too big. "\
3710 "Use .inst.w instead"));
3711 size = 0;
3712 }
3713 else
3714 {
3715 if (now_it.state == AUTOMATIC_IT_BLOCK)
3716 set_it_insn_type_nonvoid (OUTSIDE_IT_INSN, 0);
3717 else
3718 set_it_insn_type_nonvoid (NEUTRAL_IT_INSN, 0);
3719
3720 if (thumb_mode && (size > THUMB_SIZE) && !target_big_endian)
3721 emit_thumb32_expr (exp);
3722 else
3723 emit_expr (exp, (unsigned int) size);
3724
3725 it_fsm_post_encode ();
3726 }
3727 }
3728 else
3729 as_bad (_("cannot determine Thumb instruction size. " \
3730 "Use .inst.n/.inst.w instead"));
3731 }
3732 else
3733 as_bad (_("constant expression required"));
3734
3735 return (size != 0);
3736}
3737
3738/* Like s_arm_elf_cons but do not use md_cons_align and
3739 set the mapping state to MAP_ARM/MAP_THUMB. */
3740
3741static void
3742s_arm_elf_inst (int nbytes)
3743{
3744 if (is_it_end_of_statement ())
3745 {
3746 demand_empty_rest_of_line ();
3747 return;
3748 }
3749
3750 /* Calling mapping_state () here will not change ARM/THUMB,
3751 but will ensure not to be in DATA state. */
3752
3753 if (thumb_mode)
3754 mapping_state (MAP_THUMB);
3755 else
3756 {
3757 if (nbytes != 0)
3758 {
3759 as_bad (_("width suffixes are invalid in ARM mode"));
3760 ignore_rest_of_line ();
3761 return;
3762 }
3763
3764 nbytes = 4;
3765
3766 mapping_state (MAP_ARM);
3767 }
3768
3769 do
3770 {
3771 expressionS exp;
3772
3773 expression (& exp);
3774
3775 if (! emit_insn (& exp, nbytes))
3776 {
3777 ignore_rest_of_line ();
3778 return;
3779 }
3780 }
3781 while (*input_line_pointer++ == ',');
3782
3783 /* Put terminator back into stream. */
3784 input_line_pointer --;
3785 demand_empty_rest_of_line ();
3786}
b99bd4ef 3787
c19d1205 3788/* Parse a .rel31 directive. */
b99bd4ef 3789
c19d1205
ZW
3790static void
3791s_arm_rel31 (int ignored ATTRIBUTE_UNUSED)
3792{
3793 expressionS exp;
3794 char *p;
3795 valueT highbit;
b99bd4ef 3796
c19d1205
ZW
3797 highbit = 0;
3798 if (*input_line_pointer == '1')
3799 highbit = 0x80000000;
3800 else if (*input_line_pointer != '0')
3801 as_bad (_("expected 0 or 1"));
b99bd4ef 3802
c19d1205
ZW
3803 input_line_pointer++;
3804 if (*input_line_pointer != ',')
3805 as_bad (_("missing comma"));
3806 input_line_pointer++;
b99bd4ef 3807
c19d1205
ZW
3808#ifdef md_flush_pending_output
3809 md_flush_pending_output ();
3810#endif
b99bd4ef 3811
c19d1205
ZW
3812#ifdef md_cons_align
3813 md_cons_align (4);
3814#endif
b99bd4ef 3815
c19d1205 3816 mapping_state (MAP_DATA);
b99bd4ef 3817
c19d1205 3818 expression (&exp);
b99bd4ef 3819
c19d1205
ZW
3820 p = frag_more (4);
3821 md_number_to_chars (p, highbit, 4);
3822 fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 1,
3823 BFD_RELOC_ARM_PREL31);
b99bd4ef 3824
c19d1205 3825 demand_empty_rest_of_line ();
b99bd4ef
NC
3826}
3827
c19d1205 3828/* Directives: AEABI stack-unwind tables. */
b99bd4ef 3829
c19d1205 3830/* Parse an unwind_fnstart directive. Simply records the current location. */
b99bd4ef 3831
c19d1205
ZW
3832static void
3833s_arm_unwind_fnstart (int ignored ATTRIBUTE_UNUSED)
3834{
3835 demand_empty_rest_of_line ();
921e5f0a
PB
3836 if (unwind.proc_start)
3837 {
c921be7d 3838 as_bad (_("duplicate .fnstart directive"));
921e5f0a
PB
3839 return;
3840 }
3841
c19d1205
ZW
3842 /* Mark the start of the function. */
3843 unwind.proc_start = expr_build_dot ();
b99bd4ef 3844
c19d1205
ZW
3845 /* Reset the rest of the unwind info. */
3846 unwind.opcode_count = 0;
3847 unwind.table_entry = NULL;
3848 unwind.personality_routine = NULL;
3849 unwind.personality_index = -1;
3850 unwind.frame_size = 0;
3851 unwind.fp_offset = 0;
fdfde340 3852 unwind.fp_reg = REG_SP;
c19d1205
ZW
3853 unwind.fp_used = 0;
3854 unwind.sp_restored = 0;
3855}
b99bd4ef 3856
b99bd4ef 3857
c19d1205
ZW
3858/* Parse a handlerdata directive. Creates the exception handling table entry
3859 for the function. */
b99bd4ef 3860
c19d1205
ZW
3861static void
3862s_arm_unwind_handlerdata (int ignored ATTRIBUTE_UNUSED)
3863{
3864 demand_empty_rest_of_line ();
921e5f0a 3865 if (!unwind.proc_start)
c921be7d 3866 as_bad (MISSING_FNSTART);
921e5f0a 3867
c19d1205 3868 if (unwind.table_entry)
6decc662 3869 as_bad (_("duplicate .handlerdata directive"));
f02232aa 3870
c19d1205
ZW
3871 create_unwind_entry (1);
3872}
a737bd4d 3873
c19d1205 3874/* Parse an unwind_fnend directive. Generates the index table entry. */
b99bd4ef 3875
c19d1205
ZW
3876static void
3877s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
3878{
3879 long where;
3880 char *ptr;
3881 valueT val;
940b5ce0 3882 unsigned int marked_pr_dependency;
f02232aa 3883
c19d1205 3884 demand_empty_rest_of_line ();
f02232aa 3885
921e5f0a
PB
3886 if (!unwind.proc_start)
3887 {
c921be7d 3888 as_bad (_(".fnend directive without .fnstart"));
921e5f0a
PB
3889 return;
3890 }
3891
c19d1205
ZW
3892 /* Add eh table entry. */
3893 if (unwind.table_entry == NULL)
3894 val = create_unwind_entry (0);
3895 else
3896 val = 0;
f02232aa 3897
c19d1205
ZW
3898 /* Add index table entry. This is two words. */
3899 start_unwind_section (unwind.saved_seg, 1);
3900 frag_align (2, 0, 0);
3901 record_alignment (now_seg, 2);
b99bd4ef 3902
c19d1205 3903 ptr = frag_more (8);
5011093d 3904 memset (ptr, 0, 8);
c19d1205 3905 where = frag_now_fix () - 8;
f02232aa 3906
c19d1205
ZW
3907 /* Self relative offset of the function start. */
3908 fix_new (frag_now, where, 4, unwind.proc_start, 0, 1,
3909 BFD_RELOC_ARM_PREL31);
f02232aa 3910
c19d1205
ZW
3911 /* Indicate dependency on EHABI-defined personality routines to the
3912 linker, if it hasn't been done already. */
940b5ce0
DJ
3913 marked_pr_dependency
3914 = seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency;
c19d1205
ZW
3915 if (unwind.personality_index >= 0 && unwind.personality_index < 3
3916 && !(marked_pr_dependency & (1 << unwind.personality_index)))
3917 {
5f4273c7
NC
3918 static const char *const name[] =
3919 {
3920 "__aeabi_unwind_cpp_pr0",
3921 "__aeabi_unwind_cpp_pr1",
3922 "__aeabi_unwind_cpp_pr2"
3923 };
c19d1205
ZW
3924 symbolS *pr = symbol_find_or_make (name[unwind.personality_index]);
3925 fix_new (frag_now, where, 0, pr, 0, 1, BFD_RELOC_NONE);
c19d1205 3926 seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency
940b5ce0 3927 |= 1 << unwind.personality_index;
c19d1205 3928 }
f02232aa 3929
c19d1205
ZW
3930 if (val)
3931 /* Inline exception table entry. */
3932 md_number_to_chars (ptr + 4, val, 4);
3933 else
3934 /* Self relative offset of the table entry. */
3935 fix_new (frag_now, where + 4, 4, unwind.table_entry, 0, 1,
3936 BFD_RELOC_ARM_PREL31);
f02232aa 3937
c19d1205
ZW
3938 /* Restore the original section. */
3939 subseg_set (unwind.saved_seg, unwind.saved_subseg);
921e5f0a
PB
3940
3941 unwind.proc_start = NULL;
c19d1205 3942}
f02232aa 3943
f02232aa 3944
c19d1205 3945/* Parse an unwind_cantunwind directive. */
b99bd4ef 3946
c19d1205
ZW
3947static void
3948s_arm_unwind_cantunwind (int ignored ATTRIBUTE_UNUSED)
3949{
3950 demand_empty_rest_of_line ();
921e5f0a 3951 if (!unwind.proc_start)
c921be7d 3952 as_bad (MISSING_FNSTART);
921e5f0a 3953
c19d1205
ZW
3954 if (unwind.personality_routine || unwind.personality_index != -1)
3955 as_bad (_("personality routine specified for cantunwind frame"));
b99bd4ef 3956
c19d1205
ZW
3957 unwind.personality_index = -2;
3958}
b99bd4ef 3959
b99bd4ef 3960
c19d1205 3961/* Parse a personalityindex directive. */
b99bd4ef 3962
c19d1205
ZW
3963static void
3964s_arm_unwind_personalityindex (int ignored ATTRIBUTE_UNUSED)
3965{
3966 expressionS exp;
b99bd4ef 3967
921e5f0a 3968 if (!unwind.proc_start)
c921be7d 3969 as_bad (MISSING_FNSTART);
921e5f0a 3970
c19d1205
ZW
3971 if (unwind.personality_routine || unwind.personality_index != -1)
3972 as_bad (_("duplicate .personalityindex directive"));
b99bd4ef 3973
c19d1205 3974 expression (&exp);
b99bd4ef 3975
c19d1205
ZW
3976 if (exp.X_op != O_constant
3977 || exp.X_add_number < 0 || exp.X_add_number > 15)
b99bd4ef 3978 {
c19d1205
ZW
3979 as_bad (_("bad personality routine number"));
3980 ignore_rest_of_line ();
3981 return;
b99bd4ef
NC
3982 }
3983
c19d1205 3984 unwind.personality_index = exp.X_add_number;
b99bd4ef 3985
c19d1205
ZW
3986 demand_empty_rest_of_line ();
3987}
e16bb312 3988
e16bb312 3989
c19d1205 3990/* Parse a personality directive. */
e16bb312 3991
c19d1205
ZW
3992static void
3993s_arm_unwind_personality (int ignored ATTRIBUTE_UNUSED)
3994{
3995 char *name, *p, c;
a737bd4d 3996
921e5f0a 3997 if (!unwind.proc_start)
c921be7d 3998 as_bad (MISSING_FNSTART);
921e5f0a 3999
c19d1205
ZW
4000 if (unwind.personality_routine || unwind.personality_index != -1)
4001 as_bad (_("duplicate .personality directive"));
a737bd4d 4002
d02603dc 4003 c = get_symbol_name (& name);
c19d1205 4004 p = input_line_pointer;
d02603dc
NC
4005 if (c == '"')
4006 ++ input_line_pointer;
c19d1205
ZW
4007 unwind.personality_routine = symbol_find_or_make (name);
4008 *p = c;
4009 demand_empty_rest_of_line ();
4010}
e16bb312 4011
e16bb312 4012
c19d1205 4013/* Parse a directive saving core registers. */
e16bb312 4014
c19d1205
ZW
4015static void
4016s_arm_unwind_save_core (void)
e16bb312 4017{
c19d1205
ZW
4018 valueT op;
4019 long range;
4020 int n;
e16bb312 4021
4b5a202f 4022 range = parse_reg_list (&input_line_pointer, REGLIST_RN);
c19d1205 4023 if (range == FAIL)
e16bb312 4024 {
c19d1205
ZW
4025 as_bad (_("expected register list"));
4026 ignore_rest_of_line ();
4027 return;
4028 }
e16bb312 4029
c19d1205 4030 demand_empty_rest_of_line ();
e16bb312 4031
c19d1205
ZW
4032 /* Turn .unwind_movsp ip followed by .unwind_save {..., ip, ...}
4033 into .unwind_save {..., sp...}. We aren't bothered about the value of
4034 ip because it is clobbered by calls. */
4035 if (unwind.sp_restored && unwind.fp_reg == 12
4036 && (range & 0x3000) == 0x1000)
4037 {
4038 unwind.opcode_count--;
4039 unwind.sp_restored = 0;
4040 range = (range | 0x2000) & ~0x1000;
4041 unwind.pending_offset = 0;
4042 }
e16bb312 4043
01ae4198
DJ
4044 /* Pop r4-r15. */
4045 if (range & 0xfff0)
c19d1205 4046 {
01ae4198
DJ
4047 /* See if we can use the short opcodes. These pop a block of up to 8
4048 registers starting with r4, plus maybe r14. */
4049 for (n = 0; n < 8; n++)
4050 {
4051 /* Break at the first non-saved register. */
4052 if ((range & (1 << (n + 4))) == 0)
4053 break;
4054 }
4055 /* See if there are any other bits set. */
4056 if (n == 0 || (range & (0xfff0 << n) & 0xbff0) != 0)
4057 {
4058 /* Use the long form. */
4059 op = 0x8000 | ((range >> 4) & 0xfff);
4060 add_unwind_opcode (op, 2);
4061 }
0dd132b6 4062 else
01ae4198
DJ
4063 {
4064 /* Use the short form. */
4065 if (range & 0x4000)
4066 op = 0xa8; /* Pop r14. */
4067 else
4068 op = 0xa0; /* Do not pop r14. */
4069 op |= (n - 1);
4070 add_unwind_opcode (op, 1);
4071 }
c19d1205 4072 }
0dd132b6 4073
c19d1205
ZW
4074 /* Pop r0-r3. */
4075 if (range & 0xf)
4076 {
4077 op = 0xb100 | (range & 0xf);
4078 add_unwind_opcode (op, 2);
0dd132b6
NC
4079 }
4080
c19d1205
ZW
4081 /* Record the number of bytes pushed. */
4082 for (n = 0; n < 16; n++)
4083 {
4084 if (range & (1 << n))
4085 unwind.frame_size += 4;
4086 }
0dd132b6
NC
4087}
4088
c19d1205
ZW
4089
4090/* Parse a directive saving FPA registers. */
b99bd4ef
NC
4091
4092static void
c19d1205 4093s_arm_unwind_save_fpa (int reg)
b99bd4ef 4094{
c19d1205
ZW
4095 expressionS exp;
4096 int num_regs;
4097 valueT op;
b99bd4ef 4098
c19d1205
ZW
4099 /* Get Number of registers to transfer. */
4100 if (skip_past_comma (&input_line_pointer) != FAIL)
4101 expression (&exp);
4102 else
4103 exp.X_op = O_illegal;
b99bd4ef 4104
c19d1205 4105 if (exp.X_op != O_constant)
b99bd4ef 4106 {
c19d1205
ZW
4107 as_bad (_("expected , <constant>"));
4108 ignore_rest_of_line ();
b99bd4ef
NC
4109 return;
4110 }
4111
c19d1205
ZW
4112 num_regs = exp.X_add_number;
4113
4114 if (num_regs < 1 || num_regs > 4)
b99bd4ef 4115 {
c19d1205
ZW
4116 as_bad (_("number of registers must be in the range [1:4]"));
4117 ignore_rest_of_line ();
b99bd4ef
NC
4118 return;
4119 }
4120
c19d1205 4121 demand_empty_rest_of_line ();
b99bd4ef 4122
c19d1205
ZW
4123 if (reg == 4)
4124 {
4125 /* Short form. */
4126 op = 0xb4 | (num_regs - 1);
4127 add_unwind_opcode (op, 1);
4128 }
b99bd4ef
NC
4129 else
4130 {
c19d1205
ZW
4131 /* Long form. */
4132 op = 0xc800 | (reg << 4) | (num_regs - 1);
4133 add_unwind_opcode (op, 2);
b99bd4ef 4134 }
c19d1205 4135 unwind.frame_size += num_regs * 12;
b99bd4ef
NC
4136}
4137
c19d1205 4138
fa073d69
MS
4139/* Parse a directive saving VFP registers for ARMv6 and above. */
4140
4141static void
4142s_arm_unwind_save_vfp_armv6 (void)
4143{
4144 int count;
4145 unsigned int start;
4146 valueT op;
4147 int num_vfpv3_regs = 0;
4148 int num_regs_below_16;
4149
4150 count = parse_vfp_reg_list (&input_line_pointer, &start, REGLIST_VFP_D);
4151 if (count == FAIL)
4152 {
4153 as_bad (_("expected register list"));
4154 ignore_rest_of_line ();
4155 return;
4156 }
4157
4158 demand_empty_rest_of_line ();
4159
4160 /* We always generate FSTMD/FLDMD-style unwinding opcodes (rather
4161 than FSTMX/FLDMX-style ones). */
4162
4163 /* Generate opcode for (VFPv3) registers numbered in the range 16 .. 31. */
4164 if (start >= 16)
4165 num_vfpv3_regs = count;
4166 else if (start + count > 16)
4167 num_vfpv3_regs = start + count - 16;
4168
4169 if (num_vfpv3_regs > 0)
4170 {
4171 int start_offset = start > 16 ? start - 16 : 0;
4172 op = 0xc800 | (start_offset << 4) | (num_vfpv3_regs - 1);
4173 add_unwind_opcode (op, 2);
4174 }
4175
4176 /* Generate opcode for registers numbered in the range 0 .. 15. */
4177 num_regs_below_16 = num_vfpv3_regs > 0 ? 16 - (int) start : count;
9c2799c2 4178 gas_assert (num_regs_below_16 + num_vfpv3_regs == count);
fa073d69
MS
4179 if (num_regs_below_16 > 0)
4180 {
4181 op = 0xc900 | (start << 4) | (num_regs_below_16 - 1);
4182 add_unwind_opcode (op, 2);
4183 }
4184
4185 unwind.frame_size += count * 8;
4186}
4187
4188
4189/* Parse a directive saving VFP registers for pre-ARMv6. */
b99bd4ef
NC
4190
4191static void
c19d1205 4192s_arm_unwind_save_vfp (void)
b99bd4ef 4193{
c19d1205 4194 int count;
ca3f61f7 4195 unsigned int reg;
c19d1205 4196 valueT op;
b99bd4ef 4197
5287ad62 4198 count = parse_vfp_reg_list (&input_line_pointer, &reg, REGLIST_VFP_D);
c19d1205 4199 if (count == FAIL)
b99bd4ef 4200 {
c19d1205
ZW
4201 as_bad (_("expected register list"));
4202 ignore_rest_of_line ();
b99bd4ef
NC
4203 return;
4204 }
4205
c19d1205 4206 demand_empty_rest_of_line ();
b99bd4ef 4207
c19d1205 4208 if (reg == 8)
b99bd4ef 4209 {
c19d1205
ZW
4210 /* Short form. */
4211 op = 0xb8 | (count - 1);
4212 add_unwind_opcode (op, 1);
b99bd4ef 4213 }
c19d1205 4214 else
b99bd4ef 4215 {
c19d1205
ZW
4216 /* Long form. */
4217 op = 0xb300 | (reg << 4) | (count - 1);
4218 add_unwind_opcode (op, 2);
b99bd4ef 4219 }
c19d1205
ZW
4220 unwind.frame_size += count * 8 + 4;
4221}
b99bd4ef 4222
b99bd4ef 4223
c19d1205
ZW
4224/* Parse a directive saving iWMMXt data registers. */
4225
4226static void
4227s_arm_unwind_save_mmxwr (void)
4228{
4229 int reg;
4230 int hi_reg;
4231 int i;
4232 unsigned mask = 0;
4233 valueT op;
b99bd4ef 4234
c19d1205
ZW
4235 if (*input_line_pointer == '{')
4236 input_line_pointer++;
b99bd4ef 4237
c19d1205 4238 do
b99bd4ef 4239 {
dcbf9037 4240 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
b99bd4ef 4241
c19d1205 4242 if (reg == FAIL)
b99bd4ef 4243 {
9b7132d3 4244 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWR]));
c19d1205 4245 goto error;
b99bd4ef
NC
4246 }
4247
c19d1205
ZW
4248 if (mask >> reg)
4249 as_tsktsk (_("register list not in ascending order"));
4250 mask |= 1 << reg;
b99bd4ef 4251
c19d1205
ZW
4252 if (*input_line_pointer == '-')
4253 {
4254 input_line_pointer++;
dcbf9037 4255 hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
c19d1205
ZW
4256 if (hi_reg == FAIL)
4257 {
9b7132d3 4258 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWR]));
c19d1205
ZW
4259 goto error;
4260 }
4261 else if (reg >= hi_reg)
4262 {
4263 as_bad (_("bad register range"));
4264 goto error;
4265 }
4266 for (; reg < hi_reg; reg++)
4267 mask |= 1 << reg;
4268 }
4269 }
4270 while (skip_past_comma (&input_line_pointer) != FAIL);
b99bd4ef 4271
d996d970 4272 skip_past_char (&input_line_pointer, '}');
b99bd4ef 4273
c19d1205 4274 demand_empty_rest_of_line ();
b99bd4ef 4275
708587a4 4276 /* Generate any deferred opcodes because we're going to be looking at
c19d1205
ZW
4277 the list. */
4278 flush_pending_unwind ();
b99bd4ef 4279
c19d1205 4280 for (i = 0; i < 16; i++)
b99bd4ef 4281 {
c19d1205
ZW
4282 if (mask & (1 << i))
4283 unwind.frame_size += 8;
b99bd4ef
NC
4284 }
4285
c19d1205
ZW
4286 /* Attempt to combine with a previous opcode. We do this because gcc
4287 likes to output separate unwind directives for a single block of
4288 registers. */
4289 if (unwind.opcode_count > 0)
b99bd4ef 4290 {
c19d1205
ZW
4291 i = unwind.opcodes[unwind.opcode_count - 1];
4292 if ((i & 0xf8) == 0xc0)
4293 {
4294 i &= 7;
4295 /* Only merge if the blocks are contiguous. */
4296 if (i < 6)
4297 {
4298 if ((mask & 0xfe00) == (1 << 9))
4299 {
4300 mask |= ((1 << (i + 11)) - 1) & 0xfc00;
4301 unwind.opcode_count--;
4302 }
4303 }
4304 else if (i == 6 && unwind.opcode_count >= 2)
4305 {
4306 i = unwind.opcodes[unwind.opcode_count - 2];
4307 reg = i >> 4;
4308 i &= 0xf;
b99bd4ef 4309
c19d1205
ZW
4310 op = 0xffff << (reg - 1);
4311 if (reg > 0
87a1fd79 4312 && ((mask & op) == (1u << (reg - 1))))
c19d1205
ZW
4313 {
4314 op = (1 << (reg + i + 1)) - 1;
4315 op &= ~((1 << reg) - 1);
4316 mask |= op;
4317 unwind.opcode_count -= 2;
4318 }
4319 }
4320 }
b99bd4ef
NC
4321 }
4322
c19d1205
ZW
4323 hi_reg = 15;
4324 /* We want to generate opcodes in the order the registers have been
4325 saved, ie. descending order. */
4326 for (reg = 15; reg >= -1; reg--)
b99bd4ef 4327 {
c19d1205
ZW
4328 /* Save registers in blocks. */
4329 if (reg < 0
4330 || !(mask & (1 << reg)))
4331 {
4332 /* We found an unsaved reg. Generate opcodes to save the
5f4273c7 4333 preceding block. */
c19d1205
ZW
4334 if (reg != hi_reg)
4335 {
4336 if (reg == 9)
4337 {
4338 /* Short form. */
4339 op = 0xc0 | (hi_reg - 10);
4340 add_unwind_opcode (op, 1);
4341 }
4342 else
4343 {
4344 /* Long form. */
4345 op = 0xc600 | ((reg + 1) << 4) | ((hi_reg - reg) - 1);
4346 add_unwind_opcode (op, 2);
4347 }
4348 }
4349 hi_reg = reg - 1;
4350 }
b99bd4ef
NC
4351 }
4352
c19d1205
ZW
4353 return;
4354error:
4355 ignore_rest_of_line ();
b99bd4ef
NC
4356}
4357
4358static void
c19d1205 4359s_arm_unwind_save_mmxwcg (void)
b99bd4ef 4360{
c19d1205
ZW
4361 int reg;
4362 int hi_reg;
4363 unsigned mask = 0;
4364 valueT op;
b99bd4ef 4365
c19d1205
ZW
4366 if (*input_line_pointer == '{')
4367 input_line_pointer++;
b99bd4ef 4368
477330fc
RM
4369 skip_whitespace (input_line_pointer);
4370
c19d1205 4371 do
b99bd4ef 4372 {
dcbf9037 4373 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
b99bd4ef 4374
c19d1205
ZW
4375 if (reg == FAIL)
4376 {
9b7132d3 4377 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWCG]));
c19d1205
ZW
4378 goto error;
4379 }
b99bd4ef 4380
c19d1205
ZW
4381 reg -= 8;
4382 if (mask >> reg)
4383 as_tsktsk (_("register list not in ascending order"));
4384 mask |= 1 << reg;
b99bd4ef 4385
c19d1205
ZW
4386 if (*input_line_pointer == '-')
4387 {
4388 input_line_pointer++;
dcbf9037 4389 hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
c19d1205
ZW
4390 if (hi_reg == FAIL)
4391 {
9b7132d3 4392 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWCG]));
c19d1205
ZW
4393 goto error;
4394 }
4395 else if (reg >= hi_reg)
4396 {
4397 as_bad (_("bad register range"));
4398 goto error;
4399 }
4400 for (; reg < hi_reg; reg++)
4401 mask |= 1 << reg;
4402 }
b99bd4ef 4403 }
c19d1205 4404 while (skip_past_comma (&input_line_pointer) != FAIL);
b99bd4ef 4405
d996d970 4406 skip_past_char (&input_line_pointer, '}');
b99bd4ef 4407
c19d1205
ZW
4408 demand_empty_rest_of_line ();
4409
708587a4 4410 /* Generate any deferred opcodes because we're going to be looking at
c19d1205
ZW
4411 the list. */
4412 flush_pending_unwind ();
b99bd4ef 4413
c19d1205 4414 for (reg = 0; reg < 16; reg++)
b99bd4ef 4415 {
c19d1205
ZW
4416 if (mask & (1 << reg))
4417 unwind.frame_size += 4;
b99bd4ef 4418 }
c19d1205
ZW
4419 op = 0xc700 | mask;
4420 add_unwind_opcode (op, 2);
4421 return;
4422error:
4423 ignore_rest_of_line ();
b99bd4ef
NC
4424}
4425
c19d1205 4426
fa073d69
MS
4427/* Parse an unwind_save directive.
4428 If the argument is non-zero, this is a .vsave directive. */
c19d1205 4429
b99bd4ef 4430static void
fa073d69 4431s_arm_unwind_save (int arch_v6)
b99bd4ef 4432{
c19d1205
ZW
4433 char *peek;
4434 struct reg_entry *reg;
4435 bfd_boolean had_brace = FALSE;
b99bd4ef 4436
921e5f0a 4437 if (!unwind.proc_start)
c921be7d 4438 as_bad (MISSING_FNSTART);
921e5f0a 4439
c19d1205
ZW
4440 /* Figure out what sort of save we have. */
4441 peek = input_line_pointer;
b99bd4ef 4442
c19d1205 4443 if (*peek == '{')
b99bd4ef 4444 {
c19d1205
ZW
4445 had_brace = TRUE;
4446 peek++;
b99bd4ef
NC
4447 }
4448
c19d1205 4449 reg = arm_reg_parse_multi (&peek);
b99bd4ef 4450
c19d1205 4451 if (!reg)
b99bd4ef 4452 {
c19d1205
ZW
4453 as_bad (_("register expected"));
4454 ignore_rest_of_line ();
b99bd4ef
NC
4455 return;
4456 }
4457
c19d1205 4458 switch (reg->type)
b99bd4ef 4459 {
c19d1205
ZW
4460 case REG_TYPE_FN:
4461 if (had_brace)
4462 {
4463 as_bad (_("FPA .unwind_save does not take a register list"));
4464 ignore_rest_of_line ();
4465 return;
4466 }
93ac2687 4467 input_line_pointer = peek;
c19d1205 4468 s_arm_unwind_save_fpa (reg->number);
b99bd4ef 4469 return;
c19d1205 4470
1f5afe1c
NC
4471 case REG_TYPE_RN:
4472 s_arm_unwind_save_core ();
4473 return;
4474
fa073d69
MS
4475 case REG_TYPE_VFD:
4476 if (arch_v6)
477330fc 4477 s_arm_unwind_save_vfp_armv6 ();
fa073d69 4478 else
477330fc 4479 s_arm_unwind_save_vfp ();
fa073d69 4480 return;
1f5afe1c
NC
4481
4482 case REG_TYPE_MMXWR:
4483 s_arm_unwind_save_mmxwr ();
4484 return;
4485
4486 case REG_TYPE_MMXWCG:
4487 s_arm_unwind_save_mmxwcg ();
4488 return;
c19d1205
ZW
4489
4490 default:
4491 as_bad (_(".unwind_save does not support this kind of register"));
4492 ignore_rest_of_line ();
b99bd4ef 4493 }
c19d1205 4494}
b99bd4ef 4495
b99bd4ef 4496
c19d1205
ZW
4497/* Parse an unwind_movsp directive. */
4498
4499static void
4500s_arm_unwind_movsp (int ignored ATTRIBUTE_UNUSED)
4501{
4502 int reg;
4503 valueT op;
4fa3602b 4504 int offset;
c19d1205 4505
921e5f0a 4506 if (!unwind.proc_start)
c921be7d 4507 as_bad (MISSING_FNSTART);
921e5f0a 4508
dcbf9037 4509 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
c19d1205 4510 if (reg == FAIL)
b99bd4ef 4511 {
9b7132d3 4512 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_RN]));
c19d1205 4513 ignore_rest_of_line ();
b99bd4ef
NC
4514 return;
4515 }
4fa3602b
PB
4516
4517 /* Optional constant. */
4518 if (skip_past_comma (&input_line_pointer) != FAIL)
4519 {
4520 if (immediate_for_directive (&offset) == FAIL)
4521 return;
4522 }
4523 else
4524 offset = 0;
4525
c19d1205 4526 demand_empty_rest_of_line ();
b99bd4ef 4527
c19d1205 4528 if (reg == REG_SP || reg == REG_PC)
b99bd4ef 4529 {
c19d1205 4530 as_bad (_("SP and PC not permitted in .unwind_movsp directive"));
b99bd4ef
NC
4531 return;
4532 }
4533
c19d1205
ZW
4534 if (unwind.fp_reg != REG_SP)
4535 as_bad (_("unexpected .unwind_movsp directive"));
b99bd4ef 4536
c19d1205
ZW
4537 /* Generate opcode to restore the value. */
4538 op = 0x90 | reg;
4539 add_unwind_opcode (op, 1);
4540
4541 /* Record the information for later. */
4542 unwind.fp_reg = reg;
4fa3602b 4543 unwind.fp_offset = unwind.frame_size - offset;
c19d1205 4544 unwind.sp_restored = 1;
b05fe5cf
ZW
4545}
4546
c19d1205
ZW
4547/* Parse an unwind_pad directive. */
4548
b05fe5cf 4549static void
c19d1205 4550s_arm_unwind_pad (int ignored ATTRIBUTE_UNUSED)
b05fe5cf 4551{
c19d1205 4552 int offset;
b05fe5cf 4553
921e5f0a 4554 if (!unwind.proc_start)
c921be7d 4555 as_bad (MISSING_FNSTART);
921e5f0a 4556
c19d1205
ZW
4557 if (immediate_for_directive (&offset) == FAIL)
4558 return;
b99bd4ef 4559
c19d1205
ZW
4560 if (offset & 3)
4561 {
4562 as_bad (_("stack increment must be multiple of 4"));
4563 ignore_rest_of_line ();
4564 return;
4565 }
b99bd4ef 4566
c19d1205
ZW
4567 /* Don't generate any opcodes, just record the details for later. */
4568 unwind.frame_size += offset;
4569 unwind.pending_offset += offset;
4570
4571 demand_empty_rest_of_line ();
4572}
4573
4574/* Parse an unwind_setfp directive. */
4575
4576static void
4577s_arm_unwind_setfp (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 4578{
c19d1205
ZW
4579 int sp_reg;
4580 int fp_reg;
4581 int offset;
4582
921e5f0a 4583 if (!unwind.proc_start)
c921be7d 4584 as_bad (MISSING_FNSTART);
921e5f0a 4585
dcbf9037 4586 fp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
c19d1205
ZW
4587 if (skip_past_comma (&input_line_pointer) == FAIL)
4588 sp_reg = FAIL;
4589 else
dcbf9037 4590 sp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
b99bd4ef 4591
c19d1205
ZW
4592 if (fp_reg == FAIL || sp_reg == FAIL)
4593 {
4594 as_bad (_("expected <reg>, <reg>"));
4595 ignore_rest_of_line ();
4596 return;
4597 }
b99bd4ef 4598
c19d1205
ZW
4599 /* Optional constant. */
4600 if (skip_past_comma (&input_line_pointer) != FAIL)
4601 {
4602 if (immediate_for_directive (&offset) == FAIL)
4603 return;
4604 }
4605 else
4606 offset = 0;
a737bd4d 4607
c19d1205 4608 demand_empty_rest_of_line ();
a737bd4d 4609
fdfde340 4610 if (sp_reg != REG_SP && sp_reg != unwind.fp_reg)
a737bd4d 4611 {
c19d1205
ZW
4612 as_bad (_("register must be either sp or set by a previous"
4613 "unwind_movsp directive"));
4614 return;
a737bd4d
NC
4615 }
4616
c19d1205
ZW
4617 /* Don't generate any opcodes, just record the information for later. */
4618 unwind.fp_reg = fp_reg;
4619 unwind.fp_used = 1;
fdfde340 4620 if (sp_reg == REG_SP)
c19d1205
ZW
4621 unwind.fp_offset = unwind.frame_size - offset;
4622 else
4623 unwind.fp_offset -= offset;
a737bd4d
NC
4624}
4625
c19d1205
ZW
4626/* Parse an unwind_raw directive. */
4627
4628static void
4629s_arm_unwind_raw (int ignored ATTRIBUTE_UNUSED)
a737bd4d 4630{
c19d1205 4631 expressionS exp;
708587a4 4632 /* This is an arbitrary limit. */
c19d1205
ZW
4633 unsigned char op[16];
4634 int count;
a737bd4d 4635
921e5f0a 4636 if (!unwind.proc_start)
c921be7d 4637 as_bad (MISSING_FNSTART);
921e5f0a 4638
c19d1205
ZW
4639 expression (&exp);
4640 if (exp.X_op == O_constant
4641 && skip_past_comma (&input_line_pointer) != FAIL)
a737bd4d 4642 {
c19d1205
ZW
4643 unwind.frame_size += exp.X_add_number;
4644 expression (&exp);
4645 }
4646 else
4647 exp.X_op = O_illegal;
a737bd4d 4648
c19d1205
ZW
4649 if (exp.X_op != O_constant)
4650 {
4651 as_bad (_("expected <offset>, <opcode>"));
4652 ignore_rest_of_line ();
4653 return;
4654 }
a737bd4d 4655
c19d1205 4656 count = 0;
a737bd4d 4657
c19d1205
ZW
4658 /* Parse the opcode. */
4659 for (;;)
4660 {
4661 if (count >= 16)
4662 {
4663 as_bad (_("unwind opcode too long"));
4664 ignore_rest_of_line ();
a737bd4d 4665 }
c19d1205 4666 if (exp.X_op != O_constant || exp.X_add_number & ~0xff)
a737bd4d 4667 {
c19d1205
ZW
4668 as_bad (_("invalid unwind opcode"));
4669 ignore_rest_of_line ();
4670 return;
a737bd4d 4671 }
c19d1205 4672 op[count++] = exp.X_add_number;
a737bd4d 4673
c19d1205
ZW
4674 /* Parse the next byte. */
4675 if (skip_past_comma (&input_line_pointer) == FAIL)
4676 break;
a737bd4d 4677
c19d1205
ZW
4678 expression (&exp);
4679 }
b99bd4ef 4680
c19d1205
ZW
4681 /* Add the opcode bytes in reverse order. */
4682 while (count--)
4683 add_unwind_opcode (op[count], 1);
b99bd4ef 4684
c19d1205 4685 demand_empty_rest_of_line ();
b99bd4ef 4686}
ee065d83
PB
4687
4688
4689/* Parse a .eabi_attribute directive. */
4690
4691static void
4692s_arm_eabi_attribute (int ignored ATTRIBUTE_UNUSED)
4693{
0420f52b 4694 int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC);
ee3c0378
AS
4695
4696 if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
4697 attributes_set_explicitly[tag] = 1;
ee065d83
PB
4698}
4699
0855e32b
NS
4700/* Emit a tls fix for the symbol. */
4701
4702static void
4703s_arm_tls_descseq (int ignored ATTRIBUTE_UNUSED)
4704{
4705 char *p;
4706 expressionS exp;
4707#ifdef md_flush_pending_output
4708 md_flush_pending_output ();
4709#endif
4710
4711#ifdef md_cons_align
4712 md_cons_align (4);
4713#endif
4714
4715 /* Since we're just labelling the code, there's no need to define a
4716 mapping symbol. */
4717 expression (&exp);
4718 p = obstack_next_free (&frchain_now->frch_obstack);
4719 fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
4720 thumb_mode ? BFD_RELOC_ARM_THM_TLS_DESCSEQ
4721 : BFD_RELOC_ARM_TLS_DESCSEQ);
4722}
cdf9ccec 4723#endif /* OBJ_ELF */
0855e32b 4724
ee065d83 4725static void s_arm_arch (int);
7a1d4c38 4726static void s_arm_object_arch (int);
ee065d83
PB
4727static void s_arm_cpu (int);
4728static void s_arm_fpu (int);
69133863 4729static void s_arm_arch_extension (int);
b99bd4ef 4730
f0927246
NC
4731#ifdef TE_PE
4732
4733static void
5f4273c7 4734pe_directive_secrel (int dummy ATTRIBUTE_UNUSED)
f0927246
NC
4735{
4736 expressionS exp;
4737
4738 do
4739 {
4740 expression (&exp);
4741 if (exp.X_op == O_symbol)
4742 exp.X_op = O_secrel;
4743
4744 emit_expr (&exp, 4);
4745 }
4746 while (*input_line_pointer++ == ',');
4747
4748 input_line_pointer--;
4749 demand_empty_rest_of_line ();
4750}
4751#endif /* TE_PE */
4752
c19d1205
ZW
4753/* This table describes all the machine specific pseudo-ops the assembler
4754 has to support. The fields are:
4755 pseudo-op name without dot
4756 function to call to execute this pseudo-op
4757 Integer arg to pass to the function. */
b99bd4ef 4758
c19d1205 4759const pseudo_typeS md_pseudo_table[] =
b99bd4ef 4760{
c19d1205
ZW
4761 /* Never called because '.req' does not start a line. */
4762 { "req", s_req, 0 },
dcbf9037
JB
4763 /* Following two are likewise never called. */
4764 { "dn", s_dn, 0 },
4765 { "qn", s_qn, 0 },
c19d1205
ZW
4766 { "unreq", s_unreq, 0 },
4767 { "bss", s_bss, 0 },
db2ed2e0 4768 { "align", s_align_ptwo, 2 },
c19d1205
ZW
4769 { "arm", s_arm, 0 },
4770 { "thumb", s_thumb, 0 },
4771 { "code", s_code, 0 },
4772 { "force_thumb", s_force_thumb, 0 },
4773 { "thumb_func", s_thumb_func, 0 },
4774 { "thumb_set", s_thumb_set, 0 },
4775 { "even", s_even, 0 },
4776 { "ltorg", s_ltorg, 0 },
4777 { "pool", s_ltorg, 0 },
4778 { "syntax", s_syntax, 0 },
8463be01
PB
4779 { "cpu", s_arm_cpu, 0 },
4780 { "arch", s_arm_arch, 0 },
7a1d4c38 4781 { "object_arch", s_arm_object_arch, 0 },
8463be01 4782 { "fpu", s_arm_fpu, 0 },
69133863 4783 { "arch_extension", s_arm_arch_extension, 0 },
c19d1205 4784#ifdef OBJ_ELF
c921be7d
NC
4785 { "word", s_arm_elf_cons, 4 },
4786 { "long", s_arm_elf_cons, 4 },
4787 { "inst.n", s_arm_elf_inst, 2 },
4788 { "inst.w", s_arm_elf_inst, 4 },
4789 { "inst", s_arm_elf_inst, 0 },
4790 { "rel31", s_arm_rel31, 0 },
c19d1205
ZW
4791 { "fnstart", s_arm_unwind_fnstart, 0 },
4792 { "fnend", s_arm_unwind_fnend, 0 },
4793 { "cantunwind", s_arm_unwind_cantunwind, 0 },
4794 { "personality", s_arm_unwind_personality, 0 },
4795 { "personalityindex", s_arm_unwind_personalityindex, 0 },
4796 { "handlerdata", s_arm_unwind_handlerdata, 0 },
4797 { "save", s_arm_unwind_save, 0 },
fa073d69 4798 { "vsave", s_arm_unwind_save, 1 },
c19d1205
ZW
4799 { "movsp", s_arm_unwind_movsp, 0 },
4800 { "pad", s_arm_unwind_pad, 0 },
4801 { "setfp", s_arm_unwind_setfp, 0 },
4802 { "unwind_raw", s_arm_unwind_raw, 0 },
ee065d83 4803 { "eabi_attribute", s_arm_eabi_attribute, 0 },
0855e32b 4804 { "tlsdescseq", s_arm_tls_descseq, 0 },
c19d1205
ZW
4805#else
4806 { "word", cons, 4},
f0927246
NC
4807
4808 /* These are used for dwarf. */
4809 {"2byte", cons, 2},
4810 {"4byte", cons, 4},
4811 {"8byte", cons, 8},
4812 /* These are used for dwarf2. */
68d20676 4813 { "file", dwarf2_directive_file, 0 },
f0927246
NC
4814 { "loc", dwarf2_directive_loc, 0 },
4815 { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 },
c19d1205
ZW
4816#endif
4817 { "extend", float_cons, 'x' },
4818 { "ldouble", float_cons, 'x' },
4819 { "packed", float_cons, 'p' },
f0927246
NC
4820#ifdef TE_PE
4821 {"secrel32", pe_directive_secrel, 0},
4822#endif
2e6976a8
DG
4823
4824 /* These are for compatibility with CodeComposer Studio. */
4825 {"ref", s_ccs_ref, 0},
4826 {"def", s_ccs_def, 0},
4827 {"asmfunc", s_ccs_asmfunc, 0},
4828 {"endasmfunc", s_ccs_endasmfunc, 0},
4829
c19d1205
ZW
4830 { 0, 0, 0 }
4831};
4832\f
4833/* Parser functions used exclusively in instruction operands. */
b99bd4ef 4834
c19d1205
ZW
4835/* Generic immediate-value read function for use in insn parsing.
4836 STR points to the beginning of the immediate (the leading #);
4837 VAL receives the value; if the value is outside [MIN, MAX]
4838 issue an error. PREFIX_OPT is true if the immediate prefix is
4839 optional. */
b99bd4ef 4840
c19d1205
ZW
4841static int
4842parse_immediate (char **str, int *val, int min, int max,
4843 bfd_boolean prefix_opt)
4844{
4845 expressionS exp;
0198d5e6 4846
c19d1205
ZW
4847 my_get_expression (&exp, str, prefix_opt ? GE_OPT_PREFIX : GE_IMM_PREFIX);
4848 if (exp.X_op != O_constant)
b99bd4ef 4849 {
c19d1205
ZW
4850 inst.error = _("constant expression required");
4851 return FAIL;
4852 }
b99bd4ef 4853
c19d1205
ZW
4854 if (exp.X_add_number < min || exp.X_add_number > max)
4855 {
4856 inst.error = _("immediate value out of range");
4857 return FAIL;
4858 }
b99bd4ef 4859
c19d1205
ZW
4860 *val = exp.X_add_number;
4861 return SUCCESS;
4862}
b99bd4ef 4863
5287ad62 4864/* Less-generic immediate-value read function with the possibility of loading a
036dc3f7 4865 big (64-bit) immediate, as required by Neon VMOV, VMVN and logic immediate
5287ad62
JB
4866 instructions. Puts the result directly in inst.operands[i]. */
4867
4868static int
8335d6aa
JW
4869parse_big_immediate (char **str, int i, expressionS *in_exp,
4870 bfd_boolean allow_symbol_p)
5287ad62
JB
4871{
4872 expressionS exp;
8335d6aa 4873 expressionS *exp_p = in_exp ? in_exp : &exp;
5287ad62
JB
4874 char *ptr = *str;
4875
8335d6aa 4876 my_get_expression (exp_p, &ptr, GE_OPT_PREFIX_BIG);
5287ad62 4877
8335d6aa 4878 if (exp_p->X_op == O_constant)
036dc3f7 4879 {
8335d6aa 4880 inst.operands[i].imm = exp_p->X_add_number & 0xffffffff;
036dc3f7
PB
4881 /* If we're on a 64-bit host, then a 64-bit number can be returned using
4882 O_constant. We have to be careful not to break compilation for
4883 32-bit X_add_number, though. */
8335d6aa 4884 if ((exp_p->X_add_number & ~(offsetT)(0xffffffffU)) != 0)
036dc3f7 4885 {
8335d6aa
JW
4886 /* X >> 32 is illegal if sizeof (exp_p->X_add_number) == 4. */
4887 inst.operands[i].reg = (((exp_p->X_add_number >> 16) >> 16)
4888 & 0xffffffff);
036dc3f7
PB
4889 inst.operands[i].regisimm = 1;
4890 }
4891 }
8335d6aa
JW
4892 else if (exp_p->X_op == O_big
4893 && LITTLENUM_NUMBER_OF_BITS * exp_p->X_add_number > 32)
5287ad62
JB
4894 {
4895 unsigned parts = 32 / LITTLENUM_NUMBER_OF_BITS, j, idx = 0;
95b75c01 4896
5287ad62 4897 /* Bignums have their least significant bits in
477330fc
RM
4898 generic_bignum[0]. Make sure we put 32 bits in imm and
4899 32 bits in reg, in a (hopefully) portable way. */
9c2799c2 4900 gas_assert (parts != 0);
95b75c01
NC
4901
4902 /* Make sure that the number is not too big.
4903 PR 11972: Bignums can now be sign-extended to the
4904 size of a .octa so check that the out of range bits
4905 are all zero or all one. */
8335d6aa 4906 if (LITTLENUM_NUMBER_OF_BITS * exp_p->X_add_number > 64)
95b75c01
NC
4907 {
4908 LITTLENUM_TYPE m = -1;
4909
4910 if (generic_bignum[parts * 2] != 0
4911 && generic_bignum[parts * 2] != m)
4912 return FAIL;
4913
8335d6aa 4914 for (j = parts * 2 + 1; j < (unsigned) exp_p->X_add_number; j++)
95b75c01
NC
4915 if (generic_bignum[j] != generic_bignum[j-1])
4916 return FAIL;
4917 }
4918
5287ad62
JB
4919 inst.operands[i].imm = 0;
4920 for (j = 0; j < parts; j++, idx++)
477330fc
RM
4921 inst.operands[i].imm |= generic_bignum[idx]
4922 << (LITTLENUM_NUMBER_OF_BITS * j);
5287ad62
JB
4923 inst.operands[i].reg = 0;
4924 for (j = 0; j < parts; j++, idx++)
477330fc
RM
4925 inst.operands[i].reg |= generic_bignum[idx]
4926 << (LITTLENUM_NUMBER_OF_BITS * j);
5287ad62
JB
4927 inst.operands[i].regisimm = 1;
4928 }
8335d6aa 4929 else if (!(exp_p->X_op == O_symbol && allow_symbol_p))
5287ad62 4930 return FAIL;
5f4273c7 4931
5287ad62
JB
4932 *str = ptr;
4933
4934 return SUCCESS;
4935}
4936
c19d1205
ZW
4937/* Returns the pseudo-register number of an FPA immediate constant,
4938 or FAIL if there isn't a valid constant here. */
b99bd4ef 4939
c19d1205
ZW
4940static int
4941parse_fpa_immediate (char ** str)
4942{
4943 LITTLENUM_TYPE words[MAX_LITTLENUMS];
4944 char * save_in;
4945 expressionS exp;
4946 int i;
4947 int j;
b99bd4ef 4948
c19d1205
ZW
4949 /* First try and match exact strings, this is to guarantee
4950 that some formats will work even for cross assembly. */
b99bd4ef 4951
c19d1205
ZW
4952 for (i = 0; fp_const[i]; i++)
4953 {
4954 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
b99bd4ef 4955 {
c19d1205 4956 char *start = *str;
b99bd4ef 4957
c19d1205
ZW
4958 *str += strlen (fp_const[i]);
4959 if (is_end_of_line[(unsigned char) **str])
4960 return i + 8;
4961 *str = start;
4962 }
4963 }
b99bd4ef 4964
c19d1205
ZW
4965 /* Just because we didn't get a match doesn't mean that the constant
4966 isn't valid, just that it is in a format that we don't
4967 automatically recognize. Try parsing it with the standard
4968 expression routines. */
b99bd4ef 4969
c19d1205 4970 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
b99bd4ef 4971
c19d1205
ZW
4972 /* Look for a raw floating point number. */
4973 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
4974 && is_end_of_line[(unsigned char) *save_in])
4975 {
4976 for (i = 0; i < NUM_FLOAT_VALS; i++)
4977 {
4978 for (j = 0; j < MAX_LITTLENUMS; j++)
b99bd4ef 4979 {
c19d1205
ZW
4980 if (words[j] != fp_values[i][j])
4981 break;
b99bd4ef
NC
4982 }
4983
c19d1205 4984 if (j == MAX_LITTLENUMS)
b99bd4ef 4985 {
c19d1205
ZW
4986 *str = save_in;
4987 return i + 8;
b99bd4ef
NC
4988 }
4989 }
4990 }
b99bd4ef 4991
c19d1205
ZW
4992 /* Try and parse a more complex expression, this will probably fail
4993 unless the code uses a floating point prefix (eg "0f"). */
4994 save_in = input_line_pointer;
4995 input_line_pointer = *str;
4996 if (expression (&exp) == absolute_section
4997 && exp.X_op == O_big
4998 && exp.X_add_number < 0)
4999 {
5000 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
5001 Ditto for 15. */
ba592044
AM
5002#define X_PRECISION 5
5003#define E_PRECISION 15L
5004 if (gen_to_words (words, X_PRECISION, E_PRECISION) == 0)
c19d1205
ZW
5005 {
5006 for (i = 0; i < NUM_FLOAT_VALS; i++)
5007 {
5008 for (j = 0; j < MAX_LITTLENUMS; j++)
5009 {
5010 if (words[j] != fp_values[i][j])
5011 break;
5012 }
b99bd4ef 5013
c19d1205
ZW
5014 if (j == MAX_LITTLENUMS)
5015 {
5016 *str = input_line_pointer;
5017 input_line_pointer = save_in;
5018 return i + 8;
5019 }
5020 }
5021 }
b99bd4ef
NC
5022 }
5023
c19d1205
ZW
5024 *str = input_line_pointer;
5025 input_line_pointer = save_in;
5026 inst.error = _("invalid FPA immediate expression");
5027 return FAIL;
b99bd4ef
NC
5028}
5029
136da414
JB
5030/* Returns 1 if a number has "quarter-precision" float format
5031 0baBbbbbbc defgh000 00000000 00000000. */
5032
5033static int
5034is_quarter_float (unsigned imm)
5035{
5036 int bs = (imm & 0x20000000) ? 0x3e000000 : 0x40000000;
5037 return (imm & 0x7ffff) == 0 && ((imm & 0x7e000000) ^ bs) == 0;
5038}
5039
aacf0b33
KT
5040
5041/* Detect the presence of a floating point or integer zero constant,
5042 i.e. #0.0 or #0. */
5043
5044static bfd_boolean
5045parse_ifimm_zero (char **in)
5046{
5047 int error_code;
5048
5049 if (!is_immediate_prefix (**in))
3c6452ae
TP
5050 {
5051 /* In unified syntax, all prefixes are optional. */
5052 if (!unified_syntax)
5053 return FALSE;
5054 }
5055 else
5056 ++*in;
0900a05b
JW
5057
5058 /* Accept #0x0 as a synonym for #0. */
5059 if (strncmp (*in, "0x", 2) == 0)
5060 {
5061 int val;
5062 if (parse_immediate (in, &val, 0, 0, TRUE) == FAIL)
5063 return FALSE;
5064 return TRUE;
5065 }
5066
aacf0b33
KT
5067 error_code = atof_generic (in, ".", EXP_CHARS,
5068 &generic_floating_point_number);
5069
5070 if (!error_code
5071 && generic_floating_point_number.sign == '+'
5072 && (generic_floating_point_number.low
5073 > generic_floating_point_number.leader))
5074 return TRUE;
5075
5076 return FALSE;
5077}
5078
136da414
JB
5079/* Parse an 8-bit "quarter-precision" floating point number of the form:
5080 0baBbbbbbc defgh000 00000000 00000000.
c96612cc
JB
5081 The zero and minus-zero cases need special handling, since they can't be
5082 encoded in the "quarter-precision" float format, but can nonetheless be
5083 loaded as integer constants. */
136da414
JB
5084
5085static unsigned
5086parse_qfloat_immediate (char **ccp, int *immed)
5087{
5088 char *str = *ccp;
c96612cc 5089 char *fpnum;
136da414 5090 LITTLENUM_TYPE words[MAX_LITTLENUMS];
c96612cc 5091 int found_fpchar = 0;
5f4273c7 5092
136da414 5093 skip_past_char (&str, '#');
5f4273c7 5094
c96612cc
JB
5095 /* We must not accidentally parse an integer as a floating-point number. Make
5096 sure that the value we parse is not an integer by checking for special
5097 characters '.' or 'e'.
5098 FIXME: This is a horrible hack, but doing better is tricky because type
5099 information isn't in a very usable state at parse time. */
5100 fpnum = str;
5101 skip_whitespace (fpnum);
5102
5103 if (strncmp (fpnum, "0x", 2) == 0)
5104 return FAIL;
5105 else
5106 {
5107 for (; *fpnum != '\0' && *fpnum != ' ' && *fpnum != '\n'; fpnum++)
477330fc
RM
5108 if (*fpnum == '.' || *fpnum == 'e' || *fpnum == 'E')
5109 {
5110 found_fpchar = 1;
5111 break;
5112 }
c96612cc
JB
5113
5114 if (!found_fpchar)
477330fc 5115 return FAIL;
c96612cc 5116 }
5f4273c7 5117
136da414
JB
5118 if ((str = atof_ieee (str, 's', words)) != NULL)
5119 {
5120 unsigned fpword = 0;
5121 int i;
5f4273c7 5122
136da414
JB
5123 /* Our FP word must be 32 bits (single-precision FP). */
5124 for (i = 0; i < 32 / LITTLENUM_NUMBER_OF_BITS; i++)
477330fc
RM
5125 {
5126 fpword <<= LITTLENUM_NUMBER_OF_BITS;
5127 fpword |= words[i];
5128 }
5f4273c7 5129
c96612cc 5130 if (is_quarter_float (fpword) || (fpword & 0x7fffffff) == 0)
477330fc 5131 *immed = fpword;
136da414 5132 else
477330fc 5133 return FAIL;
136da414
JB
5134
5135 *ccp = str;
5f4273c7 5136
136da414
JB
5137 return SUCCESS;
5138 }
5f4273c7 5139
136da414
JB
5140 return FAIL;
5141}
5142
c19d1205
ZW
5143/* Shift operands. */
5144enum shift_kind
b99bd4ef 5145{
c19d1205
ZW
5146 SHIFT_LSL, SHIFT_LSR, SHIFT_ASR, SHIFT_ROR, SHIFT_RRX
5147};
b99bd4ef 5148
c19d1205
ZW
5149struct asm_shift_name
5150{
5151 const char *name;
5152 enum shift_kind kind;
5153};
b99bd4ef 5154
c19d1205
ZW
5155/* Third argument to parse_shift. */
5156enum parse_shift_mode
5157{
5158 NO_SHIFT_RESTRICT, /* Any kind of shift is accepted. */
5159 SHIFT_IMMEDIATE, /* Shift operand must be an immediate. */
5160 SHIFT_LSL_OR_ASR_IMMEDIATE, /* Shift must be LSL or ASR immediate. */
5161 SHIFT_ASR_IMMEDIATE, /* Shift must be ASR immediate. */
5162 SHIFT_LSL_IMMEDIATE, /* Shift must be LSL immediate. */
5163};
b99bd4ef 5164
c19d1205
ZW
5165/* Parse a <shift> specifier on an ARM data processing instruction.
5166 This has three forms:
b99bd4ef 5167
c19d1205
ZW
5168 (LSL|LSR|ASL|ASR|ROR) Rs
5169 (LSL|LSR|ASL|ASR|ROR) #imm
5170 RRX
b99bd4ef 5171
c19d1205
ZW
5172 Note that ASL is assimilated to LSL in the instruction encoding, and
5173 RRX to ROR #0 (which cannot be written as such). */
b99bd4ef 5174
c19d1205
ZW
5175static int
5176parse_shift (char **str, int i, enum parse_shift_mode mode)
b99bd4ef 5177{
c19d1205
ZW
5178 const struct asm_shift_name *shift_name;
5179 enum shift_kind shift;
5180 char *s = *str;
5181 char *p = s;
5182 int reg;
b99bd4ef 5183
c19d1205
ZW
5184 for (p = *str; ISALPHA (*p); p++)
5185 ;
b99bd4ef 5186
c19d1205 5187 if (p == *str)
b99bd4ef 5188 {
c19d1205
ZW
5189 inst.error = _("shift expression expected");
5190 return FAIL;
b99bd4ef
NC
5191 }
5192
21d799b5 5193 shift_name = (const struct asm_shift_name *) hash_find_n (arm_shift_hsh, *str,
477330fc 5194 p - *str);
c19d1205
ZW
5195
5196 if (shift_name == NULL)
b99bd4ef 5197 {
c19d1205
ZW
5198 inst.error = _("shift expression expected");
5199 return FAIL;
b99bd4ef
NC
5200 }
5201
c19d1205 5202 shift = shift_name->kind;
b99bd4ef 5203
c19d1205
ZW
5204 switch (mode)
5205 {
5206 case NO_SHIFT_RESTRICT:
5207 case SHIFT_IMMEDIATE: break;
b99bd4ef 5208
c19d1205
ZW
5209 case SHIFT_LSL_OR_ASR_IMMEDIATE:
5210 if (shift != SHIFT_LSL && shift != SHIFT_ASR)
5211 {
5212 inst.error = _("'LSL' or 'ASR' required");
5213 return FAIL;
5214 }
5215 break;
b99bd4ef 5216
c19d1205
ZW
5217 case SHIFT_LSL_IMMEDIATE:
5218 if (shift != SHIFT_LSL)
5219 {
5220 inst.error = _("'LSL' required");
5221 return FAIL;
5222 }
5223 break;
b99bd4ef 5224
c19d1205
ZW
5225 case SHIFT_ASR_IMMEDIATE:
5226 if (shift != SHIFT_ASR)
5227 {
5228 inst.error = _("'ASR' required");
5229 return FAIL;
5230 }
5231 break;
b99bd4ef 5232
c19d1205
ZW
5233 default: abort ();
5234 }
b99bd4ef 5235
c19d1205
ZW
5236 if (shift != SHIFT_RRX)
5237 {
5238 /* Whitespace can appear here if the next thing is a bare digit. */
5239 skip_whitespace (p);
b99bd4ef 5240
c19d1205 5241 if (mode == NO_SHIFT_RESTRICT
dcbf9037 5242 && (reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
c19d1205
ZW
5243 {
5244 inst.operands[i].imm = reg;
5245 inst.operands[i].immisreg = 1;
5246 }
e2b0ab59 5247 else if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
c19d1205
ZW
5248 return FAIL;
5249 }
5250 inst.operands[i].shift_kind = shift;
5251 inst.operands[i].shifted = 1;
5252 *str = p;
5253 return SUCCESS;
b99bd4ef
NC
5254}
5255
c19d1205 5256/* Parse a <shifter_operand> for an ARM data processing instruction:
b99bd4ef 5257
c19d1205
ZW
5258 #<immediate>
5259 #<immediate>, <rotate>
5260 <Rm>
5261 <Rm>, <shift>
b99bd4ef 5262
c19d1205
ZW
5263 where <shift> is defined by parse_shift above, and <rotate> is a
5264 multiple of 2 between 0 and 30. Validation of immediate operands
55cf6793 5265 is deferred to md_apply_fix. */
b99bd4ef 5266
c19d1205
ZW
5267static int
5268parse_shifter_operand (char **str, int i)
5269{
5270 int value;
91d6fa6a 5271 expressionS exp;
b99bd4ef 5272
dcbf9037 5273 if ((value = arm_reg_parse (str, REG_TYPE_RN)) != FAIL)
c19d1205
ZW
5274 {
5275 inst.operands[i].reg = value;
5276 inst.operands[i].isreg = 1;
b99bd4ef 5277
c19d1205 5278 /* parse_shift will override this if appropriate */
e2b0ab59
AV
5279 inst.relocs[0].exp.X_op = O_constant;
5280 inst.relocs[0].exp.X_add_number = 0;
b99bd4ef 5281
c19d1205
ZW
5282 if (skip_past_comma (str) == FAIL)
5283 return SUCCESS;
b99bd4ef 5284
c19d1205
ZW
5285 /* Shift operation on register. */
5286 return parse_shift (str, i, NO_SHIFT_RESTRICT);
b99bd4ef
NC
5287 }
5288
e2b0ab59 5289 if (my_get_expression (&inst.relocs[0].exp, str, GE_IMM_PREFIX))
c19d1205 5290 return FAIL;
b99bd4ef 5291
c19d1205 5292 if (skip_past_comma (str) == SUCCESS)
b99bd4ef 5293 {
c19d1205 5294 /* #x, y -- ie explicit rotation by Y. */
91d6fa6a 5295 if (my_get_expression (&exp, str, GE_NO_PREFIX))
c19d1205 5296 return FAIL;
b99bd4ef 5297
e2b0ab59 5298 if (exp.X_op != O_constant || inst.relocs[0].exp.X_op != O_constant)
c19d1205
ZW
5299 {
5300 inst.error = _("constant expression expected");
5301 return FAIL;
5302 }
b99bd4ef 5303
91d6fa6a 5304 value = exp.X_add_number;
c19d1205
ZW
5305 if (value < 0 || value > 30 || value % 2 != 0)
5306 {
5307 inst.error = _("invalid rotation");
5308 return FAIL;
5309 }
e2b0ab59
AV
5310 if (inst.relocs[0].exp.X_add_number < 0
5311 || inst.relocs[0].exp.X_add_number > 255)
c19d1205
ZW
5312 {
5313 inst.error = _("invalid constant");
5314 return FAIL;
5315 }
09d92015 5316
a415b1cd 5317 /* Encode as specified. */
e2b0ab59 5318 inst.operands[i].imm = inst.relocs[0].exp.X_add_number | value << 7;
a415b1cd 5319 return SUCCESS;
09d92015
MM
5320 }
5321
e2b0ab59
AV
5322 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
5323 inst.relocs[0].pc_rel = 0;
c19d1205 5324 return SUCCESS;
09d92015
MM
5325}
5326
4962c51a
MS
5327/* Group relocation information. Each entry in the table contains the
5328 textual name of the relocation as may appear in assembler source
5329 and must end with a colon.
5330 Along with this textual name are the relocation codes to be used if
5331 the corresponding instruction is an ALU instruction (ADD or SUB only),
5332 an LDR, an LDRS, or an LDC. */
5333
5334struct group_reloc_table_entry
5335{
5336 const char *name;
5337 int alu_code;
5338 int ldr_code;
5339 int ldrs_code;
5340 int ldc_code;
5341};
5342
5343typedef enum
5344{
5345 /* Varieties of non-ALU group relocation. */
5346
5347 GROUP_LDR,
5348 GROUP_LDRS,
5349 GROUP_LDC
5350} group_reloc_type;
5351
5352static struct group_reloc_table_entry group_reloc_table[] =
5353 { /* Program counter relative: */
5354 { "pc_g0_nc",
5355 BFD_RELOC_ARM_ALU_PC_G0_NC, /* ALU */
5356 0, /* LDR */
5357 0, /* LDRS */
5358 0 }, /* LDC */
5359 { "pc_g0",
5360 BFD_RELOC_ARM_ALU_PC_G0, /* ALU */
5361 BFD_RELOC_ARM_LDR_PC_G0, /* LDR */
5362 BFD_RELOC_ARM_LDRS_PC_G0, /* LDRS */
5363 BFD_RELOC_ARM_LDC_PC_G0 }, /* LDC */
5364 { "pc_g1_nc",
5365 BFD_RELOC_ARM_ALU_PC_G1_NC, /* ALU */
5366 0, /* LDR */
5367 0, /* LDRS */
5368 0 }, /* LDC */
5369 { "pc_g1",
5370 BFD_RELOC_ARM_ALU_PC_G1, /* ALU */
5371 BFD_RELOC_ARM_LDR_PC_G1, /* LDR */
5372 BFD_RELOC_ARM_LDRS_PC_G1, /* LDRS */
5373 BFD_RELOC_ARM_LDC_PC_G1 }, /* LDC */
5374 { "pc_g2",
5375 BFD_RELOC_ARM_ALU_PC_G2, /* ALU */
5376 BFD_RELOC_ARM_LDR_PC_G2, /* LDR */
5377 BFD_RELOC_ARM_LDRS_PC_G2, /* LDRS */
5378 BFD_RELOC_ARM_LDC_PC_G2 }, /* LDC */
5379 /* Section base relative */
5380 { "sb_g0_nc",
5381 BFD_RELOC_ARM_ALU_SB_G0_NC, /* ALU */
5382 0, /* LDR */
5383 0, /* LDRS */
5384 0 }, /* LDC */
5385 { "sb_g0",
5386 BFD_RELOC_ARM_ALU_SB_G0, /* ALU */
5387 BFD_RELOC_ARM_LDR_SB_G0, /* LDR */
5388 BFD_RELOC_ARM_LDRS_SB_G0, /* LDRS */
5389 BFD_RELOC_ARM_LDC_SB_G0 }, /* LDC */
5390 { "sb_g1_nc",
5391 BFD_RELOC_ARM_ALU_SB_G1_NC, /* ALU */
5392 0, /* LDR */
5393 0, /* LDRS */
5394 0 }, /* LDC */
5395 { "sb_g1",
5396 BFD_RELOC_ARM_ALU_SB_G1, /* ALU */
5397 BFD_RELOC_ARM_LDR_SB_G1, /* LDR */
5398 BFD_RELOC_ARM_LDRS_SB_G1, /* LDRS */
5399 BFD_RELOC_ARM_LDC_SB_G1 }, /* LDC */
5400 { "sb_g2",
5401 BFD_RELOC_ARM_ALU_SB_G2, /* ALU */
5402 BFD_RELOC_ARM_LDR_SB_G2, /* LDR */
5403 BFD_RELOC_ARM_LDRS_SB_G2, /* LDRS */
72d98d16
MG
5404 BFD_RELOC_ARM_LDC_SB_G2 }, /* LDC */
5405 /* Absolute thumb alu relocations. */
5406 { "lower0_7",
5407 BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC,/* ALU. */
5408 0, /* LDR. */
5409 0, /* LDRS. */
5410 0 }, /* LDC. */
5411 { "lower8_15",
5412 BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC,/* ALU. */
5413 0, /* LDR. */
5414 0, /* LDRS. */
5415 0 }, /* LDC. */
5416 { "upper0_7",
5417 BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC,/* ALU. */
5418 0, /* LDR. */
5419 0, /* LDRS. */
5420 0 }, /* LDC. */
5421 { "upper8_15",
5422 BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC,/* ALU. */
5423 0, /* LDR. */
5424 0, /* LDRS. */
5425 0 } }; /* LDC. */
4962c51a
MS
5426
5427/* Given the address of a pointer pointing to the textual name of a group
5428 relocation as may appear in assembler source, attempt to find its details
5429 in group_reloc_table. The pointer will be updated to the character after
5430 the trailing colon. On failure, FAIL will be returned; SUCCESS
5431 otherwise. On success, *entry will be updated to point at the relevant
5432 group_reloc_table entry. */
5433
5434static int
5435find_group_reloc_table_entry (char **str, struct group_reloc_table_entry **out)
5436{
5437 unsigned int i;
5438 for (i = 0; i < ARRAY_SIZE (group_reloc_table); i++)
5439 {
5440 int length = strlen (group_reloc_table[i].name);
5441
5f4273c7
NC
5442 if (strncasecmp (group_reloc_table[i].name, *str, length) == 0
5443 && (*str)[length] == ':')
477330fc
RM
5444 {
5445 *out = &group_reloc_table[i];
5446 *str += (length + 1);
5447 return SUCCESS;
5448 }
4962c51a
MS
5449 }
5450
5451 return FAIL;
5452}
5453
5454/* Parse a <shifter_operand> for an ARM data processing instruction
5455 (as for parse_shifter_operand) where group relocations are allowed:
5456
5457 #<immediate>
5458 #<immediate>, <rotate>
5459 #:<group_reloc>:<expression>
5460 <Rm>
5461 <Rm>, <shift>
5462
5463 where <group_reloc> is one of the strings defined in group_reloc_table.
5464 The hashes are optional.
5465
5466 Everything else is as for parse_shifter_operand. */
5467
5468static parse_operand_result
5469parse_shifter_operand_group_reloc (char **str, int i)
5470{
5471 /* Determine if we have the sequence of characters #: or just :
5472 coming next. If we do, then we check for a group relocation.
5473 If we don't, punt the whole lot to parse_shifter_operand. */
5474
5475 if (((*str)[0] == '#' && (*str)[1] == ':')
5476 || (*str)[0] == ':')
5477 {
5478 struct group_reloc_table_entry *entry;
5479
5480 if ((*str)[0] == '#')
477330fc 5481 (*str) += 2;
4962c51a 5482 else
477330fc 5483 (*str)++;
4962c51a
MS
5484
5485 /* Try to parse a group relocation. Anything else is an error. */
5486 if (find_group_reloc_table_entry (str, &entry) == FAIL)
477330fc
RM
5487 {
5488 inst.error = _("unknown group relocation");
5489 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5490 }
4962c51a
MS
5491
5492 /* We now have the group relocation table entry corresponding to
477330fc 5493 the name in the assembler source. Next, we parse the expression. */
e2b0ab59 5494 if (my_get_expression (&inst.relocs[0].exp, str, GE_NO_PREFIX))
477330fc 5495 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
4962c51a
MS
5496
5497 /* Record the relocation type (always the ALU variant here). */
e2b0ab59
AV
5498 inst.relocs[0].type = (bfd_reloc_code_real_type) entry->alu_code;
5499 gas_assert (inst.relocs[0].type != 0);
4962c51a
MS
5500
5501 return PARSE_OPERAND_SUCCESS;
5502 }
5503 else
5504 return parse_shifter_operand (str, i) == SUCCESS
477330fc 5505 ? PARSE_OPERAND_SUCCESS : PARSE_OPERAND_FAIL;
4962c51a
MS
5506
5507 /* Never reached. */
5508}
5509
8e560766
MGD
5510/* Parse a Neon alignment expression. Information is written to
5511 inst.operands[i]. We assume the initial ':' has been skipped.
fa94de6b 5512
8e560766
MGD
5513 align .imm = align << 8, .immisalign=1, .preind=0 */
5514static parse_operand_result
5515parse_neon_alignment (char **str, int i)
5516{
5517 char *p = *str;
5518 expressionS exp;
5519
5520 my_get_expression (&exp, &p, GE_NO_PREFIX);
5521
5522 if (exp.X_op != O_constant)
5523 {
5524 inst.error = _("alignment must be constant");
5525 return PARSE_OPERAND_FAIL;
5526 }
5527
5528 inst.operands[i].imm = exp.X_add_number << 8;
5529 inst.operands[i].immisalign = 1;
5530 /* Alignments are not pre-indexes. */
5531 inst.operands[i].preind = 0;
5532
5533 *str = p;
5534 return PARSE_OPERAND_SUCCESS;
5535}
5536
c19d1205 5537/* Parse all forms of an ARM address expression. Information is written
e2b0ab59 5538 to inst.operands[i] and/or inst.relocs[0].
09d92015 5539
c19d1205 5540 Preindexed addressing (.preind=1):
09d92015 5541
e2b0ab59 5542 [Rn, #offset] .reg=Rn .relocs[0].exp=offset
c19d1205
ZW
5543 [Rn, +/-Rm] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
5544 [Rn, +/-Rm, shift] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
e2b0ab59 5545 .shift_kind=shift .relocs[0].exp=shift_imm
09d92015 5546
c19d1205 5547 These three may have a trailing ! which causes .writeback to be set also.
09d92015 5548
c19d1205 5549 Postindexed addressing (.postind=1, .writeback=1):
09d92015 5550
e2b0ab59 5551 [Rn], #offset .reg=Rn .relocs[0].exp=offset
c19d1205
ZW
5552 [Rn], +/-Rm .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
5553 [Rn], +/-Rm, shift .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
e2b0ab59 5554 .shift_kind=shift .relocs[0].exp=shift_imm
09d92015 5555
c19d1205 5556 Unindexed addressing (.preind=0, .postind=0):
09d92015 5557
c19d1205 5558 [Rn], {option} .reg=Rn .imm=option .immisreg=0
09d92015 5559
c19d1205 5560 Other:
09d92015 5561
c19d1205 5562 [Rn]{!} shorthand for [Rn,#0]{!}
e2b0ab59
AV
5563 =immediate .isreg=0 .relocs[0].exp=immediate
5564 label .reg=PC .relocs[0].pc_rel=1 .relocs[0].exp=label
09d92015 5565
c19d1205 5566 It is the caller's responsibility to check for addressing modes not
e2b0ab59 5567 supported by the instruction, and to set inst.relocs[0].type. */
c19d1205 5568
4962c51a
MS
5569static parse_operand_result
5570parse_address_main (char **str, int i, int group_relocations,
477330fc 5571 group_reloc_type group_type)
09d92015 5572{
c19d1205
ZW
5573 char *p = *str;
5574 int reg;
09d92015 5575
c19d1205 5576 if (skip_past_char (&p, '[') == FAIL)
09d92015 5577 {
c19d1205
ZW
5578 if (skip_past_char (&p, '=') == FAIL)
5579 {
974da60d 5580 /* Bare address - translate to PC-relative offset. */
e2b0ab59 5581 inst.relocs[0].pc_rel = 1;
c19d1205
ZW
5582 inst.operands[i].reg = REG_PC;
5583 inst.operands[i].isreg = 1;
5584 inst.operands[i].preind = 1;
09d92015 5585
e2b0ab59 5586 if (my_get_expression (&inst.relocs[0].exp, &p, GE_OPT_PREFIX_BIG))
8335d6aa
JW
5587 return PARSE_OPERAND_FAIL;
5588 }
e2b0ab59 5589 else if (parse_big_immediate (&p, i, &inst.relocs[0].exp,
8335d6aa 5590 /*allow_symbol_p=*/TRUE))
4962c51a 5591 return PARSE_OPERAND_FAIL;
09d92015 5592
c19d1205 5593 *str = p;
4962c51a 5594 return PARSE_OPERAND_SUCCESS;
09d92015
MM
5595 }
5596
8ab8155f
NC
5597 /* PR gas/14887: Allow for whitespace after the opening bracket. */
5598 skip_whitespace (p);
5599
dcbf9037 5600 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
09d92015 5601 {
c19d1205 5602 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
4962c51a 5603 return PARSE_OPERAND_FAIL;
09d92015 5604 }
c19d1205
ZW
5605 inst.operands[i].reg = reg;
5606 inst.operands[i].isreg = 1;
09d92015 5607
c19d1205 5608 if (skip_past_comma (&p) == SUCCESS)
09d92015 5609 {
c19d1205 5610 inst.operands[i].preind = 1;
09d92015 5611
c19d1205
ZW
5612 if (*p == '+') p++;
5613 else if (*p == '-') p++, inst.operands[i].negative = 1;
5614
dcbf9037 5615 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
09d92015 5616 {
c19d1205
ZW
5617 inst.operands[i].imm = reg;
5618 inst.operands[i].immisreg = 1;
5619
5620 if (skip_past_comma (&p) == SUCCESS)
5621 if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
4962c51a 5622 return PARSE_OPERAND_FAIL;
c19d1205 5623 }
5287ad62 5624 else if (skip_past_char (&p, ':') == SUCCESS)
8e560766
MGD
5625 {
5626 /* FIXME: '@' should be used here, but it's filtered out by generic
5627 code before we get to see it here. This may be subject to
5628 change. */
5629 parse_operand_result result = parse_neon_alignment (&p, i);
fa94de6b 5630
8e560766
MGD
5631 if (result != PARSE_OPERAND_SUCCESS)
5632 return result;
5633 }
c19d1205
ZW
5634 else
5635 {
5636 if (inst.operands[i].negative)
5637 {
5638 inst.operands[i].negative = 0;
5639 p--;
5640 }
4962c51a 5641
5f4273c7
NC
5642 if (group_relocations
5643 && ((*p == '#' && *(p + 1) == ':') || *p == ':'))
4962c51a
MS
5644 {
5645 struct group_reloc_table_entry *entry;
5646
477330fc
RM
5647 /* Skip over the #: or : sequence. */
5648 if (*p == '#')
5649 p += 2;
5650 else
5651 p++;
4962c51a
MS
5652
5653 /* Try to parse a group relocation. Anything else is an
477330fc 5654 error. */
4962c51a
MS
5655 if (find_group_reloc_table_entry (&p, &entry) == FAIL)
5656 {
5657 inst.error = _("unknown group relocation");
5658 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5659 }
5660
5661 /* We now have the group relocation table entry corresponding to
5662 the name in the assembler source. Next, we parse the
477330fc 5663 expression. */
e2b0ab59 5664 if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
4962c51a
MS
5665 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5666
5667 /* Record the relocation type. */
477330fc
RM
5668 switch (group_type)
5669 {
5670 case GROUP_LDR:
e2b0ab59
AV
5671 inst.relocs[0].type
5672 = (bfd_reloc_code_real_type) entry->ldr_code;
477330fc 5673 break;
4962c51a 5674
477330fc 5675 case GROUP_LDRS:
e2b0ab59
AV
5676 inst.relocs[0].type
5677 = (bfd_reloc_code_real_type) entry->ldrs_code;
477330fc 5678 break;
4962c51a 5679
477330fc 5680 case GROUP_LDC:
e2b0ab59
AV
5681 inst.relocs[0].type
5682 = (bfd_reloc_code_real_type) entry->ldc_code;
477330fc 5683 break;
4962c51a 5684
477330fc
RM
5685 default:
5686 gas_assert (0);
5687 }
4962c51a 5688
e2b0ab59 5689 if (inst.relocs[0].type == 0)
4962c51a
MS
5690 {
5691 inst.error = _("this group relocation is not allowed on this instruction");
5692 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5693 }
477330fc
RM
5694 }
5695 else
26d97720
NS
5696 {
5697 char *q = p;
0198d5e6 5698
e2b0ab59 5699 if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
26d97720
NS
5700 return PARSE_OPERAND_FAIL;
5701 /* If the offset is 0, find out if it's a +0 or -0. */
e2b0ab59
AV
5702 if (inst.relocs[0].exp.X_op == O_constant
5703 && inst.relocs[0].exp.X_add_number == 0)
26d97720
NS
5704 {
5705 skip_whitespace (q);
5706 if (*q == '#')
5707 {
5708 q++;
5709 skip_whitespace (q);
5710 }
5711 if (*q == '-')
5712 inst.operands[i].negative = 1;
5713 }
5714 }
09d92015
MM
5715 }
5716 }
8e560766
MGD
5717 else if (skip_past_char (&p, ':') == SUCCESS)
5718 {
5719 /* FIXME: '@' should be used here, but it's filtered out by generic code
5720 before we get to see it here. This may be subject to change. */
5721 parse_operand_result result = parse_neon_alignment (&p, i);
fa94de6b 5722
8e560766
MGD
5723 if (result != PARSE_OPERAND_SUCCESS)
5724 return result;
5725 }
09d92015 5726
c19d1205 5727 if (skip_past_char (&p, ']') == FAIL)
09d92015 5728 {
c19d1205 5729 inst.error = _("']' expected");
4962c51a 5730 return PARSE_OPERAND_FAIL;
09d92015
MM
5731 }
5732
c19d1205
ZW
5733 if (skip_past_char (&p, '!') == SUCCESS)
5734 inst.operands[i].writeback = 1;
09d92015 5735
c19d1205 5736 else if (skip_past_comma (&p) == SUCCESS)
09d92015 5737 {
c19d1205
ZW
5738 if (skip_past_char (&p, '{') == SUCCESS)
5739 {
5740 /* [Rn], {expr} - unindexed, with option */
5741 if (parse_immediate (&p, &inst.operands[i].imm,
ca3f61f7 5742 0, 255, TRUE) == FAIL)
4962c51a 5743 return PARSE_OPERAND_FAIL;
09d92015 5744
c19d1205
ZW
5745 if (skip_past_char (&p, '}') == FAIL)
5746 {
5747 inst.error = _("'}' expected at end of 'option' field");
4962c51a 5748 return PARSE_OPERAND_FAIL;
c19d1205
ZW
5749 }
5750 if (inst.operands[i].preind)
5751 {
5752 inst.error = _("cannot combine index with option");
4962c51a 5753 return PARSE_OPERAND_FAIL;
c19d1205
ZW
5754 }
5755 *str = p;
4962c51a 5756 return PARSE_OPERAND_SUCCESS;
09d92015 5757 }
c19d1205
ZW
5758 else
5759 {
5760 inst.operands[i].postind = 1;
5761 inst.operands[i].writeback = 1;
09d92015 5762
c19d1205
ZW
5763 if (inst.operands[i].preind)
5764 {
5765 inst.error = _("cannot combine pre- and post-indexing");
4962c51a 5766 return PARSE_OPERAND_FAIL;
c19d1205 5767 }
09d92015 5768
c19d1205
ZW
5769 if (*p == '+') p++;
5770 else if (*p == '-') p++, inst.operands[i].negative = 1;
a737bd4d 5771
dcbf9037 5772 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
c19d1205 5773 {
477330fc
RM
5774 /* We might be using the immediate for alignment already. If we
5775 are, OR the register number into the low-order bits. */
5776 if (inst.operands[i].immisalign)
5777 inst.operands[i].imm |= reg;
5778 else
5779 inst.operands[i].imm = reg;
c19d1205 5780 inst.operands[i].immisreg = 1;
a737bd4d 5781
c19d1205
ZW
5782 if (skip_past_comma (&p) == SUCCESS)
5783 if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
4962c51a 5784 return PARSE_OPERAND_FAIL;
c19d1205
ZW
5785 }
5786 else
5787 {
26d97720 5788 char *q = p;
0198d5e6 5789
c19d1205
ZW
5790 if (inst.operands[i].negative)
5791 {
5792 inst.operands[i].negative = 0;
5793 p--;
5794 }
e2b0ab59 5795 if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
4962c51a 5796 return PARSE_OPERAND_FAIL;
26d97720 5797 /* If the offset is 0, find out if it's a +0 or -0. */
e2b0ab59
AV
5798 if (inst.relocs[0].exp.X_op == O_constant
5799 && inst.relocs[0].exp.X_add_number == 0)
26d97720
NS
5800 {
5801 skip_whitespace (q);
5802 if (*q == '#')
5803 {
5804 q++;
5805 skip_whitespace (q);
5806 }
5807 if (*q == '-')
5808 inst.operands[i].negative = 1;
5809 }
c19d1205
ZW
5810 }
5811 }
a737bd4d
NC
5812 }
5813
c19d1205
ZW
5814 /* If at this point neither .preind nor .postind is set, we have a
5815 bare [Rn]{!}, which is shorthand for [Rn,#0]{!}. */
5816 if (inst.operands[i].preind == 0 && inst.operands[i].postind == 0)
5817 {
5818 inst.operands[i].preind = 1;
e2b0ab59
AV
5819 inst.relocs[0].exp.X_op = O_constant;
5820 inst.relocs[0].exp.X_add_number = 0;
c19d1205
ZW
5821 }
5822 *str = p;
4962c51a
MS
5823 return PARSE_OPERAND_SUCCESS;
5824}
5825
5826static int
5827parse_address (char **str, int i)
5828{
21d799b5 5829 return parse_address_main (str, i, 0, GROUP_LDR) == PARSE_OPERAND_SUCCESS
477330fc 5830 ? SUCCESS : FAIL;
4962c51a
MS
5831}
5832
5833static parse_operand_result
5834parse_address_group_reloc (char **str, int i, group_reloc_type type)
5835{
5836 return parse_address_main (str, i, 1, type);
a737bd4d
NC
5837}
5838
b6895b4f
PB
5839/* Parse an operand for a MOVW or MOVT instruction. */
5840static int
5841parse_half (char **str)
5842{
5843 char * p;
5f4273c7 5844
b6895b4f
PB
5845 p = *str;
5846 skip_past_char (&p, '#');
5f4273c7 5847 if (strncasecmp (p, ":lower16:", 9) == 0)
e2b0ab59 5848 inst.relocs[0].type = BFD_RELOC_ARM_MOVW;
b6895b4f 5849 else if (strncasecmp (p, ":upper16:", 9) == 0)
e2b0ab59 5850 inst.relocs[0].type = BFD_RELOC_ARM_MOVT;
b6895b4f 5851
e2b0ab59 5852 if (inst.relocs[0].type != BFD_RELOC_UNUSED)
b6895b4f
PB
5853 {
5854 p += 9;
5f4273c7 5855 skip_whitespace (p);
b6895b4f
PB
5856 }
5857
e2b0ab59 5858 if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
b6895b4f
PB
5859 return FAIL;
5860
e2b0ab59 5861 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 5862 {
e2b0ab59 5863 if (inst.relocs[0].exp.X_op != O_constant)
b6895b4f
PB
5864 {
5865 inst.error = _("constant expression expected");
5866 return FAIL;
5867 }
e2b0ab59
AV
5868 if (inst.relocs[0].exp.X_add_number < 0
5869 || inst.relocs[0].exp.X_add_number > 0xffff)
b6895b4f
PB
5870 {
5871 inst.error = _("immediate value out of range");
5872 return FAIL;
5873 }
5874 }
5875 *str = p;
5876 return SUCCESS;
5877}
5878
c19d1205 5879/* Miscellaneous. */
a737bd4d 5880
c19d1205
ZW
5881/* Parse a PSR flag operand. The value returned is FAIL on syntax error,
5882 or a bitmask suitable to be or-ed into the ARM msr instruction. */
5883static int
d2cd1205 5884parse_psr (char **str, bfd_boolean lhs)
09d92015 5885{
c19d1205
ZW
5886 char *p;
5887 unsigned long psr_field;
62b3e311
PB
5888 const struct asm_psr *psr;
5889 char *start;
d2cd1205 5890 bfd_boolean is_apsr = FALSE;
ac7f631b 5891 bfd_boolean m_profile = ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m);
09d92015 5892
a4482bb6
NC
5893 /* PR gas/12698: If the user has specified -march=all then m_profile will
5894 be TRUE, but we want to ignore it in this case as we are building for any
5895 CPU type, including non-m variants. */
823d2571 5896 if (ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any))
a4482bb6
NC
5897 m_profile = FALSE;
5898
c19d1205
ZW
5899 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
5900 feature for ease of use and backwards compatibility. */
5901 p = *str;
62b3e311 5902 if (strncasecmp (p, "SPSR", 4) == 0)
d2cd1205
JB
5903 {
5904 if (m_profile)
5905 goto unsupported_psr;
fa94de6b 5906
d2cd1205
JB
5907 psr_field = SPSR_BIT;
5908 }
5909 else if (strncasecmp (p, "CPSR", 4) == 0)
5910 {
5911 if (m_profile)
5912 goto unsupported_psr;
5913
5914 psr_field = 0;
5915 }
5916 else if (strncasecmp (p, "APSR", 4) == 0)
5917 {
5918 /* APSR[_<bits>] can be used as a synonym for CPSR[_<flags>] on ARMv7-A
5919 and ARMv7-R architecture CPUs. */
5920 is_apsr = TRUE;
5921 psr_field = 0;
5922 }
5923 else if (m_profile)
62b3e311
PB
5924 {
5925 start = p;
5926 do
5927 p++;
5928 while (ISALNUM (*p) || *p == '_');
5929
d2cd1205
JB
5930 if (strncasecmp (start, "iapsr", 5) == 0
5931 || strncasecmp (start, "eapsr", 5) == 0
5932 || strncasecmp (start, "xpsr", 4) == 0
5933 || strncasecmp (start, "psr", 3) == 0)
5934 p = start + strcspn (start, "rR") + 1;
5935
21d799b5 5936 psr = (const struct asm_psr *) hash_find_n (arm_v7m_psr_hsh, start,
477330fc 5937 p - start);
d2cd1205 5938
62b3e311
PB
5939 if (!psr)
5940 return FAIL;
09d92015 5941
d2cd1205
JB
5942 /* If APSR is being written, a bitfield may be specified. Note that
5943 APSR itself is handled above. */
5944 if (psr->field <= 3)
5945 {
5946 psr_field = psr->field;
5947 is_apsr = TRUE;
5948 goto check_suffix;
5949 }
5950
62b3e311 5951 *str = p;
d2cd1205
JB
5952 /* M-profile MSR instructions have the mask field set to "10", except
5953 *PSR variants which modify APSR, which may use a different mask (and
5954 have been handled already). Do that by setting the PSR_f field
5955 here. */
5956 return psr->field | (lhs ? PSR_f : 0);
62b3e311 5957 }
d2cd1205
JB
5958 else
5959 goto unsupported_psr;
09d92015 5960
62b3e311 5961 p += 4;
d2cd1205 5962check_suffix:
c19d1205
ZW
5963 if (*p == '_')
5964 {
5965 /* A suffix follows. */
c19d1205
ZW
5966 p++;
5967 start = p;
a737bd4d 5968
c19d1205
ZW
5969 do
5970 p++;
5971 while (ISALNUM (*p) || *p == '_');
a737bd4d 5972
d2cd1205
JB
5973 if (is_apsr)
5974 {
5975 /* APSR uses a notation for bits, rather than fields. */
5976 unsigned int nzcvq_bits = 0;
5977 unsigned int g_bit = 0;
5978 char *bit;
fa94de6b 5979
d2cd1205
JB
5980 for (bit = start; bit != p; bit++)
5981 {
5982 switch (TOLOWER (*bit))
477330fc 5983 {
d2cd1205
JB
5984 case 'n':
5985 nzcvq_bits |= (nzcvq_bits & 0x01) ? 0x20 : 0x01;
5986 break;
5987
5988 case 'z':
5989 nzcvq_bits |= (nzcvq_bits & 0x02) ? 0x20 : 0x02;
5990 break;
5991
5992 case 'c':
5993 nzcvq_bits |= (nzcvq_bits & 0x04) ? 0x20 : 0x04;
5994 break;
5995
5996 case 'v':
5997 nzcvq_bits |= (nzcvq_bits & 0x08) ? 0x20 : 0x08;
5998 break;
fa94de6b 5999
d2cd1205
JB
6000 case 'q':
6001 nzcvq_bits |= (nzcvq_bits & 0x10) ? 0x20 : 0x10;
6002 break;
fa94de6b 6003
d2cd1205
JB
6004 case 'g':
6005 g_bit |= (g_bit & 0x1) ? 0x2 : 0x1;
6006 break;
fa94de6b 6007
d2cd1205
JB
6008 default:
6009 inst.error = _("unexpected bit specified after APSR");
6010 return FAIL;
6011 }
6012 }
fa94de6b 6013
d2cd1205
JB
6014 if (nzcvq_bits == 0x1f)
6015 psr_field |= PSR_f;
fa94de6b 6016
d2cd1205
JB
6017 if (g_bit == 0x1)
6018 {
6019 if (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp))
477330fc 6020 {
d2cd1205
JB
6021 inst.error = _("selected processor does not "
6022 "support DSP extension");
6023 return FAIL;
6024 }
6025
6026 psr_field |= PSR_s;
6027 }
fa94de6b 6028
d2cd1205
JB
6029 if ((nzcvq_bits & 0x20) != 0
6030 || (nzcvq_bits != 0x1f && nzcvq_bits != 0)
6031 || (g_bit & 0x2) != 0)
6032 {
6033 inst.error = _("bad bitmask specified after APSR");
6034 return FAIL;
6035 }
6036 }
6037 else
477330fc 6038 {
d2cd1205 6039 psr = (const struct asm_psr *) hash_find_n (arm_psr_hsh, start,
477330fc 6040 p - start);
d2cd1205 6041 if (!psr)
477330fc 6042 goto error;
a737bd4d 6043
d2cd1205
JB
6044 psr_field |= psr->field;
6045 }
a737bd4d 6046 }
c19d1205 6047 else
a737bd4d 6048 {
c19d1205
ZW
6049 if (ISALNUM (*p))
6050 goto error; /* Garbage after "[CS]PSR". */
6051
d2cd1205 6052 /* Unadorned APSR is equivalent to APSR_nzcvq/CPSR_f (for writes). This
477330fc 6053 is deprecated, but allow it anyway. */
d2cd1205
JB
6054 if (is_apsr && lhs)
6055 {
6056 psr_field |= PSR_f;
6057 as_tsktsk (_("writing to APSR without specifying a bitmask is "
6058 "deprecated"));
6059 }
6060 else if (!m_profile)
6061 /* These bits are never right for M-profile devices: don't set them
6062 (only code paths which read/write APSR reach here). */
6063 psr_field |= (PSR_c | PSR_f);
a737bd4d 6064 }
c19d1205
ZW
6065 *str = p;
6066 return psr_field;
a737bd4d 6067
d2cd1205
JB
6068 unsupported_psr:
6069 inst.error = _("selected processor does not support requested special "
6070 "purpose register");
6071 return FAIL;
6072
c19d1205
ZW
6073 error:
6074 inst.error = _("flag for {c}psr instruction expected");
6075 return FAIL;
a737bd4d
NC
6076}
6077
c19d1205
ZW
6078/* Parse the flags argument to CPSI[ED]. Returns FAIL on error, or a
6079 value suitable for splatting into the AIF field of the instruction. */
a737bd4d 6080
c19d1205
ZW
6081static int
6082parse_cps_flags (char **str)
a737bd4d 6083{
c19d1205
ZW
6084 int val = 0;
6085 int saw_a_flag = 0;
6086 char *s = *str;
a737bd4d 6087
c19d1205
ZW
6088 for (;;)
6089 switch (*s++)
6090 {
6091 case '\0': case ',':
6092 goto done;
a737bd4d 6093
c19d1205
ZW
6094 case 'a': case 'A': saw_a_flag = 1; val |= 0x4; break;
6095 case 'i': case 'I': saw_a_flag = 1; val |= 0x2; break;
6096 case 'f': case 'F': saw_a_flag = 1; val |= 0x1; break;
a737bd4d 6097
c19d1205
ZW
6098 default:
6099 inst.error = _("unrecognized CPS flag");
6100 return FAIL;
6101 }
a737bd4d 6102
c19d1205
ZW
6103 done:
6104 if (saw_a_flag == 0)
a737bd4d 6105 {
c19d1205
ZW
6106 inst.error = _("missing CPS flags");
6107 return FAIL;
a737bd4d 6108 }
a737bd4d 6109
c19d1205
ZW
6110 *str = s - 1;
6111 return val;
a737bd4d
NC
6112}
6113
c19d1205
ZW
6114/* Parse an endian specifier ("BE" or "LE", case insensitive);
6115 returns 0 for big-endian, 1 for little-endian, FAIL for an error. */
a737bd4d
NC
6116
6117static int
c19d1205 6118parse_endian_specifier (char **str)
a737bd4d 6119{
c19d1205
ZW
6120 int little_endian;
6121 char *s = *str;
a737bd4d 6122
c19d1205
ZW
6123 if (strncasecmp (s, "BE", 2))
6124 little_endian = 0;
6125 else if (strncasecmp (s, "LE", 2))
6126 little_endian = 1;
6127 else
a737bd4d 6128 {
c19d1205 6129 inst.error = _("valid endian specifiers are be or le");
a737bd4d
NC
6130 return FAIL;
6131 }
6132
c19d1205 6133 if (ISALNUM (s[2]) || s[2] == '_')
a737bd4d 6134 {
c19d1205 6135 inst.error = _("valid endian specifiers are be or le");
a737bd4d
NC
6136 return FAIL;
6137 }
6138
c19d1205
ZW
6139 *str = s + 2;
6140 return little_endian;
6141}
a737bd4d 6142
c19d1205
ZW
6143/* Parse a rotation specifier: ROR #0, #8, #16, #24. *val receives a
6144 value suitable for poking into the rotate field of an sxt or sxta
6145 instruction, or FAIL on error. */
6146
6147static int
6148parse_ror (char **str)
6149{
6150 int rot;
6151 char *s = *str;
6152
6153 if (strncasecmp (s, "ROR", 3) == 0)
6154 s += 3;
6155 else
a737bd4d 6156 {
c19d1205 6157 inst.error = _("missing rotation field after comma");
a737bd4d
NC
6158 return FAIL;
6159 }
c19d1205
ZW
6160
6161 if (parse_immediate (&s, &rot, 0, 24, FALSE) == FAIL)
6162 return FAIL;
6163
6164 switch (rot)
a737bd4d 6165 {
c19d1205
ZW
6166 case 0: *str = s; return 0x0;
6167 case 8: *str = s; return 0x1;
6168 case 16: *str = s; return 0x2;
6169 case 24: *str = s; return 0x3;
6170
6171 default:
6172 inst.error = _("rotation can only be 0, 8, 16, or 24");
a737bd4d
NC
6173 return FAIL;
6174 }
c19d1205 6175}
a737bd4d 6176
c19d1205
ZW
6177/* Parse a conditional code (from conds[] below). The value returned is in the
6178 range 0 .. 14, or FAIL. */
6179static int
6180parse_cond (char **str)
6181{
c462b453 6182 char *q;
c19d1205 6183 const struct asm_cond *c;
c462b453
PB
6184 int n;
6185 /* Condition codes are always 2 characters, so matching up to
6186 3 characters is sufficient. */
6187 char cond[3];
a737bd4d 6188
c462b453
PB
6189 q = *str;
6190 n = 0;
6191 while (ISALPHA (*q) && n < 3)
6192 {
e07e6e58 6193 cond[n] = TOLOWER (*q);
c462b453
PB
6194 q++;
6195 n++;
6196 }
a737bd4d 6197
21d799b5 6198 c = (const struct asm_cond *) hash_find_n (arm_cond_hsh, cond, n);
c19d1205 6199 if (!c)
a737bd4d 6200 {
c19d1205 6201 inst.error = _("condition required");
a737bd4d
NC
6202 return FAIL;
6203 }
6204
c19d1205
ZW
6205 *str = q;
6206 return c->value;
6207}
6208
643afb90
MW
6209/* Record a use of the given feature. */
6210static void
6211record_feature_use (const arm_feature_set *feature)
6212{
6213 if (thumb_mode)
6214 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used, *feature);
6215 else
6216 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, *feature);
6217}
6218
4d354d8b
TP
6219/* If the given feature is currently allowed, mark it as used and return TRUE.
6220 Return FALSE otherwise. */
e797f7e0
MGD
6221static bfd_boolean
6222mark_feature_used (const arm_feature_set *feature)
6223{
4d354d8b 6224 /* Ensure the option is currently allowed. */
e797f7e0
MGD
6225 if (!ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
6226 return FALSE;
6227
4d354d8b 6228 /* Add the appropriate architecture feature for the barrier option used. */
643afb90 6229 record_feature_use (feature);
e797f7e0
MGD
6230
6231 return TRUE;
6232}
6233
62b3e311
PB
6234/* Parse an option for a barrier instruction. Returns the encoding for the
6235 option, or FAIL. */
6236static int
6237parse_barrier (char **str)
6238{
6239 char *p, *q;
6240 const struct asm_barrier_opt *o;
6241
6242 p = q = *str;
6243 while (ISALPHA (*q))
6244 q++;
6245
21d799b5 6246 o = (const struct asm_barrier_opt *) hash_find_n (arm_barrier_opt_hsh, p,
477330fc 6247 q - p);
62b3e311
PB
6248 if (!o)
6249 return FAIL;
6250
e797f7e0
MGD
6251 if (!mark_feature_used (&o->arch))
6252 return FAIL;
6253
62b3e311
PB
6254 *str = q;
6255 return o->value;
6256}
6257
92e90b6e
PB
6258/* Parse the operands of a table branch instruction. Similar to a memory
6259 operand. */
6260static int
6261parse_tb (char **str)
6262{
6263 char * p = *str;
6264 int reg;
6265
6266 if (skip_past_char (&p, '[') == FAIL)
ab1eb5fe
PB
6267 {
6268 inst.error = _("'[' expected");
6269 return FAIL;
6270 }
92e90b6e 6271
dcbf9037 6272 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
92e90b6e
PB
6273 {
6274 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
6275 return FAIL;
6276 }
6277 inst.operands[0].reg = reg;
6278
6279 if (skip_past_comma (&p) == FAIL)
ab1eb5fe
PB
6280 {
6281 inst.error = _("',' expected");
6282 return FAIL;
6283 }
5f4273c7 6284
dcbf9037 6285 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
92e90b6e
PB
6286 {
6287 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
6288 return FAIL;
6289 }
6290 inst.operands[0].imm = reg;
6291
6292 if (skip_past_comma (&p) == SUCCESS)
6293 {
6294 if (parse_shift (&p, 0, SHIFT_LSL_IMMEDIATE) == FAIL)
6295 return FAIL;
e2b0ab59 6296 if (inst.relocs[0].exp.X_add_number != 1)
92e90b6e
PB
6297 {
6298 inst.error = _("invalid shift");
6299 return FAIL;
6300 }
6301 inst.operands[0].shifted = 1;
6302 }
6303
6304 if (skip_past_char (&p, ']') == FAIL)
6305 {
6306 inst.error = _("']' expected");
6307 return FAIL;
6308 }
6309 *str = p;
6310 return SUCCESS;
6311}
6312
5287ad62
JB
6313/* Parse the operands of a Neon VMOV instruction. See do_neon_mov for more
6314 information on the types the operands can take and how they are encoded.
037e8744
JB
6315 Up to four operands may be read; this function handles setting the
6316 ".present" field for each read operand itself.
5287ad62
JB
6317 Updates STR and WHICH_OPERAND if parsing is successful and returns SUCCESS,
6318 else returns FAIL. */
6319
6320static int
6321parse_neon_mov (char **str, int *which_operand)
6322{
6323 int i = *which_operand, val;
6324 enum arm_reg_type rtype;
6325 char *ptr = *str;
dcbf9037 6326 struct neon_type_el optype;
5f4273c7 6327
dcbf9037 6328 if ((val = parse_scalar (&ptr, 8, &optype)) != FAIL)
5287ad62
JB
6329 {
6330 /* Case 4: VMOV<c><q>.<size> <Dn[x]>, <Rd>. */
6331 inst.operands[i].reg = val;
6332 inst.operands[i].isscalar = 1;
dcbf9037 6333 inst.operands[i].vectype = optype;
5287ad62
JB
6334 inst.operands[i++].present = 1;
6335
6336 if (skip_past_comma (&ptr) == FAIL)
477330fc 6337 goto wanted_comma;
5f4273c7 6338
dcbf9037 6339 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
477330fc 6340 goto wanted_arm;
5f4273c7 6341
5287ad62
JB
6342 inst.operands[i].reg = val;
6343 inst.operands[i].isreg = 1;
6344 inst.operands[i].present = 1;
6345 }
037e8744 6346 else if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_NSDQ, &rtype, &optype))
477330fc 6347 != FAIL)
5287ad62
JB
6348 {
6349 /* Cases 0, 1, 2, 3, 5 (D only). */
6350 if (skip_past_comma (&ptr) == FAIL)
477330fc 6351 goto wanted_comma;
5f4273c7 6352
5287ad62
JB
6353 inst.operands[i].reg = val;
6354 inst.operands[i].isreg = 1;
6355 inst.operands[i].isquad = (rtype == REG_TYPE_NQ);
037e8744
JB
6356 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6357 inst.operands[i].isvec = 1;
dcbf9037 6358 inst.operands[i].vectype = optype;
5287ad62
JB
6359 inst.operands[i++].present = 1;
6360
dcbf9037 6361 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
477330fc
RM
6362 {
6363 /* Case 5: VMOV<c><q> <Dm>, <Rd>, <Rn>.
6364 Case 13: VMOV <Sd>, <Rm> */
6365 inst.operands[i].reg = val;
6366 inst.operands[i].isreg = 1;
6367 inst.operands[i].present = 1;
6368
6369 if (rtype == REG_TYPE_NQ)
6370 {
6371 first_error (_("can't use Neon quad register here"));
6372 return FAIL;
6373 }
6374 else if (rtype != REG_TYPE_VFS)
6375 {
6376 i++;
6377 if (skip_past_comma (&ptr) == FAIL)
6378 goto wanted_comma;
6379 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6380 goto wanted_arm;
6381 inst.operands[i].reg = val;
6382 inst.operands[i].isreg = 1;
6383 inst.operands[i].present = 1;
6384 }
6385 }
037e8744 6386 else if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_NSDQ, &rtype,
477330fc
RM
6387 &optype)) != FAIL)
6388 {
6389 /* Case 0: VMOV<c><q> <Qd>, <Qm>
6390 Case 1: VMOV<c><q> <Dd>, <Dm>
6391 Case 8: VMOV.F32 <Sd>, <Sm>
6392 Case 15: VMOV <Sd>, <Se>, <Rn>, <Rm> */
6393
6394 inst.operands[i].reg = val;
6395 inst.operands[i].isreg = 1;
6396 inst.operands[i].isquad = (rtype == REG_TYPE_NQ);
6397 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6398 inst.operands[i].isvec = 1;
6399 inst.operands[i].vectype = optype;
6400 inst.operands[i].present = 1;
6401
6402 if (skip_past_comma (&ptr) == SUCCESS)
6403 {
6404 /* Case 15. */
6405 i++;
6406
6407 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6408 goto wanted_arm;
6409
6410 inst.operands[i].reg = val;
6411 inst.operands[i].isreg = 1;
6412 inst.operands[i++].present = 1;
6413
6414 if (skip_past_comma (&ptr) == FAIL)
6415 goto wanted_comma;
6416
6417 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6418 goto wanted_arm;
6419
6420 inst.operands[i].reg = val;
6421 inst.operands[i].isreg = 1;
6422 inst.operands[i].present = 1;
6423 }
6424 }
4641781c 6425 else if (parse_qfloat_immediate (&ptr, &inst.operands[i].imm) == SUCCESS)
477330fc
RM
6426 /* Case 2: VMOV<c><q>.<dt> <Qd>, #<float-imm>
6427 Case 3: VMOV<c><q>.<dt> <Dd>, #<float-imm>
6428 Case 10: VMOV.F32 <Sd>, #<imm>
6429 Case 11: VMOV.F64 <Dd>, #<imm> */
6430 inst.operands[i].immisfloat = 1;
8335d6aa
JW
6431 else if (parse_big_immediate (&ptr, i, NULL, /*allow_symbol_p=*/FALSE)
6432 == SUCCESS)
477330fc
RM
6433 /* Case 2: VMOV<c><q>.<dt> <Qd>, #<imm>
6434 Case 3: VMOV<c><q>.<dt> <Dd>, #<imm> */
6435 ;
5287ad62 6436 else
477330fc
RM
6437 {
6438 first_error (_("expected <Rm> or <Dm> or <Qm> operand"));
6439 return FAIL;
6440 }
5287ad62 6441 }
dcbf9037 6442 else if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
5287ad62
JB
6443 {
6444 /* Cases 6, 7. */
6445 inst.operands[i].reg = val;
6446 inst.operands[i].isreg = 1;
6447 inst.operands[i++].present = 1;
5f4273c7 6448
5287ad62 6449 if (skip_past_comma (&ptr) == FAIL)
477330fc 6450 goto wanted_comma;
5f4273c7 6451
dcbf9037 6452 if ((val = parse_scalar (&ptr, 8, &optype)) != FAIL)
477330fc
RM
6453 {
6454 /* Case 6: VMOV<c><q>.<dt> <Rd>, <Dn[x]> */
6455 inst.operands[i].reg = val;
6456 inst.operands[i].isscalar = 1;
6457 inst.operands[i].present = 1;
6458 inst.operands[i].vectype = optype;
6459 }
dcbf9037 6460 else if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
477330fc
RM
6461 {
6462 /* Case 7: VMOV<c><q> <Rd>, <Rn>, <Dm> */
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_typed_reg_parse (&ptr, REG_TYPE_VFSD, &rtype, &optype))
6471 == FAIL)
6472 {
6473 first_error (_(reg_expected_msgs[REG_TYPE_VFSD]));
6474 return FAIL;
6475 }
6476
6477 inst.operands[i].reg = val;
6478 inst.operands[i].isreg = 1;
6479 inst.operands[i].isvec = 1;
6480 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6481 inst.operands[i].vectype = optype;
6482 inst.operands[i].present = 1;
6483
6484 if (rtype == REG_TYPE_VFS)
6485 {
6486 /* Case 14. */
6487 i++;
6488 if (skip_past_comma (&ptr) == FAIL)
6489 goto wanted_comma;
6490 if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL,
6491 &optype)) == FAIL)
6492 {
6493 first_error (_(reg_expected_msgs[REG_TYPE_VFS]));
6494 return FAIL;
6495 }
6496 inst.operands[i].reg = val;
6497 inst.operands[i].isreg = 1;
6498 inst.operands[i].isvec = 1;
6499 inst.operands[i].issingle = 1;
6500 inst.operands[i].vectype = optype;
6501 inst.operands[i].present = 1;
6502 }
6503 }
037e8744 6504 else if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL, &optype))
477330fc
RM
6505 != FAIL)
6506 {
6507 /* Case 13. */
6508 inst.operands[i].reg = val;
6509 inst.operands[i].isreg = 1;
6510 inst.operands[i].isvec = 1;
6511 inst.operands[i].issingle = 1;
6512 inst.operands[i].vectype = optype;
6513 inst.operands[i].present = 1;
6514 }
5287ad62
JB
6515 }
6516 else
6517 {
dcbf9037 6518 first_error (_("parse error"));
5287ad62
JB
6519 return FAIL;
6520 }
6521
6522 /* Successfully parsed the operands. Update args. */
6523 *which_operand = i;
6524 *str = ptr;
6525 return SUCCESS;
6526
5f4273c7 6527 wanted_comma:
dcbf9037 6528 first_error (_("expected comma"));
5287ad62 6529 return FAIL;
5f4273c7
NC
6530
6531 wanted_arm:
dcbf9037 6532 first_error (_(reg_expected_msgs[REG_TYPE_RN]));
5287ad62 6533 return FAIL;
5287ad62
JB
6534}
6535
5be8be5d
DG
6536/* Use this macro when the operand constraints are different
6537 for ARM and THUMB (e.g. ldrd). */
6538#define MIX_ARM_THUMB_OPERANDS(arm_operand, thumb_operand) \
6539 ((arm_operand) | ((thumb_operand) << 16))
6540
c19d1205
ZW
6541/* Matcher codes for parse_operands. */
6542enum operand_parse_code
6543{
6544 OP_stop, /* end of line */
6545
6546 OP_RR, /* ARM register */
6547 OP_RRnpc, /* ARM register, not r15 */
5be8be5d 6548 OP_RRnpcsp, /* ARM register, neither r15 nor r13 (a.k.a. 'BadReg') */
c19d1205 6549 OP_RRnpcb, /* ARM register, not r15, in square brackets */
fa94de6b 6550 OP_RRnpctw, /* ARM register, not r15 in Thumb-state or with writeback,
55881a11 6551 optional trailing ! */
c19d1205
ZW
6552 OP_RRw, /* ARM register, not r15, optional trailing ! */
6553 OP_RCP, /* Coprocessor number */
6554 OP_RCN, /* Coprocessor register */
6555 OP_RF, /* FPA register */
6556 OP_RVS, /* VFP single precision register */
5287ad62
JB
6557 OP_RVD, /* VFP double precision register (0..15) */
6558 OP_RND, /* Neon double precision register (0..31) */
6559 OP_RNQ, /* Neon quad precision register */
037e8744 6560 OP_RVSD, /* VFP single or double precision register */
dec41383 6561 OP_RNSD, /* Neon single or double precision register */
5287ad62 6562 OP_RNDQ, /* Neon double or quad precision register */
037e8744 6563 OP_RNSDQ, /* Neon single, double or quad precision register */
5287ad62 6564 OP_RNSC, /* Neon scalar D[X] */
c19d1205
ZW
6565 OP_RVC, /* VFP control register */
6566 OP_RMF, /* Maverick F register */
6567 OP_RMD, /* Maverick D register */
6568 OP_RMFX, /* Maverick FX register */
6569 OP_RMDX, /* Maverick DX register */
6570 OP_RMAX, /* Maverick AX register */
6571 OP_RMDS, /* Maverick DSPSC register */
6572 OP_RIWR, /* iWMMXt wR register */
6573 OP_RIWC, /* iWMMXt wC register */
6574 OP_RIWG, /* iWMMXt wCG register */
6575 OP_RXA, /* XScale accumulator register */
6576
60f993ce
AV
6577 /* New operands for Armv8.1-M Mainline. */
6578 OP_LR, /* ARM LR register */
6579 OP_RRnpcsp_I32, /* ARM register (no BadReg) or literal 1 .. 32 */
6580
c19d1205 6581 OP_REGLST, /* ARM register list */
4b5a202f 6582 OP_CLRMLST, /* CLRM register list */
c19d1205
ZW
6583 OP_VRSLST, /* VFP single-precision register list */
6584 OP_VRDLST, /* VFP double-precision register list */
037e8744 6585 OP_VRSDLST, /* VFP single or double-precision register list (& quad) */
5287ad62
JB
6586 OP_NRDLST, /* Neon double-precision register list (d0-d31, qN aliases) */
6587 OP_NSTRLST, /* Neon element/structure list */
6588
5287ad62 6589 OP_RNDQ_I0, /* Neon D or Q reg, or immediate zero. */
037e8744 6590 OP_RVSD_I0, /* VFP S or D reg, or immediate zero. */
aacf0b33 6591 OP_RSVD_FI0, /* VFP S or D reg, or floating point immediate zero. */
5287ad62 6592 OP_RR_RNSC, /* ARM reg or Neon scalar. */
dec41383 6593 OP_RNSD_RNSC, /* Neon S or D reg, or Neon scalar. */
037e8744 6594 OP_RNSDQ_RNSC, /* Vector S, D or Q reg, or Neon scalar. */
5287ad62
JB
6595 OP_RNDQ_RNSC, /* Neon D or Q reg, or Neon scalar. */
6596 OP_RND_RNSC, /* Neon D reg, or Neon scalar. */
6597 OP_VMOV, /* Neon VMOV operands. */
4316f0d2 6598 OP_RNDQ_Ibig, /* Neon D or Q reg, or big immediate for logic and VMVN. */
5287ad62 6599 OP_RNDQ_I63b, /* Neon D or Q reg, or immediate for shift. */
2d447fca 6600 OP_RIWR_I32z, /* iWMMXt wR register, or immediate 0 .. 32 for iWMMXt2. */
5287ad62
JB
6601
6602 OP_I0, /* immediate zero */
c19d1205
ZW
6603 OP_I7, /* immediate value 0 .. 7 */
6604 OP_I15, /* 0 .. 15 */
6605 OP_I16, /* 1 .. 16 */
5287ad62 6606 OP_I16z, /* 0 .. 16 */
c19d1205
ZW
6607 OP_I31, /* 0 .. 31 */
6608 OP_I31w, /* 0 .. 31, optional trailing ! */
6609 OP_I32, /* 1 .. 32 */
5287ad62
JB
6610 OP_I32z, /* 0 .. 32 */
6611 OP_I63, /* 0 .. 63 */
c19d1205 6612 OP_I63s, /* -64 .. 63 */
5287ad62
JB
6613 OP_I64, /* 1 .. 64 */
6614 OP_I64z, /* 0 .. 64 */
c19d1205 6615 OP_I255, /* 0 .. 255 */
c19d1205
ZW
6616
6617 OP_I4b, /* immediate, prefix optional, 1 .. 4 */
6618 OP_I7b, /* 0 .. 7 */
6619 OP_I15b, /* 0 .. 15 */
6620 OP_I31b, /* 0 .. 31 */
6621
6622 OP_SH, /* shifter operand */
4962c51a 6623 OP_SHG, /* shifter operand with possible group relocation */
c19d1205 6624 OP_ADDR, /* Memory address expression (any mode) */
4962c51a
MS
6625 OP_ADDRGLDR, /* Mem addr expr (any mode) with possible LDR group reloc */
6626 OP_ADDRGLDRS, /* Mem addr expr (any mode) with possible LDRS group reloc */
6627 OP_ADDRGLDC, /* Mem addr expr (any mode) with possible LDC group reloc */
c19d1205
ZW
6628 OP_EXP, /* arbitrary expression */
6629 OP_EXPi, /* same, with optional immediate prefix */
6630 OP_EXPr, /* same, with optional relocation suffix */
e2b0ab59 6631 OP_EXPs, /* same, with optional non-first operand relocation suffix */
b6895b4f 6632 OP_HALF, /* 0 .. 65535 or low/high reloc. */
c28eeff2
SN
6633 OP_IROT1, /* VCADD rotate immediate: 90, 270. */
6634 OP_IROT2, /* VCMLA rotate immediate: 0, 90, 180, 270. */
c19d1205
ZW
6635
6636 OP_CPSF, /* CPS flags */
6637 OP_ENDI, /* Endianness specifier */
d2cd1205
JB
6638 OP_wPSR, /* CPSR/SPSR/APSR mask for msr (writing). */
6639 OP_rPSR, /* CPSR/SPSR/APSR mask for msr (reading). */
c19d1205 6640 OP_COND, /* conditional code */
92e90b6e 6641 OP_TB, /* Table branch. */
c19d1205 6642
037e8744
JB
6643 OP_APSR_RR, /* ARM register or "APSR_nzcv". */
6644
c19d1205 6645 OP_RRnpc_I0, /* ARM register or literal 0 */
33eaf5de 6646 OP_RR_EXr, /* ARM register or expression with opt. reloc stuff. */
c19d1205
ZW
6647 OP_RR_EXi, /* ARM register or expression with imm prefix */
6648 OP_RF_IF, /* FPA register or immediate */
6649 OP_RIWR_RIWC, /* iWMMXt R or C reg */
41adaa5c 6650 OP_RIWC_RIWG, /* iWMMXt wC or wCG reg */
c19d1205
ZW
6651
6652 /* Optional operands. */
6653 OP_oI7b, /* immediate, prefix optional, 0 .. 7 */
6654 OP_oI31b, /* 0 .. 31 */
5287ad62 6655 OP_oI32b, /* 1 .. 32 */
5f1af56b 6656 OP_oI32z, /* 0 .. 32 */
c19d1205
ZW
6657 OP_oIffffb, /* 0 .. 65535 */
6658 OP_oI255c, /* curly-brace enclosed, 0 .. 255 */
6659
6660 OP_oRR, /* ARM register */
60f993ce 6661 OP_oLR, /* ARM LR register */
c19d1205 6662 OP_oRRnpc, /* ARM register, not the PC */
5be8be5d 6663 OP_oRRnpcsp, /* ARM register, neither the PC nor the SP (a.k.a. BadReg) */
b6702015 6664 OP_oRRw, /* ARM register, not r15, optional trailing ! */
5287ad62
JB
6665 OP_oRND, /* Optional Neon double precision register */
6666 OP_oRNQ, /* Optional Neon quad precision register */
6667 OP_oRNDQ, /* Optional Neon double or quad precision register */
037e8744 6668 OP_oRNSDQ, /* Optional single, double or quad precision vector register */
c19d1205
ZW
6669 OP_oSHll, /* LSL immediate */
6670 OP_oSHar, /* ASR immediate */
6671 OP_oSHllar, /* LSL or ASR immediate */
6672 OP_oROR, /* ROR 0/8/16/24 */
52e7f43d 6673 OP_oBARRIER_I15, /* Option argument for a barrier instruction. */
c19d1205 6674
5be8be5d
DG
6675 /* Some pre-defined mixed (ARM/THUMB) operands. */
6676 OP_RR_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RR, OP_RRnpcsp),
6677 OP_RRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RRnpc, OP_RRnpcsp),
6678 OP_oRRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_oRRnpc, OP_oRRnpcsp),
6679
c19d1205
ZW
6680 OP_FIRST_OPTIONAL = OP_oI7b
6681};
a737bd4d 6682
c19d1205
ZW
6683/* Generic instruction operand parser. This does no encoding and no
6684 semantic validation; it merely squirrels values away in the inst
6685 structure. Returns SUCCESS or FAIL depending on whether the
6686 specified grammar matched. */
6687static int
5be8be5d 6688parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
c19d1205 6689{
5be8be5d 6690 unsigned const int *upat = pattern;
c19d1205
ZW
6691 char *backtrack_pos = 0;
6692 const char *backtrack_error = 0;
99aad254 6693 int i, val = 0, backtrack_index = 0;
5287ad62 6694 enum arm_reg_type rtype;
4962c51a 6695 parse_operand_result result;
5be8be5d 6696 unsigned int op_parse_code;
c19d1205 6697
e07e6e58
NC
6698#define po_char_or_fail(chr) \
6699 do \
6700 { \
6701 if (skip_past_char (&str, chr) == FAIL) \
477330fc 6702 goto bad_args; \
e07e6e58
NC
6703 } \
6704 while (0)
c19d1205 6705
e07e6e58
NC
6706#define po_reg_or_fail(regtype) \
6707 do \
dcbf9037 6708 { \
e07e6e58 6709 val = arm_typed_reg_parse (& str, regtype, & rtype, \
477330fc 6710 & inst.operands[i].vectype); \
e07e6e58 6711 if (val == FAIL) \
477330fc
RM
6712 { \
6713 first_error (_(reg_expected_msgs[regtype])); \
6714 goto failure; \
6715 } \
e07e6e58
NC
6716 inst.operands[i].reg = val; \
6717 inst.operands[i].isreg = 1; \
6718 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
6719 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
6720 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc
RM
6721 || rtype == REG_TYPE_VFD \
6722 || rtype == REG_TYPE_NQ); \
dcbf9037 6723 } \
e07e6e58
NC
6724 while (0)
6725
6726#define po_reg_or_goto(regtype, label) \
6727 do \
6728 { \
6729 val = arm_typed_reg_parse (& str, regtype, & rtype, \
6730 & inst.operands[i].vectype); \
6731 if (val == FAIL) \
6732 goto label; \
dcbf9037 6733 \
e07e6e58
NC
6734 inst.operands[i].reg = val; \
6735 inst.operands[i].isreg = 1; \
6736 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
6737 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
6738 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc 6739 || rtype == REG_TYPE_VFD \
e07e6e58
NC
6740 || rtype == REG_TYPE_NQ); \
6741 } \
6742 while (0)
6743
6744#define po_imm_or_fail(min, max, popt) \
6745 do \
6746 { \
6747 if (parse_immediate (&str, &val, min, max, popt) == FAIL) \
6748 goto failure; \
6749 inst.operands[i].imm = val; \
6750 } \
6751 while (0)
6752
6753#define po_scalar_or_goto(elsz, label) \
6754 do \
6755 { \
6756 val = parse_scalar (& str, elsz, & inst.operands[i].vectype); \
6757 if (val == FAIL) \
6758 goto label; \
6759 inst.operands[i].reg = val; \
6760 inst.operands[i].isscalar = 1; \
6761 } \
6762 while (0)
6763
6764#define po_misc_or_fail(expr) \
6765 do \
6766 { \
6767 if (expr) \
6768 goto failure; \
6769 } \
6770 while (0)
6771
6772#define po_misc_or_fail_no_backtrack(expr) \
6773 do \
6774 { \
6775 result = expr; \
6776 if (result == PARSE_OPERAND_FAIL_NO_BACKTRACK) \
6777 backtrack_pos = 0; \
6778 if (result != PARSE_OPERAND_SUCCESS) \
6779 goto failure; \
6780 } \
6781 while (0)
4962c51a 6782
52e7f43d
RE
6783#define po_barrier_or_imm(str) \
6784 do \
6785 { \
6786 val = parse_barrier (&str); \
ccb84d65
JB
6787 if (val == FAIL && ! ISALPHA (*str)) \
6788 goto immediate; \
6789 if (val == FAIL \
6790 /* ISB can only take SY as an option. */ \
6791 || ((inst.instruction & 0xf0) == 0x60 \
6792 && val != 0xf)) \
52e7f43d 6793 { \
ccb84d65
JB
6794 inst.error = _("invalid barrier type"); \
6795 backtrack_pos = 0; \
6796 goto failure; \
52e7f43d
RE
6797 } \
6798 } \
6799 while (0)
6800
c19d1205
ZW
6801 skip_whitespace (str);
6802
6803 for (i = 0; upat[i] != OP_stop; i++)
6804 {
5be8be5d
DG
6805 op_parse_code = upat[i];
6806 if (op_parse_code >= 1<<16)
6807 op_parse_code = thumb ? (op_parse_code >> 16)
6808 : (op_parse_code & ((1<<16)-1));
6809
6810 if (op_parse_code >= OP_FIRST_OPTIONAL)
c19d1205
ZW
6811 {
6812 /* Remember where we are in case we need to backtrack. */
9c2799c2 6813 gas_assert (!backtrack_pos);
c19d1205
ZW
6814 backtrack_pos = str;
6815 backtrack_error = inst.error;
6816 backtrack_index = i;
6817 }
6818
b6702015 6819 if (i > 0 && (i > 1 || inst.operands[0].present))
c19d1205
ZW
6820 po_char_or_fail (',');
6821
5be8be5d 6822 switch (op_parse_code)
c19d1205
ZW
6823 {
6824 /* Registers */
6825 case OP_oRRnpc:
5be8be5d 6826 case OP_oRRnpcsp:
c19d1205 6827 case OP_RRnpc:
5be8be5d 6828 case OP_RRnpcsp:
c19d1205 6829 case OP_oRR:
60f993ce
AV
6830 case OP_LR:
6831 case OP_oLR:
c19d1205
ZW
6832 case OP_RR: po_reg_or_fail (REG_TYPE_RN); break;
6833 case OP_RCP: po_reg_or_fail (REG_TYPE_CP); break;
6834 case OP_RCN: po_reg_or_fail (REG_TYPE_CN); break;
6835 case OP_RF: po_reg_or_fail (REG_TYPE_FN); break;
6836 case OP_RVS: po_reg_or_fail (REG_TYPE_VFS); break;
6837 case OP_RVD: po_reg_or_fail (REG_TYPE_VFD); break;
477330fc 6838 case OP_oRND:
5287ad62 6839 case OP_RND: po_reg_or_fail (REG_TYPE_VFD); break;
cd2cf30b
PB
6840 case OP_RVC:
6841 po_reg_or_goto (REG_TYPE_VFC, coproc_reg);
6842 break;
6843 /* Also accept generic coprocessor regs for unknown registers. */
6844 coproc_reg:
6845 po_reg_or_fail (REG_TYPE_CN);
6846 break;
c19d1205
ZW
6847 case OP_RMF: po_reg_or_fail (REG_TYPE_MVF); break;
6848 case OP_RMD: po_reg_or_fail (REG_TYPE_MVD); break;
6849 case OP_RMFX: po_reg_or_fail (REG_TYPE_MVFX); break;
6850 case OP_RMDX: po_reg_or_fail (REG_TYPE_MVDX); break;
6851 case OP_RMAX: po_reg_or_fail (REG_TYPE_MVAX); break;
6852 case OP_RMDS: po_reg_or_fail (REG_TYPE_DSPSC); break;
6853 case OP_RIWR: po_reg_or_fail (REG_TYPE_MMXWR); break;
6854 case OP_RIWC: po_reg_or_fail (REG_TYPE_MMXWC); break;
6855 case OP_RIWG: po_reg_or_fail (REG_TYPE_MMXWCG); break;
6856 case OP_RXA: po_reg_or_fail (REG_TYPE_XSCALE); break;
477330fc 6857 case OP_oRNQ:
5287ad62 6858 case OP_RNQ: po_reg_or_fail (REG_TYPE_NQ); break;
dec41383 6859 case OP_RNSD: po_reg_or_fail (REG_TYPE_NSD); break;
477330fc 6860 case OP_oRNDQ:
5287ad62 6861 case OP_RNDQ: po_reg_or_fail (REG_TYPE_NDQ); break;
477330fc
RM
6862 case OP_RVSD: po_reg_or_fail (REG_TYPE_VFSD); break;
6863 case OP_oRNSDQ:
6864 case OP_RNSDQ: po_reg_or_fail (REG_TYPE_NSDQ); break;
6865
6866 /* Neon scalar. Using an element size of 8 means that some invalid
6867 scalars are accepted here, so deal with those in later code. */
6868 case OP_RNSC: po_scalar_or_goto (8, failure); break;
6869
6870 case OP_RNDQ_I0:
6871 {
6872 po_reg_or_goto (REG_TYPE_NDQ, try_imm0);
6873 break;
6874 try_imm0:
6875 po_imm_or_fail (0, 0, TRUE);
6876 }
6877 break;
6878
6879 case OP_RVSD_I0:
6880 po_reg_or_goto (REG_TYPE_VFSD, try_imm0);
6881 break;
6882
aacf0b33
KT
6883 case OP_RSVD_FI0:
6884 {
6885 po_reg_or_goto (REG_TYPE_VFSD, try_ifimm0);
6886 break;
6887 try_ifimm0:
6888 if (parse_ifimm_zero (&str))
6889 inst.operands[i].imm = 0;
6890 else
6891 {
6892 inst.error
6893 = _("only floating point zero is allowed as immediate value");
6894 goto failure;
6895 }
6896 }
6897 break;
6898
477330fc
RM
6899 case OP_RR_RNSC:
6900 {
6901 po_scalar_or_goto (8, try_rr);
6902 break;
6903 try_rr:
6904 po_reg_or_fail (REG_TYPE_RN);
6905 }
6906 break;
6907
6908 case OP_RNSDQ_RNSC:
6909 {
6910 po_scalar_or_goto (8, try_nsdq);
6911 break;
6912 try_nsdq:
6913 po_reg_or_fail (REG_TYPE_NSDQ);
6914 }
6915 break;
6916
dec41383
JW
6917 case OP_RNSD_RNSC:
6918 {
6919 po_scalar_or_goto (8, try_s_scalar);
6920 break;
6921 try_s_scalar:
6922 po_scalar_or_goto (4, try_nsd);
6923 break;
6924 try_nsd:
6925 po_reg_or_fail (REG_TYPE_NSD);
6926 }
6927 break;
6928
477330fc
RM
6929 case OP_RNDQ_RNSC:
6930 {
6931 po_scalar_or_goto (8, try_ndq);
6932 break;
6933 try_ndq:
6934 po_reg_or_fail (REG_TYPE_NDQ);
6935 }
6936 break;
6937
6938 case OP_RND_RNSC:
6939 {
6940 po_scalar_or_goto (8, try_vfd);
6941 break;
6942 try_vfd:
6943 po_reg_or_fail (REG_TYPE_VFD);
6944 }
6945 break;
6946
6947 case OP_VMOV:
6948 /* WARNING: parse_neon_mov can move the operand counter, i. If we're
6949 not careful then bad things might happen. */
6950 po_misc_or_fail (parse_neon_mov (&str, &i) == FAIL);
6951 break;
6952
6953 case OP_RNDQ_Ibig:
6954 {
6955 po_reg_or_goto (REG_TYPE_NDQ, try_immbig);
6956 break;
6957 try_immbig:
6958 /* There's a possibility of getting a 64-bit immediate here, so
6959 we need special handling. */
8335d6aa
JW
6960 if (parse_big_immediate (&str, i, NULL, /*allow_symbol_p=*/FALSE)
6961 == FAIL)
477330fc
RM
6962 {
6963 inst.error = _("immediate value is out of range");
6964 goto failure;
6965 }
6966 }
6967 break;
6968
6969 case OP_RNDQ_I63b:
6970 {
6971 po_reg_or_goto (REG_TYPE_NDQ, try_shimm);
6972 break;
6973 try_shimm:
6974 po_imm_or_fail (0, 63, TRUE);
6975 }
6976 break;
c19d1205
ZW
6977
6978 case OP_RRnpcb:
6979 po_char_or_fail ('[');
6980 po_reg_or_fail (REG_TYPE_RN);
6981 po_char_or_fail (']');
6982 break;
a737bd4d 6983
55881a11 6984 case OP_RRnpctw:
c19d1205 6985 case OP_RRw:
b6702015 6986 case OP_oRRw:
c19d1205
ZW
6987 po_reg_or_fail (REG_TYPE_RN);
6988 if (skip_past_char (&str, '!') == SUCCESS)
6989 inst.operands[i].writeback = 1;
6990 break;
6991
6992 /* Immediates */
6993 case OP_I7: po_imm_or_fail ( 0, 7, FALSE); break;
6994 case OP_I15: po_imm_or_fail ( 0, 15, FALSE); break;
6995 case OP_I16: po_imm_or_fail ( 1, 16, FALSE); break;
477330fc 6996 case OP_I16z: po_imm_or_fail ( 0, 16, FALSE); break;
c19d1205
ZW
6997 case OP_I31: po_imm_or_fail ( 0, 31, FALSE); break;
6998 case OP_I32: po_imm_or_fail ( 1, 32, FALSE); break;
477330fc 6999 case OP_I32z: po_imm_or_fail ( 0, 32, FALSE); break;
c19d1205 7000 case OP_I63s: po_imm_or_fail (-64, 63, FALSE); break;
477330fc
RM
7001 case OP_I63: po_imm_or_fail ( 0, 63, FALSE); break;
7002 case OP_I64: po_imm_or_fail ( 1, 64, FALSE); break;
7003 case OP_I64z: po_imm_or_fail ( 0, 64, FALSE); break;
c19d1205 7004 case OP_I255: po_imm_or_fail ( 0, 255, FALSE); break;
c19d1205
ZW
7005
7006 case OP_I4b: po_imm_or_fail ( 1, 4, TRUE); break;
7007 case OP_oI7b:
7008 case OP_I7b: po_imm_or_fail ( 0, 7, TRUE); break;
7009 case OP_I15b: po_imm_or_fail ( 0, 15, TRUE); break;
7010 case OP_oI31b:
7011 case OP_I31b: po_imm_or_fail ( 0, 31, TRUE); break;
477330fc
RM
7012 case OP_oI32b: po_imm_or_fail ( 1, 32, TRUE); break;
7013 case OP_oI32z: po_imm_or_fail ( 0, 32, TRUE); break;
c19d1205
ZW
7014 case OP_oIffffb: po_imm_or_fail ( 0, 0xffff, TRUE); break;
7015
7016 /* Immediate variants */
7017 case OP_oI255c:
7018 po_char_or_fail ('{');
7019 po_imm_or_fail (0, 255, TRUE);
7020 po_char_or_fail ('}');
7021 break;
7022
7023 case OP_I31w:
7024 /* The expression parser chokes on a trailing !, so we have
7025 to find it first and zap it. */
7026 {
7027 char *s = str;
7028 while (*s && *s != ',')
7029 s++;
7030 if (s[-1] == '!')
7031 {
7032 s[-1] = '\0';
7033 inst.operands[i].writeback = 1;
7034 }
7035 po_imm_or_fail (0, 31, TRUE);
7036 if (str == s - 1)
7037 str = s;
7038 }
7039 break;
7040
7041 /* Expressions */
7042 case OP_EXPi: EXPi:
e2b0ab59 7043 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7044 GE_OPT_PREFIX));
7045 break;
7046
7047 case OP_EXP:
e2b0ab59 7048 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7049 GE_NO_PREFIX));
7050 break;
7051
7052 case OP_EXPr: EXPr:
e2b0ab59 7053 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205 7054 GE_NO_PREFIX));
e2b0ab59 7055 if (inst.relocs[0].exp.X_op == O_symbol)
a737bd4d 7056 {
c19d1205
ZW
7057 val = parse_reloc (&str);
7058 if (val == -1)
7059 {
7060 inst.error = _("unrecognized relocation suffix");
7061 goto failure;
7062 }
7063 else if (val != BFD_RELOC_UNUSED)
7064 {
7065 inst.operands[i].imm = val;
7066 inst.operands[i].hasreloc = 1;
7067 }
a737bd4d 7068 }
c19d1205 7069 break;
a737bd4d 7070
e2b0ab59
AV
7071 case OP_EXPs:
7072 po_misc_or_fail (my_get_expression (&inst.relocs[i].exp, &str,
7073 GE_NO_PREFIX));
7074 if (inst.relocs[i].exp.X_op == O_symbol)
7075 {
7076 inst.operands[i].hasreloc = 1;
7077 }
7078 else if (inst.relocs[i].exp.X_op == O_constant)
7079 {
7080 inst.operands[i].imm = inst.relocs[i].exp.X_add_number;
7081 inst.operands[i].hasreloc = 0;
7082 }
7083 break;
7084
b6895b4f
PB
7085 /* Operand for MOVW or MOVT. */
7086 case OP_HALF:
7087 po_misc_or_fail (parse_half (&str));
7088 break;
7089
e07e6e58 7090 /* Register or expression. */
c19d1205
ZW
7091 case OP_RR_EXr: po_reg_or_goto (REG_TYPE_RN, EXPr); break;
7092 case OP_RR_EXi: po_reg_or_goto (REG_TYPE_RN, EXPi); break;
a737bd4d 7093
e07e6e58 7094 /* Register or immediate. */
c19d1205
ZW
7095 case OP_RRnpc_I0: po_reg_or_goto (REG_TYPE_RN, I0); break;
7096 I0: po_imm_or_fail (0, 0, FALSE); break;
a737bd4d 7097
c19d1205
ZW
7098 case OP_RF_IF: po_reg_or_goto (REG_TYPE_FN, IF); break;
7099 IF:
7100 if (!is_immediate_prefix (*str))
7101 goto bad_args;
7102 str++;
7103 val = parse_fpa_immediate (&str);
7104 if (val == FAIL)
7105 goto failure;
7106 /* FPA immediates are encoded as registers 8-15.
7107 parse_fpa_immediate has already applied the offset. */
7108 inst.operands[i].reg = val;
7109 inst.operands[i].isreg = 1;
7110 break;
09d92015 7111
2d447fca
JM
7112 case OP_RIWR_I32z: po_reg_or_goto (REG_TYPE_MMXWR, I32z); break;
7113 I32z: po_imm_or_fail (0, 32, FALSE); break;
7114
e07e6e58 7115 /* Two kinds of register. */
c19d1205
ZW
7116 case OP_RIWR_RIWC:
7117 {
7118 struct reg_entry *rege = arm_reg_parse_multi (&str);
97f87066
JM
7119 if (!rege
7120 || (rege->type != REG_TYPE_MMXWR
7121 && rege->type != REG_TYPE_MMXWC
7122 && rege->type != REG_TYPE_MMXWCG))
c19d1205
ZW
7123 {
7124 inst.error = _("iWMMXt data or control register expected");
7125 goto failure;
7126 }
7127 inst.operands[i].reg = rege->number;
7128 inst.operands[i].isreg = (rege->type == REG_TYPE_MMXWR);
7129 }
7130 break;
09d92015 7131
41adaa5c
JM
7132 case OP_RIWC_RIWG:
7133 {
7134 struct reg_entry *rege = arm_reg_parse_multi (&str);
7135 if (!rege
7136 || (rege->type != REG_TYPE_MMXWC
7137 && rege->type != REG_TYPE_MMXWCG))
7138 {
7139 inst.error = _("iWMMXt control register expected");
7140 goto failure;
7141 }
7142 inst.operands[i].reg = rege->number;
7143 inst.operands[i].isreg = 1;
7144 }
7145 break;
7146
c19d1205
ZW
7147 /* Misc */
7148 case OP_CPSF: val = parse_cps_flags (&str); break;
7149 case OP_ENDI: val = parse_endian_specifier (&str); break;
7150 case OP_oROR: val = parse_ror (&str); break;
c19d1205 7151 case OP_COND: val = parse_cond (&str); break;
52e7f43d
RE
7152 case OP_oBARRIER_I15:
7153 po_barrier_or_imm (str); break;
7154 immediate:
7155 if (parse_immediate (&str, &val, 0, 15, TRUE) == FAIL)
477330fc 7156 goto failure;
52e7f43d 7157 break;
c19d1205 7158
fa94de6b 7159 case OP_wPSR:
d2cd1205 7160 case OP_rPSR:
90ec0d68
MGD
7161 po_reg_or_goto (REG_TYPE_RNB, try_psr);
7162 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_virt))
7163 {
7164 inst.error = _("Banked registers are not available with this "
7165 "architecture.");
7166 goto failure;
7167 }
7168 break;
d2cd1205
JB
7169 try_psr:
7170 val = parse_psr (&str, op_parse_code == OP_wPSR);
7171 break;
037e8744 7172
477330fc
RM
7173 case OP_APSR_RR:
7174 po_reg_or_goto (REG_TYPE_RN, try_apsr);
7175 break;
7176 try_apsr:
7177 /* Parse "APSR_nvzc" operand (for FMSTAT-equivalent MRS
7178 instruction). */
7179 if (strncasecmp (str, "APSR_", 5) == 0)
7180 {
7181 unsigned found = 0;
7182 str += 5;
7183 while (found < 15)
7184 switch (*str++)
7185 {
7186 case 'c': found = (found & 1) ? 16 : found | 1; break;
7187 case 'n': found = (found & 2) ? 16 : found | 2; break;
7188 case 'z': found = (found & 4) ? 16 : found | 4; break;
7189 case 'v': found = (found & 8) ? 16 : found | 8; break;
7190 default: found = 16;
7191 }
7192 if (found != 15)
7193 goto failure;
7194 inst.operands[i].isvec = 1;
f7c21dc7
NC
7195 /* APSR_nzcv is encoded in instructions as if it were the REG_PC. */
7196 inst.operands[i].reg = REG_PC;
477330fc
RM
7197 }
7198 else
7199 goto failure;
7200 break;
037e8744 7201
92e90b6e
PB
7202 case OP_TB:
7203 po_misc_or_fail (parse_tb (&str));
7204 break;
7205
e07e6e58 7206 /* Register lists. */
c19d1205 7207 case OP_REGLST:
4b5a202f 7208 val = parse_reg_list (&str, REGLIST_RN);
c19d1205
ZW
7209 if (*str == '^')
7210 {
5e0d7f77 7211 inst.operands[i].writeback = 1;
c19d1205
ZW
7212 str++;
7213 }
7214 break;
09d92015 7215
4b5a202f
AV
7216 case OP_CLRMLST:
7217 val = parse_reg_list (&str, REGLIST_CLRM);
7218 break;
7219
c19d1205 7220 case OP_VRSLST:
5287ad62 7221 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_S);
c19d1205 7222 break;
09d92015 7223
c19d1205 7224 case OP_VRDLST:
5287ad62 7225 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_D);
c19d1205 7226 break;
a737bd4d 7227
477330fc
RM
7228 case OP_VRSDLST:
7229 /* Allow Q registers too. */
7230 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
7231 REGLIST_NEON_D);
7232 if (val == FAIL)
7233 {
7234 inst.error = NULL;
7235 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
7236 REGLIST_VFP_S);
7237 inst.operands[i].issingle = 1;
7238 }
7239 break;
7240
7241 case OP_NRDLST:
7242 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
7243 REGLIST_NEON_D);
7244 break;
5287ad62
JB
7245
7246 case OP_NSTRLST:
477330fc
RM
7247 val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
7248 &inst.operands[i].vectype);
7249 break;
5287ad62 7250
c19d1205
ZW
7251 /* Addressing modes */
7252 case OP_ADDR:
7253 po_misc_or_fail (parse_address (&str, i));
7254 break;
09d92015 7255
4962c51a
MS
7256 case OP_ADDRGLDR:
7257 po_misc_or_fail_no_backtrack (
477330fc 7258 parse_address_group_reloc (&str, i, GROUP_LDR));
4962c51a
MS
7259 break;
7260
7261 case OP_ADDRGLDRS:
7262 po_misc_or_fail_no_backtrack (
477330fc 7263 parse_address_group_reloc (&str, i, GROUP_LDRS));
4962c51a
MS
7264 break;
7265
7266 case OP_ADDRGLDC:
7267 po_misc_or_fail_no_backtrack (
477330fc 7268 parse_address_group_reloc (&str, i, GROUP_LDC));
4962c51a
MS
7269 break;
7270
c19d1205
ZW
7271 case OP_SH:
7272 po_misc_or_fail (parse_shifter_operand (&str, i));
7273 break;
09d92015 7274
4962c51a
MS
7275 case OP_SHG:
7276 po_misc_or_fail_no_backtrack (
477330fc 7277 parse_shifter_operand_group_reloc (&str, i));
4962c51a
MS
7278 break;
7279
c19d1205
ZW
7280 case OP_oSHll:
7281 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_IMMEDIATE));
7282 break;
09d92015 7283
c19d1205
ZW
7284 case OP_oSHar:
7285 po_misc_or_fail (parse_shift (&str, i, SHIFT_ASR_IMMEDIATE));
7286 break;
09d92015 7287
c19d1205
ZW
7288 case OP_oSHllar:
7289 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_OR_ASR_IMMEDIATE));
7290 break;
09d92015 7291
c19d1205 7292 default:
5be8be5d 7293 as_fatal (_("unhandled operand code %d"), op_parse_code);
c19d1205 7294 }
09d92015 7295
c19d1205
ZW
7296 /* Various value-based sanity checks and shared operations. We
7297 do not signal immediate failures for the register constraints;
7298 this allows a syntax error to take precedence. */
5be8be5d 7299 switch (op_parse_code)
c19d1205
ZW
7300 {
7301 case OP_oRRnpc:
7302 case OP_RRnpc:
7303 case OP_RRnpcb:
7304 case OP_RRw:
b6702015 7305 case OP_oRRw:
c19d1205
ZW
7306 case OP_RRnpc_I0:
7307 if (inst.operands[i].isreg && inst.operands[i].reg == REG_PC)
7308 inst.error = BAD_PC;
7309 break;
09d92015 7310
5be8be5d
DG
7311 case OP_oRRnpcsp:
7312 case OP_RRnpcsp:
7313 if (inst.operands[i].isreg)
7314 {
7315 if (inst.operands[i].reg == REG_PC)
7316 inst.error = BAD_PC;
5c8ed6a4
JW
7317 else if (inst.operands[i].reg == REG_SP
7318 /* The restriction on Rd/Rt/Rt2 on Thumb mode has been
7319 relaxed since ARMv8-A. */
7320 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
7321 {
7322 gas_assert (thumb);
7323 inst.error = BAD_SP;
7324 }
5be8be5d
DG
7325 }
7326 break;
7327
55881a11 7328 case OP_RRnpctw:
fa94de6b
RM
7329 if (inst.operands[i].isreg
7330 && inst.operands[i].reg == REG_PC
55881a11
MGD
7331 && (inst.operands[i].writeback || thumb))
7332 inst.error = BAD_PC;
7333 break;
7334
c19d1205
ZW
7335 case OP_CPSF:
7336 case OP_ENDI:
7337 case OP_oROR:
d2cd1205
JB
7338 case OP_wPSR:
7339 case OP_rPSR:
c19d1205 7340 case OP_COND:
52e7f43d 7341 case OP_oBARRIER_I15:
c19d1205 7342 case OP_REGLST:
4b5a202f 7343 case OP_CLRMLST:
c19d1205
ZW
7344 case OP_VRSLST:
7345 case OP_VRDLST:
477330fc
RM
7346 case OP_VRSDLST:
7347 case OP_NRDLST:
7348 case OP_NSTRLST:
c19d1205
ZW
7349 if (val == FAIL)
7350 goto failure;
7351 inst.operands[i].imm = val;
7352 break;
a737bd4d 7353
60f993ce
AV
7354 case OP_LR:
7355 case OP_oLR:
7356 if (inst.operands[i].reg != REG_LR)
7357 inst.error = _("operand must be LR register");
7358 break;
7359
c19d1205
ZW
7360 default:
7361 break;
7362 }
09d92015 7363
c19d1205
ZW
7364 /* If we get here, this operand was successfully parsed. */
7365 inst.operands[i].present = 1;
7366 continue;
09d92015 7367
c19d1205 7368 bad_args:
09d92015 7369 inst.error = BAD_ARGS;
c19d1205
ZW
7370
7371 failure:
7372 if (!backtrack_pos)
d252fdde
PB
7373 {
7374 /* The parse routine should already have set inst.error, but set a
5f4273c7 7375 default here just in case. */
d252fdde
PB
7376 if (!inst.error)
7377 inst.error = _("syntax error");
7378 return FAIL;
7379 }
c19d1205
ZW
7380
7381 /* Do not backtrack over a trailing optional argument that
7382 absorbed some text. We will only fail again, with the
7383 'garbage following instruction' error message, which is
7384 probably less helpful than the current one. */
7385 if (backtrack_index == i && backtrack_pos != str
7386 && upat[i+1] == OP_stop)
d252fdde
PB
7387 {
7388 if (!inst.error)
7389 inst.error = _("syntax error");
7390 return FAIL;
7391 }
c19d1205
ZW
7392
7393 /* Try again, skipping the optional argument at backtrack_pos. */
7394 str = backtrack_pos;
7395 inst.error = backtrack_error;
7396 inst.operands[backtrack_index].present = 0;
7397 i = backtrack_index;
7398 backtrack_pos = 0;
09d92015 7399 }
09d92015 7400
c19d1205
ZW
7401 /* Check that we have parsed all the arguments. */
7402 if (*str != '\0' && !inst.error)
7403 inst.error = _("garbage following instruction");
09d92015 7404
c19d1205 7405 return inst.error ? FAIL : SUCCESS;
09d92015
MM
7406}
7407
c19d1205
ZW
7408#undef po_char_or_fail
7409#undef po_reg_or_fail
7410#undef po_reg_or_goto
7411#undef po_imm_or_fail
5287ad62 7412#undef po_scalar_or_fail
52e7f43d 7413#undef po_barrier_or_imm
e07e6e58 7414
c19d1205 7415/* Shorthand macro for instruction encoding functions issuing errors. */
e07e6e58
NC
7416#define constraint(expr, err) \
7417 do \
c19d1205 7418 { \
e07e6e58
NC
7419 if (expr) \
7420 { \
7421 inst.error = err; \
7422 return; \
7423 } \
c19d1205 7424 } \
e07e6e58 7425 while (0)
c19d1205 7426
fdfde340
JM
7427/* Reject "bad registers" for Thumb-2 instructions. Many Thumb-2
7428 instructions are unpredictable if these registers are used. This
5c8ed6a4
JW
7429 is the BadReg predicate in ARM's Thumb-2 documentation.
7430
7431 Before ARMv8-A, REG_PC and REG_SP were not allowed in quite a few
7432 places, while the restriction on REG_SP was relaxed since ARMv8-A. */
7433#define reject_bad_reg(reg) \
7434 do \
7435 if (reg == REG_PC) \
7436 { \
7437 inst.error = BAD_PC; \
7438 return; \
7439 } \
7440 else if (reg == REG_SP \
7441 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)) \
7442 { \
7443 inst.error = BAD_SP; \
7444 return; \
7445 } \
fdfde340
JM
7446 while (0)
7447
94206790
MM
7448/* If REG is R13 (the stack pointer), warn that its use is
7449 deprecated. */
7450#define warn_deprecated_sp(reg) \
7451 do \
7452 if (warn_on_deprecated && reg == REG_SP) \
5c3696f8 7453 as_tsktsk (_("use of r13 is deprecated")); \
94206790
MM
7454 while (0)
7455
c19d1205
ZW
7456/* Functions for operand encoding. ARM, then Thumb. */
7457
d840c081 7458#define rotate_left(v, n) (v << (n & 31) | v >> ((32 - n) & 31))
c19d1205 7459
9db2f6b4
RL
7460/* If the current inst is scalar ARMv8.2 fp16 instruction, do special encoding.
7461
7462 The only binary encoding difference is the Coprocessor number. Coprocessor
7463 9 is used for half-precision calculations or conversions. The format of the
2b0f3761 7464 instruction is the same as the equivalent Coprocessor 10 instruction that
9db2f6b4
RL
7465 exists for Single-Precision operation. */
7466
7467static void
7468do_scalar_fp16_v82_encode (void)
7469{
7470 if (inst.cond != COND_ALWAYS)
7471 as_warn (_("ARMv8.2 scalar fp16 instruction cannot be conditional,"
7472 " the behaviour is UNPREDICTABLE"));
7473 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
7474 _(BAD_FP16));
7475
7476 inst.instruction = (inst.instruction & 0xfffff0ff) | 0x900;
7477 mark_feature_used (&arm_ext_fp16);
7478}
7479
c19d1205
ZW
7480/* If VAL can be encoded in the immediate field of an ARM instruction,
7481 return the encoded form. Otherwise, return FAIL. */
7482
7483static unsigned int
7484encode_arm_immediate (unsigned int val)
09d92015 7485{
c19d1205
ZW
7486 unsigned int a, i;
7487
4f1d6205
L
7488 if (val <= 0xff)
7489 return val;
7490
7491 for (i = 2; i < 32; i += 2)
c19d1205
ZW
7492 if ((a = rotate_left (val, i)) <= 0xff)
7493 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
7494
7495 return FAIL;
09d92015
MM
7496}
7497
c19d1205
ZW
7498/* If VAL can be encoded in the immediate field of a Thumb32 instruction,
7499 return the encoded form. Otherwise, return FAIL. */
7500static unsigned int
7501encode_thumb32_immediate (unsigned int val)
09d92015 7502{
c19d1205 7503 unsigned int a, i;
09d92015 7504
9c3c69f2 7505 if (val <= 0xff)
c19d1205 7506 return val;
a737bd4d 7507
9c3c69f2 7508 for (i = 1; i <= 24; i++)
09d92015 7509 {
9c3c69f2
PB
7510 a = val >> i;
7511 if ((val & ~(0xff << i)) == 0)
7512 return ((val >> i) & 0x7f) | ((32 - i) << 7);
09d92015 7513 }
a737bd4d 7514
c19d1205
ZW
7515 a = val & 0xff;
7516 if (val == ((a << 16) | a))
7517 return 0x100 | a;
7518 if (val == ((a << 24) | (a << 16) | (a << 8) | a))
7519 return 0x300 | a;
09d92015 7520
c19d1205
ZW
7521 a = val & 0xff00;
7522 if (val == ((a << 16) | a))
7523 return 0x200 | (a >> 8);
a737bd4d 7524
c19d1205 7525 return FAIL;
09d92015 7526}
5287ad62 7527/* Encode a VFP SP or DP register number into inst.instruction. */
09d92015
MM
7528
7529static void
5287ad62
JB
7530encode_arm_vfp_reg (int reg, enum vfp_reg_pos pos)
7531{
7532 if ((pos == VFP_REG_Dd || pos == VFP_REG_Dn || pos == VFP_REG_Dm)
7533 && reg > 15)
7534 {
b1cc4aeb 7535 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
477330fc
RM
7536 {
7537 if (thumb_mode)
7538 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
7539 fpu_vfp_ext_d32);
7540 else
7541 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
7542 fpu_vfp_ext_d32);
7543 }
5287ad62 7544 else
477330fc
RM
7545 {
7546 first_error (_("D register out of range for selected VFP version"));
7547 return;
7548 }
5287ad62
JB
7549 }
7550
c19d1205 7551 switch (pos)
09d92015 7552 {
c19d1205
ZW
7553 case VFP_REG_Sd:
7554 inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
7555 break;
7556
7557 case VFP_REG_Sn:
7558 inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
7559 break;
7560
7561 case VFP_REG_Sm:
7562 inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
7563 break;
7564
5287ad62
JB
7565 case VFP_REG_Dd:
7566 inst.instruction |= ((reg & 15) << 12) | ((reg >> 4) << 22);
7567 break;
5f4273c7 7568
5287ad62
JB
7569 case VFP_REG_Dn:
7570 inst.instruction |= ((reg & 15) << 16) | ((reg >> 4) << 7);
7571 break;
5f4273c7 7572
5287ad62
JB
7573 case VFP_REG_Dm:
7574 inst.instruction |= (reg & 15) | ((reg >> 4) << 5);
7575 break;
7576
c19d1205
ZW
7577 default:
7578 abort ();
09d92015 7579 }
09d92015
MM
7580}
7581
c19d1205 7582/* Encode a <shift> in an ARM-format instruction. The immediate,
55cf6793 7583 if any, is handled by md_apply_fix. */
09d92015 7584static void
c19d1205 7585encode_arm_shift (int i)
09d92015 7586{
008a97ef
RL
7587 /* register-shifted register. */
7588 if (inst.operands[i].immisreg)
7589 {
bf355b69
MR
7590 int op_index;
7591 for (op_index = 0; op_index <= i; ++op_index)
008a97ef 7592 {
5689c942
RL
7593 /* Check the operand only when it's presented. In pre-UAL syntax,
7594 if the destination register is the same as the first operand, two
7595 register form of the instruction can be used. */
bf355b69
MR
7596 if (inst.operands[op_index].present && inst.operands[op_index].isreg
7597 && inst.operands[op_index].reg == REG_PC)
008a97ef
RL
7598 as_warn (UNPRED_REG ("r15"));
7599 }
7600
7601 if (inst.operands[i].imm == REG_PC)
7602 as_warn (UNPRED_REG ("r15"));
7603 }
7604
c19d1205
ZW
7605 if (inst.operands[i].shift_kind == SHIFT_RRX)
7606 inst.instruction |= SHIFT_ROR << 5;
7607 else
09d92015 7608 {
c19d1205
ZW
7609 inst.instruction |= inst.operands[i].shift_kind << 5;
7610 if (inst.operands[i].immisreg)
7611 {
7612 inst.instruction |= SHIFT_BY_REG;
7613 inst.instruction |= inst.operands[i].imm << 8;
7614 }
7615 else
e2b0ab59 7616 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
09d92015 7617 }
c19d1205 7618}
09d92015 7619
c19d1205
ZW
7620static void
7621encode_arm_shifter_operand (int i)
7622{
7623 if (inst.operands[i].isreg)
09d92015 7624 {
c19d1205
ZW
7625 inst.instruction |= inst.operands[i].reg;
7626 encode_arm_shift (i);
09d92015 7627 }
c19d1205 7628 else
a415b1cd
JB
7629 {
7630 inst.instruction |= INST_IMMEDIATE;
e2b0ab59 7631 if (inst.relocs[0].type != BFD_RELOC_ARM_IMMEDIATE)
a415b1cd
JB
7632 inst.instruction |= inst.operands[i].imm;
7633 }
09d92015
MM
7634}
7635
c19d1205 7636/* Subroutine of encode_arm_addr_mode_2 and encode_arm_addr_mode_3. */
09d92015 7637static void
c19d1205 7638encode_arm_addr_mode_common (int i, bfd_boolean is_t)
09d92015 7639{
2b2f5df9
NC
7640 /* PR 14260:
7641 Generate an error if the operand is not a register. */
7642 constraint (!inst.operands[i].isreg,
7643 _("Instruction does not support =N addresses"));
7644
c19d1205 7645 inst.instruction |= inst.operands[i].reg << 16;
a737bd4d 7646
c19d1205 7647 if (inst.operands[i].preind)
09d92015 7648 {
c19d1205
ZW
7649 if (is_t)
7650 {
7651 inst.error = _("instruction does not accept preindexed addressing");
7652 return;
7653 }
7654 inst.instruction |= PRE_INDEX;
7655 if (inst.operands[i].writeback)
7656 inst.instruction |= WRITE_BACK;
09d92015 7657
c19d1205
ZW
7658 }
7659 else if (inst.operands[i].postind)
7660 {
9c2799c2 7661 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
7662 if (is_t)
7663 inst.instruction |= WRITE_BACK;
7664 }
7665 else /* unindexed - only for coprocessor */
09d92015 7666 {
c19d1205 7667 inst.error = _("instruction does not accept unindexed addressing");
09d92015
MM
7668 return;
7669 }
7670
c19d1205
ZW
7671 if (((inst.instruction & WRITE_BACK) || !(inst.instruction & PRE_INDEX))
7672 && (((inst.instruction & 0x000f0000) >> 16)
7673 == ((inst.instruction & 0x0000f000) >> 12)))
7674 as_warn ((inst.instruction & LOAD_BIT)
7675 ? _("destination register same as write-back base")
7676 : _("source register same as write-back base"));
09d92015
MM
7677}
7678
c19d1205
ZW
7679/* inst.operands[i] was set up by parse_address. Encode it into an
7680 ARM-format mode 2 load or store instruction. If is_t is true,
7681 reject forms that cannot be used with a T instruction (i.e. not
7682 post-indexed). */
a737bd4d 7683static void
c19d1205 7684encode_arm_addr_mode_2 (int i, bfd_boolean is_t)
09d92015 7685{
5be8be5d
DG
7686 const bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
7687
c19d1205 7688 encode_arm_addr_mode_common (i, is_t);
a737bd4d 7689
c19d1205 7690 if (inst.operands[i].immisreg)
09d92015 7691 {
5be8be5d
DG
7692 constraint ((inst.operands[i].imm == REG_PC
7693 || (is_pc && inst.operands[i].writeback)),
7694 BAD_PC_ADDRESSING);
c19d1205
ZW
7695 inst.instruction |= INST_IMMEDIATE; /* yes, this is backwards */
7696 inst.instruction |= inst.operands[i].imm;
7697 if (!inst.operands[i].negative)
7698 inst.instruction |= INDEX_UP;
7699 if (inst.operands[i].shifted)
7700 {
7701 if (inst.operands[i].shift_kind == SHIFT_RRX)
7702 inst.instruction |= SHIFT_ROR << 5;
7703 else
7704 {
7705 inst.instruction |= inst.operands[i].shift_kind << 5;
e2b0ab59 7706 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
c19d1205
ZW
7707 }
7708 }
09d92015 7709 }
e2b0ab59 7710 else /* immediate offset in inst.relocs[0] */
09d92015 7711 {
e2b0ab59 7712 if (is_pc && !inst.relocs[0].pc_rel)
5be8be5d
DG
7713 {
7714 const bfd_boolean is_load = ((inst.instruction & LOAD_BIT) != 0);
23a10334
JZ
7715
7716 /* If is_t is TRUE, it's called from do_ldstt. ldrt/strt
7717 cannot use PC in addressing.
7718 PC cannot be used in writeback addressing, either. */
7719 constraint ((is_t || inst.operands[i].writeback),
5be8be5d 7720 BAD_PC_ADDRESSING);
23a10334 7721
dc5ec521 7722 /* Use of PC in str is deprecated for ARMv7. */
23a10334
JZ
7723 if (warn_on_deprecated
7724 && !is_load
7725 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7))
5c3696f8 7726 as_tsktsk (_("use of PC in this instruction is deprecated"));
5be8be5d
DG
7727 }
7728
e2b0ab59 7729 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
7730 {
7731 /* Prefer + for zero encoded value. */
7732 if (!inst.operands[i].negative)
7733 inst.instruction |= INDEX_UP;
e2b0ab59 7734 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM;
26d97720 7735 }
09d92015 7736 }
09d92015
MM
7737}
7738
c19d1205
ZW
7739/* inst.operands[i] was set up by parse_address. Encode it into an
7740 ARM-format mode 3 load or store instruction. Reject forms that
7741 cannot be used with such instructions. If is_t is true, reject
7742 forms that cannot be used with a T instruction (i.e. not
7743 post-indexed). */
7744static void
7745encode_arm_addr_mode_3 (int i, bfd_boolean is_t)
09d92015 7746{
c19d1205 7747 if (inst.operands[i].immisreg && inst.operands[i].shifted)
09d92015 7748 {
c19d1205
ZW
7749 inst.error = _("instruction does not accept scaled register index");
7750 return;
09d92015 7751 }
a737bd4d 7752
c19d1205 7753 encode_arm_addr_mode_common (i, is_t);
a737bd4d 7754
c19d1205
ZW
7755 if (inst.operands[i].immisreg)
7756 {
5be8be5d 7757 constraint ((inst.operands[i].imm == REG_PC
eb9f3f00 7758 || (is_t && inst.operands[i].reg == REG_PC)),
5be8be5d 7759 BAD_PC_ADDRESSING);
eb9f3f00
JB
7760 constraint (inst.operands[i].reg == REG_PC && inst.operands[i].writeback,
7761 BAD_PC_WRITEBACK);
c19d1205
ZW
7762 inst.instruction |= inst.operands[i].imm;
7763 if (!inst.operands[i].negative)
7764 inst.instruction |= INDEX_UP;
7765 }
e2b0ab59 7766 else /* immediate offset in inst.relocs[0] */
c19d1205 7767 {
e2b0ab59 7768 constraint ((inst.operands[i].reg == REG_PC && !inst.relocs[0].pc_rel
5be8be5d
DG
7769 && inst.operands[i].writeback),
7770 BAD_PC_WRITEBACK);
c19d1205 7771 inst.instruction |= HWOFFSET_IMM;
e2b0ab59 7772 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
7773 {
7774 /* Prefer + for zero encoded value. */
7775 if (!inst.operands[i].negative)
7776 inst.instruction |= INDEX_UP;
7777
e2b0ab59 7778 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM8;
26d97720 7779 }
c19d1205 7780 }
a737bd4d
NC
7781}
7782
8335d6aa
JW
7783/* Write immediate bits [7:0] to the following locations:
7784
7785 |28/24|23 19|18 16|15 4|3 0|
7786 | 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|
7787
7788 This function is used by VMOV/VMVN/VORR/VBIC. */
7789
7790static void
7791neon_write_immbits (unsigned immbits)
7792{
7793 inst.instruction |= immbits & 0xf;
7794 inst.instruction |= ((immbits >> 4) & 0x7) << 16;
7795 inst.instruction |= ((immbits >> 7) & 0x1) << (thumb_mode ? 28 : 24);
7796}
7797
7798/* Invert low-order SIZE bits of XHI:XLO. */
7799
7800static void
7801neon_invert_size (unsigned *xlo, unsigned *xhi, int size)
7802{
7803 unsigned immlo = xlo ? *xlo : 0;
7804 unsigned immhi = xhi ? *xhi : 0;
7805
7806 switch (size)
7807 {
7808 case 8:
7809 immlo = (~immlo) & 0xff;
7810 break;
7811
7812 case 16:
7813 immlo = (~immlo) & 0xffff;
7814 break;
7815
7816 case 64:
7817 immhi = (~immhi) & 0xffffffff;
7818 /* fall through. */
7819
7820 case 32:
7821 immlo = (~immlo) & 0xffffffff;
7822 break;
7823
7824 default:
7825 abort ();
7826 }
7827
7828 if (xlo)
7829 *xlo = immlo;
7830
7831 if (xhi)
7832 *xhi = immhi;
7833}
7834
7835/* True if IMM has form 0bAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD for bits
7836 A, B, C, D. */
09d92015 7837
c19d1205 7838static int
8335d6aa 7839neon_bits_same_in_bytes (unsigned imm)
09d92015 7840{
8335d6aa
JW
7841 return ((imm & 0x000000ff) == 0 || (imm & 0x000000ff) == 0x000000ff)
7842 && ((imm & 0x0000ff00) == 0 || (imm & 0x0000ff00) == 0x0000ff00)
7843 && ((imm & 0x00ff0000) == 0 || (imm & 0x00ff0000) == 0x00ff0000)
7844 && ((imm & 0xff000000) == 0 || (imm & 0xff000000) == 0xff000000);
7845}
a737bd4d 7846
8335d6aa 7847/* For immediate of above form, return 0bABCD. */
09d92015 7848
8335d6aa
JW
7849static unsigned
7850neon_squash_bits (unsigned imm)
7851{
7852 return (imm & 0x01) | ((imm & 0x0100) >> 7) | ((imm & 0x010000) >> 14)
7853 | ((imm & 0x01000000) >> 21);
7854}
7855
7856/* Compress quarter-float representation to 0b...000 abcdefgh. */
7857
7858static unsigned
7859neon_qfloat_bits (unsigned imm)
7860{
7861 return ((imm >> 19) & 0x7f) | ((imm >> 24) & 0x80);
7862}
7863
7864/* Returns CMODE. IMMBITS [7:0] is set to bits suitable for inserting into
7865 the instruction. *OP is passed as the initial value of the op field, and
7866 may be set to a different value depending on the constant (i.e.
7867 "MOV I64, 0bAAAAAAAABBBB..." which uses OP = 1 despite being MOV not
7868 MVN). If the immediate looks like a repeated pattern then also
7869 try smaller element sizes. */
7870
7871static int
7872neon_cmode_for_move_imm (unsigned immlo, unsigned immhi, int float_p,
7873 unsigned *immbits, int *op, int size,
7874 enum neon_el_type type)
7875{
7876 /* Only permit float immediates (including 0.0/-0.0) if the operand type is
7877 float. */
7878 if (type == NT_float && !float_p)
7879 return FAIL;
7880
7881 if (type == NT_float && is_quarter_float (immlo) && immhi == 0)
09d92015 7882 {
8335d6aa
JW
7883 if (size != 32 || *op == 1)
7884 return FAIL;
7885 *immbits = neon_qfloat_bits (immlo);
7886 return 0xf;
7887 }
7888
7889 if (size == 64)
7890 {
7891 if (neon_bits_same_in_bytes (immhi)
7892 && neon_bits_same_in_bytes (immlo))
c19d1205 7893 {
8335d6aa
JW
7894 if (*op == 1)
7895 return FAIL;
7896 *immbits = (neon_squash_bits (immhi) << 4)
7897 | neon_squash_bits (immlo);
7898 *op = 1;
7899 return 0xe;
c19d1205 7900 }
a737bd4d 7901
8335d6aa
JW
7902 if (immhi != immlo)
7903 return FAIL;
7904 }
a737bd4d 7905
8335d6aa 7906 if (size >= 32)
09d92015 7907 {
8335d6aa 7908 if (immlo == (immlo & 0x000000ff))
c19d1205 7909 {
8335d6aa
JW
7910 *immbits = immlo;
7911 return 0x0;
c19d1205 7912 }
8335d6aa 7913 else if (immlo == (immlo & 0x0000ff00))
c19d1205 7914 {
8335d6aa
JW
7915 *immbits = immlo >> 8;
7916 return 0x2;
c19d1205 7917 }
8335d6aa
JW
7918 else if (immlo == (immlo & 0x00ff0000))
7919 {
7920 *immbits = immlo >> 16;
7921 return 0x4;
7922 }
7923 else if (immlo == (immlo & 0xff000000))
7924 {
7925 *immbits = immlo >> 24;
7926 return 0x6;
7927 }
7928 else if (immlo == ((immlo & 0x0000ff00) | 0x000000ff))
7929 {
7930 *immbits = (immlo >> 8) & 0xff;
7931 return 0xc;
7932 }
7933 else if (immlo == ((immlo & 0x00ff0000) | 0x0000ffff))
7934 {
7935 *immbits = (immlo >> 16) & 0xff;
7936 return 0xd;
7937 }
7938
7939 if ((immlo & 0xffff) != (immlo >> 16))
7940 return FAIL;
7941 immlo &= 0xffff;
09d92015 7942 }
a737bd4d 7943
8335d6aa 7944 if (size >= 16)
4962c51a 7945 {
8335d6aa
JW
7946 if (immlo == (immlo & 0x000000ff))
7947 {
7948 *immbits = immlo;
7949 return 0x8;
7950 }
7951 else if (immlo == (immlo & 0x0000ff00))
7952 {
7953 *immbits = immlo >> 8;
7954 return 0xa;
7955 }
7956
7957 if ((immlo & 0xff) != (immlo >> 8))
7958 return FAIL;
7959 immlo &= 0xff;
4962c51a
MS
7960 }
7961
8335d6aa
JW
7962 if (immlo == (immlo & 0x000000ff))
7963 {
7964 /* Don't allow MVN with 8-bit immediate. */
7965 if (*op == 1)
7966 return FAIL;
7967 *immbits = immlo;
7968 return 0xe;
7969 }
26d97720 7970
8335d6aa 7971 return FAIL;
c19d1205 7972}
a737bd4d 7973
5fc177c8 7974#if defined BFD_HOST_64_BIT
ba592044
AM
7975/* Returns TRUE if double precision value V may be cast
7976 to single precision without loss of accuracy. */
7977
7978static bfd_boolean
5fc177c8 7979is_double_a_single (bfd_int64_t v)
ba592044 7980{
5fc177c8 7981 int exp = (int)((v >> 52) & 0x7FF);
8fe3f3d6 7982 bfd_int64_t mantissa = (v & (bfd_int64_t)0xFFFFFFFFFFFFFULL);
ba592044
AM
7983
7984 return (exp == 0 || exp == 0x7FF
7985 || (exp >= 1023 - 126 && exp <= 1023 + 127))
7986 && (mantissa & 0x1FFFFFFFl) == 0;
7987}
7988
3739860c 7989/* Returns a double precision value casted to single precision
ba592044
AM
7990 (ignoring the least significant bits in exponent and mantissa). */
7991
7992static int
5fc177c8 7993double_to_single (bfd_int64_t v)
ba592044
AM
7994{
7995 int sign = (int) ((v >> 63) & 1l);
5fc177c8 7996 int exp = (int) ((v >> 52) & 0x7FF);
8fe3f3d6 7997 bfd_int64_t mantissa = (v & (bfd_int64_t)0xFFFFFFFFFFFFFULL);
ba592044
AM
7998
7999 if (exp == 0x7FF)
8000 exp = 0xFF;
8001 else
8002 {
8003 exp = exp - 1023 + 127;
8004 if (exp >= 0xFF)
8005 {
8006 /* Infinity. */
8007 exp = 0x7F;
8008 mantissa = 0;
8009 }
8010 else if (exp < 0)
8011 {
8012 /* No denormalized numbers. */
8013 exp = 0;
8014 mantissa = 0;
8015 }
8016 }
8017 mantissa >>= 29;
8018 return (sign << 31) | (exp << 23) | mantissa;
8019}
5fc177c8 8020#endif /* BFD_HOST_64_BIT */
ba592044 8021
8335d6aa
JW
8022enum lit_type
8023{
8024 CONST_THUMB,
8025 CONST_ARM,
8026 CONST_VEC
8027};
8028
ba592044
AM
8029static void do_vfp_nsyn_opcode (const char *);
8030
e2b0ab59 8031/* inst.relocs[0].exp describes an "=expr" load pseudo-operation.
c19d1205
ZW
8032 Determine whether it can be performed with a move instruction; if
8033 it can, convert inst.instruction to that move instruction and
c921be7d
NC
8034 return TRUE; if it can't, convert inst.instruction to a literal-pool
8035 load and return FALSE. If this is not a valid thing to do in the
8036 current context, set inst.error and return TRUE.
a737bd4d 8037
c19d1205
ZW
8038 inst.operands[i] describes the destination register. */
8039
c921be7d 8040static bfd_boolean
8335d6aa 8041move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
c19d1205 8042{
53365c0d 8043 unsigned long tbit;
8335d6aa
JW
8044 bfd_boolean thumb_p = (t == CONST_THUMB);
8045 bfd_boolean arm_p = (t == CONST_ARM);
53365c0d
PB
8046
8047 if (thumb_p)
8048 tbit = (inst.instruction > 0xffff) ? THUMB2_LOAD_BIT : THUMB_LOAD_BIT;
8049 else
8050 tbit = LOAD_BIT;
8051
8052 if ((inst.instruction & tbit) == 0)
09d92015 8053 {
c19d1205 8054 inst.error = _("invalid pseudo operation");
c921be7d 8055 return TRUE;
09d92015 8056 }
ba592044 8057
e2b0ab59
AV
8058 if (inst.relocs[0].exp.X_op != O_constant
8059 && inst.relocs[0].exp.X_op != O_symbol
8060 && inst.relocs[0].exp.X_op != O_big)
09d92015
MM
8061 {
8062 inst.error = _("constant expression expected");
c921be7d 8063 return TRUE;
09d92015 8064 }
ba592044 8065
e2b0ab59
AV
8066 if (inst.relocs[0].exp.X_op == O_constant
8067 || inst.relocs[0].exp.X_op == O_big)
8335d6aa 8068 {
5fc177c8
NC
8069#if defined BFD_HOST_64_BIT
8070 bfd_int64_t v;
8071#else
ba592044 8072 offsetT v;
5fc177c8 8073#endif
e2b0ab59 8074 if (inst.relocs[0].exp.X_op == O_big)
8335d6aa 8075 {
ba592044
AM
8076 LITTLENUM_TYPE w[X_PRECISION];
8077 LITTLENUM_TYPE * l;
8078
e2b0ab59 8079 if (inst.relocs[0].exp.X_add_number == -1)
8335d6aa 8080 {
ba592044
AM
8081 gen_to_words (w, X_PRECISION, E_PRECISION);
8082 l = w;
8083 /* FIXME: Should we check words w[2..5] ? */
8335d6aa 8084 }
ba592044
AM
8085 else
8086 l = generic_bignum;
3739860c 8087
5fc177c8
NC
8088#if defined BFD_HOST_64_BIT
8089 v =
8090 ((((((((bfd_int64_t) l[3] & LITTLENUM_MASK)
8091 << LITTLENUM_NUMBER_OF_BITS)
8092 | ((bfd_int64_t) l[2] & LITTLENUM_MASK))
8093 << LITTLENUM_NUMBER_OF_BITS)
8094 | ((bfd_int64_t) l[1] & LITTLENUM_MASK))
8095 << LITTLENUM_NUMBER_OF_BITS)
8096 | ((bfd_int64_t) l[0] & LITTLENUM_MASK));
8097#else
ba592044
AM
8098 v = ((l[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
8099 | (l[0] & LITTLENUM_MASK);
5fc177c8 8100#endif
8335d6aa 8101 }
ba592044 8102 else
e2b0ab59 8103 v = inst.relocs[0].exp.X_add_number;
ba592044
AM
8104
8105 if (!inst.operands[i].issingle)
8335d6aa 8106 {
12569877 8107 if (thumb_p)
8335d6aa 8108 {
53445554
TP
8109 /* LDR should not use lead in a flag-setting instruction being
8110 chosen so we do not check whether movs can be used. */
12569877 8111
53445554 8112 if ((ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
ff8646ee 8113 || ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
53445554
TP
8114 && inst.operands[i].reg != 13
8115 && inst.operands[i].reg != 15)
12569877 8116 {
fc289b0a
TP
8117 /* Check if on thumb2 it can be done with a mov.w, mvn or
8118 movw instruction. */
12569877
AM
8119 unsigned int newimm;
8120 bfd_boolean isNegated;
8121
8122 newimm = encode_thumb32_immediate (v);
8123 if (newimm != (unsigned int) FAIL)
8124 isNegated = FALSE;
8125 else
8126 {
582cfe03 8127 newimm = encode_thumb32_immediate (~v);
12569877
AM
8128 if (newimm != (unsigned int) FAIL)
8129 isNegated = TRUE;
8130 }
8131
fc289b0a
TP
8132 /* The number can be loaded with a mov.w or mvn
8133 instruction. */
ff8646ee
TP
8134 if (newimm != (unsigned int) FAIL
8135 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
12569877 8136 {
fc289b0a 8137 inst.instruction = (0xf04f0000 /* MOV.W. */
582cfe03 8138 | (inst.operands[i].reg << 8));
fc289b0a 8139 /* Change to MOVN. */
582cfe03 8140 inst.instruction |= (isNegated ? 0x200000 : 0);
12569877
AM
8141 inst.instruction |= (newimm & 0x800) << 15;
8142 inst.instruction |= (newimm & 0x700) << 4;
8143 inst.instruction |= (newimm & 0x0ff);
8144 return TRUE;
8145 }
fc289b0a 8146 /* The number can be loaded with a movw instruction. */
ff8646ee
TP
8147 else if ((v & ~0xFFFF) == 0
8148 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
3739860c 8149 {
582cfe03 8150 int imm = v & 0xFFFF;
12569877 8151
582cfe03 8152 inst.instruction = 0xf2400000; /* MOVW. */
12569877
AM
8153 inst.instruction |= (inst.operands[i].reg << 8);
8154 inst.instruction |= (imm & 0xf000) << 4;
8155 inst.instruction |= (imm & 0x0800) << 15;
8156 inst.instruction |= (imm & 0x0700) << 4;
8157 inst.instruction |= (imm & 0x00ff);
8158 return TRUE;
8159 }
8160 }
8335d6aa 8161 }
12569877 8162 else if (arm_p)
ba592044
AM
8163 {
8164 int value = encode_arm_immediate (v);
12569877 8165
ba592044
AM
8166 if (value != FAIL)
8167 {
8168 /* This can be done with a mov instruction. */
8169 inst.instruction &= LITERAL_MASK;
8170 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
8171 inst.instruction |= value & 0xfff;
8172 return TRUE;
8173 }
8335d6aa 8174
ba592044
AM
8175 value = encode_arm_immediate (~ v);
8176 if (value != FAIL)
8177 {
8178 /* This can be done with a mvn instruction. */
8179 inst.instruction &= LITERAL_MASK;
8180 inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
8181 inst.instruction |= value & 0xfff;
8182 return TRUE;
8183 }
8184 }
934c2632 8185 else if (t == CONST_VEC && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
8335d6aa 8186 {
ba592044
AM
8187 int op = 0;
8188 unsigned immbits = 0;
8189 unsigned immlo = inst.operands[1].imm;
8190 unsigned immhi = inst.operands[1].regisimm
8191 ? inst.operands[1].reg
e2b0ab59 8192 : inst.relocs[0].exp.X_unsigned
ba592044
AM
8193 ? 0
8194 : ((bfd_int64_t)((int) immlo)) >> 32;
8195 int cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
8196 &op, 64, NT_invtype);
8197
8198 if (cmode == FAIL)
8199 {
8200 neon_invert_size (&immlo, &immhi, 64);
8201 op = !op;
8202 cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
8203 &op, 64, NT_invtype);
8204 }
8205
8206 if (cmode != FAIL)
8207 {
8208 inst.instruction = (inst.instruction & VLDR_VMOV_SAME)
8209 | (1 << 23)
8210 | (cmode << 8)
8211 | (op << 5)
8212 | (1 << 4);
8213
8214 /* Fill other bits in vmov encoding for both thumb and arm. */
8215 if (thumb_mode)
eff0bc54 8216 inst.instruction |= (0x7U << 29) | (0xF << 24);
ba592044 8217 else
eff0bc54 8218 inst.instruction |= (0xFU << 28) | (0x1 << 25);
ba592044
AM
8219 neon_write_immbits (immbits);
8220 return TRUE;
8221 }
8335d6aa
JW
8222 }
8223 }
8335d6aa 8224
ba592044
AM
8225 if (t == CONST_VEC)
8226 {
8227 /* Check if vldr Rx, =constant could be optimized to vmov Rx, #constant. */
8228 if (inst.operands[i].issingle
8229 && is_quarter_float (inst.operands[1].imm)
8230 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3xd))
8335d6aa 8231 {
ba592044
AM
8232 inst.operands[1].imm =
8233 neon_qfloat_bits (v);
8234 do_vfp_nsyn_opcode ("fconsts");
8235 return TRUE;
8335d6aa 8236 }
5fc177c8
NC
8237
8238 /* If our host does not support a 64-bit type then we cannot perform
8239 the following optimization. This mean that there will be a
8240 discrepancy between the output produced by an assembler built for
8241 a 32-bit-only host and the output produced from a 64-bit host, but
8242 this cannot be helped. */
8243#if defined BFD_HOST_64_BIT
ba592044
AM
8244 else if (!inst.operands[1].issingle
8245 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3))
8335d6aa 8246 {
ba592044
AM
8247 if (is_double_a_single (v)
8248 && is_quarter_float (double_to_single (v)))
8249 {
8250 inst.operands[1].imm =
8251 neon_qfloat_bits (double_to_single (v));
8252 do_vfp_nsyn_opcode ("fconstd");
8253 return TRUE;
8254 }
8335d6aa 8255 }
5fc177c8 8256#endif
8335d6aa
JW
8257 }
8258 }
8259
8260 if (add_to_lit_pool ((!inst.operands[i].isvec
8261 || inst.operands[i].issingle) ? 4 : 8) == FAIL)
8262 return TRUE;
8263
8264 inst.operands[1].reg = REG_PC;
8265 inst.operands[1].isreg = 1;
8266 inst.operands[1].preind = 1;
e2b0ab59
AV
8267 inst.relocs[0].pc_rel = 1;
8268 inst.relocs[0].type = (thumb_p
8335d6aa
JW
8269 ? BFD_RELOC_ARM_THUMB_OFFSET
8270 : (mode_3
8271 ? BFD_RELOC_ARM_HWLITERAL
8272 : BFD_RELOC_ARM_LITERAL));
8273 return FALSE;
8274}
8275
8276/* inst.operands[i] was set up by parse_address. Encode it into an
8277 ARM-format instruction. Reject all forms which cannot be encoded
8278 into a coprocessor load/store instruction. If wb_ok is false,
8279 reject use of writeback; if unind_ok is false, reject use of
8280 unindexed addressing. If reloc_override is not 0, use it instead
8281 of BFD_ARM_CP_OFF_IMM, unless the initial relocation is a group one
8282 (in which case it is preserved). */
8283
8284static int
8285encode_arm_cp_address (int i, int wb_ok, int unind_ok, int reloc_override)
8286{
8287 if (!inst.operands[i].isreg)
8288 {
99b2a2dd
NC
8289 /* PR 18256 */
8290 if (! inst.operands[0].isvec)
8291 {
8292 inst.error = _("invalid co-processor operand");
8293 return FAIL;
8294 }
8335d6aa
JW
8295 if (move_or_literal_pool (0, CONST_VEC, /*mode_3=*/FALSE))
8296 return SUCCESS;
8297 }
8298
8299 inst.instruction |= inst.operands[i].reg << 16;
8300
8301 gas_assert (!(inst.operands[i].preind && inst.operands[i].postind));
8302
8303 if (!inst.operands[i].preind && !inst.operands[i].postind) /* unindexed */
8304 {
8305 gas_assert (!inst.operands[i].writeback);
8306 if (!unind_ok)
8307 {
8308 inst.error = _("instruction does not support unindexed addressing");
8309 return FAIL;
8310 }
8311 inst.instruction |= inst.operands[i].imm;
8312 inst.instruction |= INDEX_UP;
8313 return SUCCESS;
8314 }
8315
8316 if (inst.operands[i].preind)
8317 inst.instruction |= PRE_INDEX;
8318
8319 if (inst.operands[i].writeback)
09d92015 8320 {
8335d6aa 8321 if (inst.operands[i].reg == REG_PC)
c19d1205 8322 {
8335d6aa
JW
8323 inst.error = _("pc may not be used with write-back");
8324 return FAIL;
c19d1205 8325 }
8335d6aa 8326 if (!wb_ok)
c19d1205 8327 {
8335d6aa
JW
8328 inst.error = _("instruction does not support writeback");
8329 return FAIL;
c19d1205 8330 }
8335d6aa 8331 inst.instruction |= WRITE_BACK;
09d92015
MM
8332 }
8333
8335d6aa 8334 if (reloc_override)
e2b0ab59
AV
8335 inst.relocs[0].type = (bfd_reloc_code_real_type) reloc_override;
8336 else if ((inst.relocs[0].type < BFD_RELOC_ARM_ALU_PC_G0_NC
8337 || inst.relocs[0].type > BFD_RELOC_ARM_LDC_SB_G2)
8338 && inst.relocs[0].type != BFD_RELOC_ARM_LDR_PC_G0)
c19d1205 8339 {
8335d6aa 8340 if (thumb_mode)
e2b0ab59 8341 inst.relocs[0].type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
8335d6aa 8342 else
e2b0ab59 8343 inst.relocs[0].type = BFD_RELOC_ARM_CP_OFF_IMM;
c19d1205 8344 }
8335d6aa
JW
8345
8346 /* Prefer + for zero encoded value. */
8347 if (!inst.operands[i].negative)
8348 inst.instruction |= INDEX_UP;
8349
8350 return SUCCESS;
09d92015
MM
8351}
8352
5f4273c7 8353/* Functions for instruction encoding, sorted by sub-architecture.
c19d1205
ZW
8354 First some generics; their names are taken from the conventional
8355 bit positions for register arguments in ARM format instructions. */
09d92015 8356
a737bd4d 8357static void
c19d1205 8358do_noargs (void)
09d92015 8359{
c19d1205 8360}
a737bd4d 8361
c19d1205
ZW
8362static void
8363do_rd (void)
8364{
8365 inst.instruction |= inst.operands[0].reg << 12;
8366}
a737bd4d 8367
16a1fa25
TP
8368static void
8369do_rn (void)
8370{
8371 inst.instruction |= inst.operands[0].reg << 16;
8372}
8373
c19d1205
ZW
8374static void
8375do_rd_rm (void)
8376{
8377 inst.instruction |= inst.operands[0].reg << 12;
8378 inst.instruction |= inst.operands[1].reg;
8379}
09d92015 8380
9eb6c0f1
MGD
8381static void
8382do_rm_rn (void)
8383{
8384 inst.instruction |= inst.operands[0].reg;
8385 inst.instruction |= inst.operands[1].reg << 16;
8386}
8387
c19d1205
ZW
8388static void
8389do_rd_rn (void)
8390{
8391 inst.instruction |= inst.operands[0].reg << 12;
8392 inst.instruction |= inst.operands[1].reg << 16;
8393}
a737bd4d 8394
c19d1205
ZW
8395static void
8396do_rn_rd (void)
8397{
8398 inst.instruction |= inst.operands[0].reg << 16;
8399 inst.instruction |= inst.operands[1].reg << 12;
8400}
09d92015 8401
4ed7ed8d
TP
8402static void
8403do_tt (void)
8404{
8405 inst.instruction |= inst.operands[0].reg << 8;
8406 inst.instruction |= inst.operands[1].reg << 16;
8407}
8408
59d09be6
MGD
8409static bfd_boolean
8410check_obsolete (const arm_feature_set *feature, const char *msg)
8411{
8412 if (ARM_CPU_IS_ANY (cpu_variant))
8413 {
5c3696f8 8414 as_tsktsk ("%s", msg);
59d09be6
MGD
8415 return TRUE;
8416 }
8417 else if (ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
8418 {
8419 as_bad ("%s", msg);
8420 return TRUE;
8421 }
8422
8423 return FALSE;
8424}
8425
c19d1205
ZW
8426static void
8427do_rd_rm_rn (void)
8428{
9a64e435 8429 unsigned Rn = inst.operands[2].reg;
708587a4 8430 /* Enforce restrictions on SWP instruction. */
9a64e435 8431 if ((inst.instruction & 0x0fbfffff) == 0x01000090)
56adecf4
DG
8432 {
8433 constraint (Rn == inst.operands[0].reg || Rn == inst.operands[1].reg,
8434 _("Rn must not overlap other operands"));
8435
59d09be6
MGD
8436 /* SWP{b} is obsolete for ARMv8-A, and deprecated for ARMv6* and ARMv7.
8437 */
8438 if (!check_obsolete (&arm_ext_v8,
8439 _("swp{b} use is obsoleted for ARMv8 and later"))
8440 && warn_on_deprecated
8441 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6))
5c3696f8 8442 as_tsktsk (_("swp{b} use is deprecated for ARMv6 and ARMv7"));
56adecf4 8443 }
59d09be6 8444
c19d1205
ZW
8445 inst.instruction |= inst.operands[0].reg << 12;
8446 inst.instruction |= inst.operands[1].reg;
9a64e435 8447 inst.instruction |= Rn << 16;
c19d1205 8448}
09d92015 8449
c19d1205
ZW
8450static void
8451do_rd_rn_rm (void)
8452{
8453 inst.instruction |= inst.operands[0].reg << 12;
8454 inst.instruction |= inst.operands[1].reg << 16;
8455 inst.instruction |= inst.operands[2].reg;
8456}
a737bd4d 8457
c19d1205
ZW
8458static void
8459do_rm_rd_rn (void)
8460{
5be8be5d 8461 constraint ((inst.operands[2].reg == REG_PC), BAD_PC);
e2b0ab59
AV
8462 constraint (((inst.relocs[0].exp.X_op != O_constant
8463 && inst.relocs[0].exp.X_op != O_illegal)
8464 || inst.relocs[0].exp.X_add_number != 0),
5be8be5d 8465 BAD_ADDR_MODE);
c19d1205
ZW
8466 inst.instruction |= inst.operands[0].reg;
8467 inst.instruction |= inst.operands[1].reg << 12;
8468 inst.instruction |= inst.operands[2].reg << 16;
8469}
09d92015 8470
c19d1205
ZW
8471static void
8472do_imm0 (void)
8473{
8474 inst.instruction |= inst.operands[0].imm;
8475}
09d92015 8476
c19d1205
ZW
8477static void
8478do_rd_cpaddr (void)
8479{
8480 inst.instruction |= inst.operands[0].reg << 12;
8481 encode_arm_cp_address (1, TRUE, TRUE, 0);
09d92015 8482}
a737bd4d 8483
c19d1205
ZW
8484/* ARM instructions, in alphabetical order by function name (except
8485 that wrapper functions appear immediately after the function they
8486 wrap). */
09d92015 8487
c19d1205
ZW
8488/* This is a pseudo-op of the form "adr rd, label" to be converted
8489 into a relative address of the form "add rd, pc, #label-.-8". */
09d92015
MM
8490
8491static void
c19d1205 8492do_adr (void)
09d92015 8493{
c19d1205 8494 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 8495
c19d1205
ZW
8496 /* Frag hacking will turn this into a sub instruction if the offset turns
8497 out to be negative. */
e2b0ab59
AV
8498 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
8499 inst.relocs[0].pc_rel = 1;
8500 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 8501
fc6141f0 8502 if (support_interwork
e2b0ab59
AV
8503 && inst.relocs[0].exp.X_op == O_symbol
8504 && inst.relocs[0].exp.X_add_symbol != NULL
8505 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
8506 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
8507 inst.relocs[0].exp.X_add_number |= 1;
c19d1205 8508}
b99bd4ef 8509
c19d1205
ZW
8510/* This is a pseudo-op of the form "adrl rd, label" to be converted
8511 into a relative address of the form:
8512 add rd, pc, #low(label-.-8)"
8513 add rd, rd, #high(label-.-8)" */
b99bd4ef 8514
c19d1205
ZW
8515static void
8516do_adrl (void)
8517{
8518 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 8519
c19d1205
ZW
8520 /* Frag hacking will turn this into a sub instruction if the offset turns
8521 out to be negative. */
e2b0ab59
AV
8522 inst.relocs[0].type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
8523 inst.relocs[0].pc_rel = 1;
c19d1205 8524 inst.size = INSN_SIZE * 2;
e2b0ab59 8525 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 8526
fc6141f0 8527 if (support_interwork
e2b0ab59
AV
8528 && inst.relocs[0].exp.X_op == O_symbol
8529 && inst.relocs[0].exp.X_add_symbol != NULL
8530 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
8531 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
8532 inst.relocs[0].exp.X_add_number |= 1;
b99bd4ef
NC
8533}
8534
b99bd4ef 8535static void
c19d1205 8536do_arit (void)
b99bd4ef 8537{
e2b0ab59
AV
8538 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
8539 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 8540 THUMB1_RELOC_ONLY);
c19d1205
ZW
8541 if (!inst.operands[1].present)
8542 inst.operands[1].reg = inst.operands[0].reg;
8543 inst.instruction |= inst.operands[0].reg << 12;
8544 inst.instruction |= inst.operands[1].reg << 16;
8545 encode_arm_shifter_operand (2);
8546}
b99bd4ef 8547
62b3e311
PB
8548static void
8549do_barrier (void)
8550{
8551 if (inst.operands[0].present)
ccb84d65 8552 inst.instruction |= inst.operands[0].imm;
62b3e311
PB
8553 else
8554 inst.instruction |= 0xf;
8555}
8556
c19d1205
ZW
8557static void
8558do_bfc (void)
8559{
8560 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
8561 constraint (msb > 32, _("bit-field extends past end of register"));
8562 /* The instruction encoding stores the LSB and MSB,
8563 not the LSB and width. */
8564 inst.instruction |= inst.operands[0].reg << 12;
8565 inst.instruction |= inst.operands[1].imm << 7;
8566 inst.instruction |= (msb - 1) << 16;
8567}
b99bd4ef 8568
c19d1205
ZW
8569static void
8570do_bfi (void)
8571{
8572 unsigned int msb;
b99bd4ef 8573
c19d1205
ZW
8574 /* #0 in second position is alternative syntax for bfc, which is
8575 the same instruction but with REG_PC in the Rm field. */
8576 if (!inst.operands[1].isreg)
8577 inst.operands[1].reg = REG_PC;
b99bd4ef 8578
c19d1205
ZW
8579 msb = inst.operands[2].imm + inst.operands[3].imm;
8580 constraint (msb > 32, _("bit-field extends past end of register"));
8581 /* The instruction encoding stores the LSB and MSB,
8582 not the LSB and width. */
8583 inst.instruction |= inst.operands[0].reg << 12;
8584 inst.instruction |= inst.operands[1].reg;
8585 inst.instruction |= inst.operands[2].imm << 7;
8586 inst.instruction |= (msb - 1) << 16;
b99bd4ef
NC
8587}
8588
b99bd4ef 8589static void
c19d1205 8590do_bfx (void)
b99bd4ef 8591{
c19d1205
ZW
8592 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
8593 _("bit-field extends past end of register"));
8594 inst.instruction |= inst.operands[0].reg << 12;
8595 inst.instruction |= inst.operands[1].reg;
8596 inst.instruction |= inst.operands[2].imm << 7;
8597 inst.instruction |= (inst.operands[3].imm - 1) << 16;
8598}
09d92015 8599
c19d1205
ZW
8600/* ARM V5 breakpoint instruction (argument parse)
8601 BKPT <16 bit unsigned immediate>
8602 Instruction is not conditional.
8603 The bit pattern given in insns[] has the COND_ALWAYS condition,
8604 and it is an error if the caller tried to override that. */
b99bd4ef 8605
c19d1205
ZW
8606static void
8607do_bkpt (void)
8608{
8609 /* Top 12 of 16 bits to bits 19:8. */
8610 inst.instruction |= (inst.operands[0].imm & 0xfff0) << 4;
09d92015 8611
c19d1205
ZW
8612 /* Bottom 4 of 16 bits to bits 3:0. */
8613 inst.instruction |= inst.operands[0].imm & 0xf;
8614}
09d92015 8615
c19d1205
ZW
8616static void
8617encode_branch (int default_reloc)
8618{
8619 if (inst.operands[0].hasreloc)
8620 {
0855e32b
NS
8621 constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32
8622 && inst.operands[0].imm != BFD_RELOC_ARM_TLS_CALL,
8623 _("the only valid suffixes here are '(plt)' and '(tlscall)'"));
e2b0ab59 8624 inst.relocs[0].type = inst.operands[0].imm == BFD_RELOC_ARM_PLT32
0855e32b
NS
8625 ? BFD_RELOC_ARM_PLT32
8626 : thumb_mode ? BFD_RELOC_ARM_THM_TLS_CALL : BFD_RELOC_ARM_TLS_CALL;
c19d1205 8627 }
b99bd4ef 8628 else
e2b0ab59
AV
8629 inst.relocs[0].type = (bfd_reloc_code_real_type) default_reloc;
8630 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
8631}
8632
b99bd4ef 8633static void
c19d1205 8634do_branch (void)
b99bd4ef 8635{
39b41c9c
PB
8636#ifdef OBJ_ELF
8637 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
8638 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
8639 else
8640#endif
8641 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
8642}
8643
8644static void
8645do_bl (void)
8646{
8647#ifdef OBJ_ELF
8648 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
8649 {
8650 if (inst.cond == COND_ALWAYS)
8651 encode_branch (BFD_RELOC_ARM_PCREL_CALL);
8652 else
8653 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
8654 }
8655 else
8656#endif
8657 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
c19d1205 8658}
b99bd4ef 8659
c19d1205
ZW
8660/* ARM V5 branch-link-exchange instruction (argument parse)
8661 BLX <target_addr> ie BLX(1)
8662 BLX{<condition>} <Rm> ie BLX(2)
8663 Unfortunately, there are two different opcodes for this mnemonic.
8664 So, the insns[].value is not used, and the code here zaps values
8665 into inst.instruction.
8666 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
b99bd4ef 8667
c19d1205
ZW
8668static void
8669do_blx (void)
8670{
8671 if (inst.operands[0].isreg)
b99bd4ef 8672 {
c19d1205
ZW
8673 /* Arg is a register; the opcode provided by insns[] is correct.
8674 It is not illegal to do "blx pc", just useless. */
8675 if (inst.operands[0].reg == REG_PC)
8676 as_tsktsk (_("use of r15 in blx in ARM mode is not really useful"));
b99bd4ef 8677
c19d1205
ZW
8678 inst.instruction |= inst.operands[0].reg;
8679 }
8680 else
b99bd4ef 8681 {
c19d1205 8682 /* Arg is an address; this instruction cannot be executed
267bf995
RR
8683 conditionally, and the opcode must be adjusted.
8684 We retain the BFD_RELOC_ARM_PCREL_BLX till the very end
8685 where we generate out a BFD_RELOC_ARM_PCREL_CALL instead. */
c19d1205 8686 constraint (inst.cond != COND_ALWAYS, BAD_COND);
2fc8bdac 8687 inst.instruction = 0xfa000000;
267bf995 8688 encode_branch (BFD_RELOC_ARM_PCREL_BLX);
b99bd4ef 8689 }
c19d1205
ZW
8690}
8691
8692static void
8693do_bx (void)
8694{
845b51d6
PB
8695 bfd_boolean want_reloc;
8696
c19d1205
ZW
8697 if (inst.operands[0].reg == REG_PC)
8698 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
b99bd4ef 8699
c19d1205 8700 inst.instruction |= inst.operands[0].reg;
845b51d6
PB
8701 /* Output R_ARM_V4BX relocations if is an EABI object that looks like
8702 it is for ARMv4t or earlier. */
8703 want_reloc = !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5);
4d354d8b
TP
8704 if (!ARM_FEATURE_ZERO (selected_object_arch)
8705 && !ARM_CPU_HAS_FEATURE (selected_object_arch, arm_ext_v5))
845b51d6
PB
8706 want_reloc = TRUE;
8707
5ad34203 8708#ifdef OBJ_ELF
845b51d6 8709 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
5ad34203 8710#endif
584206db 8711 want_reloc = FALSE;
845b51d6
PB
8712
8713 if (want_reloc)
e2b0ab59 8714 inst.relocs[0].type = BFD_RELOC_ARM_V4BX;
09d92015
MM
8715}
8716
c19d1205
ZW
8717
8718/* ARM v5TEJ. Jump to Jazelle code. */
a737bd4d
NC
8719
8720static void
c19d1205 8721do_bxj (void)
a737bd4d 8722{
c19d1205
ZW
8723 if (inst.operands[0].reg == REG_PC)
8724 as_tsktsk (_("use of r15 in bxj is not really useful"));
8725
8726 inst.instruction |= inst.operands[0].reg;
a737bd4d
NC
8727}
8728
c19d1205
ZW
8729/* Co-processor data operation:
8730 CDP{cond} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>}
8731 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>} */
8732static void
8733do_cdp (void)
8734{
8735 inst.instruction |= inst.operands[0].reg << 8;
8736 inst.instruction |= inst.operands[1].imm << 20;
8737 inst.instruction |= inst.operands[2].reg << 12;
8738 inst.instruction |= inst.operands[3].reg << 16;
8739 inst.instruction |= inst.operands[4].reg;
8740 inst.instruction |= inst.operands[5].imm << 5;
8741}
a737bd4d
NC
8742
8743static void
c19d1205 8744do_cmp (void)
a737bd4d 8745{
c19d1205
ZW
8746 inst.instruction |= inst.operands[0].reg << 16;
8747 encode_arm_shifter_operand (1);
a737bd4d
NC
8748}
8749
c19d1205
ZW
8750/* Transfer between coprocessor and ARM registers.
8751 MRC{cond} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}
8752 MRC2
8753 MCR{cond}
8754 MCR2
8755
8756 No special properties. */
09d92015 8757
dcbd0d71
MGD
8758struct deprecated_coproc_regs_s
8759{
8760 unsigned cp;
8761 int opc1;
8762 unsigned crn;
8763 unsigned crm;
8764 int opc2;
8765 arm_feature_set deprecated;
8766 arm_feature_set obsoleted;
8767 const char *dep_msg;
8768 const char *obs_msg;
8769};
8770
8771#define DEPR_ACCESS_V8 \
8772 N_("This coprocessor register access is deprecated in ARMv8")
8773
8774/* Table of all deprecated coprocessor registers. */
8775static struct deprecated_coproc_regs_s deprecated_coproc_regs[] =
8776{
8777 {15, 0, 7, 10, 5, /* CP15DMB. */
823d2571 8778 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
8779 DEPR_ACCESS_V8, NULL},
8780 {15, 0, 7, 10, 4, /* CP15DSB. */
823d2571 8781 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
8782 DEPR_ACCESS_V8, NULL},
8783 {15, 0, 7, 5, 4, /* CP15ISB. */
823d2571 8784 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
8785 DEPR_ACCESS_V8, NULL},
8786 {14, 6, 1, 0, 0, /* TEEHBR. */
823d2571 8787 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
8788 DEPR_ACCESS_V8, NULL},
8789 {14, 6, 0, 0, 0, /* TEECR. */
823d2571 8790 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
8791 DEPR_ACCESS_V8, NULL},
8792};
8793
8794#undef DEPR_ACCESS_V8
8795
8796static const size_t deprecated_coproc_reg_count =
8797 sizeof (deprecated_coproc_regs) / sizeof (deprecated_coproc_regs[0]);
8798
09d92015 8799static void
c19d1205 8800do_co_reg (void)
09d92015 8801{
fdfde340 8802 unsigned Rd;
dcbd0d71 8803 size_t i;
fdfde340
JM
8804
8805 Rd = inst.operands[2].reg;
8806 if (thumb_mode)
8807 {
8808 if (inst.instruction == 0xee000010
8809 || inst.instruction == 0xfe000010)
8810 /* MCR, MCR2 */
8811 reject_bad_reg (Rd);
5c8ed6a4 8812 else if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
fdfde340
JM
8813 /* MRC, MRC2 */
8814 constraint (Rd == REG_SP, BAD_SP);
8815 }
8816 else
8817 {
8818 /* MCR */
8819 if (inst.instruction == 0xe000010)
8820 constraint (Rd == REG_PC, BAD_PC);
8821 }
8822
dcbd0d71
MGD
8823 for (i = 0; i < deprecated_coproc_reg_count; ++i)
8824 {
8825 const struct deprecated_coproc_regs_s *r =
8826 deprecated_coproc_regs + i;
8827
8828 if (inst.operands[0].reg == r->cp
8829 && inst.operands[1].imm == r->opc1
8830 && inst.operands[3].reg == r->crn
8831 && inst.operands[4].reg == r->crm
8832 && inst.operands[5].imm == r->opc2)
8833 {
b10bf8c5 8834 if (! ARM_CPU_IS_ANY (cpu_variant)
477330fc 8835 && warn_on_deprecated
dcbd0d71 8836 && ARM_CPU_HAS_FEATURE (cpu_variant, r->deprecated))
5c3696f8 8837 as_tsktsk ("%s", r->dep_msg);
dcbd0d71
MGD
8838 }
8839 }
fdfde340 8840
c19d1205
ZW
8841 inst.instruction |= inst.operands[0].reg << 8;
8842 inst.instruction |= inst.operands[1].imm << 21;
fdfde340 8843 inst.instruction |= Rd << 12;
c19d1205
ZW
8844 inst.instruction |= inst.operands[3].reg << 16;
8845 inst.instruction |= inst.operands[4].reg;
8846 inst.instruction |= inst.operands[5].imm << 5;
8847}
09d92015 8848
c19d1205
ZW
8849/* Transfer between coprocessor register and pair of ARM registers.
8850 MCRR{cond} <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
8851 MCRR2
8852 MRRC{cond}
8853 MRRC2
b99bd4ef 8854
c19d1205 8855 Two XScale instructions are special cases of these:
09d92015 8856
c19d1205
ZW
8857 MAR{cond} acc0, <RdLo>, <RdHi> == MCRR{cond} p0, #0, <RdLo>, <RdHi>, c0
8858 MRA{cond} acc0, <RdLo>, <RdHi> == MRRC{cond} p0, #0, <RdLo>, <RdHi>, c0
b99bd4ef 8859
5f4273c7 8860 Result unpredictable if Rd or Rn is R15. */
a737bd4d 8861
c19d1205
ZW
8862static void
8863do_co_reg2c (void)
8864{
fdfde340
JM
8865 unsigned Rd, Rn;
8866
8867 Rd = inst.operands[2].reg;
8868 Rn = inst.operands[3].reg;
8869
8870 if (thumb_mode)
8871 {
8872 reject_bad_reg (Rd);
8873 reject_bad_reg (Rn);
8874 }
8875 else
8876 {
8877 constraint (Rd == REG_PC, BAD_PC);
8878 constraint (Rn == REG_PC, BAD_PC);
8879 }
8880
873f10f0
TC
8881 /* Only check the MRRC{2} variants. */
8882 if ((inst.instruction & 0x0FF00000) == 0x0C500000)
8883 {
8884 /* If Rd == Rn, error that the operation is
8885 unpredictable (example MRRC p3,#1,r1,r1,c4). */
8886 constraint (Rd == Rn, BAD_OVERLAP);
8887 }
8888
c19d1205
ZW
8889 inst.instruction |= inst.operands[0].reg << 8;
8890 inst.instruction |= inst.operands[1].imm << 4;
fdfde340
JM
8891 inst.instruction |= Rd << 12;
8892 inst.instruction |= Rn << 16;
c19d1205 8893 inst.instruction |= inst.operands[4].reg;
b99bd4ef
NC
8894}
8895
c19d1205
ZW
8896static void
8897do_cpsi (void)
8898{
8899 inst.instruction |= inst.operands[0].imm << 6;
a028a6f5
PB
8900 if (inst.operands[1].present)
8901 {
8902 inst.instruction |= CPSI_MMOD;
8903 inst.instruction |= inst.operands[1].imm;
8904 }
c19d1205 8905}
b99bd4ef 8906
62b3e311
PB
8907static void
8908do_dbg (void)
8909{
8910 inst.instruction |= inst.operands[0].imm;
8911}
8912
eea54501
MGD
8913static void
8914do_div (void)
8915{
8916 unsigned Rd, Rn, Rm;
8917
8918 Rd = inst.operands[0].reg;
8919 Rn = (inst.operands[1].present
8920 ? inst.operands[1].reg : Rd);
8921 Rm = inst.operands[2].reg;
8922
8923 constraint ((Rd == REG_PC), BAD_PC);
8924 constraint ((Rn == REG_PC), BAD_PC);
8925 constraint ((Rm == REG_PC), BAD_PC);
8926
8927 inst.instruction |= Rd << 16;
8928 inst.instruction |= Rn << 0;
8929 inst.instruction |= Rm << 8;
8930}
8931
b99bd4ef 8932static void
c19d1205 8933do_it (void)
b99bd4ef 8934{
c19d1205 8935 /* There is no IT instruction in ARM mode. We
e07e6e58
NC
8936 process it to do the validation as if in
8937 thumb mode, just in case the code gets
8938 assembled for thumb using the unified syntax. */
8939
c19d1205 8940 inst.size = 0;
e07e6e58
NC
8941 if (unified_syntax)
8942 {
8943 set_it_insn_type (IT_INSN);
8944 now_it.mask = (inst.instruction & 0xf) | 0x10;
8945 now_it.cc = inst.operands[0].imm;
8946 }
09d92015 8947}
b99bd4ef 8948
6530b175
NC
8949/* If there is only one register in the register list,
8950 then return its register number. Otherwise return -1. */
8951static int
8952only_one_reg_in_list (int range)
8953{
8954 int i = ffs (range) - 1;
8955 return (i > 15 || range != (1 << i)) ? -1 : i;
8956}
8957
09d92015 8958static void
6530b175 8959encode_ldmstm(int from_push_pop_mnem)
ea6ef066 8960{
c19d1205
ZW
8961 int base_reg = inst.operands[0].reg;
8962 int range = inst.operands[1].imm;
6530b175 8963 int one_reg;
ea6ef066 8964
c19d1205
ZW
8965 inst.instruction |= base_reg << 16;
8966 inst.instruction |= range;
ea6ef066 8967
c19d1205
ZW
8968 if (inst.operands[1].writeback)
8969 inst.instruction |= LDM_TYPE_2_OR_3;
09d92015 8970
c19d1205 8971 if (inst.operands[0].writeback)
ea6ef066 8972 {
c19d1205
ZW
8973 inst.instruction |= WRITE_BACK;
8974 /* Check for unpredictable uses of writeback. */
8975 if (inst.instruction & LOAD_BIT)
09d92015 8976 {
c19d1205
ZW
8977 /* Not allowed in LDM type 2. */
8978 if ((inst.instruction & LDM_TYPE_2_OR_3)
8979 && ((range & (1 << REG_PC)) == 0))
8980 as_warn (_("writeback of base register is UNPREDICTABLE"));
8981 /* Only allowed if base reg not in list for other types. */
8982 else if (range & (1 << base_reg))
8983 as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
8984 }
8985 else /* STM. */
8986 {
8987 /* Not allowed for type 2. */
8988 if (inst.instruction & LDM_TYPE_2_OR_3)
8989 as_warn (_("writeback of base register is UNPREDICTABLE"));
8990 /* Only allowed if base reg not in list, or first in list. */
8991 else if ((range & (1 << base_reg))
8992 && (range & ((1 << base_reg) - 1)))
8993 as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
09d92015 8994 }
ea6ef066 8995 }
6530b175
NC
8996
8997 /* If PUSH/POP has only one register, then use the A2 encoding. */
8998 one_reg = only_one_reg_in_list (range);
8999 if (from_push_pop_mnem && one_reg >= 0)
9000 {
9001 int is_push = (inst.instruction & A_PUSH_POP_OP_MASK) == A1_OPCODE_PUSH;
9002
4f588891
NC
9003 if (is_push && one_reg == 13 /* SP */)
9004 /* PR 22483: The A2 encoding cannot be used when
9005 pushing the stack pointer as this is UNPREDICTABLE. */
9006 return;
9007
6530b175
NC
9008 inst.instruction &= A_COND_MASK;
9009 inst.instruction |= is_push ? A2_OPCODE_PUSH : A2_OPCODE_POP;
9010 inst.instruction |= one_reg << 12;
9011 }
9012}
9013
9014static void
9015do_ldmstm (void)
9016{
9017 encode_ldmstm (/*from_push_pop_mnem=*/FALSE);
a737bd4d
NC
9018}
9019
c19d1205
ZW
9020/* ARMv5TE load-consecutive (argument parse)
9021 Mode is like LDRH.
9022
9023 LDRccD R, mode
9024 STRccD R, mode. */
9025
a737bd4d 9026static void
c19d1205 9027do_ldrd (void)
a737bd4d 9028{
c19d1205 9029 constraint (inst.operands[0].reg % 2 != 0,
c56791bb 9030 _("first transfer register must be even"));
c19d1205
ZW
9031 constraint (inst.operands[1].present
9032 && inst.operands[1].reg != inst.operands[0].reg + 1,
c56791bb 9033 _("can only transfer two consecutive registers"));
c19d1205
ZW
9034 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
9035 constraint (!inst.operands[2].isreg, _("'[' expected"));
a737bd4d 9036
c19d1205
ZW
9037 if (!inst.operands[1].present)
9038 inst.operands[1].reg = inst.operands[0].reg + 1;
5f4273c7 9039
c56791bb
RE
9040 /* encode_arm_addr_mode_3 will diagnose overlap between the base
9041 register and the first register written; we have to diagnose
9042 overlap between the base and the second register written here. */
ea6ef066 9043
c56791bb
RE
9044 if (inst.operands[2].reg == inst.operands[1].reg
9045 && (inst.operands[2].writeback || inst.operands[2].postind))
9046 as_warn (_("base register written back, and overlaps "
9047 "second transfer register"));
b05fe5cf 9048
c56791bb
RE
9049 if (!(inst.instruction & V4_STR_BIT))
9050 {
c19d1205 9051 /* For an index-register load, the index register must not overlap the
c56791bb
RE
9052 destination (even if not write-back). */
9053 if (inst.operands[2].immisreg
9054 && ((unsigned) inst.operands[2].imm == inst.operands[0].reg
9055 || (unsigned) inst.operands[2].imm == inst.operands[1].reg))
9056 as_warn (_("index register overlaps transfer register"));
b05fe5cf 9057 }
c19d1205
ZW
9058 inst.instruction |= inst.operands[0].reg << 12;
9059 encode_arm_addr_mode_3 (2, /*is_t=*/FALSE);
b05fe5cf
ZW
9060}
9061
9062static void
c19d1205 9063do_ldrex (void)
b05fe5cf 9064{
c19d1205
ZW
9065 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
9066 || inst.operands[1].postind || inst.operands[1].writeback
9067 || inst.operands[1].immisreg || inst.operands[1].shifted
01cfc07f
NC
9068 || inst.operands[1].negative
9069 /* This can arise if the programmer has written
9070 strex rN, rM, foo
9071 or if they have mistakenly used a register name as the last
9072 operand, eg:
9073 strex rN, rM, rX
9074 It is very difficult to distinguish between these two cases
9075 because "rX" might actually be a label. ie the register
9076 name has been occluded by a symbol of the same name. So we
9077 just generate a general 'bad addressing mode' type error
9078 message and leave it up to the programmer to discover the
9079 true cause and fix their mistake. */
9080 || (inst.operands[1].reg == REG_PC),
9081 BAD_ADDR_MODE);
b05fe5cf 9082
e2b0ab59
AV
9083 constraint (inst.relocs[0].exp.X_op != O_constant
9084 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9085 _("offset must be zero in ARM encoding"));
b05fe5cf 9086
5be8be5d
DG
9087 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
9088
c19d1205
ZW
9089 inst.instruction |= inst.operands[0].reg << 12;
9090 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 9091 inst.relocs[0].type = BFD_RELOC_UNUSED;
b05fe5cf
ZW
9092}
9093
9094static void
c19d1205 9095do_ldrexd (void)
b05fe5cf 9096{
c19d1205
ZW
9097 constraint (inst.operands[0].reg % 2 != 0,
9098 _("even register required"));
9099 constraint (inst.operands[1].present
9100 && inst.operands[1].reg != inst.operands[0].reg + 1,
9101 _("can only load two consecutive registers"));
9102 /* If op 1 were present and equal to PC, this function wouldn't
9103 have been called in the first place. */
9104 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
b05fe5cf 9105
c19d1205
ZW
9106 inst.instruction |= inst.operands[0].reg << 12;
9107 inst.instruction |= inst.operands[2].reg << 16;
b05fe5cf
ZW
9108}
9109
1be5fd2e
NC
9110/* In both ARM and thumb state 'ldr pc, #imm' with an immediate
9111 which is not a multiple of four is UNPREDICTABLE. */
9112static void
9113check_ldr_r15_aligned (void)
9114{
9115 constraint (!(inst.operands[1].immisreg)
9116 && (inst.operands[0].reg == REG_PC
9117 && inst.operands[1].reg == REG_PC
e2b0ab59 9118 && (inst.relocs[0].exp.X_add_number & 0x3)),
de194d85 9119 _("ldr to register 15 must be 4-byte aligned"));
1be5fd2e
NC
9120}
9121
b05fe5cf 9122static void
c19d1205 9123do_ldst (void)
b05fe5cf 9124{
c19d1205
ZW
9125 inst.instruction |= inst.operands[0].reg << 12;
9126 if (!inst.operands[1].isreg)
8335d6aa 9127 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/FALSE))
b05fe5cf 9128 return;
c19d1205 9129 encode_arm_addr_mode_2 (1, /*is_t=*/FALSE);
1be5fd2e 9130 check_ldr_r15_aligned ();
b05fe5cf
ZW
9131}
9132
9133static void
c19d1205 9134do_ldstt (void)
b05fe5cf 9135{
c19d1205
ZW
9136 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
9137 reject [Rn,...]. */
9138 if (inst.operands[1].preind)
b05fe5cf 9139 {
e2b0ab59
AV
9140 constraint (inst.relocs[0].exp.X_op != O_constant
9141 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9142 _("this instruction requires a post-indexed address"));
b05fe5cf 9143
c19d1205
ZW
9144 inst.operands[1].preind = 0;
9145 inst.operands[1].postind = 1;
9146 inst.operands[1].writeback = 1;
b05fe5cf 9147 }
c19d1205
ZW
9148 inst.instruction |= inst.operands[0].reg << 12;
9149 encode_arm_addr_mode_2 (1, /*is_t=*/TRUE);
9150}
b05fe5cf 9151
c19d1205 9152/* Halfword and signed-byte load/store operations. */
b05fe5cf 9153
c19d1205
ZW
9154static void
9155do_ldstv4 (void)
9156{
ff4a8d2b 9157 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205
ZW
9158 inst.instruction |= inst.operands[0].reg << 12;
9159 if (!inst.operands[1].isreg)
8335d6aa 9160 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/TRUE))
b05fe5cf 9161 return;
c19d1205 9162 encode_arm_addr_mode_3 (1, /*is_t=*/FALSE);
b05fe5cf
ZW
9163}
9164
9165static void
c19d1205 9166do_ldsttv4 (void)
b05fe5cf 9167{
c19d1205
ZW
9168 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
9169 reject [Rn,...]. */
9170 if (inst.operands[1].preind)
b05fe5cf 9171 {
e2b0ab59
AV
9172 constraint (inst.relocs[0].exp.X_op != O_constant
9173 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9174 _("this instruction requires a post-indexed address"));
b05fe5cf 9175
c19d1205
ZW
9176 inst.operands[1].preind = 0;
9177 inst.operands[1].postind = 1;
9178 inst.operands[1].writeback = 1;
b05fe5cf 9179 }
c19d1205
ZW
9180 inst.instruction |= inst.operands[0].reg << 12;
9181 encode_arm_addr_mode_3 (1, /*is_t=*/TRUE);
9182}
b05fe5cf 9183
c19d1205
ZW
9184/* Co-processor register load/store.
9185 Format: <LDC|STC>{cond}[L] CP#,CRd,<address> */
9186static void
9187do_lstc (void)
9188{
9189 inst.instruction |= inst.operands[0].reg << 8;
9190 inst.instruction |= inst.operands[1].reg << 12;
9191 encode_arm_cp_address (2, TRUE, TRUE, 0);
b05fe5cf
ZW
9192}
9193
b05fe5cf 9194static void
c19d1205 9195do_mlas (void)
b05fe5cf 9196{
8fb9d7b9 9197 /* This restriction does not apply to mls (nor to mla in v6 or later). */
c19d1205 9198 if (inst.operands[0].reg == inst.operands[1].reg
8fb9d7b9 9199 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6)
c19d1205 9200 && !(inst.instruction & 0x00400000))
8fb9d7b9 9201 as_tsktsk (_("Rd and Rm should be different in mla"));
b05fe5cf 9202
c19d1205
ZW
9203 inst.instruction |= inst.operands[0].reg << 16;
9204 inst.instruction |= inst.operands[1].reg;
9205 inst.instruction |= inst.operands[2].reg << 8;
9206 inst.instruction |= inst.operands[3].reg << 12;
c19d1205 9207}
b05fe5cf 9208
c19d1205
ZW
9209static void
9210do_mov (void)
9211{
e2b0ab59
AV
9212 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
9213 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 9214 THUMB1_RELOC_ONLY);
c19d1205
ZW
9215 inst.instruction |= inst.operands[0].reg << 12;
9216 encode_arm_shifter_operand (1);
9217}
b05fe5cf 9218
c19d1205
ZW
9219/* ARM V6T2 16-bit immediate register load: MOV[WT]{cond} Rd, #<imm16>. */
9220static void
9221do_mov16 (void)
9222{
b6895b4f
PB
9223 bfd_vma imm;
9224 bfd_boolean top;
9225
9226 top = (inst.instruction & 0x00400000) != 0;
e2b0ab59 9227 constraint (top && inst.relocs[0].type == BFD_RELOC_ARM_MOVW,
33eaf5de 9228 _(":lower16: not allowed in this instruction"));
e2b0ab59 9229 constraint (!top && inst.relocs[0].type == BFD_RELOC_ARM_MOVT,
33eaf5de 9230 _(":upper16: not allowed in this instruction"));
c19d1205 9231 inst.instruction |= inst.operands[0].reg << 12;
e2b0ab59 9232 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 9233 {
e2b0ab59 9234 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
9235 /* The value is in two pieces: 0:11, 16:19. */
9236 inst.instruction |= (imm & 0x00000fff);
9237 inst.instruction |= (imm & 0x0000f000) << 4;
9238 }
b05fe5cf 9239}
b99bd4ef 9240
037e8744
JB
9241static int
9242do_vfp_nsyn_mrs (void)
9243{
9244 if (inst.operands[0].isvec)
9245 {
9246 if (inst.operands[1].reg != 1)
477330fc 9247 first_error (_("operand 1 must be FPSCR"));
037e8744
JB
9248 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
9249 memset (&inst.operands[1], '\0', sizeof (inst.operands[1]));
9250 do_vfp_nsyn_opcode ("fmstat");
9251 }
9252 else if (inst.operands[1].isvec)
9253 do_vfp_nsyn_opcode ("fmrx");
9254 else
9255 return FAIL;
5f4273c7 9256
037e8744
JB
9257 return SUCCESS;
9258}
9259
9260static int
9261do_vfp_nsyn_msr (void)
9262{
9263 if (inst.operands[0].isvec)
9264 do_vfp_nsyn_opcode ("fmxr");
9265 else
9266 return FAIL;
9267
9268 return SUCCESS;
9269}
9270
f7c21dc7
NC
9271static void
9272do_vmrs (void)
9273{
9274 unsigned Rt = inst.operands[0].reg;
fa94de6b 9275
16d02dc9 9276 if (thumb_mode && Rt == REG_SP)
f7c21dc7
NC
9277 {
9278 inst.error = BAD_SP;
9279 return;
9280 }
9281
40c7d507
RR
9282 /* MVFR2 is only valid at ARMv8-A. */
9283 if (inst.operands[1].reg == 5)
9284 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
9285 _(BAD_FPU));
9286
f7c21dc7 9287 /* APSR_ sets isvec. All other refs to PC are illegal. */
16d02dc9 9288 if (!inst.operands[0].isvec && Rt == REG_PC)
f7c21dc7
NC
9289 {
9290 inst.error = BAD_PC;
9291 return;
9292 }
9293
16d02dc9
JB
9294 /* If we get through parsing the register name, we just insert the number
9295 generated into the instruction without further validation. */
9296 inst.instruction |= (inst.operands[1].reg << 16);
f7c21dc7
NC
9297 inst.instruction |= (Rt << 12);
9298}
9299
9300static void
9301do_vmsr (void)
9302{
9303 unsigned Rt = inst.operands[1].reg;
fa94de6b 9304
f7c21dc7
NC
9305 if (thumb_mode)
9306 reject_bad_reg (Rt);
9307 else if (Rt == REG_PC)
9308 {
9309 inst.error = BAD_PC;
9310 return;
9311 }
9312
40c7d507
RR
9313 /* MVFR2 is only valid for ARMv8-A. */
9314 if (inst.operands[0].reg == 5)
9315 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
9316 _(BAD_FPU));
9317
16d02dc9
JB
9318 /* If we get through parsing the register name, we just insert the number
9319 generated into the instruction without further validation. */
9320 inst.instruction |= (inst.operands[0].reg << 16);
f7c21dc7
NC
9321 inst.instruction |= (Rt << 12);
9322}
9323
b99bd4ef 9324static void
c19d1205 9325do_mrs (void)
b99bd4ef 9326{
90ec0d68
MGD
9327 unsigned br;
9328
037e8744
JB
9329 if (do_vfp_nsyn_mrs () == SUCCESS)
9330 return;
9331
ff4a8d2b 9332 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205 9333 inst.instruction |= inst.operands[0].reg << 12;
90ec0d68
MGD
9334
9335 if (inst.operands[1].isreg)
9336 {
9337 br = inst.operands[1].reg;
806ab1c0 9338 if (((br & 0x200) == 0) && ((br & 0xf0000) != 0xf0000))
90ec0d68
MGD
9339 as_bad (_("bad register for mrs"));
9340 }
9341 else
9342 {
9343 /* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all. */
9344 constraint ((inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f))
9345 != (PSR_c|PSR_f),
d2cd1205 9346 _("'APSR', 'CPSR' or 'SPSR' expected"));
90ec0d68
MGD
9347 br = (15<<16) | (inst.operands[1].imm & SPSR_BIT);
9348 }
9349
9350 inst.instruction |= br;
c19d1205 9351}
b99bd4ef 9352
c19d1205
ZW
9353/* Two possible forms:
9354 "{C|S}PSR_<field>, Rm",
9355 "{C|S}PSR_f, #expression". */
b99bd4ef 9356
c19d1205
ZW
9357static void
9358do_msr (void)
9359{
037e8744
JB
9360 if (do_vfp_nsyn_msr () == SUCCESS)
9361 return;
9362
c19d1205
ZW
9363 inst.instruction |= inst.operands[0].imm;
9364 if (inst.operands[1].isreg)
9365 inst.instruction |= inst.operands[1].reg;
9366 else
b99bd4ef 9367 {
c19d1205 9368 inst.instruction |= INST_IMMEDIATE;
e2b0ab59
AV
9369 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
9370 inst.relocs[0].pc_rel = 0;
b99bd4ef 9371 }
b99bd4ef
NC
9372}
9373
c19d1205
ZW
9374static void
9375do_mul (void)
a737bd4d 9376{
ff4a8d2b
NC
9377 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
9378
c19d1205
ZW
9379 if (!inst.operands[2].present)
9380 inst.operands[2].reg = inst.operands[0].reg;
9381 inst.instruction |= inst.operands[0].reg << 16;
9382 inst.instruction |= inst.operands[1].reg;
9383 inst.instruction |= inst.operands[2].reg << 8;
a737bd4d 9384
8fb9d7b9
MS
9385 if (inst.operands[0].reg == inst.operands[1].reg
9386 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
9387 as_tsktsk (_("Rd and Rm should be different in mul"));
a737bd4d
NC
9388}
9389
c19d1205
ZW
9390/* Long Multiply Parser
9391 UMULL RdLo, RdHi, Rm, Rs
9392 SMULL RdLo, RdHi, Rm, Rs
9393 UMLAL RdLo, RdHi, Rm, Rs
9394 SMLAL RdLo, RdHi, Rm, Rs. */
b99bd4ef
NC
9395
9396static void
c19d1205 9397do_mull (void)
b99bd4ef 9398{
c19d1205
ZW
9399 inst.instruction |= inst.operands[0].reg << 12;
9400 inst.instruction |= inst.operands[1].reg << 16;
9401 inst.instruction |= inst.operands[2].reg;
9402 inst.instruction |= inst.operands[3].reg << 8;
b99bd4ef 9403
682b27ad
PB
9404 /* rdhi and rdlo must be different. */
9405 if (inst.operands[0].reg == inst.operands[1].reg)
9406 as_tsktsk (_("rdhi and rdlo must be different"));
9407
9408 /* rdhi, rdlo and rm must all be different before armv6. */
9409 if ((inst.operands[0].reg == inst.operands[2].reg
c19d1205 9410 || inst.operands[1].reg == inst.operands[2].reg)
682b27ad 9411 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
c19d1205
ZW
9412 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
9413}
b99bd4ef 9414
c19d1205
ZW
9415static void
9416do_nop (void)
9417{
e7495e45
NS
9418 if (inst.operands[0].present
9419 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6k))
c19d1205
ZW
9420 {
9421 /* Architectural NOP hints are CPSR sets with no bits selected. */
9422 inst.instruction &= 0xf0000000;
e7495e45
NS
9423 inst.instruction |= 0x0320f000;
9424 if (inst.operands[0].present)
9425 inst.instruction |= inst.operands[0].imm;
c19d1205 9426 }
b99bd4ef
NC
9427}
9428
c19d1205
ZW
9429/* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
9430 PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
9431 Condition defaults to COND_ALWAYS.
9432 Error if Rd, Rn or Rm are R15. */
b99bd4ef
NC
9433
9434static void
c19d1205 9435do_pkhbt (void)
b99bd4ef 9436{
c19d1205
ZW
9437 inst.instruction |= inst.operands[0].reg << 12;
9438 inst.instruction |= inst.operands[1].reg << 16;
9439 inst.instruction |= inst.operands[2].reg;
9440 if (inst.operands[3].present)
9441 encode_arm_shift (3);
9442}
b99bd4ef 9443
c19d1205 9444/* ARM V6 PKHTB (Argument Parse). */
b99bd4ef 9445
c19d1205
ZW
9446static void
9447do_pkhtb (void)
9448{
9449 if (!inst.operands[3].present)
b99bd4ef 9450 {
c19d1205
ZW
9451 /* If the shift specifier is omitted, turn the instruction
9452 into pkhbt rd, rm, rn. */
9453 inst.instruction &= 0xfff00010;
9454 inst.instruction |= inst.operands[0].reg << 12;
9455 inst.instruction |= inst.operands[1].reg;
9456 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
9457 }
9458 else
9459 {
c19d1205
ZW
9460 inst.instruction |= inst.operands[0].reg << 12;
9461 inst.instruction |= inst.operands[1].reg << 16;
9462 inst.instruction |= inst.operands[2].reg;
9463 encode_arm_shift (3);
b99bd4ef
NC
9464 }
9465}
9466
c19d1205 9467/* ARMv5TE: Preload-Cache
60e5ef9f 9468 MP Extensions: Preload for write
c19d1205 9469
60e5ef9f 9470 PLD(W) <addr_mode>
c19d1205
ZW
9471
9472 Syntactically, like LDR with B=1, W=0, L=1. */
b99bd4ef
NC
9473
9474static void
c19d1205 9475do_pld (void)
b99bd4ef 9476{
c19d1205
ZW
9477 constraint (!inst.operands[0].isreg,
9478 _("'[' expected after PLD mnemonic"));
9479 constraint (inst.operands[0].postind,
9480 _("post-indexed expression used in preload instruction"));
9481 constraint (inst.operands[0].writeback,
9482 _("writeback used in preload instruction"));
9483 constraint (!inst.operands[0].preind,
9484 _("unindexed addressing used in preload instruction"));
c19d1205
ZW
9485 encode_arm_addr_mode_2 (0, /*is_t=*/FALSE);
9486}
b99bd4ef 9487
62b3e311
PB
9488/* ARMv7: PLI <addr_mode> */
9489static void
9490do_pli (void)
9491{
9492 constraint (!inst.operands[0].isreg,
9493 _("'[' expected after PLI mnemonic"));
9494 constraint (inst.operands[0].postind,
9495 _("post-indexed expression used in preload instruction"));
9496 constraint (inst.operands[0].writeback,
9497 _("writeback used in preload instruction"));
9498 constraint (!inst.operands[0].preind,
9499 _("unindexed addressing used in preload instruction"));
9500 encode_arm_addr_mode_2 (0, /*is_t=*/FALSE);
9501 inst.instruction &= ~PRE_INDEX;
9502}
9503
c19d1205
ZW
9504static void
9505do_push_pop (void)
9506{
5e0d7f77
MP
9507 constraint (inst.operands[0].writeback,
9508 _("push/pop do not support {reglist}^"));
c19d1205
ZW
9509 inst.operands[1] = inst.operands[0];
9510 memset (&inst.operands[0], 0, sizeof inst.operands[0]);
9511 inst.operands[0].isreg = 1;
9512 inst.operands[0].writeback = 1;
9513 inst.operands[0].reg = REG_SP;
6530b175 9514 encode_ldmstm (/*from_push_pop_mnem=*/TRUE);
c19d1205 9515}
b99bd4ef 9516
c19d1205
ZW
9517/* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
9518 word at the specified address and the following word
9519 respectively.
9520 Unconditionally executed.
9521 Error if Rn is R15. */
b99bd4ef 9522
c19d1205
ZW
9523static void
9524do_rfe (void)
9525{
9526 inst.instruction |= inst.operands[0].reg << 16;
9527 if (inst.operands[0].writeback)
9528 inst.instruction |= WRITE_BACK;
9529}
b99bd4ef 9530
c19d1205 9531/* ARM V6 ssat (argument parse). */
b99bd4ef 9532
c19d1205
ZW
9533static void
9534do_ssat (void)
9535{
9536 inst.instruction |= inst.operands[0].reg << 12;
9537 inst.instruction |= (inst.operands[1].imm - 1) << 16;
9538 inst.instruction |= inst.operands[2].reg;
b99bd4ef 9539
c19d1205
ZW
9540 if (inst.operands[3].present)
9541 encode_arm_shift (3);
b99bd4ef
NC
9542}
9543
c19d1205 9544/* ARM V6 usat (argument parse). */
b99bd4ef
NC
9545
9546static void
c19d1205 9547do_usat (void)
b99bd4ef 9548{
c19d1205
ZW
9549 inst.instruction |= inst.operands[0].reg << 12;
9550 inst.instruction |= inst.operands[1].imm << 16;
9551 inst.instruction |= inst.operands[2].reg;
b99bd4ef 9552
c19d1205
ZW
9553 if (inst.operands[3].present)
9554 encode_arm_shift (3);
b99bd4ef
NC
9555}
9556
c19d1205 9557/* ARM V6 ssat16 (argument parse). */
09d92015
MM
9558
9559static void
c19d1205 9560do_ssat16 (void)
09d92015 9561{
c19d1205
ZW
9562 inst.instruction |= inst.operands[0].reg << 12;
9563 inst.instruction |= ((inst.operands[1].imm - 1) << 16);
9564 inst.instruction |= inst.operands[2].reg;
09d92015
MM
9565}
9566
c19d1205
ZW
9567static void
9568do_usat16 (void)
a737bd4d 9569{
c19d1205
ZW
9570 inst.instruction |= inst.operands[0].reg << 12;
9571 inst.instruction |= inst.operands[1].imm << 16;
9572 inst.instruction |= inst.operands[2].reg;
9573}
a737bd4d 9574
c19d1205
ZW
9575/* ARM V6 SETEND (argument parse). Sets the E bit in the CPSR while
9576 preserving the other bits.
a737bd4d 9577
c19d1205
ZW
9578 setend <endian_specifier>, where <endian_specifier> is either
9579 BE or LE. */
a737bd4d 9580
c19d1205
ZW
9581static void
9582do_setend (void)
9583{
12e37cbc
MGD
9584 if (warn_on_deprecated
9585 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 9586 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 9587
c19d1205
ZW
9588 if (inst.operands[0].imm)
9589 inst.instruction |= 0x200;
a737bd4d
NC
9590}
9591
9592static void
c19d1205 9593do_shift (void)
a737bd4d 9594{
c19d1205
ZW
9595 unsigned int Rm = (inst.operands[1].present
9596 ? inst.operands[1].reg
9597 : inst.operands[0].reg);
a737bd4d 9598
c19d1205
ZW
9599 inst.instruction |= inst.operands[0].reg << 12;
9600 inst.instruction |= Rm;
9601 if (inst.operands[2].isreg) /* Rd, {Rm,} Rs */
a737bd4d 9602 {
c19d1205
ZW
9603 inst.instruction |= inst.operands[2].reg << 8;
9604 inst.instruction |= SHIFT_BY_REG;
94342ec3
NC
9605 /* PR 12854: Error on extraneous shifts. */
9606 constraint (inst.operands[2].shifted,
9607 _("extraneous shift as part of operand to shift insn"));
a737bd4d
NC
9608 }
9609 else
e2b0ab59 9610 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
a737bd4d
NC
9611}
9612
09d92015 9613static void
3eb17e6b 9614do_smc (void)
09d92015 9615{
e2b0ab59
AV
9616 inst.relocs[0].type = BFD_RELOC_ARM_SMC;
9617 inst.relocs[0].pc_rel = 0;
09d92015
MM
9618}
9619
90ec0d68
MGD
9620static void
9621do_hvc (void)
9622{
e2b0ab59
AV
9623 inst.relocs[0].type = BFD_RELOC_ARM_HVC;
9624 inst.relocs[0].pc_rel = 0;
90ec0d68
MGD
9625}
9626
09d92015 9627static void
c19d1205 9628do_swi (void)
09d92015 9629{
e2b0ab59
AV
9630 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
9631 inst.relocs[0].pc_rel = 0;
09d92015
MM
9632}
9633
ddfded2f
MW
9634static void
9635do_setpan (void)
9636{
9637 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
9638 _("selected processor does not support SETPAN instruction"));
9639
9640 inst.instruction |= ((inst.operands[0].imm & 1) << 9);
9641}
9642
9643static void
9644do_t_setpan (void)
9645{
9646 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
9647 _("selected processor does not support SETPAN instruction"));
9648
9649 inst.instruction |= (inst.operands[0].imm << 3);
9650}
9651
c19d1205
ZW
9652/* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
9653 SMLAxy{cond} Rd,Rm,Rs,Rn
9654 SMLAWy{cond} Rd,Rm,Rs,Rn
9655 Error if any register is R15. */
e16bb312 9656
c19d1205
ZW
9657static void
9658do_smla (void)
e16bb312 9659{
c19d1205
ZW
9660 inst.instruction |= inst.operands[0].reg << 16;
9661 inst.instruction |= inst.operands[1].reg;
9662 inst.instruction |= inst.operands[2].reg << 8;
9663 inst.instruction |= inst.operands[3].reg << 12;
9664}
a737bd4d 9665
c19d1205
ZW
9666/* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
9667 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
9668 Error if any register is R15.
9669 Warning if Rdlo == Rdhi. */
a737bd4d 9670
c19d1205
ZW
9671static void
9672do_smlal (void)
9673{
9674 inst.instruction |= inst.operands[0].reg << 12;
9675 inst.instruction |= inst.operands[1].reg << 16;
9676 inst.instruction |= inst.operands[2].reg;
9677 inst.instruction |= inst.operands[3].reg << 8;
a737bd4d 9678
c19d1205
ZW
9679 if (inst.operands[0].reg == inst.operands[1].reg)
9680 as_tsktsk (_("rdhi and rdlo must be different"));
9681}
a737bd4d 9682
c19d1205
ZW
9683/* ARM V5E (El Segundo) signed-multiply (argument parse)
9684 SMULxy{cond} Rd,Rm,Rs
9685 Error if any register is R15. */
a737bd4d 9686
c19d1205
ZW
9687static void
9688do_smul (void)
9689{
9690 inst.instruction |= inst.operands[0].reg << 16;
9691 inst.instruction |= inst.operands[1].reg;
9692 inst.instruction |= inst.operands[2].reg << 8;
9693}
a737bd4d 9694
b6702015
PB
9695/* ARM V6 srs (argument parse). The variable fields in the encoding are
9696 the same for both ARM and Thumb-2. */
a737bd4d 9697
c19d1205
ZW
9698static void
9699do_srs (void)
9700{
b6702015
PB
9701 int reg;
9702
9703 if (inst.operands[0].present)
9704 {
9705 reg = inst.operands[0].reg;
fdfde340 9706 constraint (reg != REG_SP, _("SRS base register must be r13"));
b6702015
PB
9707 }
9708 else
fdfde340 9709 reg = REG_SP;
b6702015
PB
9710
9711 inst.instruction |= reg << 16;
9712 inst.instruction |= inst.operands[1].imm;
9713 if (inst.operands[0].writeback || inst.operands[1].writeback)
c19d1205
ZW
9714 inst.instruction |= WRITE_BACK;
9715}
a737bd4d 9716
c19d1205 9717/* ARM V6 strex (argument parse). */
a737bd4d 9718
c19d1205
ZW
9719static void
9720do_strex (void)
9721{
9722 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
9723 || inst.operands[2].postind || inst.operands[2].writeback
9724 || inst.operands[2].immisreg || inst.operands[2].shifted
01cfc07f
NC
9725 || inst.operands[2].negative
9726 /* See comment in do_ldrex(). */
9727 || (inst.operands[2].reg == REG_PC),
9728 BAD_ADDR_MODE);
a737bd4d 9729
c19d1205
ZW
9730 constraint (inst.operands[0].reg == inst.operands[1].reg
9731 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
a737bd4d 9732
e2b0ab59
AV
9733 constraint (inst.relocs[0].exp.X_op != O_constant
9734 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9735 _("offset must be zero in ARM encoding"));
a737bd4d 9736
c19d1205
ZW
9737 inst.instruction |= inst.operands[0].reg << 12;
9738 inst.instruction |= inst.operands[1].reg;
9739 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 9740 inst.relocs[0].type = BFD_RELOC_UNUSED;
e16bb312
NC
9741}
9742
877807f8
NC
9743static void
9744do_t_strexbh (void)
9745{
9746 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
9747 || inst.operands[2].postind || inst.operands[2].writeback
9748 || inst.operands[2].immisreg || inst.operands[2].shifted
9749 || inst.operands[2].negative,
9750 BAD_ADDR_MODE);
9751
9752 constraint (inst.operands[0].reg == inst.operands[1].reg
9753 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
9754
9755 do_rm_rd_rn ();
9756}
9757
e16bb312 9758static void
c19d1205 9759do_strexd (void)
e16bb312 9760{
c19d1205
ZW
9761 constraint (inst.operands[1].reg % 2 != 0,
9762 _("even register required"));
9763 constraint (inst.operands[2].present
9764 && inst.operands[2].reg != inst.operands[1].reg + 1,
9765 _("can only store two consecutive registers"));
9766 /* If op 2 were present and equal to PC, this function wouldn't
9767 have been called in the first place. */
9768 constraint (inst.operands[1].reg == REG_LR, _("r14 not allowed here"));
e16bb312 9769
c19d1205
ZW
9770 constraint (inst.operands[0].reg == inst.operands[1].reg
9771 || inst.operands[0].reg == inst.operands[1].reg + 1
9772 || inst.operands[0].reg == inst.operands[3].reg,
9773 BAD_OVERLAP);
e16bb312 9774
c19d1205
ZW
9775 inst.instruction |= inst.operands[0].reg << 12;
9776 inst.instruction |= inst.operands[1].reg;
9777 inst.instruction |= inst.operands[3].reg << 16;
e16bb312
NC
9778}
9779
9eb6c0f1
MGD
9780/* ARM V8 STRL. */
9781static void
4b8c8c02 9782do_stlex (void)
9eb6c0f1
MGD
9783{
9784 constraint (inst.operands[0].reg == inst.operands[1].reg
9785 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
9786
9787 do_rd_rm_rn ();
9788}
9789
9790static void
4b8c8c02 9791do_t_stlex (void)
9eb6c0f1
MGD
9792{
9793 constraint (inst.operands[0].reg == inst.operands[1].reg
9794 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
9795
9796 do_rm_rd_rn ();
9797}
9798
c19d1205
ZW
9799/* ARM V6 SXTAH extracts a 16-bit value from a register, sign
9800 extends it to 32-bits, and adds the result to a value in another
9801 register. You can specify a rotation by 0, 8, 16, or 24 bits
9802 before extracting the 16-bit value.
9803 SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
9804 Condition defaults to COND_ALWAYS.
9805 Error if any register uses R15. */
9806
e16bb312 9807static void
c19d1205 9808do_sxtah (void)
e16bb312 9809{
c19d1205
ZW
9810 inst.instruction |= inst.operands[0].reg << 12;
9811 inst.instruction |= inst.operands[1].reg << 16;
9812 inst.instruction |= inst.operands[2].reg;
9813 inst.instruction |= inst.operands[3].imm << 10;
9814}
e16bb312 9815
c19d1205 9816/* ARM V6 SXTH.
e16bb312 9817
c19d1205
ZW
9818 SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
9819 Condition defaults to COND_ALWAYS.
9820 Error if any register uses R15. */
e16bb312
NC
9821
9822static void
c19d1205 9823do_sxth (void)
e16bb312 9824{
c19d1205
ZW
9825 inst.instruction |= inst.operands[0].reg << 12;
9826 inst.instruction |= inst.operands[1].reg;
9827 inst.instruction |= inst.operands[2].imm << 10;
e16bb312 9828}
c19d1205
ZW
9829\f
9830/* VFP instructions. In a logical order: SP variant first, monad
9831 before dyad, arithmetic then move then load/store. */
e16bb312
NC
9832
9833static void
c19d1205 9834do_vfp_sp_monadic (void)
e16bb312 9835{
5287ad62
JB
9836 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
9837 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
9838}
9839
9840static void
c19d1205 9841do_vfp_sp_dyadic (void)
e16bb312 9842{
5287ad62
JB
9843 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
9844 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
9845 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
9846}
9847
9848static void
c19d1205 9849do_vfp_sp_compare_z (void)
e16bb312 9850{
5287ad62 9851 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
e16bb312
NC
9852}
9853
9854static void
c19d1205 9855do_vfp_dp_sp_cvt (void)
e16bb312 9856{
5287ad62
JB
9857 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
9858 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
9859}
9860
9861static void
c19d1205 9862do_vfp_sp_dp_cvt (void)
e16bb312 9863{
5287ad62
JB
9864 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
9865 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
e16bb312
NC
9866}
9867
9868static void
c19d1205 9869do_vfp_reg_from_sp (void)
e16bb312 9870{
c19d1205 9871 inst.instruction |= inst.operands[0].reg << 12;
5287ad62 9872 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
e16bb312
NC
9873}
9874
9875static void
c19d1205 9876do_vfp_reg2_from_sp2 (void)
e16bb312 9877{
c19d1205
ZW
9878 constraint (inst.operands[2].imm != 2,
9879 _("only two consecutive VFP SP registers allowed here"));
9880 inst.instruction |= inst.operands[0].reg << 12;
9881 inst.instruction |= inst.operands[1].reg << 16;
5287ad62 9882 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
9883}
9884
9885static void
c19d1205 9886do_vfp_sp_from_reg (void)
e16bb312 9887{
5287ad62 9888 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sn);
c19d1205 9889 inst.instruction |= inst.operands[1].reg << 12;
e16bb312
NC
9890}
9891
9892static void
c19d1205 9893do_vfp_sp2_from_reg2 (void)
e16bb312 9894{
c19d1205
ZW
9895 constraint (inst.operands[0].imm != 2,
9896 _("only two consecutive VFP SP registers allowed here"));
5287ad62 9897 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sm);
c19d1205
ZW
9898 inst.instruction |= inst.operands[1].reg << 12;
9899 inst.instruction |= inst.operands[2].reg << 16;
e16bb312
NC
9900}
9901
9902static void
c19d1205 9903do_vfp_sp_ldst (void)
e16bb312 9904{
5287ad62 9905 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
c19d1205 9906 encode_arm_cp_address (1, FALSE, TRUE, 0);
e16bb312
NC
9907}
9908
9909static void
c19d1205 9910do_vfp_dp_ldst (void)
e16bb312 9911{
5287ad62 9912 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
c19d1205 9913 encode_arm_cp_address (1, FALSE, TRUE, 0);
e16bb312
NC
9914}
9915
c19d1205 9916
e16bb312 9917static void
c19d1205 9918vfp_sp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 9919{
c19d1205
ZW
9920 if (inst.operands[0].writeback)
9921 inst.instruction |= WRITE_BACK;
9922 else
9923 constraint (ldstm_type != VFP_LDSTMIA,
9924 _("this addressing mode requires base-register writeback"));
9925 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 9926 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sd);
c19d1205 9927 inst.instruction |= inst.operands[1].imm;
e16bb312
NC
9928}
9929
9930static void
c19d1205 9931vfp_dp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 9932{
c19d1205 9933 int count;
e16bb312 9934
c19d1205
ZW
9935 if (inst.operands[0].writeback)
9936 inst.instruction |= WRITE_BACK;
9937 else
9938 constraint (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX,
9939 _("this addressing mode requires base-register writeback"));
e16bb312 9940
c19d1205 9941 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 9942 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
e16bb312 9943
c19d1205
ZW
9944 count = inst.operands[1].imm << 1;
9945 if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
9946 count += 1;
e16bb312 9947
c19d1205 9948 inst.instruction |= count;
e16bb312
NC
9949}
9950
9951static void
c19d1205 9952do_vfp_sp_ldstmia (void)
e16bb312 9953{
c19d1205 9954 vfp_sp_ldstm (VFP_LDSTMIA);
e16bb312
NC
9955}
9956
9957static void
c19d1205 9958do_vfp_sp_ldstmdb (void)
e16bb312 9959{
c19d1205 9960 vfp_sp_ldstm (VFP_LDSTMDB);
e16bb312
NC
9961}
9962
9963static void
c19d1205 9964do_vfp_dp_ldstmia (void)
e16bb312 9965{
c19d1205 9966 vfp_dp_ldstm (VFP_LDSTMIA);
e16bb312
NC
9967}
9968
9969static void
c19d1205 9970do_vfp_dp_ldstmdb (void)
e16bb312 9971{
c19d1205 9972 vfp_dp_ldstm (VFP_LDSTMDB);
e16bb312
NC
9973}
9974
9975static void
c19d1205 9976do_vfp_xp_ldstmia (void)
e16bb312 9977{
c19d1205
ZW
9978 vfp_dp_ldstm (VFP_LDSTMIAX);
9979}
e16bb312 9980
c19d1205
ZW
9981static void
9982do_vfp_xp_ldstmdb (void)
9983{
9984 vfp_dp_ldstm (VFP_LDSTMDBX);
e16bb312 9985}
5287ad62
JB
9986
9987static void
9988do_vfp_dp_rd_rm (void)
9989{
9990 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
9991 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
9992}
9993
9994static void
9995do_vfp_dp_rn_rd (void)
9996{
9997 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dn);
9998 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
9999}
10000
10001static void
10002do_vfp_dp_rd_rn (void)
10003{
10004 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10005 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10006}
10007
10008static void
10009do_vfp_dp_rd_rn_rm (void)
10010{
10011 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10012 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10013 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dm);
10014}
10015
10016static void
10017do_vfp_dp_rd (void)
10018{
10019 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10020}
10021
10022static void
10023do_vfp_dp_rm_rd_rn (void)
10024{
10025 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dm);
10026 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10027 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dn);
10028}
10029
10030/* VFPv3 instructions. */
10031static void
10032do_vfp_sp_const (void)
10033{
10034 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
00249aaa
PB
10035 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
10036 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
10037}
10038
10039static void
10040do_vfp_dp_const (void)
10041{
10042 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
00249aaa
PB
10043 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
10044 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
10045}
10046
10047static void
10048vfp_conv (int srcsize)
10049{
5f1af56b
MGD
10050 int immbits = srcsize - inst.operands[1].imm;
10051
fa94de6b
RM
10052 if (srcsize == 16 && !(immbits >= 0 && immbits <= srcsize))
10053 {
5f1af56b 10054 /* If srcsize is 16, inst.operands[1].imm must be in the range 0-16.
477330fc 10055 i.e. immbits must be in range 0 - 16. */
5f1af56b
MGD
10056 inst.error = _("immediate value out of range, expected range [0, 16]");
10057 return;
10058 }
fa94de6b 10059 else if (srcsize == 32 && !(immbits >= 0 && immbits < srcsize))
5f1af56b
MGD
10060 {
10061 /* If srcsize is 32, inst.operands[1].imm must be in the range 1-32.
477330fc 10062 i.e. immbits must be in range 0 - 31. */
5f1af56b
MGD
10063 inst.error = _("immediate value out of range, expected range [1, 32]");
10064 return;
10065 }
10066
5287ad62
JB
10067 inst.instruction |= (immbits & 1) << 5;
10068 inst.instruction |= (immbits >> 1);
10069}
10070
10071static void
10072do_vfp_sp_conv_16 (void)
10073{
10074 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10075 vfp_conv (16);
10076}
10077
10078static void
10079do_vfp_dp_conv_16 (void)
10080{
10081 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10082 vfp_conv (16);
10083}
10084
10085static void
10086do_vfp_sp_conv_32 (void)
10087{
10088 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10089 vfp_conv (32);
10090}
10091
10092static void
10093do_vfp_dp_conv_32 (void)
10094{
10095 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10096 vfp_conv (32);
10097}
c19d1205
ZW
10098\f
10099/* FPA instructions. Also in a logical order. */
e16bb312 10100
c19d1205
ZW
10101static void
10102do_fpa_cmp (void)
10103{
10104 inst.instruction |= inst.operands[0].reg << 16;
10105 inst.instruction |= inst.operands[1].reg;
10106}
b99bd4ef
NC
10107
10108static void
c19d1205 10109do_fpa_ldmstm (void)
b99bd4ef 10110{
c19d1205
ZW
10111 inst.instruction |= inst.operands[0].reg << 12;
10112 switch (inst.operands[1].imm)
10113 {
10114 case 1: inst.instruction |= CP_T_X; break;
10115 case 2: inst.instruction |= CP_T_Y; break;
10116 case 3: inst.instruction |= CP_T_Y | CP_T_X; break;
10117 case 4: break;
10118 default: abort ();
10119 }
b99bd4ef 10120
c19d1205
ZW
10121 if (inst.instruction & (PRE_INDEX | INDEX_UP))
10122 {
10123 /* The instruction specified "ea" or "fd", so we can only accept
10124 [Rn]{!}. The instruction does not really support stacking or
10125 unstacking, so we have to emulate these by setting appropriate
10126 bits and offsets. */
e2b0ab59
AV
10127 constraint (inst.relocs[0].exp.X_op != O_constant
10128 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 10129 _("this instruction does not support indexing"));
b99bd4ef 10130
c19d1205 10131 if ((inst.instruction & PRE_INDEX) || inst.operands[2].writeback)
e2b0ab59 10132 inst.relocs[0].exp.X_add_number = 12 * inst.operands[1].imm;
b99bd4ef 10133
c19d1205 10134 if (!(inst.instruction & INDEX_UP))
e2b0ab59 10135 inst.relocs[0].exp.X_add_number = -inst.relocs[0].exp.X_add_number;
b99bd4ef 10136
c19d1205
ZW
10137 if (!(inst.instruction & PRE_INDEX) && inst.operands[2].writeback)
10138 {
10139 inst.operands[2].preind = 0;
10140 inst.operands[2].postind = 1;
10141 }
10142 }
b99bd4ef 10143
c19d1205 10144 encode_arm_cp_address (2, TRUE, TRUE, 0);
b99bd4ef 10145}
c19d1205
ZW
10146\f
10147/* iWMMXt instructions: strictly in alphabetical order. */
b99bd4ef 10148
c19d1205
ZW
10149static void
10150do_iwmmxt_tandorc (void)
10151{
10152 constraint (inst.operands[0].reg != REG_PC, _("only r15 allowed here"));
10153}
b99bd4ef 10154
c19d1205
ZW
10155static void
10156do_iwmmxt_textrc (void)
10157{
10158 inst.instruction |= inst.operands[0].reg << 12;
10159 inst.instruction |= inst.operands[1].imm;
10160}
b99bd4ef
NC
10161
10162static void
c19d1205 10163do_iwmmxt_textrm (void)
b99bd4ef 10164{
c19d1205
ZW
10165 inst.instruction |= inst.operands[0].reg << 12;
10166 inst.instruction |= inst.operands[1].reg << 16;
10167 inst.instruction |= inst.operands[2].imm;
10168}
b99bd4ef 10169
c19d1205
ZW
10170static void
10171do_iwmmxt_tinsr (void)
10172{
10173 inst.instruction |= inst.operands[0].reg << 16;
10174 inst.instruction |= inst.operands[1].reg << 12;
10175 inst.instruction |= inst.operands[2].imm;
10176}
b99bd4ef 10177
c19d1205
ZW
10178static void
10179do_iwmmxt_tmia (void)
10180{
10181 inst.instruction |= inst.operands[0].reg << 5;
10182 inst.instruction |= inst.operands[1].reg;
10183 inst.instruction |= inst.operands[2].reg << 12;
10184}
b99bd4ef 10185
c19d1205
ZW
10186static void
10187do_iwmmxt_waligni (void)
10188{
10189 inst.instruction |= inst.operands[0].reg << 12;
10190 inst.instruction |= inst.operands[1].reg << 16;
10191 inst.instruction |= inst.operands[2].reg;
10192 inst.instruction |= inst.operands[3].imm << 20;
10193}
b99bd4ef 10194
2d447fca
JM
10195static void
10196do_iwmmxt_wmerge (void)
10197{
10198 inst.instruction |= inst.operands[0].reg << 12;
10199 inst.instruction |= inst.operands[1].reg << 16;
10200 inst.instruction |= inst.operands[2].reg;
10201 inst.instruction |= inst.operands[3].imm << 21;
10202}
10203
c19d1205
ZW
10204static void
10205do_iwmmxt_wmov (void)
10206{
10207 /* WMOV rD, rN is an alias for WOR rD, rN, rN. */
10208 inst.instruction |= inst.operands[0].reg << 12;
10209 inst.instruction |= inst.operands[1].reg << 16;
10210 inst.instruction |= inst.operands[1].reg;
10211}
b99bd4ef 10212
c19d1205
ZW
10213static void
10214do_iwmmxt_wldstbh (void)
10215{
8f06b2d8 10216 int reloc;
c19d1205 10217 inst.instruction |= inst.operands[0].reg << 12;
8f06b2d8
PB
10218 if (thumb_mode)
10219 reloc = BFD_RELOC_ARM_T32_CP_OFF_IMM_S2;
10220 else
10221 reloc = BFD_RELOC_ARM_CP_OFF_IMM_S2;
10222 encode_arm_cp_address (1, TRUE, FALSE, reloc);
b99bd4ef
NC
10223}
10224
c19d1205
ZW
10225static void
10226do_iwmmxt_wldstw (void)
10227{
10228 /* RIWR_RIWC clears .isreg for a control register. */
10229 if (!inst.operands[0].isreg)
10230 {
10231 constraint (inst.cond != COND_ALWAYS, BAD_COND);
10232 inst.instruction |= 0xf0000000;
10233 }
b99bd4ef 10234
c19d1205
ZW
10235 inst.instruction |= inst.operands[0].reg << 12;
10236 encode_arm_cp_address (1, TRUE, TRUE, 0);
10237}
b99bd4ef
NC
10238
10239static void
c19d1205 10240do_iwmmxt_wldstd (void)
b99bd4ef 10241{
c19d1205 10242 inst.instruction |= inst.operands[0].reg << 12;
2d447fca
JM
10243 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2)
10244 && inst.operands[1].immisreg)
10245 {
10246 inst.instruction &= ~0x1a000ff;
eff0bc54 10247 inst.instruction |= (0xfU << 28);
2d447fca
JM
10248 if (inst.operands[1].preind)
10249 inst.instruction |= PRE_INDEX;
10250 if (!inst.operands[1].negative)
10251 inst.instruction |= INDEX_UP;
10252 if (inst.operands[1].writeback)
10253 inst.instruction |= WRITE_BACK;
10254 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 10255 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
2d447fca
JM
10256 inst.instruction |= inst.operands[1].imm;
10257 }
10258 else
10259 encode_arm_cp_address (1, TRUE, FALSE, 0);
c19d1205 10260}
b99bd4ef 10261
c19d1205
ZW
10262static void
10263do_iwmmxt_wshufh (void)
10264{
10265 inst.instruction |= inst.operands[0].reg << 12;
10266 inst.instruction |= inst.operands[1].reg << 16;
10267 inst.instruction |= ((inst.operands[2].imm & 0xf0) << 16);
10268 inst.instruction |= (inst.operands[2].imm & 0x0f);
10269}
b99bd4ef 10270
c19d1205
ZW
10271static void
10272do_iwmmxt_wzero (void)
10273{
10274 /* WZERO reg is an alias for WANDN reg, reg, reg. */
10275 inst.instruction |= inst.operands[0].reg;
10276 inst.instruction |= inst.operands[0].reg << 12;
10277 inst.instruction |= inst.operands[0].reg << 16;
10278}
2d447fca
JM
10279
10280static void
10281do_iwmmxt_wrwrwr_or_imm5 (void)
10282{
10283 if (inst.operands[2].isreg)
10284 do_rd_rn_rm ();
10285 else {
10286 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2),
10287 _("immediate operand requires iWMMXt2"));
10288 do_rd_rn ();
10289 if (inst.operands[2].imm == 0)
10290 {
10291 switch ((inst.instruction >> 20) & 0xf)
10292 {
10293 case 4:
10294 case 5:
10295 case 6:
5f4273c7 10296 case 7:
2d447fca
JM
10297 /* w...h wrd, wrn, #0 -> wrorh wrd, wrn, #16. */
10298 inst.operands[2].imm = 16;
10299 inst.instruction = (inst.instruction & 0xff0fffff) | (0x7 << 20);
10300 break;
10301 case 8:
10302 case 9:
10303 case 10:
10304 case 11:
10305 /* w...w wrd, wrn, #0 -> wrorw wrd, wrn, #32. */
10306 inst.operands[2].imm = 32;
10307 inst.instruction = (inst.instruction & 0xff0fffff) | (0xb << 20);
10308 break;
10309 case 12:
10310 case 13:
10311 case 14:
10312 case 15:
10313 {
10314 /* w...d wrd, wrn, #0 -> wor wrd, wrn, wrn. */
10315 unsigned long wrn;
10316 wrn = (inst.instruction >> 16) & 0xf;
10317 inst.instruction &= 0xff0fff0f;
10318 inst.instruction |= wrn;
10319 /* Bail out here; the instruction is now assembled. */
10320 return;
10321 }
10322 }
10323 }
10324 /* Map 32 -> 0, etc. */
10325 inst.operands[2].imm &= 0x1f;
eff0bc54 10326 inst.instruction |= (0xfU << 28) | ((inst.operands[2].imm & 0x10) << 4) | (inst.operands[2].imm & 0xf);
2d447fca
JM
10327 }
10328}
c19d1205
ZW
10329\f
10330/* Cirrus Maverick instructions. Simple 2-, 3-, and 4-register
10331 operations first, then control, shift, and load/store. */
b99bd4ef 10332
c19d1205 10333/* Insns like "foo X,Y,Z". */
b99bd4ef 10334
c19d1205
ZW
10335static void
10336do_mav_triple (void)
10337{
10338 inst.instruction |= inst.operands[0].reg << 16;
10339 inst.instruction |= inst.operands[1].reg;
10340 inst.instruction |= inst.operands[2].reg << 12;
10341}
b99bd4ef 10342
c19d1205
ZW
10343/* Insns like "foo W,X,Y,Z".
10344 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
a737bd4d 10345
c19d1205
ZW
10346static void
10347do_mav_quad (void)
10348{
10349 inst.instruction |= inst.operands[0].reg << 5;
10350 inst.instruction |= inst.operands[1].reg << 12;
10351 inst.instruction |= inst.operands[2].reg << 16;
10352 inst.instruction |= inst.operands[3].reg;
a737bd4d
NC
10353}
10354
c19d1205
ZW
10355/* cfmvsc32<cond> DSPSC,MVDX[15:0]. */
10356static void
10357do_mav_dspsc (void)
a737bd4d 10358{
c19d1205
ZW
10359 inst.instruction |= inst.operands[1].reg << 12;
10360}
a737bd4d 10361
c19d1205
ZW
10362/* Maverick shift immediate instructions.
10363 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
10364 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
a737bd4d 10365
c19d1205
ZW
10366static void
10367do_mav_shift (void)
10368{
10369 int imm = inst.operands[2].imm;
a737bd4d 10370
c19d1205
ZW
10371 inst.instruction |= inst.operands[0].reg << 12;
10372 inst.instruction |= inst.operands[1].reg << 16;
a737bd4d 10373
c19d1205
ZW
10374 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
10375 Bits 5-7 of the insn should have bits 4-6 of the immediate.
10376 Bit 4 should be 0. */
10377 imm = (imm & 0xf) | ((imm & 0x70) << 1);
a737bd4d 10378
c19d1205
ZW
10379 inst.instruction |= imm;
10380}
10381\f
10382/* XScale instructions. Also sorted arithmetic before move. */
a737bd4d 10383
c19d1205
ZW
10384/* Xscale multiply-accumulate (argument parse)
10385 MIAcc acc0,Rm,Rs
10386 MIAPHcc acc0,Rm,Rs
10387 MIAxycc acc0,Rm,Rs. */
a737bd4d 10388
c19d1205
ZW
10389static void
10390do_xsc_mia (void)
10391{
10392 inst.instruction |= inst.operands[1].reg;
10393 inst.instruction |= inst.operands[2].reg << 12;
10394}
a737bd4d 10395
c19d1205 10396/* Xscale move-accumulator-register (argument parse)
a737bd4d 10397
c19d1205 10398 MARcc acc0,RdLo,RdHi. */
b99bd4ef 10399
c19d1205
ZW
10400static void
10401do_xsc_mar (void)
10402{
10403 inst.instruction |= inst.operands[1].reg << 12;
10404 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
10405}
10406
c19d1205 10407/* Xscale move-register-accumulator (argument parse)
b99bd4ef 10408
c19d1205 10409 MRAcc RdLo,RdHi,acc0. */
b99bd4ef
NC
10410
10411static void
c19d1205 10412do_xsc_mra (void)
b99bd4ef 10413{
c19d1205
ZW
10414 constraint (inst.operands[0].reg == inst.operands[1].reg, BAD_OVERLAP);
10415 inst.instruction |= inst.operands[0].reg << 12;
10416 inst.instruction |= inst.operands[1].reg << 16;
10417}
10418\f
10419/* Encoding functions relevant only to Thumb. */
b99bd4ef 10420
c19d1205
ZW
10421/* inst.operands[i] is a shifted-register operand; encode
10422 it into inst.instruction in the format used by Thumb32. */
10423
10424static void
10425encode_thumb32_shifted_operand (int i)
10426{
e2b0ab59 10427 unsigned int value = inst.relocs[0].exp.X_add_number;
c19d1205 10428 unsigned int shift = inst.operands[i].shift_kind;
b99bd4ef 10429
9c3c69f2
PB
10430 constraint (inst.operands[i].immisreg,
10431 _("shift by register not allowed in thumb mode"));
c19d1205
ZW
10432 inst.instruction |= inst.operands[i].reg;
10433 if (shift == SHIFT_RRX)
10434 inst.instruction |= SHIFT_ROR << 4;
10435 else
b99bd4ef 10436 {
e2b0ab59 10437 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
10438 _("expression too complex"));
10439
10440 constraint (value > 32
10441 || (value == 32 && (shift == SHIFT_LSL
10442 || shift == SHIFT_ROR)),
10443 _("shift expression is too large"));
10444
10445 if (value == 0)
10446 shift = SHIFT_LSL;
10447 else if (value == 32)
10448 value = 0;
10449
10450 inst.instruction |= shift << 4;
10451 inst.instruction |= (value & 0x1c) << 10;
10452 inst.instruction |= (value & 0x03) << 6;
b99bd4ef 10453 }
c19d1205 10454}
b99bd4ef 10455
b99bd4ef 10456
c19d1205
ZW
10457/* inst.operands[i] was set up by parse_address. Encode it into a
10458 Thumb32 format load or store instruction. Reject forms that cannot
10459 be used with such instructions. If is_t is true, reject forms that
10460 cannot be used with a T instruction; if is_d is true, reject forms
5be8be5d
DG
10461 that cannot be used with a D instruction. If it is a store insn,
10462 reject PC in Rn. */
b99bd4ef 10463
c19d1205
ZW
10464static void
10465encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
10466{
5be8be5d 10467 const bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
c19d1205
ZW
10468
10469 constraint (!inst.operands[i].isreg,
53365c0d 10470 _("Instruction does not support =N addresses"));
b99bd4ef 10471
c19d1205
ZW
10472 inst.instruction |= inst.operands[i].reg << 16;
10473 if (inst.operands[i].immisreg)
b99bd4ef 10474 {
5be8be5d 10475 constraint (is_pc, BAD_PC_ADDRESSING);
c19d1205
ZW
10476 constraint (is_t || is_d, _("cannot use register index with this instruction"));
10477 constraint (inst.operands[i].negative,
10478 _("Thumb does not support negative register indexing"));
10479 constraint (inst.operands[i].postind,
10480 _("Thumb does not support register post-indexing"));
10481 constraint (inst.operands[i].writeback,
10482 _("Thumb does not support register indexing with writeback"));
10483 constraint (inst.operands[i].shifted && inst.operands[i].shift_kind != SHIFT_LSL,
10484 _("Thumb supports only LSL in shifted register indexing"));
b99bd4ef 10485
f40d1643 10486 inst.instruction |= inst.operands[i].imm;
c19d1205 10487 if (inst.operands[i].shifted)
b99bd4ef 10488 {
e2b0ab59 10489 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 10490 _("expression too complex"));
e2b0ab59
AV
10491 constraint (inst.relocs[0].exp.X_add_number < 0
10492 || inst.relocs[0].exp.X_add_number > 3,
c19d1205 10493 _("shift out of range"));
e2b0ab59 10494 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
c19d1205 10495 }
e2b0ab59 10496 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205
ZW
10497 }
10498 else if (inst.operands[i].preind)
10499 {
5be8be5d 10500 constraint (is_pc && inst.operands[i].writeback, BAD_PC_WRITEBACK);
f40d1643 10501 constraint (is_t && inst.operands[i].writeback,
c19d1205 10502 _("cannot use writeback with this instruction"));
4755303e
WN
10503 constraint (is_pc && ((inst.instruction & THUMB2_LOAD_BIT) == 0),
10504 BAD_PC_ADDRESSING);
c19d1205
ZW
10505
10506 if (is_d)
10507 {
10508 inst.instruction |= 0x01000000;
10509 if (inst.operands[i].writeback)
10510 inst.instruction |= 0x00200000;
b99bd4ef 10511 }
c19d1205 10512 else
b99bd4ef 10513 {
c19d1205
ZW
10514 inst.instruction |= 0x00000c00;
10515 if (inst.operands[i].writeback)
10516 inst.instruction |= 0x00000100;
b99bd4ef 10517 }
e2b0ab59 10518 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
b99bd4ef 10519 }
c19d1205 10520 else if (inst.operands[i].postind)
b99bd4ef 10521 {
9c2799c2 10522 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
10523 constraint (is_pc, _("cannot use post-indexing with PC-relative addressing"));
10524 constraint (is_t, _("cannot use post-indexing with this instruction"));
10525
10526 if (is_d)
10527 inst.instruction |= 0x00200000;
10528 else
10529 inst.instruction |= 0x00000900;
e2b0ab59 10530 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
c19d1205
ZW
10531 }
10532 else /* unindexed - only for coprocessor */
10533 inst.error = _("instruction does not accept unindexed addressing");
10534}
10535
10536/* Table of Thumb instructions which exist in both 16- and 32-bit
10537 encodings (the latter only in post-V6T2 cores). The index is the
10538 value used in the insns table below. When there is more than one
10539 possible 16-bit encoding for the instruction, this table always
0110f2b8
PB
10540 holds variant (1).
10541 Also contains several pseudo-instructions used during relaxation. */
c19d1205 10542#define T16_32_TAB \
21d799b5
NC
10543 X(_adc, 4140, eb400000), \
10544 X(_adcs, 4140, eb500000), \
10545 X(_add, 1c00, eb000000), \
10546 X(_adds, 1c00, eb100000), \
10547 X(_addi, 0000, f1000000), \
10548 X(_addis, 0000, f1100000), \
10549 X(_add_pc,000f, f20f0000), \
10550 X(_add_sp,000d, f10d0000), \
10551 X(_adr, 000f, f20f0000), \
10552 X(_and, 4000, ea000000), \
10553 X(_ands, 4000, ea100000), \
10554 X(_asr, 1000, fa40f000), \
10555 X(_asrs, 1000, fa50f000), \
10556 X(_b, e000, f000b000), \
10557 X(_bcond, d000, f0008000), \
4389b29a 10558 X(_bf, 0000, f040e001), \
f6b2b12d 10559 X(_bfcsel,0000, f000e001), \
f1c7f421 10560 X(_bfx, 0000, f060e001), \
65d1bc05 10561 X(_bfl, 0000, f000c001), \
f1c7f421 10562 X(_bflx, 0000, f070e001), \
21d799b5
NC
10563 X(_bic, 4380, ea200000), \
10564 X(_bics, 4380, ea300000), \
10565 X(_cmn, 42c0, eb100f00), \
10566 X(_cmp, 2800, ebb00f00), \
10567 X(_cpsie, b660, f3af8400), \
10568 X(_cpsid, b670, f3af8600), \
10569 X(_cpy, 4600, ea4f0000), \
10570 X(_dec_sp,80dd, f1ad0d00), \
60f993ce 10571 X(_dls, 0000, f040e001), \
21d799b5
NC
10572 X(_eor, 4040, ea800000), \
10573 X(_eors, 4040, ea900000), \
10574 X(_inc_sp,00dd, f10d0d00), \
10575 X(_ldmia, c800, e8900000), \
10576 X(_ldr, 6800, f8500000), \
10577 X(_ldrb, 7800, f8100000), \
10578 X(_ldrh, 8800, f8300000), \
10579 X(_ldrsb, 5600, f9100000), \
10580 X(_ldrsh, 5e00, f9300000), \
10581 X(_ldr_pc,4800, f85f0000), \
10582 X(_ldr_pc2,4800, f85f0000), \
10583 X(_ldr_sp,9800, f85d0000), \
60f993ce 10584 X(_le, 0000, f00fc001), \
21d799b5
NC
10585 X(_lsl, 0000, fa00f000), \
10586 X(_lsls, 0000, fa10f000), \
10587 X(_lsr, 0800, fa20f000), \
10588 X(_lsrs, 0800, fa30f000), \
10589 X(_mov, 2000, ea4f0000), \
10590 X(_movs, 2000, ea5f0000), \
10591 X(_mul, 4340, fb00f000), \
10592 X(_muls, 4340, ffffffff), /* no 32b muls */ \
10593 X(_mvn, 43c0, ea6f0000), \
10594 X(_mvns, 43c0, ea7f0000), \
10595 X(_neg, 4240, f1c00000), /* rsb #0 */ \
10596 X(_negs, 4240, f1d00000), /* rsbs #0 */ \
10597 X(_orr, 4300, ea400000), \
10598 X(_orrs, 4300, ea500000), \
10599 X(_pop, bc00, e8bd0000), /* ldmia sp!,... */ \
10600 X(_push, b400, e92d0000), /* stmdb sp!,... */ \
10601 X(_rev, ba00, fa90f080), \
10602 X(_rev16, ba40, fa90f090), \
10603 X(_revsh, bac0, fa90f0b0), \
10604 X(_ror, 41c0, fa60f000), \
10605 X(_rors, 41c0, fa70f000), \
10606 X(_sbc, 4180, eb600000), \
10607 X(_sbcs, 4180, eb700000), \
10608 X(_stmia, c000, e8800000), \
10609 X(_str, 6000, f8400000), \
10610 X(_strb, 7000, f8000000), \
10611 X(_strh, 8000, f8200000), \
10612 X(_str_sp,9000, f84d0000), \
10613 X(_sub, 1e00, eba00000), \
10614 X(_subs, 1e00, ebb00000), \
10615 X(_subi, 8000, f1a00000), \
10616 X(_subis, 8000, f1b00000), \
10617 X(_sxtb, b240, fa4ff080), \
10618 X(_sxth, b200, fa0ff080), \
10619 X(_tst, 4200, ea100f00), \
10620 X(_uxtb, b2c0, fa5ff080), \
10621 X(_uxth, b280, fa1ff080), \
10622 X(_nop, bf00, f3af8000), \
10623 X(_yield, bf10, f3af8001), \
10624 X(_wfe, bf20, f3af8002), \
10625 X(_wfi, bf30, f3af8003), \
60f993ce 10626 X(_wls, 0000, f040c001), \
53c4b28b 10627 X(_sev, bf40, f3af8004), \
74db7efb
NC
10628 X(_sevl, bf50, f3af8005), \
10629 X(_udf, de00, f7f0a000)
c19d1205
ZW
10630
10631/* To catch errors in encoding functions, the codes are all offset by
10632 0xF800, putting them in one of the 32-bit prefix ranges, ergo undefined
10633 as 16-bit instructions. */
21d799b5 10634#define X(a,b,c) T_MNEM##a
c19d1205
ZW
10635enum t16_32_codes { T16_32_OFFSET = 0xF7FF, T16_32_TAB };
10636#undef X
10637
10638#define X(a,b,c) 0x##b
10639static const unsigned short thumb_op16[] = { T16_32_TAB };
10640#define THUMB_OP16(n) (thumb_op16[(n) - (T16_32_OFFSET + 1)])
10641#undef X
10642
10643#define X(a,b,c) 0x##c
10644static const unsigned int thumb_op32[] = { T16_32_TAB };
c921be7d
NC
10645#define THUMB_OP32(n) (thumb_op32[(n) - (T16_32_OFFSET + 1)])
10646#define THUMB_SETS_FLAGS(n) (THUMB_OP32 (n) & 0x00100000)
c19d1205
ZW
10647#undef X
10648#undef T16_32_TAB
10649
10650/* Thumb instruction encoders, in alphabetical order. */
10651
92e90b6e 10652/* ADDW or SUBW. */
c921be7d 10653
92e90b6e
PB
10654static void
10655do_t_add_sub_w (void)
10656{
10657 int Rd, Rn;
10658
10659 Rd = inst.operands[0].reg;
10660 Rn = inst.operands[1].reg;
10661
539d4391
NC
10662 /* If Rn is REG_PC, this is ADR; if Rn is REG_SP, then this
10663 is the SP-{plus,minus}-immediate form of the instruction. */
10664 if (Rn == REG_SP)
10665 constraint (Rd == REG_PC, BAD_PC);
10666 else
10667 reject_bad_reg (Rd);
fdfde340 10668
92e90b6e 10669 inst.instruction |= (Rn << 16) | (Rd << 8);
e2b0ab59 10670 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
92e90b6e
PB
10671}
10672
c19d1205 10673/* Parse an add or subtract instruction. We get here with inst.instruction
33eaf5de 10674 equaling any of THUMB_OPCODE_add, adds, sub, or subs. */
c19d1205
ZW
10675
10676static void
10677do_t_add_sub (void)
10678{
10679 int Rd, Rs, Rn;
10680
10681 Rd = inst.operands[0].reg;
10682 Rs = (inst.operands[1].present
10683 ? inst.operands[1].reg /* Rd, Rs, foo */
10684 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
10685
e07e6e58
NC
10686 if (Rd == REG_PC)
10687 set_it_insn_type_last ();
10688
c19d1205
ZW
10689 if (unified_syntax)
10690 {
0110f2b8
PB
10691 bfd_boolean flags;
10692 bfd_boolean narrow;
10693 int opcode;
10694
10695 flags = (inst.instruction == T_MNEM_adds
10696 || inst.instruction == T_MNEM_subs);
10697 if (flags)
e07e6e58 10698 narrow = !in_it_block ();
0110f2b8 10699 else
e07e6e58 10700 narrow = in_it_block ();
c19d1205 10701 if (!inst.operands[2].isreg)
b99bd4ef 10702 {
16805f35
PB
10703 int add;
10704
5c8ed6a4
JW
10705 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
10706 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340 10707
16805f35
PB
10708 add = (inst.instruction == T_MNEM_add
10709 || inst.instruction == T_MNEM_adds);
0110f2b8
PB
10710 opcode = 0;
10711 if (inst.size_req != 4)
10712 {
0110f2b8 10713 /* Attempt to use a narrow opcode, with relaxation if
477330fc 10714 appropriate. */
0110f2b8
PB
10715 if (Rd == REG_SP && Rs == REG_SP && !flags)
10716 opcode = add ? T_MNEM_inc_sp : T_MNEM_dec_sp;
10717 else if (Rd <= 7 && Rs == REG_SP && add && !flags)
10718 opcode = T_MNEM_add_sp;
10719 else if (Rd <= 7 && Rs == REG_PC && add && !flags)
10720 opcode = T_MNEM_add_pc;
10721 else if (Rd <= 7 && Rs <= 7 && narrow)
10722 {
10723 if (flags)
10724 opcode = add ? T_MNEM_addis : T_MNEM_subis;
10725 else
10726 opcode = add ? T_MNEM_addi : T_MNEM_subi;
10727 }
10728 if (opcode)
10729 {
10730 inst.instruction = THUMB_OP16(opcode);
10731 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59
AV
10732 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
10733 || (inst.relocs[0].type
10734 > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC))
a9f02af8
MG
10735 {
10736 if (inst.size_req == 2)
e2b0ab59 10737 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
a9f02af8
MG
10738 else
10739 inst.relax = opcode;
10740 }
0110f2b8
PB
10741 }
10742 else
10743 constraint (inst.size_req == 2, BAD_HIREG);
10744 }
10745 if (inst.size_req == 4
10746 || (inst.size_req != 2 && !opcode))
10747 {
e2b0ab59
AV
10748 constraint ((inst.relocs[0].type
10749 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
10750 && (inst.relocs[0].type
10751 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8 10752 THUMB1_RELOC_ONLY);
efd81785
PB
10753 if (Rd == REG_PC)
10754 {
fdfde340 10755 constraint (add, BAD_PC);
efd81785
PB
10756 constraint (Rs != REG_LR || inst.instruction != T_MNEM_subs,
10757 _("only SUBS PC, LR, #const allowed"));
e2b0ab59 10758 constraint (inst.relocs[0].exp.X_op != O_constant,
efd81785 10759 _("expression too complex"));
e2b0ab59
AV
10760 constraint (inst.relocs[0].exp.X_add_number < 0
10761 || inst.relocs[0].exp.X_add_number > 0xff,
efd81785
PB
10762 _("immediate value out of range"));
10763 inst.instruction = T2_SUBS_PC_LR
e2b0ab59
AV
10764 | inst.relocs[0].exp.X_add_number;
10765 inst.relocs[0].type = BFD_RELOC_UNUSED;
efd81785
PB
10766 return;
10767 }
10768 else if (Rs == REG_PC)
16805f35
PB
10769 {
10770 /* Always use addw/subw. */
10771 inst.instruction = add ? 0xf20f0000 : 0xf2af0000;
e2b0ab59 10772 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
16805f35
PB
10773 }
10774 else
10775 {
10776 inst.instruction = THUMB_OP32 (inst.instruction);
10777 inst.instruction = (inst.instruction & 0xe1ffffff)
10778 | 0x10000000;
10779 if (flags)
e2b0ab59 10780 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
16805f35 10781 else
e2b0ab59 10782 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_IMM;
16805f35 10783 }
dc4503c6
PB
10784 inst.instruction |= Rd << 8;
10785 inst.instruction |= Rs << 16;
0110f2b8 10786 }
b99bd4ef 10787 }
c19d1205
ZW
10788 else
10789 {
e2b0ab59 10790 unsigned int value = inst.relocs[0].exp.X_add_number;
5f4cb198
NC
10791 unsigned int shift = inst.operands[2].shift_kind;
10792
c19d1205
ZW
10793 Rn = inst.operands[2].reg;
10794 /* See if we can do this with a 16-bit instruction. */
10795 if (!inst.operands[2].shifted && inst.size_req != 4)
10796 {
e27ec89e
PB
10797 if (Rd > 7 || Rs > 7 || Rn > 7)
10798 narrow = FALSE;
10799
10800 if (narrow)
c19d1205 10801 {
e27ec89e
PB
10802 inst.instruction = ((inst.instruction == T_MNEM_adds
10803 || inst.instruction == T_MNEM_add)
c19d1205
ZW
10804 ? T_OPCODE_ADD_R3
10805 : T_OPCODE_SUB_R3);
10806 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
10807 return;
10808 }
b99bd4ef 10809
7e806470 10810 if (inst.instruction == T_MNEM_add && (Rd == Rs || Rd == Rn))
c19d1205 10811 {
7e806470
PB
10812 /* Thumb-1 cores (except v6-M) require at least one high
10813 register in a narrow non flag setting add. */
10814 if (Rd > 7 || Rn > 7
10815 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2)
10816 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_msr))
c19d1205 10817 {
7e806470
PB
10818 if (Rd == Rn)
10819 {
10820 Rn = Rs;
10821 Rs = Rd;
10822 }
c19d1205
ZW
10823 inst.instruction = T_OPCODE_ADD_HI;
10824 inst.instruction |= (Rd & 8) << 4;
10825 inst.instruction |= (Rd & 7);
10826 inst.instruction |= Rn << 3;
10827 return;
10828 }
c19d1205
ZW
10829 }
10830 }
c921be7d 10831
fdfde340 10832 constraint (Rd == REG_PC, BAD_PC);
5c8ed6a4
JW
10833 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
10834 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340
JM
10835 constraint (Rs == REG_PC, BAD_PC);
10836 reject_bad_reg (Rn);
10837
c19d1205
ZW
10838 /* If we get here, it can't be done in 16 bits. */
10839 constraint (inst.operands[2].shifted && inst.operands[2].immisreg,
10840 _("shift must be constant"));
10841 inst.instruction = THUMB_OP32 (inst.instruction);
10842 inst.instruction |= Rd << 8;
10843 inst.instruction |= Rs << 16;
5f4cb198
NC
10844 constraint (Rd == REG_SP && Rs == REG_SP && value > 3,
10845 _("shift value over 3 not allowed in thumb mode"));
10846 constraint (Rd == REG_SP && Rs == REG_SP && shift != SHIFT_LSL,
10847 _("only LSL shift allowed in thumb mode"));
c19d1205
ZW
10848 encode_thumb32_shifted_operand (2);
10849 }
10850 }
10851 else
10852 {
10853 constraint (inst.instruction == T_MNEM_adds
10854 || inst.instruction == T_MNEM_subs,
10855 BAD_THUMB32);
b99bd4ef 10856
c19d1205 10857 if (!inst.operands[2].isreg) /* Rd, Rs, #imm */
b99bd4ef 10858 {
c19d1205
ZW
10859 constraint ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
10860 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC),
10861 BAD_HIREG);
10862
10863 inst.instruction = (inst.instruction == T_MNEM_add
10864 ? 0x0000 : 0x8000);
10865 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59 10866 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
b99bd4ef
NC
10867 return;
10868 }
10869
c19d1205
ZW
10870 Rn = inst.operands[2].reg;
10871 constraint (inst.operands[2].shifted, _("unshifted register required"));
b99bd4ef 10872
c19d1205
ZW
10873 /* We now have Rd, Rs, and Rn set to registers. */
10874 if (Rd > 7 || Rs > 7 || Rn > 7)
b99bd4ef 10875 {
c19d1205
ZW
10876 /* Can't do this for SUB. */
10877 constraint (inst.instruction == T_MNEM_sub, BAD_HIREG);
10878 inst.instruction = T_OPCODE_ADD_HI;
10879 inst.instruction |= (Rd & 8) << 4;
10880 inst.instruction |= (Rd & 7);
10881 if (Rs == Rd)
10882 inst.instruction |= Rn << 3;
10883 else if (Rn == Rd)
10884 inst.instruction |= Rs << 3;
10885 else
10886 constraint (1, _("dest must overlap one source register"));
10887 }
10888 else
10889 {
10890 inst.instruction = (inst.instruction == T_MNEM_add
10891 ? T_OPCODE_ADD_R3 : T_OPCODE_SUB_R3);
10892 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
b99bd4ef 10893 }
b99bd4ef 10894 }
b99bd4ef
NC
10895}
10896
c19d1205
ZW
10897static void
10898do_t_adr (void)
10899{
fdfde340
JM
10900 unsigned Rd;
10901
10902 Rd = inst.operands[0].reg;
10903 reject_bad_reg (Rd);
10904
10905 if (unified_syntax && inst.size_req == 0 && Rd <= 7)
0110f2b8
PB
10906 {
10907 /* Defer to section relaxation. */
10908 inst.relax = inst.instruction;
10909 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 10910 inst.instruction |= Rd << 4;
0110f2b8
PB
10911 }
10912 else if (unified_syntax && inst.size_req != 2)
e9f89963 10913 {
0110f2b8 10914 /* Generate a 32-bit opcode. */
e9f89963 10915 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 10916 inst.instruction |= Rd << 8;
e2b0ab59
AV
10917 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_PC12;
10918 inst.relocs[0].pc_rel = 1;
e9f89963
PB
10919 }
10920 else
10921 {
0110f2b8 10922 /* Generate a 16-bit opcode. */
e9f89963 10923 inst.instruction = THUMB_OP16 (inst.instruction);
e2b0ab59
AV
10924 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
10925 inst.relocs[0].exp.X_add_number -= 4; /* PC relative adjust. */
10926 inst.relocs[0].pc_rel = 1;
fdfde340 10927 inst.instruction |= Rd << 4;
e9f89963 10928 }
52a86f84 10929
e2b0ab59
AV
10930 if (inst.relocs[0].exp.X_op == O_symbol
10931 && inst.relocs[0].exp.X_add_symbol != NULL
10932 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
10933 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
10934 inst.relocs[0].exp.X_add_number += 1;
c19d1205 10935}
b99bd4ef 10936
c19d1205
ZW
10937/* Arithmetic instructions for which there is just one 16-bit
10938 instruction encoding, and it allows only two low registers.
10939 For maximal compatibility with ARM syntax, we allow three register
10940 operands even when Thumb-32 instructions are not available, as long
10941 as the first two are identical. For instance, both "sbc r0,r1" and
10942 "sbc r0,r0,r1" are allowed. */
b99bd4ef 10943static void
c19d1205 10944do_t_arit3 (void)
b99bd4ef 10945{
c19d1205 10946 int Rd, Rs, Rn;
b99bd4ef 10947
c19d1205
ZW
10948 Rd = inst.operands[0].reg;
10949 Rs = (inst.operands[1].present
10950 ? inst.operands[1].reg /* Rd, Rs, foo */
10951 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
10952 Rn = inst.operands[2].reg;
b99bd4ef 10953
fdfde340
JM
10954 reject_bad_reg (Rd);
10955 reject_bad_reg (Rs);
10956 if (inst.operands[2].isreg)
10957 reject_bad_reg (Rn);
10958
c19d1205 10959 if (unified_syntax)
b99bd4ef 10960 {
c19d1205
ZW
10961 if (!inst.operands[2].isreg)
10962 {
10963 /* For an immediate, we always generate a 32-bit opcode;
10964 section relaxation will shrink it later if possible. */
10965 inst.instruction = THUMB_OP32 (inst.instruction);
10966 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
10967 inst.instruction |= Rd << 8;
10968 inst.instruction |= Rs << 16;
e2b0ab59 10969 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
c19d1205
ZW
10970 }
10971 else
10972 {
e27ec89e
PB
10973 bfd_boolean narrow;
10974
c19d1205 10975 /* See if we can do this with a 16-bit instruction. */
e27ec89e 10976 if (THUMB_SETS_FLAGS (inst.instruction))
e07e6e58 10977 narrow = !in_it_block ();
e27ec89e 10978 else
e07e6e58 10979 narrow = in_it_block ();
e27ec89e
PB
10980
10981 if (Rd > 7 || Rn > 7 || Rs > 7)
10982 narrow = FALSE;
10983 if (inst.operands[2].shifted)
10984 narrow = FALSE;
10985 if (inst.size_req == 4)
10986 narrow = FALSE;
10987
10988 if (narrow
c19d1205
ZW
10989 && Rd == Rs)
10990 {
10991 inst.instruction = THUMB_OP16 (inst.instruction);
10992 inst.instruction |= Rd;
10993 inst.instruction |= Rn << 3;
10994 return;
10995 }
b99bd4ef 10996
c19d1205
ZW
10997 /* If we get here, it can't be done in 16 bits. */
10998 constraint (inst.operands[2].shifted
10999 && inst.operands[2].immisreg,
11000 _("shift must be constant"));
11001 inst.instruction = THUMB_OP32 (inst.instruction);
11002 inst.instruction |= Rd << 8;
11003 inst.instruction |= Rs << 16;
11004 encode_thumb32_shifted_operand (2);
11005 }
a737bd4d 11006 }
c19d1205 11007 else
b99bd4ef 11008 {
c19d1205
ZW
11009 /* On its face this is a lie - the instruction does set the
11010 flags. However, the only supported mnemonic in this mode
11011 says it doesn't. */
11012 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 11013
c19d1205
ZW
11014 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
11015 _("unshifted register required"));
11016 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
11017 constraint (Rd != Rs,
11018 _("dest and source1 must be the same register"));
a737bd4d 11019
c19d1205
ZW
11020 inst.instruction = THUMB_OP16 (inst.instruction);
11021 inst.instruction |= Rd;
11022 inst.instruction |= Rn << 3;
b99bd4ef 11023 }
a737bd4d 11024}
b99bd4ef 11025
c19d1205
ZW
11026/* Similarly, but for instructions where the arithmetic operation is
11027 commutative, so we can allow either of them to be different from
11028 the destination operand in a 16-bit instruction. For instance, all
11029 three of "adc r0,r1", "adc r0,r0,r1", and "adc r0,r1,r0" are
11030 accepted. */
11031static void
11032do_t_arit3c (void)
a737bd4d 11033{
c19d1205 11034 int Rd, Rs, Rn;
b99bd4ef 11035
c19d1205
ZW
11036 Rd = inst.operands[0].reg;
11037 Rs = (inst.operands[1].present
11038 ? inst.operands[1].reg /* Rd, Rs, foo */
11039 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11040 Rn = inst.operands[2].reg;
c921be7d 11041
fdfde340
JM
11042 reject_bad_reg (Rd);
11043 reject_bad_reg (Rs);
11044 if (inst.operands[2].isreg)
11045 reject_bad_reg (Rn);
a737bd4d 11046
c19d1205 11047 if (unified_syntax)
a737bd4d 11048 {
c19d1205 11049 if (!inst.operands[2].isreg)
b99bd4ef 11050 {
c19d1205
ZW
11051 /* For an immediate, we always generate a 32-bit opcode;
11052 section relaxation will shrink it later if possible. */
11053 inst.instruction = THUMB_OP32 (inst.instruction);
11054 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
11055 inst.instruction |= Rd << 8;
11056 inst.instruction |= Rs << 16;
e2b0ab59 11057 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 11058 }
c19d1205 11059 else
a737bd4d 11060 {
e27ec89e
PB
11061 bfd_boolean narrow;
11062
c19d1205 11063 /* See if we can do this with a 16-bit instruction. */
e27ec89e 11064 if (THUMB_SETS_FLAGS (inst.instruction))
e07e6e58 11065 narrow = !in_it_block ();
e27ec89e 11066 else
e07e6e58 11067 narrow = in_it_block ();
e27ec89e
PB
11068
11069 if (Rd > 7 || Rn > 7 || Rs > 7)
11070 narrow = FALSE;
11071 if (inst.operands[2].shifted)
11072 narrow = FALSE;
11073 if (inst.size_req == 4)
11074 narrow = FALSE;
11075
11076 if (narrow)
a737bd4d 11077 {
c19d1205 11078 if (Rd == Rs)
a737bd4d 11079 {
c19d1205
ZW
11080 inst.instruction = THUMB_OP16 (inst.instruction);
11081 inst.instruction |= Rd;
11082 inst.instruction |= Rn << 3;
11083 return;
a737bd4d 11084 }
c19d1205 11085 if (Rd == Rn)
a737bd4d 11086 {
c19d1205
ZW
11087 inst.instruction = THUMB_OP16 (inst.instruction);
11088 inst.instruction |= Rd;
11089 inst.instruction |= Rs << 3;
11090 return;
a737bd4d
NC
11091 }
11092 }
c19d1205
ZW
11093
11094 /* If we get here, it can't be done in 16 bits. */
11095 constraint (inst.operands[2].shifted
11096 && inst.operands[2].immisreg,
11097 _("shift must be constant"));
11098 inst.instruction = THUMB_OP32 (inst.instruction);
11099 inst.instruction |= Rd << 8;
11100 inst.instruction |= Rs << 16;
11101 encode_thumb32_shifted_operand (2);
a737bd4d 11102 }
b99bd4ef 11103 }
c19d1205
ZW
11104 else
11105 {
11106 /* On its face this is a lie - the instruction does set the
11107 flags. However, the only supported mnemonic in this mode
11108 says it doesn't. */
11109 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 11110
c19d1205
ZW
11111 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
11112 _("unshifted register required"));
11113 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
11114
11115 inst.instruction = THUMB_OP16 (inst.instruction);
11116 inst.instruction |= Rd;
11117
11118 if (Rd == Rs)
11119 inst.instruction |= Rn << 3;
11120 else if (Rd == Rn)
11121 inst.instruction |= Rs << 3;
11122 else
11123 constraint (1, _("dest must overlap one source register"));
11124 }
a737bd4d
NC
11125}
11126
c19d1205
ZW
11127static void
11128do_t_bfc (void)
a737bd4d 11129{
fdfde340 11130 unsigned Rd;
c19d1205
ZW
11131 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
11132 constraint (msb > 32, _("bit-field extends past end of register"));
11133 /* The instruction encoding stores the LSB and MSB,
11134 not the LSB and width. */
fdfde340
JM
11135 Rd = inst.operands[0].reg;
11136 reject_bad_reg (Rd);
11137 inst.instruction |= Rd << 8;
c19d1205
ZW
11138 inst.instruction |= (inst.operands[1].imm & 0x1c) << 10;
11139 inst.instruction |= (inst.operands[1].imm & 0x03) << 6;
11140 inst.instruction |= msb - 1;
b99bd4ef
NC
11141}
11142
c19d1205
ZW
11143static void
11144do_t_bfi (void)
b99bd4ef 11145{
fdfde340 11146 int Rd, Rn;
c19d1205 11147 unsigned int msb;
b99bd4ef 11148
fdfde340
JM
11149 Rd = inst.operands[0].reg;
11150 reject_bad_reg (Rd);
11151
c19d1205
ZW
11152 /* #0 in second position is alternative syntax for bfc, which is
11153 the same instruction but with REG_PC in the Rm field. */
11154 if (!inst.operands[1].isreg)
fdfde340
JM
11155 Rn = REG_PC;
11156 else
11157 {
11158 Rn = inst.operands[1].reg;
11159 reject_bad_reg (Rn);
11160 }
b99bd4ef 11161
c19d1205
ZW
11162 msb = inst.operands[2].imm + inst.operands[3].imm;
11163 constraint (msb > 32, _("bit-field extends past end of register"));
11164 /* The instruction encoding stores the LSB and MSB,
11165 not the LSB and width. */
fdfde340
JM
11166 inst.instruction |= Rd << 8;
11167 inst.instruction |= Rn << 16;
c19d1205
ZW
11168 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
11169 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
11170 inst.instruction |= msb - 1;
b99bd4ef
NC
11171}
11172
c19d1205
ZW
11173static void
11174do_t_bfx (void)
b99bd4ef 11175{
fdfde340
JM
11176 unsigned Rd, Rn;
11177
11178 Rd = inst.operands[0].reg;
11179 Rn = inst.operands[1].reg;
11180
11181 reject_bad_reg (Rd);
11182 reject_bad_reg (Rn);
11183
c19d1205
ZW
11184 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
11185 _("bit-field extends past end of register"));
fdfde340
JM
11186 inst.instruction |= Rd << 8;
11187 inst.instruction |= Rn << 16;
c19d1205
ZW
11188 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
11189 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
11190 inst.instruction |= inst.operands[3].imm - 1;
11191}
b99bd4ef 11192
c19d1205
ZW
11193/* ARM V5 Thumb BLX (argument parse)
11194 BLX <target_addr> which is BLX(1)
11195 BLX <Rm> which is BLX(2)
11196 Unfortunately, there are two different opcodes for this mnemonic.
11197 So, the insns[].value is not used, and the code here zaps values
11198 into inst.instruction.
b99bd4ef 11199
c19d1205
ZW
11200 ??? How to take advantage of the additional two bits of displacement
11201 available in Thumb32 mode? Need new relocation? */
b99bd4ef 11202
c19d1205
ZW
11203static void
11204do_t_blx (void)
11205{
e07e6e58
NC
11206 set_it_insn_type_last ();
11207
c19d1205 11208 if (inst.operands[0].isreg)
fdfde340
JM
11209 {
11210 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
11211 /* We have a register, so this is BLX(2). */
11212 inst.instruction |= inst.operands[0].reg << 3;
11213 }
b99bd4ef
NC
11214 else
11215 {
c19d1205 11216 /* No register. This must be BLX(1). */
2fc8bdac 11217 inst.instruction = 0xf000e800;
0855e32b 11218 encode_branch (BFD_RELOC_THUMB_PCREL_BLX);
b99bd4ef
NC
11219 }
11220}
11221
c19d1205
ZW
11222static void
11223do_t_branch (void)
b99bd4ef 11224{
0110f2b8 11225 int opcode;
dfa9f0d5 11226 int cond;
2fe88214 11227 bfd_reloc_code_real_type reloc;
dfa9f0d5 11228
e07e6e58
NC
11229 cond = inst.cond;
11230 set_it_insn_type (IF_INSIDE_IT_LAST_INSN);
11231
11232 if (in_it_block ())
dfa9f0d5
PB
11233 {
11234 /* Conditional branches inside IT blocks are encoded as unconditional
477330fc 11235 branches. */
dfa9f0d5 11236 cond = COND_ALWAYS;
dfa9f0d5
PB
11237 }
11238 else
11239 cond = inst.cond;
11240
11241 if (cond != COND_ALWAYS)
0110f2b8
PB
11242 opcode = T_MNEM_bcond;
11243 else
11244 opcode = inst.instruction;
11245
12d6b0b7
RS
11246 if (unified_syntax
11247 && (inst.size_req == 4
10960bfb
PB
11248 || (inst.size_req != 2
11249 && (inst.operands[0].hasreloc
e2b0ab59 11250 || inst.relocs[0].exp.X_op == O_constant))))
c19d1205 11251 {
0110f2b8 11252 inst.instruction = THUMB_OP32(opcode);
dfa9f0d5 11253 if (cond == COND_ALWAYS)
9ae92b05 11254 reloc = BFD_RELOC_THUMB_PCREL_BRANCH25;
c19d1205
ZW
11255 else
11256 {
ff8646ee
TP
11257 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2),
11258 _("selected architecture does not support "
11259 "wide conditional branch instruction"));
11260
9c2799c2 11261 gas_assert (cond != 0xF);
dfa9f0d5 11262 inst.instruction |= cond << 22;
9ae92b05 11263 reloc = BFD_RELOC_THUMB_PCREL_BRANCH20;
c19d1205
ZW
11264 }
11265 }
b99bd4ef
NC
11266 else
11267 {
0110f2b8 11268 inst.instruction = THUMB_OP16(opcode);
dfa9f0d5 11269 if (cond == COND_ALWAYS)
9ae92b05 11270 reloc = BFD_RELOC_THUMB_PCREL_BRANCH12;
c19d1205 11271 else
b99bd4ef 11272 {
dfa9f0d5 11273 inst.instruction |= cond << 8;
9ae92b05 11274 reloc = BFD_RELOC_THUMB_PCREL_BRANCH9;
b99bd4ef 11275 }
0110f2b8
PB
11276 /* Allow section relaxation. */
11277 if (unified_syntax && inst.size_req != 2)
11278 inst.relax = opcode;
b99bd4ef 11279 }
e2b0ab59
AV
11280 inst.relocs[0].type = reloc;
11281 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
11282}
11283
8884b720 11284/* Actually do the work for Thumb state bkpt and hlt. The only difference
bacebabc 11285 between the two is the maximum immediate allowed - which is passed in
8884b720 11286 RANGE. */
b99bd4ef 11287static void
8884b720 11288do_t_bkpt_hlt1 (int range)
b99bd4ef 11289{
dfa9f0d5
PB
11290 constraint (inst.cond != COND_ALWAYS,
11291 _("instruction is always unconditional"));
c19d1205 11292 if (inst.operands[0].present)
b99bd4ef 11293 {
8884b720 11294 constraint (inst.operands[0].imm > range,
c19d1205
ZW
11295 _("immediate value out of range"));
11296 inst.instruction |= inst.operands[0].imm;
b99bd4ef 11297 }
8884b720
MGD
11298
11299 set_it_insn_type (NEUTRAL_IT_INSN);
11300}
11301
11302static void
11303do_t_hlt (void)
11304{
11305 do_t_bkpt_hlt1 (63);
11306}
11307
11308static void
11309do_t_bkpt (void)
11310{
11311 do_t_bkpt_hlt1 (255);
b99bd4ef
NC
11312}
11313
11314static void
c19d1205 11315do_t_branch23 (void)
b99bd4ef 11316{
e07e6e58 11317 set_it_insn_type_last ();
0855e32b 11318 encode_branch (BFD_RELOC_THUMB_PCREL_BRANCH23);
fa94de6b 11319
0855e32b
NS
11320 /* md_apply_fix blows up with 'bl foo(PLT)' where foo is defined in
11321 this file. We used to simply ignore the PLT reloc type here --
11322 the branch encoding is now needed to deal with TLSCALL relocs.
11323 So if we see a PLT reloc now, put it back to how it used to be to
11324 keep the preexisting behaviour. */
e2b0ab59
AV
11325 if (inst.relocs[0].type == BFD_RELOC_ARM_PLT32)
11326 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH23;
90e4755a 11327
4343666d 11328#if defined(OBJ_COFF)
c19d1205
ZW
11329 /* If the destination of the branch is a defined symbol which does not have
11330 the THUMB_FUNC attribute, then we must be calling a function which has
11331 the (interfacearm) attribute. We look for the Thumb entry point to that
11332 function and change the branch to refer to that function instead. */
e2b0ab59
AV
11333 if ( inst.relocs[0].exp.X_op == O_symbol
11334 && inst.relocs[0].exp.X_add_symbol != NULL
11335 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
11336 && ! THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
11337 inst.relocs[0].exp.X_add_symbol
11338 = find_real_start (inst.relocs[0].exp.X_add_symbol);
4343666d 11339#endif
90e4755a
RE
11340}
11341
11342static void
c19d1205 11343do_t_bx (void)
90e4755a 11344{
e07e6e58 11345 set_it_insn_type_last ();
c19d1205
ZW
11346 inst.instruction |= inst.operands[0].reg << 3;
11347 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
11348 should cause the alignment to be checked once it is known. This is
11349 because BX PC only works if the instruction is word aligned. */
11350}
90e4755a 11351
c19d1205
ZW
11352static void
11353do_t_bxj (void)
11354{
fdfde340 11355 int Rm;
90e4755a 11356
e07e6e58 11357 set_it_insn_type_last ();
fdfde340
JM
11358 Rm = inst.operands[0].reg;
11359 reject_bad_reg (Rm);
11360 inst.instruction |= Rm << 16;
90e4755a
RE
11361}
11362
11363static void
c19d1205 11364do_t_clz (void)
90e4755a 11365{
fdfde340
JM
11366 unsigned Rd;
11367 unsigned Rm;
11368
11369 Rd = inst.operands[0].reg;
11370 Rm = inst.operands[1].reg;
11371
11372 reject_bad_reg (Rd);
11373 reject_bad_reg (Rm);
11374
11375 inst.instruction |= Rd << 8;
11376 inst.instruction |= Rm << 16;
11377 inst.instruction |= Rm;
c19d1205 11378}
90e4755a 11379
91d8b670
JG
11380static void
11381do_t_csdb (void)
11382{
11383 set_it_insn_type (OUTSIDE_IT_INSN);
11384}
11385
dfa9f0d5
PB
11386static void
11387do_t_cps (void)
11388{
e07e6e58 11389 set_it_insn_type (OUTSIDE_IT_INSN);
dfa9f0d5
PB
11390 inst.instruction |= inst.operands[0].imm;
11391}
11392
c19d1205
ZW
11393static void
11394do_t_cpsi (void)
11395{
e07e6e58 11396 set_it_insn_type (OUTSIDE_IT_INSN);
c19d1205 11397 if (unified_syntax
62b3e311
PB
11398 && (inst.operands[1].present || inst.size_req == 4)
11399 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6_notm))
90e4755a 11400 {
c19d1205
ZW
11401 unsigned int imod = (inst.instruction & 0x0030) >> 4;
11402 inst.instruction = 0xf3af8000;
11403 inst.instruction |= imod << 9;
11404 inst.instruction |= inst.operands[0].imm << 5;
11405 if (inst.operands[1].present)
11406 inst.instruction |= 0x100 | inst.operands[1].imm;
90e4755a 11407 }
c19d1205 11408 else
90e4755a 11409 {
62b3e311
PB
11410 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1)
11411 && (inst.operands[0].imm & 4),
11412 _("selected processor does not support 'A' form "
11413 "of this instruction"));
11414 constraint (inst.operands[1].present || inst.size_req == 4,
c19d1205
ZW
11415 _("Thumb does not support the 2-argument "
11416 "form of this instruction"));
11417 inst.instruction |= inst.operands[0].imm;
90e4755a 11418 }
90e4755a
RE
11419}
11420
c19d1205
ZW
11421/* THUMB CPY instruction (argument parse). */
11422
90e4755a 11423static void
c19d1205 11424do_t_cpy (void)
90e4755a 11425{
c19d1205 11426 if (inst.size_req == 4)
90e4755a 11427 {
c19d1205
ZW
11428 inst.instruction = THUMB_OP32 (T_MNEM_mov);
11429 inst.instruction |= inst.operands[0].reg << 8;
11430 inst.instruction |= inst.operands[1].reg;
90e4755a 11431 }
c19d1205 11432 else
90e4755a 11433 {
c19d1205
ZW
11434 inst.instruction |= (inst.operands[0].reg & 0x8) << 4;
11435 inst.instruction |= (inst.operands[0].reg & 0x7);
11436 inst.instruction |= inst.operands[1].reg << 3;
90e4755a 11437 }
90e4755a
RE
11438}
11439
90e4755a 11440static void
25fe350b 11441do_t_cbz (void)
90e4755a 11442{
e07e6e58 11443 set_it_insn_type (OUTSIDE_IT_INSN);
c19d1205
ZW
11444 constraint (inst.operands[0].reg > 7, BAD_HIREG);
11445 inst.instruction |= inst.operands[0].reg;
e2b0ab59
AV
11446 inst.relocs[0].pc_rel = 1;
11447 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH7;
c19d1205 11448}
90e4755a 11449
62b3e311
PB
11450static void
11451do_t_dbg (void)
11452{
11453 inst.instruction |= inst.operands[0].imm;
11454}
11455
11456static void
11457do_t_div (void)
11458{
fdfde340
JM
11459 unsigned Rd, Rn, Rm;
11460
11461 Rd = inst.operands[0].reg;
11462 Rn = (inst.operands[1].present
11463 ? inst.operands[1].reg : Rd);
11464 Rm = inst.operands[2].reg;
11465
11466 reject_bad_reg (Rd);
11467 reject_bad_reg (Rn);
11468 reject_bad_reg (Rm);
11469
11470 inst.instruction |= Rd << 8;
11471 inst.instruction |= Rn << 16;
11472 inst.instruction |= Rm;
62b3e311
PB
11473}
11474
c19d1205
ZW
11475static void
11476do_t_hint (void)
11477{
11478 if (unified_syntax && inst.size_req == 4)
11479 inst.instruction = THUMB_OP32 (inst.instruction);
11480 else
11481 inst.instruction = THUMB_OP16 (inst.instruction);
11482}
90e4755a 11483
c19d1205
ZW
11484static void
11485do_t_it (void)
11486{
11487 unsigned int cond = inst.operands[0].imm;
e27ec89e 11488
e07e6e58
NC
11489 set_it_insn_type (IT_INSN);
11490 now_it.mask = (inst.instruction & 0xf) | 0x10;
11491 now_it.cc = cond;
5a01bb1d 11492 now_it.warn_deprecated = FALSE;
e27ec89e
PB
11493
11494 /* If the condition is a negative condition, invert the mask. */
c19d1205 11495 if ((cond & 0x1) == 0x0)
90e4755a 11496 {
c19d1205 11497 unsigned int mask = inst.instruction & 0x000f;
90e4755a 11498
c19d1205 11499 if ((mask & 0x7) == 0)
5a01bb1d
MGD
11500 {
11501 /* No conversion needed. */
11502 now_it.block_length = 1;
11503 }
c19d1205 11504 else if ((mask & 0x3) == 0)
5a01bb1d
MGD
11505 {
11506 mask ^= 0x8;
11507 now_it.block_length = 2;
11508 }
e27ec89e 11509 else if ((mask & 0x1) == 0)
5a01bb1d
MGD
11510 {
11511 mask ^= 0xC;
11512 now_it.block_length = 3;
11513 }
c19d1205 11514 else
5a01bb1d
MGD
11515 {
11516 mask ^= 0xE;
11517 now_it.block_length = 4;
11518 }
90e4755a 11519
e27ec89e
PB
11520 inst.instruction &= 0xfff0;
11521 inst.instruction |= mask;
c19d1205 11522 }
90e4755a 11523
c19d1205
ZW
11524 inst.instruction |= cond << 4;
11525}
90e4755a 11526
3c707909
PB
11527/* Helper function used for both push/pop and ldm/stm. */
11528static void
4b5a202f
AV
11529encode_thumb2_multi (bfd_boolean do_io, int base, unsigned mask,
11530 bfd_boolean writeback)
3c707909 11531{
4b5a202f 11532 bfd_boolean load, store;
3c707909 11533
4b5a202f
AV
11534 gas_assert (base != -1 || !do_io);
11535 load = do_io && ((inst.instruction & (1 << 20)) != 0);
11536 store = do_io && !load;
3c707909
PB
11537
11538 if (mask & (1 << 13))
11539 inst.error = _("SP not allowed in register list");
1e5b0379 11540
4b5a202f 11541 if (do_io && (mask & (1 << base)) != 0
1e5b0379
NC
11542 && writeback)
11543 inst.error = _("having the base register in the register list when "
11544 "using write back is UNPREDICTABLE");
11545
3c707909
PB
11546 if (load)
11547 {
e07e6e58 11548 if (mask & (1 << 15))
477330fc
RM
11549 {
11550 if (mask & (1 << 14))
11551 inst.error = _("LR and PC should not both be in register list");
11552 else
11553 set_it_insn_type_last ();
11554 }
3c707909 11555 }
4b5a202f 11556 else if (store)
3c707909
PB
11557 {
11558 if (mask & (1 << 15))
11559 inst.error = _("PC not allowed in register list");
3c707909
PB
11560 }
11561
4b5a202f 11562 if (do_io && ((mask & (mask - 1)) == 0))
3c707909
PB
11563 {
11564 /* Single register transfers implemented as str/ldr. */
11565 if (writeback)
11566 {
11567 if (inst.instruction & (1 << 23))
11568 inst.instruction = 0x00000b04; /* ia! -> [base], #4 */
11569 else
11570 inst.instruction = 0x00000d04; /* db! -> [base, #-4]! */
11571 }
11572 else
11573 {
11574 if (inst.instruction & (1 << 23))
11575 inst.instruction = 0x00800000; /* ia -> [base] */
11576 else
11577 inst.instruction = 0x00000c04; /* db -> [base, #-4] */
11578 }
11579
11580 inst.instruction |= 0xf8400000;
11581 if (load)
11582 inst.instruction |= 0x00100000;
11583
5f4273c7 11584 mask = ffs (mask) - 1;
3c707909
PB
11585 mask <<= 12;
11586 }
11587 else if (writeback)
11588 inst.instruction |= WRITE_BACK;
11589
11590 inst.instruction |= mask;
4b5a202f
AV
11591 if (do_io)
11592 inst.instruction |= base << 16;
3c707909
PB
11593}
11594
c19d1205
ZW
11595static void
11596do_t_ldmstm (void)
11597{
11598 /* This really doesn't seem worth it. */
e2b0ab59 11599 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205
ZW
11600 _("expression too complex"));
11601 constraint (inst.operands[1].writeback,
11602 _("Thumb load/store multiple does not support {reglist}^"));
90e4755a 11603
c19d1205
ZW
11604 if (unified_syntax)
11605 {
3c707909
PB
11606 bfd_boolean narrow;
11607 unsigned mask;
11608
11609 narrow = FALSE;
c19d1205
ZW
11610 /* See if we can use a 16-bit instruction. */
11611 if (inst.instruction < 0xffff /* not ldmdb/stmdb */
11612 && inst.size_req != 4
3c707909 11613 && !(inst.operands[1].imm & ~0xff))
90e4755a 11614 {
3c707909 11615 mask = 1 << inst.operands[0].reg;
90e4755a 11616
eab4f823 11617 if (inst.operands[0].reg <= 7)
90e4755a 11618 {
3c707909 11619 if (inst.instruction == T_MNEM_stmia
eab4f823
MGD
11620 ? inst.operands[0].writeback
11621 : (inst.operands[0].writeback
11622 == !(inst.operands[1].imm & mask)))
477330fc 11623 {
eab4f823
MGD
11624 if (inst.instruction == T_MNEM_stmia
11625 && (inst.operands[1].imm & mask)
11626 && (inst.operands[1].imm & (mask - 1)))
11627 as_warn (_("value stored for r%d is UNKNOWN"),
11628 inst.operands[0].reg);
3c707909 11629
eab4f823
MGD
11630 inst.instruction = THUMB_OP16 (inst.instruction);
11631 inst.instruction |= inst.operands[0].reg << 8;
11632 inst.instruction |= inst.operands[1].imm;
11633 narrow = TRUE;
11634 }
11635 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
11636 {
11637 /* This means 1 register in reg list one of 3 situations:
11638 1. Instruction is stmia, but without writeback.
11639 2. lmdia without writeback, but with Rn not in
477330fc 11640 reglist.
eab4f823
MGD
11641 3. ldmia with writeback, but with Rn in reglist.
11642 Case 3 is UNPREDICTABLE behaviour, so we handle
11643 case 1 and 2 which can be converted into a 16-bit
11644 str or ldr. The SP cases are handled below. */
11645 unsigned long opcode;
11646 /* First, record an error for Case 3. */
11647 if (inst.operands[1].imm & mask
11648 && inst.operands[0].writeback)
fa94de6b 11649 inst.error =
eab4f823
MGD
11650 _("having the base register in the register list when "
11651 "using write back is UNPREDICTABLE");
fa94de6b
RM
11652
11653 opcode = (inst.instruction == T_MNEM_stmia ? T_MNEM_str
eab4f823
MGD
11654 : T_MNEM_ldr);
11655 inst.instruction = THUMB_OP16 (opcode);
11656 inst.instruction |= inst.operands[0].reg << 3;
11657 inst.instruction |= (ffs (inst.operands[1].imm)-1);
11658 narrow = TRUE;
11659 }
90e4755a 11660 }
eab4f823 11661 else if (inst.operands[0] .reg == REG_SP)
90e4755a 11662 {
eab4f823
MGD
11663 if (inst.operands[0].writeback)
11664 {
fa94de6b 11665 inst.instruction =
eab4f823 11666 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 11667 ? T_MNEM_push : T_MNEM_pop);
eab4f823 11668 inst.instruction |= inst.operands[1].imm;
477330fc 11669 narrow = TRUE;
eab4f823
MGD
11670 }
11671 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
11672 {
fa94de6b 11673 inst.instruction =
eab4f823 11674 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 11675 ? T_MNEM_str_sp : T_MNEM_ldr_sp);
eab4f823 11676 inst.instruction |= ((ffs (inst.operands[1].imm)-1) << 8);
477330fc 11677 narrow = TRUE;
eab4f823 11678 }
90e4755a 11679 }
3c707909
PB
11680 }
11681
11682 if (!narrow)
11683 {
c19d1205
ZW
11684 if (inst.instruction < 0xffff)
11685 inst.instruction = THUMB_OP32 (inst.instruction);
3c707909 11686
4b5a202f
AV
11687 encode_thumb2_multi (TRUE /* do_io */, inst.operands[0].reg,
11688 inst.operands[1].imm,
11689 inst.operands[0].writeback);
90e4755a
RE
11690 }
11691 }
c19d1205 11692 else
90e4755a 11693 {
c19d1205
ZW
11694 constraint (inst.operands[0].reg > 7
11695 || (inst.operands[1].imm & ~0xff), BAD_HIREG);
1198ca51
PB
11696 constraint (inst.instruction != T_MNEM_ldmia
11697 && inst.instruction != T_MNEM_stmia,
11698 _("Thumb-2 instruction only valid in unified syntax"));
c19d1205 11699 if (inst.instruction == T_MNEM_stmia)
f03698e6 11700 {
c19d1205
ZW
11701 if (!inst.operands[0].writeback)
11702 as_warn (_("this instruction will write back the base register"));
11703 if ((inst.operands[1].imm & (1 << inst.operands[0].reg))
11704 && (inst.operands[1].imm & ((1 << inst.operands[0].reg) - 1)))
1e5b0379 11705 as_warn (_("value stored for r%d is UNKNOWN"),
c19d1205 11706 inst.operands[0].reg);
f03698e6 11707 }
c19d1205 11708 else
90e4755a 11709 {
c19d1205
ZW
11710 if (!inst.operands[0].writeback
11711 && !(inst.operands[1].imm & (1 << inst.operands[0].reg)))
11712 as_warn (_("this instruction will write back the base register"));
11713 else if (inst.operands[0].writeback
11714 && (inst.operands[1].imm & (1 << inst.operands[0].reg)))
11715 as_warn (_("this instruction will not write back the base register"));
90e4755a
RE
11716 }
11717
c19d1205
ZW
11718 inst.instruction = THUMB_OP16 (inst.instruction);
11719 inst.instruction |= inst.operands[0].reg << 8;
11720 inst.instruction |= inst.operands[1].imm;
11721 }
11722}
e28cd48c 11723
c19d1205
ZW
11724static void
11725do_t_ldrex (void)
11726{
11727 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
11728 || inst.operands[1].postind || inst.operands[1].writeback
11729 || inst.operands[1].immisreg || inst.operands[1].shifted
11730 || inst.operands[1].negative,
01cfc07f 11731 BAD_ADDR_MODE);
e28cd48c 11732
5be8be5d
DG
11733 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
11734
c19d1205
ZW
11735 inst.instruction |= inst.operands[0].reg << 12;
11736 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 11737 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
c19d1205 11738}
e28cd48c 11739
c19d1205
ZW
11740static void
11741do_t_ldrexd (void)
11742{
11743 if (!inst.operands[1].present)
1cac9012 11744 {
c19d1205
ZW
11745 constraint (inst.operands[0].reg == REG_LR,
11746 _("r14 not allowed as first register "
11747 "when second register is omitted"));
11748 inst.operands[1].reg = inst.operands[0].reg + 1;
b99bd4ef 11749 }
c19d1205
ZW
11750 constraint (inst.operands[0].reg == inst.operands[1].reg,
11751 BAD_OVERLAP);
b99bd4ef 11752
c19d1205
ZW
11753 inst.instruction |= inst.operands[0].reg << 12;
11754 inst.instruction |= inst.operands[1].reg << 8;
11755 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
11756}
11757
11758static void
c19d1205 11759do_t_ldst (void)
b99bd4ef 11760{
0110f2b8
PB
11761 unsigned long opcode;
11762 int Rn;
11763
e07e6e58
NC
11764 if (inst.operands[0].isreg
11765 && !inst.operands[0].preind
11766 && inst.operands[0].reg == REG_PC)
11767 set_it_insn_type_last ();
11768
0110f2b8 11769 opcode = inst.instruction;
c19d1205 11770 if (unified_syntax)
b99bd4ef 11771 {
53365c0d
PB
11772 if (!inst.operands[1].isreg)
11773 {
11774 if (opcode <= 0xffff)
11775 inst.instruction = THUMB_OP32 (opcode);
8335d6aa 11776 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/FALSE))
53365c0d
PB
11777 return;
11778 }
0110f2b8
PB
11779 if (inst.operands[1].isreg
11780 && !inst.operands[1].writeback
c19d1205
ZW
11781 && !inst.operands[1].shifted && !inst.operands[1].postind
11782 && !inst.operands[1].negative && inst.operands[0].reg <= 7
0110f2b8
PB
11783 && opcode <= 0xffff
11784 && inst.size_req != 4)
c19d1205 11785 {
0110f2b8
PB
11786 /* Insn may have a 16-bit form. */
11787 Rn = inst.operands[1].reg;
11788 if (inst.operands[1].immisreg)
11789 {
11790 inst.instruction = THUMB_OP16 (opcode);
5f4273c7 11791 /* [Rn, Rik] */
0110f2b8
PB
11792 if (Rn <= 7 && inst.operands[1].imm <= 7)
11793 goto op16;
5be8be5d
DG
11794 else if (opcode != T_MNEM_ldr && opcode != T_MNEM_str)
11795 reject_bad_reg (inst.operands[1].imm);
0110f2b8
PB
11796 }
11797 else if ((Rn <= 7 && opcode != T_MNEM_ldrsh
11798 && opcode != T_MNEM_ldrsb)
11799 || ((Rn == REG_PC || Rn == REG_SP) && opcode == T_MNEM_ldr)
11800 || (Rn == REG_SP && opcode == T_MNEM_str))
11801 {
11802 /* [Rn, #const] */
11803 if (Rn > 7)
11804 {
11805 if (Rn == REG_PC)
11806 {
e2b0ab59 11807 if (inst.relocs[0].pc_rel)
0110f2b8
PB
11808 opcode = T_MNEM_ldr_pc2;
11809 else
11810 opcode = T_MNEM_ldr_pc;
11811 }
11812 else
11813 {
11814 if (opcode == T_MNEM_ldr)
11815 opcode = T_MNEM_ldr_sp;
11816 else
11817 opcode = T_MNEM_str_sp;
11818 }
11819 inst.instruction = inst.operands[0].reg << 8;
11820 }
11821 else
11822 {
11823 inst.instruction = inst.operands[0].reg;
11824 inst.instruction |= inst.operands[1].reg << 3;
11825 }
11826 inst.instruction |= THUMB_OP16 (opcode);
11827 if (inst.size_req == 2)
e2b0ab59 11828 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
0110f2b8
PB
11829 else
11830 inst.relax = opcode;
11831 return;
11832 }
c19d1205 11833 }
0110f2b8 11834 /* Definitely a 32-bit variant. */
5be8be5d 11835
8d67f500
NC
11836 /* Warning for Erratum 752419. */
11837 if (opcode == T_MNEM_ldr
11838 && inst.operands[0].reg == REG_SP
11839 && inst.operands[1].writeback == 1
11840 && !inst.operands[1].immisreg)
11841 {
11842 if (no_cpu_selected ()
11843 || (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7)
477330fc
RM
11844 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a)
11845 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7r)))
8d67f500
NC
11846 as_warn (_("This instruction may be unpredictable "
11847 "if executed on M-profile cores "
11848 "with interrupts enabled."));
11849 }
11850
5be8be5d 11851 /* Do some validations regarding addressing modes. */
1be5fd2e 11852 if (inst.operands[1].immisreg)
5be8be5d
DG
11853 reject_bad_reg (inst.operands[1].imm);
11854
1be5fd2e
NC
11855 constraint (inst.operands[1].writeback == 1
11856 && inst.operands[0].reg == inst.operands[1].reg,
11857 BAD_OVERLAP);
11858
0110f2b8 11859 inst.instruction = THUMB_OP32 (opcode);
c19d1205
ZW
11860 inst.instruction |= inst.operands[0].reg << 12;
11861 encode_thumb32_addr_mode (1, /*is_t=*/FALSE, /*is_d=*/FALSE);
1be5fd2e 11862 check_ldr_r15_aligned ();
b99bd4ef
NC
11863 return;
11864 }
11865
c19d1205
ZW
11866 constraint (inst.operands[0].reg > 7, BAD_HIREG);
11867
11868 if (inst.instruction == T_MNEM_ldrsh || inst.instruction == T_MNEM_ldrsb)
b99bd4ef 11869 {
c19d1205
ZW
11870 /* Only [Rn,Rm] is acceptable. */
11871 constraint (inst.operands[1].reg > 7 || inst.operands[1].imm > 7, BAD_HIREG);
11872 constraint (!inst.operands[1].isreg || !inst.operands[1].immisreg
11873 || inst.operands[1].postind || inst.operands[1].shifted
11874 || inst.operands[1].negative,
11875 _("Thumb does not support this addressing mode"));
11876 inst.instruction = THUMB_OP16 (inst.instruction);
11877 goto op16;
b99bd4ef 11878 }
5f4273c7 11879
c19d1205
ZW
11880 inst.instruction = THUMB_OP16 (inst.instruction);
11881 if (!inst.operands[1].isreg)
8335d6aa 11882 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/FALSE))
c19d1205 11883 return;
b99bd4ef 11884
c19d1205
ZW
11885 constraint (!inst.operands[1].preind
11886 || inst.operands[1].shifted
11887 || inst.operands[1].writeback,
11888 _("Thumb does not support this addressing mode"));
11889 if (inst.operands[1].reg == REG_PC || inst.operands[1].reg == REG_SP)
90e4755a 11890 {
c19d1205
ZW
11891 constraint (inst.instruction & 0x0600,
11892 _("byte or halfword not valid for base register"));
11893 constraint (inst.operands[1].reg == REG_PC
11894 && !(inst.instruction & THUMB_LOAD_BIT),
11895 _("r15 based store not allowed"));
11896 constraint (inst.operands[1].immisreg,
11897 _("invalid base register for register offset"));
b99bd4ef 11898
c19d1205
ZW
11899 if (inst.operands[1].reg == REG_PC)
11900 inst.instruction = T_OPCODE_LDR_PC;
11901 else if (inst.instruction & THUMB_LOAD_BIT)
11902 inst.instruction = T_OPCODE_LDR_SP;
11903 else
11904 inst.instruction = T_OPCODE_STR_SP;
b99bd4ef 11905
c19d1205 11906 inst.instruction |= inst.operands[0].reg << 8;
e2b0ab59 11907 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
11908 return;
11909 }
90e4755a 11910
c19d1205
ZW
11911 constraint (inst.operands[1].reg > 7, BAD_HIREG);
11912 if (!inst.operands[1].immisreg)
11913 {
11914 /* Immediate offset. */
11915 inst.instruction |= inst.operands[0].reg;
11916 inst.instruction |= inst.operands[1].reg << 3;
e2b0ab59 11917 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
11918 return;
11919 }
90e4755a 11920
c19d1205
ZW
11921 /* Register offset. */
11922 constraint (inst.operands[1].imm > 7, BAD_HIREG);
11923 constraint (inst.operands[1].negative,
11924 _("Thumb does not support this addressing mode"));
90e4755a 11925
c19d1205
ZW
11926 op16:
11927 switch (inst.instruction)
11928 {
11929 case T_OPCODE_STR_IW: inst.instruction = T_OPCODE_STR_RW; break;
11930 case T_OPCODE_STR_IH: inst.instruction = T_OPCODE_STR_RH; break;
11931 case T_OPCODE_STR_IB: inst.instruction = T_OPCODE_STR_RB; break;
11932 case T_OPCODE_LDR_IW: inst.instruction = T_OPCODE_LDR_RW; break;
11933 case T_OPCODE_LDR_IH: inst.instruction = T_OPCODE_LDR_RH; break;
11934 case T_OPCODE_LDR_IB: inst.instruction = T_OPCODE_LDR_RB; break;
11935 case 0x5600 /* ldrsb */:
11936 case 0x5e00 /* ldrsh */: break;
11937 default: abort ();
11938 }
90e4755a 11939
c19d1205
ZW
11940 inst.instruction |= inst.operands[0].reg;
11941 inst.instruction |= inst.operands[1].reg << 3;
11942 inst.instruction |= inst.operands[1].imm << 6;
11943}
90e4755a 11944
c19d1205
ZW
11945static void
11946do_t_ldstd (void)
11947{
11948 if (!inst.operands[1].present)
b99bd4ef 11949 {
c19d1205
ZW
11950 inst.operands[1].reg = inst.operands[0].reg + 1;
11951 constraint (inst.operands[0].reg == REG_LR,
11952 _("r14 not allowed here"));
bd340a04 11953 constraint (inst.operands[0].reg == REG_R12,
477330fc 11954 _("r12 not allowed here"));
b99bd4ef 11955 }
bd340a04
MGD
11956
11957 if (inst.operands[2].writeback
11958 && (inst.operands[0].reg == inst.operands[2].reg
11959 || inst.operands[1].reg == inst.operands[2].reg))
11960 as_warn (_("base register written back, and overlaps "
477330fc 11961 "one of transfer registers"));
bd340a04 11962
c19d1205
ZW
11963 inst.instruction |= inst.operands[0].reg << 12;
11964 inst.instruction |= inst.operands[1].reg << 8;
11965 encode_thumb32_addr_mode (2, /*is_t=*/FALSE, /*is_d=*/TRUE);
b99bd4ef
NC
11966}
11967
c19d1205
ZW
11968static void
11969do_t_ldstt (void)
11970{
11971 inst.instruction |= inst.operands[0].reg << 12;
11972 encode_thumb32_addr_mode (1, /*is_t=*/TRUE, /*is_d=*/FALSE);
11973}
a737bd4d 11974
b99bd4ef 11975static void
c19d1205 11976do_t_mla (void)
b99bd4ef 11977{
fdfde340 11978 unsigned Rd, Rn, Rm, Ra;
c921be7d 11979
fdfde340
JM
11980 Rd = inst.operands[0].reg;
11981 Rn = inst.operands[1].reg;
11982 Rm = inst.operands[2].reg;
11983 Ra = inst.operands[3].reg;
11984
11985 reject_bad_reg (Rd);
11986 reject_bad_reg (Rn);
11987 reject_bad_reg (Rm);
11988 reject_bad_reg (Ra);
11989
11990 inst.instruction |= Rd << 8;
11991 inst.instruction |= Rn << 16;
11992 inst.instruction |= Rm;
11993 inst.instruction |= Ra << 12;
c19d1205 11994}
b99bd4ef 11995
c19d1205
ZW
11996static void
11997do_t_mlal (void)
11998{
fdfde340
JM
11999 unsigned RdLo, RdHi, Rn, Rm;
12000
12001 RdLo = inst.operands[0].reg;
12002 RdHi = inst.operands[1].reg;
12003 Rn = inst.operands[2].reg;
12004 Rm = inst.operands[3].reg;
12005
12006 reject_bad_reg (RdLo);
12007 reject_bad_reg (RdHi);
12008 reject_bad_reg (Rn);
12009 reject_bad_reg (Rm);
12010
12011 inst.instruction |= RdLo << 12;
12012 inst.instruction |= RdHi << 8;
12013 inst.instruction |= Rn << 16;
12014 inst.instruction |= Rm;
c19d1205 12015}
b99bd4ef 12016
c19d1205
ZW
12017static void
12018do_t_mov_cmp (void)
12019{
fdfde340
JM
12020 unsigned Rn, Rm;
12021
12022 Rn = inst.operands[0].reg;
12023 Rm = inst.operands[1].reg;
12024
e07e6e58
NC
12025 if (Rn == REG_PC)
12026 set_it_insn_type_last ();
12027
c19d1205 12028 if (unified_syntax)
b99bd4ef 12029 {
c19d1205
ZW
12030 int r0off = (inst.instruction == T_MNEM_mov
12031 || inst.instruction == T_MNEM_movs) ? 8 : 16;
0110f2b8 12032 unsigned long opcode;
3d388997
PB
12033 bfd_boolean narrow;
12034 bfd_boolean low_regs;
12035
fdfde340 12036 low_regs = (Rn <= 7 && Rm <= 7);
0110f2b8 12037 opcode = inst.instruction;
e07e6e58 12038 if (in_it_block ())
0110f2b8 12039 narrow = opcode != T_MNEM_movs;
3d388997 12040 else
0110f2b8 12041 narrow = opcode != T_MNEM_movs || low_regs;
3d388997
PB
12042 if (inst.size_req == 4
12043 || inst.operands[1].shifted)
12044 narrow = FALSE;
12045
efd81785
PB
12046 /* MOVS PC, LR is encoded as SUBS PC, LR, #0. */
12047 if (opcode == T_MNEM_movs && inst.operands[1].isreg
12048 && !inst.operands[1].shifted
fdfde340
JM
12049 && Rn == REG_PC
12050 && Rm == REG_LR)
efd81785
PB
12051 {
12052 inst.instruction = T2_SUBS_PC_LR;
12053 return;
12054 }
12055
fdfde340
JM
12056 if (opcode == T_MNEM_cmp)
12057 {
12058 constraint (Rn == REG_PC, BAD_PC);
94206790
MM
12059 if (narrow)
12060 {
12061 /* In the Thumb-2 ISA, use of R13 as Rm is deprecated,
12062 but valid. */
12063 warn_deprecated_sp (Rm);
12064 /* R15 was documented as a valid choice for Rm in ARMv6,
12065 but as UNPREDICTABLE in ARMv7. ARM's proprietary
12066 tools reject R15, so we do too. */
12067 constraint (Rm == REG_PC, BAD_PC);
12068 }
12069 else
12070 reject_bad_reg (Rm);
fdfde340
JM
12071 }
12072 else if (opcode == T_MNEM_mov
12073 || opcode == T_MNEM_movs)
12074 {
12075 if (inst.operands[1].isreg)
12076 {
12077 if (opcode == T_MNEM_movs)
12078 {
12079 reject_bad_reg (Rn);
12080 reject_bad_reg (Rm);
12081 }
76fa04a4
MGD
12082 else if (narrow)
12083 {
12084 /* This is mov.n. */
12085 if ((Rn == REG_SP || Rn == REG_PC)
12086 && (Rm == REG_SP || Rm == REG_PC))
12087 {
5c3696f8 12088 as_tsktsk (_("Use of r%u as a source register is "
76fa04a4
MGD
12089 "deprecated when r%u is the destination "
12090 "register."), Rm, Rn);
12091 }
12092 }
12093 else
12094 {
12095 /* This is mov.w. */
12096 constraint (Rn == REG_PC, BAD_PC);
12097 constraint (Rm == REG_PC, BAD_PC);
5c8ed6a4
JW
12098 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
12099 constraint (Rn == REG_SP && Rm == REG_SP, BAD_SP);
76fa04a4 12100 }
fdfde340
JM
12101 }
12102 else
12103 reject_bad_reg (Rn);
12104 }
12105
c19d1205
ZW
12106 if (!inst.operands[1].isreg)
12107 {
0110f2b8 12108 /* Immediate operand. */
e07e6e58 12109 if (!in_it_block () && opcode == T_MNEM_mov)
0110f2b8
PB
12110 narrow = 0;
12111 if (low_regs && narrow)
12112 {
12113 inst.instruction = THUMB_OP16 (opcode);
fdfde340 12114 inst.instruction |= Rn << 8;
e2b0ab59
AV
12115 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
12116 || inst.relocs[0].type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
72d98d16 12117 {
a9f02af8 12118 if (inst.size_req == 2)
e2b0ab59 12119 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
a9f02af8
MG
12120 else
12121 inst.relax = opcode;
72d98d16 12122 }
0110f2b8
PB
12123 }
12124 else
12125 {
e2b0ab59
AV
12126 constraint ((inst.relocs[0].type
12127 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
12128 && (inst.relocs[0].type
12129 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8
MG
12130 THUMB1_RELOC_ONLY);
12131
0110f2b8
PB
12132 inst.instruction = THUMB_OP32 (inst.instruction);
12133 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 12134 inst.instruction |= Rn << r0off;
e2b0ab59 12135 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8 12136 }
c19d1205 12137 }
728ca7c9
PB
12138 else if (inst.operands[1].shifted && inst.operands[1].immisreg
12139 && (inst.instruction == T_MNEM_mov
12140 || inst.instruction == T_MNEM_movs))
12141 {
12142 /* Register shifts are encoded as separate shift instructions. */
12143 bfd_boolean flags = (inst.instruction == T_MNEM_movs);
12144
e07e6e58 12145 if (in_it_block ())
728ca7c9
PB
12146 narrow = !flags;
12147 else
12148 narrow = flags;
12149
12150 if (inst.size_req == 4)
12151 narrow = FALSE;
12152
12153 if (!low_regs || inst.operands[1].imm > 7)
12154 narrow = FALSE;
12155
fdfde340 12156 if (Rn != Rm)
728ca7c9
PB
12157 narrow = FALSE;
12158
12159 switch (inst.operands[1].shift_kind)
12160 {
12161 case SHIFT_LSL:
12162 opcode = narrow ? T_OPCODE_LSL_R : THUMB_OP32 (T_MNEM_lsl);
12163 break;
12164 case SHIFT_ASR:
12165 opcode = narrow ? T_OPCODE_ASR_R : THUMB_OP32 (T_MNEM_asr);
12166 break;
12167 case SHIFT_LSR:
12168 opcode = narrow ? T_OPCODE_LSR_R : THUMB_OP32 (T_MNEM_lsr);
12169 break;
12170 case SHIFT_ROR:
12171 opcode = narrow ? T_OPCODE_ROR_R : THUMB_OP32 (T_MNEM_ror);
12172 break;
12173 default:
5f4273c7 12174 abort ();
728ca7c9
PB
12175 }
12176
12177 inst.instruction = opcode;
12178 if (narrow)
12179 {
fdfde340 12180 inst.instruction |= Rn;
728ca7c9
PB
12181 inst.instruction |= inst.operands[1].imm << 3;
12182 }
12183 else
12184 {
12185 if (flags)
12186 inst.instruction |= CONDS_BIT;
12187
fdfde340
JM
12188 inst.instruction |= Rn << 8;
12189 inst.instruction |= Rm << 16;
728ca7c9
PB
12190 inst.instruction |= inst.operands[1].imm;
12191 }
12192 }
3d388997 12193 else if (!narrow)
c19d1205 12194 {
728ca7c9
PB
12195 /* Some mov with immediate shift have narrow variants.
12196 Register shifts are handled above. */
12197 if (low_regs && inst.operands[1].shifted
12198 && (inst.instruction == T_MNEM_mov
12199 || inst.instruction == T_MNEM_movs))
12200 {
e07e6e58 12201 if (in_it_block ())
728ca7c9
PB
12202 narrow = (inst.instruction == T_MNEM_mov);
12203 else
12204 narrow = (inst.instruction == T_MNEM_movs);
12205 }
12206
12207 if (narrow)
12208 {
12209 switch (inst.operands[1].shift_kind)
12210 {
12211 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
12212 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
12213 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
12214 default: narrow = FALSE; break;
12215 }
12216 }
12217
12218 if (narrow)
12219 {
fdfde340
JM
12220 inst.instruction |= Rn;
12221 inst.instruction |= Rm << 3;
e2b0ab59 12222 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
728ca7c9
PB
12223 }
12224 else
12225 {
12226 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 12227 inst.instruction |= Rn << r0off;
728ca7c9
PB
12228 encode_thumb32_shifted_operand (1);
12229 }
c19d1205
ZW
12230 }
12231 else
12232 switch (inst.instruction)
12233 {
12234 case T_MNEM_mov:
837b3435 12235 /* In v4t or v5t a move of two lowregs produces unpredictable
c6400f8a
MGD
12236 results. Don't allow this. */
12237 if (low_regs)
12238 {
12239 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6),
12240 "MOV Rd, Rs with two low registers is not "
12241 "permitted on this architecture");
fa94de6b 12242 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
c6400f8a
MGD
12243 arm_ext_v6);
12244 }
12245
c19d1205 12246 inst.instruction = T_OPCODE_MOV_HR;
fdfde340
JM
12247 inst.instruction |= (Rn & 0x8) << 4;
12248 inst.instruction |= (Rn & 0x7);
12249 inst.instruction |= Rm << 3;
c19d1205 12250 break;
b99bd4ef 12251
c19d1205
ZW
12252 case T_MNEM_movs:
12253 /* We know we have low registers at this point.
941a8a52
MGD
12254 Generate LSLS Rd, Rs, #0. */
12255 inst.instruction = T_OPCODE_LSL_I;
fdfde340
JM
12256 inst.instruction |= Rn;
12257 inst.instruction |= Rm << 3;
c19d1205
ZW
12258 break;
12259
12260 case T_MNEM_cmp:
3d388997 12261 if (low_regs)
c19d1205
ZW
12262 {
12263 inst.instruction = T_OPCODE_CMP_LR;
fdfde340
JM
12264 inst.instruction |= Rn;
12265 inst.instruction |= Rm << 3;
c19d1205
ZW
12266 }
12267 else
12268 {
12269 inst.instruction = T_OPCODE_CMP_HR;
fdfde340
JM
12270 inst.instruction |= (Rn & 0x8) << 4;
12271 inst.instruction |= (Rn & 0x7);
12272 inst.instruction |= Rm << 3;
c19d1205
ZW
12273 }
12274 break;
12275 }
b99bd4ef
NC
12276 return;
12277 }
12278
c19d1205 12279 inst.instruction = THUMB_OP16 (inst.instruction);
539d4391
NC
12280
12281 /* PR 10443: Do not silently ignore shifted operands. */
12282 constraint (inst.operands[1].shifted,
12283 _("shifts in CMP/MOV instructions are only supported in unified syntax"));
12284
c19d1205 12285 if (inst.operands[1].isreg)
b99bd4ef 12286 {
fdfde340 12287 if (Rn < 8 && Rm < 8)
b99bd4ef 12288 {
c19d1205
ZW
12289 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
12290 since a MOV instruction produces unpredictable results. */
12291 if (inst.instruction == T_OPCODE_MOV_I8)
12292 inst.instruction = T_OPCODE_ADD_I3;
b99bd4ef 12293 else
c19d1205 12294 inst.instruction = T_OPCODE_CMP_LR;
b99bd4ef 12295
fdfde340
JM
12296 inst.instruction |= Rn;
12297 inst.instruction |= Rm << 3;
b99bd4ef
NC
12298 }
12299 else
12300 {
c19d1205
ZW
12301 if (inst.instruction == T_OPCODE_MOV_I8)
12302 inst.instruction = T_OPCODE_MOV_HR;
12303 else
12304 inst.instruction = T_OPCODE_CMP_HR;
12305 do_t_cpy ();
b99bd4ef
NC
12306 }
12307 }
c19d1205 12308 else
b99bd4ef 12309 {
fdfde340 12310 constraint (Rn > 7,
c19d1205 12311 _("only lo regs allowed with immediate"));
fdfde340 12312 inst.instruction |= Rn << 8;
e2b0ab59 12313 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
c19d1205
ZW
12314 }
12315}
b99bd4ef 12316
c19d1205
ZW
12317static void
12318do_t_mov16 (void)
12319{
fdfde340 12320 unsigned Rd;
b6895b4f
PB
12321 bfd_vma imm;
12322 bfd_boolean top;
12323
12324 top = (inst.instruction & 0x00800000) != 0;
e2b0ab59 12325 if (inst.relocs[0].type == BFD_RELOC_ARM_MOVW)
b6895b4f 12326 {
33eaf5de 12327 constraint (top, _(":lower16: not allowed in this instruction"));
e2b0ab59 12328 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVW;
b6895b4f 12329 }
e2b0ab59 12330 else if (inst.relocs[0].type == BFD_RELOC_ARM_MOVT)
b6895b4f 12331 {
33eaf5de 12332 constraint (!top, _(":upper16: not allowed in this instruction"));
e2b0ab59 12333 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVT;
b6895b4f
PB
12334 }
12335
fdfde340
JM
12336 Rd = inst.operands[0].reg;
12337 reject_bad_reg (Rd);
12338
12339 inst.instruction |= Rd << 8;
e2b0ab59 12340 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 12341 {
e2b0ab59 12342 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
12343 inst.instruction |= (imm & 0xf000) << 4;
12344 inst.instruction |= (imm & 0x0800) << 15;
12345 inst.instruction |= (imm & 0x0700) << 4;
12346 inst.instruction |= (imm & 0x00ff);
12347 }
c19d1205 12348}
b99bd4ef 12349
c19d1205
ZW
12350static void
12351do_t_mvn_tst (void)
12352{
fdfde340 12353 unsigned Rn, Rm;
c921be7d 12354
fdfde340
JM
12355 Rn = inst.operands[0].reg;
12356 Rm = inst.operands[1].reg;
12357
12358 if (inst.instruction == T_MNEM_cmp
12359 || inst.instruction == T_MNEM_cmn)
12360 constraint (Rn == REG_PC, BAD_PC);
12361 else
12362 reject_bad_reg (Rn);
12363 reject_bad_reg (Rm);
12364
c19d1205
ZW
12365 if (unified_syntax)
12366 {
12367 int r0off = (inst.instruction == T_MNEM_mvn
12368 || inst.instruction == T_MNEM_mvns) ? 8 : 16;
3d388997
PB
12369 bfd_boolean narrow;
12370
12371 if (inst.size_req == 4
12372 || inst.instruction > 0xffff
12373 || inst.operands[1].shifted
fdfde340 12374 || Rn > 7 || Rm > 7)
3d388997 12375 narrow = FALSE;
fe8b4cc3
KT
12376 else if (inst.instruction == T_MNEM_cmn
12377 || inst.instruction == T_MNEM_tst)
3d388997
PB
12378 narrow = TRUE;
12379 else if (THUMB_SETS_FLAGS (inst.instruction))
e07e6e58 12380 narrow = !in_it_block ();
3d388997 12381 else
e07e6e58 12382 narrow = in_it_block ();
3d388997 12383
c19d1205 12384 if (!inst.operands[1].isreg)
b99bd4ef 12385 {
c19d1205
ZW
12386 /* For an immediate, we always generate a 32-bit opcode;
12387 section relaxation will shrink it later if possible. */
12388 if (inst.instruction < 0xffff)
12389 inst.instruction = THUMB_OP32 (inst.instruction);
12390 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 12391 inst.instruction |= Rn << r0off;
e2b0ab59 12392 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 12393 }
c19d1205 12394 else
b99bd4ef 12395 {
c19d1205 12396 /* See if we can do this with a 16-bit instruction. */
3d388997 12397 if (narrow)
b99bd4ef 12398 {
c19d1205 12399 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
12400 inst.instruction |= Rn;
12401 inst.instruction |= Rm << 3;
b99bd4ef 12402 }
c19d1205 12403 else
b99bd4ef 12404 {
c19d1205
ZW
12405 constraint (inst.operands[1].shifted
12406 && inst.operands[1].immisreg,
12407 _("shift must be constant"));
12408 if (inst.instruction < 0xffff)
12409 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 12410 inst.instruction |= Rn << r0off;
c19d1205 12411 encode_thumb32_shifted_operand (1);
b99bd4ef 12412 }
b99bd4ef
NC
12413 }
12414 }
12415 else
12416 {
c19d1205
ZW
12417 constraint (inst.instruction > 0xffff
12418 || inst.instruction == T_MNEM_mvns, BAD_THUMB32);
12419 constraint (!inst.operands[1].isreg || inst.operands[1].shifted,
12420 _("unshifted register required"));
fdfde340 12421 constraint (Rn > 7 || Rm > 7,
c19d1205 12422 BAD_HIREG);
b99bd4ef 12423
c19d1205 12424 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
12425 inst.instruction |= Rn;
12426 inst.instruction |= Rm << 3;
b99bd4ef 12427 }
b99bd4ef
NC
12428}
12429
b05fe5cf 12430static void
c19d1205 12431do_t_mrs (void)
b05fe5cf 12432{
fdfde340 12433 unsigned Rd;
037e8744
JB
12434
12435 if (do_vfp_nsyn_mrs () == SUCCESS)
12436 return;
12437
90ec0d68
MGD
12438 Rd = inst.operands[0].reg;
12439 reject_bad_reg (Rd);
12440 inst.instruction |= Rd << 8;
12441
12442 if (inst.operands[1].isreg)
62b3e311 12443 {
90ec0d68
MGD
12444 unsigned br = inst.operands[1].reg;
12445 if (((br & 0x200) == 0) && ((br & 0xf000) != 0xf000))
12446 as_bad (_("bad register for mrs"));
12447
12448 inst.instruction |= br & (0xf << 16);
12449 inst.instruction |= (br & 0x300) >> 4;
12450 inst.instruction |= (br & SPSR_BIT) >> 2;
62b3e311
PB
12451 }
12452 else
12453 {
90ec0d68 12454 int flags = inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
5f4273c7 12455
d2cd1205 12456 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
1a43faaf
NC
12457 {
12458 /* PR gas/12698: The constraint is only applied for m_profile.
12459 If the user has specified -march=all, we want to ignore it as
12460 we are building for any CPU type, including non-m variants. */
823d2571
TG
12461 bfd_boolean m_profile =
12462 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf
NC
12463 constraint ((flags != 0) && m_profile, _("selected processor does "
12464 "not support requested special purpose register"));
12465 }
90ec0d68 12466 else
d2cd1205
JB
12467 /* mrs only accepts APSR/CPSR/SPSR/CPSR_all/SPSR_all (for non-M profile
12468 devices). */
12469 constraint ((flags & ~SPSR_BIT) != (PSR_c|PSR_f),
12470 _("'APSR', 'CPSR' or 'SPSR' expected"));
fdfde340 12471
90ec0d68
MGD
12472 inst.instruction |= (flags & SPSR_BIT) >> 2;
12473 inst.instruction |= inst.operands[1].imm & 0xff;
12474 inst.instruction |= 0xf0000;
12475 }
c19d1205 12476}
b05fe5cf 12477
c19d1205
ZW
12478static void
12479do_t_msr (void)
12480{
62b3e311 12481 int flags;
fdfde340 12482 unsigned Rn;
62b3e311 12483
037e8744
JB
12484 if (do_vfp_nsyn_msr () == SUCCESS)
12485 return;
12486
c19d1205
ZW
12487 constraint (!inst.operands[1].isreg,
12488 _("Thumb encoding does not support an immediate here"));
90ec0d68
MGD
12489
12490 if (inst.operands[0].isreg)
12491 flags = (int)(inst.operands[0].reg);
12492 else
12493 flags = inst.operands[0].imm;
12494
d2cd1205 12495 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
62b3e311 12496 {
d2cd1205
JB
12497 int bits = inst.operands[0].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
12498
1a43faaf 12499 /* PR gas/12698: The constraint is only applied for m_profile.
477330fc
RM
12500 If the user has specified -march=all, we want to ignore it as
12501 we are building for any CPU type, including non-m variants. */
823d2571
TG
12502 bfd_boolean m_profile =
12503 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf 12504 constraint (((ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
477330fc
RM
12505 && (bits & ~(PSR_s | PSR_f)) != 0)
12506 || (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
12507 && bits != PSR_f)) && m_profile,
12508 _("selected processor does not support requested special "
12509 "purpose register"));
62b3e311
PB
12510 }
12511 else
d2cd1205
JB
12512 constraint ((flags & 0xff) != 0, _("selected processor does not support "
12513 "requested special purpose register"));
c921be7d 12514
fdfde340
JM
12515 Rn = inst.operands[1].reg;
12516 reject_bad_reg (Rn);
12517
62b3e311 12518 inst.instruction |= (flags & SPSR_BIT) >> 2;
90ec0d68
MGD
12519 inst.instruction |= (flags & 0xf0000) >> 8;
12520 inst.instruction |= (flags & 0x300) >> 4;
62b3e311 12521 inst.instruction |= (flags & 0xff);
fdfde340 12522 inst.instruction |= Rn << 16;
c19d1205 12523}
b05fe5cf 12524
c19d1205
ZW
12525static void
12526do_t_mul (void)
12527{
17828f45 12528 bfd_boolean narrow;
fdfde340 12529 unsigned Rd, Rn, Rm;
17828f45 12530
c19d1205
ZW
12531 if (!inst.operands[2].present)
12532 inst.operands[2].reg = inst.operands[0].reg;
b05fe5cf 12533
fdfde340
JM
12534 Rd = inst.operands[0].reg;
12535 Rn = inst.operands[1].reg;
12536 Rm = inst.operands[2].reg;
12537
17828f45 12538 if (unified_syntax)
b05fe5cf 12539 {
17828f45 12540 if (inst.size_req == 4
fdfde340
JM
12541 || (Rd != Rn
12542 && Rd != Rm)
12543 || Rn > 7
12544 || Rm > 7)
17828f45
JM
12545 narrow = FALSE;
12546 else if (inst.instruction == T_MNEM_muls)
e07e6e58 12547 narrow = !in_it_block ();
17828f45 12548 else
e07e6e58 12549 narrow = in_it_block ();
b05fe5cf 12550 }
c19d1205 12551 else
b05fe5cf 12552 {
17828f45 12553 constraint (inst.instruction == T_MNEM_muls, BAD_THUMB32);
fdfde340 12554 constraint (Rn > 7 || Rm > 7,
c19d1205 12555 BAD_HIREG);
17828f45
JM
12556 narrow = TRUE;
12557 }
b05fe5cf 12558
17828f45
JM
12559 if (narrow)
12560 {
12561 /* 16-bit MULS/Conditional MUL. */
c19d1205 12562 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 12563 inst.instruction |= Rd;
b05fe5cf 12564
fdfde340
JM
12565 if (Rd == Rn)
12566 inst.instruction |= Rm << 3;
12567 else if (Rd == Rm)
12568 inst.instruction |= Rn << 3;
c19d1205
ZW
12569 else
12570 constraint (1, _("dest must overlap one source register"));
12571 }
17828f45
JM
12572 else
12573 {
e07e6e58
NC
12574 constraint (inst.instruction != T_MNEM_mul,
12575 _("Thumb-2 MUL must not set flags"));
17828f45
JM
12576 /* 32-bit MUL. */
12577 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
12578 inst.instruction |= Rd << 8;
12579 inst.instruction |= Rn << 16;
12580 inst.instruction |= Rm << 0;
12581
12582 reject_bad_reg (Rd);
12583 reject_bad_reg (Rn);
12584 reject_bad_reg (Rm);
17828f45 12585 }
c19d1205 12586}
b05fe5cf 12587
c19d1205
ZW
12588static void
12589do_t_mull (void)
12590{
fdfde340 12591 unsigned RdLo, RdHi, Rn, Rm;
b05fe5cf 12592
fdfde340
JM
12593 RdLo = inst.operands[0].reg;
12594 RdHi = inst.operands[1].reg;
12595 Rn = inst.operands[2].reg;
12596 Rm = inst.operands[3].reg;
12597
12598 reject_bad_reg (RdLo);
12599 reject_bad_reg (RdHi);
12600 reject_bad_reg (Rn);
12601 reject_bad_reg (Rm);
12602
12603 inst.instruction |= RdLo << 12;
12604 inst.instruction |= RdHi << 8;
12605 inst.instruction |= Rn << 16;
12606 inst.instruction |= Rm;
12607
12608 if (RdLo == RdHi)
c19d1205
ZW
12609 as_tsktsk (_("rdhi and rdlo must be different"));
12610}
b05fe5cf 12611
c19d1205
ZW
12612static void
12613do_t_nop (void)
12614{
e07e6e58
NC
12615 set_it_insn_type (NEUTRAL_IT_INSN);
12616
c19d1205
ZW
12617 if (unified_syntax)
12618 {
12619 if (inst.size_req == 4 || inst.operands[0].imm > 15)
b05fe5cf 12620 {
c19d1205
ZW
12621 inst.instruction = THUMB_OP32 (inst.instruction);
12622 inst.instruction |= inst.operands[0].imm;
12623 }
12624 else
12625 {
bc2d1808
NC
12626 /* PR9722: Check for Thumb2 availability before
12627 generating a thumb2 nop instruction. */
afa62d5e 12628 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2))
bc2d1808
NC
12629 {
12630 inst.instruction = THUMB_OP16 (inst.instruction);
12631 inst.instruction |= inst.operands[0].imm << 4;
12632 }
12633 else
12634 inst.instruction = 0x46c0;
c19d1205
ZW
12635 }
12636 }
12637 else
12638 {
12639 constraint (inst.operands[0].present,
12640 _("Thumb does not support NOP with hints"));
12641 inst.instruction = 0x46c0;
12642 }
12643}
b05fe5cf 12644
c19d1205
ZW
12645static void
12646do_t_neg (void)
12647{
12648 if (unified_syntax)
12649 {
3d388997
PB
12650 bfd_boolean narrow;
12651
12652 if (THUMB_SETS_FLAGS (inst.instruction))
e07e6e58 12653 narrow = !in_it_block ();
3d388997 12654 else
e07e6e58 12655 narrow = in_it_block ();
3d388997
PB
12656 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
12657 narrow = FALSE;
12658 if (inst.size_req == 4)
12659 narrow = FALSE;
12660
12661 if (!narrow)
c19d1205
ZW
12662 {
12663 inst.instruction = THUMB_OP32 (inst.instruction);
12664 inst.instruction |= inst.operands[0].reg << 8;
12665 inst.instruction |= inst.operands[1].reg << 16;
b05fe5cf
ZW
12666 }
12667 else
12668 {
c19d1205
ZW
12669 inst.instruction = THUMB_OP16 (inst.instruction);
12670 inst.instruction |= inst.operands[0].reg;
12671 inst.instruction |= inst.operands[1].reg << 3;
b05fe5cf
ZW
12672 }
12673 }
12674 else
12675 {
c19d1205
ZW
12676 constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7,
12677 BAD_HIREG);
12678 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
12679
12680 inst.instruction = THUMB_OP16 (inst.instruction);
12681 inst.instruction |= inst.operands[0].reg;
12682 inst.instruction |= inst.operands[1].reg << 3;
12683 }
12684}
12685
1c444d06
JM
12686static void
12687do_t_orn (void)
12688{
12689 unsigned Rd, Rn;
12690
12691 Rd = inst.operands[0].reg;
12692 Rn = inst.operands[1].present ? inst.operands[1].reg : Rd;
12693
fdfde340
JM
12694 reject_bad_reg (Rd);
12695 /* Rn == REG_SP is unpredictable; Rn == REG_PC is MVN. */
12696 reject_bad_reg (Rn);
12697
1c444d06
JM
12698 inst.instruction |= Rd << 8;
12699 inst.instruction |= Rn << 16;
12700
12701 if (!inst.operands[2].isreg)
12702 {
12703 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 12704 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
1c444d06
JM
12705 }
12706 else
12707 {
12708 unsigned Rm;
12709
12710 Rm = inst.operands[2].reg;
fdfde340 12711 reject_bad_reg (Rm);
1c444d06
JM
12712
12713 constraint (inst.operands[2].shifted
12714 && inst.operands[2].immisreg,
12715 _("shift must be constant"));
12716 encode_thumb32_shifted_operand (2);
12717 }
12718}
12719
c19d1205
ZW
12720static void
12721do_t_pkhbt (void)
12722{
fdfde340
JM
12723 unsigned Rd, Rn, Rm;
12724
12725 Rd = inst.operands[0].reg;
12726 Rn = inst.operands[1].reg;
12727 Rm = inst.operands[2].reg;
12728
12729 reject_bad_reg (Rd);
12730 reject_bad_reg (Rn);
12731 reject_bad_reg (Rm);
12732
12733 inst.instruction |= Rd << 8;
12734 inst.instruction |= Rn << 16;
12735 inst.instruction |= Rm;
c19d1205
ZW
12736 if (inst.operands[3].present)
12737 {
e2b0ab59
AV
12738 unsigned int val = inst.relocs[0].exp.X_add_number;
12739 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
12740 _("expression too complex"));
12741 inst.instruction |= (val & 0x1c) << 10;
12742 inst.instruction |= (val & 0x03) << 6;
b05fe5cf 12743 }
c19d1205 12744}
b05fe5cf 12745
c19d1205
ZW
12746static void
12747do_t_pkhtb (void)
12748{
12749 if (!inst.operands[3].present)
1ef52f49
NC
12750 {
12751 unsigned Rtmp;
12752
12753 inst.instruction &= ~0x00000020;
12754
12755 /* PR 10168. Swap the Rm and Rn registers. */
12756 Rtmp = inst.operands[1].reg;
12757 inst.operands[1].reg = inst.operands[2].reg;
12758 inst.operands[2].reg = Rtmp;
12759 }
c19d1205 12760 do_t_pkhbt ();
b05fe5cf
ZW
12761}
12762
c19d1205
ZW
12763static void
12764do_t_pld (void)
12765{
fdfde340
JM
12766 if (inst.operands[0].immisreg)
12767 reject_bad_reg (inst.operands[0].imm);
12768
c19d1205
ZW
12769 encode_thumb32_addr_mode (0, /*is_t=*/FALSE, /*is_d=*/FALSE);
12770}
b05fe5cf 12771
c19d1205
ZW
12772static void
12773do_t_push_pop (void)
b99bd4ef 12774{
e9f89963 12775 unsigned mask;
5f4273c7 12776
c19d1205
ZW
12777 constraint (inst.operands[0].writeback,
12778 _("push/pop do not support {reglist}^"));
e2b0ab59 12779 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205 12780 _("expression too complex"));
b99bd4ef 12781
e9f89963 12782 mask = inst.operands[0].imm;
d3bfe16e 12783 if (inst.size_req != 4 && (mask & ~0xff) == 0)
3c707909 12784 inst.instruction = THUMB_OP16 (inst.instruction) | mask;
d3bfe16e 12785 else if (inst.size_req != 4
c6025a80 12786 && (mask & ~0xff) == (1U << (inst.instruction == T_MNEM_push
d3bfe16e 12787 ? REG_LR : REG_PC)))
b99bd4ef 12788 {
c19d1205
ZW
12789 inst.instruction = THUMB_OP16 (inst.instruction);
12790 inst.instruction |= THUMB_PP_PC_LR;
3c707909 12791 inst.instruction |= mask & 0xff;
c19d1205
ZW
12792 }
12793 else if (unified_syntax)
12794 {
3c707909 12795 inst.instruction = THUMB_OP32 (inst.instruction);
4b5a202f
AV
12796 encode_thumb2_multi (TRUE /* do_io */, 13, mask, TRUE);
12797 }
12798 else
12799 {
12800 inst.error = _("invalid register list to push/pop instruction");
12801 return;
c19d1205 12802 }
4b5a202f
AV
12803}
12804
12805static void
12806do_t_clrm (void)
12807{
12808 if (unified_syntax)
12809 encode_thumb2_multi (FALSE /* do_io */, -1, inst.operands[0].imm, FALSE);
c19d1205
ZW
12810 else
12811 {
12812 inst.error = _("invalid register list to push/pop instruction");
12813 return;
12814 }
c19d1205 12815}
b99bd4ef 12816
c19d1205
ZW
12817static void
12818do_t_rbit (void)
12819{
fdfde340
JM
12820 unsigned Rd, Rm;
12821
12822 Rd = inst.operands[0].reg;
12823 Rm = inst.operands[1].reg;
12824
12825 reject_bad_reg (Rd);
12826 reject_bad_reg (Rm);
12827
12828 inst.instruction |= Rd << 8;
12829 inst.instruction |= Rm << 16;
12830 inst.instruction |= Rm;
c19d1205 12831}
b99bd4ef 12832
c19d1205
ZW
12833static void
12834do_t_rev (void)
12835{
fdfde340
JM
12836 unsigned Rd, Rm;
12837
12838 Rd = inst.operands[0].reg;
12839 Rm = inst.operands[1].reg;
12840
12841 reject_bad_reg (Rd);
12842 reject_bad_reg (Rm);
12843
12844 if (Rd <= 7 && Rm <= 7
c19d1205
ZW
12845 && inst.size_req != 4)
12846 {
12847 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
12848 inst.instruction |= Rd;
12849 inst.instruction |= Rm << 3;
c19d1205
ZW
12850 }
12851 else if (unified_syntax)
12852 {
12853 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
12854 inst.instruction |= Rd << 8;
12855 inst.instruction |= Rm << 16;
12856 inst.instruction |= Rm;
c19d1205
ZW
12857 }
12858 else
12859 inst.error = BAD_HIREG;
12860}
b99bd4ef 12861
1c444d06
JM
12862static void
12863do_t_rrx (void)
12864{
12865 unsigned Rd, Rm;
12866
12867 Rd = inst.operands[0].reg;
12868 Rm = inst.operands[1].reg;
12869
fdfde340
JM
12870 reject_bad_reg (Rd);
12871 reject_bad_reg (Rm);
c921be7d 12872
1c444d06
JM
12873 inst.instruction |= Rd << 8;
12874 inst.instruction |= Rm;
12875}
12876
c19d1205
ZW
12877static void
12878do_t_rsb (void)
12879{
fdfde340 12880 unsigned Rd, Rs;
b99bd4ef 12881
c19d1205
ZW
12882 Rd = inst.operands[0].reg;
12883 Rs = (inst.operands[1].present
12884 ? inst.operands[1].reg /* Rd, Rs, foo */
12885 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
b99bd4ef 12886
fdfde340
JM
12887 reject_bad_reg (Rd);
12888 reject_bad_reg (Rs);
12889 if (inst.operands[2].isreg)
12890 reject_bad_reg (inst.operands[2].reg);
12891
c19d1205
ZW
12892 inst.instruction |= Rd << 8;
12893 inst.instruction |= Rs << 16;
12894 if (!inst.operands[2].isreg)
12895 {
026d3abb
PB
12896 bfd_boolean narrow;
12897
12898 if ((inst.instruction & 0x00100000) != 0)
e07e6e58 12899 narrow = !in_it_block ();
026d3abb 12900 else
e07e6e58 12901 narrow = in_it_block ();
026d3abb
PB
12902
12903 if (Rd > 7 || Rs > 7)
12904 narrow = FALSE;
12905
12906 if (inst.size_req == 4 || !unified_syntax)
12907 narrow = FALSE;
12908
e2b0ab59
AV
12909 if (inst.relocs[0].exp.X_op != O_constant
12910 || inst.relocs[0].exp.X_add_number != 0)
026d3abb
PB
12911 narrow = FALSE;
12912
12913 /* Turn rsb #0 into 16-bit neg. We should probably do this via
477330fc 12914 relaxation, but it doesn't seem worth the hassle. */
026d3abb
PB
12915 if (narrow)
12916 {
e2b0ab59 12917 inst.relocs[0].type = BFD_RELOC_UNUSED;
026d3abb
PB
12918 inst.instruction = THUMB_OP16 (T_MNEM_negs);
12919 inst.instruction |= Rs << 3;
12920 inst.instruction |= Rd;
12921 }
12922 else
12923 {
12924 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 12925 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
026d3abb 12926 }
c19d1205
ZW
12927 }
12928 else
12929 encode_thumb32_shifted_operand (2);
12930}
b99bd4ef 12931
c19d1205
ZW
12932static void
12933do_t_setend (void)
12934{
12e37cbc
MGD
12935 if (warn_on_deprecated
12936 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 12937 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 12938
e07e6e58 12939 set_it_insn_type (OUTSIDE_IT_INSN);
c19d1205
ZW
12940 if (inst.operands[0].imm)
12941 inst.instruction |= 0x8;
12942}
b99bd4ef 12943
c19d1205
ZW
12944static void
12945do_t_shift (void)
12946{
12947 if (!inst.operands[1].present)
12948 inst.operands[1].reg = inst.operands[0].reg;
12949
12950 if (unified_syntax)
12951 {
3d388997
PB
12952 bfd_boolean narrow;
12953 int shift_kind;
12954
12955 switch (inst.instruction)
12956 {
12957 case T_MNEM_asr:
12958 case T_MNEM_asrs: shift_kind = SHIFT_ASR; break;
12959 case T_MNEM_lsl:
12960 case T_MNEM_lsls: shift_kind = SHIFT_LSL; break;
12961 case T_MNEM_lsr:
12962 case T_MNEM_lsrs: shift_kind = SHIFT_LSR; break;
12963 case T_MNEM_ror:
12964 case T_MNEM_rors: shift_kind = SHIFT_ROR; break;
12965 default: abort ();
12966 }
12967
12968 if (THUMB_SETS_FLAGS (inst.instruction))
e07e6e58 12969 narrow = !in_it_block ();
3d388997 12970 else
e07e6e58 12971 narrow = in_it_block ();
3d388997
PB
12972 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
12973 narrow = FALSE;
12974 if (!inst.operands[2].isreg && shift_kind == SHIFT_ROR)
12975 narrow = FALSE;
12976 if (inst.operands[2].isreg
12977 && (inst.operands[1].reg != inst.operands[0].reg
12978 || inst.operands[2].reg > 7))
12979 narrow = FALSE;
12980 if (inst.size_req == 4)
12981 narrow = FALSE;
12982
fdfde340
JM
12983 reject_bad_reg (inst.operands[0].reg);
12984 reject_bad_reg (inst.operands[1].reg);
c921be7d 12985
3d388997 12986 if (!narrow)
c19d1205
ZW
12987 {
12988 if (inst.operands[2].isreg)
b99bd4ef 12989 {
fdfde340 12990 reject_bad_reg (inst.operands[2].reg);
c19d1205
ZW
12991 inst.instruction = THUMB_OP32 (inst.instruction);
12992 inst.instruction |= inst.operands[0].reg << 8;
12993 inst.instruction |= inst.operands[1].reg << 16;
12994 inst.instruction |= inst.operands[2].reg;
94342ec3
NC
12995
12996 /* PR 12854: Error on extraneous shifts. */
12997 constraint (inst.operands[2].shifted,
12998 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
12999 }
13000 else
13001 {
13002 inst.operands[1].shifted = 1;
3d388997 13003 inst.operands[1].shift_kind = shift_kind;
c19d1205
ZW
13004 inst.instruction = THUMB_OP32 (THUMB_SETS_FLAGS (inst.instruction)
13005 ? T_MNEM_movs : T_MNEM_mov);
13006 inst.instruction |= inst.operands[0].reg << 8;
13007 encode_thumb32_shifted_operand (1);
13008 /* Prevent the incorrect generation of an ARM_IMMEDIATE fixup. */
e2b0ab59 13009 inst.relocs[0].type = BFD_RELOC_UNUSED;
b99bd4ef
NC
13010 }
13011 }
13012 else
13013 {
c19d1205 13014 if (inst.operands[2].isreg)
b99bd4ef 13015 {
3d388997 13016 switch (shift_kind)
b99bd4ef 13017 {
3d388997
PB
13018 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_R; break;
13019 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_R; break;
13020 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_R; break;
13021 case SHIFT_ROR: inst.instruction = T_OPCODE_ROR_R; break;
c19d1205 13022 default: abort ();
b99bd4ef 13023 }
5f4273c7 13024
c19d1205
ZW
13025 inst.instruction |= inst.operands[0].reg;
13026 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
13027
13028 /* PR 12854: Error on extraneous shifts. */
13029 constraint (inst.operands[2].shifted,
13030 _("extraneous shift as part of operand to shift insn"));
b99bd4ef
NC
13031 }
13032 else
13033 {
3d388997 13034 switch (shift_kind)
b99bd4ef 13035 {
3d388997
PB
13036 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
13037 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
13038 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
c19d1205 13039 default: abort ();
b99bd4ef 13040 }
e2b0ab59 13041 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
13042 inst.instruction |= inst.operands[0].reg;
13043 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
13044 }
13045 }
c19d1205
ZW
13046 }
13047 else
13048 {
13049 constraint (inst.operands[0].reg > 7
13050 || inst.operands[1].reg > 7, BAD_HIREG);
13051 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
b99bd4ef 13052
c19d1205
ZW
13053 if (inst.operands[2].isreg) /* Rd, {Rs,} Rn */
13054 {
13055 constraint (inst.operands[2].reg > 7, BAD_HIREG);
13056 constraint (inst.operands[0].reg != inst.operands[1].reg,
13057 _("source1 and dest must be same register"));
b99bd4ef 13058
c19d1205
ZW
13059 switch (inst.instruction)
13060 {
13061 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_R; break;
13062 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_R; break;
13063 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_R; break;
13064 case T_MNEM_ror: inst.instruction = T_OPCODE_ROR_R; break;
13065 default: abort ();
13066 }
5f4273c7 13067
c19d1205
ZW
13068 inst.instruction |= inst.operands[0].reg;
13069 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
13070
13071 /* PR 12854: Error on extraneous shifts. */
13072 constraint (inst.operands[2].shifted,
13073 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
13074 }
13075 else
b99bd4ef 13076 {
c19d1205
ZW
13077 switch (inst.instruction)
13078 {
13079 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_I; break;
13080 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_I; break;
13081 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_I; break;
13082 case T_MNEM_ror: inst.error = _("ror #imm not supported"); return;
13083 default: abort ();
13084 }
e2b0ab59 13085 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
13086 inst.instruction |= inst.operands[0].reg;
13087 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
13088 }
13089 }
b99bd4ef
NC
13090}
13091
13092static void
c19d1205 13093do_t_simd (void)
b99bd4ef 13094{
fdfde340
JM
13095 unsigned Rd, Rn, Rm;
13096
13097 Rd = inst.operands[0].reg;
13098 Rn = inst.operands[1].reg;
13099 Rm = inst.operands[2].reg;
13100
13101 reject_bad_reg (Rd);
13102 reject_bad_reg (Rn);
13103 reject_bad_reg (Rm);
13104
13105 inst.instruction |= Rd << 8;
13106 inst.instruction |= Rn << 16;
13107 inst.instruction |= Rm;
c19d1205 13108}
b99bd4ef 13109
03ee1b7f
NC
13110static void
13111do_t_simd2 (void)
13112{
13113 unsigned Rd, Rn, Rm;
13114
13115 Rd = inst.operands[0].reg;
13116 Rm = inst.operands[1].reg;
13117 Rn = inst.operands[2].reg;
13118
13119 reject_bad_reg (Rd);
13120 reject_bad_reg (Rn);
13121 reject_bad_reg (Rm);
13122
13123 inst.instruction |= Rd << 8;
13124 inst.instruction |= Rn << 16;
13125 inst.instruction |= Rm;
13126}
13127
c19d1205 13128static void
3eb17e6b 13129do_t_smc (void)
c19d1205 13130{
e2b0ab59 13131 unsigned int value = inst.relocs[0].exp.X_add_number;
f4c65163
MGD
13132 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a),
13133 _("SMC is not permitted on this architecture"));
e2b0ab59 13134 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 13135 _("expression too complex"));
e2b0ab59 13136 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205
ZW
13137 inst.instruction |= (value & 0xf000) >> 12;
13138 inst.instruction |= (value & 0x0ff0);
13139 inst.instruction |= (value & 0x000f) << 16;
24382199
NC
13140 /* PR gas/15623: SMC instructions must be last in an IT block. */
13141 set_it_insn_type_last ();
c19d1205 13142}
b99bd4ef 13143
90ec0d68
MGD
13144static void
13145do_t_hvc (void)
13146{
e2b0ab59 13147 unsigned int value = inst.relocs[0].exp.X_add_number;
90ec0d68 13148
e2b0ab59 13149 inst.relocs[0].type = BFD_RELOC_UNUSED;
90ec0d68
MGD
13150 inst.instruction |= (value & 0x0fff);
13151 inst.instruction |= (value & 0xf000) << 4;
13152}
13153
c19d1205 13154static void
3a21c15a 13155do_t_ssat_usat (int bias)
c19d1205 13156{
fdfde340
JM
13157 unsigned Rd, Rn;
13158
13159 Rd = inst.operands[0].reg;
13160 Rn = inst.operands[2].reg;
13161
13162 reject_bad_reg (Rd);
13163 reject_bad_reg (Rn);
13164
13165 inst.instruction |= Rd << 8;
3a21c15a 13166 inst.instruction |= inst.operands[1].imm - bias;
fdfde340 13167 inst.instruction |= Rn << 16;
b99bd4ef 13168
c19d1205 13169 if (inst.operands[3].present)
b99bd4ef 13170 {
e2b0ab59 13171 offsetT shift_amount = inst.relocs[0].exp.X_add_number;
3a21c15a 13172
e2b0ab59 13173 inst.relocs[0].type = BFD_RELOC_UNUSED;
3a21c15a 13174
e2b0ab59 13175 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 13176 _("expression too complex"));
b99bd4ef 13177
3a21c15a 13178 if (shift_amount != 0)
6189168b 13179 {
3a21c15a
NC
13180 constraint (shift_amount > 31,
13181 _("shift expression is too large"));
13182
c19d1205 13183 if (inst.operands[3].shift_kind == SHIFT_ASR)
3a21c15a
NC
13184 inst.instruction |= 0x00200000; /* sh bit. */
13185
13186 inst.instruction |= (shift_amount & 0x1c) << 10;
13187 inst.instruction |= (shift_amount & 0x03) << 6;
6189168b
NC
13188 }
13189 }
b99bd4ef 13190}
c921be7d 13191
3a21c15a
NC
13192static void
13193do_t_ssat (void)
13194{
13195 do_t_ssat_usat (1);
13196}
b99bd4ef 13197
0dd132b6 13198static void
c19d1205 13199do_t_ssat16 (void)
0dd132b6 13200{
fdfde340
JM
13201 unsigned Rd, Rn;
13202
13203 Rd = inst.operands[0].reg;
13204 Rn = inst.operands[2].reg;
13205
13206 reject_bad_reg (Rd);
13207 reject_bad_reg (Rn);
13208
13209 inst.instruction |= Rd << 8;
c19d1205 13210 inst.instruction |= inst.operands[1].imm - 1;
fdfde340 13211 inst.instruction |= Rn << 16;
c19d1205 13212}
0dd132b6 13213
c19d1205
ZW
13214static void
13215do_t_strex (void)
13216{
13217 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
13218 || inst.operands[2].postind || inst.operands[2].writeback
13219 || inst.operands[2].immisreg || inst.operands[2].shifted
13220 || inst.operands[2].negative,
01cfc07f 13221 BAD_ADDR_MODE);
0dd132b6 13222
5be8be5d
DG
13223 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
13224
c19d1205
ZW
13225 inst.instruction |= inst.operands[0].reg << 8;
13226 inst.instruction |= inst.operands[1].reg << 12;
13227 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 13228 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
0dd132b6
NC
13229}
13230
b99bd4ef 13231static void
c19d1205 13232do_t_strexd (void)
b99bd4ef 13233{
c19d1205
ZW
13234 if (!inst.operands[2].present)
13235 inst.operands[2].reg = inst.operands[1].reg + 1;
b99bd4ef 13236
c19d1205
ZW
13237 constraint (inst.operands[0].reg == inst.operands[1].reg
13238 || inst.operands[0].reg == inst.operands[2].reg
f8a8e9d6 13239 || inst.operands[0].reg == inst.operands[3].reg,
c19d1205 13240 BAD_OVERLAP);
b99bd4ef 13241
c19d1205
ZW
13242 inst.instruction |= inst.operands[0].reg;
13243 inst.instruction |= inst.operands[1].reg << 12;
13244 inst.instruction |= inst.operands[2].reg << 8;
13245 inst.instruction |= inst.operands[3].reg << 16;
b99bd4ef
NC
13246}
13247
13248static void
c19d1205 13249do_t_sxtah (void)
b99bd4ef 13250{
fdfde340
JM
13251 unsigned Rd, Rn, Rm;
13252
13253 Rd = inst.operands[0].reg;
13254 Rn = inst.operands[1].reg;
13255 Rm = inst.operands[2].reg;
13256
13257 reject_bad_reg (Rd);
13258 reject_bad_reg (Rn);
13259 reject_bad_reg (Rm);
13260
13261 inst.instruction |= Rd << 8;
13262 inst.instruction |= Rn << 16;
13263 inst.instruction |= Rm;
c19d1205
ZW
13264 inst.instruction |= inst.operands[3].imm << 4;
13265}
b99bd4ef 13266
c19d1205
ZW
13267static void
13268do_t_sxth (void)
13269{
fdfde340
JM
13270 unsigned Rd, Rm;
13271
13272 Rd = inst.operands[0].reg;
13273 Rm = inst.operands[1].reg;
13274
13275 reject_bad_reg (Rd);
13276 reject_bad_reg (Rm);
c921be7d
NC
13277
13278 if (inst.instruction <= 0xffff
13279 && inst.size_req != 4
fdfde340 13280 && Rd <= 7 && Rm <= 7
c19d1205 13281 && (!inst.operands[2].present || inst.operands[2].imm == 0))
b99bd4ef 13282 {
c19d1205 13283 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13284 inst.instruction |= Rd;
13285 inst.instruction |= Rm << 3;
b99bd4ef 13286 }
c19d1205 13287 else if (unified_syntax)
b99bd4ef 13288 {
c19d1205
ZW
13289 if (inst.instruction <= 0xffff)
13290 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13291 inst.instruction |= Rd << 8;
13292 inst.instruction |= Rm;
c19d1205 13293 inst.instruction |= inst.operands[2].imm << 4;
b99bd4ef 13294 }
c19d1205 13295 else
b99bd4ef 13296 {
c19d1205
ZW
13297 constraint (inst.operands[2].present && inst.operands[2].imm != 0,
13298 _("Thumb encoding does not support rotation"));
13299 constraint (1, BAD_HIREG);
b99bd4ef 13300 }
c19d1205 13301}
b99bd4ef 13302
c19d1205
ZW
13303static void
13304do_t_swi (void)
13305{
e2b0ab59 13306 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
c19d1205 13307}
b99bd4ef 13308
92e90b6e
PB
13309static void
13310do_t_tb (void)
13311{
fdfde340 13312 unsigned Rn, Rm;
92e90b6e
PB
13313 int half;
13314
13315 half = (inst.instruction & 0x10) != 0;
e07e6e58 13316 set_it_insn_type_last ();
dfa9f0d5
PB
13317 constraint (inst.operands[0].immisreg,
13318 _("instruction requires register index"));
fdfde340
JM
13319
13320 Rn = inst.operands[0].reg;
13321 Rm = inst.operands[0].imm;
c921be7d 13322
5c8ed6a4
JW
13323 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
13324 constraint (Rn == REG_SP, BAD_SP);
fdfde340
JM
13325 reject_bad_reg (Rm);
13326
92e90b6e
PB
13327 constraint (!half && inst.operands[0].shifted,
13328 _("instruction does not allow shifted index"));
fdfde340 13329 inst.instruction |= (Rn << 16) | Rm;
92e90b6e
PB
13330}
13331
74db7efb
NC
13332static void
13333do_t_udf (void)
13334{
13335 if (!inst.operands[0].present)
13336 inst.operands[0].imm = 0;
13337
13338 if ((unsigned int) inst.operands[0].imm > 255 || inst.size_req == 4)
13339 {
13340 constraint (inst.size_req == 2,
13341 _("immediate value out of range"));
13342 inst.instruction = THUMB_OP32 (inst.instruction);
13343 inst.instruction |= (inst.operands[0].imm & 0xf000u) << 4;
13344 inst.instruction |= (inst.operands[0].imm & 0x0fffu) << 0;
13345 }
13346 else
13347 {
13348 inst.instruction = THUMB_OP16 (inst.instruction);
13349 inst.instruction |= inst.operands[0].imm;
13350 }
13351
13352 set_it_insn_type (NEUTRAL_IT_INSN);
13353}
13354
13355
c19d1205
ZW
13356static void
13357do_t_usat (void)
13358{
3a21c15a 13359 do_t_ssat_usat (0);
b99bd4ef
NC
13360}
13361
13362static void
c19d1205 13363do_t_usat16 (void)
b99bd4ef 13364{
fdfde340
JM
13365 unsigned Rd, Rn;
13366
13367 Rd = inst.operands[0].reg;
13368 Rn = inst.operands[2].reg;
13369
13370 reject_bad_reg (Rd);
13371 reject_bad_reg (Rn);
13372
13373 inst.instruction |= Rd << 8;
c19d1205 13374 inst.instruction |= inst.operands[1].imm;
fdfde340 13375 inst.instruction |= Rn << 16;
b99bd4ef 13376}
c19d1205 13377
e12437dc
AV
13378/* Checking the range of the branch offset (VAL) with NBITS bits
13379 and IS_SIGNED signedness. Also checks the LSB to be 0. */
13380static int
13381v8_1_branch_value_check (int val, int nbits, int is_signed)
13382{
13383 gas_assert (nbits > 0 && nbits <= 32);
13384 if (is_signed)
13385 {
13386 int cmp = (1 << (nbits - 1));
13387 if ((val < -cmp) || (val >= cmp) || (val & 0x01))
13388 return FAIL;
13389 }
13390 else
13391 {
13392 if ((val <= 0) || (val >= (1 << nbits)) || (val & 0x1))
13393 return FAIL;
13394 }
13395 return SUCCESS;
13396}
13397
4389b29a
AV
13398/* For branches in Armv8.1-M Mainline. */
13399static void
13400do_t_branch_future (void)
13401{
13402 unsigned long insn = inst.instruction;
13403
13404 inst.instruction = THUMB_OP32 (inst.instruction);
13405 if (inst.operands[0].hasreloc == 0)
13406 {
13407 if (v8_1_branch_value_check (inst.operands[0].imm, 5, FALSE) == FAIL)
13408 as_bad (BAD_BRANCH_OFF);
13409
13410 inst.instruction |= ((inst.operands[0].imm & 0x1f) >> 1) << 23;
13411 }
13412 else
13413 {
13414 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH5;
13415 inst.relocs[0].pc_rel = 1;
13416 }
13417
13418 switch (insn)
13419 {
13420 case T_MNEM_bf:
13421 if (inst.operands[1].hasreloc == 0)
13422 {
13423 int val = inst.operands[1].imm;
13424 if (v8_1_branch_value_check (inst.operands[1].imm, 17, TRUE) == FAIL)
13425 as_bad (BAD_BRANCH_OFF);
13426
13427 int immA = (val & 0x0001f000) >> 12;
13428 int immB = (val & 0x00000ffc) >> 2;
13429 int immC = (val & 0x00000002) >> 1;
13430 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
13431 }
13432 else
13433 {
13434 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF17;
13435 inst.relocs[1].pc_rel = 1;
13436 }
13437 break;
13438
65d1bc05
AV
13439 case T_MNEM_bfl:
13440 if (inst.operands[1].hasreloc == 0)
13441 {
13442 int val = inst.operands[1].imm;
13443 if (v8_1_branch_value_check (inst.operands[1].imm, 19, TRUE) == FAIL)
13444 as_bad (BAD_BRANCH_OFF);
13445
13446 int immA = (val & 0x0007f000) >> 12;
13447 int immB = (val & 0x00000ffc) >> 2;
13448 int immC = (val & 0x00000002) >> 1;
13449 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
13450 }
13451 else
13452 {
13453 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF19;
13454 inst.relocs[1].pc_rel = 1;
13455 }
13456 break;
13457
f6b2b12d
AV
13458 case T_MNEM_bfcsel:
13459 /* Operand 1. */
13460 if (inst.operands[1].hasreloc == 0)
13461 {
13462 int val = inst.operands[1].imm;
13463 int immA = (val & 0x00001000) >> 12;
13464 int immB = (val & 0x00000ffc) >> 2;
13465 int immC = (val & 0x00000002) >> 1;
13466 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
13467 }
13468 else
13469 {
13470 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF13;
13471 inst.relocs[1].pc_rel = 1;
13472 }
13473
13474 /* Operand 2. */
13475 if (inst.operands[2].hasreloc == 0)
13476 {
13477 constraint ((inst.operands[0].hasreloc != 0), BAD_ARGS);
13478 int val2 = inst.operands[2].imm;
13479 int val0 = inst.operands[0].imm & 0x1f;
13480 int diff = val2 - val0;
13481 if (diff == 4)
13482 inst.instruction |= 1 << 17; /* T bit. */
13483 else if (diff != 2)
13484 as_bad (_("out of range label-relative fixup value"));
13485 }
13486 else
13487 {
13488 constraint ((inst.operands[0].hasreloc == 0), BAD_ARGS);
13489 inst.relocs[2].type = BFD_RELOC_THUMB_PCREL_BFCSEL;
13490 inst.relocs[2].pc_rel = 1;
13491 }
13492
13493 /* Operand 3. */
13494 constraint (inst.cond != COND_ALWAYS, BAD_COND);
13495 inst.instruction |= (inst.operands[3].imm & 0xf) << 18;
13496 break;
13497
f1c7f421
AV
13498 case T_MNEM_bfx:
13499 case T_MNEM_bflx:
13500 inst.instruction |= inst.operands[1].reg << 16;
13501 break;
13502
4389b29a
AV
13503 default: abort ();
13504 }
13505}
13506
60f993ce
AV
13507/* Helper function for do_t_loloop to handle relocations. */
13508static void
13509v8_1_loop_reloc (int is_le)
13510{
13511 if (inst.relocs[0].exp.X_op == O_constant)
13512 {
13513 int value = inst.relocs[0].exp.X_add_number;
13514 value = (is_le) ? -value : value;
13515
13516 if (v8_1_branch_value_check (value, 12, FALSE) == FAIL)
13517 as_bad (BAD_BRANCH_OFF);
13518
13519 int imml, immh;
13520
13521 immh = (value & 0x00000ffc) >> 2;
13522 imml = (value & 0x00000002) >> 1;
13523
13524 inst.instruction |= (imml << 11) | (immh << 1);
13525 }
13526 else
13527 {
13528 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_LOOP12;
13529 inst.relocs[0].pc_rel = 1;
13530 }
13531}
13532
13533/* To handle the Scalar Low Overhead Loop instructions
13534 in Armv8.1-M Mainline. */
13535static void
13536do_t_loloop (void)
13537{
13538 unsigned long insn = inst.instruction;
13539
13540 set_it_insn_type (OUTSIDE_IT_INSN);
13541 inst.instruction = THUMB_OP32 (inst.instruction);
13542
13543 switch (insn)
13544 {
13545 case T_MNEM_le:
13546 /* le <label>. */
13547 if (!inst.operands[0].present)
13548 inst.instruction |= 1 << 21;
13549
13550 v8_1_loop_reloc (TRUE);
13551 break;
13552
13553 case T_MNEM_wls:
13554 v8_1_loop_reloc (FALSE);
13555 /* Fall through. */
13556 case T_MNEM_dls:
13557 constraint (inst.operands[1].isreg != 1, BAD_ARGS);
13558 inst.instruction |= (inst.operands[1].reg << 16);
13559 break;
13560
13561 default: abort();
13562 }
13563}
13564
5287ad62 13565/* Neon instruction encoder helpers. */
5f4273c7 13566
5287ad62 13567/* Encodings for the different types for various Neon opcodes. */
b99bd4ef 13568
5287ad62
JB
13569/* An "invalid" code for the following tables. */
13570#define N_INV -1u
13571
13572struct neon_tab_entry
b99bd4ef 13573{
5287ad62
JB
13574 unsigned integer;
13575 unsigned float_or_poly;
13576 unsigned scalar_or_imm;
13577};
5f4273c7 13578
5287ad62
JB
13579/* Map overloaded Neon opcodes to their respective encodings. */
13580#define NEON_ENC_TAB \
13581 X(vabd, 0x0000700, 0x1200d00, N_INV), \
13582 X(vmax, 0x0000600, 0x0000f00, N_INV), \
13583 X(vmin, 0x0000610, 0x0200f00, N_INV), \
13584 X(vpadd, 0x0000b10, 0x1000d00, N_INV), \
13585 X(vpmax, 0x0000a00, 0x1000f00, N_INV), \
13586 X(vpmin, 0x0000a10, 0x1200f00, N_INV), \
13587 X(vadd, 0x0000800, 0x0000d00, N_INV), \
13588 X(vsub, 0x1000800, 0x0200d00, N_INV), \
13589 X(vceq, 0x1000810, 0x0000e00, 0x1b10100), \
13590 X(vcge, 0x0000310, 0x1000e00, 0x1b10080), \
13591 X(vcgt, 0x0000300, 0x1200e00, 0x1b10000), \
13592 /* Register variants of the following two instructions are encoded as
e07e6e58 13593 vcge / vcgt with the operands reversed. */ \
92559b5b
PB
13594 X(vclt, 0x0000300, 0x1200e00, 0x1b10200), \
13595 X(vcle, 0x0000310, 0x1000e00, 0x1b10180), \
62f3b8c8
PB
13596 X(vfma, N_INV, 0x0000c10, N_INV), \
13597 X(vfms, N_INV, 0x0200c10, N_INV), \
5287ad62
JB
13598 X(vmla, 0x0000900, 0x0000d10, 0x0800040), \
13599 X(vmls, 0x1000900, 0x0200d10, 0x0800440), \
13600 X(vmul, 0x0000910, 0x1000d10, 0x0800840), \
13601 X(vmull, 0x0800c00, 0x0800e00, 0x0800a40), /* polynomial not float. */ \
13602 X(vmlal, 0x0800800, N_INV, 0x0800240), \
13603 X(vmlsl, 0x0800a00, N_INV, 0x0800640), \
13604 X(vqdmlal, 0x0800900, N_INV, 0x0800340), \
13605 X(vqdmlsl, 0x0800b00, N_INV, 0x0800740), \
13606 X(vqdmull, 0x0800d00, N_INV, 0x0800b40), \
13607 X(vqdmulh, 0x0000b00, N_INV, 0x0800c40), \
13608 X(vqrdmulh, 0x1000b00, N_INV, 0x0800d40), \
d6b4b13e
MW
13609 X(vqrdmlah, 0x3000b10, N_INV, 0x0800e40), \
13610 X(vqrdmlsh, 0x3000c10, N_INV, 0x0800f40), \
5287ad62
JB
13611 X(vshl, 0x0000400, N_INV, 0x0800510), \
13612 X(vqshl, 0x0000410, N_INV, 0x0800710), \
13613 X(vand, 0x0000110, N_INV, 0x0800030), \
13614 X(vbic, 0x0100110, N_INV, 0x0800030), \
13615 X(veor, 0x1000110, N_INV, N_INV), \
13616 X(vorn, 0x0300110, N_INV, 0x0800010), \
13617 X(vorr, 0x0200110, N_INV, 0x0800010), \
13618 X(vmvn, 0x1b00580, N_INV, 0x0800030), \
13619 X(vshll, 0x1b20300, N_INV, 0x0800a10), /* max shift, immediate. */ \
13620 X(vcvt, 0x1b30600, N_INV, 0x0800e10), /* integer, fixed-point. */ \
13621 X(vdup, 0xe800b10, N_INV, 0x1b00c00), /* arm, scalar. */ \
13622 X(vld1, 0x0200000, 0x0a00000, 0x0a00c00), /* interlv, lane, dup. */ \
13623 X(vst1, 0x0000000, 0x0800000, N_INV), \
13624 X(vld2, 0x0200100, 0x0a00100, 0x0a00d00), \
13625 X(vst2, 0x0000100, 0x0800100, N_INV), \
13626 X(vld3, 0x0200200, 0x0a00200, 0x0a00e00), \
13627 X(vst3, 0x0000200, 0x0800200, N_INV), \
13628 X(vld4, 0x0200300, 0x0a00300, 0x0a00f00), \
13629 X(vst4, 0x0000300, 0x0800300, N_INV), \
13630 X(vmovn, 0x1b20200, N_INV, N_INV), \
13631 X(vtrn, 0x1b20080, N_INV, N_INV), \
13632 X(vqmovn, 0x1b20200, N_INV, N_INV), \
037e8744
JB
13633 X(vqmovun, 0x1b20240, N_INV, N_INV), \
13634 X(vnmul, 0xe200a40, 0xe200b40, N_INV), \
e6655fda
PB
13635 X(vnmla, 0xe100a40, 0xe100b40, N_INV), \
13636 X(vnmls, 0xe100a00, 0xe100b00, N_INV), \
62f3b8c8
PB
13637 X(vfnma, 0xe900a40, 0xe900b40, N_INV), \
13638 X(vfnms, 0xe900a00, 0xe900b00, N_INV), \
037e8744
JB
13639 X(vcmp, 0xeb40a40, 0xeb40b40, N_INV), \
13640 X(vcmpz, 0xeb50a40, 0xeb50b40, N_INV), \
13641 X(vcmpe, 0xeb40ac0, 0xeb40bc0, N_INV), \
33399f07
MGD
13642 X(vcmpez, 0xeb50ac0, 0xeb50bc0, N_INV), \
13643 X(vseleq, 0xe000a00, N_INV, N_INV), \
13644 X(vselvs, 0xe100a00, N_INV, N_INV), \
13645 X(vselge, 0xe200a00, N_INV, N_INV), \
73924fbc
MGD
13646 X(vselgt, 0xe300a00, N_INV, N_INV), \
13647 X(vmaxnm, 0xe800a00, 0x3000f10, N_INV), \
7e8e6784 13648 X(vminnm, 0xe800a40, 0x3200f10, N_INV), \
30bdf752
MGD
13649 X(vcvta, 0xebc0a40, 0x3bb0000, N_INV), \
13650 X(vrintr, 0xeb60a40, 0x3ba0400, N_INV), \
91ff7894 13651 X(vrinta, 0xeb80a40, 0x3ba0400, N_INV), \
48adcd8e 13652 X(aes, 0x3b00300, N_INV, N_INV), \
3c9017d2
MGD
13653 X(sha3op, 0x2000c00, N_INV, N_INV), \
13654 X(sha1h, 0x3b902c0, N_INV, N_INV), \
13655 X(sha2op, 0x3ba0380, N_INV, N_INV)
5287ad62
JB
13656
13657enum neon_opc
13658{
13659#define X(OPC,I,F,S) N_MNEM_##OPC
13660NEON_ENC_TAB
13661#undef X
13662};
b99bd4ef 13663
5287ad62
JB
13664static const struct neon_tab_entry neon_enc_tab[] =
13665{
13666#define X(OPC,I,F,S) { (I), (F), (S) }
13667NEON_ENC_TAB
13668#undef X
13669};
b99bd4ef 13670
88714cb8
DG
13671/* Do not use these macros; instead, use NEON_ENCODE defined below. */
13672#define NEON_ENC_INTEGER_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
13673#define NEON_ENC_ARMREG_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
13674#define NEON_ENC_POLY_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
13675#define NEON_ENC_FLOAT_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
13676#define NEON_ENC_SCALAR_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
13677#define NEON_ENC_IMMED_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
13678#define NEON_ENC_INTERLV_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
13679#define NEON_ENC_LANE_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
13680#define NEON_ENC_DUP_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
13681#define NEON_ENC_SINGLE_(X) \
037e8744 13682 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf0000000))
88714cb8 13683#define NEON_ENC_DOUBLE_(X) \
037e8744 13684 ((neon_enc_tab[(X) & 0x0fffffff].float_or_poly) | ((X) & 0xf0000000))
33399f07
MGD
13685#define NEON_ENC_FPV8_(X) \
13686 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf000000))
5287ad62 13687
88714cb8
DG
13688#define NEON_ENCODE(type, inst) \
13689 do \
13690 { \
13691 inst.instruction = NEON_ENC_##type##_ (inst.instruction); \
13692 inst.is_neon = 1; \
13693 } \
13694 while (0)
13695
13696#define check_neon_suffixes \
13697 do \
13698 { \
13699 if (!inst.error && inst.vectype.elems > 0 && !inst.is_neon) \
13700 { \
13701 as_bad (_("invalid neon suffix for non neon instruction")); \
13702 return; \
13703 } \
13704 } \
13705 while (0)
13706
037e8744
JB
13707/* Define shapes for instruction operands. The following mnemonic characters
13708 are used in this table:
5287ad62 13709
037e8744 13710 F - VFP S<n> register
5287ad62
JB
13711 D - Neon D<n> register
13712 Q - Neon Q<n> register
13713 I - Immediate
13714 S - Scalar
13715 R - ARM register
13716 L - D<n> register list
5f4273c7 13717
037e8744
JB
13718 This table is used to generate various data:
13719 - enumerations of the form NS_DDR to be used as arguments to
13720 neon_select_shape.
13721 - a table classifying shapes into single, double, quad, mixed.
5f4273c7 13722 - a table used to drive neon_select_shape. */
b99bd4ef 13723
037e8744
JB
13724#define NEON_SHAPE_DEF \
13725 X(3, (D, D, D), DOUBLE), \
13726 X(3, (Q, Q, Q), QUAD), \
13727 X(3, (D, D, I), DOUBLE), \
13728 X(3, (Q, Q, I), QUAD), \
13729 X(3, (D, D, S), DOUBLE), \
13730 X(3, (Q, Q, S), QUAD), \
13731 X(2, (D, D), DOUBLE), \
13732 X(2, (Q, Q), QUAD), \
13733 X(2, (D, S), DOUBLE), \
13734 X(2, (Q, S), QUAD), \
13735 X(2, (D, R), DOUBLE), \
13736 X(2, (Q, R), QUAD), \
13737 X(2, (D, I), DOUBLE), \
13738 X(2, (Q, I), QUAD), \
13739 X(3, (D, L, D), DOUBLE), \
13740 X(2, (D, Q), MIXED), \
13741 X(2, (Q, D), MIXED), \
13742 X(3, (D, Q, I), MIXED), \
13743 X(3, (Q, D, I), MIXED), \
13744 X(3, (Q, D, D), MIXED), \
13745 X(3, (D, Q, Q), MIXED), \
13746 X(3, (Q, Q, D), MIXED), \
13747 X(3, (Q, D, S), MIXED), \
13748 X(3, (D, Q, S), MIXED), \
13749 X(4, (D, D, D, I), DOUBLE), \
13750 X(4, (Q, Q, Q, I), QUAD), \
c28eeff2
SN
13751 X(4, (D, D, S, I), DOUBLE), \
13752 X(4, (Q, Q, S, I), QUAD), \
037e8744
JB
13753 X(2, (F, F), SINGLE), \
13754 X(3, (F, F, F), SINGLE), \
13755 X(2, (F, I), SINGLE), \
13756 X(2, (F, D), MIXED), \
13757 X(2, (D, F), MIXED), \
13758 X(3, (F, F, I), MIXED), \
13759 X(4, (R, R, F, F), SINGLE), \
13760 X(4, (F, F, R, R), SINGLE), \
13761 X(3, (D, R, R), DOUBLE), \
13762 X(3, (R, R, D), DOUBLE), \
13763 X(2, (S, R), SINGLE), \
13764 X(2, (R, S), SINGLE), \
13765 X(2, (F, R), SINGLE), \
d54af2d0
RL
13766 X(2, (R, F), SINGLE), \
13767/* Half float shape supported so far. */\
13768 X (2, (H, D), MIXED), \
13769 X (2, (D, H), MIXED), \
13770 X (2, (H, F), MIXED), \
13771 X (2, (F, H), MIXED), \
13772 X (2, (H, H), HALF), \
13773 X (2, (H, R), HALF), \
13774 X (2, (R, H), HALF), \
13775 X (2, (H, I), HALF), \
13776 X (3, (H, H, H), HALF), \
13777 X (3, (H, F, I), MIXED), \
dec41383
JW
13778 X (3, (F, H, I), MIXED), \
13779 X (3, (D, H, H), MIXED), \
13780 X (3, (D, H, S), MIXED)
037e8744
JB
13781
13782#define S2(A,B) NS_##A##B
13783#define S3(A,B,C) NS_##A##B##C
13784#define S4(A,B,C,D) NS_##A##B##C##D
13785
13786#define X(N, L, C) S##N L
13787
5287ad62
JB
13788enum neon_shape
13789{
037e8744
JB
13790 NEON_SHAPE_DEF,
13791 NS_NULL
5287ad62 13792};
b99bd4ef 13793
037e8744
JB
13794#undef X
13795#undef S2
13796#undef S3
13797#undef S4
13798
13799enum neon_shape_class
13800{
d54af2d0 13801 SC_HALF,
037e8744
JB
13802 SC_SINGLE,
13803 SC_DOUBLE,
13804 SC_QUAD,
13805 SC_MIXED
13806};
13807
13808#define X(N, L, C) SC_##C
13809
13810static enum neon_shape_class neon_shape_class[] =
13811{
13812 NEON_SHAPE_DEF
13813};
13814
13815#undef X
13816
13817enum neon_shape_el
13818{
d54af2d0 13819 SE_H,
037e8744
JB
13820 SE_F,
13821 SE_D,
13822 SE_Q,
13823 SE_I,
13824 SE_S,
13825 SE_R,
13826 SE_L
13827};
13828
13829/* Register widths of above. */
13830static unsigned neon_shape_el_size[] =
13831{
d54af2d0 13832 16,
037e8744
JB
13833 32,
13834 64,
13835 128,
13836 0,
13837 32,
13838 32,
13839 0
13840};
13841
13842struct neon_shape_info
13843{
13844 unsigned els;
13845 enum neon_shape_el el[NEON_MAX_TYPE_ELS];
13846};
13847
13848#define S2(A,B) { SE_##A, SE_##B }
13849#define S3(A,B,C) { SE_##A, SE_##B, SE_##C }
13850#define S4(A,B,C,D) { SE_##A, SE_##B, SE_##C, SE_##D }
13851
13852#define X(N, L, C) { N, S##N L }
13853
13854static struct neon_shape_info neon_shape_tab[] =
13855{
13856 NEON_SHAPE_DEF
13857};
13858
13859#undef X
13860#undef S2
13861#undef S3
13862#undef S4
13863
5287ad62
JB
13864/* Bit masks used in type checking given instructions.
13865 'N_EQK' means the type must be the same as (or based on in some way) the key
13866 type, which itself is marked with the 'N_KEY' bit. If the 'N_EQK' bit is
13867 set, various other bits can be set as well in order to modify the meaning of
13868 the type constraint. */
13869
13870enum neon_type_mask
13871{
8e79c3df
CM
13872 N_S8 = 0x0000001,
13873 N_S16 = 0x0000002,
13874 N_S32 = 0x0000004,
13875 N_S64 = 0x0000008,
13876 N_U8 = 0x0000010,
13877 N_U16 = 0x0000020,
13878 N_U32 = 0x0000040,
13879 N_U64 = 0x0000080,
13880 N_I8 = 0x0000100,
13881 N_I16 = 0x0000200,
13882 N_I32 = 0x0000400,
13883 N_I64 = 0x0000800,
13884 N_8 = 0x0001000,
13885 N_16 = 0x0002000,
13886 N_32 = 0x0004000,
13887 N_64 = 0x0008000,
13888 N_P8 = 0x0010000,
13889 N_P16 = 0x0020000,
13890 N_F16 = 0x0040000,
13891 N_F32 = 0x0080000,
13892 N_F64 = 0x0100000,
4f51b4bd 13893 N_P64 = 0x0200000,
c921be7d
NC
13894 N_KEY = 0x1000000, /* Key element (main type specifier). */
13895 N_EQK = 0x2000000, /* Given operand has the same type & size as the key. */
8e79c3df 13896 N_VFP = 0x4000000, /* VFP mode: operand size must match register width. */
91ff7894 13897 N_UNT = 0x8000000, /* Must be explicitly untyped. */
c921be7d
NC
13898 N_DBL = 0x0000001, /* If N_EQK, this operand is twice the size. */
13899 N_HLF = 0x0000002, /* If N_EQK, this operand is half the size. */
13900 N_SGN = 0x0000004, /* If N_EQK, this operand is forced to be signed. */
13901 N_UNS = 0x0000008, /* If N_EQK, this operand is forced to be unsigned. */
13902 N_INT = 0x0000010, /* If N_EQK, this operand is forced to be integer. */
13903 N_FLT = 0x0000020, /* If N_EQK, this operand is forced to be float. */
13904 N_SIZ = 0x0000040, /* If N_EQK, this operand is forced to be size-only. */
5287ad62 13905 N_UTYP = 0,
4f51b4bd 13906 N_MAX_NONSPECIAL = N_P64
5287ad62
JB
13907};
13908
dcbf9037
JB
13909#define N_ALLMODS (N_DBL | N_HLF | N_SGN | N_UNS | N_INT | N_FLT | N_SIZ)
13910
5287ad62
JB
13911#define N_SU_ALL (N_S8 | N_S16 | N_S32 | N_S64 | N_U8 | N_U16 | N_U32 | N_U64)
13912#define N_SU_32 (N_S8 | N_S16 | N_S32 | N_U8 | N_U16 | N_U32)
13913#define N_SU_16_64 (N_S16 | N_S32 | N_S64 | N_U16 | N_U32 | N_U64)
cc933301
JW
13914#define N_S_32 (N_S8 | N_S16 | N_S32)
13915#define N_F_16_32 (N_F16 | N_F32)
13916#define N_SUF_32 (N_SU_32 | N_F_16_32)
5287ad62 13917#define N_I_ALL (N_I8 | N_I16 | N_I32 | N_I64)
cc933301 13918#define N_IF_32 (N_I8 | N_I16 | N_I32 | N_F16 | N_F32)
d54af2d0 13919#define N_F_ALL (N_F16 | N_F32 | N_F64)
5287ad62
JB
13920
13921/* Pass this as the first type argument to neon_check_type to ignore types
13922 altogether. */
13923#define N_IGNORE_TYPE (N_KEY | N_EQK)
13924
037e8744
JB
13925/* Select a "shape" for the current instruction (describing register types or
13926 sizes) from a list of alternatives. Return NS_NULL if the current instruction
13927 doesn't fit. For non-polymorphic shapes, checking is usually done as a
13928 function of operand parsing, so this function doesn't need to be called.
13929 Shapes should be listed in order of decreasing length. */
5287ad62
JB
13930
13931static enum neon_shape
037e8744 13932neon_select_shape (enum neon_shape shape, ...)
5287ad62 13933{
037e8744
JB
13934 va_list ap;
13935 enum neon_shape first_shape = shape;
5287ad62
JB
13936
13937 /* Fix missing optional operands. FIXME: we don't know at this point how
13938 many arguments we should have, so this makes the assumption that we have
13939 > 1. This is true of all current Neon opcodes, I think, but may not be
13940 true in the future. */
13941 if (!inst.operands[1].present)
13942 inst.operands[1] = inst.operands[0];
13943
037e8744 13944 va_start (ap, shape);
5f4273c7 13945
21d799b5 13946 for (; shape != NS_NULL; shape = (enum neon_shape) va_arg (ap, int))
037e8744
JB
13947 {
13948 unsigned j;
13949 int matches = 1;
13950
13951 for (j = 0; j < neon_shape_tab[shape].els; j++)
477330fc
RM
13952 {
13953 if (!inst.operands[j].present)
13954 {
13955 matches = 0;
13956 break;
13957 }
13958
13959 switch (neon_shape_tab[shape].el[j])
13960 {
d54af2d0
RL
13961 /* If a .f16, .16, .u16, .s16 type specifier is given over
13962 a VFP single precision register operand, it's essentially
13963 means only half of the register is used.
13964
13965 If the type specifier is given after the mnemonics, the
13966 information is stored in inst.vectype. If the type specifier
13967 is given after register operand, the information is stored
13968 in inst.operands[].vectype.
13969
13970 When there is only one type specifier, and all the register
13971 operands are the same type of hardware register, the type
13972 specifier applies to all register operands.
13973
13974 If no type specifier is given, the shape is inferred from
13975 operand information.
13976
13977 for example:
13978 vadd.f16 s0, s1, s2: NS_HHH
13979 vabs.f16 s0, s1: NS_HH
13980 vmov.f16 s0, r1: NS_HR
13981 vmov.f16 r0, s1: NS_RH
13982 vcvt.f16 r0, s1: NS_RH
13983 vcvt.f16.s32 s2, s2, #29: NS_HFI
13984 vcvt.f16.s32 s2, s2: NS_HF
13985 */
13986 case SE_H:
13987 if (!(inst.operands[j].isreg
13988 && inst.operands[j].isvec
13989 && inst.operands[j].issingle
13990 && !inst.operands[j].isquad
13991 && ((inst.vectype.elems == 1
13992 && inst.vectype.el[0].size == 16)
13993 || (inst.vectype.elems > 1
13994 && inst.vectype.el[j].size == 16)
13995 || (inst.vectype.elems == 0
13996 && inst.operands[j].vectype.type != NT_invtype
13997 && inst.operands[j].vectype.size == 16))))
13998 matches = 0;
13999 break;
14000
477330fc
RM
14001 case SE_F:
14002 if (!(inst.operands[j].isreg
14003 && inst.operands[j].isvec
14004 && inst.operands[j].issingle
d54af2d0
RL
14005 && !inst.operands[j].isquad
14006 && ((inst.vectype.elems == 1 && inst.vectype.el[0].size == 32)
14007 || (inst.vectype.elems > 1 && inst.vectype.el[j].size == 32)
14008 || (inst.vectype.elems == 0
14009 && (inst.operands[j].vectype.size == 32
14010 || inst.operands[j].vectype.type == NT_invtype)))))
477330fc
RM
14011 matches = 0;
14012 break;
14013
14014 case SE_D:
14015 if (!(inst.operands[j].isreg
14016 && inst.operands[j].isvec
14017 && !inst.operands[j].isquad
14018 && !inst.operands[j].issingle))
14019 matches = 0;
14020 break;
14021
14022 case SE_R:
14023 if (!(inst.operands[j].isreg
14024 && !inst.operands[j].isvec))
14025 matches = 0;
14026 break;
14027
14028 case SE_Q:
14029 if (!(inst.operands[j].isreg
14030 && inst.operands[j].isvec
14031 && inst.operands[j].isquad
14032 && !inst.operands[j].issingle))
14033 matches = 0;
14034 break;
14035
14036 case SE_I:
14037 if (!(!inst.operands[j].isreg
14038 && !inst.operands[j].isscalar))
14039 matches = 0;
14040 break;
14041
14042 case SE_S:
14043 if (!(!inst.operands[j].isreg
14044 && inst.operands[j].isscalar))
14045 matches = 0;
14046 break;
14047
14048 case SE_L:
14049 break;
14050 }
3fde54a2
JZ
14051 if (!matches)
14052 break;
477330fc 14053 }
ad6cec43
MGD
14054 if (matches && (j >= ARM_IT_MAX_OPERANDS || !inst.operands[j].present))
14055 /* We've matched all the entries in the shape table, and we don't
14056 have any left over operands which have not been matched. */
477330fc 14057 break;
037e8744 14058 }
5f4273c7 14059
037e8744 14060 va_end (ap);
5287ad62 14061
037e8744
JB
14062 if (shape == NS_NULL && first_shape != NS_NULL)
14063 first_error (_("invalid instruction shape"));
5287ad62 14064
037e8744
JB
14065 return shape;
14066}
5287ad62 14067
037e8744
JB
14068/* True if SHAPE is predominantly a quadword operation (most of the time, this
14069 means the Q bit should be set). */
14070
14071static int
14072neon_quad (enum neon_shape shape)
14073{
14074 return neon_shape_class[shape] == SC_QUAD;
5287ad62 14075}
037e8744 14076
5287ad62
JB
14077static void
14078neon_modify_type_size (unsigned typebits, enum neon_el_type *g_type,
477330fc 14079 unsigned *g_size)
5287ad62
JB
14080{
14081 /* Allow modification to be made to types which are constrained to be
14082 based on the key element, based on bits set alongside N_EQK. */
14083 if ((typebits & N_EQK) != 0)
14084 {
14085 if ((typebits & N_HLF) != 0)
14086 *g_size /= 2;
14087 else if ((typebits & N_DBL) != 0)
14088 *g_size *= 2;
14089 if ((typebits & N_SGN) != 0)
14090 *g_type = NT_signed;
14091 else if ((typebits & N_UNS) != 0)
477330fc 14092 *g_type = NT_unsigned;
5287ad62 14093 else if ((typebits & N_INT) != 0)
477330fc 14094 *g_type = NT_integer;
5287ad62 14095 else if ((typebits & N_FLT) != 0)
477330fc 14096 *g_type = NT_float;
dcbf9037 14097 else if ((typebits & N_SIZ) != 0)
477330fc 14098 *g_type = NT_untyped;
5287ad62
JB
14099 }
14100}
5f4273c7 14101
5287ad62
JB
14102/* Return operand OPNO promoted by bits set in THISARG. KEY should be the "key"
14103 operand type, i.e. the single type specified in a Neon instruction when it
14104 is the only one given. */
14105
14106static struct neon_type_el
14107neon_type_promote (struct neon_type_el *key, unsigned thisarg)
14108{
14109 struct neon_type_el dest = *key;
5f4273c7 14110
9c2799c2 14111 gas_assert ((thisarg & N_EQK) != 0);
5f4273c7 14112
5287ad62
JB
14113 neon_modify_type_size (thisarg, &dest.type, &dest.size);
14114
14115 return dest;
14116}
14117
14118/* Convert Neon type and size into compact bitmask representation. */
14119
14120static enum neon_type_mask
14121type_chk_of_el_type (enum neon_el_type type, unsigned size)
14122{
14123 switch (type)
14124 {
14125 case NT_untyped:
14126 switch (size)
477330fc
RM
14127 {
14128 case 8: return N_8;
14129 case 16: return N_16;
14130 case 32: return N_32;
14131 case 64: return N_64;
14132 default: ;
14133 }
5287ad62
JB
14134 break;
14135
14136 case NT_integer:
14137 switch (size)
477330fc
RM
14138 {
14139 case 8: return N_I8;
14140 case 16: return N_I16;
14141 case 32: return N_I32;
14142 case 64: return N_I64;
14143 default: ;
14144 }
5287ad62
JB
14145 break;
14146
14147 case NT_float:
037e8744 14148 switch (size)
477330fc 14149 {
8e79c3df 14150 case 16: return N_F16;
477330fc
RM
14151 case 32: return N_F32;
14152 case 64: return N_F64;
14153 default: ;
14154 }
5287ad62
JB
14155 break;
14156
14157 case NT_poly:
14158 switch (size)
477330fc
RM
14159 {
14160 case 8: return N_P8;
14161 case 16: return N_P16;
4f51b4bd 14162 case 64: return N_P64;
477330fc
RM
14163 default: ;
14164 }
5287ad62
JB
14165 break;
14166
14167 case NT_signed:
14168 switch (size)
477330fc
RM
14169 {
14170 case 8: return N_S8;
14171 case 16: return N_S16;
14172 case 32: return N_S32;
14173 case 64: return N_S64;
14174 default: ;
14175 }
5287ad62
JB
14176 break;
14177
14178 case NT_unsigned:
14179 switch (size)
477330fc
RM
14180 {
14181 case 8: return N_U8;
14182 case 16: return N_U16;
14183 case 32: return N_U32;
14184 case 64: return N_U64;
14185 default: ;
14186 }
5287ad62
JB
14187 break;
14188
14189 default: ;
14190 }
5f4273c7 14191
5287ad62
JB
14192 return N_UTYP;
14193}
14194
14195/* Convert compact Neon bitmask type representation to a type and size. Only
14196 handles the case where a single bit is set in the mask. */
14197
dcbf9037 14198static int
5287ad62 14199el_type_of_type_chk (enum neon_el_type *type, unsigned *size,
477330fc 14200 enum neon_type_mask mask)
5287ad62 14201{
dcbf9037
JB
14202 if ((mask & N_EQK) != 0)
14203 return FAIL;
14204
5287ad62
JB
14205 if ((mask & (N_S8 | N_U8 | N_I8 | N_8 | N_P8)) != 0)
14206 *size = 8;
c70a8987 14207 else if ((mask & (N_S16 | N_U16 | N_I16 | N_16 | N_F16 | N_P16)) != 0)
5287ad62 14208 *size = 16;
dcbf9037 14209 else if ((mask & (N_S32 | N_U32 | N_I32 | N_32 | N_F32)) != 0)
5287ad62 14210 *size = 32;
4f51b4bd 14211 else if ((mask & (N_S64 | N_U64 | N_I64 | N_64 | N_F64 | N_P64)) != 0)
5287ad62 14212 *size = 64;
dcbf9037
JB
14213 else
14214 return FAIL;
14215
5287ad62
JB
14216 if ((mask & (N_S8 | N_S16 | N_S32 | N_S64)) != 0)
14217 *type = NT_signed;
dcbf9037 14218 else if ((mask & (N_U8 | N_U16 | N_U32 | N_U64)) != 0)
5287ad62 14219 *type = NT_unsigned;
dcbf9037 14220 else if ((mask & (N_I8 | N_I16 | N_I32 | N_I64)) != 0)
5287ad62 14221 *type = NT_integer;
dcbf9037 14222 else if ((mask & (N_8 | N_16 | N_32 | N_64)) != 0)
5287ad62 14223 *type = NT_untyped;
4f51b4bd 14224 else if ((mask & (N_P8 | N_P16 | N_P64)) != 0)
5287ad62 14225 *type = NT_poly;
d54af2d0 14226 else if ((mask & (N_F_ALL)) != 0)
5287ad62 14227 *type = NT_float;
dcbf9037
JB
14228 else
14229 return FAIL;
5f4273c7 14230
dcbf9037 14231 return SUCCESS;
5287ad62
JB
14232}
14233
14234/* Modify a bitmask of allowed types. This is only needed for type
14235 relaxation. */
14236
14237static unsigned
14238modify_types_allowed (unsigned allowed, unsigned mods)
14239{
14240 unsigned size;
14241 enum neon_el_type type;
14242 unsigned destmask;
14243 int i;
5f4273c7 14244
5287ad62 14245 destmask = 0;
5f4273c7 14246
5287ad62
JB
14247 for (i = 1; i <= N_MAX_NONSPECIAL; i <<= 1)
14248 {
21d799b5 14249 if (el_type_of_type_chk (&type, &size,
477330fc
RM
14250 (enum neon_type_mask) (allowed & i)) == SUCCESS)
14251 {
14252 neon_modify_type_size (mods, &type, &size);
14253 destmask |= type_chk_of_el_type (type, size);
14254 }
5287ad62 14255 }
5f4273c7 14256
5287ad62
JB
14257 return destmask;
14258}
14259
14260/* Check type and return type classification.
14261 The manual states (paraphrase): If one datatype is given, it indicates the
14262 type given in:
14263 - the second operand, if there is one
14264 - the operand, if there is no second operand
14265 - the result, if there are no operands.
14266 This isn't quite good enough though, so we use a concept of a "key" datatype
14267 which is set on a per-instruction basis, which is the one which matters when
14268 only one data type is written.
14269 Note: this function has side-effects (e.g. filling in missing operands). All
037e8744 14270 Neon instructions should call it before performing bit encoding. */
5287ad62
JB
14271
14272static struct neon_type_el
14273neon_check_type (unsigned els, enum neon_shape ns, ...)
14274{
14275 va_list ap;
14276 unsigned i, pass, key_el = 0;
14277 unsigned types[NEON_MAX_TYPE_ELS];
14278 enum neon_el_type k_type = NT_invtype;
14279 unsigned k_size = -1u;
14280 struct neon_type_el badtype = {NT_invtype, -1};
14281 unsigned key_allowed = 0;
14282
14283 /* Optional registers in Neon instructions are always (not) in operand 1.
14284 Fill in the missing operand here, if it was omitted. */
14285 if (els > 1 && !inst.operands[1].present)
14286 inst.operands[1] = inst.operands[0];
14287
14288 /* Suck up all the varargs. */
14289 va_start (ap, ns);
14290 for (i = 0; i < els; i++)
14291 {
14292 unsigned thisarg = va_arg (ap, unsigned);
14293 if (thisarg == N_IGNORE_TYPE)
477330fc
RM
14294 {
14295 va_end (ap);
14296 return badtype;
14297 }
5287ad62
JB
14298 types[i] = thisarg;
14299 if ((thisarg & N_KEY) != 0)
477330fc 14300 key_el = i;
5287ad62
JB
14301 }
14302 va_end (ap);
14303
dcbf9037
JB
14304 if (inst.vectype.elems > 0)
14305 for (i = 0; i < els; i++)
14306 if (inst.operands[i].vectype.type != NT_invtype)
477330fc
RM
14307 {
14308 first_error (_("types specified in both the mnemonic and operands"));
14309 return badtype;
14310 }
dcbf9037 14311
5287ad62
JB
14312 /* Duplicate inst.vectype elements here as necessary.
14313 FIXME: No idea if this is exactly the same as the ARM assembler,
14314 particularly when an insn takes one register and one non-register
14315 operand. */
14316 if (inst.vectype.elems == 1 && els > 1)
14317 {
14318 unsigned j;
14319 inst.vectype.elems = els;
14320 inst.vectype.el[key_el] = inst.vectype.el[0];
14321 for (j = 0; j < els; j++)
477330fc
RM
14322 if (j != key_el)
14323 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
14324 types[j]);
dcbf9037
JB
14325 }
14326 else if (inst.vectype.elems == 0 && els > 0)
14327 {
14328 unsigned j;
14329 /* No types were given after the mnemonic, so look for types specified
477330fc
RM
14330 after each operand. We allow some flexibility here; as long as the
14331 "key" operand has a type, we can infer the others. */
dcbf9037 14332 for (j = 0; j < els; j++)
477330fc
RM
14333 if (inst.operands[j].vectype.type != NT_invtype)
14334 inst.vectype.el[j] = inst.operands[j].vectype;
dcbf9037
JB
14335
14336 if (inst.operands[key_el].vectype.type != NT_invtype)
477330fc
RM
14337 {
14338 for (j = 0; j < els; j++)
14339 if (inst.operands[j].vectype.type == NT_invtype)
14340 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
14341 types[j]);
14342 }
dcbf9037 14343 else
477330fc
RM
14344 {
14345 first_error (_("operand types can't be inferred"));
14346 return badtype;
14347 }
5287ad62
JB
14348 }
14349 else if (inst.vectype.elems != els)
14350 {
dcbf9037 14351 first_error (_("type specifier has the wrong number of parts"));
5287ad62
JB
14352 return badtype;
14353 }
14354
14355 for (pass = 0; pass < 2; pass++)
14356 {
14357 for (i = 0; i < els; i++)
477330fc
RM
14358 {
14359 unsigned thisarg = types[i];
14360 unsigned types_allowed = ((thisarg & N_EQK) != 0 && pass != 0)
14361 ? modify_types_allowed (key_allowed, thisarg) : thisarg;
14362 enum neon_el_type g_type = inst.vectype.el[i].type;
14363 unsigned g_size = inst.vectype.el[i].size;
14364
14365 /* Decay more-specific signed & unsigned types to sign-insensitive
5287ad62 14366 integer types if sign-specific variants are unavailable. */
477330fc 14367 if ((g_type == NT_signed || g_type == NT_unsigned)
5287ad62
JB
14368 && (types_allowed & N_SU_ALL) == 0)
14369 g_type = NT_integer;
14370
477330fc 14371 /* If only untyped args are allowed, decay any more specific types to
5287ad62
JB
14372 them. Some instructions only care about signs for some element
14373 sizes, so handle that properly. */
477330fc 14374 if (((types_allowed & N_UNT) == 0)
91ff7894
MGD
14375 && ((g_size == 8 && (types_allowed & N_8) != 0)
14376 || (g_size == 16 && (types_allowed & N_16) != 0)
14377 || (g_size == 32 && (types_allowed & N_32) != 0)
14378 || (g_size == 64 && (types_allowed & N_64) != 0)))
5287ad62
JB
14379 g_type = NT_untyped;
14380
477330fc
RM
14381 if (pass == 0)
14382 {
14383 if ((thisarg & N_KEY) != 0)
14384 {
14385 k_type = g_type;
14386 k_size = g_size;
14387 key_allowed = thisarg & ~N_KEY;
cc933301
JW
14388
14389 /* Check architecture constraint on FP16 extension. */
14390 if (k_size == 16
14391 && k_type == NT_float
14392 && ! ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
14393 {
14394 inst.error = _(BAD_FP16);
14395 return badtype;
14396 }
477330fc
RM
14397 }
14398 }
14399 else
14400 {
14401 if ((thisarg & N_VFP) != 0)
14402 {
14403 enum neon_shape_el regshape;
14404 unsigned regwidth, match;
99b253c5
NC
14405
14406 /* PR 11136: Catch the case where we are passed a shape of NS_NULL. */
14407 if (ns == NS_NULL)
14408 {
14409 first_error (_("invalid instruction shape"));
14410 return badtype;
14411 }
477330fc
RM
14412 regshape = neon_shape_tab[ns].el[i];
14413 regwidth = neon_shape_el_size[regshape];
14414
14415 /* In VFP mode, operands must match register widths. If we
14416 have a key operand, use its width, else use the width of
14417 the current operand. */
14418 if (k_size != -1u)
14419 match = k_size;
14420 else
14421 match = g_size;
14422
9db2f6b4
RL
14423 /* FP16 will use a single precision register. */
14424 if (regwidth == 32 && match == 16)
14425 {
14426 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
14427 match = regwidth;
14428 else
14429 {
14430 inst.error = _(BAD_FP16);
14431 return badtype;
14432 }
14433 }
14434
477330fc
RM
14435 if (regwidth != match)
14436 {
14437 first_error (_("operand size must match register width"));
14438 return badtype;
14439 }
14440 }
14441
14442 if ((thisarg & N_EQK) == 0)
14443 {
14444 unsigned given_type = type_chk_of_el_type (g_type, g_size);
14445
14446 if ((given_type & types_allowed) == 0)
14447 {
14448 first_error (_("bad type in Neon instruction"));
14449 return badtype;
14450 }
14451 }
14452 else
14453 {
14454 enum neon_el_type mod_k_type = k_type;
14455 unsigned mod_k_size = k_size;
14456 neon_modify_type_size (thisarg, &mod_k_type, &mod_k_size);
14457 if (g_type != mod_k_type || g_size != mod_k_size)
14458 {
14459 first_error (_("inconsistent types in Neon instruction"));
14460 return badtype;
14461 }
14462 }
14463 }
14464 }
5287ad62
JB
14465 }
14466
14467 return inst.vectype.el[key_el];
14468}
14469
037e8744 14470/* Neon-style VFP instruction forwarding. */
5287ad62 14471
037e8744
JB
14472/* Thumb VFP instructions have 0xE in the condition field. */
14473
14474static void
14475do_vfp_cond_or_thumb (void)
5287ad62 14476{
88714cb8
DG
14477 inst.is_neon = 1;
14478
5287ad62 14479 if (thumb_mode)
037e8744 14480 inst.instruction |= 0xe0000000;
5287ad62 14481 else
037e8744 14482 inst.instruction |= inst.cond << 28;
5287ad62
JB
14483}
14484
037e8744
JB
14485/* Look up and encode a simple mnemonic, for use as a helper function for the
14486 Neon-style VFP syntax. This avoids duplication of bits of the insns table,
14487 etc. It is assumed that operand parsing has already been done, and that the
14488 operands are in the form expected by the given opcode (this isn't necessarily
14489 the same as the form in which they were parsed, hence some massaging must
14490 take place before this function is called).
14491 Checks current arch version against that in the looked-up opcode. */
5287ad62 14492
037e8744
JB
14493static void
14494do_vfp_nsyn_opcode (const char *opname)
5287ad62 14495{
037e8744 14496 const struct asm_opcode *opcode;
5f4273c7 14497
21d799b5 14498 opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, opname);
5287ad62 14499
037e8744
JB
14500 if (!opcode)
14501 abort ();
5287ad62 14502
037e8744 14503 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant,
477330fc
RM
14504 thumb_mode ? *opcode->tvariant : *opcode->avariant),
14505 _(BAD_FPU));
5287ad62 14506
88714cb8
DG
14507 inst.is_neon = 1;
14508
037e8744
JB
14509 if (thumb_mode)
14510 {
14511 inst.instruction = opcode->tvalue;
14512 opcode->tencode ();
14513 }
14514 else
14515 {
14516 inst.instruction = (inst.cond << 28) | opcode->avalue;
14517 opcode->aencode ();
14518 }
14519}
5287ad62
JB
14520
14521static void
037e8744 14522do_vfp_nsyn_add_sub (enum neon_shape rs)
5287ad62 14523{
037e8744
JB
14524 int is_add = (inst.instruction & 0x0fffffff) == N_MNEM_vadd;
14525
9db2f6b4 14526 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
14527 {
14528 if (is_add)
477330fc 14529 do_vfp_nsyn_opcode ("fadds");
037e8744 14530 else
477330fc 14531 do_vfp_nsyn_opcode ("fsubs");
9db2f6b4
RL
14532
14533 /* ARMv8.2 fp16 instruction. */
14534 if (rs == NS_HHH)
14535 do_scalar_fp16_v82_encode ();
037e8744
JB
14536 }
14537 else
14538 {
14539 if (is_add)
477330fc 14540 do_vfp_nsyn_opcode ("faddd");
037e8744 14541 else
477330fc 14542 do_vfp_nsyn_opcode ("fsubd");
037e8744
JB
14543 }
14544}
14545
14546/* Check operand types to see if this is a VFP instruction, and if so call
14547 PFN (). */
14548
14549static int
14550try_vfp_nsyn (int args, void (*pfn) (enum neon_shape))
14551{
14552 enum neon_shape rs;
14553 struct neon_type_el et;
14554
14555 switch (args)
14556 {
14557 case 2:
9db2f6b4
RL
14558 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
14559 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
037e8744 14560 break;
5f4273c7 14561
037e8744 14562 case 3:
9db2f6b4
RL
14563 rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
14564 et = neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
14565 N_F_ALL | N_KEY | N_VFP);
037e8744
JB
14566 break;
14567
14568 default:
14569 abort ();
14570 }
14571
14572 if (et.type != NT_invtype)
14573 {
14574 pfn (rs);
14575 return SUCCESS;
14576 }
037e8744 14577
99b253c5 14578 inst.error = NULL;
037e8744
JB
14579 return FAIL;
14580}
14581
14582static void
14583do_vfp_nsyn_mla_mls (enum neon_shape rs)
14584{
14585 int is_mla = (inst.instruction & 0x0fffffff) == N_MNEM_vmla;
5f4273c7 14586
9db2f6b4 14587 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
14588 {
14589 if (is_mla)
477330fc 14590 do_vfp_nsyn_opcode ("fmacs");
037e8744 14591 else
477330fc 14592 do_vfp_nsyn_opcode ("fnmacs");
9db2f6b4
RL
14593
14594 /* ARMv8.2 fp16 instruction. */
14595 if (rs == NS_HHH)
14596 do_scalar_fp16_v82_encode ();
037e8744
JB
14597 }
14598 else
14599 {
14600 if (is_mla)
477330fc 14601 do_vfp_nsyn_opcode ("fmacd");
037e8744 14602 else
477330fc 14603 do_vfp_nsyn_opcode ("fnmacd");
037e8744
JB
14604 }
14605}
14606
62f3b8c8
PB
14607static void
14608do_vfp_nsyn_fma_fms (enum neon_shape rs)
14609{
14610 int is_fma = (inst.instruction & 0x0fffffff) == N_MNEM_vfma;
14611
9db2f6b4 14612 if (rs == NS_FFF || rs == NS_HHH)
62f3b8c8
PB
14613 {
14614 if (is_fma)
477330fc 14615 do_vfp_nsyn_opcode ("ffmas");
62f3b8c8 14616 else
477330fc 14617 do_vfp_nsyn_opcode ("ffnmas");
9db2f6b4
RL
14618
14619 /* ARMv8.2 fp16 instruction. */
14620 if (rs == NS_HHH)
14621 do_scalar_fp16_v82_encode ();
62f3b8c8
PB
14622 }
14623 else
14624 {
14625 if (is_fma)
477330fc 14626 do_vfp_nsyn_opcode ("ffmad");
62f3b8c8 14627 else
477330fc 14628 do_vfp_nsyn_opcode ("ffnmad");
62f3b8c8
PB
14629 }
14630}
14631
037e8744
JB
14632static void
14633do_vfp_nsyn_mul (enum neon_shape rs)
14634{
9db2f6b4
RL
14635 if (rs == NS_FFF || rs == NS_HHH)
14636 {
14637 do_vfp_nsyn_opcode ("fmuls");
14638
14639 /* ARMv8.2 fp16 instruction. */
14640 if (rs == NS_HHH)
14641 do_scalar_fp16_v82_encode ();
14642 }
037e8744
JB
14643 else
14644 do_vfp_nsyn_opcode ("fmuld");
14645}
14646
14647static void
14648do_vfp_nsyn_abs_neg (enum neon_shape rs)
14649{
14650 int is_neg = (inst.instruction & 0x80) != 0;
9db2f6b4 14651 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_VFP | N_KEY);
037e8744 14652
9db2f6b4 14653 if (rs == NS_FF || rs == NS_HH)
037e8744
JB
14654 {
14655 if (is_neg)
477330fc 14656 do_vfp_nsyn_opcode ("fnegs");
037e8744 14657 else
477330fc 14658 do_vfp_nsyn_opcode ("fabss");
9db2f6b4
RL
14659
14660 /* ARMv8.2 fp16 instruction. */
14661 if (rs == NS_HH)
14662 do_scalar_fp16_v82_encode ();
037e8744
JB
14663 }
14664 else
14665 {
14666 if (is_neg)
477330fc 14667 do_vfp_nsyn_opcode ("fnegd");
037e8744 14668 else
477330fc 14669 do_vfp_nsyn_opcode ("fabsd");
037e8744
JB
14670 }
14671}
14672
14673/* Encode single-precision (only!) VFP fldm/fstm instructions. Double precision
14674 insns belong to Neon, and are handled elsewhere. */
14675
14676static void
14677do_vfp_nsyn_ldm_stm (int is_dbmode)
14678{
14679 int is_ldm = (inst.instruction & (1 << 20)) != 0;
14680 if (is_ldm)
14681 {
14682 if (is_dbmode)
477330fc 14683 do_vfp_nsyn_opcode ("fldmdbs");
037e8744 14684 else
477330fc 14685 do_vfp_nsyn_opcode ("fldmias");
037e8744
JB
14686 }
14687 else
14688 {
14689 if (is_dbmode)
477330fc 14690 do_vfp_nsyn_opcode ("fstmdbs");
037e8744 14691 else
477330fc 14692 do_vfp_nsyn_opcode ("fstmias");
037e8744
JB
14693 }
14694}
14695
037e8744
JB
14696static void
14697do_vfp_nsyn_sqrt (void)
14698{
9db2f6b4
RL
14699 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
14700 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 14701
9db2f6b4
RL
14702 if (rs == NS_FF || rs == NS_HH)
14703 {
14704 do_vfp_nsyn_opcode ("fsqrts");
14705
14706 /* ARMv8.2 fp16 instruction. */
14707 if (rs == NS_HH)
14708 do_scalar_fp16_v82_encode ();
14709 }
037e8744
JB
14710 else
14711 do_vfp_nsyn_opcode ("fsqrtd");
14712}
14713
14714static void
14715do_vfp_nsyn_div (void)
14716{
9db2f6b4 14717 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 14718 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 14719 N_F_ALL | N_KEY | N_VFP);
5f4273c7 14720
9db2f6b4
RL
14721 if (rs == NS_FFF || rs == NS_HHH)
14722 {
14723 do_vfp_nsyn_opcode ("fdivs");
14724
14725 /* ARMv8.2 fp16 instruction. */
14726 if (rs == NS_HHH)
14727 do_scalar_fp16_v82_encode ();
14728 }
037e8744
JB
14729 else
14730 do_vfp_nsyn_opcode ("fdivd");
14731}
14732
14733static void
14734do_vfp_nsyn_nmul (void)
14735{
9db2f6b4 14736 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 14737 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 14738 N_F_ALL | N_KEY | N_VFP);
5f4273c7 14739
9db2f6b4 14740 if (rs == NS_FFF || rs == NS_HHH)
037e8744 14741 {
88714cb8 14742 NEON_ENCODE (SINGLE, inst);
037e8744 14743 do_vfp_sp_dyadic ();
9db2f6b4
RL
14744
14745 /* ARMv8.2 fp16 instruction. */
14746 if (rs == NS_HHH)
14747 do_scalar_fp16_v82_encode ();
037e8744
JB
14748 }
14749 else
14750 {
88714cb8 14751 NEON_ENCODE (DOUBLE, inst);
037e8744
JB
14752 do_vfp_dp_rd_rn_rm ();
14753 }
14754 do_vfp_cond_or_thumb ();
9db2f6b4 14755
037e8744
JB
14756}
14757
14758static void
14759do_vfp_nsyn_cmp (void)
14760{
9db2f6b4 14761 enum neon_shape rs;
037e8744
JB
14762 if (inst.operands[1].isreg)
14763 {
9db2f6b4
RL
14764 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
14765 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 14766
9db2f6b4 14767 if (rs == NS_FF || rs == NS_HH)
477330fc
RM
14768 {
14769 NEON_ENCODE (SINGLE, inst);
14770 do_vfp_sp_monadic ();
14771 }
037e8744 14772 else
477330fc
RM
14773 {
14774 NEON_ENCODE (DOUBLE, inst);
14775 do_vfp_dp_rd_rm ();
14776 }
037e8744
JB
14777 }
14778 else
14779 {
9db2f6b4
RL
14780 rs = neon_select_shape (NS_HI, NS_FI, NS_DI, NS_NULL);
14781 neon_check_type (2, rs, N_F_ALL | N_KEY | N_VFP, N_EQK);
037e8744
JB
14782
14783 switch (inst.instruction & 0x0fffffff)
477330fc
RM
14784 {
14785 case N_MNEM_vcmp:
14786 inst.instruction += N_MNEM_vcmpz - N_MNEM_vcmp;
14787 break;
14788 case N_MNEM_vcmpe:
14789 inst.instruction += N_MNEM_vcmpez - N_MNEM_vcmpe;
14790 break;
14791 default:
14792 abort ();
14793 }
5f4273c7 14794
9db2f6b4 14795 if (rs == NS_FI || rs == NS_HI)
477330fc
RM
14796 {
14797 NEON_ENCODE (SINGLE, inst);
14798 do_vfp_sp_compare_z ();
14799 }
037e8744 14800 else
477330fc
RM
14801 {
14802 NEON_ENCODE (DOUBLE, inst);
14803 do_vfp_dp_rd ();
14804 }
037e8744
JB
14805 }
14806 do_vfp_cond_or_thumb ();
9db2f6b4
RL
14807
14808 /* ARMv8.2 fp16 instruction. */
14809 if (rs == NS_HI || rs == NS_HH)
14810 do_scalar_fp16_v82_encode ();
037e8744
JB
14811}
14812
14813static void
14814nsyn_insert_sp (void)
14815{
14816 inst.operands[1] = inst.operands[0];
14817 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
fdfde340 14818 inst.operands[0].reg = REG_SP;
037e8744
JB
14819 inst.operands[0].isreg = 1;
14820 inst.operands[0].writeback = 1;
14821 inst.operands[0].present = 1;
14822}
14823
14824static void
14825do_vfp_nsyn_push (void)
14826{
14827 nsyn_insert_sp ();
b126985e
NC
14828
14829 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
14830 _("register list must contain at least 1 and at most 16 "
14831 "registers"));
14832
037e8744
JB
14833 if (inst.operands[1].issingle)
14834 do_vfp_nsyn_opcode ("fstmdbs");
14835 else
14836 do_vfp_nsyn_opcode ("fstmdbd");
14837}
14838
14839static void
14840do_vfp_nsyn_pop (void)
14841{
14842 nsyn_insert_sp ();
b126985e
NC
14843
14844 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
14845 _("register list must contain at least 1 and at most 16 "
14846 "registers"));
14847
037e8744 14848 if (inst.operands[1].issingle)
22b5b651 14849 do_vfp_nsyn_opcode ("fldmias");
037e8744 14850 else
22b5b651 14851 do_vfp_nsyn_opcode ("fldmiad");
037e8744
JB
14852}
14853
14854/* Fix up Neon data-processing instructions, ORing in the correct bits for
14855 ARM mode or Thumb mode and moving the encoded bit 24 to bit 28. */
14856
88714cb8
DG
14857static void
14858neon_dp_fixup (struct arm_it* insn)
037e8744 14859{
88714cb8
DG
14860 unsigned int i = insn->instruction;
14861 insn->is_neon = 1;
14862
037e8744
JB
14863 if (thumb_mode)
14864 {
14865 /* The U bit is at bit 24 by default. Move to bit 28 in Thumb mode. */
14866 if (i & (1 << 24))
477330fc 14867 i |= 1 << 28;
5f4273c7 14868
037e8744 14869 i &= ~(1 << 24);
5f4273c7 14870
037e8744
JB
14871 i |= 0xef000000;
14872 }
14873 else
14874 i |= 0xf2000000;
5f4273c7 14875
88714cb8 14876 insn->instruction = i;
037e8744
JB
14877}
14878
14879/* Turn a size (8, 16, 32, 64) into the respective bit number minus 3
14880 (0, 1, 2, 3). */
14881
14882static unsigned
14883neon_logbits (unsigned x)
14884{
14885 return ffs (x) - 4;
14886}
14887
14888#define LOW4(R) ((R) & 0xf)
14889#define HI1(R) (((R) >> 4) & 1)
14890
14891/* Encode insns with bit pattern:
14892
14893 |28/24|23|22 |21 20|19 16|15 12|11 8|7|6|5|4|3 0|
14894 | U |x |D |size | Rn | Rd |x x x x|N|Q|M|x| Rm |
5f4273c7 14895
037e8744
JB
14896 SIZE is passed in bits. -1 means size field isn't changed, in case it has a
14897 different meaning for some instruction. */
14898
14899static void
14900neon_three_same (int isquad, int ubit, int size)
14901{
14902 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
14903 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
14904 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
14905 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
14906 inst.instruction |= LOW4 (inst.operands[2].reg);
14907 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
14908 inst.instruction |= (isquad != 0) << 6;
14909 inst.instruction |= (ubit != 0) << 24;
14910 if (size != -1)
14911 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 14912
88714cb8 14913 neon_dp_fixup (&inst);
037e8744
JB
14914}
14915
14916/* Encode instructions of the form:
14917
14918 |28/24|23|22|21 20|19 18|17 16|15 12|11 7|6|5|4|3 0|
14919 | U |x |D |x x |size |x x | Rd |x x x x x|Q|M|x| Rm |
5287ad62
JB
14920
14921 Don't write size if SIZE == -1. */
14922
14923static void
14924neon_two_same (int qbit, int ubit, int size)
14925{
14926 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
14927 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
14928 inst.instruction |= LOW4 (inst.operands[1].reg);
14929 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
14930 inst.instruction |= (qbit != 0) << 6;
14931 inst.instruction |= (ubit != 0) << 24;
14932
14933 if (size != -1)
14934 inst.instruction |= neon_logbits (size) << 18;
14935
88714cb8 14936 neon_dp_fixup (&inst);
5287ad62
JB
14937}
14938
14939/* Neon instruction encoders, in approximate order of appearance. */
14940
14941static void
14942do_neon_dyadic_i_su (void)
14943{
037e8744 14944 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
14945 struct neon_type_el et = neon_check_type (3, rs,
14946 N_EQK, N_EQK, N_SU_32 | N_KEY);
037e8744 14947 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
14948}
14949
14950static void
14951do_neon_dyadic_i64_su (void)
14952{
037e8744 14953 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
14954 struct neon_type_el et = neon_check_type (3, rs,
14955 N_EQK, N_EQK, N_SU_ALL | N_KEY);
037e8744 14956 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
14957}
14958
14959static void
14960neon_imm_shift (int write_ubit, int uval, int isquad, struct neon_type_el et,
477330fc 14961 unsigned immbits)
5287ad62
JB
14962{
14963 unsigned size = et.size >> 3;
14964 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
14965 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
14966 inst.instruction |= LOW4 (inst.operands[1].reg);
14967 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
14968 inst.instruction |= (isquad != 0) << 6;
14969 inst.instruction |= immbits << 16;
14970 inst.instruction |= (size >> 3) << 7;
14971 inst.instruction |= (size & 0x7) << 19;
14972 if (write_ubit)
14973 inst.instruction |= (uval != 0) << 24;
14974
88714cb8 14975 neon_dp_fixup (&inst);
5287ad62
JB
14976}
14977
14978static void
14979do_neon_shl_imm (void)
14980{
14981 if (!inst.operands[2].isreg)
14982 {
037e8744 14983 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62 14984 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_KEY | N_I_ALL);
cb3b1e65
JB
14985 int imm = inst.operands[2].imm;
14986
14987 constraint (imm < 0 || (unsigned)imm >= et.size,
14988 _("immediate out of range for shift"));
88714cb8 14989 NEON_ENCODE (IMMED, inst);
cb3b1e65 14990 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
14991 }
14992 else
14993 {
037e8744 14994 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62 14995 struct neon_type_el et = neon_check_type (3, rs,
477330fc 14996 N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
627907b7
JB
14997 unsigned int tmp;
14998
14999 /* VSHL/VQSHL 3-register variants have syntax such as:
477330fc
RM
15000 vshl.xx Dd, Dm, Dn
15001 whereas other 3-register operations encoded by neon_three_same have
15002 syntax like:
15003 vadd.xx Dd, Dn, Dm
15004 (i.e. with Dn & Dm reversed). Swap operands[1].reg and operands[2].reg
15005 here. */
627907b7
JB
15006 tmp = inst.operands[2].reg;
15007 inst.operands[2].reg = inst.operands[1].reg;
15008 inst.operands[1].reg = tmp;
88714cb8 15009 NEON_ENCODE (INTEGER, inst);
037e8744 15010 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
15011 }
15012}
15013
15014static void
15015do_neon_qshl_imm (void)
15016{
15017 if (!inst.operands[2].isreg)
15018 {
037e8744 15019 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62 15020 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
cb3b1e65 15021 int imm = inst.operands[2].imm;
627907b7 15022
cb3b1e65
JB
15023 constraint (imm < 0 || (unsigned)imm >= et.size,
15024 _("immediate out of range for shift"));
88714cb8 15025 NEON_ENCODE (IMMED, inst);
cb3b1e65 15026 neon_imm_shift (TRUE, et.type == NT_unsigned, neon_quad (rs), et, imm);
5287ad62
JB
15027 }
15028 else
15029 {
037e8744 15030 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62 15031 struct neon_type_el et = neon_check_type (3, rs,
477330fc 15032 N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
627907b7
JB
15033 unsigned int tmp;
15034
15035 /* See note in do_neon_shl_imm. */
15036 tmp = inst.operands[2].reg;
15037 inst.operands[2].reg = inst.operands[1].reg;
15038 inst.operands[1].reg = tmp;
88714cb8 15039 NEON_ENCODE (INTEGER, inst);
037e8744 15040 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
15041 }
15042}
15043
627907b7
JB
15044static void
15045do_neon_rshl (void)
15046{
15047 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
15048 struct neon_type_el et = neon_check_type (3, rs,
15049 N_EQK, N_EQK, N_SU_ALL | N_KEY);
15050 unsigned int tmp;
15051
15052 tmp = inst.operands[2].reg;
15053 inst.operands[2].reg = inst.operands[1].reg;
15054 inst.operands[1].reg = tmp;
15055 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
15056}
15057
5287ad62
JB
15058static int
15059neon_cmode_for_logic_imm (unsigned immediate, unsigned *immbits, int size)
15060{
036dc3f7
PB
15061 /* Handle .I8 pseudo-instructions. */
15062 if (size == 8)
5287ad62 15063 {
5287ad62 15064 /* Unfortunately, this will make everything apart from zero out-of-range.
477330fc
RM
15065 FIXME is this the intended semantics? There doesn't seem much point in
15066 accepting .I8 if so. */
5287ad62
JB
15067 immediate |= immediate << 8;
15068 size = 16;
036dc3f7
PB
15069 }
15070
15071 if (size >= 32)
15072 {
15073 if (immediate == (immediate & 0x000000ff))
15074 {
15075 *immbits = immediate;
15076 return 0x1;
15077 }
15078 else if (immediate == (immediate & 0x0000ff00))
15079 {
15080 *immbits = immediate >> 8;
15081 return 0x3;
15082 }
15083 else if (immediate == (immediate & 0x00ff0000))
15084 {
15085 *immbits = immediate >> 16;
15086 return 0x5;
15087 }
15088 else if (immediate == (immediate & 0xff000000))
15089 {
15090 *immbits = immediate >> 24;
15091 return 0x7;
15092 }
15093 if ((immediate & 0xffff) != (immediate >> 16))
15094 goto bad_immediate;
15095 immediate &= 0xffff;
5287ad62
JB
15096 }
15097
15098 if (immediate == (immediate & 0x000000ff))
15099 {
15100 *immbits = immediate;
036dc3f7 15101 return 0x9;
5287ad62
JB
15102 }
15103 else if (immediate == (immediate & 0x0000ff00))
15104 {
15105 *immbits = immediate >> 8;
036dc3f7 15106 return 0xb;
5287ad62
JB
15107 }
15108
15109 bad_immediate:
dcbf9037 15110 first_error (_("immediate value out of range"));
5287ad62
JB
15111 return FAIL;
15112}
15113
5287ad62
JB
15114static void
15115do_neon_logic (void)
15116{
15117 if (inst.operands[2].present && inst.operands[2].isreg)
15118 {
037e8744 15119 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
15120 neon_check_type (3, rs, N_IGNORE_TYPE);
15121 /* U bit and size field were set as part of the bitmask. */
88714cb8 15122 NEON_ENCODE (INTEGER, inst);
037e8744 15123 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
15124 }
15125 else
15126 {
4316f0d2
DG
15127 const int three_ops_form = (inst.operands[2].present
15128 && !inst.operands[2].isreg);
15129 const int immoperand = (three_ops_form ? 2 : 1);
15130 enum neon_shape rs = (three_ops_form
15131 ? neon_select_shape (NS_DDI, NS_QQI, NS_NULL)
15132 : neon_select_shape (NS_DI, NS_QI, NS_NULL));
037e8744 15133 struct neon_type_el et = neon_check_type (2, rs,
477330fc 15134 N_I8 | N_I16 | N_I32 | N_I64 | N_F32 | N_KEY, N_EQK);
21d799b5 15135 enum neon_opc opcode = (enum neon_opc) inst.instruction & 0x0fffffff;
5287ad62
JB
15136 unsigned immbits;
15137 int cmode;
5f4273c7 15138
5287ad62 15139 if (et.type == NT_invtype)
477330fc 15140 return;
5f4273c7 15141
4316f0d2
DG
15142 if (three_ops_form)
15143 constraint (inst.operands[0].reg != inst.operands[1].reg,
15144 _("first and second operands shall be the same register"));
15145
88714cb8 15146 NEON_ENCODE (IMMED, inst);
5287ad62 15147
4316f0d2 15148 immbits = inst.operands[immoperand].imm;
036dc3f7
PB
15149 if (et.size == 64)
15150 {
15151 /* .i64 is a pseudo-op, so the immediate must be a repeating
15152 pattern. */
4316f0d2
DG
15153 if (immbits != (inst.operands[immoperand].regisimm ?
15154 inst.operands[immoperand].reg : 0))
036dc3f7
PB
15155 {
15156 /* Set immbits to an invalid constant. */
15157 immbits = 0xdeadbeef;
15158 }
15159 }
15160
5287ad62 15161 switch (opcode)
477330fc
RM
15162 {
15163 case N_MNEM_vbic:
15164 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
15165 break;
15166
15167 case N_MNEM_vorr:
15168 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
15169 break;
15170
15171 case N_MNEM_vand:
15172 /* Pseudo-instruction for VBIC. */
15173 neon_invert_size (&immbits, 0, et.size);
15174 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
15175 break;
15176
15177 case N_MNEM_vorn:
15178 /* Pseudo-instruction for VORR. */
15179 neon_invert_size (&immbits, 0, et.size);
15180 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
15181 break;
15182
15183 default:
15184 abort ();
15185 }
5287ad62
JB
15186
15187 if (cmode == FAIL)
477330fc 15188 return;
5287ad62 15189
037e8744 15190 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
15191 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15192 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15193 inst.instruction |= cmode << 8;
15194 neon_write_immbits (immbits);
5f4273c7 15195
88714cb8 15196 neon_dp_fixup (&inst);
5287ad62
JB
15197 }
15198}
15199
15200static void
15201do_neon_bitfield (void)
15202{
037e8744 15203 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
dcbf9037 15204 neon_check_type (3, rs, N_IGNORE_TYPE);
037e8744 15205 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
15206}
15207
15208static void
dcbf9037 15209neon_dyadic_misc (enum neon_el_type ubit_meaning, unsigned types,
477330fc 15210 unsigned destbits)
5287ad62 15211{
037e8744 15212 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
dcbf9037 15213 struct neon_type_el et = neon_check_type (3, rs, N_EQK | destbits, N_EQK,
477330fc 15214 types | N_KEY);
5287ad62
JB
15215 if (et.type == NT_float)
15216 {
88714cb8 15217 NEON_ENCODE (FLOAT, inst);
cc933301 15218 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
15219 }
15220 else
15221 {
88714cb8 15222 NEON_ENCODE (INTEGER, inst);
037e8744 15223 neon_three_same (neon_quad (rs), et.type == ubit_meaning, et.size);
5287ad62
JB
15224 }
15225}
15226
15227static void
15228do_neon_dyadic_if_su (void)
15229{
dcbf9037 15230 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
5287ad62
JB
15231}
15232
15233static void
15234do_neon_dyadic_if_su_d (void)
15235{
15236 /* This version only allow D registers, but that constraint is enforced during
15237 operand parsing so we don't need to do anything extra here. */
dcbf9037 15238 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
5287ad62
JB
15239}
15240
5287ad62
JB
15241static void
15242do_neon_dyadic_if_i_d (void)
15243{
428e3f1f
PB
15244 /* The "untyped" case can't happen. Do this to stop the "U" bit being
15245 affected if we specify unsigned args. */
15246 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
5287ad62
JB
15247}
15248
037e8744
JB
15249enum vfp_or_neon_is_neon_bits
15250{
15251 NEON_CHECK_CC = 1,
73924fbc
MGD
15252 NEON_CHECK_ARCH = 2,
15253 NEON_CHECK_ARCH8 = 4
037e8744
JB
15254};
15255
15256/* Call this function if an instruction which may have belonged to the VFP or
15257 Neon instruction sets, but turned out to be a Neon instruction (due to the
15258 operand types involved, etc.). We have to check and/or fix-up a couple of
15259 things:
15260
15261 - Make sure the user hasn't attempted to make a Neon instruction
15262 conditional.
15263 - Alter the value in the condition code field if necessary.
15264 - Make sure that the arch supports Neon instructions.
15265
15266 Which of these operations take place depends on bits from enum
15267 vfp_or_neon_is_neon_bits.
15268
15269 WARNING: This function has side effects! If NEON_CHECK_CC is used and the
15270 current instruction's condition is COND_ALWAYS, the condition field is
15271 changed to inst.uncond_value. This is necessary because instructions shared
15272 between VFP and Neon may be conditional for the VFP variants only, and the
15273 unconditional Neon version must have, e.g., 0xF in the condition field. */
15274
15275static int
15276vfp_or_neon_is_neon (unsigned check)
15277{
15278 /* Conditions are always legal in Thumb mode (IT blocks). */
15279 if (!thumb_mode && (check & NEON_CHECK_CC))
15280 {
15281 if (inst.cond != COND_ALWAYS)
477330fc
RM
15282 {
15283 first_error (_(BAD_COND));
15284 return FAIL;
15285 }
037e8744 15286 if (inst.uncond_value != -1)
477330fc 15287 inst.instruction |= inst.uncond_value << 28;
037e8744 15288 }
5f4273c7 15289
037e8744 15290 if ((check & NEON_CHECK_ARCH)
73924fbc
MGD
15291 && !mark_feature_used (&fpu_neon_ext_v1))
15292 {
15293 first_error (_(BAD_FPU));
15294 return FAIL;
15295 }
15296
15297 if ((check & NEON_CHECK_ARCH8)
15298 && !mark_feature_used (&fpu_neon_ext_armv8))
037e8744
JB
15299 {
15300 first_error (_(BAD_FPU));
15301 return FAIL;
15302 }
5f4273c7 15303
037e8744
JB
15304 return SUCCESS;
15305}
15306
5287ad62
JB
15307static void
15308do_neon_addsub_if_i (void)
15309{
037e8744
JB
15310 if (try_vfp_nsyn (3, do_vfp_nsyn_add_sub) == SUCCESS)
15311 return;
15312
15313 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
15314 return;
15315
5287ad62
JB
15316 /* The "untyped" case can't happen. Do this to stop the "U" bit being
15317 affected if we specify unsigned args. */
dcbf9037 15318 neon_dyadic_misc (NT_untyped, N_IF_32 | N_I64, 0);
5287ad62
JB
15319}
15320
15321/* Swaps operands 1 and 2. If operand 1 (optional arg) was omitted, we want the
15322 result to be:
15323 V<op> A,B (A is operand 0, B is operand 2)
15324 to mean:
15325 V<op> A,B,A
15326 not:
15327 V<op> A,B,B
15328 so handle that case specially. */
15329
15330static void
15331neon_exchange_operands (void)
15332{
5287ad62
JB
15333 if (inst.operands[1].present)
15334 {
e1fa0163
NC
15335 void *scratch = xmalloc (sizeof (inst.operands[0]));
15336
5287ad62
JB
15337 /* Swap operands[1] and operands[2]. */
15338 memcpy (scratch, &inst.operands[1], sizeof (inst.operands[0]));
15339 inst.operands[1] = inst.operands[2];
15340 memcpy (&inst.operands[2], scratch, sizeof (inst.operands[0]));
e1fa0163 15341 free (scratch);
5287ad62
JB
15342 }
15343 else
15344 {
15345 inst.operands[1] = inst.operands[2];
15346 inst.operands[2] = inst.operands[0];
15347 }
15348}
15349
15350static void
15351neon_compare (unsigned regtypes, unsigned immtypes, int invert)
15352{
15353 if (inst.operands[2].isreg)
15354 {
15355 if (invert)
477330fc 15356 neon_exchange_operands ();
dcbf9037 15357 neon_dyadic_misc (NT_unsigned, regtypes, N_SIZ);
5287ad62
JB
15358 }
15359 else
15360 {
037e8744 15361 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
dcbf9037 15362 struct neon_type_el et = neon_check_type (2, rs,
477330fc 15363 N_EQK | N_SIZ, immtypes | N_KEY);
5287ad62 15364
88714cb8 15365 NEON_ENCODE (IMMED, inst);
5287ad62
JB
15366 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15367 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15368 inst.instruction |= LOW4 (inst.operands[1].reg);
15369 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 15370 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
15371 inst.instruction |= (et.type == NT_float) << 10;
15372 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 15373
88714cb8 15374 neon_dp_fixup (&inst);
5287ad62
JB
15375 }
15376}
15377
15378static void
15379do_neon_cmp (void)
15380{
cc933301 15381 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, FALSE);
5287ad62
JB
15382}
15383
15384static void
15385do_neon_cmp_inv (void)
15386{
cc933301 15387 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, TRUE);
5287ad62
JB
15388}
15389
15390static void
15391do_neon_ceq (void)
15392{
15393 neon_compare (N_IF_32, N_IF_32, FALSE);
15394}
15395
15396/* For multiply instructions, we have the possibility of 16-bit or 32-bit
15397 scalars, which are encoded in 5 bits, M : Rm.
15398 For 16-bit scalars, the register is encoded in Rm[2:0] and the index in
15399 M:Rm[3], and for 32-bit scalars, the register is encoded in Rm[3:0] and the
c604a79a
JW
15400 index in M.
15401
15402 Dot Product instructions are similar to multiply instructions except elsize
15403 should always be 32.
15404
15405 This function translates SCALAR, which is GAS's internal encoding of indexed
15406 scalar register, to raw encoding. There is also register and index range
15407 check based on ELSIZE. */
5287ad62
JB
15408
15409static unsigned
15410neon_scalar_for_mul (unsigned scalar, unsigned elsize)
15411{
dcbf9037
JB
15412 unsigned regno = NEON_SCALAR_REG (scalar);
15413 unsigned elno = NEON_SCALAR_INDEX (scalar);
5287ad62
JB
15414
15415 switch (elsize)
15416 {
15417 case 16:
15418 if (regno > 7 || elno > 3)
477330fc 15419 goto bad_scalar;
5287ad62 15420 return regno | (elno << 3);
5f4273c7 15421
5287ad62
JB
15422 case 32:
15423 if (regno > 15 || elno > 1)
477330fc 15424 goto bad_scalar;
5287ad62
JB
15425 return regno | (elno << 4);
15426
15427 default:
15428 bad_scalar:
dcbf9037 15429 first_error (_("scalar out of range for multiply instruction"));
5287ad62
JB
15430 }
15431
15432 return 0;
15433}
15434
15435/* Encode multiply / multiply-accumulate scalar instructions. */
15436
15437static void
15438neon_mul_mac (struct neon_type_el et, int ubit)
15439{
dcbf9037
JB
15440 unsigned scalar;
15441
15442 /* Give a more helpful error message if we have an invalid type. */
15443 if (et.type == NT_invtype)
15444 return;
5f4273c7 15445
dcbf9037 15446 scalar = neon_scalar_for_mul (inst.operands[2].reg, et.size);
5287ad62
JB
15447 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15448 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15449 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15450 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
15451 inst.instruction |= LOW4 (scalar);
15452 inst.instruction |= HI1 (scalar) << 5;
15453 inst.instruction |= (et.type == NT_float) << 8;
15454 inst.instruction |= neon_logbits (et.size) << 20;
15455 inst.instruction |= (ubit != 0) << 24;
15456
88714cb8 15457 neon_dp_fixup (&inst);
5287ad62
JB
15458}
15459
15460static void
15461do_neon_mac_maybe_scalar (void)
15462{
037e8744
JB
15463 if (try_vfp_nsyn (3, do_vfp_nsyn_mla_mls) == SUCCESS)
15464 return;
15465
15466 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
15467 return;
15468
5287ad62
JB
15469 if (inst.operands[2].isscalar)
15470 {
037e8744 15471 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 15472 struct neon_type_el et = neon_check_type (3, rs,
589a7d88 15473 N_EQK, N_EQK, N_I16 | N_I32 | N_F_16_32 | N_KEY);
88714cb8 15474 NEON_ENCODE (SCALAR, inst);
037e8744 15475 neon_mul_mac (et, neon_quad (rs));
5287ad62
JB
15476 }
15477 else
428e3f1f
PB
15478 {
15479 /* The "untyped" case can't happen. Do this to stop the "U" bit being
15480 affected if we specify unsigned args. */
15481 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
15482 }
5287ad62
JB
15483}
15484
62f3b8c8
PB
15485static void
15486do_neon_fmac (void)
15487{
15488 if (try_vfp_nsyn (3, do_vfp_nsyn_fma_fms) == SUCCESS)
15489 return;
15490
15491 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
15492 return;
15493
15494 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
15495}
15496
5287ad62
JB
15497static void
15498do_neon_tst (void)
15499{
037e8744 15500 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
15501 struct neon_type_el et = neon_check_type (3, rs,
15502 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_KEY);
037e8744 15503 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
15504}
15505
15506/* VMUL with 3 registers allows the P8 type. The scalar version supports the
15507 same types as the MAC equivalents. The polynomial type for this instruction
15508 is encoded the same as the integer type. */
15509
15510static void
15511do_neon_mul (void)
15512{
037e8744
JB
15513 if (try_vfp_nsyn (3, do_vfp_nsyn_mul) == SUCCESS)
15514 return;
15515
15516 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
15517 return;
15518
5287ad62
JB
15519 if (inst.operands[2].isscalar)
15520 do_neon_mac_maybe_scalar ();
15521 else
cc933301 15522 neon_dyadic_misc (NT_poly, N_I8 | N_I16 | N_I32 | N_F16 | N_F32 | N_P8, 0);
5287ad62
JB
15523}
15524
15525static void
15526do_neon_qdmulh (void)
15527{
15528 if (inst.operands[2].isscalar)
15529 {
037e8744 15530 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 15531 struct neon_type_el et = neon_check_type (3, rs,
477330fc 15532 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
88714cb8 15533 NEON_ENCODE (SCALAR, inst);
037e8744 15534 neon_mul_mac (et, neon_quad (rs));
5287ad62
JB
15535 }
15536 else
15537 {
037e8744 15538 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62 15539 struct neon_type_el et = neon_check_type (3, rs,
477330fc 15540 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
88714cb8 15541 NEON_ENCODE (INTEGER, inst);
5287ad62 15542 /* The U bit (rounding) comes from bit mask. */
037e8744 15543 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
15544 }
15545}
15546
643afb90
MW
15547static void
15548do_neon_qrdmlah (void)
15549{
15550 /* Check we're on the correct architecture. */
15551 if (!mark_feature_used (&fpu_neon_ext_armv8))
15552 inst.error =
15553 _("instruction form not available on this architecture.");
15554 else if (!mark_feature_used (&fpu_neon_ext_v8_1))
15555 {
15556 as_warn (_("this instruction implies use of ARMv8.1 AdvSIMD."));
15557 record_feature_use (&fpu_neon_ext_v8_1);
15558 }
15559
15560 if (inst.operands[2].isscalar)
15561 {
15562 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
15563 struct neon_type_el et = neon_check_type (3, rs,
15564 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
15565 NEON_ENCODE (SCALAR, inst);
15566 neon_mul_mac (et, neon_quad (rs));
15567 }
15568 else
15569 {
15570 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
15571 struct neon_type_el et = neon_check_type (3, rs,
15572 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
15573 NEON_ENCODE (INTEGER, inst);
15574 /* The U bit (rounding) comes from bit mask. */
15575 neon_three_same (neon_quad (rs), 0, et.size);
15576 }
15577}
15578
5287ad62
JB
15579static void
15580do_neon_fcmp_absolute (void)
15581{
037e8744 15582 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
15583 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
15584 N_F_16_32 | N_KEY);
5287ad62 15585 /* Size field comes from bit mask. */
cc933301 15586 neon_three_same (neon_quad (rs), 1, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
15587}
15588
15589static void
15590do_neon_fcmp_absolute_inv (void)
15591{
15592 neon_exchange_operands ();
15593 do_neon_fcmp_absolute ();
15594}
15595
15596static void
15597do_neon_step (void)
15598{
037e8744 15599 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
15600 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
15601 N_F_16_32 | N_KEY);
15602 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
15603}
15604
15605static void
15606do_neon_abs_neg (void)
15607{
037e8744
JB
15608 enum neon_shape rs;
15609 struct neon_type_el et;
5f4273c7 15610
037e8744
JB
15611 if (try_vfp_nsyn (2, do_vfp_nsyn_abs_neg) == SUCCESS)
15612 return;
15613
15614 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
15615 return;
15616
15617 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
cc933301 15618 et = neon_check_type (2, rs, N_EQK, N_S_32 | N_F_16_32 | N_KEY);
5f4273c7 15619
5287ad62
JB
15620 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15621 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15622 inst.instruction |= LOW4 (inst.operands[1].reg);
15623 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 15624 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
15625 inst.instruction |= (et.type == NT_float) << 10;
15626 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 15627
88714cb8 15628 neon_dp_fixup (&inst);
5287ad62
JB
15629}
15630
15631static void
15632do_neon_sli (void)
15633{
037e8744 15634 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
15635 struct neon_type_el et = neon_check_type (2, rs,
15636 N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
15637 int imm = inst.operands[2].imm;
15638 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 15639 _("immediate out of range for insert"));
037e8744 15640 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
15641}
15642
15643static void
15644do_neon_sri (void)
15645{
037e8744 15646 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
15647 struct neon_type_el et = neon_check_type (2, rs,
15648 N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
15649 int imm = inst.operands[2].imm;
15650 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 15651 _("immediate out of range for insert"));
037e8744 15652 neon_imm_shift (FALSE, 0, neon_quad (rs), et, et.size - imm);
5287ad62
JB
15653}
15654
15655static void
15656do_neon_qshlu_imm (void)
15657{
037e8744 15658 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
15659 struct neon_type_el et = neon_check_type (2, rs,
15660 N_EQK | N_UNS, N_S8 | N_S16 | N_S32 | N_S64 | N_KEY);
15661 int imm = inst.operands[2].imm;
15662 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 15663 _("immediate out of range for shift"));
5287ad62
JB
15664 /* Only encodes the 'U present' variant of the instruction.
15665 In this case, signed types have OP (bit 8) set to 0.
15666 Unsigned types have OP set to 1. */
15667 inst.instruction |= (et.type == NT_unsigned) << 8;
15668 /* The rest of the bits are the same as other immediate shifts. */
037e8744 15669 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
15670}
15671
15672static void
15673do_neon_qmovn (void)
15674{
15675 struct neon_type_el et = neon_check_type (2, NS_DQ,
15676 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
15677 /* Saturating move where operands can be signed or unsigned, and the
15678 destination has the same signedness. */
88714cb8 15679 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
15680 if (et.type == NT_unsigned)
15681 inst.instruction |= 0xc0;
15682 else
15683 inst.instruction |= 0x80;
15684 neon_two_same (0, 1, et.size / 2);
15685}
15686
15687static void
15688do_neon_qmovun (void)
15689{
15690 struct neon_type_el et = neon_check_type (2, NS_DQ,
15691 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
15692 /* Saturating move with unsigned results. Operands must be signed. */
88714cb8 15693 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
15694 neon_two_same (0, 1, et.size / 2);
15695}
15696
15697static void
15698do_neon_rshift_sat_narrow (void)
15699{
15700 /* FIXME: Types for narrowing. If operands are signed, results can be signed
15701 or unsigned. If operands are unsigned, results must also be unsigned. */
15702 struct neon_type_el et = neon_check_type (2, NS_DQI,
15703 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
15704 int imm = inst.operands[2].imm;
15705 /* This gets the bounds check, size encoding and immediate bits calculation
15706 right. */
15707 et.size /= 2;
5f4273c7 15708
5287ad62
JB
15709 /* VQ{R}SHRN.I<size> <Dd>, <Qm>, #0 is a synonym for
15710 VQMOVN.I<size> <Dd>, <Qm>. */
15711 if (imm == 0)
15712 {
15713 inst.operands[2].present = 0;
15714 inst.instruction = N_MNEM_vqmovn;
15715 do_neon_qmovn ();
15716 return;
15717 }
5f4273c7 15718
5287ad62 15719 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 15720 _("immediate out of range"));
5287ad62
JB
15721 neon_imm_shift (TRUE, et.type == NT_unsigned, 0, et, et.size - imm);
15722}
15723
15724static void
15725do_neon_rshift_sat_narrow_u (void)
15726{
15727 /* FIXME: Types for narrowing. If operands are signed, results can be signed
15728 or unsigned. If operands are unsigned, results must also be unsigned. */
15729 struct neon_type_el et = neon_check_type (2, NS_DQI,
15730 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
15731 int imm = inst.operands[2].imm;
15732 /* This gets the bounds check, size encoding and immediate bits calculation
15733 right. */
15734 et.size /= 2;
15735
15736 /* VQSHRUN.I<size> <Dd>, <Qm>, #0 is a synonym for
15737 VQMOVUN.I<size> <Dd>, <Qm>. */
15738 if (imm == 0)
15739 {
15740 inst.operands[2].present = 0;
15741 inst.instruction = N_MNEM_vqmovun;
15742 do_neon_qmovun ();
15743 return;
15744 }
15745
15746 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 15747 _("immediate out of range"));
5287ad62
JB
15748 /* FIXME: The manual is kind of unclear about what value U should have in
15749 VQ{R}SHRUN instructions, but U=0, op=0 definitely encodes VRSHR, so it
15750 must be 1. */
15751 neon_imm_shift (TRUE, 1, 0, et, et.size - imm);
15752}
15753
15754static void
15755do_neon_movn (void)
15756{
15757 struct neon_type_el et = neon_check_type (2, NS_DQ,
15758 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
88714cb8 15759 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
15760 neon_two_same (0, 1, et.size / 2);
15761}
15762
15763static void
15764do_neon_rshift_narrow (void)
15765{
15766 struct neon_type_el et = neon_check_type (2, NS_DQI,
15767 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
15768 int imm = inst.operands[2].imm;
15769 /* This gets the bounds check, size encoding and immediate bits calculation
15770 right. */
15771 et.size /= 2;
5f4273c7 15772
5287ad62
JB
15773 /* If immediate is zero then we are a pseudo-instruction for
15774 VMOVN.I<size> <Dd>, <Qm> */
15775 if (imm == 0)
15776 {
15777 inst.operands[2].present = 0;
15778 inst.instruction = N_MNEM_vmovn;
15779 do_neon_movn ();
15780 return;
15781 }
5f4273c7 15782
5287ad62 15783 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 15784 _("immediate out of range for narrowing operation"));
5287ad62
JB
15785 neon_imm_shift (FALSE, 0, 0, et, et.size - imm);
15786}
15787
15788static void
15789do_neon_shll (void)
15790{
15791 /* FIXME: Type checking when lengthening. */
15792 struct neon_type_el et = neon_check_type (2, NS_QDI,
15793 N_EQK | N_DBL, N_I8 | N_I16 | N_I32 | N_KEY);
15794 unsigned imm = inst.operands[2].imm;
15795
15796 if (imm == et.size)
15797 {
15798 /* Maximum shift variant. */
88714cb8 15799 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
15800 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15801 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15802 inst.instruction |= LOW4 (inst.operands[1].reg);
15803 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
15804 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 15805
88714cb8 15806 neon_dp_fixup (&inst);
5287ad62
JB
15807 }
15808 else
15809 {
15810 /* A more-specific type check for non-max versions. */
15811 et = neon_check_type (2, NS_QDI,
477330fc 15812 N_EQK | N_DBL, N_SU_32 | N_KEY);
88714cb8 15813 NEON_ENCODE (IMMED, inst);
5287ad62
JB
15814 neon_imm_shift (TRUE, et.type == NT_unsigned, 0, et, imm);
15815 }
15816}
15817
037e8744 15818/* Check the various types for the VCVT instruction, and return which version
5287ad62
JB
15819 the current instruction is. */
15820
6b9a8b67
MGD
15821#define CVT_FLAVOUR_VAR \
15822 CVT_VAR (s32_f32, N_S32, N_F32, whole_reg, "ftosls", "ftosis", "ftosizs") \
15823 CVT_VAR (u32_f32, N_U32, N_F32, whole_reg, "ftouls", "ftouis", "ftouizs") \
15824 CVT_VAR (f32_s32, N_F32, N_S32, whole_reg, "fsltos", "fsitos", NULL) \
15825 CVT_VAR (f32_u32, N_F32, N_U32, whole_reg, "fultos", "fuitos", NULL) \
15826 /* Half-precision conversions. */ \
cc933301
JW
15827 CVT_VAR (s16_f16, N_S16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
15828 CVT_VAR (u16_f16, N_U16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
15829 CVT_VAR (f16_s16, N_F16 | N_KEY, N_S16, whole_reg, NULL, NULL, NULL) \
15830 CVT_VAR (f16_u16, N_F16 | N_KEY, N_U16, whole_reg, NULL, NULL, NULL) \
6b9a8b67
MGD
15831 CVT_VAR (f32_f16, N_F32, N_F16, whole_reg, NULL, NULL, NULL) \
15832 CVT_VAR (f16_f32, N_F16, N_F32, whole_reg, NULL, NULL, NULL) \
9db2f6b4
RL
15833 /* New VCVT instructions introduced by ARMv8.2 fp16 extension. \
15834 Compared with single/double precision variants, only the co-processor \
15835 field is different, so the encoding flow is reused here. */ \
15836 CVT_VAR (f16_s32, N_F16 | N_KEY, N_S32, N_VFP, "fsltos", "fsitos", NULL) \
15837 CVT_VAR (f16_u32, N_F16 | N_KEY, N_U32, N_VFP, "fultos", "fuitos", NULL) \
15838 CVT_VAR (u32_f16, N_U32, N_F16 | N_KEY, N_VFP, "ftouls", "ftouis", "ftouizs")\
15839 CVT_VAR (s32_f16, N_S32, N_F16 | N_KEY, N_VFP, "ftosls", "ftosis", "ftosizs")\
6b9a8b67
MGD
15840 /* VFP instructions. */ \
15841 CVT_VAR (f32_f64, N_F32, N_F64, N_VFP, NULL, "fcvtsd", NULL) \
15842 CVT_VAR (f64_f32, N_F64, N_F32, N_VFP, NULL, "fcvtds", NULL) \
15843 CVT_VAR (s32_f64, N_S32, N_F64 | key, N_VFP, "ftosld", "ftosid", "ftosizd") \
15844 CVT_VAR (u32_f64, N_U32, N_F64 | key, N_VFP, "ftould", "ftouid", "ftouizd") \
15845 CVT_VAR (f64_s32, N_F64 | key, N_S32, N_VFP, "fsltod", "fsitod", NULL) \
15846 CVT_VAR (f64_u32, N_F64 | key, N_U32, N_VFP, "fultod", "fuitod", NULL) \
15847 /* VFP instructions with bitshift. */ \
15848 CVT_VAR (f32_s16, N_F32 | key, N_S16, N_VFP, "fshtos", NULL, NULL) \
15849 CVT_VAR (f32_u16, N_F32 | key, N_U16, N_VFP, "fuhtos", NULL, NULL) \
15850 CVT_VAR (f64_s16, N_F64 | key, N_S16, N_VFP, "fshtod", NULL, NULL) \
15851 CVT_VAR (f64_u16, N_F64 | key, N_U16, N_VFP, "fuhtod", NULL, NULL) \
15852 CVT_VAR (s16_f32, N_S16, N_F32 | key, N_VFP, "ftoshs", NULL, NULL) \
15853 CVT_VAR (u16_f32, N_U16, N_F32 | key, N_VFP, "ftouhs", NULL, NULL) \
15854 CVT_VAR (s16_f64, N_S16, N_F64 | key, N_VFP, "ftoshd", NULL, NULL) \
15855 CVT_VAR (u16_f64, N_U16, N_F64 | key, N_VFP, "ftouhd", NULL, NULL)
15856
15857#define CVT_VAR(C, X, Y, R, BSN, CN, ZN) \
15858 neon_cvt_flavour_##C,
15859
15860/* The different types of conversions we can do. */
15861enum neon_cvt_flavour
15862{
15863 CVT_FLAVOUR_VAR
15864 neon_cvt_flavour_invalid,
15865 neon_cvt_flavour_first_fp = neon_cvt_flavour_f32_f64
15866};
15867
15868#undef CVT_VAR
15869
15870static enum neon_cvt_flavour
15871get_neon_cvt_flavour (enum neon_shape rs)
5287ad62 15872{
6b9a8b67
MGD
15873#define CVT_VAR(C,X,Y,R,BSN,CN,ZN) \
15874 et = neon_check_type (2, rs, (R) | (X), (R) | (Y)); \
15875 if (et.type != NT_invtype) \
15876 { \
15877 inst.error = NULL; \
15878 return (neon_cvt_flavour_##C); \
5287ad62 15879 }
6b9a8b67 15880
5287ad62 15881 struct neon_type_el et;
037e8744 15882 unsigned whole_reg = (rs == NS_FFI || rs == NS_FD || rs == NS_DF
477330fc 15883 || rs == NS_FF) ? N_VFP : 0;
037e8744
JB
15884 /* The instruction versions which take an immediate take one register
15885 argument, which is extended to the width of the full register. Thus the
15886 "source" and "destination" registers must have the same width. Hack that
15887 here by making the size equal to the key (wider, in this case) operand. */
15888 unsigned key = (rs == NS_QQI || rs == NS_DDI || rs == NS_FFI) ? N_KEY : 0;
5f4273c7 15889
6b9a8b67
MGD
15890 CVT_FLAVOUR_VAR;
15891
15892 return neon_cvt_flavour_invalid;
5287ad62
JB
15893#undef CVT_VAR
15894}
15895
7e8e6784
MGD
15896enum neon_cvt_mode
15897{
15898 neon_cvt_mode_a,
15899 neon_cvt_mode_n,
15900 neon_cvt_mode_p,
15901 neon_cvt_mode_m,
15902 neon_cvt_mode_z,
30bdf752
MGD
15903 neon_cvt_mode_x,
15904 neon_cvt_mode_r
7e8e6784
MGD
15905};
15906
037e8744
JB
15907/* Neon-syntax VFP conversions. */
15908
5287ad62 15909static void
6b9a8b67 15910do_vfp_nsyn_cvt (enum neon_shape rs, enum neon_cvt_flavour flavour)
5287ad62 15911{
037e8744 15912 const char *opname = 0;
5f4273c7 15913
d54af2d0
RL
15914 if (rs == NS_DDI || rs == NS_QQI || rs == NS_FFI
15915 || rs == NS_FHI || rs == NS_HFI)
5287ad62 15916 {
037e8744
JB
15917 /* Conversions with immediate bitshift. */
15918 const char *enc[] =
477330fc 15919 {
6b9a8b67
MGD
15920#define CVT_VAR(C,A,B,R,BSN,CN,ZN) BSN,
15921 CVT_FLAVOUR_VAR
15922 NULL
15923#undef CVT_VAR
477330fc 15924 };
037e8744 15925
6b9a8b67 15926 if (flavour < (int) ARRAY_SIZE (enc))
477330fc
RM
15927 {
15928 opname = enc[flavour];
15929 constraint (inst.operands[0].reg != inst.operands[1].reg,
15930 _("operands 0 and 1 must be the same register"));
15931 inst.operands[1] = inst.operands[2];
15932 memset (&inst.operands[2], '\0', sizeof (inst.operands[2]));
15933 }
5287ad62
JB
15934 }
15935 else
15936 {
037e8744
JB
15937 /* Conversions without bitshift. */
15938 const char *enc[] =
477330fc 15939 {
6b9a8b67
MGD
15940#define CVT_VAR(C,A,B,R,BSN,CN,ZN) CN,
15941 CVT_FLAVOUR_VAR
15942 NULL
15943#undef CVT_VAR
477330fc 15944 };
037e8744 15945
6b9a8b67 15946 if (flavour < (int) ARRAY_SIZE (enc))
477330fc 15947 opname = enc[flavour];
037e8744
JB
15948 }
15949
15950 if (opname)
15951 do_vfp_nsyn_opcode (opname);
9db2f6b4
RL
15952
15953 /* ARMv8.2 fp16 VCVT instruction. */
15954 if (flavour == neon_cvt_flavour_s32_f16
15955 || flavour == neon_cvt_flavour_u32_f16
15956 || flavour == neon_cvt_flavour_f16_u32
15957 || flavour == neon_cvt_flavour_f16_s32)
15958 do_scalar_fp16_v82_encode ();
037e8744
JB
15959}
15960
15961static void
15962do_vfp_nsyn_cvtz (void)
15963{
d54af2d0 15964 enum neon_shape rs = neon_select_shape (NS_FH, NS_FF, NS_FD, NS_NULL);
6b9a8b67 15965 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744
JB
15966 const char *enc[] =
15967 {
6b9a8b67
MGD
15968#define CVT_VAR(C,A,B,R,BSN,CN,ZN) ZN,
15969 CVT_FLAVOUR_VAR
15970 NULL
15971#undef CVT_VAR
037e8744
JB
15972 };
15973
6b9a8b67 15974 if (flavour < (int) ARRAY_SIZE (enc) && enc[flavour])
037e8744
JB
15975 do_vfp_nsyn_opcode (enc[flavour]);
15976}
f31fef98 15977
037e8744 15978static void
bacebabc 15979do_vfp_nsyn_cvt_fpv8 (enum neon_cvt_flavour flavour,
7e8e6784
MGD
15980 enum neon_cvt_mode mode)
15981{
15982 int sz, op;
15983 int rm;
15984
a715796b
TG
15985 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
15986 D register operands. */
15987 if (flavour == neon_cvt_flavour_s32_f64
15988 || flavour == neon_cvt_flavour_u32_f64)
15989 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
15990 _(BAD_FPU));
15991
9db2f6b4
RL
15992 if (flavour == neon_cvt_flavour_s32_f16
15993 || flavour == neon_cvt_flavour_u32_f16)
15994 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
15995 _(BAD_FP16));
15996
7e8e6784
MGD
15997 set_it_insn_type (OUTSIDE_IT_INSN);
15998
15999 switch (flavour)
16000 {
16001 case neon_cvt_flavour_s32_f64:
16002 sz = 1;
827f64ff 16003 op = 1;
7e8e6784
MGD
16004 break;
16005 case neon_cvt_flavour_s32_f32:
16006 sz = 0;
16007 op = 1;
16008 break;
9db2f6b4
RL
16009 case neon_cvt_flavour_s32_f16:
16010 sz = 0;
16011 op = 1;
16012 break;
7e8e6784
MGD
16013 case neon_cvt_flavour_u32_f64:
16014 sz = 1;
16015 op = 0;
16016 break;
16017 case neon_cvt_flavour_u32_f32:
16018 sz = 0;
16019 op = 0;
16020 break;
9db2f6b4
RL
16021 case neon_cvt_flavour_u32_f16:
16022 sz = 0;
16023 op = 0;
16024 break;
7e8e6784
MGD
16025 default:
16026 first_error (_("invalid instruction shape"));
16027 return;
16028 }
16029
16030 switch (mode)
16031 {
16032 case neon_cvt_mode_a: rm = 0; break;
16033 case neon_cvt_mode_n: rm = 1; break;
16034 case neon_cvt_mode_p: rm = 2; break;
16035 case neon_cvt_mode_m: rm = 3; break;
16036 default: first_error (_("invalid rounding mode")); return;
16037 }
16038
16039 NEON_ENCODE (FPV8, inst);
16040 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
16041 encode_arm_vfp_reg (inst.operands[1].reg, sz == 1 ? VFP_REG_Dm : VFP_REG_Sm);
16042 inst.instruction |= sz << 8;
9db2f6b4
RL
16043
16044 /* ARMv8.2 fp16 VCVT instruction. */
16045 if (flavour == neon_cvt_flavour_s32_f16
16046 ||flavour == neon_cvt_flavour_u32_f16)
16047 do_scalar_fp16_v82_encode ();
7e8e6784
MGD
16048 inst.instruction |= op << 7;
16049 inst.instruction |= rm << 16;
16050 inst.instruction |= 0xf0000000;
16051 inst.is_neon = TRUE;
16052}
16053
16054static void
16055do_neon_cvt_1 (enum neon_cvt_mode mode)
037e8744
JB
16056{
16057 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_FFI, NS_DD, NS_QQ,
d54af2d0
RL
16058 NS_FD, NS_DF, NS_FF, NS_QD, NS_DQ,
16059 NS_FH, NS_HF, NS_FHI, NS_HFI,
16060 NS_NULL);
6b9a8b67 16061 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744 16062
cc933301
JW
16063 if (flavour == neon_cvt_flavour_invalid)
16064 return;
16065
e3e535bc 16066 /* PR11109: Handle round-to-zero for VCVT conversions. */
7e8e6784 16067 if (mode == neon_cvt_mode_z
e3e535bc 16068 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_vfp_v2)
cc933301
JW
16069 && (flavour == neon_cvt_flavour_s16_f16
16070 || flavour == neon_cvt_flavour_u16_f16
16071 || flavour == neon_cvt_flavour_s32_f32
bacebabc
RM
16072 || flavour == neon_cvt_flavour_u32_f32
16073 || flavour == neon_cvt_flavour_s32_f64
6b9a8b67 16074 || flavour == neon_cvt_flavour_u32_f64)
e3e535bc
NC
16075 && (rs == NS_FD || rs == NS_FF))
16076 {
16077 do_vfp_nsyn_cvtz ();
16078 return;
16079 }
16080
9db2f6b4
RL
16081 /* ARMv8.2 fp16 VCVT conversions. */
16082 if (mode == neon_cvt_mode_z
16083 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16)
16084 && (flavour == neon_cvt_flavour_s32_f16
16085 || flavour == neon_cvt_flavour_u32_f16)
16086 && (rs == NS_FH))
16087 {
16088 do_vfp_nsyn_cvtz ();
16089 do_scalar_fp16_v82_encode ();
16090 return;
16091 }
16092
037e8744 16093 /* VFP rather than Neon conversions. */
6b9a8b67 16094 if (flavour >= neon_cvt_flavour_first_fp)
037e8744 16095 {
7e8e6784
MGD
16096 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
16097 do_vfp_nsyn_cvt (rs, flavour);
16098 else
16099 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
16100
037e8744
JB
16101 return;
16102 }
16103
16104 switch (rs)
16105 {
16106 case NS_DDI:
16107 case NS_QQI:
16108 {
477330fc 16109 unsigned immbits;
cc933301
JW
16110 unsigned enctab[] = {0x0000100, 0x1000100, 0x0, 0x1000000,
16111 0x0000100, 0x1000100, 0x0, 0x1000000};
35997600 16112
477330fc
RM
16113 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
16114 return;
037e8744 16115
477330fc
RM
16116 /* Fixed-point conversion with #0 immediate is encoded as an
16117 integer conversion. */
16118 if (inst.operands[2].present && inst.operands[2].imm == 0)
16119 goto int_encode;
477330fc
RM
16120 NEON_ENCODE (IMMED, inst);
16121 if (flavour != neon_cvt_flavour_invalid)
16122 inst.instruction |= enctab[flavour];
16123 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16124 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16125 inst.instruction |= LOW4 (inst.operands[1].reg);
16126 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16127 inst.instruction |= neon_quad (rs) << 6;
16128 inst.instruction |= 1 << 21;
cc933301
JW
16129 if (flavour < neon_cvt_flavour_s16_f16)
16130 {
16131 inst.instruction |= 1 << 21;
16132 immbits = 32 - inst.operands[2].imm;
16133 inst.instruction |= immbits << 16;
16134 }
16135 else
16136 {
16137 inst.instruction |= 3 << 20;
16138 immbits = 16 - inst.operands[2].imm;
16139 inst.instruction |= immbits << 16;
16140 inst.instruction &= ~(1 << 9);
16141 }
477330fc
RM
16142
16143 neon_dp_fixup (&inst);
037e8744
JB
16144 }
16145 break;
16146
16147 case NS_DD:
16148 case NS_QQ:
7e8e6784
MGD
16149 if (mode != neon_cvt_mode_x && mode != neon_cvt_mode_z)
16150 {
16151 NEON_ENCODE (FLOAT, inst);
16152 set_it_insn_type (OUTSIDE_IT_INSN);
16153
16154 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH8) == FAIL)
16155 return;
16156
16157 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16158 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16159 inst.instruction |= LOW4 (inst.operands[1].reg);
16160 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16161 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
16162 inst.instruction |= (flavour == neon_cvt_flavour_u16_f16
16163 || flavour == neon_cvt_flavour_u32_f32) << 7;
7e8e6784 16164 inst.instruction |= mode << 8;
cc933301
JW
16165 if (flavour == neon_cvt_flavour_u16_f16
16166 || flavour == neon_cvt_flavour_s16_f16)
16167 /* Mask off the original size bits and reencode them. */
16168 inst.instruction = ((inst.instruction & 0xfff3ffff) | (1 << 18));
16169
7e8e6784
MGD
16170 if (thumb_mode)
16171 inst.instruction |= 0xfc000000;
16172 else
16173 inst.instruction |= 0xf0000000;
16174 }
16175 else
16176 {
037e8744 16177 int_encode:
7e8e6784 16178 {
cc933301
JW
16179 unsigned enctab[] = { 0x100, 0x180, 0x0, 0x080,
16180 0x100, 0x180, 0x0, 0x080};
037e8744 16181
7e8e6784 16182 NEON_ENCODE (INTEGER, inst);
037e8744 16183
7e8e6784
MGD
16184 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
16185 return;
037e8744 16186
7e8e6784
MGD
16187 if (flavour != neon_cvt_flavour_invalid)
16188 inst.instruction |= enctab[flavour];
037e8744 16189
7e8e6784
MGD
16190 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16191 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16192 inst.instruction |= LOW4 (inst.operands[1].reg);
16193 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16194 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
16195 if (flavour >= neon_cvt_flavour_s16_f16
16196 && flavour <= neon_cvt_flavour_f16_u16)
16197 /* Half precision. */
16198 inst.instruction |= 1 << 18;
16199 else
16200 inst.instruction |= 2 << 18;
037e8744 16201
7e8e6784
MGD
16202 neon_dp_fixup (&inst);
16203 }
16204 }
16205 break;
037e8744 16206
8e79c3df
CM
16207 /* Half-precision conversions for Advanced SIMD -- neon. */
16208 case NS_QD:
16209 case NS_DQ:
bc52d49c
MM
16210 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
16211 return;
8e79c3df
CM
16212
16213 if ((rs == NS_DQ)
16214 && (inst.vectype.el[0].size != 16 || inst.vectype.el[1].size != 32))
16215 {
16216 as_bad (_("operand size must match register width"));
16217 break;
16218 }
16219
16220 if ((rs == NS_QD)
16221 && ((inst.vectype.el[0].size != 32 || inst.vectype.el[1].size != 16)))
16222 {
16223 as_bad (_("operand size must match register width"));
16224 break;
16225 }
16226
16227 if (rs == NS_DQ)
477330fc 16228 inst.instruction = 0x3b60600;
8e79c3df
CM
16229 else
16230 inst.instruction = 0x3b60700;
16231
16232 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16233 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16234 inst.instruction |= LOW4 (inst.operands[1].reg);
16235 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
88714cb8 16236 neon_dp_fixup (&inst);
8e79c3df
CM
16237 break;
16238
037e8744
JB
16239 default:
16240 /* Some VFP conversions go here (s32 <-> f32, u32 <-> f32). */
7e8e6784
MGD
16241 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
16242 do_vfp_nsyn_cvt (rs, flavour);
16243 else
16244 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
5287ad62 16245 }
5287ad62
JB
16246}
16247
e3e535bc
NC
16248static void
16249do_neon_cvtr (void)
16250{
7e8e6784 16251 do_neon_cvt_1 (neon_cvt_mode_x);
e3e535bc
NC
16252}
16253
16254static void
16255do_neon_cvt (void)
16256{
7e8e6784
MGD
16257 do_neon_cvt_1 (neon_cvt_mode_z);
16258}
16259
16260static void
16261do_neon_cvta (void)
16262{
16263 do_neon_cvt_1 (neon_cvt_mode_a);
16264}
16265
16266static void
16267do_neon_cvtn (void)
16268{
16269 do_neon_cvt_1 (neon_cvt_mode_n);
16270}
16271
16272static void
16273do_neon_cvtp (void)
16274{
16275 do_neon_cvt_1 (neon_cvt_mode_p);
16276}
16277
16278static void
16279do_neon_cvtm (void)
16280{
16281 do_neon_cvt_1 (neon_cvt_mode_m);
e3e535bc
NC
16282}
16283
8e79c3df 16284static void
c70a8987 16285do_neon_cvttb_2 (bfd_boolean t, bfd_boolean to, bfd_boolean is_double)
8e79c3df 16286{
c70a8987
MGD
16287 if (is_double)
16288 mark_feature_used (&fpu_vfp_ext_armv8);
8e79c3df 16289
c70a8987
MGD
16290 encode_arm_vfp_reg (inst.operands[0].reg,
16291 (is_double && !to) ? VFP_REG_Dd : VFP_REG_Sd);
16292 encode_arm_vfp_reg (inst.operands[1].reg,
16293 (is_double && to) ? VFP_REG_Dm : VFP_REG_Sm);
16294 inst.instruction |= to ? 0x10000 : 0;
16295 inst.instruction |= t ? 0x80 : 0;
16296 inst.instruction |= is_double ? 0x100 : 0;
16297 do_vfp_cond_or_thumb ();
16298}
8e79c3df 16299
c70a8987
MGD
16300static void
16301do_neon_cvttb_1 (bfd_boolean t)
16302{
d54af2d0
RL
16303 enum neon_shape rs = neon_select_shape (NS_HF, NS_HD, NS_FH, NS_FF, NS_FD,
16304 NS_DF, NS_DH, NS_NULL);
8e79c3df 16305
c70a8987
MGD
16306 if (rs == NS_NULL)
16307 return;
16308 else if (neon_check_type (2, rs, N_F16, N_F32 | N_VFP).type != NT_invtype)
16309 {
16310 inst.error = NULL;
16311 do_neon_cvttb_2 (t, /*to=*/TRUE, /*is_double=*/FALSE);
16312 }
16313 else if (neon_check_type (2, rs, N_F32 | N_VFP, N_F16).type != NT_invtype)
16314 {
16315 inst.error = NULL;
16316 do_neon_cvttb_2 (t, /*to=*/FALSE, /*is_double=*/FALSE);
16317 }
16318 else if (neon_check_type (2, rs, N_F16, N_F64 | N_VFP).type != NT_invtype)
16319 {
a715796b
TG
16320 /* The VCVTB and VCVTT instructions with D-register operands
16321 don't work for SP only targets. */
16322 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
16323 _(BAD_FPU));
16324
c70a8987
MGD
16325 inst.error = NULL;
16326 do_neon_cvttb_2 (t, /*to=*/TRUE, /*is_double=*/TRUE);
16327 }
16328 else if (neon_check_type (2, rs, N_F64 | N_VFP, N_F16).type != NT_invtype)
16329 {
a715796b
TG
16330 /* The VCVTB and VCVTT instructions with D-register operands
16331 don't work for SP only targets. */
16332 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
16333 _(BAD_FPU));
16334
c70a8987
MGD
16335 inst.error = NULL;
16336 do_neon_cvttb_2 (t, /*to=*/FALSE, /*is_double=*/TRUE);
16337 }
16338 else
16339 return;
16340}
16341
16342static void
16343do_neon_cvtb (void)
16344{
16345 do_neon_cvttb_1 (FALSE);
8e79c3df
CM
16346}
16347
16348
16349static void
16350do_neon_cvtt (void)
16351{
c70a8987 16352 do_neon_cvttb_1 (TRUE);
8e79c3df
CM
16353}
16354
5287ad62
JB
16355static void
16356neon_move_immediate (void)
16357{
037e8744
JB
16358 enum neon_shape rs = neon_select_shape (NS_DI, NS_QI, NS_NULL);
16359 struct neon_type_el et = neon_check_type (2, rs,
16360 N_I8 | N_I16 | N_I32 | N_I64 | N_F32 | N_KEY, N_EQK);
5287ad62 16361 unsigned immlo, immhi = 0, immbits;
c96612cc 16362 int op, cmode, float_p;
5287ad62 16363
037e8744 16364 constraint (et.type == NT_invtype,
477330fc 16365 _("operand size must be specified for immediate VMOV"));
037e8744 16366
5287ad62
JB
16367 /* We start out as an MVN instruction if OP = 1, MOV otherwise. */
16368 op = (inst.instruction & (1 << 5)) != 0;
16369
16370 immlo = inst.operands[1].imm;
16371 if (inst.operands[1].regisimm)
16372 immhi = inst.operands[1].reg;
16373
16374 constraint (et.size < 32 && (immlo & ~((1 << et.size) - 1)) != 0,
477330fc 16375 _("immediate has bits set outside the operand size"));
5287ad62 16376
c96612cc
JB
16377 float_p = inst.operands[1].immisfloat;
16378
16379 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits, &op,
477330fc 16380 et.size, et.type)) == FAIL)
5287ad62
JB
16381 {
16382 /* Invert relevant bits only. */
16383 neon_invert_size (&immlo, &immhi, et.size);
16384 /* Flip from VMOV/VMVN to VMVN/VMOV. Some immediate types are unavailable
477330fc
RM
16385 with one or the other; those cases are caught by
16386 neon_cmode_for_move_imm. */
5287ad62 16387 op = !op;
c96612cc
JB
16388 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits,
16389 &op, et.size, et.type)) == FAIL)
477330fc
RM
16390 {
16391 first_error (_("immediate out of range"));
16392 return;
16393 }
5287ad62
JB
16394 }
16395
16396 inst.instruction &= ~(1 << 5);
16397 inst.instruction |= op << 5;
16398
16399 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16400 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
037e8744 16401 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
16402 inst.instruction |= cmode << 8;
16403
16404 neon_write_immbits (immbits);
16405}
16406
16407static void
16408do_neon_mvn (void)
16409{
16410 if (inst.operands[1].isreg)
16411 {
037e8744 16412 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5f4273c7 16413
88714cb8 16414 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
16415 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16416 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16417 inst.instruction |= LOW4 (inst.operands[1].reg);
16418 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 16419 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
16420 }
16421 else
16422 {
88714cb8 16423 NEON_ENCODE (IMMED, inst);
5287ad62
JB
16424 neon_move_immediate ();
16425 }
16426
88714cb8 16427 neon_dp_fixup (&inst);
5287ad62
JB
16428}
16429
16430/* Encode instructions of form:
16431
16432 |28/24|23|22|21 20|19 16|15 12|11 8|7|6|5|4|3 0|
5f4273c7 16433 | U |x |D |size | Rn | Rd |x x x x|N|x|M|x| Rm | */
5287ad62
JB
16434
16435static void
16436neon_mixed_length (struct neon_type_el et, unsigned size)
16437{
16438 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16439 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16440 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16441 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16442 inst.instruction |= LOW4 (inst.operands[2].reg);
16443 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16444 inst.instruction |= (et.type == NT_unsigned) << 24;
16445 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 16446
88714cb8 16447 neon_dp_fixup (&inst);
5287ad62
JB
16448}
16449
16450static void
16451do_neon_dyadic_long (void)
16452{
16453 /* FIXME: Type checking for lengthening op. */
16454 struct neon_type_el et = neon_check_type (3, NS_QDD,
16455 N_EQK | N_DBL, N_EQK, N_SU_32 | N_KEY);
16456 neon_mixed_length (et, et.size);
16457}
16458
16459static void
16460do_neon_abal (void)
16461{
16462 struct neon_type_el et = neon_check_type (3, NS_QDD,
16463 N_EQK | N_INT | N_DBL, N_EQK, N_SU_32 | N_KEY);
16464 neon_mixed_length (et, et.size);
16465}
16466
16467static void
16468neon_mac_reg_scalar_long (unsigned regtypes, unsigned scalartypes)
16469{
16470 if (inst.operands[2].isscalar)
16471 {
dcbf9037 16472 struct neon_type_el et = neon_check_type (3, NS_QDS,
477330fc 16473 N_EQK | N_DBL, N_EQK, regtypes | N_KEY);
88714cb8 16474 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
16475 neon_mul_mac (et, et.type == NT_unsigned);
16476 }
16477 else
16478 {
16479 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 16480 N_EQK | N_DBL, N_EQK, scalartypes | N_KEY);
88714cb8 16481 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
16482 neon_mixed_length (et, et.size);
16483 }
16484}
16485
16486static void
16487do_neon_mac_maybe_scalar_long (void)
16488{
16489 neon_mac_reg_scalar_long (N_S16 | N_S32 | N_U16 | N_U32, N_SU_32);
16490}
16491
dec41383
JW
16492/* Like neon_scalar_for_mul, this function generate Rm encoding from GAS's
16493 internal SCALAR. QUAD_P is 1 if it's for Q format, otherwise it's 0. */
16494
16495static unsigned
16496neon_scalar_for_fmac_fp16_long (unsigned scalar, unsigned quad_p)
16497{
16498 unsigned regno = NEON_SCALAR_REG (scalar);
16499 unsigned elno = NEON_SCALAR_INDEX (scalar);
16500
16501 if (quad_p)
16502 {
16503 if (regno > 7 || elno > 3)
16504 goto bad_scalar;
16505
16506 return ((regno & 0x7)
16507 | ((elno & 0x1) << 3)
16508 | (((elno >> 1) & 0x1) << 5));
16509 }
16510 else
16511 {
16512 if (regno > 15 || elno > 1)
16513 goto bad_scalar;
16514
16515 return (((regno & 0x1) << 5)
16516 | ((regno >> 1) & 0x7)
16517 | ((elno & 0x1) << 3));
16518 }
16519
16520bad_scalar:
16521 first_error (_("scalar out of range for multiply instruction"));
16522 return 0;
16523}
16524
16525static void
16526do_neon_fmac_maybe_scalar_long (int subtype)
16527{
16528 enum neon_shape rs;
16529 int high8;
16530 /* NOTE: vfmal/vfmsl use slightly different NEON three-same encoding. 'size"
16531 field (bits[21:20]) has different meaning. For scalar index variant, it's
16532 used to differentiate add and subtract, otherwise it's with fixed value
16533 0x2. */
16534 int size = -1;
16535
16536 if (inst.cond != COND_ALWAYS)
16537 as_warn (_("vfmal/vfmsl with FP16 type cannot be conditional, the "
16538 "behaviour is UNPREDICTABLE"));
16539
01f48020 16540 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16_fml),
dec41383
JW
16541 _(BAD_FP16));
16542
16543 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
16544 _(BAD_FPU));
16545
16546 /* vfmal/vfmsl are in three-same D/Q register format or the third operand can
16547 be a scalar index register. */
16548 if (inst.operands[2].isscalar)
16549 {
16550 high8 = 0xfe000000;
16551 if (subtype)
16552 size = 16;
16553 rs = neon_select_shape (NS_DHS, NS_QDS, NS_NULL);
16554 }
16555 else
16556 {
16557 high8 = 0xfc000000;
16558 size = 32;
16559 if (subtype)
16560 inst.instruction |= (0x1 << 23);
16561 rs = neon_select_shape (NS_DHH, NS_QDD, NS_NULL);
16562 }
16563
16564 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16);
16565
16566 /* "opcode" from template has included "ubit", so simply pass 0 here. Also,
16567 the "S" bit in size field has been reused to differentiate vfmal and vfmsl,
16568 so we simply pass -1 as size. */
16569 unsigned quad_p = (rs == NS_QDD || rs == NS_QDS);
16570 neon_three_same (quad_p, 0, size);
16571
16572 /* Undo neon_dp_fixup. Redo the high eight bits. */
16573 inst.instruction &= 0x00ffffff;
16574 inst.instruction |= high8;
16575
16576#define LOW1(R) ((R) & 0x1)
16577#define HI4(R) (((R) >> 1) & 0xf)
16578 /* Unlike usually NEON three-same, encoding for Vn and Vm will depend on
16579 whether the instruction is in Q form and whether Vm is a scalar indexed
16580 operand. */
16581 if (inst.operands[2].isscalar)
16582 {
16583 unsigned rm
16584 = neon_scalar_for_fmac_fp16_long (inst.operands[2].reg, quad_p);
16585 inst.instruction &= 0xffffffd0;
16586 inst.instruction |= rm;
16587
16588 if (!quad_p)
16589 {
16590 /* Redo Rn as well. */
16591 inst.instruction &= 0xfff0ff7f;
16592 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
16593 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
16594 }
16595 }
16596 else if (!quad_p)
16597 {
16598 /* Redo Rn and Rm. */
16599 inst.instruction &= 0xfff0ff50;
16600 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
16601 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
16602 inst.instruction |= HI4 (inst.operands[2].reg);
16603 inst.instruction |= LOW1 (inst.operands[2].reg) << 5;
16604 }
16605}
16606
16607static void
16608do_neon_vfmal (void)
16609{
16610 return do_neon_fmac_maybe_scalar_long (0);
16611}
16612
16613static void
16614do_neon_vfmsl (void)
16615{
16616 return do_neon_fmac_maybe_scalar_long (1);
16617}
16618
5287ad62
JB
16619static void
16620do_neon_dyadic_wide (void)
16621{
16622 struct neon_type_el et = neon_check_type (3, NS_QQD,
16623 N_EQK | N_DBL, N_EQK | N_DBL, N_SU_32 | N_KEY);
16624 neon_mixed_length (et, et.size);
16625}
16626
16627static void
16628do_neon_dyadic_narrow (void)
16629{
16630 struct neon_type_el et = neon_check_type (3, NS_QDD,
16631 N_EQK | N_DBL, N_EQK, N_I16 | N_I32 | N_I64 | N_KEY);
428e3f1f
PB
16632 /* Operand sign is unimportant, and the U bit is part of the opcode,
16633 so force the operand type to integer. */
16634 et.type = NT_integer;
5287ad62
JB
16635 neon_mixed_length (et, et.size / 2);
16636}
16637
16638static void
16639do_neon_mul_sat_scalar_long (void)
16640{
16641 neon_mac_reg_scalar_long (N_S16 | N_S32, N_S16 | N_S32);
16642}
16643
16644static void
16645do_neon_vmull (void)
16646{
16647 if (inst.operands[2].isscalar)
16648 do_neon_mac_maybe_scalar_long ();
16649 else
16650 {
16651 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 16652 N_EQK | N_DBL, N_EQK, N_SU_32 | N_P8 | N_P64 | N_KEY);
4f51b4bd 16653
5287ad62 16654 if (et.type == NT_poly)
477330fc 16655 NEON_ENCODE (POLY, inst);
5287ad62 16656 else
477330fc 16657 NEON_ENCODE (INTEGER, inst);
4f51b4bd
MGD
16658
16659 /* For polynomial encoding the U bit must be zero, and the size must
16660 be 8 (encoded as 0b00) or, on ARMv8 or later 64 (encoded, non
16661 obviously, as 0b10). */
16662 if (et.size == 64)
16663 {
16664 /* Check we're on the correct architecture. */
16665 if (!mark_feature_used (&fpu_crypto_ext_armv8))
16666 inst.error =
16667 _("Instruction form not available on this architecture.");
16668
16669 et.size = 32;
16670 }
16671
5287ad62
JB
16672 neon_mixed_length (et, et.size);
16673 }
16674}
16675
16676static void
16677do_neon_ext (void)
16678{
037e8744 16679 enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
5287ad62
JB
16680 struct neon_type_el et = neon_check_type (3, rs,
16681 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
16682 unsigned imm = (inst.operands[3].imm * et.size) / 8;
35997600
NC
16683
16684 constraint (imm >= (unsigned) (neon_quad (rs) ? 16 : 8),
16685 _("shift out of range"));
5287ad62
JB
16686 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16687 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16688 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16689 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16690 inst.instruction |= LOW4 (inst.operands[2].reg);
16691 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
037e8744 16692 inst.instruction |= neon_quad (rs) << 6;
5287ad62 16693 inst.instruction |= imm << 8;
5f4273c7 16694
88714cb8 16695 neon_dp_fixup (&inst);
5287ad62
JB
16696}
16697
16698static void
16699do_neon_rev (void)
16700{
037e8744 16701 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
16702 struct neon_type_el et = neon_check_type (2, rs,
16703 N_EQK, N_8 | N_16 | N_32 | N_KEY);
16704 unsigned op = (inst.instruction >> 7) & 3;
16705 /* N (width of reversed regions) is encoded as part of the bitmask. We
16706 extract it here to check the elements to be reversed are smaller.
16707 Otherwise we'd get a reserved instruction. */
16708 unsigned elsize = (op == 2) ? 16 : (op == 1) ? 32 : (op == 0) ? 64 : 0;
9c2799c2 16709 gas_assert (elsize != 0);
5287ad62 16710 constraint (et.size >= elsize,
477330fc 16711 _("elements must be smaller than reversal region"));
037e8744 16712 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
16713}
16714
16715static void
16716do_neon_dup (void)
16717{
16718 if (inst.operands[1].isscalar)
16719 {
037e8744 16720 enum neon_shape rs = neon_select_shape (NS_DS, NS_QS, NS_NULL);
dcbf9037 16721 struct neon_type_el et = neon_check_type (2, rs,
477330fc 16722 N_EQK, N_8 | N_16 | N_32 | N_KEY);
5287ad62 16723 unsigned sizebits = et.size >> 3;
dcbf9037 16724 unsigned dm = NEON_SCALAR_REG (inst.operands[1].reg);
5287ad62 16725 int logsize = neon_logbits (et.size);
dcbf9037 16726 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg) << logsize;
037e8744
JB
16727
16728 if (vfp_or_neon_is_neon (NEON_CHECK_CC) == FAIL)
477330fc 16729 return;
037e8744 16730
88714cb8 16731 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
16732 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16733 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16734 inst.instruction |= LOW4 (dm);
16735 inst.instruction |= HI1 (dm) << 5;
037e8744 16736 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
16737 inst.instruction |= x << 17;
16738 inst.instruction |= sizebits << 16;
5f4273c7 16739
88714cb8 16740 neon_dp_fixup (&inst);
5287ad62
JB
16741 }
16742 else
16743 {
037e8744
JB
16744 enum neon_shape rs = neon_select_shape (NS_DR, NS_QR, NS_NULL);
16745 struct neon_type_el et = neon_check_type (2, rs,
477330fc 16746 N_8 | N_16 | N_32 | N_KEY, N_EQK);
5287ad62 16747 /* Duplicate ARM register to lanes of vector. */
88714cb8 16748 NEON_ENCODE (ARMREG, inst);
5287ad62 16749 switch (et.size)
477330fc
RM
16750 {
16751 case 8: inst.instruction |= 0x400000; break;
16752 case 16: inst.instruction |= 0x000020; break;
16753 case 32: inst.instruction |= 0x000000; break;
16754 default: break;
16755 }
5287ad62
JB
16756 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
16757 inst.instruction |= LOW4 (inst.operands[0].reg) << 16;
16758 inst.instruction |= HI1 (inst.operands[0].reg) << 7;
037e8744 16759 inst.instruction |= neon_quad (rs) << 21;
5287ad62 16760 /* The encoding for this instruction is identical for the ARM and Thumb
477330fc 16761 variants, except for the condition field. */
037e8744 16762 do_vfp_cond_or_thumb ();
5287ad62
JB
16763 }
16764}
16765
16766/* VMOV has particularly many variations. It can be one of:
16767 0. VMOV<c><q> <Qd>, <Qm>
16768 1. VMOV<c><q> <Dd>, <Dm>
16769 (Register operations, which are VORR with Rm = Rn.)
16770 2. VMOV<c><q>.<dt> <Qd>, #<imm>
16771 3. VMOV<c><q>.<dt> <Dd>, #<imm>
16772 (Immediate loads.)
16773 4. VMOV<c><q>.<size> <Dn[x]>, <Rd>
16774 (ARM register to scalar.)
16775 5. VMOV<c><q> <Dm>, <Rd>, <Rn>
16776 (Two ARM registers to vector.)
16777 6. VMOV<c><q>.<dt> <Rd>, <Dn[x]>
16778 (Scalar to ARM register.)
16779 7. VMOV<c><q> <Rd>, <Rn>, <Dm>
16780 (Vector to two ARM registers.)
037e8744
JB
16781 8. VMOV.F32 <Sd>, <Sm>
16782 9. VMOV.F64 <Dd>, <Dm>
16783 (VFP register moves.)
16784 10. VMOV.F32 <Sd>, #imm
16785 11. VMOV.F64 <Dd>, #imm
16786 (VFP float immediate load.)
16787 12. VMOV <Rd>, <Sm>
16788 (VFP single to ARM reg.)
16789 13. VMOV <Sd>, <Rm>
16790 (ARM reg to VFP single.)
16791 14. VMOV <Rd>, <Re>, <Sn>, <Sm>
16792 (Two ARM regs to two VFP singles.)
16793 15. VMOV <Sd>, <Se>, <Rn>, <Rm>
16794 (Two VFP singles to two ARM regs.)
5f4273c7 16795
037e8744
JB
16796 These cases can be disambiguated using neon_select_shape, except cases 1/9
16797 and 3/11 which depend on the operand type too.
5f4273c7 16798
5287ad62 16799 All the encoded bits are hardcoded by this function.
5f4273c7 16800
b7fc2769
JB
16801 Cases 4, 6 may be used with VFPv1 and above (only 32-bit transfers!).
16802 Cases 5, 7 may be used with VFPv2 and above.
5f4273c7 16803
5287ad62 16804 FIXME: Some of the checking may be a bit sloppy (in a couple of cases you
5f4273c7 16805 can specify a type where it doesn't make sense to, and is ignored). */
5287ad62
JB
16806
16807static void
16808do_neon_mov (void)
16809{
037e8744 16810 enum neon_shape rs = neon_select_shape (NS_RRFF, NS_FFRR, NS_DRR, NS_RRD,
9db2f6b4
RL
16811 NS_QQ, NS_DD, NS_QI, NS_DI, NS_SR,
16812 NS_RS, NS_FF, NS_FI, NS_RF, NS_FR,
16813 NS_HR, NS_RH, NS_HI, NS_NULL);
037e8744
JB
16814 struct neon_type_el et;
16815 const char *ldconst = 0;
5287ad62 16816
037e8744 16817 switch (rs)
5287ad62 16818 {
037e8744
JB
16819 case NS_DD: /* case 1/9. */
16820 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
16821 /* It is not an error here if no type is given. */
16822 inst.error = NULL;
16823 if (et.type == NT_float && et.size == 64)
477330fc
RM
16824 {
16825 do_vfp_nsyn_opcode ("fcpyd");
16826 break;
16827 }
037e8744 16828 /* fall through. */
5287ad62 16829
037e8744
JB
16830 case NS_QQ: /* case 0/1. */
16831 {
477330fc
RM
16832 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
16833 return;
16834 /* The architecture manual I have doesn't explicitly state which
16835 value the U bit should have for register->register moves, but
16836 the equivalent VORR instruction has U = 0, so do that. */
16837 inst.instruction = 0x0200110;
16838 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16839 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16840 inst.instruction |= LOW4 (inst.operands[1].reg);
16841 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16842 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16843 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16844 inst.instruction |= neon_quad (rs) << 6;
16845
16846 neon_dp_fixup (&inst);
037e8744
JB
16847 }
16848 break;
5f4273c7 16849
037e8744
JB
16850 case NS_DI: /* case 3/11. */
16851 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
16852 inst.error = NULL;
16853 if (et.type == NT_float && et.size == 64)
477330fc
RM
16854 {
16855 /* case 11 (fconstd). */
16856 ldconst = "fconstd";
16857 goto encode_fconstd;
16858 }
037e8744
JB
16859 /* fall through. */
16860
16861 case NS_QI: /* case 2/3. */
16862 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
477330fc 16863 return;
037e8744
JB
16864 inst.instruction = 0x0800010;
16865 neon_move_immediate ();
88714cb8 16866 neon_dp_fixup (&inst);
5287ad62 16867 break;
5f4273c7 16868
037e8744
JB
16869 case NS_SR: /* case 4. */
16870 {
477330fc
RM
16871 unsigned bcdebits = 0;
16872 int logsize;
16873 unsigned dn = NEON_SCALAR_REG (inst.operands[0].reg);
16874 unsigned x = NEON_SCALAR_INDEX (inst.operands[0].reg);
037e8744 16875
05ac0ffb
JB
16876 /* .<size> is optional here, defaulting to .32. */
16877 if (inst.vectype.elems == 0
16878 && inst.operands[0].vectype.type == NT_invtype
16879 && inst.operands[1].vectype.type == NT_invtype)
16880 {
16881 inst.vectype.el[0].type = NT_untyped;
16882 inst.vectype.el[0].size = 32;
16883 inst.vectype.elems = 1;
16884 }
16885
477330fc
RM
16886 et = neon_check_type (2, NS_NULL, N_8 | N_16 | N_32 | N_KEY, N_EQK);
16887 logsize = neon_logbits (et.size);
16888
16889 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1),
16890 _(BAD_FPU));
16891 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1)
16892 && et.size != 32, _(BAD_FPU));
16893 constraint (et.type == NT_invtype, _("bad type for scalar"));
16894 constraint (x >= 64 / et.size, _("scalar index out of range"));
16895
16896 switch (et.size)
16897 {
16898 case 8: bcdebits = 0x8; break;
16899 case 16: bcdebits = 0x1; break;
16900 case 32: bcdebits = 0x0; break;
16901 default: ;
16902 }
16903
16904 bcdebits |= x << logsize;
16905
16906 inst.instruction = 0xe000b10;
16907 do_vfp_cond_or_thumb ();
16908 inst.instruction |= LOW4 (dn) << 16;
16909 inst.instruction |= HI1 (dn) << 7;
16910 inst.instruction |= inst.operands[1].reg << 12;
16911 inst.instruction |= (bcdebits & 3) << 5;
16912 inst.instruction |= (bcdebits >> 2) << 21;
037e8744
JB
16913 }
16914 break;
5f4273c7 16915
037e8744 16916 case NS_DRR: /* case 5 (fmdrr). */
b7fc2769 16917 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2),
477330fc 16918 _(BAD_FPU));
b7fc2769 16919
037e8744
JB
16920 inst.instruction = 0xc400b10;
16921 do_vfp_cond_or_thumb ();
16922 inst.instruction |= LOW4 (inst.operands[0].reg);
16923 inst.instruction |= HI1 (inst.operands[0].reg) << 5;
16924 inst.instruction |= inst.operands[1].reg << 12;
16925 inst.instruction |= inst.operands[2].reg << 16;
16926 break;
5f4273c7 16927
037e8744
JB
16928 case NS_RS: /* case 6. */
16929 {
477330fc
RM
16930 unsigned logsize;
16931 unsigned dn = NEON_SCALAR_REG (inst.operands[1].reg);
16932 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg);
16933 unsigned abcdebits = 0;
037e8744 16934
05ac0ffb
JB
16935 /* .<dt> is optional here, defaulting to .32. */
16936 if (inst.vectype.elems == 0
16937 && inst.operands[0].vectype.type == NT_invtype
16938 && inst.operands[1].vectype.type == NT_invtype)
16939 {
16940 inst.vectype.el[0].type = NT_untyped;
16941 inst.vectype.el[0].size = 32;
16942 inst.vectype.elems = 1;
16943 }
16944
91d6fa6a
NC
16945 et = neon_check_type (2, NS_NULL,
16946 N_EQK, N_S8 | N_S16 | N_U8 | N_U16 | N_32 | N_KEY);
477330fc
RM
16947 logsize = neon_logbits (et.size);
16948
16949 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1),
16950 _(BAD_FPU));
16951 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1)
16952 && et.size != 32, _(BAD_FPU));
16953 constraint (et.type == NT_invtype, _("bad type for scalar"));
16954 constraint (x >= 64 / et.size, _("scalar index out of range"));
16955
16956 switch (et.size)
16957 {
16958 case 8: abcdebits = (et.type == NT_signed) ? 0x08 : 0x18; break;
16959 case 16: abcdebits = (et.type == NT_signed) ? 0x01 : 0x11; break;
16960 case 32: abcdebits = 0x00; break;
16961 default: ;
16962 }
16963
16964 abcdebits |= x << logsize;
16965 inst.instruction = 0xe100b10;
16966 do_vfp_cond_or_thumb ();
16967 inst.instruction |= LOW4 (dn) << 16;
16968 inst.instruction |= HI1 (dn) << 7;
16969 inst.instruction |= inst.operands[0].reg << 12;
16970 inst.instruction |= (abcdebits & 3) << 5;
16971 inst.instruction |= (abcdebits >> 2) << 21;
037e8744
JB
16972 }
16973 break;
5f4273c7 16974
037e8744
JB
16975 case NS_RRD: /* case 7 (fmrrd). */
16976 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2),
477330fc 16977 _(BAD_FPU));
037e8744
JB
16978
16979 inst.instruction = 0xc500b10;
16980 do_vfp_cond_or_thumb ();
16981 inst.instruction |= inst.operands[0].reg << 12;
16982 inst.instruction |= inst.operands[1].reg << 16;
16983 inst.instruction |= LOW4 (inst.operands[2].reg);
16984 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16985 break;
5f4273c7 16986
037e8744
JB
16987 case NS_FF: /* case 8 (fcpys). */
16988 do_vfp_nsyn_opcode ("fcpys");
16989 break;
5f4273c7 16990
9db2f6b4 16991 case NS_HI:
037e8744
JB
16992 case NS_FI: /* case 10 (fconsts). */
16993 ldconst = "fconsts";
4ef4710f 16994 encode_fconstd:
58ed5c38
TC
16995 if (!inst.operands[1].immisfloat)
16996 {
4ef4710f 16997 unsigned new_imm;
58ed5c38 16998 /* Immediate has to fit in 8 bits so float is enough. */
4ef4710f
NC
16999 float imm = (float) inst.operands[1].imm;
17000 memcpy (&new_imm, &imm, sizeof (float));
17001 /* But the assembly may have been written to provide an integer
17002 bit pattern that equates to a float, so check that the
17003 conversion has worked. */
17004 if (is_quarter_float (new_imm))
17005 {
17006 if (is_quarter_float (inst.operands[1].imm))
17007 as_warn (_("immediate constant is valid both as a bit-pattern and a floating point value (using the fp value)"));
17008
17009 inst.operands[1].imm = new_imm;
17010 inst.operands[1].immisfloat = 1;
17011 }
58ed5c38
TC
17012 }
17013
037e8744 17014 if (is_quarter_float (inst.operands[1].imm))
477330fc
RM
17015 {
17016 inst.operands[1].imm = neon_qfloat_bits (inst.operands[1].imm);
17017 do_vfp_nsyn_opcode (ldconst);
9db2f6b4
RL
17018
17019 /* ARMv8.2 fp16 vmov.f16 instruction. */
17020 if (rs == NS_HI)
17021 do_scalar_fp16_v82_encode ();
477330fc 17022 }
5287ad62 17023 else
477330fc 17024 first_error (_("immediate out of range"));
037e8744 17025 break;
5f4273c7 17026
9db2f6b4 17027 case NS_RH:
037e8744
JB
17028 case NS_RF: /* case 12 (fmrs). */
17029 do_vfp_nsyn_opcode ("fmrs");
9db2f6b4
RL
17030 /* ARMv8.2 fp16 vmov.f16 instruction. */
17031 if (rs == NS_RH)
17032 do_scalar_fp16_v82_encode ();
037e8744 17033 break;
5f4273c7 17034
9db2f6b4 17035 case NS_HR:
037e8744
JB
17036 case NS_FR: /* case 13 (fmsr). */
17037 do_vfp_nsyn_opcode ("fmsr");
9db2f6b4
RL
17038 /* ARMv8.2 fp16 vmov.f16 instruction. */
17039 if (rs == NS_HR)
17040 do_scalar_fp16_v82_encode ();
037e8744 17041 break;
5f4273c7 17042
037e8744
JB
17043 /* The encoders for the fmrrs and fmsrr instructions expect three operands
17044 (one of which is a list), but we have parsed four. Do some fiddling to
17045 make the operands what do_vfp_reg2_from_sp2 and do_vfp_sp2_from_reg2
17046 expect. */
17047 case NS_RRFF: /* case 14 (fmrrs). */
17048 constraint (inst.operands[3].reg != inst.operands[2].reg + 1,
477330fc 17049 _("VFP registers must be adjacent"));
037e8744
JB
17050 inst.operands[2].imm = 2;
17051 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
17052 do_vfp_nsyn_opcode ("fmrrs");
17053 break;
5f4273c7 17054
037e8744
JB
17055 case NS_FFRR: /* case 15 (fmsrr). */
17056 constraint (inst.operands[1].reg != inst.operands[0].reg + 1,
477330fc 17057 _("VFP registers must be adjacent"));
037e8744
JB
17058 inst.operands[1] = inst.operands[2];
17059 inst.operands[2] = inst.operands[3];
17060 inst.operands[0].imm = 2;
17061 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
17062 do_vfp_nsyn_opcode ("fmsrr");
5287ad62 17063 break;
5f4273c7 17064
4c261dff
NC
17065 case NS_NULL:
17066 /* neon_select_shape has determined that the instruction
17067 shape is wrong and has already set the error message. */
17068 break;
17069
5287ad62
JB
17070 default:
17071 abort ();
17072 }
17073}
17074
17075static void
17076do_neon_rshift_round_imm (void)
17077{
037e8744 17078 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
17079 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
17080 int imm = inst.operands[2].imm;
17081
17082 /* imm == 0 case is encoded as VMOV for V{R}SHR. */
17083 if (imm == 0)
17084 {
17085 inst.operands[2].present = 0;
17086 do_neon_mov ();
17087 return;
17088 }
17089
17090 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 17091 _("immediate out of range for shift"));
037e8744 17092 neon_imm_shift (TRUE, et.type == NT_unsigned, neon_quad (rs), et,
477330fc 17093 et.size - imm);
5287ad62
JB
17094}
17095
9db2f6b4
RL
17096static void
17097do_neon_movhf (void)
17098{
17099 enum neon_shape rs = neon_select_shape (NS_HH, NS_NULL);
17100 constraint (rs != NS_HH, _("invalid suffix"));
17101
7bdf778b
ASDV
17102 if (inst.cond != COND_ALWAYS)
17103 {
17104 if (thumb_mode)
17105 {
17106 as_warn (_("ARMv8.2 scalar fp16 instruction cannot be conditional,"
17107 " the behaviour is UNPREDICTABLE"));
17108 }
17109 else
17110 {
17111 inst.error = BAD_COND;
17112 return;
17113 }
17114 }
17115
9db2f6b4
RL
17116 do_vfp_sp_monadic ();
17117
17118 inst.is_neon = 1;
17119 inst.instruction |= 0xf0000000;
17120}
17121
5287ad62
JB
17122static void
17123do_neon_movl (void)
17124{
17125 struct neon_type_el et = neon_check_type (2, NS_QD,
17126 N_EQK | N_DBL, N_SU_32 | N_KEY);
17127 unsigned sizebits = et.size >> 3;
17128 inst.instruction |= sizebits << 19;
17129 neon_two_same (0, et.type == NT_unsigned, -1);
17130}
17131
17132static void
17133do_neon_trn (void)
17134{
037e8744 17135 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17136 struct neon_type_el et = neon_check_type (2, rs,
17137 N_EQK, N_8 | N_16 | N_32 | N_KEY);
88714cb8 17138 NEON_ENCODE (INTEGER, inst);
037e8744 17139 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17140}
17141
17142static void
17143do_neon_zip_uzp (void)
17144{
037e8744 17145 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17146 struct neon_type_el et = neon_check_type (2, rs,
17147 N_EQK, N_8 | N_16 | N_32 | N_KEY);
17148 if (rs == NS_DD && et.size == 32)
17149 {
17150 /* Special case: encode as VTRN.32 <Dd>, <Dm>. */
17151 inst.instruction = N_MNEM_vtrn;
17152 do_neon_trn ();
17153 return;
17154 }
037e8744 17155 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17156}
17157
17158static void
17159do_neon_sat_abs_neg (void)
17160{
037e8744 17161 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17162 struct neon_type_el et = neon_check_type (2, rs,
17163 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 17164 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17165}
17166
17167static void
17168do_neon_pair_long (void)
17169{
037e8744 17170 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17171 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_32 | N_KEY);
17172 /* Unsigned is encoded in OP field (bit 7) for these instruction. */
17173 inst.instruction |= (et.type == NT_unsigned) << 7;
037e8744 17174 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17175}
17176
17177static void
17178do_neon_recip_est (void)
17179{
037e8744 17180 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62 17181 struct neon_type_el et = neon_check_type (2, rs,
cc933301 17182 N_EQK | N_FLT, N_F_16_32 | N_U32 | N_KEY);
5287ad62 17183 inst.instruction |= (et.type == NT_float) << 8;
037e8744 17184 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17185}
17186
17187static void
17188do_neon_cls (void)
17189{
037e8744 17190 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17191 struct neon_type_el et = neon_check_type (2, rs,
17192 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 17193 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17194}
17195
17196static void
17197do_neon_clz (void)
17198{
037e8744 17199 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17200 struct neon_type_el et = neon_check_type (2, rs,
17201 N_EQK, N_I8 | N_I16 | N_I32 | N_KEY);
037e8744 17202 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17203}
17204
17205static void
17206do_neon_cnt (void)
17207{
037e8744 17208 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17209 struct neon_type_el et = neon_check_type (2, rs,
17210 N_EQK | N_INT, N_8 | N_KEY);
037e8744 17211 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17212}
17213
17214static void
17215do_neon_swp (void)
17216{
037e8744
JB
17217 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
17218 neon_two_same (neon_quad (rs), 1, -1);
5287ad62
JB
17219}
17220
17221static void
17222do_neon_tbl_tbx (void)
17223{
17224 unsigned listlenbits;
dcbf9037 17225 neon_check_type (3, NS_DLD, N_EQK, N_EQK, N_8 | N_KEY);
5f4273c7 17226
5287ad62
JB
17227 if (inst.operands[1].imm < 1 || inst.operands[1].imm > 4)
17228 {
dcbf9037 17229 first_error (_("bad list length for table lookup"));
5287ad62
JB
17230 return;
17231 }
5f4273c7 17232
5287ad62
JB
17233 listlenbits = inst.operands[1].imm - 1;
17234 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17235 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17236 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17237 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
17238 inst.instruction |= LOW4 (inst.operands[2].reg);
17239 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
17240 inst.instruction |= listlenbits << 8;
5f4273c7 17241
88714cb8 17242 neon_dp_fixup (&inst);
5287ad62
JB
17243}
17244
17245static void
17246do_neon_ldm_stm (void)
17247{
17248 /* P, U and L bits are part of bitmask. */
17249 int is_dbmode = (inst.instruction & (1 << 24)) != 0;
17250 unsigned offsetbits = inst.operands[1].imm * 2;
17251
037e8744
JB
17252 if (inst.operands[1].issingle)
17253 {
17254 do_vfp_nsyn_ldm_stm (is_dbmode);
17255 return;
17256 }
17257
5287ad62 17258 constraint (is_dbmode && !inst.operands[0].writeback,
477330fc 17259 _("writeback (!) must be used for VLDMDB and VSTMDB"));
5287ad62
JB
17260
17261 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
477330fc
RM
17262 _("register list must contain at least 1 and at most 16 "
17263 "registers"));
5287ad62
JB
17264
17265 inst.instruction |= inst.operands[0].reg << 16;
17266 inst.instruction |= inst.operands[0].writeback << 21;
17267 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
17268 inst.instruction |= HI1 (inst.operands[1].reg) << 22;
17269
17270 inst.instruction |= offsetbits;
5f4273c7 17271
037e8744 17272 do_vfp_cond_or_thumb ();
5287ad62
JB
17273}
17274
17275static void
17276do_neon_ldr_str (void)
17277{
5287ad62 17278 int is_ldr = (inst.instruction & (1 << 20)) != 0;
5f4273c7 17279
6844b2c2
MGD
17280 /* Use of PC in vstr in ARM mode is deprecated in ARMv7.
17281 And is UNPREDICTABLE in thumb mode. */
fa94de6b 17282 if (!is_ldr
6844b2c2 17283 && inst.operands[1].reg == REG_PC
ba86b375 17284 && (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7) || thumb_mode))
6844b2c2 17285 {
94dcf8bf 17286 if (thumb_mode)
6844b2c2 17287 inst.error = _("Use of PC here is UNPREDICTABLE");
94dcf8bf 17288 else if (warn_on_deprecated)
5c3696f8 17289 as_tsktsk (_("Use of PC here is deprecated"));
6844b2c2
MGD
17290 }
17291
037e8744
JB
17292 if (inst.operands[0].issingle)
17293 {
cd2f129f 17294 if (is_ldr)
477330fc 17295 do_vfp_nsyn_opcode ("flds");
cd2f129f 17296 else
477330fc 17297 do_vfp_nsyn_opcode ("fsts");
9db2f6b4
RL
17298
17299 /* ARMv8.2 vldr.16/vstr.16 instruction. */
17300 if (inst.vectype.el[0].size == 16)
17301 do_scalar_fp16_v82_encode ();
5287ad62
JB
17302 }
17303 else
5287ad62 17304 {
cd2f129f 17305 if (is_ldr)
477330fc 17306 do_vfp_nsyn_opcode ("fldd");
5287ad62 17307 else
477330fc 17308 do_vfp_nsyn_opcode ("fstd");
5287ad62 17309 }
5287ad62
JB
17310}
17311
17312/* "interleave" version also handles non-interleaving register VLD1/VST1
17313 instructions. */
17314
17315static void
17316do_neon_ld_st_interleave (void)
17317{
037e8744 17318 struct neon_type_el et = neon_check_type (1, NS_NULL,
477330fc 17319 N_8 | N_16 | N_32 | N_64);
5287ad62
JB
17320 unsigned alignbits = 0;
17321 unsigned idx;
17322 /* The bits in this table go:
17323 0: register stride of one (0) or two (1)
17324 1,2: register list length, minus one (1, 2, 3, 4).
17325 3,4: <n> in instruction type, minus one (VLD<n> / VST<n>).
17326 We use -1 for invalid entries. */
17327 const int typetable[] =
17328 {
17329 0x7, -1, 0xa, -1, 0x6, -1, 0x2, -1, /* VLD1 / VST1. */
17330 -1, -1, 0x8, 0x9, -1, -1, 0x3, -1, /* VLD2 / VST2. */
17331 -1, -1, -1, -1, 0x4, 0x5, -1, -1, /* VLD3 / VST3. */
17332 -1, -1, -1, -1, -1, -1, 0x0, 0x1 /* VLD4 / VST4. */
17333 };
17334 int typebits;
17335
dcbf9037
JB
17336 if (et.type == NT_invtype)
17337 return;
17338
5287ad62
JB
17339 if (inst.operands[1].immisalign)
17340 switch (inst.operands[1].imm >> 8)
17341 {
17342 case 64: alignbits = 1; break;
17343 case 128:
477330fc 17344 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2
e23c0ad8 17345 && NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
477330fc
RM
17346 goto bad_alignment;
17347 alignbits = 2;
17348 break;
5287ad62 17349 case 256:
477330fc
RM
17350 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
17351 goto bad_alignment;
17352 alignbits = 3;
17353 break;
5287ad62
JB
17354 default:
17355 bad_alignment:
477330fc
RM
17356 first_error (_("bad alignment"));
17357 return;
5287ad62
JB
17358 }
17359
17360 inst.instruction |= alignbits << 4;
17361 inst.instruction |= neon_logbits (et.size) << 6;
17362
17363 /* Bits [4:6] of the immediate in a list specifier encode register stride
17364 (minus 1) in bit 4, and list length in bits [5:6]. We put the <n> of
17365 VLD<n>/VST<n> in bits [9:8] of the initial bitmask. Suck it out here, look
17366 up the right value for "type" in a table based on this value and the given
17367 list style, then stick it back. */
17368 idx = ((inst.operands[0].imm >> 4) & 7)
477330fc 17369 | (((inst.instruction >> 8) & 3) << 3);
5287ad62
JB
17370
17371 typebits = typetable[idx];
5f4273c7 17372
5287ad62 17373 constraint (typebits == -1, _("bad list type for instruction"));
1d50d57c
WN
17374 constraint (((inst.instruction >> 8) & 3) && et.size == 64,
17375 _("bad element type for instruction"));
5287ad62
JB
17376
17377 inst.instruction &= ~0xf00;
17378 inst.instruction |= typebits << 8;
17379}
17380
17381/* Check alignment is valid for do_neon_ld_st_lane and do_neon_ld_dup.
17382 *DO_ALIGN is set to 1 if the relevant alignment bit should be set, 0
17383 otherwise. The variable arguments are a list of pairs of legal (size, align)
17384 values, terminated with -1. */
17385
17386static int
aa8a0863 17387neon_alignment_bit (int size, int align, int *do_alignment, ...)
5287ad62
JB
17388{
17389 va_list ap;
17390 int result = FAIL, thissize, thisalign;
5f4273c7 17391
5287ad62
JB
17392 if (!inst.operands[1].immisalign)
17393 {
aa8a0863 17394 *do_alignment = 0;
5287ad62
JB
17395 return SUCCESS;
17396 }
5f4273c7 17397
aa8a0863 17398 va_start (ap, do_alignment);
5287ad62
JB
17399
17400 do
17401 {
17402 thissize = va_arg (ap, int);
17403 if (thissize == -1)
477330fc 17404 break;
5287ad62
JB
17405 thisalign = va_arg (ap, int);
17406
17407 if (size == thissize && align == thisalign)
477330fc 17408 result = SUCCESS;
5287ad62
JB
17409 }
17410 while (result != SUCCESS);
17411
17412 va_end (ap);
17413
17414 if (result == SUCCESS)
aa8a0863 17415 *do_alignment = 1;
5287ad62 17416 else
dcbf9037 17417 first_error (_("unsupported alignment for instruction"));
5f4273c7 17418
5287ad62
JB
17419 return result;
17420}
17421
17422static void
17423do_neon_ld_st_lane (void)
17424{
037e8744 17425 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 17426 int align_good, do_alignment = 0;
5287ad62
JB
17427 int logsize = neon_logbits (et.size);
17428 int align = inst.operands[1].imm >> 8;
17429 int n = (inst.instruction >> 8) & 3;
17430 int max_el = 64 / et.size;
5f4273c7 17431
dcbf9037
JB
17432 if (et.type == NT_invtype)
17433 return;
5f4273c7 17434
5287ad62 17435 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != n + 1,
477330fc 17436 _("bad list length"));
5287ad62 17437 constraint (NEON_LANE (inst.operands[0].imm) >= max_el,
477330fc 17438 _("scalar index out of range"));
5287ad62 17439 constraint (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2
477330fc
RM
17440 && et.size == 8,
17441 _("stride of 2 unavailable when element size is 8"));
5f4273c7 17442
5287ad62
JB
17443 switch (n)
17444 {
17445 case 0: /* VLD1 / VST1. */
aa8a0863 17446 align_good = neon_alignment_bit (et.size, align, &do_alignment, 16, 16,
477330fc 17447 32, 32, -1);
5287ad62 17448 if (align_good == FAIL)
477330fc 17449 return;
aa8a0863 17450 if (do_alignment)
477330fc
RM
17451 {
17452 unsigned alignbits = 0;
17453 switch (et.size)
17454 {
17455 case 16: alignbits = 0x1; break;
17456 case 32: alignbits = 0x3; break;
17457 default: ;
17458 }
17459 inst.instruction |= alignbits << 4;
17460 }
5287ad62
JB
17461 break;
17462
17463 case 1: /* VLD2 / VST2. */
aa8a0863
TS
17464 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 16,
17465 16, 32, 32, 64, -1);
5287ad62 17466 if (align_good == FAIL)
477330fc 17467 return;
aa8a0863 17468 if (do_alignment)
477330fc 17469 inst.instruction |= 1 << 4;
5287ad62
JB
17470 break;
17471
17472 case 2: /* VLD3 / VST3. */
17473 constraint (inst.operands[1].immisalign,
477330fc 17474 _("can't use alignment with this instruction"));
5287ad62
JB
17475 break;
17476
17477 case 3: /* VLD4 / VST4. */
aa8a0863 17478 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc 17479 16, 64, 32, 64, 32, 128, -1);
5287ad62 17480 if (align_good == FAIL)
477330fc 17481 return;
aa8a0863 17482 if (do_alignment)
477330fc
RM
17483 {
17484 unsigned alignbits = 0;
17485 switch (et.size)
17486 {
17487 case 8: alignbits = 0x1; break;
17488 case 16: alignbits = 0x1; break;
17489 case 32: alignbits = (align == 64) ? 0x1 : 0x2; break;
17490 default: ;
17491 }
17492 inst.instruction |= alignbits << 4;
17493 }
5287ad62
JB
17494 break;
17495
17496 default: ;
17497 }
17498
17499 /* Reg stride of 2 is encoded in bit 5 when size==16, bit 6 when size==32. */
17500 if (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2)
17501 inst.instruction |= 1 << (4 + logsize);
5f4273c7 17502
5287ad62
JB
17503 inst.instruction |= NEON_LANE (inst.operands[0].imm) << (logsize + 5);
17504 inst.instruction |= logsize << 10;
17505}
17506
17507/* Encode single n-element structure to all lanes VLD<n> instructions. */
17508
17509static void
17510do_neon_ld_dup (void)
17511{
037e8744 17512 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 17513 int align_good, do_alignment = 0;
5287ad62 17514
dcbf9037
JB
17515 if (et.type == NT_invtype)
17516 return;
17517
5287ad62
JB
17518 switch ((inst.instruction >> 8) & 3)
17519 {
17520 case 0: /* VLD1. */
9c2799c2 17521 gas_assert (NEON_REG_STRIDE (inst.operands[0].imm) != 2);
5287ad62 17522 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863 17523 &do_alignment, 16, 16, 32, 32, -1);
5287ad62 17524 if (align_good == FAIL)
477330fc 17525 return;
5287ad62 17526 switch (NEON_REGLIST_LENGTH (inst.operands[0].imm))
477330fc
RM
17527 {
17528 case 1: break;
17529 case 2: inst.instruction |= 1 << 5; break;
17530 default: first_error (_("bad list length")); return;
17531 }
5287ad62
JB
17532 inst.instruction |= neon_logbits (et.size) << 6;
17533 break;
17534
17535 case 1: /* VLD2. */
17536 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863
TS
17537 &do_alignment, 8, 16, 16, 32, 32, 64,
17538 -1);
5287ad62 17539 if (align_good == FAIL)
477330fc 17540 return;
5287ad62 17541 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2,
477330fc 17542 _("bad list length"));
5287ad62 17543 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 17544 inst.instruction |= 1 << 5;
5287ad62
JB
17545 inst.instruction |= neon_logbits (et.size) << 6;
17546 break;
17547
17548 case 2: /* VLD3. */
17549 constraint (inst.operands[1].immisalign,
477330fc 17550 _("can't use alignment with this instruction"));
5287ad62 17551 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 3,
477330fc 17552 _("bad list length"));
5287ad62 17553 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 17554 inst.instruction |= 1 << 5;
5287ad62
JB
17555 inst.instruction |= neon_logbits (et.size) << 6;
17556 break;
17557
17558 case 3: /* VLD4. */
17559 {
477330fc 17560 int align = inst.operands[1].imm >> 8;
aa8a0863 17561 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc
RM
17562 16, 64, 32, 64, 32, 128, -1);
17563 if (align_good == FAIL)
17564 return;
17565 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4,
17566 _("bad list length"));
17567 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
17568 inst.instruction |= 1 << 5;
17569 if (et.size == 32 && align == 128)
17570 inst.instruction |= 0x3 << 6;
17571 else
17572 inst.instruction |= neon_logbits (et.size) << 6;
5287ad62
JB
17573 }
17574 break;
17575
17576 default: ;
17577 }
17578
aa8a0863 17579 inst.instruction |= do_alignment << 4;
5287ad62
JB
17580}
17581
17582/* Disambiguate VLD<n> and VST<n> instructions, and fill in common bits (those
17583 apart from bits [11:4]. */
17584
17585static void
17586do_neon_ldx_stx (void)
17587{
b1a769ed
DG
17588 if (inst.operands[1].isreg)
17589 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
17590
5287ad62
JB
17591 switch (NEON_LANE (inst.operands[0].imm))
17592 {
17593 case NEON_INTERLEAVE_LANES:
88714cb8 17594 NEON_ENCODE (INTERLV, inst);
5287ad62
JB
17595 do_neon_ld_st_interleave ();
17596 break;
5f4273c7 17597
5287ad62 17598 case NEON_ALL_LANES:
88714cb8 17599 NEON_ENCODE (DUP, inst);
2d51fb74
JB
17600 if (inst.instruction == N_INV)
17601 {
17602 first_error ("only loads support such operands");
17603 break;
17604 }
5287ad62
JB
17605 do_neon_ld_dup ();
17606 break;
5f4273c7 17607
5287ad62 17608 default:
88714cb8 17609 NEON_ENCODE (LANE, inst);
5287ad62
JB
17610 do_neon_ld_st_lane ();
17611 }
17612
17613 /* L bit comes from bit mask. */
17614 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17615 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17616 inst.instruction |= inst.operands[1].reg << 16;
5f4273c7 17617
5287ad62
JB
17618 if (inst.operands[1].postind)
17619 {
17620 int postreg = inst.operands[1].imm & 0xf;
17621 constraint (!inst.operands[1].immisreg,
477330fc 17622 _("post-index must be a register"));
5287ad62 17623 constraint (postreg == 0xd || postreg == 0xf,
477330fc 17624 _("bad register for post-index"));
5287ad62
JB
17625 inst.instruction |= postreg;
17626 }
4f2374c7 17627 else
5287ad62 17628 {
4f2374c7 17629 constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
e2b0ab59
AV
17630 constraint (inst.relocs[0].exp.X_op != O_constant
17631 || inst.relocs[0].exp.X_add_number != 0,
4f2374c7
WN
17632 BAD_ADDR_MODE);
17633
17634 if (inst.operands[1].writeback)
17635 {
17636 inst.instruction |= 0xd;
17637 }
17638 else
17639 inst.instruction |= 0xf;
5287ad62 17640 }
5f4273c7 17641
5287ad62
JB
17642 if (thumb_mode)
17643 inst.instruction |= 0xf9000000;
17644 else
17645 inst.instruction |= 0xf4000000;
17646}
33399f07
MGD
17647
17648/* FP v8. */
17649static void
17650do_vfp_nsyn_fpv8 (enum neon_shape rs)
17651{
a715796b
TG
17652 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
17653 D register operands. */
17654 if (neon_shape_class[rs] == SC_DOUBLE)
17655 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
17656 _(BAD_FPU));
17657
33399f07
MGD
17658 NEON_ENCODE (FPV8, inst);
17659
9db2f6b4
RL
17660 if (rs == NS_FFF || rs == NS_HHH)
17661 {
17662 do_vfp_sp_dyadic ();
17663
17664 /* ARMv8.2 fp16 instruction. */
17665 if (rs == NS_HHH)
17666 do_scalar_fp16_v82_encode ();
17667 }
33399f07
MGD
17668 else
17669 do_vfp_dp_rd_rn_rm ();
17670
17671 if (rs == NS_DDD)
17672 inst.instruction |= 0x100;
17673
17674 inst.instruction |= 0xf0000000;
17675}
17676
17677static void
17678do_vsel (void)
17679{
17680 set_it_insn_type (OUTSIDE_IT_INSN);
17681
17682 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) != SUCCESS)
17683 first_error (_("invalid instruction shape"));
17684}
17685
73924fbc
MGD
17686static void
17687do_vmaxnm (void)
17688{
17689 set_it_insn_type (OUTSIDE_IT_INSN);
17690
17691 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) == SUCCESS)
17692 return;
17693
17694 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH8) == FAIL)
17695 return;
17696
cc933301 17697 neon_dyadic_misc (NT_untyped, N_F_16_32, 0);
73924fbc
MGD
17698}
17699
30bdf752
MGD
17700static void
17701do_vrint_1 (enum neon_cvt_mode mode)
17702{
9db2f6b4 17703 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_QQ, NS_NULL);
30bdf752
MGD
17704 struct neon_type_el et;
17705
17706 if (rs == NS_NULL)
17707 return;
17708
a715796b
TG
17709 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
17710 D register operands. */
17711 if (neon_shape_class[rs] == SC_DOUBLE)
17712 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
17713 _(BAD_FPU));
17714
9db2f6b4
RL
17715 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY
17716 | N_VFP);
30bdf752
MGD
17717 if (et.type != NT_invtype)
17718 {
17719 /* VFP encodings. */
17720 if (mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
17721 || mode == neon_cvt_mode_p || mode == neon_cvt_mode_m)
17722 set_it_insn_type (OUTSIDE_IT_INSN);
17723
17724 NEON_ENCODE (FPV8, inst);
9db2f6b4 17725 if (rs == NS_FF || rs == NS_HH)
30bdf752
MGD
17726 do_vfp_sp_monadic ();
17727 else
17728 do_vfp_dp_rd_rm ();
17729
17730 switch (mode)
17731 {
17732 case neon_cvt_mode_r: inst.instruction |= 0x00000000; break;
17733 case neon_cvt_mode_z: inst.instruction |= 0x00000080; break;
17734 case neon_cvt_mode_x: inst.instruction |= 0x00010000; break;
17735 case neon_cvt_mode_a: inst.instruction |= 0xf0000000; break;
17736 case neon_cvt_mode_n: inst.instruction |= 0xf0010000; break;
17737 case neon_cvt_mode_p: inst.instruction |= 0xf0020000; break;
17738 case neon_cvt_mode_m: inst.instruction |= 0xf0030000; break;
17739 default: abort ();
17740 }
17741
17742 inst.instruction |= (rs == NS_DD) << 8;
17743 do_vfp_cond_or_thumb ();
9db2f6b4
RL
17744
17745 /* ARMv8.2 fp16 vrint instruction. */
17746 if (rs == NS_HH)
17747 do_scalar_fp16_v82_encode ();
30bdf752
MGD
17748 }
17749 else
17750 {
17751 /* Neon encodings (or something broken...). */
17752 inst.error = NULL;
cc933301 17753 et = neon_check_type (2, rs, N_EQK, N_F_16_32 | N_KEY);
30bdf752
MGD
17754
17755 if (et.type == NT_invtype)
17756 return;
17757
17758 set_it_insn_type (OUTSIDE_IT_INSN);
17759 NEON_ENCODE (FLOAT, inst);
17760
17761 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH8) == FAIL)
17762 return;
17763
17764 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17765 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17766 inst.instruction |= LOW4 (inst.operands[1].reg);
17767 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
17768 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
17769 /* Mask off the original size bits and reencode them. */
17770 inst.instruction = ((inst.instruction & 0xfff3ffff)
17771 | neon_logbits (et.size) << 18);
17772
30bdf752
MGD
17773 switch (mode)
17774 {
17775 case neon_cvt_mode_z: inst.instruction |= 3 << 7; break;
17776 case neon_cvt_mode_x: inst.instruction |= 1 << 7; break;
17777 case neon_cvt_mode_a: inst.instruction |= 2 << 7; break;
17778 case neon_cvt_mode_n: inst.instruction |= 0 << 7; break;
17779 case neon_cvt_mode_p: inst.instruction |= 7 << 7; break;
17780 case neon_cvt_mode_m: inst.instruction |= 5 << 7; break;
17781 case neon_cvt_mode_r: inst.error = _("invalid rounding mode"); break;
17782 default: abort ();
17783 }
17784
17785 if (thumb_mode)
17786 inst.instruction |= 0xfc000000;
17787 else
17788 inst.instruction |= 0xf0000000;
17789 }
17790}
17791
17792static void
17793do_vrintx (void)
17794{
17795 do_vrint_1 (neon_cvt_mode_x);
17796}
17797
17798static void
17799do_vrintz (void)
17800{
17801 do_vrint_1 (neon_cvt_mode_z);
17802}
17803
17804static void
17805do_vrintr (void)
17806{
17807 do_vrint_1 (neon_cvt_mode_r);
17808}
17809
17810static void
17811do_vrinta (void)
17812{
17813 do_vrint_1 (neon_cvt_mode_a);
17814}
17815
17816static void
17817do_vrintn (void)
17818{
17819 do_vrint_1 (neon_cvt_mode_n);
17820}
17821
17822static void
17823do_vrintp (void)
17824{
17825 do_vrint_1 (neon_cvt_mode_p);
17826}
17827
17828static void
17829do_vrintm (void)
17830{
17831 do_vrint_1 (neon_cvt_mode_m);
17832}
17833
c28eeff2
SN
17834static unsigned
17835neon_scalar_for_vcmla (unsigned opnd, unsigned elsize)
17836{
17837 unsigned regno = NEON_SCALAR_REG (opnd);
17838 unsigned elno = NEON_SCALAR_INDEX (opnd);
17839
17840 if (elsize == 16 && elno < 2 && regno < 16)
17841 return regno | (elno << 4);
17842 else if (elsize == 32 && elno == 0)
17843 return regno;
17844
17845 first_error (_("scalar out of range"));
17846 return 0;
17847}
17848
17849static void
17850do_vcmla (void)
17851{
17852 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
17853 _(BAD_FPU));
e2b0ab59
AV
17854 constraint (inst.relocs[0].exp.X_op != O_constant,
17855 _("expression too complex"));
17856 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2
SN
17857 constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
17858 _("immediate out of range"));
17859 rot /= 90;
17860 if (inst.operands[2].isscalar)
17861 {
17862 enum neon_shape rs = neon_select_shape (NS_DDSI, NS_QQSI, NS_NULL);
17863 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
17864 N_KEY | N_F16 | N_F32).size;
17865 unsigned m = neon_scalar_for_vcmla (inst.operands[2].reg, size);
17866 inst.is_neon = 1;
17867 inst.instruction = 0xfe000800;
17868 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17869 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17870 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17871 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
17872 inst.instruction |= LOW4 (m);
17873 inst.instruction |= HI1 (m) << 5;
17874 inst.instruction |= neon_quad (rs) << 6;
17875 inst.instruction |= rot << 20;
17876 inst.instruction |= (size == 32) << 23;
17877 }
17878 else
17879 {
17880 enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
17881 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
17882 N_KEY | N_F16 | N_F32).size;
17883 neon_three_same (neon_quad (rs), 0, -1);
17884 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
17885 inst.instruction |= 0xfc200800;
17886 inst.instruction |= rot << 23;
17887 inst.instruction |= (size == 32) << 20;
17888 }
17889}
17890
17891static void
17892do_vcadd (void)
17893{
17894 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
17895 _(BAD_FPU));
e2b0ab59
AV
17896 constraint (inst.relocs[0].exp.X_op != O_constant,
17897 _("expression too complex"));
17898 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2
SN
17899 constraint (rot != 90 && rot != 270, _("immediate out of range"));
17900 enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
17901 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
17902 N_KEY | N_F16 | N_F32).size;
17903 neon_three_same (neon_quad (rs), 0, -1);
17904 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
17905 inst.instruction |= 0xfc800800;
17906 inst.instruction |= (rot == 270) << 24;
17907 inst.instruction |= (size == 32) << 20;
17908}
17909
c604a79a
JW
17910/* Dot Product instructions encoding support. */
17911
17912static void
17913do_neon_dotproduct (int unsigned_p)
17914{
17915 enum neon_shape rs;
17916 unsigned scalar_oprd2 = 0;
17917 int high8;
17918
17919 if (inst.cond != COND_ALWAYS)
17920 as_warn (_("Dot Product instructions cannot be conditional, the behaviour "
17921 "is UNPREDICTABLE"));
17922
17923 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
17924 _(BAD_FPU));
17925
17926 /* Dot Product instructions are in three-same D/Q register format or the third
17927 operand can be a scalar index register. */
17928 if (inst.operands[2].isscalar)
17929 {
17930 scalar_oprd2 = neon_scalar_for_mul (inst.operands[2].reg, 32);
17931 high8 = 0xfe000000;
17932 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
17933 }
17934 else
17935 {
17936 high8 = 0xfc000000;
17937 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17938 }
17939
17940 if (unsigned_p)
17941 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_U8);
17942 else
17943 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_S8);
17944
17945 /* The "U" bit in traditional Three Same encoding is fixed to 0 for Dot
17946 Product instruction, so we pass 0 as the "ubit" parameter. And the
17947 "Size" field are fixed to 0x2, so we pass 32 as the "size" parameter. */
17948 neon_three_same (neon_quad (rs), 0, 32);
17949
17950 /* Undo neon_dp_fixup. Dot Product instructions are using a slightly
17951 different NEON three-same encoding. */
17952 inst.instruction &= 0x00ffffff;
17953 inst.instruction |= high8;
17954 /* Encode 'U' bit which indicates signedness. */
17955 inst.instruction |= (unsigned_p ? 1 : 0) << 4;
17956 /* Re-encode operand2 if it's indexed scalar operand. What has been encoded
17957 from inst.operand[2].reg in neon_three_same is GAS's internal encoding, not
17958 the instruction encoding. */
17959 if (inst.operands[2].isscalar)
17960 {
17961 inst.instruction &= 0xffffffd0;
17962 inst.instruction |= LOW4 (scalar_oprd2);
17963 inst.instruction |= HI1 (scalar_oprd2) << 5;
17964 }
17965}
17966
17967/* Dot Product instructions for signed integer. */
17968
17969static void
17970do_neon_dotproduct_s (void)
17971{
17972 return do_neon_dotproduct (0);
17973}
17974
17975/* Dot Product instructions for unsigned integer. */
17976
17977static void
17978do_neon_dotproduct_u (void)
17979{
17980 return do_neon_dotproduct (1);
17981}
17982
91ff7894
MGD
17983/* Crypto v1 instructions. */
17984static void
17985do_crypto_2op_1 (unsigned elttype, int op)
17986{
17987 set_it_insn_type (OUTSIDE_IT_INSN);
17988
17989 if (neon_check_type (2, NS_QQ, N_EQK | N_UNT, elttype | N_UNT | N_KEY).type
17990 == NT_invtype)
17991 return;
17992
17993 inst.error = NULL;
17994
17995 NEON_ENCODE (INTEGER, inst);
17996 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17997 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17998 inst.instruction |= LOW4 (inst.operands[1].reg);
17999 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18000 if (op != -1)
18001 inst.instruction |= op << 6;
18002
18003 if (thumb_mode)
18004 inst.instruction |= 0xfc000000;
18005 else
18006 inst.instruction |= 0xf0000000;
18007}
18008
48adcd8e
MGD
18009static void
18010do_crypto_3op_1 (int u, int op)
18011{
18012 set_it_insn_type (OUTSIDE_IT_INSN);
18013
18014 if (neon_check_type (3, NS_QQQ, N_EQK | N_UNT, N_EQK | N_UNT,
18015 N_32 | N_UNT | N_KEY).type == NT_invtype)
18016 return;
18017
18018 inst.error = NULL;
18019
18020 NEON_ENCODE (INTEGER, inst);
18021 neon_three_same (1, u, 8 << op);
18022}
18023
91ff7894
MGD
18024static void
18025do_aese (void)
18026{
18027 do_crypto_2op_1 (N_8, 0);
18028}
18029
18030static void
18031do_aesd (void)
18032{
18033 do_crypto_2op_1 (N_8, 1);
18034}
18035
18036static void
18037do_aesmc (void)
18038{
18039 do_crypto_2op_1 (N_8, 2);
18040}
18041
18042static void
18043do_aesimc (void)
18044{
18045 do_crypto_2op_1 (N_8, 3);
18046}
18047
48adcd8e
MGD
18048static void
18049do_sha1c (void)
18050{
18051 do_crypto_3op_1 (0, 0);
18052}
18053
18054static void
18055do_sha1p (void)
18056{
18057 do_crypto_3op_1 (0, 1);
18058}
18059
18060static void
18061do_sha1m (void)
18062{
18063 do_crypto_3op_1 (0, 2);
18064}
18065
18066static void
18067do_sha1su0 (void)
18068{
18069 do_crypto_3op_1 (0, 3);
18070}
91ff7894 18071
48adcd8e
MGD
18072static void
18073do_sha256h (void)
18074{
18075 do_crypto_3op_1 (1, 0);
18076}
18077
18078static void
18079do_sha256h2 (void)
18080{
18081 do_crypto_3op_1 (1, 1);
18082}
18083
18084static void
18085do_sha256su1 (void)
18086{
18087 do_crypto_3op_1 (1, 2);
18088}
3c9017d2
MGD
18089
18090static void
18091do_sha1h (void)
18092{
18093 do_crypto_2op_1 (N_32, -1);
18094}
18095
18096static void
18097do_sha1su1 (void)
18098{
18099 do_crypto_2op_1 (N_32, 0);
18100}
18101
18102static void
18103do_sha256su0 (void)
18104{
18105 do_crypto_2op_1 (N_32, 1);
18106}
dd5181d5
KT
18107
18108static void
18109do_crc32_1 (unsigned int poly, unsigned int sz)
18110{
18111 unsigned int Rd = inst.operands[0].reg;
18112 unsigned int Rn = inst.operands[1].reg;
18113 unsigned int Rm = inst.operands[2].reg;
18114
18115 set_it_insn_type (OUTSIDE_IT_INSN);
18116 inst.instruction |= LOW4 (Rd) << (thumb_mode ? 8 : 12);
18117 inst.instruction |= LOW4 (Rn) << 16;
18118 inst.instruction |= LOW4 (Rm);
18119 inst.instruction |= sz << (thumb_mode ? 4 : 21);
18120 inst.instruction |= poly << (thumb_mode ? 20 : 9);
18121
18122 if (Rd == REG_PC || Rn == REG_PC || Rm == REG_PC)
18123 as_warn (UNPRED_REG ("r15"));
dd5181d5
KT
18124}
18125
18126static void
18127do_crc32b (void)
18128{
18129 do_crc32_1 (0, 0);
18130}
18131
18132static void
18133do_crc32h (void)
18134{
18135 do_crc32_1 (0, 1);
18136}
18137
18138static void
18139do_crc32w (void)
18140{
18141 do_crc32_1 (0, 2);
18142}
18143
18144static void
18145do_crc32cb (void)
18146{
18147 do_crc32_1 (1, 0);
18148}
18149
18150static void
18151do_crc32ch (void)
18152{
18153 do_crc32_1 (1, 1);
18154}
18155
18156static void
18157do_crc32cw (void)
18158{
18159 do_crc32_1 (1, 2);
18160}
18161
49e8a725
SN
18162static void
18163do_vjcvt (void)
18164{
18165 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
18166 _(BAD_FPU));
18167 neon_check_type (2, NS_FD, N_S32, N_F64);
18168 do_vfp_sp_dp_cvt ();
18169 do_vfp_cond_or_thumb ();
18170}
18171
5287ad62
JB
18172\f
18173/* Overall per-instruction processing. */
18174
18175/* We need to be able to fix up arbitrary expressions in some statements.
18176 This is so that we can handle symbols that are an arbitrary distance from
18177 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
18178 which returns part of an address in a form which will be valid for
18179 a data instruction. We do this by pushing the expression into a symbol
18180 in the expr_section, and creating a fix for that. */
18181
18182static void
18183fix_new_arm (fragS * frag,
18184 int where,
18185 short int size,
18186 expressionS * exp,
18187 int pc_rel,
18188 int reloc)
18189{
18190 fixS * new_fix;
18191
18192 switch (exp->X_op)
18193 {
18194 case O_constant:
6e7ce2cd
PB
18195 if (pc_rel)
18196 {
18197 /* Create an absolute valued symbol, so we have something to
477330fc
RM
18198 refer to in the object file. Unfortunately for us, gas's
18199 generic expression parsing will already have folded out
18200 any use of .set foo/.type foo %function that may have
18201 been used to set type information of the target location,
18202 that's being specified symbolically. We have to presume
18203 the user knows what they are doing. */
6e7ce2cd
PB
18204 char name[16 + 8];
18205 symbolS *symbol;
18206
18207 sprintf (name, "*ABS*0x%lx", (unsigned long)exp->X_add_number);
18208
18209 symbol = symbol_find_or_make (name);
18210 S_SET_SEGMENT (symbol, absolute_section);
18211 symbol_set_frag (symbol, &zero_address_frag);
18212 S_SET_VALUE (symbol, exp->X_add_number);
18213 exp->X_op = O_symbol;
18214 exp->X_add_symbol = symbol;
18215 exp->X_add_number = 0;
18216 }
18217 /* FALLTHROUGH */
5287ad62
JB
18218 case O_symbol:
18219 case O_add:
18220 case O_subtract:
21d799b5 18221 new_fix = fix_new_exp (frag, where, size, exp, pc_rel,
477330fc 18222 (enum bfd_reloc_code_real) reloc);
5287ad62
JB
18223 break;
18224
18225 default:
21d799b5 18226 new_fix = (fixS *) fix_new (frag, where, size, make_expr_symbol (exp), 0,
477330fc 18227 pc_rel, (enum bfd_reloc_code_real) reloc);
5287ad62
JB
18228 break;
18229 }
18230
18231 /* Mark whether the fix is to a THUMB instruction, or an ARM
18232 instruction. */
18233 new_fix->tc_fix_data = thumb_mode;
18234}
18235
18236/* Create a frg for an instruction requiring relaxation. */
18237static void
18238output_relax_insn (void)
18239{
18240 char * to;
18241 symbolS *sym;
0110f2b8
PB
18242 int offset;
18243
6e1cb1a6
PB
18244 /* The size of the instruction is unknown, so tie the debug info to the
18245 start of the instruction. */
18246 dwarf2_emit_insn (0);
6e1cb1a6 18247
e2b0ab59 18248 switch (inst.relocs[0].exp.X_op)
0110f2b8
PB
18249 {
18250 case O_symbol:
e2b0ab59
AV
18251 sym = inst.relocs[0].exp.X_add_symbol;
18252 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
18253 break;
18254 case O_constant:
18255 sym = NULL;
e2b0ab59 18256 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
18257 break;
18258 default:
e2b0ab59 18259 sym = make_expr_symbol (&inst.relocs[0].exp);
0110f2b8
PB
18260 offset = 0;
18261 break;
18262 }
18263 to = frag_var (rs_machine_dependent, INSN_SIZE, THUMB_SIZE,
18264 inst.relax, sym, offset, NULL/*offset, opcode*/);
18265 md_number_to_chars (to, inst.instruction, THUMB_SIZE);
0110f2b8
PB
18266}
18267
18268/* Write a 32-bit thumb instruction to buf. */
18269static void
18270put_thumb32_insn (char * buf, unsigned long insn)
18271{
18272 md_number_to_chars (buf, insn >> 16, THUMB_SIZE);
18273 md_number_to_chars (buf + THUMB_SIZE, insn, THUMB_SIZE);
18274}
18275
b99bd4ef 18276static void
c19d1205 18277output_inst (const char * str)
b99bd4ef 18278{
c19d1205 18279 char * to = NULL;
b99bd4ef 18280
c19d1205 18281 if (inst.error)
b99bd4ef 18282 {
c19d1205 18283 as_bad ("%s -- `%s'", inst.error, str);
b99bd4ef
NC
18284 return;
18285 }
5f4273c7
NC
18286 if (inst.relax)
18287 {
18288 output_relax_insn ();
0110f2b8 18289 return;
5f4273c7 18290 }
c19d1205
ZW
18291 if (inst.size == 0)
18292 return;
b99bd4ef 18293
c19d1205 18294 to = frag_more (inst.size);
8dc2430f
NC
18295 /* PR 9814: Record the thumb mode into the current frag so that we know
18296 what type of NOP padding to use, if necessary. We override any previous
18297 setting so that if the mode has changed then the NOPS that we use will
18298 match the encoding of the last instruction in the frag. */
cd000bff 18299 frag_now->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
c19d1205
ZW
18300
18301 if (thumb_mode && (inst.size > THUMB_SIZE))
b99bd4ef 18302 {
9c2799c2 18303 gas_assert (inst.size == (2 * THUMB_SIZE));
0110f2b8 18304 put_thumb32_insn (to, inst.instruction);
b99bd4ef 18305 }
c19d1205 18306 else if (inst.size > INSN_SIZE)
b99bd4ef 18307 {
9c2799c2 18308 gas_assert (inst.size == (2 * INSN_SIZE));
c19d1205
ZW
18309 md_number_to_chars (to, inst.instruction, INSN_SIZE);
18310 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
b99bd4ef 18311 }
c19d1205
ZW
18312 else
18313 md_number_to_chars (to, inst.instruction, inst.size);
b99bd4ef 18314
e2b0ab59
AV
18315 int r;
18316 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
18317 {
18318 if (inst.relocs[r].type != BFD_RELOC_UNUSED)
18319 fix_new_arm (frag_now, to - frag_now->fr_literal,
18320 inst.size, & inst.relocs[r].exp, inst.relocs[r].pc_rel,
18321 inst.relocs[r].type);
18322 }
b99bd4ef 18323
c19d1205 18324 dwarf2_emit_insn (inst.size);
c19d1205 18325}
b99bd4ef 18326
e07e6e58
NC
18327static char *
18328output_it_inst (int cond, int mask, char * to)
18329{
18330 unsigned long instruction = 0xbf00;
18331
18332 mask &= 0xf;
18333 instruction |= mask;
18334 instruction |= cond << 4;
18335
18336 if (to == NULL)
18337 {
18338 to = frag_more (2);
18339#ifdef OBJ_ELF
18340 dwarf2_emit_insn (2);
18341#endif
18342 }
18343
18344 md_number_to_chars (to, instruction, 2);
18345
18346 return to;
18347}
18348
c19d1205
ZW
18349/* Tag values used in struct asm_opcode's tag field. */
18350enum opcode_tag
18351{
18352 OT_unconditional, /* Instruction cannot be conditionalized.
18353 The ARM condition field is still 0xE. */
18354 OT_unconditionalF, /* Instruction cannot be conditionalized
18355 and carries 0xF in its ARM condition field. */
18356 OT_csuffix, /* Instruction takes a conditional suffix. */
037e8744 18357 OT_csuffixF, /* Some forms of the instruction take a conditional
477330fc
RM
18358 suffix, others place 0xF where the condition field
18359 would be. */
c19d1205
ZW
18360 OT_cinfix3, /* Instruction takes a conditional infix,
18361 beginning at character index 3. (In
18362 unified mode, it becomes a suffix.) */
088fa78e
KH
18363 OT_cinfix3_deprecated, /* The same as OT_cinfix3. This is used for
18364 tsts, cmps, cmns, and teqs. */
e3cb604e
PB
18365 OT_cinfix3_legacy, /* Legacy instruction takes a conditional infix at
18366 character index 3, even in unified mode. Used for
18367 legacy instructions where suffix and infix forms
18368 may be ambiguous. */
c19d1205 18369 OT_csuf_or_in3, /* Instruction takes either a conditional
e3cb604e 18370 suffix or an infix at character index 3. */
c19d1205
ZW
18371 OT_odd_infix_unc, /* This is the unconditional variant of an
18372 instruction that takes a conditional infix
18373 at an unusual position. In unified mode,
18374 this variant will accept a suffix. */
18375 OT_odd_infix_0 /* Values greater than or equal to OT_odd_infix_0
18376 are the conditional variants of instructions that
18377 take conditional infixes in unusual positions.
18378 The infix appears at character index
18379 (tag - OT_odd_infix_0). These are not accepted
18380 in unified mode. */
18381};
b99bd4ef 18382
c19d1205
ZW
18383/* Subroutine of md_assemble, responsible for looking up the primary
18384 opcode from the mnemonic the user wrote. STR points to the
18385 beginning of the mnemonic.
18386
18387 This is not simply a hash table lookup, because of conditional
18388 variants. Most instructions have conditional variants, which are
18389 expressed with a _conditional affix_ to the mnemonic. If we were
18390 to encode each conditional variant as a literal string in the opcode
18391 table, it would have approximately 20,000 entries.
18392
18393 Most mnemonics take this affix as a suffix, and in unified syntax,
18394 'most' is upgraded to 'all'. However, in the divided syntax, some
18395 instructions take the affix as an infix, notably the s-variants of
18396 the arithmetic instructions. Of those instructions, all but six
18397 have the infix appear after the third character of the mnemonic.
18398
18399 Accordingly, the algorithm for looking up primary opcodes given
18400 an identifier is:
18401
18402 1. Look up the identifier in the opcode table.
18403 If we find a match, go to step U.
18404
18405 2. Look up the last two characters of the identifier in the
18406 conditions table. If we find a match, look up the first N-2
18407 characters of the identifier in the opcode table. If we
18408 find a match, go to step CE.
18409
18410 3. Look up the fourth and fifth characters of the identifier in
18411 the conditions table. If we find a match, extract those
18412 characters from the identifier, and look up the remaining
18413 characters in the opcode table. If we find a match, go
18414 to step CM.
18415
18416 4. Fail.
18417
18418 U. Examine the tag field of the opcode structure, in case this is
18419 one of the six instructions with its conditional infix in an
18420 unusual place. If it is, the tag tells us where to find the
18421 infix; look it up in the conditions table and set inst.cond
18422 accordingly. Otherwise, this is an unconditional instruction.
18423 Again set inst.cond accordingly. Return the opcode structure.
18424
18425 CE. Examine the tag field to make sure this is an instruction that
18426 should receive a conditional suffix. If it is not, fail.
18427 Otherwise, set inst.cond from the suffix we already looked up,
18428 and return the opcode structure.
18429
18430 CM. Examine the tag field to make sure this is an instruction that
18431 should receive a conditional infix after the third character.
18432 If it is not, fail. Otherwise, undo the edits to the current
18433 line of input and proceed as for case CE. */
18434
18435static const struct asm_opcode *
18436opcode_lookup (char **str)
18437{
18438 char *end, *base;
18439 char *affix;
18440 const struct asm_opcode *opcode;
18441 const struct asm_cond *cond;
e3cb604e 18442 char save[2];
c19d1205
ZW
18443
18444 /* Scan up to the end of the mnemonic, which must end in white space,
721a8186 18445 '.' (in unified mode, or for Neon/VFP instructions), or end of string. */
c19d1205 18446 for (base = end = *str; *end != '\0'; end++)
721a8186 18447 if (*end == ' ' || *end == '.')
c19d1205 18448 break;
b99bd4ef 18449
c19d1205 18450 if (end == base)
c921be7d 18451 return NULL;
b99bd4ef 18452
5287ad62 18453 /* Handle a possible width suffix and/or Neon type suffix. */
c19d1205 18454 if (end[0] == '.')
b99bd4ef 18455 {
5287ad62 18456 int offset = 2;
5f4273c7 18457
267d2029 18458 /* The .w and .n suffixes are only valid if the unified syntax is in
477330fc 18459 use. */
267d2029 18460 if (unified_syntax && end[1] == 'w')
c19d1205 18461 inst.size_req = 4;
267d2029 18462 else if (unified_syntax && end[1] == 'n')
c19d1205
ZW
18463 inst.size_req = 2;
18464 else
477330fc 18465 offset = 0;
5287ad62
JB
18466
18467 inst.vectype.elems = 0;
18468
18469 *str = end + offset;
b99bd4ef 18470
5f4273c7 18471 if (end[offset] == '.')
5287ad62 18472 {
267d2029 18473 /* See if we have a Neon type suffix (possible in either unified or
477330fc
RM
18474 non-unified ARM syntax mode). */
18475 if (parse_neon_type (&inst.vectype, str) == FAIL)
c921be7d 18476 return NULL;
477330fc 18477 }
5287ad62 18478 else if (end[offset] != '\0' && end[offset] != ' ')
477330fc 18479 return NULL;
b99bd4ef 18480 }
c19d1205
ZW
18481 else
18482 *str = end;
b99bd4ef 18483
c19d1205 18484 /* Look for unaffixed or special-case affixed mnemonic. */
21d799b5 18485 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
477330fc 18486 end - base);
c19d1205 18487 if (opcode)
b99bd4ef 18488 {
c19d1205
ZW
18489 /* step U */
18490 if (opcode->tag < OT_odd_infix_0)
b99bd4ef 18491 {
c19d1205
ZW
18492 inst.cond = COND_ALWAYS;
18493 return opcode;
b99bd4ef 18494 }
b99bd4ef 18495
278df34e 18496 if (warn_on_deprecated && unified_syntax)
5c3696f8 18497 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205 18498 affix = base + (opcode->tag - OT_odd_infix_0);
21d799b5 18499 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
9c2799c2 18500 gas_assert (cond);
b99bd4ef 18501
c19d1205
ZW
18502 inst.cond = cond->value;
18503 return opcode;
18504 }
b99bd4ef 18505
c19d1205
ZW
18506 /* Cannot have a conditional suffix on a mnemonic of less than two
18507 characters. */
18508 if (end - base < 3)
c921be7d 18509 return NULL;
b99bd4ef 18510
c19d1205
ZW
18511 /* Look for suffixed mnemonic. */
18512 affix = end - 2;
21d799b5
NC
18513 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
18514 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
477330fc 18515 affix - base);
c19d1205
ZW
18516 if (opcode && cond)
18517 {
18518 /* step CE */
18519 switch (opcode->tag)
18520 {
e3cb604e
PB
18521 case OT_cinfix3_legacy:
18522 /* Ignore conditional suffixes matched on infix only mnemonics. */
18523 break;
18524
c19d1205 18525 case OT_cinfix3:
088fa78e 18526 case OT_cinfix3_deprecated:
c19d1205
ZW
18527 case OT_odd_infix_unc:
18528 if (!unified_syntax)
0198d5e6 18529 return NULL;
1a0670f3 18530 /* Fall through. */
c19d1205
ZW
18531
18532 case OT_csuffix:
477330fc 18533 case OT_csuffixF:
c19d1205
ZW
18534 case OT_csuf_or_in3:
18535 inst.cond = cond->value;
18536 return opcode;
18537
18538 case OT_unconditional:
18539 case OT_unconditionalF:
dfa9f0d5 18540 if (thumb_mode)
c921be7d 18541 inst.cond = cond->value;
dfa9f0d5
PB
18542 else
18543 {
c921be7d 18544 /* Delayed diagnostic. */
dfa9f0d5
PB
18545 inst.error = BAD_COND;
18546 inst.cond = COND_ALWAYS;
18547 }
c19d1205 18548 return opcode;
b99bd4ef 18549
c19d1205 18550 default:
c921be7d 18551 return NULL;
c19d1205
ZW
18552 }
18553 }
b99bd4ef 18554
c19d1205
ZW
18555 /* Cannot have a usual-position infix on a mnemonic of less than
18556 six characters (five would be a suffix). */
18557 if (end - base < 6)
c921be7d 18558 return NULL;
b99bd4ef 18559
c19d1205
ZW
18560 /* Look for infixed mnemonic in the usual position. */
18561 affix = base + 3;
21d799b5 18562 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
e3cb604e 18563 if (!cond)
c921be7d 18564 return NULL;
e3cb604e
PB
18565
18566 memcpy (save, affix, 2);
18567 memmove (affix, affix + 2, (end - affix) - 2);
21d799b5 18568 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
477330fc 18569 (end - base) - 2);
e3cb604e
PB
18570 memmove (affix + 2, affix, (end - affix) - 2);
18571 memcpy (affix, save, 2);
18572
088fa78e
KH
18573 if (opcode
18574 && (opcode->tag == OT_cinfix3
18575 || opcode->tag == OT_cinfix3_deprecated
18576 || opcode->tag == OT_csuf_or_in3
18577 || opcode->tag == OT_cinfix3_legacy))
b99bd4ef 18578 {
c921be7d 18579 /* Step CM. */
278df34e 18580 if (warn_on_deprecated && unified_syntax
088fa78e
KH
18581 && (opcode->tag == OT_cinfix3
18582 || opcode->tag == OT_cinfix3_deprecated))
5c3696f8 18583 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205
ZW
18584
18585 inst.cond = cond->value;
18586 return opcode;
b99bd4ef
NC
18587 }
18588
c921be7d 18589 return NULL;
b99bd4ef
NC
18590}
18591
e07e6e58
NC
18592/* This function generates an initial IT instruction, leaving its block
18593 virtually open for the new instructions. Eventually,
18594 the mask will be updated by now_it_add_mask () each time
18595 a new instruction needs to be included in the IT block.
18596 Finally, the block is closed with close_automatic_it_block ().
18597 The block closure can be requested either from md_assemble (),
18598 a tencode (), or due to a label hook. */
18599
18600static void
18601new_automatic_it_block (int cond)
18602{
18603 now_it.state = AUTOMATIC_IT_BLOCK;
18604 now_it.mask = 0x18;
18605 now_it.cc = cond;
18606 now_it.block_length = 1;
cd000bff 18607 mapping_state (MAP_THUMB);
e07e6e58 18608 now_it.insn = output_it_inst (cond, now_it.mask, NULL);
5a01bb1d
MGD
18609 now_it.warn_deprecated = FALSE;
18610 now_it.insn_cond = TRUE;
e07e6e58
NC
18611}
18612
18613/* Close an automatic IT block.
18614 See comments in new_automatic_it_block (). */
18615
18616static void
18617close_automatic_it_block (void)
18618{
18619 now_it.mask = 0x10;
18620 now_it.block_length = 0;
18621}
18622
18623/* Update the mask of the current automatically-generated IT
18624 instruction. See comments in new_automatic_it_block (). */
18625
18626static void
18627now_it_add_mask (int cond)
18628{
18629#define CLEAR_BIT(value, nbit) ((value) & ~(1 << (nbit)))
18630#define SET_BIT_VALUE(value, bitvalue, nbit) (CLEAR_BIT (value, nbit) \
477330fc 18631 | ((bitvalue) << (nbit)))
e07e6e58 18632 const int resulting_bit = (cond & 1);
c921be7d 18633
e07e6e58
NC
18634 now_it.mask &= 0xf;
18635 now_it.mask = SET_BIT_VALUE (now_it.mask,
477330fc
RM
18636 resulting_bit,
18637 (5 - now_it.block_length));
e07e6e58 18638 now_it.mask = SET_BIT_VALUE (now_it.mask,
477330fc
RM
18639 1,
18640 ((5 - now_it.block_length) - 1) );
e07e6e58
NC
18641 output_it_inst (now_it.cc, now_it.mask, now_it.insn);
18642
18643#undef CLEAR_BIT
18644#undef SET_BIT_VALUE
e07e6e58
NC
18645}
18646
18647/* The IT blocks handling machinery is accessed through the these functions:
18648 it_fsm_pre_encode () from md_assemble ()
18649 set_it_insn_type () optional, from the tencode functions
18650 set_it_insn_type_last () ditto
18651 in_it_block () ditto
18652 it_fsm_post_encode () from md_assemble ()
33eaf5de 18653 force_automatic_it_block_close () from label handling functions
e07e6e58
NC
18654
18655 Rationale:
18656 1) md_assemble () calls it_fsm_pre_encode () before calling tencode (),
477330fc
RM
18657 initializing the IT insn type with a generic initial value depending
18658 on the inst.condition.
e07e6e58 18659 2) During the tencode function, two things may happen:
477330fc
RM
18660 a) The tencode function overrides the IT insn type by
18661 calling either set_it_insn_type (type) or set_it_insn_type_last ().
18662 b) The tencode function queries the IT block state by
18663 calling in_it_block () (i.e. to determine narrow/not narrow mode).
18664
18665 Both set_it_insn_type and in_it_block run the internal FSM state
18666 handling function (handle_it_state), because: a) setting the IT insn
18667 type may incur in an invalid state (exiting the function),
18668 and b) querying the state requires the FSM to be updated.
18669 Specifically we want to avoid creating an IT block for conditional
18670 branches, so it_fsm_pre_encode is actually a guess and we can't
18671 determine whether an IT block is required until the tencode () routine
18672 has decided what type of instruction this actually it.
18673 Because of this, if set_it_insn_type and in_it_block have to be used,
18674 set_it_insn_type has to be called first.
18675
18676 set_it_insn_type_last () is a wrapper of set_it_insn_type (type), that
18677 determines the insn IT type depending on the inst.cond code.
18678 When a tencode () routine encodes an instruction that can be
18679 either outside an IT block, or, in the case of being inside, has to be
18680 the last one, set_it_insn_type_last () will determine the proper
18681 IT instruction type based on the inst.cond code. Otherwise,
18682 set_it_insn_type can be called for overriding that logic or
18683 for covering other cases.
18684
18685 Calling handle_it_state () may not transition the IT block state to
2b0f3761 18686 OUTSIDE_IT_BLOCK immediately, since the (current) state could be
477330fc
RM
18687 still queried. Instead, if the FSM determines that the state should
18688 be transitioned to OUTSIDE_IT_BLOCK, a flag is marked to be closed
18689 after the tencode () function: that's what it_fsm_post_encode () does.
18690
18691 Since in_it_block () calls the state handling function to get an
18692 updated state, an error may occur (due to invalid insns combination).
18693 In that case, inst.error is set.
18694 Therefore, inst.error has to be checked after the execution of
18695 the tencode () routine.
e07e6e58
NC
18696
18697 3) Back in md_assemble(), it_fsm_post_encode () is called to commit
477330fc
RM
18698 any pending state change (if any) that didn't take place in
18699 handle_it_state () as explained above. */
e07e6e58
NC
18700
18701static void
18702it_fsm_pre_encode (void)
18703{
18704 if (inst.cond != COND_ALWAYS)
18705 inst.it_insn_type = INSIDE_IT_INSN;
18706 else
18707 inst.it_insn_type = OUTSIDE_IT_INSN;
18708
18709 now_it.state_handled = 0;
18710}
18711
18712/* IT state FSM handling function. */
18713
18714static int
18715handle_it_state (void)
18716{
18717 now_it.state_handled = 1;
5a01bb1d 18718 now_it.insn_cond = FALSE;
e07e6e58
NC
18719
18720 switch (now_it.state)
18721 {
18722 case OUTSIDE_IT_BLOCK:
18723 switch (inst.it_insn_type)
18724 {
18725 case OUTSIDE_IT_INSN:
18726 break;
18727
18728 case INSIDE_IT_INSN:
18729 case INSIDE_IT_LAST_INSN:
18730 if (thumb_mode == 0)
18731 {
c921be7d 18732 if (unified_syntax
e07e6e58
NC
18733 && !(implicit_it_mode & IMPLICIT_IT_MODE_ARM))
18734 as_tsktsk (_("Warning: conditional outside an IT block"\
18735 " for Thumb."));
18736 }
18737 else
18738 {
18739 if ((implicit_it_mode & IMPLICIT_IT_MODE_THUMB)
fc289b0a 18740 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
e07e6e58
NC
18741 {
18742 /* Automatically generate the IT instruction. */
18743 new_automatic_it_block (inst.cond);
18744 if (inst.it_insn_type == INSIDE_IT_LAST_INSN)
18745 close_automatic_it_block ();
18746 }
18747 else
18748 {
18749 inst.error = BAD_OUT_IT;
18750 return FAIL;
18751 }
18752 }
18753 break;
18754
18755 case IF_INSIDE_IT_LAST_INSN:
18756 case NEUTRAL_IT_INSN:
18757 break;
18758
18759 case IT_INSN:
18760 now_it.state = MANUAL_IT_BLOCK;
18761 now_it.block_length = 0;
18762 break;
18763 }
18764 break;
18765
18766 case AUTOMATIC_IT_BLOCK:
18767 /* Three things may happen now:
18768 a) We should increment current it block size;
18769 b) We should close current it block (closing insn or 4 insns);
18770 c) We should close current it block and start a new one (due
18771 to incompatible conditions or
18772 4 insns-length block reached). */
18773
18774 switch (inst.it_insn_type)
18775 {
18776 case OUTSIDE_IT_INSN:
2b0f3761 18777 /* The closure of the block shall happen immediately,
e07e6e58
NC
18778 so any in_it_block () call reports the block as closed. */
18779 force_automatic_it_block_close ();
18780 break;
18781
18782 case INSIDE_IT_INSN:
18783 case INSIDE_IT_LAST_INSN:
18784 case IF_INSIDE_IT_LAST_INSN:
18785 now_it.block_length++;
18786
18787 if (now_it.block_length > 4
18788 || !now_it_compatible (inst.cond))
18789 {
18790 force_automatic_it_block_close ();
18791 if (inst.it_insn_type != IF_INSIDE_IT_LAST_INSN)
18792 new_automatic_it_block (inst.cond);
18793 }
18794 else
18795 {
5a01bb1d 18796 now_it.insn_cond = TRUE;
e07e6e58
NC
18797 now_it_add_mask (inst.cond);
18798 }
18799
18800 if (now_it.state == AUTOMATIC_IT_BLOCK
18801 && (inst.it_insn_type == INSIDE_IT_LAST_INSN
18802 || inst.it_insn_type == IF_INSIDE_IT_LAST_INSN))
18803 close_automatic_it_block ();
18804 break;
18805
18806 case NEUTRAL_IT_INSN:
18807 now_it.block_length++;
5a01bb1d 18808 now_it.insn_cond = TRUE;
e07e6e58
NC
18809
18810 if (now_it.block_length > 4)
18811 force_automatic_it_block_close ();
18812 else
18813 now_it_add_mask (now_it.cc & 1);
18814 break;
18815
18816 case IT_INSN:
18817 close_automatic_it_block ();
18818 now_it.state = MANUAL_IT_BLOCK;
18819 break;
18820 }
18821 break;
18822
18823 case MANUAL_IT_BLOCK:
18824 {
18825 /* Check conditional suffixes. */
18826 const int cond = now_it.cc ^ ((now_it.mask >> 4) & 1) ^ 1;
18827 int is_last;
18828 now_it.mask <<= 1;
18829 now_it.mask &= 0x1f;
18830 is_last = (now_it.mask == 0x10);
5a01bb1d 18831 now_it.insn_cond = TRUE;
e07e6e58
NC
18832
18833 switch (inst.it_insn_type)
18834 {
18835 case OUTSIDE_IT_INSN:
18836 inst.error = BAD_NOT_IT;
18837 return FAIL;
18838
18839 case INSIDE_IT_INSN:
18840 if (cond != inst.cond)
18841 {
18842 inst.error = BAD_IT_COND;
18843 return FAIL;
18844 }
18845 break;
18846
18847 case INSIDE_IT_LAST_INSN:
18848 case IF_INSIDE_IT_LAST_INSN:
18849 if (cond != inst.cond)
18850 {
18851 inst.error = BAD_IT_COND;
18852 return FAIL;
18853 }
18854 if (!is_last)
18855 {
18856 inst.error = BAD_BRANCH;
18857 return FAIL;
18858 }
18859 break;
18860
18861 case NEUTRAL_IT_INSN:
18862 /* The BKPT instruction is unconditional even in an IT block. */
18863 break;
18864
18865 case IT_INSN:
18866 inst.error = BAD_IT_IT;
18867 return FAIL;
18868 }
18869 }
18870 break;
18871 }
18872
18873 return SUCCESS;
18874}
18875
5a01bb1d
MGD
18876struct depr_insn_mask
18877{
18878 unsigned long pattern;
18879 unsigned long mask;
18880 const char* description;
18881};
18882
18883/* List of 16-bit instruction patterns deprecated in an IT block in
18884 ARMv8. */
18885static const struct depr_insn_mask depr_it_insns[] = {
18886 { 0xc000, 0xc000, N_("Short branches, Undefined, SVC, LDM/STM") },
18887 { 0xb000, 0xb000, N_("Miscellaneous 16-bit instructions") },
18888 { 0xa000, 0xb800, N_("ADR") },
18889 { 0x4800, 0xf800, N_("Literal loads") },
18890 { 0x4478, 0xf478, N_("Hi-register ADD, MOV, CMP, BX, BLX using pc") },
18891 { 0x4487, 0xfc87, N_("Hi-register ADD, MOV, CMP using pc") },
c8de034b
JW
18892 /* NOTE: 0x00dd is not the real encoding, instead, it is the 'tvalue'
18893 field in asm_opcode. 'tvalue' is used at the stage this check happen. */
18894 { 0x00dd, 0x7fff, N_("ADD/SUB sp, sp #imm") },
5a01bb1d
MGD
18895 { 0, 0, NULL }
18896};
18897
e07e6e58
NC
18898static void
18899it_fsm_post_encode (void)
18900{
18901 int is_last;
18902
18903 if (!now_it.state_handled)
18904 handle_it_state ();
18905
5a01bb1d
MGD
18906 if (now_it.insn_cond
18907 && !now_it.warn_deprecated
18908 && warn_on_deprecated
df9909b8
TP
18909 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)
18910 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_m))
5a01bb1d
MGD
18911 {
18912 if (inst.instruction >= 0x10000)
18913 {
5c3696f8 18914 as_tsktsk (_("IT blocks containing 32-bit Thumb instructions are "
df9909b8 18915 "performance deprecated in ARMv8-A and ARMv8-R"));
5a01bb1d
MGD
18916 now_it.warn_deprecated = TRUE;
18917 }
18918 else
18919 {
18920 const struct depr_insn_mask *p = depr_it_insns;
18921
18922 while (p->mask != 0)
18923 {
18924 if ((inst.instruction & p->mask) == p->pattern)
18925 {
df9909b8
TP
18926 as_tsktsk (_("IT blocks containing 16-bit Thumb "
18927 "instructions of the following class are "
18928 "performance deprecated in ARMv8-A and "
18929 "ARMv8-R: %s"), p->description);
5a01bb1d
MGD
18930 now_it.warn_deprecated = TRUE;
18931 break;
18932 }
18933
18934 ++p;
18935 }
18936 }
18937
18938 if (now_it.block_length > 1)
18939 {
5c3696f8 18940 as_tsktsk (_("IT blocks containing more than one conditional "
df9909b8
TP
18941 "instruction are performance deprecated in ARMv8-A and "
18942 "ARMv8-R"));
5a01bb1d
MGD
18943 now_it.warn_deprecated = TRUE;
18944 }
18945 }
18946
e07e6e58
NC
18947 is_last = (now_it.mask == 0x10);
18948 if (is_last)
18949 {
18950 now_it.state = OUTSIDE_IT_BLOCK;
18951 now_it.mask = 0;
18952 }
18953}
18954
18955static void
18956force_automatic_it_block_close (void)
18957{
18958 if (now_it.state == AUTOMATIC_IT_BLOCK)
18959 {
18960 close_automatic_it_block ();
18961 now_it.state = OUTSIDE_IT_BLOCK;
18962 now_it.mask = 0;
18963 }
18964}
18965
18966static int
18967in_it_block (void)
18968{
18969 if (!now_it.state_handled)
18970 handle_it_state ();
18971
18972 return now_it.state != OUTSIDE_IT_BLOCK;
18973}
18974
ff8646ee
TP
18975/* Whether OPCODE only has T32 encoding. Since this function is only used by
18976 t32_insn_ok, OPCODE enabled by v6t2 extension bit do not need to be listed
18977 here, hence the "known" in the function name. */
fc289b0a
TP
18978
18979static bfd_boolean
ff8646ee 18980known_t32_only_insn (const struct asm_opcode *opcode)
fc289b0a
TP
18981{
18982 /* Original Thumb-1 wide instruction. */
18983 if (opcode->tencode == do_t_blx
18984 || opcode->tencode == do_t_branch23
18985 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_msr)
18986 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_barrier))
18987 return TRUE;
18988
16a1fa25
TP
18989 /* Wide-only instruction added to ARMv8-M Baseline. */
18990 if (ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v8m_m_only)
ff8646ee
TP
18991 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_atomics)
18992 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v6t2_v8m)
18993 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_div))
18994 return TRUE;
18995
18996 return FALSE;
18997}
18998
18999/* Whether wide instruction variant can be used if available for a valid OPCODE
19000 in ARCH. */
19001
19002static bfd_boolean
19003t32_insn_ok (arm_feature_set arch, const struct asm_opcode *opcode)
19004{
19005 if (known_t32_only_insn (opcode))
19006 return TRUE;
19007
19008 /* Instruction with narrow and wide encoding added to ARMv8-M. Availability
19009 of variant T3 of B.W is checked in do_t_branch. */
19010 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
19011 && opcode->tencode == do_t_branch)
19012 return TRUE;
19013
bada4342
JW
19014 /* MOV accepts T1/T3 encodings under Baseline, T3 encoding is 32bit. */
19015 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
19016 && opcode->tencode == do_t_mov_cmp
19017 /* Make sure CMP instruction is not affected. */
19018 && opcode->aencode == do_mov)
19019 return TRUE;
19020
ff8646ee
TP
19021 /* Wide instruction variants of all instructions with narrow *and* wide
19022 variants become available with ARMv6t2. Other opcodes are either
19023 narrow-only or wide-only and are thus available if OPCODE is valid. */
19024 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v6t2))
19025 return TRUE;
19026
19027 /* OPCODE with narrow only instruction variant or wide variant not
19028 available. */
fc289b0a
TP
19029 return FALSE;
19030}
19031
c19d1205
ZW
19032void
19033md_assemble (char *str)
b99bd4ef 19034{
c19d1205
ZW
19035 char *p = str;
19036 const struct asm_opcode * opcode;
b99bd4ef 19037
c19d1205
ZW
19038 /* Align the previous label if needed. */
19039 if (last_label_seen != NULL)
b99bd4ef 19040 {
c19d1205
ZW
19041 symbol_set_frag (last_label_seen, frag_now);
19042 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
19043 S_SET_SEGMENT (last_label_seen, now_seg);
b99bd4ef
NC
19044 }
19045
c19d1205 19046 memset (&inst, '\0', sizeof (inst));
e2b0ab59
AV
19047 int r;
19048 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
19049 inst.relocs[r].type = BFD_RELOC_UNUSED;
b99bd4ef 19050
c19d1205
ZW
19051 opcode = opcode_lookup (&p);
19052 if (!opcode)
b99bd4ef 19053 {
c19d1205 19054 /* It wasn't an instruction, but it might be a register alias of
dcbf9037 19055 the form alias .req reg, or a Neon .dn/.qn directive. */
c921be7d 19056 if (! create_register_alias (str, p)
477330fc 19057 && ! create_neon_reg_alias (str, p))
c19d1205 19058 as_bad (_("bad instruction `%s'"), str);
b99bd4ef 19059
b99bd4ef
NC
19060 return;
19061 }
19062
278df34e 19063 if (warn_on_deprecated && opcode->tag == OT_cinfix3_deprecated)
5c3696f8 19064 as_tsktsk (_("s suffix on comparison instruction is deprecated"));
088fa78e 19065
037e8744
JB
19066 /* The value which unconditional instructions should have in place of the
19067 condition field. */
19068 inst.uncond_value = (opcode->tag == OT_csuffixF) ? 0xf : -1;
19069
c19d1205 19070 if (thumb_mode)
b99bd4ef 19071 {
e74cfd16 19072 arm_feature_set variant;
8f06b2d8
PB
19073
19074 variant = cpu_variant;
19075 /* Only allow coprocessor instructions on Thumb-2 capable devices. */
e74cfd16
PB
19076 if (!ARM_CPU_HAS_FEATURE (variant, arm_arch_t2))
19077 ARM_CLEAR_FEATURE (variant, variant, fpu_any_hard);
c19d1205 19078 /* Check that this instruction is supported for this CPU. */
62b3e311
PB
19079 if (!opcode->tvariant
19080 || (thumb_mode == 1
19081 && !ARM_CPU_HAS_FEATURE (variant, *opcode->tvariant)))
b99bd4ef 19082 {
173205ca
TP
19083 if (opcode->tencode == do_t_swi)
19084 as_bad (_("SVC is not permitted on this architecture"));
19085 else
19086 as_bad (_("selected processor does not support `%s' in Thumb mode"), str);
b99bd4ef
NC
19087 return;
19088 }
c19d1205
ZW
19089 if (inst.cond != COND_ALWAYS && !unified_syntax
19090 && opcode->tencode != do_t_branch)
b99bd4ef 19091 {
c19d1205 19092 as_bad (_("Thumb does not support conditional execution"));
b99bd4ef
NC
19093 return;
19094 }
19095
fc289b0a
TP
19096 /* Two things are addressed here:
19097 1) Implicit require narrow instructions on Thumb-1.
19098 This avoids relaxation accidentally introducing Thumb-2
19099 instructions.
19100 2) Reject wide instructions in non Thumb-2 cores.
19101
19102 Only instructions with narrow and wide variants need to be handled
19103 but selecting all non wide-only instructions is easier. */
19104 if (!ARM_CPU_HAS_FEATURE (variant, arm_ext_v6t2)
ff8646ee 19105 && !t32_insn_ok (variant, opcode))
076d447c 19106 {
fc289b0a
TP
19107 if (inst.size_req == 0)
19108 inst.size_req = 2;
19109 else if (inst.size_req == 4)
752d5da4 19110 {
ff8646ee
TP
19111 if (ARM_CPU_HAS_FEATURE (variant, arm_ext_v8m))
19112 as_bad (_("selected processor does not support 32bit wide "
19113 "variant of instruction `%s'"), str);
19114 else
19115 as_bad (_("selected processor does not support `%s' in "
19116 "Thumb-2 mode"), str);
fc289b0a 19117 return;
752d5da4 19118 }
076d447c
PB
19119 }
19120
c19d1205
ZW
19121 inst.instruction = opcode->tvalue;
19122
5be8be5d 19123 if (!parse_operands (p, opcode->operands, /*thumb=*/TRUE))
477330fc
RM
19124 {
19125 /* Prepare the it_insn_type for those encodings that don't set
19126 it. */
19127 it_fsm_pre_encode ();
c19d1205 19128
477330fc 19129 opcode->tencode ();
e07e6e58 19130
477330fc
RM
19131 it_fsm_post_encode ();
19132 }
e27ec89e 19133
0110f2b8 19134 if (!(inst.error || inst.relax))
b99bd4ef 19135 {
9c2799c2 19136 gas_assert (inst.instruction < 0xe800 || inst.instruction > 0xffff);
c19d1205
ZW
19137 inst.size = (inst.instruction > 0xffff ? 4 : 2);
19138 if (inst.size_req && inst.size_req != inst.size)
b99bd4ef 19139 {
c19d1205 19140 as_bad (_("cannot honor width suffix -- `%s'"), str);
b99bd4ef
NC
19141 return;
19142 }
19143 }
076d447c
PB
19144
19145 /* Something has gone badly wrong if we try to relax a fixed size
477330fc 19146 instruction. */
9c2799c2 19147 gas_assert (inst.size_req == 0 || !inst.relax);
076d447c 19148
e74cfd16
PB
19149 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
19150 *opcode->tvariant);
ee065d83 19151 /* Many Thumb-2 instructions also have Thumb-1 variants, so explicitly
fc289b0a
TP
19152 set those bits when Thumb-2 32-bit instructions are seen. The impact
19153 of relaxable instructions will be considered later after we finish all
19154 relaxation. */
ff8646ee
TP
19155 if (ARM_FEATURE_CORE_EQUAL (cpu_variant, arm_arch_any))
19156 variant = arm_arch_none;
19157 else
19158 variant = cpu_variant;
19159 if (inst.size == 4 && !t32_insn_ok (variant, opcode))
e74cfd16
PB
19160 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
19161 arm_ext_v6t2);
cd000bff 19162
88714cb8
DG
19163 check_neon_suffixes;
19164
cd000bff 19165 if (!inst.error)
c877a2f2
NC
19166 {
19167 mapping_state (MAP_THUMB);
19168 }
c19d1205 19169 }
3e9e4fcf 19170 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
c19d1205 19171 {
845b51d6
PB
19172 bfd_boolean is_bx;
19173
19174 /* bx is allowed on v5 cores, and sometimes on v4 cores. */
19175 is_bx = (opcode->aencode == do_bx);
19176
c19d1205 19177 /* Check that this instruction is supported for this CPU. */
845b51d6
PB
19178 if (!(is_bx && fix_v4bx)
19179 && !(opcode->avariant &&
19180 ARM_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant)))
b99bd4ef 19181 {
84b52b66 19182 as_bad (_("selected processor does not support `%s' in ARM mode"), str);
c19d1205 19183 return;
b99bd4ef 19184 }
c19d1205 19185 if (inst.size_req)
b99bd4ef 19186 {
c19d1205
ZW
19187 as_bad (_("width suffixes are invalid in ARM mode -- `%s'"), str);
19188 return;
b99bd4ef
NC
19189 }
19190
c19d1205
ZW
19191 inst.instruction = opcode->avalue;
19192 if (opcode->tag == OT_unconditionalF)
eff0bc54 19193 inst.instruction |= 0xFU << 28;
c19d1205
ZW
19194 else
19195 inst.instruction |= inst.cond << 28;
19196 inst.size = INSN_SIZE;
5be8be5d 19197 if (!parse_operands (p, opcode->operands, /*thumb=*/FALSE))
477330fc
RM
19198 {
19199 it_fsm_pre_encode ();
19200 opcode->aencode ();
19201 it_fsm_post_encode ();
19202 }
ee065d83 19203 /* Arm mode bx is marked as both v4T and v5 because it's still required
477330fc 19204 on a hypothetical non-thumb v5 core. */
845b51d6 19205 if (is_bx)
e74cfd16 19206 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, arm_ext_v4t);
ee065d83 19207 else
e74cfd16
PB
19208 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
19209 *opcode->avariant);
88714cb8
DG
19210
19211 check_neon_suffixes;
19212
cd000bff 19213 if (!inst.error)
c877a2f2
NC
19214 {
19215 mapping_state (MAP_ARM);
19216 }
b99bd4ef 19217 }
3e9e4fcf
JB
19218 else
19219 {
19220 as_bad (_("attempt to use an ARM instruction on a Thumb-only processor "
19221 "-- `%s'"), str);
19222 return;
19223 }
c19d1205
ZW
19224 output_inst (str);
19225}
b99bd4ef 19226
e07e6e58
NC
19227static void
19228check_it_blocks_finished (void)
19229{
19230#ifdef OBJ_ELF
19231 asection *sect;
19232
19233 for (sect = stdoutput->sections; sect != NULL; sect = sect->next)
19234 if (seg_info (sect)->tc_segment_info_data.current_it.state
19235 == MANUAL_IT_BLOCK)
19236 {
19237 as_warn (_("section '%s' finished with an open IT block."),
19238 sect->name);
19239 }
19240#else
19241 if (now_it.state == MANUAL_IT_BLOCK)
19242 as_warn (_("file finished with an open IT block."));
19243#endif
19244}
19245
c19d1205
ZW
19246/* Various frobbings of labels and their addresses. */
19247
19248void
19249arm_start_line_hook (void)
19250{
19251 last_label_seen = NULL;
b99bd4ef
NC
19252}
19253
c19d1205
ZW
19254void
19255arm_frob_label (symbolS * sym)
b99bd4ef 19256{
c19d1205 19257 last_label_seen = sym;
b99bd4ef 19258
c19d1205 19259 ARM_SET_THUMB (sym, thumb_mode);
b99bd4ef 19260
c19d1205
ZW
19261#if defined OBJ_COFF || defined OBJ_ELF
19262 ARM_SET_INTERWORK (sym, support_interwork);
19263#endif
b99bd4ef 19264
e07e6e58
NC
19265 force_automatic_it_block_close ();
19266
5f4273c7 19267 /* Note - do not allow local symbols (.Lxxx) to be labelled
c19d1205
ZW
19268 as Thumb functions. This is because these labels, whilst
19269 they exist inside Thumb code, are not the entry points for
19270 possible ARM->Thumb calls. Also, these labels can be used
19271 as part of a computed goto or switch statement. eg gcc
19272 can generate code that looks like this:
b99bd4ef 19273
c19d1205
ZW
19274 ldr r2, [pc, .Laaa]
19275 lsl r3, r3, #2
19276 ldr r2, [r3, r2]
19277 mov pc, r2
b99bd4ef 19278
c19d1205
ZW
19279 .Lbbb: .word .Lxxx
19280 .Lccc: .word .Lyyy
19281 ..etc...
19282 .Laaa: .word Lbbb
b99bd4ef 19283
c19d1205
ZW
19284 The first instruction loads the address of the jump table.
19285 The second instruction converts a table index into a byte offset.
19286 The third instruction gets the jump address out of the table.
19287 The fourth instruction performs the jump.
b99bd4ef 19288
c19d1205
ZW
19289 If the address stored at .Laaa is that of a symbol which has the
19290 Thumb_Func bit set, then the linker will arrange for this address
19291 to have the bottom bit set, which in turn would mean that the
19292 address computation performed by the third instruction would end
19293 up with the bottom bit set. Since the ARM is capable of unaligned
19294 word loads, the instruction would then load the incorrect address
19295 out of the jump table, and chaos would ensue. */
19296 if (label_is_thumb_function_name
19297 && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
19298 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
b99bd4ef 19299 {
c19d1205
ZW
19300 /* When the address of a Thumb function is taken the bottom
19301 bit of that address should be set. This will allow
19302 interworking between Arm and Thumb functions to work
19303 correctly. */
b99bd4ef 19304
c19d1205 19305 THUMB_SET_FUNC (sym, 1);
b99bd4ef 19306
c19d1205 19307 label_is_thumb_function_name = FALSE;
b99bd4ef 19308 }
07a53e5c 19309
07a53e5c 19310 dwarf2_emit_label (sym);
b99bd4ef
NC
19311}
19312
c921be7d 19313bfd_boolean
c19d1205 19314arm_data_in_code (void)
b99bd4ef 19315{
c19d1205 19316 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
b99bd4ef 19317 {
c19d1205
ZW
19318 *input_line_pointer = '/';
19319 input_line_pointer += 5;
19320 *input_line_pointer = 0;
c921be7d 19321 return TRUE;
b99bd4ef
NC
19322 }
19323
c921be7d 19324 return FALSE;
b99bd4ef
NC
19325}
19326
c19d1205
ZW
19327char *
19328arm_canonicalize_symbol_name (char * name)
b99bd4ef 19329{
c19d1205 19330 int len;
b99bd4ef 19331
c19d1205
ZW
19332 if (thumb_mode && (len = strlen (name)) > 5
19333 && streq (name + len - 5, "/data"))
19334 *(name + len - 5) = 0;
b99bd4ef 19335
c19d1205 19336 return name;
b99bd4ef 19337}
c19d1205
ZW
19338\f
19339/* Table of all register names defined by default. The user can
19340 define additional names with .req. Note that all register names
19341 should appear in both upper and lowercase variants. Some registers
19342 also have mixed-case names. */
b99bd4ef 19343
dcbf9037 19344#define REGDEF(s,n,t) { #s, n, REG_TYPE_##t, TRUE, 0 }
c19d1205 19345#define REGNUM(p,n,t) REGDEF(p##n, n, t)
5287ad62 19346#define REGNUM2(p,n,t) REGDEF(p##n, 2 * n, t)
c19d1205
ZW
19347#define REGSET(p,t) \
19348 REGNUM(p, 0,t), REGNUM(p, 1,t), REGNUM(p, 2,t), REGNUM(p, 3,t), \
19349 REGNUM(p, 4,t), REGNUM(p, 5,t), REGNUM(p, 6,t), REGNUM(p, 7,t), \
19350 REGNUM(p, 8,t), REGNUM(p, 9,t), REGNUM(p,10,t), REGNUM(p,11,t), \
19351 REGNUM(p,12,t), REGNUM(p,13,t), REGNUM(p,14,t), REGNUM(p,15,t)
5287ad62
JB
19352#define REGSETH(p,t) \
19353 REGNUM(p,16,t), REGNUM(p,17,t), REGNUM(p,18,t), REGNUM(p,19,t), \
19354 REGNUM(p,20,t), REGNUM(p,21,t), REGNUM(p,22,t), REGNUM(p,23,t), \
19355 REGNUM(p,24,t), REGNUM(p,25,t), REGNUM(p,26,t), REGNUM(p,27,t), \
19356 REGNUM(p,28,t), REGNUM(p,29,t), REGNUM(p,30,t), REGNUM(p,31,t)
19357#define REGSET2(p,t) \
19358 REGNUM2(p, 0,t), REGNUM2(p, 1,t), REGNUM2(p, 2,t), REGNUM2(p, 3,t), \
19359 REGNUM2(p, 4,t), REGNUM2(p, 5,t), REGNUM2(p, 6,t), REGNUM2(p, 7,t), \
19360 REGNUM2(p, 8,t), REGNUM2(p, 9,t), REGNUM2(p,10,t), REGNUM2(p,11,t), \
19361 REGNUM2(p,12,t), REGNUM2(p,13,t), REGNUM2(p,14,t), REGNUM2(p,15,t)
90ec0d68
MGD
19362#define SPLRBANK(base,bank,t) \
19363 REGDEF(lr_##bank, 768|((base+0)<<16), t), \
19364 REGDEF(sp_##bank, 768|((base+1)<<16), t), \
19365 REGDEF(spsr_##bank, 768|(base<<16)|SPSR_BIT, t), \
19366 REGDEF(LR_##bank, 768|((base+0)<<16), t), \
19367 REGDEF(SP_##bank, 768|((base+1)<<16), t), \
19368 REGDEF(SPSR_##bank, 768|(base<<16)|SPSR_BIT, t)
7ed4c4c5 19369
c19d1205 19370static const struct reg_entry reg_names[] =
7ed4c4c5 19371{
c19d1205
ZW
19372 /* ARM integer registers. */
19373 REGSET(r, RN), REGSET(R, RN),
7ed4c4c5 19374
c19d1205
ZW
19375 /* ATPCS synonyms. */
19376 REGDEF(a1,0,RN), REGDEF(a2,1,RN), REGDEF(a3, 2,RN), REGDEF(a4, 3,RN),
19377 REGDEF(v1,4,RN), REGDEF(v2,5,RN), REGDEF(v3, 6,RN), REGDEF(v4, 7,RN),
19378 REGDEF(v5,8,RN), REGDEF(v6,9,RN), REGDEF(v7,10,RN), REGDEF(v8,11,RN),
7ed4c4c5 19379
c19d1205
ZW
19380 REGDEF(A1,0,RN), REGDEF(A2,1,RN), REGDEF(A3, 2,RN), REGDEF(A4, 3,RN),
19381 REGDEF(V1,4,RN), REGDEF(V2,5,RN), REGDEF(V3, 6,RN), REGDEF(V4, 7,RN),
19382 REGDEF(V5,8,RN), REGDEF(V6,9,RN), REGDEF(V7,10,RN), REGDEF(V8,11,RN),
7ed4c4c5 19383
c19d1205
ZW
19384 /* Well-known aliases. */
19385 REGDEF(wr, 7,RN), REGDEF(sb, 9,RN), REGDEF(sl,10,RN), REGDEF(fp,11,RN),
19386 REGDEF(ip,12,RN), REGDEF(sp,13,RN), REGDEF(lr,14,RN), REGDEF(pc,15,RN),
19387
19388 REGDEF(WR, 7,RN), REGDEF(SB, 9,RN), REGDEF(SL,10,RN), REGDEF(FP,11,RN),
19389 REGDEF(IP,12,RN), REGDEF(SP,13,RN), REGDEF(LR,14,RN), REGDEF(PC,15,RN),
19390
19391 /* Coprocessor numbers. */
19392 REGSET(p, CP), REGSET(P, CP),
19393
19394 /* Coprocessor register numbers. The "cr" variants are for backward
19395 compatibility. */
19396 REGSET(c, CN), REGSET(C, CN),
19397 REGSET(cr, CN), REGSET(CR, CN),
19398
90ec0d68
MGD
19399 /* ARM banked registers. */
19400 REGDEF(R8_usr,512|(0<<16),RNB), REGDEF(r8_usr,512|(0<<16),RNB),
19401 REGDEF(R9_usr,512|(1<<16),RNB), REGDEF(r9_usr,512|(1<<16),RNB),
19402 REGDEF(R10_usr,512|(2<<16),RNB), REGDEF(r10_usr,512|(2<<16),RNB),
19403 REGDEF(R11_usr,512|(3<<16),RNB), REGDEF(r11_usr,512|(3<<16),RNB),
19404 REGDEF(R12_usr,512|(4<<16),RNB), REGDEF(r12_usr,512|(4<<16),RNB),
19405 REGDEF(SP_usr,512|(5<<16),RNB), REGDEF(sp_usr,512|(5<<16),RNB),
19406 REGDEF(LR_usr,512|(6<<16),RNB), REGDEF(lr_usr,512|(6<<16),RNB),
19407
19408 REGDEF(R8_fiq,512|(8<<16),RNB), REGDEF(r8_fiq,512|(8<<16),RNB),
19409 REGDEF(R9_fiq,512|(9<<16),RNB), REGDEF(r9_fiq,512|(9<<16),RNB),
19410 REGDEF(R10_fiq,512|(10<<16),RNB), REGDEF(r10_fiq,512|(10<<16),RNB),
19411 REGDEF(R11_fiq,512|(11<<16),RNB), REGDEF(r11_fiq,512|(11<<16),RNB),
19412 REGDEF(R12_fiq,512|(12<<16),RNB), REGDEF(r12_fiq,512|(12<<16),RNB),
1472d06f 19413 REGDEF(SP_fiq,512|(13<<16),RNB), REGDEF(sp_fiq,512|(13<<16),RNB),
90ec0d68
MGD
19414 REGDEF(LR_fiq,512|(14<<16),RNB), REGDEF(lr_fiq,512|(14<<16),RNB),
19415 REGDEF(SPSR_fiq,512|(14<<16)|SPSR_BIT,RNB), REGDEF(spsr_fiq,512|(14<<16)|SPSR_BIT,RNB),
19416
19417 SPLRBANK(0,IRQ,RNB), SPLRBANK(0,irq,RNB),
19418 SPLRBANK(2,SVC,RNB), SPLRBANK(2,svc,RNB),
19419 SPLRBANK(4,ABT,RNB), SPLRBANK(4,abt,RNB),
19420 SPLRBANK(6,UND,RNB), SPLRBANK(6,und,RNB),
19421 SPLRBANK(12,MON,RNB), SPLRBANK(12,mon,RNB),
19422 REGDEF(elr_hyp,768|(14<<16),RNB), REGDEF(ELR_hyp,768|(14<<16),RNB),
19423 REGDEF(sp_hyp,768|(15<<16),RNB), REGDEF(SP_hyp,768|(15<<16),RNB),
fa94de6b 19424 REGDEF(spsr_hyp,768|(14<<16)|SPSR_BIT,RNB),
90ec0d68
MGD
19425 REGDEF(SPSR_hyp,768|(14<<16)|SPSR_BIT,RNB),
19426
c19d1205
ZW
19427 /* FPA registers. */
19428 REGNUM(f,0,FN), REGNUM(f,1,FN), REGNUM(f,2,FN), REGNUM(f,3,FN),
19429 REGNUM(f,4,FN), REGNUM(f,5,FN), REGNUM(f,6,FN), REGNUM(f,7, FN),
19430
19431 REGNUM(F,0,FN), REGNUM(F,1,FN), REGNUM(F,2,FN), REGNUM(F,3,FN),
19432 REGNUM(F,4,FN), REGNUM(F,5,FN), REGNUM(F,6,FN), REGNUM(F,7, FN),
19433
19434 /* VFP SP registers. */
5287ad62
JB
19435 REGSET(s,VFS), REGSET(S,VFS),
19436 REGSETH(s,VFS), REGSETH(S,VFS),
c19d1205
ZW
19437
19438 /* VFP DP Registers. */
5287ad62
JB
19439 REGSET(d,VFD), REGSET(D,VFD),
19440 /* Extra Neon DP registers. */
19441 REGSETH(d,VFD), REGSETH(D,VFD),
19442
19443 /* Neon QP registers. */
19444 REGSET2(q,NQ), REGSET2(Q,NQ),
c19d1205
ZW
19445
19446 /* VFP control registers. */
19447 REGDEF(fpsid,0,VFC), REGDEF(fpscr,1,VFC), REGDEF(fpexc,8,VFC),
19448 REGDEF(FPSID,0,VFC), REGDEF(FPSCR,1,VFC), REGDEF(FPEXC,8,VFC),
cd2cf30b
PB
19449 REGDEF(fpinst,9,VFC), REGDEF(fpinst2,10,VFC),
19450 REGDEF(FPINST,9,VFC), REGDEF(FPINST2,10,VFC),
19451 REGDEF(mvfr0,7,VFC), REGDEF(mvfr1,6,VFC),
19452 REGDEF(MVFR0,7,VFC), REGDEF(MVFR1,6,VFC),
40c7d507 19453 REGDEF(mvfr2,5,VFC), REGDEF(MVFR2,5,VFC),
c19d1205
ZW
19454
19455 /* Maverick DSP coprocessor registers. */
19456 REGSET(mvf,MVF), REGSET(mvd,MVD), REGSET(mvfx,MVFX), REGSET(mvdx,MVDX),
19457 REGSET(MVF,MVF), REGSET(MVD,MVD), REGSET(MVFX,MVFX), REGSET(MVDX,MVDX),
19458
19459 REGNUM(mvax,0,MVAX), REGNUM(mvax,1,MVAX),
19460 REGNUM(mvax,2,MVAX), REGNUM(mvax,3,MVAX),
19461 REGDEF(dspsc,0,DSPSC),
19462
19463 REGNUM(MVAX,0,MVAX), REGNUM(MVAX,1,MVAX),
19464 REGNUM(MVAX,2,MVAX), REGNUM(MVAX,3,MVAX),
19465 REGDEF(DSPSC,0,DSPSC),
19466
19467 /* iWMMXt data registers - p0, c0-15. */
19468 REGSET(wr,MMXWR), REGSET(wR,MMXWR), REGSET(WR, MMXWR),
19469
19470 /* iWMMXt control registers - p1, c0-3. */
19471 REGDEF(wcid, 0,MMXWC), REGDEF(wCID, 0,MMXWC), REGDEF(WCID, 0,MMXWC),
19472 REGDEF(wcon, 1,MMXWC), REGDEF(wCon, 1,MMXWC), REGDEF(WCON, 1,MMXWC),
19473 REGDEF(wcssf, 2,MMXWC), REGDEF(wCSSF, 2,MMXWC), REGDEF(WCSSF, 2,MMXWC),
19474 REGDEF(wcasf, 3,MMXWC), REGDEF(wCASF, 3,MMXWC), REGDEF(WCASF, 3,MMXWC),
19475
19476 /* iWMMXt scalar (constant/offset) registers - p1, c8-11. */
19477 REGDEF(wcgr0, 8,MMXWCG), REGDEF(wCGR0, 8,MMXWCG), REGDEF(WCGR0, 8,MMXWCG),
19478 REGDEF(wcgr1, 9,MMXWCG), REGDEF(wCGR1, 9,MMXWCG), REGDEF(WCGR1, 9,MMXWCG),
19479 REGDEF(wcgr2,10,MMXWCG), REGDEF(wCGR2,10,MMXWCG), REGDEF(WCGR2,10,MMXWCG),
19480 REGDEF(wcgr3,11,MMXWCG), REGDEF(wCGR3,11,MMXWCG), REGDEF(WCGR3,11,MMXWCG),
19481
19482 /* XScale accumulator registers. */
19483 REGNUM(acc,0,XSCALE), REGNUM(ACC,0,XSCALE),
19484};
19485#undef REGDEF
19486#undef REGNUM
19487#undef REGSET
7ed4c4c5 19488
c19d1205
ZW
19489/* Table of all PSR suffixes. Bare "CPSR" and "SPSR" are handled
19490 within psr_required_here. */
19491static const struct asm_psr psrs[] =
19492{
19493 /* Backward compatibility notation. Note that "all" is no longer
19494 truly all possible PSR bits. */
19495 {"all", PSR_c | PSR_f},
19496 {"flg", PSR_f},
19497 {"ctl", PSR_c},
19498
19499 /* Individual flags. */
19500 {"f", PSR_f},
19501 {"c", PSR_c},
19502 {"x", PSR_x},
19503 {"s", PSR_s},
59b42a0d 19504
c19d1205
ZW
19505 /* Combinations of flags. */
19506 {"fs", PSR_f | PSR_s},
19507 {"fx", PSR_f | PSR_x},
19508 {"fc", PSR_f | PSR_c},
19509 {"sf", PSR_s | PSR_f},
19510 {"sx", PSR_s | PSR_x},
19511 {"sc", PSR_s | PSR_c},
19512 {"xf", PSR_x | PSR_f},
19513 {"xs", PSR_x | PSR_s},
19514 {"xc", PSR_x | PSR_c},
19515 {"cf", PSR_c | PSR_f},
19516 {"cs", PSR_c | PSR_s},
19517 {"cx", PSR_c | PSR_x},
19518 {"fsx", PSR_f | PSR_s | PSR_x},
19519 {"fsc", PSR_f | PSR_s | PSR_c},
19520 {"fxs", PSR_f | PSR_x | PSR_s},
19521 {"fxc", PSR_f | PSR_x | PSR_c},
19522 {"fcs", PSR_f | PSR_c | PSR_s},
19523 {"fcx", PSR_f | PSR_c | PSR_x},
19524 {"sfx", PSR_s | PSR_f | PSR_x},
19525 {"sfc", PSR_s | PSR_f | PSR_c},
19526 {"sxf", PSR_s | PSR_x | PSR_f},
19527 {"sxc", PSR_s | PSR_x | PSR_c},
19528 {"scf", PSR_s | PSR_c | PSR_f},
19529 {"scx", PSR_s | PSR_c | PSR_x},
19530 {"xfs", PSR_x | PSR_f | PSR_s},
19531 {"xfc", PSR_x | PSR_f | PSR_c},
19532 {"xsf", PSR_x | PSR_s | PSR_f},
19533 {"xsc", PSR_x | PSR_s | PSR_c},
19534 {"xcf", PSR_x | PSR_c | PSR_f},
19535 {"xcs", PSR_x | PSR_c | PSR_s},
19536 {"cfs", PSR_c | PSR_f | PSR_s},
19537 {"cfx", PSR_c | PSR_f | PSR_x},
19538 {"csf", PSR_c | PSR_s | PSR_f},
19539 {"csx", PSR_c | PSR_s | PSR_x},
19540 {"cxf", PSR_c | PSR_x | PSR_f},
19541 {"cxs", PSR_c | PSR_x | PSR_s},
19542 {"fsxc", PSR_f | PSR_s | PSR_x | PSR_c},
19543 {"fscx", PSR_f | PSR_s | PSR_c | PSR_x},
19544 {"fxsc", PSR_f | PSR_x | PSR_s | PSR_c},
19545 {"fxcs", PSR_f | PSR_x | PSR_c | PSR_s},
19546 {"fcsx", PSR_f | PSR_c | PSR_s | PSR_x},
19547 {"fcxs", PSR_f | PSR_c | PSR_x | PSR_s},
19548 {"sfxc", PSR_s | PSR_f | PSR_x | PSR_c},
19549 {"sfcx", PSR_s | PSR_f | PSR_c | PSR_x},
19550 {"sxfc", PSR_s | PSR_x | PSR_f | PSR_c},
19551 {"sxcf", PSR_s | PSR_x | PSR_c | PSR_f},
19552 {"scfx", PSR_s | PSR_c | PSR_f | PSR_x},
19553 {"scxf", PSR_s | PSR_c | PSR_x | PSR_f},
19554 {"xfsc", PSR_x | PSR_f | PSR_s | PSR_c},
19555 {"xfcs", PSR_x | PSR_f | PSR_c | PSR_s},
19556 {"xsfc", PSR_x | PSR_s | PSR_f | PSR_c},
19557 {"xscf", PSR_x | PSR_s | PSR_c | PSR_f},
19558 {"xcfs", PSR_x | PSR_c | PSR_f | PSR_s},
19559 {"xcsf", PSR_x | PSR_c | PSR_s | PSR_f},
19560 {"cfsx", PSR_c | PSR_f | PSR_s | PSR_x},
19561 {"cfxs", PSR_c | PSR_f | PSR_x | PSR_s},
19562 {"csfx", PSR_c | PSR_s | PSR_f | PSR_x},
19563 {"csxf", PSR_c | PSR_s | PSR_x | PSR_f},
19564 {"cxfs", PSR_c | PSR_x | PSR_f | PSR_s},
19565 {"cxsf", PSR_c | PSR_x | PSR_s | PSR_f},
19566};
19567
62b3e311
PB
19568/* Table of V7M psr names. */
19569static const struct asm_psr v7m_psrs[] =
19570{
1a336194
TP
19571 {"apsr", 0x0 }, {"APSR", 0x0 },
19572 {"iapsr", 0x1 }, {"IAPSR", 0x1 },
19573 {"eapsr", 0x2 }, {"EAPSR", 0x2 },
19574 {"psr", 0x3 }, {"PSR", 0x3 },
19575 {"xpsr", 0x3 }, {"XPSR", 0x3 }, {"xPSR", 3 },
19576 {"ipsr", 0x5 }, {"IPSR", 0x5 },
19577 {"epsr", 0x6 }, {"EPSR", 0x6 },
19578 {"iepsr", 0x7 }, {"IEPSR", 0x7 },
19579 {"msp", 0x8 }, {"MSP", 0x8 },
19580 {"psp", 0x9 }, {"PSP", 0x9 },
19581 {"msplim", 0xa }, {"MSPLIM", 0xa },
19582 {"psplim", 0xb }, {"PSPLIM", 0xb },
19583 {"primask", 0x10}, {"PRIMASK", 0x10},
19584 {"basepri", 0x11}, {"BASEPRI", 0x11},
19585 {"basepri_max", 0x12}, {"BASEPRI_MAX", 0x12},
1a336194
TP
19586 {"faultmask", 0x13}, {"FAULTMASK", 0x13},
19587 {"control", 0x14}, {"CONTROL", 0x14},
19588 {"msp_ns", 0x88}, {"MSP_NS", 0x88},
19589 {"psp_ns", 0x89}, {"PSP_NS", 0x89},
19590 {"msplim_ns", 0x8a}, {"MSPLIM_NS", 0x8a},
19591 {"psplim_ns", 0x8b}, {"PSPLIM_NS", 0x8b},
19592 {"primask_ns", 0x90}, {"PRIMASK_NS", 0x90},
19593 {"basepri_ns", 0x91}, {"BASEPRI_NS", 0x91},
19594 {"faultmask_ns", 0x93}, {"FAULTMASK_NS", 0x93},
19595 {"control_ns", 0x94}, {"CONTROL_NS", 0x94},
19596 {"sp_ns", 0x98}, {"SP_NS", 0x98 }
62b3e311
PB
19597};
19598
c19d1205
ZW
19599/* Table of all shift-in-operand names. */
19600static const struct asm_shift_name shift_names [] =
b99bd4ef 19601{
c19d1205
ZW
19602 { "asl", SHIFT_LSL }, { "ASL", SHIFT_LSL },
19603 { "lsl", SHIFT_LSL }, { "LSL", SHIFT_LSL },
19604 { "lsr", SHIFT_LSR }, { "LSR", SHIFT_LSR },
19605 { "asr", SHIFT_ASR }, { "ASR", SHIFT_ASR },
19606 { "ror", SHIFT_ROR }, { "ROR", SHIFT_ROR },
19607 { "rrx", SHIFT_RRX }, { "RRX", SHIFT_RRX }
19608};
b99bd4ef 19609
c19d1205
ZW
19610/* Table of all explicit relocation names. */
19611#ifdef OBJ_ELF
19612static struct reloc_entry reloc_names[] =
19613{
19614 { "got", BFD_RELOC_ARM_GOT32 }, { "GOT", BFD_RELOC_ARM_GOT32 },
19615 { "gotoff", BFD_RELOC_ARM_GOTOFF }, { "GOTOFF", BFD_RELOC_ARM_GOTOFF },
19616 { "plt", BFD_RELOC_ARM_PLT32 }, { "PLT", BFD_RELOC_ARM_PLT32 },
19617 { "target1", BFD_RELOC_ARM_TARGET1 }, { "TARGET1", BFD_RELOC_ARM_TARGET1 },
19618 { "target2", BFD_RELOC_ARM_TARGET2 }, { "TARGET2", BFD_RELOC_ARM_TARGET2 },
19619 { "sbrel", BFD_RELOC_ARM_SBREL32 }, { "SBREL", BFD_RELOC_ARM_SBREL32 },
19620 { "tlsgd", BFD_RELOC_ARM_TLS_GD32}, { "TLSGD", BFD_RELOC_ARM_TLS_GD32},
19621 { "tlsldm", BFD_RELOC_ARM_TLS_LDM32}, { "TLSLDM", BFD_RELOC_ARM_TLS_LDM32},
19622 { "tlsldo", BFD_RELOC_ARM_TLS_LDO32}, { "TLSLDO", BFD_RELOC_ARM_TLS_LDO32},
19623 { "gottpoff",BFD_RELOC_ARM_TLS_IE32}, { "GOTTPOFF",BFD_RELOC_ARM_TLS_IE32},
b43420e6 19624 { "tpoff", BFD_RELOC_ARM_TLS_LE32}, { "TPOFF", BFD_RELOC_ARM_TLS_LE32},
0855e32b
NS
19625 { "got_prel", BFD_RELOC_ARM_GOT_PREL}, { "GOT_PREL", BFD_RELOC_ARM_GOT_PREL},
19626 { "tlsdesc", BFD_RELOC_ARM_TLS_GOTDESC},
477330fc 19627 { "TLSDESC", BFD_RELOC_ARM_TLS_GOTDESC},
0855e32b 19628 { "tlscall", BFD_RELOC_ARM_TLS_CALL},
477330fc 19629 { "TLSCALL", BFD_RELOC_ARM_TLS_CALL},
0855e32b 19630 { "tlsdescseq", BFD_RELOC_ARM_TLS_DESCSEQ},
188fd7ae
CL
19631 { "TLSDESCSEQ", BFD_RELOC_ARM_TLS_DESCSEQ},
19632 { "gotfuncdesc", BFD_RELOC_ARM_GOTFUNCDESC },
19633 { "GOTFUNCDESC", BFD_RELOC_ARM_GOTFUNCDESC },
19634 { "gotofffuncdesc", BFD_RELOC_ARM_GOTOFFFUNCDESC },
19635 { "GOTOFFFUNCDESC", BFD_RELOC_ARM_GOTOFFFUNCDESC },
19636 { "funcdesc", BFD_RELOC_ARM_FUNCDESC },
5c5a4843
CL
19637 { "FUNCDESC", BFD_RELOC_ARM_FUNCDESC },
19638 { "tlsgd_fdpic", BFD_RELOC_ARM_TLS_GD32_FDPIC }, { "TLSGD_FDPIC", BFD_RELOC_ARM_TLS_GD32_FDPIC },
19639 { "tlsldm_fdpic", BFD_RELOC_ARM_TLS_LDM32_FDPIC }, { "TLSLDM_FDPIC", BFD_RELOC_ARM_TLS_LDM32_FDPIC },
19640 { "gottpoff_fdpic", BFD_RELOC_ARM_TLS_IE32_FDPIC }, { "GOTTPOFF_FDIC", BFD_RELOC_ARM_TLS_IE32_FDPIC },
c19d1205
ZW
19641};
19642#endif
b99bd4ef 19643
c19d1205
ZW
19644/* Table of all conditional affixes. 0xF is not defined as a condition code. */
19645static const struct asm_cond conds[] =
19646{
19647 {"eq", 0x0},
19648 {"ne", 0x1},
19649 {"cs", 0x2}, {"hs", 0x2},
19650 {"cc", 0x3}, {"ul", 0x3}, {"lo", 0x3},
19651 {"mi", 0x4},
19652 {"pl", 0x5},
19653 {"vs", 0x6},
19654 {"vc", 0x7},
19655 {"hi", 0x8},
19656 {"ls", 0x9},
19657 {"ge", 0xa},
19658 {"lt", 0xb},
19659 {"gt", 0xc},
19660 {"le", 0xd},
19661 {"al", 0xe}
19662};
bfae80f2 19663
e797f7e0 19664#define UL_BARRIER(L,U,CODE,FEAT) \
823d2571
TG
19665 { L, CODE, ARM_FEATURE_CORE_LOW (FEAT) }, \
19666 { U, CODE, ARM_FEATURE_CORE_LOW (FEAT) }
e797f7e0 19667
62b3e311
PB
19668static struct asm_barrier_opt barrier_opt_names[] =
19669{
e797f7e0
MGD
19670 UL_BARRIER ("sy", "SY", 0xf, ARM_EXT_BARRIER),
19671 UL_BARRIER ("st", "ST", 0xe, ARM_EXT_BARRIER),
19672 UL_BARRIER ("ld", "LD", 0xd, ARM_EXT_V8),
19673 UL_BARRIER ("ish", "ISH", 0xb, ARM_EXT_BARRIER),
19674 UL_BARRIER ("sh", "SH", 0xb, ARM_EXT_BARRIER),
19675 UL_BARRIER ("ishst", "ISHST", 0xa, ARM_EXT_BARRIER),
19676 UL_BARRIER ("shst", "SHST", 0xa, ARM_EXT_BARRIER),
19677 UL_BARRIER ("ishld", "ISHLD", 0x9, ARM_EXT_V8),
19678 UL_BARRIER ("un", "UN", 0x7, ARM_EXT_BARRIER),
19679 UL_BARRIER ("nsh", "NSH", 0x7, ARM_EXT_BARRIER),
19680 UL_BARRIER ("unst", "UNST", 0x6, ARM_EXT_BARRIER),
19681 UL_BARRIER ("nshst", "NSHST", 0x6, ARM_EXT_BARRIER),
19682 UL_BARRIER ("nshld", "NSHLD", 0x5, ARM_EXT_V8),
19683 UL_BARRIER ("osh", "OSH", 0x3, ARM_EXT_BARRIER),
19684 UL_BARRIER ("oshst", "OSHST", 0x2, ARM_EXT_BARRIER),
19685 UL_BARRIER ("oshld", "OSHLD", 0x1, ARM_EXT_V8)
62b3e311
PB
19686};
19687
e797f7e0
MGD
19688#undef UL_BARRIER
19689
c19d1205
ZW
19690/* Table of ARM-format instructions. */
19691
19692/* Macros for gluing together operand strings. N.B. In all cases
19693 other than OPS0, the trailing OP_stop comes from default
19694 zero-initialization of the unspecified elements of the array. */
19695#define OPS0() { OP_stop, }
19696#define OPS1(a) { OP_##a, }
19697#define OPS2(a,b) { OP_##a,OP_##b, }
19698#define OPS3(a,b,c) { OP_##a,OP_##b,OP_##c, }
19699#define OPS4(a,b,c,d) { OP_##a,OP_##b,OP_##c,OP_##d, }
19700#define OPS5(a,b,c,d,e) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e, }
19701#define OPS6(a,b,c,d,e,f) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e,OP_##f, }
19702
5be8be5d
DG
19703/* These macros are similar to the OPSn, but do not prepend the OP_ prefix.
19704 This is useful when mixing operands for ARM and THUMB, i.e. using the
19705 MIX_ARM_THUMB_OPERANDS macro.
19706 In order to use these macros, prefix the number of operands with _
19707 e.g. _3. */
19708#define OPS_1(a) { a, }
19709#define OPS_2(a,b) { a,b, }
19710#define OPS_3(a,b,c) { a,b,c, }
19711#define OPS_4(a,b,c,d) { a,b,c,d, }
19712#define OPS_5(a,b,c,d,e) { a,b,c,d,e, }
19713#define OPS_6(a,b,c,d,e,f) { a,b,c,d,e,f, }
19714
c19d1205
ZW
19715/* These macros abstract out the exact format of the mnemonic table and
19716 save some repeated characters. */
19717
19718/* The normal sort of mnemonic; has a Thumb variant; takes a conditional suffix. */
19719#define TxCE(mnem, op, top, nops, ops, ae, te) \
21d799b5 19720 { mnem, OPS##nops ops, OT_csuffix, 0x##op, top, ARM_VARIANT, \
1887dd22 19721 THUMB_VARIANT, do_##ae, do_##te }
c19d1205
ZW
19722
19723/* Two variants of the above - TCE for a numeric Thumb opcode, tCE for
19724 a T_MNEM_xyz enumerator. */
19725#define TCE(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 19726 TxCE (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 19727#define tCE(mnem, aop, top, nops, ops, ae, te) \
21d799b5 19728 TxCE (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205
ZW
19729
19730/* Second most common sort of mnemonic: has a Thumb variant, takes a conditional
19731 infix after the third character. */
19732#define TxC3(mnem, op, top, nops, ops, ae, te) \
21d799b5 19733 { mnem, OPS##nops ops, OT_cinfix3, 0x##op, top, ARM_VARIANT, \
1887dd22 19734 THUMB_VARIANT, do_##ae, do_##te }
088fa78e 19735#define TxC3w(mnem, op, top, nops, ops, ae, te) \
21d799b5 19736 { mnem, OPS##nops ops, OT_cinfix3_deprecated, 0x##op, top, ARM_VARIANT, \
088fa78e 19737 THUMB_VARIANT, do_##ae, do_##te }
c19d1205 19738#define TC3(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 19739 TxC3 (mnem, aop, 0x##top, nops, ops, ae, te)
088fa78e 19740#define TC3w(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 19741 TxC3w (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 19742#define tC3(mnem, aop, top, nops, ops, ae, te) \
21d799b5 19743 TxC3 (mnem, aop, T_MNEM##top, nops, ops, ae, te)
088fa78e 19744#define tC3w(mnem, aop, top, nops, ops, ae, te) \
21d799b5 19745 TxC3w (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205 19746
c19d1205 19747/* Mnemonic that cannot be conditionalized. The ARM condition-code
dfa9f0d5
PB
19748 field is still 0xE. Many of the Thumb variants can be executed
19749 conditionally, so this is checked separately. */
c19d1205 19750#define TUE(mnem, op, top, nops, ops, ae, te) \
21d799b5 19751 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
1887dd22 19752 THUMB_VARIANT, do_##ae, do_##te }
c19d1205 19753
dd5181d5
KT
19754/* Same as TUE but the encoding function for ARM and Thumb modes is the same.
19755 Used by mnemonics that have very minimal differences in the encoding for
19756 ARM and Thumb variants and can be handled in a common function. */
19757#define TUEc(mnem, op, top, nops, ops, en) \
19758 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
19759 THUMB_VARIANT, do_##en, do_##en }
19760
c19d1205
ZW
19761/* Mnemonic that cannot be conditionalized, and bears 0xF in its ARM
19762 condition code field. */
19763#define TUF(mnem, op, top, nops, ops, ae, te) \
21d799b5 19764 { mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##top, ARM_VARIANT, \
1887dd22 19765 THUMB_VARIANT, do_##ae, do_##te }
c19d1205
ZW
19766
19767/* ARM-only variants of all the above. */
6a86118a 19768#define CE(mnem, op, nops, ops, ae) \
21d799b5 19769 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
6a86118a
NC
19770
19771#define C3(mnem, op, nops, ops, ae) \
19772 { #mnem, OPS##nops ops, OT_cinfix3, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
19773
cf3cf39d
TP
19774/* Thumb-only variants of TCE and TUE. */
19775#define ToC(mnem, top, nops, ops, te) \
19776 { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
19777 do_##te }
cf3cf39d
TP
19778
19779#define ToU(mnem, top, nops, ops, te) \
19780 { mnem, OPS##nops ops, OT_unconditional, 0x0, 0x##top, 0, THUMB_VARIANT, \
19781 NULL, do_##te }
cf3cf39d 19782
4389b29a
AV
19783/* T_MNEM_xyz enumerator variants of ToC. */
19784#define toC(mnem, top, nops, ops, te) \
19785 { mnem, OPS##nops ops, OT_csuffix, 0x0, T_MNEM##top, 0, THUMB_VARIANT, NULL, \
19786 do_##te }
19787
f6b2b12d
AV
19788/* T_MNEM_xyz enumerator variants of ToU. */
19789#define toU(mnem, top, nops, ops, te) \
19790 { mnem, OPS##nops ops, OT_unconditional, 0x0, T_MNEM##top, 0, THUMB_VARIANT, \
19791 NULL, do_##te }
19792
e3cb604e
PB
19793/* Legacy mnemonics that always have conditional infix after the third
19794 character. */
19795#define CL(mnem, op, nops, ops, ae) \
21d799b5 19796 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
e3cb604e
PB
19797 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
19798
8f06b2d8
PB
19799/* Coprocessor instructions. Isomorphic between Arm and Thumb-2. */
19800#define cCE(mnem, op, nops, ops, ae) \
21d799b5 19801 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae }
8f06b2d8 19802
e3cb604e
PB
19803/* Legacy coprocessor instructions where conditional infix and conditional
19804 suffix are ambiguous. For consistency this includes all FPA instructions,
19805 not just the potentially ambiguous ones. */
19806#define cCL(mnem, op, nops, ops, ae) \
21d799b5 19807 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
e3cb604e
PB
19808 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae }
19809
19810/* Coprocessor, takes either a suffix or a position-3 infix
19811 (for an FPA corner case). */
19812#define C3E(mnem, op, nops, ops, ae) \
21d799b5 19813 { mnem, OPS##nops ops, OT_csuf_or_in3, \
e3cb604e 19814 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae }
8f06b2d8 19815
6a86118a 19816#define xCM_(m1, m2, m3, op, nops, ops, ae) \
21d799b5
NC
19817 { m1 #m2 m3, OPS##nops ops, \
19818 sizeof (#m2) == 1 ? OT_odd_infix_unc : OT_odd_infix_0 + sizeof (m1) - 1, \
6a86118a
NC
19819 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
19820
19821#define CM(m1, m2, op, nops, ops, ae) \
e07e6e58
NC
19822 xCM_ (m1, , m2, op, nops, ops, ae), \
19823 xCM_ (m1, eq, m2, op, nops, ops, ae), \
19824 xCM_ (m1, ne, m2, op, nops, ops, ae), \
19825 xCM_ (m1, cs, m2, op, nops, ops, ae), \
19826 xCM_ (m1, hs, m2, op, nops, ops, ae), \
19827 xCM_ (m1, cc, m2, op, nops, ops, ae), \
19828 xCM_ (m1, ul, m2, op, nops, ops, ae), \
19829 xCM_ (m1, lo, m2, op, nops, ops, ae), \
19830 xCM_ (m1, mi, m2, op, nops, ops, ae), \
19831 xCM_ (m1, pl, m2, op, nops, ops, ae), \
19832 xCM_ (m1, vs, m2, op, nops, ops, ae), \
19833 xCM_ (m1, vc, m2, op, nops, ops, ae), \
19834 xCM_ (m1, hi, m2, op, nops, ops, ae), \
19835 xCM_ (m1, ls, m2, op, nops, ops, ae), \
19836 xCM_ (m1, ge, m2, op, nops, ops, ae), \
19837 xCM_ (m1, lt, m2, op, nops, ops, ae), \
19838 xCM_ (m1, gt, m2, op, nops, ops, ae), \
19839 xCM_ (m1, le, m2, op, nops, ops, ae), \
19840 xCM_ (m1, al, m2, op, nops, ops, ae)
6a86118a
NC
19841
19842#define UE(mnem, op, nops, ops, ae) \
19843 { #mnem, OPS##nops ops, OT_unconditional, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL }
19844
19845#define UF(mnem, op, nops, ops, ae) \
19846 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL }
19847
5287ad62
JB
19848/* Neon data-processing. ARM versions are unconditional with cond=0xf.
19849 The Thumb and ARM variants are mostly the same (bits 0-23 and 24/28), so we
19850 use the same encoding function for each. */
19851#define NUF(mnem, op, nops, ops, enc) \
19852 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op, \
19853 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc }
19854
19855/* Neon data processing, version which indirects through neon_enc_tab for
19856 the various overloaded versions of opcodes. */
19857#define nUF(mnem, op, nops, ops, enc) \
21d799b5 19858 { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op, \
5287ad62
JB
19859 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc }
19860
19861/* Neon insn with conditional suffix for the ARM version, non-overloaded
19862 version. */
037e8744
JB
19863#define NCE_tag(mnem, op, nops, ops, enc, tag) \
19864 { #mnem, OPS##nops ops, tag, 0x##op, 0x##op, ARM_VARIANT, \
5287ad62
JB
19865 THUMB_VARIANT, do_##enc, do_##enc }
19866
037e8744 19867#define NCE(mnem, op, nops, ops, enc) \
e07e6e58 19868 NCE_tag (mnem, op, nops, ops, enc, OT_csuffix)
037e8744
JB
19869
19870#define NCEF(mnem, op, nops, ops, enc) \
e07e6e58 19871 NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF)
037e8744 19872
5287ad62 19873/* Neon insn with conditional suffix for the ARM version, overloaded types. */
037e8744 19874#define nCE_tag(mnem, op, nops, ops, enc, tag) \
21d799b5 19875 { #mnem, OPS##nops ops, tag, N_MNEM##op, N_MNEM##op, \
5287ad62
JB
19876 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc }
19877
037e8744 19878#define nCE(mnem, op, nops, ops, enc) \
e07e6e58 19879 nCE_tag (mnem, op, nops, ops, enc, OT_csuffix)
037e8744
JB
19880
19881#define nCEF(mnem, op, nops, ops, enc) \
e07e6e58 19882 nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF)
037e8744 19883
c19d1205
ZW
19884#define do_0 0
19885
c19d1205 19886static const struct asm_opcode insns[] =
bfae80f2 19887{
74db7efb
NC
19888#define ARM_VARIANT & arm_ext_v1 /* Core ARM Instructions. */
19889#define THUMB_VARIANT & arm_ext_v4t
21d799b5
NC
19890 tCE("and", 0000000, _and, 3, (RR, oRR, SH), arit, t_arit3c),
19891 tC3("ands", 0100000, _ands, 3, (RR, oRR, SH), arit, t_arit3c),
19892 tCE("eor", 0200000, _eor, 3, (RR, oRR, SH), arit, t_arit3c),
19893 tC3("eors", 0300000, _eors, 3, (RR, oRR, SH), arit, t_arit3c),
19894 tCE("sub", 0400000, _sub, 3, (RR, oRR, SH), arit, t_add_sub),
19895 tC3("subs", 0500000, _subs, 3, (RR, oRR, SH), arit, t_add_sub),
19896 tCE("add", 0800000, _add, 3, (RR, oRR, SHG), arit, t_add_sub),
19897 tC3("adds", 0900000, _adds, 3, (RR, oRR, SHG), arit, t_add_sub),
19898 tCE("adc", 0a00000, _adc, 3, (RR, oRR, SH), arit, t_arit3c),
19899 tC3("adcs", 0b00000, _adcs, 3, (RR, oRR, SH), arit, t_arit3c),
19900 tCE("sbc", 0c00000, _sbc, 3, (RR, oRR, SH), arit, t_arit3),
19901 tC3("sbcs", 0d00000, _sbcs, 3, (RR, oRR, SH), arit, t_arit3),
19902 tCE("orr", 1800000, _orr, 3, (RR, oRR, SH), arit, t_arit3c),
19903 tC3("orrs", 1900000, _orrs, 3, (RR, oRR, SH), arit, t_arit3c),
19904 tCE("bic", 1c00000, _bic, 3, (RR, oRR, SH), arit, t_arit3),
19905 tC3("bics", 1d00000, _bics, 3, (RR, oRR, SH), arit, t_arit3),
c19d1205
ZW
19906
19907 /* The p-variants of tst/cmp/cmn/teq (below) are the pre-V6 mechanism
19908 for setting PSR flag bits. They are obsolete in V6 and do not
19909 have Thumb equivalents. */
21d799b5
NC
19910 tCE("tst", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
19911 tC3w("tsts", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
19912 CL("tstp", 110f000, 2, (RR, SH), cmp),
19913 tCE("cmp", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
19914 tC3w("cmps", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
19915 CL("cmpp", 150f000, 2, (RR, SH), cmp),
19916 tCE("cmn", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
19917 tC3w("cmns", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
19918 CL("cmnp", 170f000, 2, (RR, SH), cmp),
19919
19920 tCE("mov", 1a00000, _mov, 2, (RR, SH), mov, t_mov_cmp),
72d98d16 19921 tC3("movs", 1b00000, _movs, 2, (RR, SHG), mov, t_mov_cmp),
21d799b5
NC
19922 tCE("mvn", 1e00000, _mvn, 2, (RR, SH), mov, t_mvn_tst),
19923 tC3("mvns", 1f00000, _mvns, 2, (RR, SH), mov, t_mvn_tst),
19924
19925 tCE("ldr", 4100000, _ldr, 2, (RR, ADDRGLDR),ldst, t_ldst),
5be8be5d
DG
19926 tC3("ldrb", 4500000, _ldrb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
19927 tCE("str", 4000000, _str, _2, (MIX_ARM_THUMB_OPERANDS (OP_RR,
19928 OP_RRnpc),
19929 OP_ADDRGLDR),ldst, t_ldst),
19930 tC3("strb", 4400000, _strb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
21d799b5
NC
19931
19932 tCE("stm", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
19933 tC3("stmia", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
19934 tC3("stmea", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
19935 tCE("ldm", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
19936 tC3("ldmia", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
19937 tC3("ldmfd", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
19938
21d799b5
NC
19939 tCE("b", a000000, _b, 1, (EXPr), branch, t_branch),
19940 TCE("bl", b000000, f000f800, 1, (EXPr), bl, t_branch23),
bfae80f2 19941
c19d1205 19942 /* Pseudo ops. */
21d799b5 19943 tCE("adr", 28f0000, _adr, 2, (RR, EXP), adr, t_adr),
2fc8bdac 19944 C3(adrl, 28f0000, 2, (RR, EXP), adrl),
21d799b5 19945 tCE("nop", 1a00000, _nop, 1, (oI255c), nop, t_nop),
74db7efb 19946 tCE("udf", 7f000f0, _udf, 1, (oIffffb), bkpt, t_udf),
c19d1205
ZW
19947
19948 /* Thumb-compatibility pseudo ops. */
21d799b5
NC
19949 tCE("lsl", 1a00000, _lsl, 3, (RR, oRR, SH), shift, t_shift),
19950 tC3("lsls", 1b00000, _lsls, 3, (RR, oRR, SH), shift, t_shift),
19951 tCE("lsr", 1a00020, _lsr, 3, (RR, oRR, SH), shift, t_shift),
19952 tC3("lsrs", 1b00020, _lsrs, 3, (RR, oRR, SH), shift, t_shift),
19953 tCE("asr", 1a00040, _asr, 3, (RR, oRR, SH), shift, t_shift),
19954 tC3("asrs", 1b00040, _asrs, 3, (RR, oRR, SH), shift, t_shift),
19955 tCE("ror", 1a00060, _ror, 3, (RR, oRR, SH), shift, t_shift),
19956 tC3("rors", 1b00060, _rors, 3, (RR, oRR, SH), shift, t_shift),
19957 tCE("neg", 2600000, _neg, 2, (RR, RR), rd_rn, t_neg),
19958 tC3("negs", 2700000, _negs, 2, (RR, RR), rd_rn, t_neg),
19959 tCE("push", 92d0000, _push, 1, (REGLST), push_pop, t_push_pop),
19960 tCE("pop", 8bd0000, _pop, 1, (REGLST), push_pop, t_push_pop),
c19d1205 19961
16a4cf17 19962 /* These may simplify to neg. */
21d799b5
NC
19963 TCE("rsb", 0600000, ebc00000, 3, (RR, oRR, SH), arit, t_rsb),
19964 TC3("rsbs", 0700000, ebd00000, 3, (RR, oRR, SH), arit, t_rsb),
16a4cf17 19965
173205ca
TP
19966#undef THUMB_VARIANT
19967#define THUMB_VARIANT & arm_ext_os
19968
19969 TCE("swi", f000000, df00, 1, (EXPi), swi, t_swi),
19970 TCE("svc", f000000, df00, 1, (EXPi), swi, t_swi),
19971
c921be7d
NC
19972#undef THUMB_VARIANT
19973#define THUMB_VARIANT & arm_ext_v6
19974
21d799b5 19975 TCE("cpy", 1a00000, 4600, 2, (RR, RR), rd_rm, t_cpy),
c19d1205
ZW
19976
19977 /* V1 instructions with no Thumb analogue prior to V6T2. */
c921be7d
NC
19978#undef THUMB_VARIANT
19979#define THUMB_VARIANT & arm_ext_v6t2
19980
21d799b5
NC
19981 TCE("teq", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
19982 TC3w("teqs", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
19983 CL("teqp", 130f000, 2, (RR, SH), cmp),
c19d1205 19984
5be8be5d
DG
19985 TC3("ldrt", 4300000, f8500e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
19986 TC3("ldrbt", 4700000, f8100e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
19987 TC3("strt", 4200000, f8400e00, 2, (RR_npcsp, ADDR), ldstt, t_ldstt),
19988 TC3("strbt", 4600000, f8000e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
c19d1205 19989
21d799b5
NC
19990 TC3("stmdb", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
19991 TC3("stmfd", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205 19992
21d799b5
NC
19993 TC3("ldmdb", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
19994 TC3("ldmea", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205
ZW
19995
19996 /* V1 instructions with no Thumb analogue at all. */
21d799b5 19997 CE("rsc", 0e00000, 3, (RR, oRR, SH), arit),
c19d1205
ZW
19998 C3(rscs, 0f00000, 3, (RR, oRR, SH), arit),
19999
20000 C3(stmib, 9800000, 2, (RRw, REGLST), ldmstm),
20001 C3(stmfa, 9800000, 2, (RRw, REGLST), ldmstm),
20002 C3(stmda, 8000000, 2, (RRw, REGLST), ldmstm),
20003 C3(stmed, 8000000, 2, (RRw, REGLST), ldmstm),
20004 C3(ldmib, 9900000, 2, (RRw, REGLST), ldmstm),
20005 C3(ldmed, 9900000, 2, (RRw, REGLST), ldmstm),
20006 C3(ldmda, 8100000, 2, (RRw, REGLST), ldmstm),
20007 C3(ldmfa, 8100000, 2, (RRw, REGLST), ldmstm),
20008
c921be7d
NC
20009#undef ARM_VARIANT
20010#define ARM_VARIANT & arm_ext_v2 /* ARM 2 - multiplies. */
20011#undef THUMB_VARIANT
20012#define THUMB_VARIANT & arm_ext_v4t
20013
21d799b5
NC
20014 tCE("mul", 0000090, _mul, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
20015 tC3("muls", 0100090, _muls, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
c19d1205 20016
c921be7d
NC
20017#undef THUMB_VARIANT
20018#define THUMB_VARIANT & arm_ext_v6t2
20019
21d799b5 20020 TCE("mla", 0200090, fb000000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
c19d1205
ZW
20021 C3(mlas, 0300090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas),
20022
20023 /* Generic coprocessor instructions. */
21d799b5
NC
20024 TCE("cdp", e000000, ee000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
20025 TCE("ldc", c100000, ec100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20026 TC3("ldcl", c500000, ec500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20027 TCE("stc", c000000, ec000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20028 TC3("stcl", c400000, ec400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20029 TCE("mcr", e000010, ee000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
db472d6f 20030 TCE("mrc", e100010, ee100010, 6, (RCP, I7b, APSR_RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 20031
c921be7d
NC
20032#undef ARM_VARIANT
20033#define ARM_VARIANT & arm_ext_v2s /* ARM 3 - swp instructions. */
20034
21d799b5 20035 CE("swp", 1000090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
c19d1205
ZW
20036 C3(swpb, 1400090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
20037
c921be7d
NC
20038#undef ARM_VARIANT
20039#define ARM_VARIANT & arm_ext_v3 /* ARM 6 Status register instructions. */
20040#undef THUMB_VARIANT
20041#define THUMB_VARIANT & arm_ext_msr
20042
d2cd1205
JB
20043 TCE("mrs", 1000000, f3e08000, 2, (RRnpc, rPSR), mrs, t_mrs),
20044 TCE("msr", 120f000, f3808000, 2, (wPSR, RR_EXi), msr, t_msr),
c19d1205 20045
c921be7d
NC
20046#undef ARM_VARIANT
20047#define ARM_VARIANT & arm_ext_v3m /* ARM 7M long multiplies. */
20048#undef THUMB_VARIANT
20049#define THUMB_VARIANT & arm_ext_v6t2
20050
21d799b5
NC
20051 TCE("smull", 0c00090, fb800000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
20052 CM("smull","s", 0d00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
20053 TCE("umull", 0800090, fba00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
20054 CM("umull","s", 0900090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
20055 TCE("smlal", 0e00090, fbc00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
20056 CM("smlal","s", 0f00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
20057 TCE("umlal", 0a00090, fbe00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
20058 CM("umlal","s", 0b00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
c19d1205 20059
c921be7d
NC
20060#undef ARM_VARIANT
20061#define ARM_VARIANT & arm_ext_v4 /* ARM Architecture 4. */
20062#undef THUMB_VARIANT
20063#define THUMB_VARIANT & arm_ext_v4t
20064
5be8be5d
DG
20065 tC3("ldrh", 01000b0, _ldrh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
20066 tC3("strh", 00000b0, _strh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
20067 tC3("ldrsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
20068 tC3("ldrsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
56c0a61f
RE
20069 tC3("ldsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
20070 tC3("ldsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
c19d1205 20071
c921be7d
NC
20072#undef ARM_VARIANT
20073#define ARM_VARIANT & arm_ext_v4t_5
20074
c19d1205
ZW
20075 /* ARM Architecture 4T. */
20076 /* Note: bx (and blx) are required on V5, even if the processor does
20077 not support Thumb. */
21d799b5 20078 TCE("bx", 12fff10, 4700, 1, (RR), bx, t_bx),
c19d1205 20079
c921be7d
NC
20080#undef ARM_VARIANT
20081#define ARM_VARIANT & arm_ext_v5 /* ARM Architecture 5T. */
20082#undef THUMB_VARIANT
20083#define THUMB_VARIANT & arm_ext_v5t
20084
c19d1205
ZW
20085 /* Note: blx has 2 variants; the .value coded here is for
20086 BLX(2). Only this variant has conditional execution. */
21d799b5
NC
20087 TCE("blx", 12fff30, 4780, 1, (RR_EXr), blx, t_blx),
20088 TUE("bkpt", 1200070, be00, 1, (oIffffb), bkpt, t_bkpt),
c19d1205 20089
c921be7d
NC
20090#undef THUMB_VARIANT
20091#define THUMB_VARIANT & arm_ext_v6t2
20092
21d799b5
NC
20093 TCE("clz", 16f0f10, fab0f080, 2, (RRnpc, RRnpc), rd_rm, t_clz),
20094 TUF("ldc2", c100000, fc100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20095 TUF("ldc2l", c500000, fc500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20096 TUF("stc2", c000000, fc000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20097 TUF("stc2l", c400000, fc400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20098 TUF("cdp2", e000000, fe000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
20099 TUF("mcr2", e000010, fe000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
20100 TUF("mrc2", e100010, fe100010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 20101
c921be7d 20102#undef ARM_VARIANT
74db7efb
NC
20103#define ARM_VARIANT & arm_ext_v5exp /* ARM Architecture 5TExP. */
20104#undef THUMB_VARIANT
20105#define THUMB_VARIANT & arm_ext_v5exp
c921be7d 20106
21d799b5
NC
20107 TCE("smlabb", 1000080, fb100000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
20108 TCE("smlatb", 10000a0, fb100020, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
20109 TCE("smlabt", 10000c0, fb100010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
20110 TCE("smlatt", 10000e0, fb100030, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 20111
21d799b5
NC
20112 TCE("smlawb", 1200080, fb300000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
20113 TCE("smlawt", 12000c0, fb300010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 20114
21d799b5
NC
20115 TCE("smlalbb", 1400080, fbc00080, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
20116 TCE("smlaltb", 14000a0, fbc000a0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
20117 TCE("smlalbt", 14000c0, fbc00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
20118 TCE("smlaltt", 14000e0, fbc000b0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
c19d1205 20119
21d799b5
NC
20120 TCE("smulbb", 1600080, fb10f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20121 TCE("smultb", 16000a0, fb10f020, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20122 TCE("smulbt", 16000c0, fb10f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20123 TCE("smultt", 16000e0, fb10f030, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 20124
21d799b5
NC
20125 TCE("smulwb", 12000a0, fb30f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20126 TCE("smulwt", 12000e0, fb30f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 20127
03ee1b7f
NC
20128 TCE("qadd", 1000050, fa80f080, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
20129 TCE("qdadd", 1400050, fa80f090, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
20130 TCE("qsub", 1200050, fa80f0a0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
20131 TCE("qdsub", 1600050, fa80f0b0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
c19d1205 20132
c921be7d 20133#undef ARM_VARIANT
74db7efb
NC
20134#define ARM_VARIANT & arm_ext_v5e /* ARM Architecture 5TE. */
20135#undef THUMB_VARIANT
20136#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 20137
21d799b5 20138 TUF("pld", 450f000, f810f000, 1, (ADDR), pld, t_pld),
5be8be5d
DG
20139 TC3("ldrd", 00000d0, e8500000, 3, (RRnpc_npcsp, oRRnpc_npcsp, ADDRGLDRS),
20140 ldrd, t_ldstd),
20141 TC3("strd", 00000f0, e8400000, 3, (RRnpc_npcsp, oRRnpc_npcsp,
20142 ADDRGLDRS), ldrd, t_ldstd),
c19d1205 20143
21d799b5
NC
20144 TCE("mcrr", c400000, ec400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
20145 TCE("mrrc", c500000, ec500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
c19d1205 20146
c921be7d
NC
20147#undef ARM_VARIANT
20148#define ARM_VARIANT & arm_ext_v5j /* ARM Architecture 5TEJ. */
20149
21d799b5 20150 TCE("bxj", 12fff20, f3c08f00, 1, (RR), bxj, t_bxj),
c19d1205 20151
c921be7d
NC
20152#undef ARM_VARIANT
20153#define ARM_VARIANT & arm_ext_v6 /* ARM V6. */
20154#undef THUMB_VARIANT
20155#define THUMB_VARIANT & arm_ext_v6
20156
21d799b5
NC
20157 TUF("cpsie", 1080000, b660, 2, (CPSF, oI31b), cpsi, t_cpsi),
20158 TUF("cpsid", 10c0000, b670, 2, (CPSF, oI31b), cpsi, t_cpsi),
20159 tCE("rev", 6bf0f30, _rev, 2, (RRnpc, RRnpc), rd_rm, t_rev),
20160 tCE("rev16", 6bf0fb0, _rev16, 2, (RRnpc, RRnpc), rd_rm, t_rev),
20161 tCE("revsh", 6ff0fb0, _revsh, 2, (RRnpc, RRnpc), rd_rm, t_rev),
20162 tCE("sxth", 6bf0070, _sxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
20163 tCE("uxth", 6ff0070, _uxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
20164 tCE("sxtb", 6af0070, _sxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
20165 tCE("uxtb", 6ef0070, _uxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
20166 TUF("setend", 1010000, b650, 1, (ENDI), setend, t_setend),
c19d1205 20167
c921be7d 20168#undef THUMB_VARIANT
ff8646ee 20169#define THUMB_VARIANT & arm_ext_v6t2_v8m
c921be7d 20170
5be8be5d
DG
20171 TCE("ldrex", 1900f9f, e8500f00, 2, (RRnpc_npcsp, ADDR), ldrex, t_ldrex),
20172 TCE("strex", 1800f90, e8400000, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
20173 strex, t_strex),
ff8646ee
TP
20174#undef THUMB_VARIANT
20175#define THUMB_VARIANT & arm_ext_v6t2
20176
21d799b5
NC
20177 TUF("mcrr2", c400000, fc400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
20178 TUF("mrrc2", c500000, fc500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
62b3e311 20179
21d799b5
NC
20180 TCE("ssat", 6a00010, f3000000, 4, (RRnpc, I32, RRnpc, oSHllar),ssat, t_ssat),
20181 TCE("usat", 6e00010, f3800000, 4, (RRnpc, I31, RRnpc, oSHllar),usat, t_usat),
62b3e311 20182
9e3c6df6 20183/* ARM V6 not included in V7M. */
c921be7d
NC
20184#undef THUMB_VARIANT
20185#define THUMB_VARIANT & arm_ext_v6_notm
9e3c6df6 20186 TUF("rfeia", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6 20187 TUF("rfe", 8900a00, e990c000, 1, (RRw), rfe, rfe),
9e3c6df6
PB
20188 UF(rfeib, 9900a00, 1, (RRw), rfe),
20189 UF(rfeda, 8100a00, 1, (RRw), rfe),
20190 TUF("rfedb", 9100a00, e810c000, 1, (RRw), rfe, rfe),
20191 TUF("rfefd", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6
RE
20192 UF(rfefa, 8100a00, 1, (RRw), rfe),
20193 TUF("rfeea", 9100a00, e810c000, 1, (RRw), rfe, rfe),
20194 UF(rfeed, 9900a00, 1, (RRw), rfe),
9e3c6df6 20195 TUF("srsia", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
d709e4e6
RE
20196 TUF("srs", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
20197 TUF("srsea", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
9e3c6df6 20198 UF(srsib, 9c00500, 2, (oRRw, I31w), srs),
d709e4e6 20199 UF(srsfa, 9c00500, 2, (oRRw, I31w), srs),
9e3c6df6 20200 UF(srsda, 8400500, 2, (oRRw, I31w), srs),
d709e4e6 20201 UF(srsed, 8400500, 2, (oRRw, I31w), srs),
9e3c6df6 20202 TUF("srsdb", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
d709e4e6 20203 TUF("srsfd", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
941c9cad 20204 TUF("cps", 1020000, f3af8100, 1, (I31b), imm0, t_cps),
c921be7d 20205
9e3c6df6
PB
20206/* ARM V6 not included in V7M (eg. integer SIMD). */
20207#undef THUMB_VARIANT
20208#define THUMB_VARIANT & arm_ext_v6_dsp
21d799b5
NC
20209 TCE("pkhbt", 6800010, eac00000, 4, (RRnpc, RRnpc, RRnpc, oSHll), pkhbt, t_pkhbt),
20210 TCE("pkhtb", 6800050, eac00020, 4, (RRnpc, RRnpc, RRnpc, oSHar), pkhtb, t_pkhtb),
20211 TCE("qadd16", 6200f10, fa90f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20212 TCE("qadd8", 6200f90, fa80f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20213 TCE("qasx", 6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20214 /* Old name for QASX. */
74db7efb 20215 TCE("qaddsubx",6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 20216 TCE("qsax", 6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20217 /* Old name for QSAX. */
74db7efb 20218 TCE("qsubaddx",6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
20219 TCE("qsub16", 6200f70, fad0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20220 TCE("qsub8", 6200ff0, fac0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20221 TCE("sadd16", 6100f10, fa90f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20222 TCE("sadd8", 6100f90, fa80f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20223 TCE("sasx", 6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20224 /* Old name for SASX. */
74db7efb 20225 TCE("saddsubx",6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
20226 TCE("shadd16", 6300f10, fa90f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20227 TCE("shadd8", 6300f90, fa80f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 20228 TCE("shasx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20229 /* Old name for SHASX. */
21d799b5 20230 TCE("shaddsubx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 20231 TCE("shsax", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20232 /* Old name for SHSAX. */
21d799b5
NC
20233 TCE("shsubaddx", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20234 TCE("shsub16", 6300f70, fad0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20235 TCE("shsub8", 6300ff0, fac0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20236 TCE("ssax", 6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20237 /* Old name for SSAX. */
74db7efb 20238 TCE("ssubaddx",6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
20239 TCE("ssub16", 6100f70, fad0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20240 TCE("ssub8", 6100ff0, fac0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20241 TCE("uadd16", 6500f10, fa90f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20242 TCE("uadd8", 6500f90, fa80f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20243 TCE("uasx", 6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20244 /* Old name for UASX. */
74db7efb 20245 TCE("uaddsubx",6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
20246 TCE("uhadd16", 6700f10, fa90f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20247 TCE("uhadd8", 6700f90, fa80f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 20248 TCE("uhasx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20249 /* Old name for UHASX. */
21d799b5
NC
20250 TCE("uhaddsubx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20251 TCE("uhsax", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20252 /* Old name for UHSAX. */
21d799b5
NC
20253 TCE("uhsubaddx", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20254 TCE("uhsub16", 6700f70, fad0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20255 TCE("uhsub8", 6700ff0, fac0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20256 TCE("uqadd16", 6600f10, fa90f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20257 TCE("uqadd8", 6600f90, fa80f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 20258 TCE("uqasx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20259 /* Old name for UQASX. */
21d799b5
NC
20260 TCE("uqaddsubx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20261 TCE("uqsax", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20262 /* Old name for UQSAX. */
21d799b5
NC
20263 TCE("uqsubaddx", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20264 TCE("uqsub16", 6600f70, fad0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20265 TCE("uqsub8", 6600ff0, fac0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20266 TCE("usub16", 6500f70, fad0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20267 TCE("usax", 6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20268 /* Old name for USAX. */
74db7efb 20269 TCE("usubaddx",6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 20270 TCE("usub8", 6500ff0, fac0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
20271 TCE("sxtah", 6b00070, fa00f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
20272 TCE("sxtab16", 6800070, fa20f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
20273 TCE("sxtab", 6a00070, fa40f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
20274 TCE("sxtb16", 68f0070, fa2ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
20275 TCE("uxtah", 6f00070, fa10f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
20276 TCE("uxtab16", 6c00070, fa30f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
20277 TCE("uxtab", 6e00070, fa50f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
20278 TCE("uxtb16", 6cf0070, fa3ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
20279 TCE("sel", 6800fb0, faa0f080, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20280 TCE("smlad", 7000010, fb200000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20281 TCE("smladx", 7000030, fb200010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20282 TCE("smlald", 7400010, fbc000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
20283 TCE("smlaldx", 7400030, fbc000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
20284 TCE("smlsd", 7000050, fb400000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20285 TCE("smlsdx", 7000070, fb400010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20286 TCE("smlsld", 7400050, fbd000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
20287 TCE("smlsldx", 7400070, fbd000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
20288 TCE("smmla", 7500010, fb500000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20289 TCE("smmlar", 7500030, fb500010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20290 TCE("smmls", 75000d0, fb600000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20291 TCE("smmlsr", 75000f0, fb600010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20292 TCE("smmul", 750f010, fb50f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20293 TCE("smmulr", 750f030, fb50f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20294 TCE("smuad", 700f010, fb20f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20295 TCE("smuadx", 700f030, fb20f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20296 TCE("smusd", 700f050, fb40f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20297 TCE("smusdx", 700f070, fb40f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
21d799b5
NC
20298 TCE("ssat16", 6a00f30, f3200000, 3, (RRnpc, I16, RRnpc), ssat16, t_ssat16),
20299 TCE("umaal", 0400090, fbe00060, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal, t_mlal),
20300 TCE("usad8", 780f010, fb70f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20301 TCE("usada8", 7800010, fb700000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20302 TCE("usat16", 6e00f30, f3a00000, 3, (RRnpc, I15, RRnpc), usat16, t_usat16),
c19d1205 20303
c921be7d 20304#undef ARM_VARIANT
55e8aae7 20305#define ARM_VARIANT & arm_ext_v6k_v6t2
c921be7d 20306#undef THUMB_VARIANT
55e8aae7 20307#define THUMB_VARIANT & arm_ext_v6k_v6t2
c921be7d 20308
21d799b5
NC
20309 tCE("yield", 320f001, _yield, 0, (), noargs, t_hint),
20310 tCE("wfe", 320f002, _wfe, 0, (), noargs, t_hint),
20311 tCE("wfi", 320f003, _wfi, 0, (), noargs, t_hint),
20312 tCE("sev", 320f004, _sev, 0, (), noargs, t_hint),
c19d1205 20313
c921be7d
NC
20314#undef THUMB_VARIANT
20315#define THUMB_VARIANT & arm_ext_v6_notm
5be8be5d
DG
20316 TCE("ldrexd", 1b00f9f, e8d0007f, 3, (RRnpc_npcsp, oRRnpc_npcsp, RRnpcb),
20317 ldrexd, t_ldrexd),
20318 TCE("strexd", 1a00f90, e8c00070, 4, (RRnpc_npcsp, RRnpc_npcsp, oRRnpc_npcsp,
20319 RRnpcb), strexd, t_strexd),
ebdca51a 20320
c921be7d 20321#undef THUMB_VARIANT
ff8646ee 20322#define THUMB_VARIANT & arm_ext_v6t2_v8m
5be8be5d
DG
20323 TCE("ldrexb", 1d00f9f, e8d00f4f, 2, (RRnpc_npcsp,RRnpcb),
20324 rd_rn, rd_rn),
20325 TCE("ldrexh", 1f00f9f, e8d00f5f, 2, (RRnpc_npcsp, RRnpcb),
20326 rd_rn, rd_rn),
20327 TCE("strexb", 1c00f90, e8c00f40, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 20328 strex, t_strexbh),
5be8be5d 20329 TCE("strexh", 1e00f90, e8c00f50, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 20330 strex, t_strexbh),
21d799b5 20331 TUF("clrex", 57ff01f, f3bf8f2f, 0, (), noargs, noargs),
c19d1205 20332
c921be7d 20333#undef ARM_VARIANT
f4c65163 20334#define ARM_VARIANT & arm_ext_sec
74db7efb 20335#undef THUMB_VARIANT
f4c65163 20336#define THUMB_VARIANT & arm_ext_sec
c921be7d 20337
21d799b5 20338 TCE("smc", 1600070, f7f08000, 1, (EXPi), smc, t_smc),
c19d1205 20339
90ec0d68
MGD
20340#undef ARM_VARIANT
20341#define ARM_VARIANT & arm_ext_virt
20342#undef THUMB_VARIANT
20343#define THUMB_VARIANT & arm_ext_virt
20344
20345 TCE("hvc", 1400070, f7e08000, 1, (EXPi), hvc, t_hvc),
20346 TCE("eret", 160006e, f3de8f00, 0, (), noargs, noargs),
20347
ddfded2f
MW
20348#undef ARM_VARIANT
20349#define ARM_VARIANT & arm_ext_pan
20350#undef THUMB_VARIANT
20351#define THUMB_VARIANT & arm_ext_pan
20352
20353 TUF("setpan", 1100000, b610, 1, (I7), setpan, t_setpan),
20354
c921be7d 20355#undef ARM_VARIANT
74db7efb 20356#define ARM_VARIANT & arm_ext_v6t2
f4c65163
MGD
20357#undef THUMB_VARIANT
20358#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 20359
21d799b5
NC
20360 TCE("bfc", 7c0001f, f36f0000, 3, (RRnpc, I31, I32), bfc, t_bfc),
20361 TCE("bfi", 7c00010, f3600000, 4, (RRnpc, RRnpc_I0, I31, I32), bfi, t_bfi),
20362 TCE("sbfx", 7a00050, f3400000, 4, (RR, RR, I31, I32), bfx, t_bfx),
20363 TCE("ubfx", 7e00050, f3c00000, 4, (RR, RR, I31, I32), bfx, t_bfx),
c19d1205 20364
21d799b5 20365 TCE("mls", 0600090, fb000010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
21d799b5 20366 TCE("rbit", 6ff0f30, fa90f0a0, 2, (RR, RR), rd_rm, t_rbit),
c19d1205 20367
5be8be5d
DG
20368 TC3("ldrht", 03000b0, f8300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
20369 TC3("ldrsht", 03000f0, f9300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
20370 TC3("ldrsbt", 03000d0, f9100e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
20371 TC3("strht", 02000b0, f8200e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
c19d1205 20372
91d8b670
JG
20373#undef ARM_VARIANT
20374#define ARM_VARIANT & arm_ext_v3
20375#undef THUMB_VARIANT
20376#define THUMB_VARIANT & arm_ext_v6t2
20377
20378 TUE("csdb", 320f014, f3af8014, 0, (), noargs, t_csdb),
c597cc3d
SD
20379 TUF("ssbb", 57ff040, f3bf8f40, 0, (), noargs, t_csdb),
20380 TUF("pssbb", 57ff044, f3bf8f44, 0, (), noargs, t_csdb),
91d8b670
JG
20381
20382#undef ARM_VARIANT
20383#define ARM_VARIANT & arm_ext_v6t2
ff8646ee
TP
20384#undef THUMB_VARIANT
20385#define THUMB_VARIANT & arm_ext_v6t2_v8m
20386 TCE("movw", 3000000, f2400000, 2, (RRnpc, HALF), mov16, t_mov16),
20387 TCE("movt", 3400000, f2c00000, 2, (RRnpc, HALF), mov16, t_mov16),
20388
bf3eeda7 20389 /* Thumb-only instructions. */
74db7efb 20390#undef ARM_VARIANT
bf3eeda7
NS
20391#define ARM_VARIANT NULL
20392 TUE("cbnz", 0, b900, 2, (RR, EXP), 0, t_cbz),
20393 TUE("cbz", 0, b100, 2, (RR, EXP), 0, t_cbz),
c921be7d
NC
20394
20395 /* ARM does not really have an IT instruction, so always allow it.
20396 The opcode is copied from Thumb in order to allow warnings in
20397 -mimplicit-it=[never | arm] modes. */
20398#undef ARM_VARIANT
20399#define ARM_VARIANT & arm_ext_v1
ff8646ee
TP
20400#undef THUMB_VARIANT
20401#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 20402
21d799b5
NC
20403 TUE("it", bf08, bf08, 1, (COND), it, t_it),
20404 TUE("itt", bf0c, bf0c, 1, (COND), it, t_it),
20405 TUE("ite", bf04, bf04, 1, (COND), it, t_it),
20406 TUE("ittt", bf0e, bf0e, 1, (COND), it, t_it),
20407 TUE("itet", bf06, bf06, 1, (COND), it, t_it),
20408 TUE("itte", bf0a, bf0a, 1, (COND), it, t_it),
20409 TUE("itee", bf02, bf02, 1, (COND), it, t_it),
20410 TUE("itttt", bf0f, bf0f, 1, (COND), it, t_it),
20411 TUE("itett", bf07, bf07, 1, (COND), it, t_it),
20412 TUE("ittet", bf0b, bf0b, 1, (COND), it, t_it),
20413 TUE("iteet", bf03, bf03, 1, (COND), it, t_it),
20414 TUE("ittte", bf0d, bf0d, 1, (COND), it, t_it),
20415 TUE("itete", bf05, bf05, 1, (COND), it, t_it),
20416 TUE("ittee", bf09, bf09, 1, (COND), it, t_it),
20417 TUE("iteee", bf01, bf01, 1, (COND), it, t_it),
1c444d06 20418 /* ARM/Thumb-2 instructions with no Thumb-1 equivalent. */
21d799b5
NC
20419 TC3("rrx", 01a00060, ea4f0030, 2, (RR, RR), rd_rm, t_rrx),
20420 TC3("rrxs", 01b00060, ea5f0030, 2, (RR, RR), rd_rm, t_rrx),
c19d1205 20421
92e90b6e 20422 /* Thumb2 only instructions. */
c921be7d
NC
20423#undef ARM_VARIANT
20424#define ARM_VARIANT NULL
92e90b6e 20425
21d799b5
NC
20426 TCE("addw", 0, f2000000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
20427 TCE("subw", 0, f2a00000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
20428 TCE("orn", 0, ea600000, 3, (RR, oRR, SH), 0, t_orn),
20429 TCE("orns", 0, ea700000, 3, (RR, oRR, SH), 0, t_orn),
20430 TCE("tbb", 0, e8d0f000, 1, (TB), 0, t_tb),
20431 TCE("tbh", 0, e8d0f010, 1, (TB), 0, t_tb),
92e90b6e 20432
eea54501
MGD
20433 /* Hardware division instructions. */
20434#undef ARM_VARIANT
20435#define ARM_VARIANT & arm_ext_adiv
c921be7d
NC
20436#undef THUMB_VARIANT
20437#define THUMB_VARIANT & arm_ext_div
20438
eea54501
MGD
20439 TCE("sdiv", 710f010, fb90f0f0, 3, (RR, oRR, RR), div, t_div),
20440 TCE("udiv", 730f010, fbb0f0f0, 3, (RR, oRR, RR), div, t_div),
62b3e311 20441
7e806470 20442 /* ARM V6M/V7 instructions. */
c921be7d
NC
20443#undef ARM_VARIANT
20444#define ARM_VARIANT & arm_ext_barrier
20445#undef THUMB_VARIANT
20446#define THUMB_VARIANT & arm_ext_barrier
20447
ccb84d65
JB
20448 TUF("dmb", 57ff050, f3bf8f50, 1, (oBARRIER_I15), barrier, barrier),
20449 TUF("dsb", 57ff040, f3bf8f40, 1, (oBARRIER_I15), barrier, barrier),
20450 TUF("isb", 57ff060, f3bf8f60, 1, (oBARRIER_I15), barrier, barrier),
7e806470 20451
62b3e311 20452 /* ARM V7 instructions. */
c921be7d
NC
20453#undef ARM_VARIANT
20454#define ARM_VARIANT & arm_ext_v7
20455#undef THUMB_VARIANT
20456#define THUMB_VARIANT & arm_ext_v7
20457
21d799b5
NC
20458 TUF("pli", 450f000, f910f000, 1, (ADDR), pli, t_pld),
20459 TCE("dbg", 320f0f0, f3af80f0, 1, (I15), dbg, t_dbg),
62b3e311 20460
74db7efb 20461#undef ARM_VARIANT
60e5ef9f 20462#define ARM_VARIANT & arm_ext_mp
74db7efb 20463#undef THUMB_VARIANT
60e5ef9f
MGD
20464#define THUMB_VARIANT & arm_ext_mp
20465
20466 TUF("pldw", 410f000, f830f000, 1, (ADDR), pld, t_pld),
20467
53c4b28b
MGD
20468 /* AArchv8 instructions. */
20469#undef ARM_VARIANT
20470#define ARM_VARIANT & arm_ext_v8
4ed7ed8d
TP
20471
20472/* Instructions shared between armv8-a and armv8-m. */
53c4b28b 20473#undef THUMB_VARIANT
4ed7ed8d 20474#define THUMB_VARIANT & arm_ext_atomics
53c4b28b 20475
4ed7ed8d
TP
20476 TCE("lda", 1900c9f, e8d00faf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
20477 TCE("ldab", 1d00c9f, e8d00f8f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
20478 TCE("ldah", 1f00c9f, e8d00f9f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
20479 TCE("stl", 180fc90, e8c00faf, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
20480 TCE("stlb", 1c0fc90, e8c00f8f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
20481 TCE("stlh", 1e0fc90, e8c00f9f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
4b8c8c02 20482 TCE("ldaex", 1900e9f, e8d00fef, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
4b8c8c02
RE
20483 TCE("ldaexb", 1d00e9f, e8d00fcf, 2, (RRnpc,RRnpcb), rd_rn, rd_rn),
20484 TCE("ldaexh", 1f00e9f, e8d00fdf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
20485 TCE("stlex", 1800e90, e8c00fe0, 3, (RRnpc, RRnpc, RRnpcb),
20486 stlex, t_stlex),
4b8c8c02
RE
20487 TCE("stlexb", 1c00e90, e8c00fc0, 3, (RRnpc, RRnpc, RRnpcb),
20488 stlex, t_stlex),
20489 TCE("stlexh", 1e00e90, e8c00fd0, 3, (RRnpc, RRnpc, RRnpcb),
20490 stlex, t_stlex),
4ed7ed8d
TP
20491#undef THUMB_VARIANT
20492#define THUMB_VARIANT & arm_ext_v8
53c4b28b 20493
4ed7ed8d 20494 tCE("sevl", 320f005, _sevl, 0, (), noargs, t_hint),
4ed7ed8d
TP
20495 TCE("ldaexd", 1b00e9f, e8d000ff, 3, (RRnpc, oRRnpc, RRnpcb),
20496 ldrexd, t_ldrexd),
20497 TCE("stlexd", 1a00e90, e8c000f0, 4, (RRnpc, RRnpc, oRRnpc, RRnpcb),
20498 strexd, t_strexd),
f7dd2fb2
TC
20499
20500/* Defined in V8 but is in undefined encoding space for earlier
20501 architectures. However earlier architectures are required to treat
20502 this instuction as a semihosting trap as well. Hence while not explicitly
20503 defined as such, it is in fact correct to define the instruction for all
20504 architectures. */
20505#undef THUMB_VARIANT
20506#define THUMB_VARIANT & arm_ext_v1
20507#undef ARM_VARIANT
20508#define ARM_VARIANT & arm_ext_v1
20509 TUE("hlt", 1000070, ba80, 1, (oIffffb), bkpt, t_hlt),
20510
8884b720 20511 /* ARMv8 T32 only. */
74db7efb 20512#undef ARM_VARIANT
b79f7053
MGD
20513#define ARM_VARIANT NULL
20514 TUF("dcps1", 0, f78f8001, 0, (), noargs, noargs),
20515 TUF("dcps2", 0, f78f8002, 0, (), noargs, noargs),
20516 TUF("dcps3", 0, f78f8003, 0, (), noargs, noargs),
20517
33399f07
MGD
20518 /* FP for ARMv8. */
20519#undef ARM_VARIANT
a715796b 20520#define ARM_VARIANT & fpu_vfp_ext_armv8xd
33399f07 20521#undef THUMB_VARIANT
a715796b 20522#define THUMB_VARIANT & fpu_vfp_ext_armv8xd
33399f07
MGD
20523
20524 nUF(vseleq, _vseleq, 3, (RVSD, RVSD, RVSD), vsel),
20525 nUF(vselvs, _vselvs, 3, (RVSD, RVSD, RVSD), vsel),
20526 nUF(vselge, _vselge, 3, (RVSD, RVSD, RVSD), vsel),
20527 nUF(vselgt, _vselgt, 3, (RVSD, RVSD, RVSD), vsel),
73924fbc
MGD
20528 nUF(vmaxnm, _vmaxnm, 3, (RNSDQ, oRNSDQ, RNSDQ), vmaxnm),
20529 nUF(vminnm, _vminnm, 3, (RNSDQ, oRNSDQ, RNSDQ), vmaxnm),
7e8e6784
MGD
20530 nUF(vcvta, _vcvta, 2, (RNSDQ, oRNSDQ), neon_cvta),
20531 nUF(vcvtn, _vcvta, 2, (RNSDQ, oRNSDQ), neon_cvtn),
20532 nUF(vcvtp, _vcvta, 2, (RNSDQ, oRNSDQ), neon_cvtp),
20533 nUF(vcvtm, _vcvta, 2, (RNSDQ, oRNSDQ), neon_cvtm),
30bdf752
MGD
20534 nCE(vrintr, _vrintr, 2, (RNSDQ, oRNSDQ), vrintr),
20535 nCE(vrintz, _vrintr, 2, (RNSDQ, oRNSDQ), vrintz),
20536 nCE(vrintx, _vrintr, 2, (RNSDQ, oRNSDQ), vrintx),
20537 nUF(vrinta, _vrinta, 2, (RNSDQ, oRNSDQ), vrinta),
20538 nUF(vrintn, _vrinta, 2, (RNSDQ, oRNSDQ), vrintn),
20539 nUF(vrintp, _vrinta, 2, (RNSDQ, oRNSDQ), vrintp),
20540 nUF(vrintm, _vrinta, 2, (RNSDQ, oRNSDQ), vrintm),
33399f07 20541
91ff7894
MGD
20542 /* Crypto v1 extensions. */
20543#undef ARM_VARIANT
20544#define ARM_VARIANT & fpu_crypto_ext_armv8
20545#undef THUMB_VARIANT
20546#define THUMB_VARIANT & fpu_crypto_ext_armv8
20547
20548 nUF(aese, _aes, 2, (RNQ, RNQ), aese),
20549 nUF(aesd, _aes, 2, (RNQ, RNQ), aesd),
20550 nUF(aesmc, _aes, 2, (RNQ, RNQ), aesmc),
20551 nUF(aesimc, _aes, 2, (RNQ, RNQ), aesimc),
48adcd8e
MGD
20552 nUF(sha1c, _sha3op, 3, (RNQ, RNQ, RNQ), sha1c),
20553 nUF(sha1p, _sha3op, 3, (RNQ, RNQ, RNQ), sha1p),
20554 nUF(sha1m, _sha3op, 3, (RNQ, RNQ, RNQ), sha1m),
20555 nUF(sha1su0, _sha3op, 3, (RNQ, RNQ, RNQ), sha1su0),
20556 nUF(sha256h, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h),
20557 nUF(sha256h2, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h2),
20558 nUF(sha256su1, _sha3op, 3, (RNQ, RNQ, RNQ), sha256su1),
3c9017d2
MGD
20559 nUF(sha1h, _sha1h, 2, (RNQ, RNQ), sha1h),
20560 nUF(sha1su1, _sha2op, 2, (RNQ, RNQ), sha1su1),
20561 nUF(sha256su0, _sha2op, 2, (RNQ, RNQ), sha256su0),
91ff7894 20562
dd5181d5 20563#undef ARM_VARIANT
74db7efb 20564#define ARM_VARIANT & crc_ext_armv8
dd5181d5
KT
20565#undef THUMB_VARIANT
20566#define THUMB_VARIANT & crc_ext_armv8
20567 TUEc("crc32b", 1000040, fac0f080, 3, (RR, oRR, RR), crc32b),
20568 TUEc("crc32h", 1200040, fac0f090, 3, (RR, oRR, RR), crc32h),
20569 TUEc("crc32w", 1400040, fac0f0a0, 3, (RR, oRR, RR), crc32w),
20570 TUEc("crc32cb",1000240, fad0f080, 3, (RR, oRR, RR), crc32cb),
20571 TUEc("crc32ch",1200240, fad0f090, 3, (RR, oRR, RR), crc32ch),
20572 TUEc("crc32cw",1400240, fad0f0a0, 3, (RR, oRR, RR), crc32cw),
20573
105bde57
MW
20574 /* ARMv8.2 RAS extension. */
20575#undef ARM_VARIANT
4d1464f2 20576#define ARM_VARIANT & arm_ext_ras
105bde57 20577#undef THUMB_VARIANT
4d1464f2 20578#define THUMB_VARIANT & arm_ext_ras
105bde57
MW
20579 TUE ("esb", 320f010, f3af8010, 0, (), noargs, noargs),
20580
49e8a725
SN
20581#undef ARM_VARIANT
20582#define ARM_VARIANT & arm_ext_v8_3
20583#undef THUMB_VARIANT
20584#define THUMB_VARIANT & arm_ext_v8_3
20585 NCE (vjcvt, eb90bc0, 2, (RVS, RVD), vjcvt),
c28eeff2
SN
20586 NUF (vcmla, 0, 4, (RNDQ, RNDQ, RNDQ_RNSC, EXPi), vcmla),
20587 NUF (vcadd, 0, 4, (RNDQ, RNDQ, RNDQ, EXPi), vcadd),
49e8a725 20588
c604a79a
JW
20589#undef ARM_VARIANT
20590#define ARM_VARIANT & fpu_neon_ext_dotprod
20591#undef THUMB_VARIANT
20592#define THUMB_VARIANT & fpu_neon_ext_dotprod
20593 NUF (vsdot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_s),
20594 NUF (vudot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_u),
20595
c921be7d
NC
20596#undef ARM_VARIANT
20597#define ARM_VARIANT & fpu_fpa_ext_v1 /* Core FPA instruction set (V1). */
53c4b28b
MGD
20598#undef THUMB_VARIANT
20599#define THUMB_VARIANT NULL
c921be7d 20600
21d799b5
NC
20601 cCE("wfs", e200110, 1, (RR), rd),
20602 cCE("rfs", e300110, 1, (RR), rd),
20603 cCE("wfc", e400110, 1, (RR), rd),
20604 cCE("rfc", e500110, 1, (RR), rd),
20605
20606 cCL("ldfs", c100100, 2, (RF, ADDRGLDC), rd_cpaddr),
20607 cCL("ldfd", c108100, 2, (RF, ADDRGLDC), rd_cpaddr),
20608 cCL("ldfe", c500100, 2, (RF, ADDRGLDC), rd_cpaddr),
20609 cCL("ldfp", c508100, 2, (RF, ADDRGLDC), rd_cpaddr),
20610
20611 cCL("stfs", c000100, 2, (RF, ADDRGLDC), rd_cpaddr),
20612 cCL("stfd", c008100, 2, (RF, ADDRGLDC), rd_cpaddr),
20613 cCL("stfe", c400100, 2, (RF, ADDRGLDC), rd_cpaddr),
20614 cCL("stfp", c408100, 2, (RF, ADDRGLDC), rd_cpaddr),
20615
20616 cCL("mvfs", e008100, 2, (RF, RF_IF), rd_rm),
20617 cCL("mvfsp", e008120, 2, (RF, RF_IF), rd_rm),
20618 cCL("mvfsm", e008140, 2, (RF, RF_IF), rd_rm),
20619 cCL("mvfsz", e008160, 2, (RF, RF_IF), rd_rm),
20620 cCL("mvfd", e008180, 2, (RF, RF_IF), rd_rm),
20621 cCL("mvfdp", e0081a0, 2, (RF, RF_IF), rd_rm),
20622 cCL("mvfdm", e0081c0, 2, (RF, RF_IF), rd_rm),
20623 cCL("mvfdz", e0081e0, 2, (RF, RF_IF), rd_rm),
20624 cCL("mvfe", e088100, 2, (RF, RF_IF), rd_rm),
20625 cCL("mvfep", e088120, 2, (RF, RF_IF), rd_rm),
20626 cCL("mvfem", e088140, 2, (RF, RF_IF), rd_rm),
20627 cCL("mvfez", e088160, 2, (RF, RF_IF), rd_rm),
20628
20629 cCL("mnfs", e108100, 2, (RF, RF_IF), rd_rm),
20630 cCL("mnfsp", e108120, 2, (RF, RF_IF), rd_rm),
20631 cCL("mnfsm", e108140, 2, (RF, RF_IF), rd_rm),
20632 cCL("mnfsz", e108160, 2, (RF, RF_IF), rd_rm),
20633 cCL("mnfd", e108180, 2, (RF, RF_IF), rd_rm),
20634 cCL("mnfdp", e1081a0, 2, (RF, RF_IF), rd_rm),
20635 cCL("mnfdm", e1081c0, 2, (RF, RF_IF), rd_rm),
20636 cCL("mnfdz", e1081e0, 2, (RF, RF_IF), rd_rm),
20637 cCL("mnfe", e188100, 2, (RF, RF_IF), rd_rm),
20638 cCL("mnfep", e188120, 2, (RF, RF_IF), rd_rm),
20639 cCL("mnfem", e188140, 2, (RF, RF_IF), rd_rm),
20640 cCL("mnfez", e188160, 2, (RF, RF_IF), rd_rm),
20641
20642 cCL("abss", e208100, 2, (RF, RF_IF), rd_rm),
20643 cCL("abssp", e208120, 2, (RF, RF_IF), rd_rm),
20644 cCL("abssm", e208140, 2, (RF, RF_IF), rd_rm),
20645 cCL("abssz", e208160, 2, (RF, RF_IF), rd_rm),
20646 cCL("absd", e208180, 2, (RF, RF_IF), rd_rm),
20647 cCL("absdp", e2081a0, 2, (RF, RF_IF), rd_rm),
20648 cCL("absdm", e2081c0, 2, (RF, RF_IF), rd_rm),
20649 cCL("absdz", e2081e0, 2, (RF, RF_IF), rd_rm),
20650 cCL("abse", e288100, 2, (RF, RF_IF), rd_rm),
20651 cCL("absep", e288120, 2, (RF, RF_IF), rd_rm),
20652 cCL("absem", e288140, 2, (RF, RF_IF), rd_rm),
20653 cCL("absez", e288160, 2, (RF, RF_IF), rd_rm),
20654
20655 cCL("rnds", e308100, 2, (RF, RF_IF), rd_rm),
20656 cCL("rndsp", e308120, 2, (RF, RF_IF), rd_rm),
20657 cCL("rndsm", e308140, 2, (RF, RF_IF), rd_rm),
20658 cCL("rndsz", e308160, 2, (RF, RF_IF), rd_rm),
20659 cCL("rndd", e308180, 2, (RF, RF_IF), rd_rm),
20660 cCL("rnddp", e3081a0, 2, (RF, RF_IF), rd_rm),
20661 cCL("rnddm", e3081c0, 2, (RF, RF_IF), rd_rm),
20662 cCL("rnddz", e3081e0, 2, (RF, RF_IF), rd_rm),
20663 cCL("rnde", e388100, 2, (RF, RF_IF), rd_rm),
20664 cCL("rndep", e388120, 2, (RF, RF_IF), rd_rm),
20665 cCL("rndem", e388140, 2, (RF, RF_IF), rd_rm),
20666 cCL("rndez", e388160, 2, (RF, RF_IF), rd_rm),
20667
20668 cCL("sqts", e408100, 2, (RF, RF_IF), rd_rm),
20669 cCL("sqtsp", e408120, 2, (RF, RF_IF), rd_rm),
20670 cCL("sqtsm", e408140, 2, (RF, RF_IF), rd_rm),
20671 cCL("sqtsz", e408160, 2, (RF, RF_IF), rd_rm),
20672 cCL("sqtd", e408180, 2, (RF, RF_IF), rd_rm),
20673 cCL("sqtdp", e4081a0, 2, (RF, RF_IF), rd_rm),
20674 cCL("sqtdm", e4081c0, 2, (RF, RF_IF), rd_rm),
20675 cCL("sqtdz", e4081e0, 2, (RF, RF_IF), rd_rm),
20676 cCL("sqte", e488100, 2, (RF, RF_IF), rd_rm),
20677 cCL("sqtep", e488120, 2, (RF, RF_IF), rd_rm),
20678 cCL("sqtem", e488140, 2, (RF, RF_IF), rd_rm),
20679 cCL("sqtez", e488160, 2, (RF, RF_IF), rd_rm),
20680
20681 cCL("logs", e508100, 2, (RF, RF_IF), rd_rm),
20682 cCL("logsp", e508120, 2, (RF, RF_IF), rd_rm),
20683 cCL("logsm", e508140, 2, (RF, RF_IF), rd_rm),
20684 cCL("logsz", e508160, 2, (RF, RF_IF), rd_rm),
20685 cCL("logd", e508180, 2, (RF, RF_IF), rd_rm),
20686 cCL("logdp", e5081a0, 2, (RF, RF_IF), rd_rm),
20687 cCL("logdm", e5081c0, 2, (RF, RF_IF), rd_rm),
20688 cCL("logdz", e5081e0, 2, (RF, RF_IF), rd_rm),
20689 cCL("loge", e588100, 2, (RF, RF_IF), rd_rm),
20690 cCL("logep", e588120, 2, (RF, RF_IF), rd_rm),
20691 cCL("logem", e588140, 2, (RF, RF_IF), rd_rm),
20692 cCL("logez", e588160, 2, (RF, RF_IF), rd_rm),
20693
20694 cCL("lgns", e608100, 2, (RF, RF_IF), rd_rm),
20695 cCL("lgnsp", e608120, 2, (RF, RF_IF), rd_rm),
20696 cCL("lgnsm", e608140, 2, (RF, RF_IF), rd_rm),
20697 cCL("lgnsz", e608160, 2, (RF, RF_IF), rd_rm),
20698 cCL("lgnd", e608180, 2, (RF, RF_IF), rd_rm),
20699 cCL("lgndp", e6081a0, 2, (RF, RF_IF), rd_rm),
20700 cCL("lgndm", e6081c0, 2, (RF, RF_IF), rd_rm),
20701 cCL("lgndz", e6081e0, 2, (RF, RF_IF), rd_rm),
20702 cCL("lgne", e688100, 2, (RF, RF_IF), rd_rm),
20703 cCL("lgnep", e688120, 2, (RF, RF_IF), rd_rm),
20704 cCL("lgnem", e688140, 2, (RF, RF_IF), rd_rm),
20705 cCL("lgnez", e688160, 2, (RF, RF_IF), rd_rm),
20706
20707 cCL("exps", e708100, 2, (RF, RF_IF), rd_rm),
20708 cCL("expsp", e708120, 2, (RF, RF_IF), rd_rm),
20709 cCL("expsm", e708140, 2, (RF, RF_IF), rd_rm),
20710 cCL("expsz", e708160, 2, (RF, RF_IF), rd_rm),
20711 cCL("expd", e708180, 2, (RF, RF_IF), rd_rm),
20712 cCL("expdp", e7081a0, 2, (RF, RF_IF), rd_rm),
20713 cCL("expdm", e7081c0, 2, (RF, RF_IF), rd_rm),
20714 cCL("expdz", e7081e0, 2, (RF, RF_IF), rd_rm),
20715 cCL("expe", e788100, 2, (RF, RF_IF), rd_rm),
20716 cCL("expep", e788120, 2, (RF, RF_IF), rd_rm),
20717 cCL("expem", e788140, 2, (RF, RF_IF), rd_rm),
20718 cCL("expdz", e788160, 2, (RF, RF_IF), rd_rm),
20719
20720 cCL("sins", e808100, 2, (RF, RF_IF), rd_rm),
20721 cCL("sinsp", e808120, 2, (RF, RF_IF), rd_rm),
20722 cCL("sinsm", e808140, 2, (RF, RF_IF), rd_rm),
20723 cCL("sinsz", e808160, 2, (RF, RF_IF), rd_rm),
20724 cCL("sind", e808180, 2, (RF, RF_IF), rd_rm),
20725 cCL("sindp", e8081a0, 2, (RF, RF_IF), rd_rm),
20726 cCL("sindm", e8081c0, 2, (RF, RF_IF), rd_rm),
20727 cCL("sindz", e8081e0, 2, (RF, RF_IF), rd_rm),
20728 cCL("sine", e888100, 2, (RF, RF_IF), rd_rm),
20729 cCL("sinep", e888120, 2, (RF, RF_IF), rd_rm),
20730 cCL("sinem", e888140, 2, (RF, RF_IF), rd_rm),
20731 cCL("sinez", e888160, 2, (RF, RF_IF), rd_rm),
20732
20733 cCL("coss", e908100, 2, (RF, RF_IF), rd_rm),
20734 cCL("cossp", e908120, 2, (RF, RF_IF), rd_rm),
20735 cCL("cossm", e908140, 2, (RF, RF_IF), rd_rm),
20736 cCL("cossz", e908160, 2, (RF, RF_IF), rd_rm),
20737 cCL("cosd", e908180, 2, (RF, RF_IF), rd_rm),
20738 cCL("cosdp", e9081a0, 2, (RF, RF_IF), rd_rm),
20739 cCL("cosdm", e9081c0, 2, (RF, RF_IF), rd_rm),
20740 cCL("cosdz", e9081e0, 2, (RF, RF_IF), rd_rm),
20741 cCL("cose", e988100, 2, (RF, RF_IF), rd_rm),
20742 cCL("cosep", e988120, 2, (RF, RF_IF), rd_rm),
20743 cCL("cosem", e988140, 2, (RF, RF_IF), rd_rm),
20744 cCL("cosez", e988160, 2, (RF, RF_IF), rd_rm),
20745
20746 cCL("tans", ea08100, 2, (RF, RF_IF), rd_rm),
20747 cCL("tansp", ea08120, 2, (RF, RF_IF), rd_rm),
20748 cCL("tansm", ea08140, 2, (RF, RF_IF), rd_rm),
20749 cCL("tansz", ea08160, 2, (RF, RF_IF), rd_rm),
20750 cCL("tand", ea08180, 2, (RF, RF_IF), rd_rm),
20751 cCL("tandp", ea081a0, 2, (RF, RF_IF), rd_rm),
20752 cCL("tandm", ea081c0, 2, (RF, RF_IF), rd_rm),
20753 cCL("tandz", ea081e0, 2, (RF, RF_IF), rd_rm),
20754 cCL("tane", ea88100, 2, (RF, RF_IF), rd_rm),
20755 cCL("tanep", ea88120, 2, (RF, RF_IF), rd_rm),
20756 cCL("tanem", ea88140, 2, (RF, RF_IF), rd_rm),
20757 cCL("tanez", ea88160, 2, (RF, RF_IF), rd_rm),
20758
20759 cCL("asns", eb08100, 2, (RF, RF_IF), rd_rm),
20760 cCL("asnsp", eb08120, 2, (RF, RF_IF), rd_rm),
20761 cCL("asnsm", eb08140, 2, (RF, RF_IF), rd_rm),
20762 cCL("asnsz", eb08160, 2, (RF, RF_IF), rd_rm),
20763 cCL("asnd", eb08180, 2, (RF, RF_IF), rd_rm),
20764 cCL("asndp", eb081a0, 2, (RF, RF_IF), rd_rm),
20765 cCL("asndm", eb081c0, 2, (RF, RF_IF), rd_rm),
20766 cCL("asndz", eb081e0, 2, (RF, RF_IF), rd_rm),
20767 cCL("asne", eb88100, 2, (RF, RF_IF), rd_rm),
20768 cCL("asnep", eb88120, 2, (RF, RF_IF), rd_rm),
20769 cCL("asnem", eb88140, 2, (RF, RF_IF), rd_rm),
20770 cCL("asnez", eb88160, 2, (RF, RF_IF), rd_rm),
20771
20772 cCL("acss", ec08100, 2, (RF, RF_IF), rd_rm),
20773 cCL("acssp", ec08120, 2, (RF, RF_IF), rd_rm),
20774 cCL("acssm", ec08140, 2, (RF, RF_IF), rd_rm),
20775 cCL("acssz", ec08160, 2, (RF, RF_IF), rd_rm),
20776 cCL("acsd", ec08180, 2, (RF, RF_IF), rd_rm),
20777 cCL("acsdp", ec081a0, 2, (RF, RF_IF), rd_rm),
20778 cCL("acsdm", ec081c0, 2, (RF, RF_IF), rd_rm),
20779 cCL("acsdz", ec081e0, 2, (RF, RF_IF), rd_rm),
20780 cCL("acse", ec88100, 2, (RF, RF_IF), rd_rm),
20781 cCL("acsep", ec88120, 2, (RF, RF_IF), rd_rm),
20782 cCL("acsem", ec88140, 2, (RF, RF_IF), rd_rm),
20783 cCL("acsez", ec88160, 2, (RF, RF_IF), rd_rm),
20784
20785 cCL("atns", ed08100, 2, (RF, RF_IF), rd_rm),
20786 cCL("atnsp", ed08120, 2, (RF, RF_IF), rd_rm),
20787 cCL("atnsm", ed08140, 2, (RF, RF_IF), rd_rm),
20788 cCL("atnsz", ed08160, 2, (RF, RF_IF), rd_rm),
20789 cCL("atnd", ed08180, 2, (RF, RF_IF), rd_rm),
20790 cCL("atndp", ed081a0, 2, (RF, RF_IF), rd_rm),
20791 cCL("atndm", ed081c0, 2, (RF, RF_IF), rd_rm),
20792 cCL("atndz", ed081e0, 2, (RF, RF_IF), rd_rm),
20793 cCL("atne", ed88100, 2, (RF, RF_IF), rd_rm),
20794 cCL("atnep", ed88120, 2, (RF, RF_IF), rd_rm),
20795 cCL("atnem", ed88140, 2, (RF, RF_IF), rd_rm),
20796 cCL("atnez", ed88160, 2, (RF, RF_IF), rd_rm),
20797
20798 cCL("urds", ee08100, 2, (RF, RF_IF), rd_rm),
20799 cCL("urdsp", ee08120, 2, (RF, RF_IF), rd_rm),
20800 cCL("urdsm", ee08140, 2, (RF, RF_IF), rd_rm),
20801 cCL("urdsz", ee08160, 2, (RF, RF_IF), rd_rm),
20802 cCL("urdd", ee08180, 2, (RF, RF_IF), rd_rm),
20803 cCL("urddp", ee081a0, 2, (RF, RF_IF), rd_rm),
20804 cCL("urddm", ee081c0, 2, (RF, RF_IF), rd_rm),
20805 cCL("urddz", ee081e0, 2, (RF, RF_IF), rd_rm),
20806 cCL("urde", ee88100, 2, (RF, RF_IF), rd_rm),
20807 cCL("urdep", ee88120, 2, (RF, RF_IF), rd_rm),
20808 cCL("urdem", ee88140, 2, (RF, RF_IF), rd_rm),
20809 cCL("urdez", ee88160, 2, (RF, RF_IF), rd_rm),
20810
20811 cCL("nrms", ef08100, 2, (RF, RF_IF), rd_rm),
20812 cCL("nrmsp", ef08120, 2, (RF, RF_IF), rd_rm),
20813 cCL("nrmsm", ef08140, 2, (RF, RF_IF), rd_rm),
20814 cCL("nrmsz", ef08160, 2, (RF, RF_IF), rd_rm),
20815 cCL("nrmd", ef08180, 2, (RF, RF_IF), rd_rm),
20816 cCL("nrmdp", ef081a0, 2, (RF, RF_IF), rd_rm),
20817 cCL("nrmdm", ef081c0, 2, (RF, RF_IF), rd_rm),
20818 cCL("nrmdz", ef081e0, 2, (RF, RF_IF), rd_rm),
20819 cCL("nrme", ef88100, 2, (RF, RF_IF), rd_rm),
20820 cCL("nrmep", ef88120, 2, (RF, RF_IF), rd_rm),
20821 cCL("nrmem", ef88140, 2, (RF, RF_IF), rd_rm),
20822 cCL("nrmez", ef88160, 2, (RF, RF_IF), rd_rm),
20823
20824 cCL("adfs", e000100, 3, (RF, RF, RF_IF), rd_rn_rm),
20825 cCL("adfsp", e000120, 3, (RF, RF, RF_IF), rd_rn_rm),
20826 cCL("adfsm", e000140, 3, (RF, RF, RF_IF), rd_rn_rm),
20827 cCL("adfsz", e000160, 3, (RF, RF, RF_IF), rd_rn_rm),
20828 cCL("adfd", e000180, 3, (RF, RF, RF_IF), rd_rn_rm),
20829 cCL("adfdp", e0001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20830 cCL("adfdm", e0001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20831 cCL("adfdz", e0001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20832 cCL("adfe", e080100, 3, (RF, RF, RF_IF), rd_rn_rm),
20833 cCL("adfep", e080120, 3, (RF, RF, RF_IF), rd_rn_rm),
20834 cCL("adfem", e080140, 3, (RF, RF, RF_IF), rd_rn_rm),
20835 cCL("adfez", e080160, 3, (RF, RF, RF_IF), rd_rn_rm),
20836
20837 cCL("sufs", e200100, 3, (RF, RF, RF_IF), rd_rn_rm),
20838 cCL("sufsp", e200120, 3, (RF, RF, RF_IF), rd_rn_rm),
20839 cCL("sufsm", e200140, 3, (RF, RF, RF_IF), rd_rn_rm),
20840 cCL("sufsz", e200160, 3, (RF, RF, RF_IF), rd_rn_rm),
20841 cCL("sufd", e200180, 3, (RF, RF, RF_IF), rd_rn_rm),
20842 cCL("sufdp", e2001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20843 cCL("sufdm", e2001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20844 cCL("sufdz", e2001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20845 cCL("sufe", e280100, 3, (RF, RF, RF_IF), rd_rn_rm),
20846 cCL("sufep", e280120, 3, (RF, RF, RF_IF), rd_rn_rm),
20847 cCL("sufem", e280140, 3, (RF, RF, RF_IF), rd_rn_rm),
20848 cCL("sufez", e280160, 3, (RF, RF, RF_IF), rd_rn_rm),
20849
20850 cCL("rsfs", e300100, 3, (RF, RF, RF_IF), rd_rn_rm),
20851 cCL("rsfsp", e300120, 3, (RF, RF, RF_IF), rd_rn_rm),
20852 cCL("rsfsm", e300140, 3, (RF, RF, RF_IF), rd_rn_rm),
20853 cCL("rsfsz", e300160, 3, (RF, RF, RF_IF), rd_rn_rm),
20854 cCL("rsfd", e300180, 3, (RF, RF, RF_IF), rd_rn_rm),
20855 cCL("rsfdp", e3001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20856 cCL("rsfdm", e3001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20857 cCL("rsfdz", e3001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20858 cCL("rsfe", e380100, 3, (RF, RF, RF_IF), rd_rn_rm),
20859 cCL("rsfep", e380120, 3, (RF, RF, RF_IF), rd_rn_rm),
20860 cCL("rsfem", e380140, 3, (RF, RF, RF_IF), rd_rn_rm),
20861 cCL("rsfez", e380160, 3, (RF, RF, RF_IF), rd_rn_rm),
20862
20863 cCL("mufs", e100100, 3, (RF, RF, RF_IF), rd_rn_rm),
20864 cCL("mufsp", e100120, 3, (RF, RF, RF_IF), rd_rn_rm),
20865 cCL("mufsm", e100140, 3, (RF, RF, RF_IF), rd_rn_rm),
20866 cCL("mufsz", e100160, 3, (RF, RF, RF_IF), rd_rn_rm),
20867 cCL("mufd", e100180, 3, (RF, RF, RF_IF), rd_rn_rm),
20868 cCL("mufdp", e1001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20869 cCL("mufdm", e1001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20870 cCL("mufdz", e1001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20871 cCL("mufe", e180100, 3, (RF, RF, RF_IF), rd_rn_rm),
20872 cCL("mufep", e180120, 3, (RF, RF, RF_IF), rd_rn_rm),
20873 cCL("mufem", e180140, 3, (RF, RF, RF_IF), rd_rn_rm),
20874 cCL("mufez", e180160, 3, (RF, RF, RF_IF), rd_rn_rm),
20875
20876 cCL("dvfs", e400100, 3, (RF, RF, RF_IF), rd_rn_rm),
20877 cCL("dvfsp", e400120, 3, (RF, RF, RF_IF), rd_rn_rm),
20878 cCL("dvfsm", e400140, 3, (RF, RF, RF_IF), rd_rn_rm),
20879 cCL("dvfsz", e400160, 3, (RF, RF, RF_IF), rd_rn_rm),
20880 cCL("dvfd", e400180, 3, (RF, RF, RF_IF), rd_rn_rm),
20881 cCL("dvfdp", e4001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20882 cCL("dvfdm", e4001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20883 cCL("dvfdz", e4001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20884 cCL("dvfe", e480100, 3, (RF, RF, RF_IF), rd_rn_rm),
20885 cCL("dvfep", e480120, 3, (RF, RF, RF_IF), rd_rn_rm),
20886 cCL("dvfem", e480140, 3, (RF, RF, RF_IF), rd_rn_rm),
20887 cCL("dvfez", e480160, 3, (RF, RF, RF_IF), rd_rn_rm),
20888
20889 cCL("rdfs", e500100, 3, (RF, RF, RF_IF), rd_rn_rm),
20890 cCL("rdfsp", e500120, 3, (RF, RF, RF_IF), rd_rn_rm),
20891 cCL("rdfsm", e500140, 3, (RF, RF, RF_IF), rd_rn_rm),
20892 cCL("rdfsz", e500160, 3, (RF, RF, RF_IF), rd_rn_rm),
20893 cCL("rdfd", e500180, 3, (RF, RF, RF_IF), rd_rn_rm),
20894 cCL("rdfdp", e5001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20895 cCL("rdfdm", e5001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20896 cCL("rdfdz", e5001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20897 cCL("rdfe", e580100, 3, (RF, RF, RF_IF), rd_rn_rm),
20898 cCL("rdfep", e580120, 3, (RF, RF, RF_IF), rd_rn_rm),
20899 cCL("rdfem", e580140, 3, (RF, RF, RF_IF), rd_rn_rm),
20900 cCL("rdfez", e580160, 3, (RF, RF, RF_IF), rd_rn_rm),
20901
20902 cCL("pows", e600100, 3, (RF, RF, RF_IF), rd_rn_rm),
20903 cCL("powsp", e600120, 3, (RF, RF, RF_IF), rd_rn_rm),
20904 cCL("powsm", e600140, 3, (RF, RF, RF_IF), rd_rn_rm),
20905 cCL("powsz", e600160, 3, (RF, RF, RF_IF), rd_rn_rm),
20906 cCL("powd", e600180, 3, (RF, RF, RF_IF), rd_rn_rm),
20907 cCL("powdp", e6001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20908 cCL("powdm", e6001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20909 cCL("powdz", e6001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20910 cCL("powe", e680100, 3, (RF, RF, RF_IF), rd_rn_rm),
20911 cCL("powep", e680120, 3, (RF, RF, RF_IF), rd_rn_rm),
20912 cCL("powem", e680140, 3, (RF, RF, RF_IF), rd_rn_rm),
20913 cCL("powez", e680160, 3, (RF, RF, RF_IF), rd_rn_rm),
20914
20915 cCL("rpws", e700100, 3, (RF, RF, RF_IF), rd_rn_rm),
20916 cCL("rpwsp", e700120, 3, (RF, RF, RF_IF), rd_rn_rm),
20917 cCL("rpwsm", e700140, 3, (RF, RF, RF_IF), rd_rn_rm),
20918 cCL("rpwsz", e700160, 3, (RF, RF, RF_IF), rd_rn_rm),
20919 cCL("rpwd", e700180, 3, (RF, RF, RF_IF), rd_rn_rm),
20920 cCL("rpwdp", e7001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20921 cCL("rpwdm", e7001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20922 cCL("rpwdz", e7001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20923 cCL("rpwe", e780100, 3, (RF, RF, RF_IF), rd_rn_rm),
20924 cCL("rpwep", e780120, 3, (RF, RF, RF_IF), rd_rn_rm),
20925 cCL("rpwem", e780140, 3, (RF, RF, RF_IF), rd_rn_rm),
20926 cCL("rpwez", e780160, 3, (RF, RF, RF_IF), rd_rn_rm),
20927
20928 cCL("rmfs", e800100, 3, (RF, RF, RF_IF), rd_rn_rm),
20929 cCL("rmfsp", e800120, 3, (RF, RF, RF_IF), rd_rn_rm),
20930 cCL("rmfsm", e800140, 3, (RF, RF, RF_IF), rd_rn_rm),
20931 cCL("rmfsz", e800160, 3, (RF, RF, RF_IF), rd_rn_rm),
20932 cCL("rmfd", e800180, 3, (RF, RF, RF_IF), rd_rn_rm),
20933 cCL("rmfdp", e8001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20934 cCL("rmfdm", e8001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20935 cCL("rmfdz", e8001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20936 cCL("rmfe", e880100, 3, (RF, RF, RF_IF), rd_rn_rm),
20937 cCL("rmfep", e880120, 3, (RF, RF, RF_IF), rd_rn_rm),
20938 cCL("rmfem", e880140, 3, (RF, RF, RF_IF), rd_rn_rm),
20939 cCL("rmfez", e880160, 3, (RF, RF, RF_IF), rd_rn_rm),
20940
20941 cCL("fmls", e900100, 3, (RF, RF, RF_IF), rd_rn_rm),
20942 cCL("fmlsp", e900120, 3, (RF, RF, RF_IF), rd_rn_rm),
20943 cCL("fmlsm", e900140, 3, (RF, RF, RF_IF), rd_rn_rm),
20944 cCL("fmlsz", e900160, 3, (RF, RF, RF_IF), rd_rn_rm),
20945 cCL("fmld", e900180, 3, (RF, RF, RF_IF), rd_rn_rm),
20946 cCL("fmldp", e9001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20947 cCL("fmldm", e9001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20948 cCL("fmldz", e9001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20949 cCL("fmle", e980100, 3, (RF, RF, RF_IF), rd_rn_rm),
20950 cCL("fmlep", e980120, 3, (RF, RF, RF_IF), rd_rn_rm),
20951 cCL("fmlem", e980140, 3, (RF, RF, RF_IF), rd_rn_rm),
20952 cCL("fmlez", e980160, 3, (RF, RF, RF_IF), rd_rn_rm),
20953
20954 cCL("fdvs", ea00100, 3, (RF, RF, RF_IF), rd_rn_rm),
20955 cCL("fdvsp", ea00120, 3, (RF, RF, RF_IF), rd_rn_rm),
20956 cCL("fdvsm", ea00140, 3, (RF, RF, RF_IF), rd_rn_rm),
20957 cCL("fdvsz", ea00160, 3, (RF, RF, RF_IF), rd_rn_rm),
20958 cCL("fdvd", ea00180, 3, (RF, RF, RF_IF), rd_rn_rm),
20959 cCL("fdvdp", ea001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20960 cCL("fdvdm", ea001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20961 cCL("fdvdz", ea001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20962 cCL("fdve", ea80100, 3, (RF, RF, RF_IF), rd_rn_rm),
20963 cCL("fdvep", ea80120, 3, (RF, RF, RF_IF), rd_rn_rm),
20964 cCL("fdvem", ea80140, 3, (RF, RF, RF_IF), rd_rn_rm),
20965 cCL("fdvez", ea80160, 3, (RF, RF, RF_IF), rd_rn_rm),
20966
20967 cCL("frds", eb00100, 3, (RF, RF, RF_IF), rd_rn_rm),
20968 cCL("frdsp", eb00120, 3, (RF, RF, RF_IF), rd_rn_rm),
20969 cCL("frdsm", eb00140, 3, (RF, RF, RF_IF), rd_rn_rm),
20970 cCL("frdsz", eb00160, 3, (RF, RF, RF_IF), rd_rn_rm),
20971 cCL("frdd", eb00180, 3, (RF, RF, RF_IF), rd_rn_rm),
20972 cCL("frddp", eb001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20973 cCL("frddm", eb001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20974 cCL("frddz", eb001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20975 cCL("frde", eb80100, 3, (RF, RF, RF_IF), rd_rn_rm),
20976 cCL("frdep", eb80120, 3, (RF, RF, RF_IF), rd_rn_rm),
20977 cCL("frdem", eb80140, 3, (RF, RF, RF_IF), rd_rn_rm),
20978 cCL("frdez", eb80160, 3, (RF, RF, RF_IF), rd_rn_rm),
20979
20980 cCL("pols", ec00100, 3, (RF, RF, RF_IF), rd_rn_rm),
20981 cCL("polsp", ec00120, 3, (RF, RF, RF_IF), rd_rn_rm),
20982 cCL("polsm", ec00140, 3, (RF, RF, RF_IF), rd_rn_rm),
20983 cCL("polsz", ec00160, 3, (RF, RF, RF_IF), rd_rn_rm),
20984 cCL("pold", ec00180, 3, (RF, RF, RF_IF), rd_rn_rm),
20985 cCL("poldp", ec001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
20986 cCL("poldm", ec001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
20987 cCL("poldz", ec001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
20988 cCL("pole", ec80100, 3, (RF, RF, RF_IF), rd_rn_rm),
20989 cCL("polep", ec80120, 3, (RF, RF, RF_IF), rd_rn_rm),
20990 cCL("polem", ec80140, 3, (RF, RF, RF_IF), rd_rn_rm),
20991 cCL("polez", ec80160, 3, (RF, RF, RF_IF), rd_rn_rm),
20992
20993 cCE("cmf", e90f110, 2, (RF, RF_IF), fpa_cmp),
20994 C3E("cmfe", ed0f110, 2, (RF, RF_IF), fpa_cmp),
20995 cCE("cnf", eb0f110, 2, (RF, RF_IF), fpa_cmp),
20996 C3E("cnfe", ef0f110, 2, (RF, RF_IF), fpa_cmp),
20997
20998 cCL("flts", e000110, 2, (RF, RR), rn_rd),
20999 cCL("fltsp", e000130, 2, (RF, RR), rn_rd),
21000 cCL("fltsm", e000150, 2, (RF, RR), rn_rd),
21001 cCL("fltsz", e000170, 2, (RF, RR), rn_rd),
21002 cCL("fltd", e000190, 2, (RF, RR), rn_rd),
21003 cCL("fltdp", e0001b0, 2, (RF, RR), rn_rd),
21004 cCL("fltdm", e0001d0, 2, (RF, RR), rn_rd),
21005 cCL("fltdz", e0001f0, 2, (RF, RR), rn_rd),
21006 cCL("flte", e080110, 2, (RF, RR), rn_rd),
21007 cCL("fltep", e080130, 2, (RF, RR), rn_rd),
21008 cCL("fltem", e080150, 2, (RF, RR), rn_rd),
21009 cCL("fltez", e080170, 2, (RF, RR), rn_rd),
b99bd4ef 21010
c19d1205
ZW
21011 /* The implementation of the FIX instruction is broken on some
21012 assemblers, in that it accepts a precision specifier as well as a
21013 rounding specifier, despite the fact that this is meaningless.
21014 To be more compatible, we accept it as well, though of course it
21015 does not set any bits. */
21d799b5
NC
21016 cCE("fix", e100110, 2, (RR, RF), rd_rm),
21017 cCL("fixp", e100130, 2, (RR, RF), rd_rm),
21018 cCL("fixm", e100150, 2, (RR, RF), rd_rm),
21019 cCL("fixz", e100170, 2, (RR, RF), rd_rm),
21020 cCL("fixsp", e100130, 2, (RR, RF), rd_rm),
21021 cCL("fixsm", e100150, 2, (RR, RF), rd_rm),
21022 cCL("fixsz", e100170, 2, (RR, RF), rd_rm),
21023 cCL("fixdp", e100130, 2, (RR, RF), rd_rm),
21024 cCL("fixdm", e100150, 2, (RR, RF), rd_rm),
21025 cCL("fixdz", e100170, 2, (RR, RF), rd_rm),
21026 cCL("fixep", e100130, 2, (RR, RF), rd_rm),
21027 cCL("fixem", e100150, 2, (RR, RF), rd_rm),
21028 cCL("fixez", e100170, 2, (RR, RF), rd_rm),
bfae80f2 21029
c19d1205 21030 /* Instructions that were new with the real FPA, call them V2. */
c921be7d
NC
21031#undef ARM_VARIANT
21032#define ARM_VARIANT & fpu_fpa_ext_v2
21033
21d799b5
NC
21034 cCE("lfm", c100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
21035 cCL("lfmfd", c900200, 3, (RF, I4b, ADDR), fpa_ldmstm),
21036 cCL("lfmea", d100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
21037 cCE("sfm", c000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
21038 cCL("sfmfd", d000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
21039 cCL("sfmea", c800200, 3, (RF, I4b, ADDR), fpa_ldmstm),
c19d1205 21040
c921be7d
NC
21041#undef ARM_VARIANT
21042#define ARM_VARIANT & fpu_vfp_ext_v1xd /* VFP V1xD (single precision). */
21043
c19d1205 21044 /* Moves and type conversions. */
21d799b5
NC
21045 cCE("fcpys", eb00a40, 2, (RVS, RVS), vfp_sp_monadic),
21046 cCE("fmrs", e100a10, 2, (RR, RVS), vfp_reg_from_sp),
21047 cCE("fmsr", e000a10, 2, (RVS, RR), vfp_sp_from_reg),
21048 cCE("fmstat", ef1fa10, 0, (), noargs),
7465e07a
NC
21049 cCE("vmrs", ef00a10, 2, (APSR_RR, RVC), vmrs),
21050 cCE("vmsr", ee00a10, 2, (RVC, RR), vmsr),
21d799b5
NC
21051 cCE("fsitos", eb80ac0, 2, (RVS, RVS), vfp_sp_monadic),
21052 cCE("fuitos", eb80a40, 2, (RVS, RVS), vfp_sp_monadic),
21053 cCE("ftosis", ebd0a40, 2, (RVS, RVS), vfp_sp_monadic),
21054 cCE("ftosizs", ebd0ac0, 2, (RVS, RVS), vfp_sp_monadic),
21055 cCE("ftouis", ebc0a40, 2, (RVS, RVS), vfp_sp_monadic),
21056 cCE("ftouizs", ebc0ac0, 2, (RVS, RVS), vfp_sp_monadic),
21057 cCE("fmrx", ef00a10, 2, (RR, RVC), rd_rn),
21058 cCE("fmxr", ee00a10, 2, (RVC, RR), rn_rd),
c19d1205
ZW
21059
21060 /* Memory operations. */
21d799b5
NC
21061 cCE("flds", d100a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
21062 cCE("fsts", d000a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
55881a11
MGD
21063 cCE("fldmias", c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
21064 cCE("fldmfds", c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
21065 cCE("fldmdbs", d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
21066 cCE("fldmeas", d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
21067 cCE("fldmiax", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
21068 cCE("fldmfdx", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
21069 cCE("fldmdbx", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
21070 cCE("fldmeax", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
21071 cCE("fstmias", c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
21072 cCE("fstmeas", c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
21073 cCE("fstmdbs", d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
21074 cCE("fstmfds", d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
21075 cCE("fstmiax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
21076 cCE("fstmeax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
21077 cCE("fstmdbx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
21078 cCE("fstmfdx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
bfae80f2 21079
c19d1205 21080 /* Monadic operations. */
21d799b5
NC
21081 cCE("fabss", eb00ac0, 2, (RVS, RVS), vfp_sp_monadic),
21082 cCE("fnegs", eb10a40, 2, (RVS, RVS), vfp_sp_monadic),
21083 cCE("fsqrts", eb10ac0, 2, (RVS, RVS), vfp_sp_monadic),
c19d1205
ZW
21084
21085 /* Dyadic operations. */
21d799b5
NC
21086 cCE("fadds", e300a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21087 cCE("fsubs", e300a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21088 cCE("fmuls", e200a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21089 cCE("fdivs", e800a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21090 cCE("fmacs", e000a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21091 cCE("fmscs", e100a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21092 cCE("fnmuls", e200a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21093 cCE("fnmacs", e000a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21094 cCE("fnmscs", e100a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
b99bd4ef 21095
c19d1205 21096 /* Comparisons. */
21d799b5
NC
21097 cCE("fcmps", eb40a40, 2, (RVS, RVS), vfp_sp_monadic),
21098 cCE("fcmpzs", eb50a40, 1, (RVS), vfp_sp_compare_z),
21099 cCE("fcmpes", eb40ac0, 2, (RVS, RVS), vfp_sp_monadic),
21100 cCE("fcmpezs", eb50ac0, 1, (RVS), vfp_sp_compare_z),
b99bd4ef 21101
62f3b8c8
PB
21102 /* Double precision load/store are still present on single precision
21103 implementations. */
21104 cCE("fldd", d100b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
21105 cCE("fstd", d000b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
55881a11
MGD
21106 cCE("fldmiad", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
21107 cCE("fldmfdd", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
21108 cCE("fldmdbd", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
21109 cCE("fldmead", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
21110 cCE("fstmiad", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
21111 cCE("fstmead", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
21112 cCE("fstmdbd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
21113 cCE("fstmfdd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
62f3b8c8 21114
c921be7d
NC
21115#undef ARM_VARIANT
21116#define ARM_VARIANT & fpu_vfp_ext_v1 /* VFP V1 (Double precision). */
21117
c19d1205 21118 /* Moves and type conversions. */
21d799b5
NC
21119 cCE("fcpyd", eb00b40, 2, (RVD, RVD), vfp_dp_rd_rm),
21120 cCE("fcvtds", eb70ac0, 2, (RVD, RVS), vfp_dp_sp_cvt),
21121 cCE("fcvtsd", eb70bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
21122 cCE("fmdhr", e200b10, 2, (RVD, RR), vfp_dp_rn_rd),
21123 cCE("fmdlr", e000b10, 2, (RVD, RR), vfp_dp_rn_rd),
21124 cCE("fmrdh", e300b10, 2, (RR, RVD), vfp_dp_rd_rn),
21125 cCE("fmrdl", e100b10, 2, (RR, RVD), vfp_dp_rd_rn),
21126 cCE("fsitod", eb80bc0, 2, (RVD, RVS), vfp_dp_sp_cvt),
21127 cCE("fuitod", eb80b40, 2, (RVD, RVS), vfp_dp_sp_cvt),
21128 cCE("ftosid", ebd0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
21129 cCE("ftosizd", ebd0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
21130 cCE("ftouid", ebc0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
21131 cCE("ftouizd", ebc0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
c19d1205 21132
c19d1205 21133 /* Monadic operations. */
21d799b5
NC
21134 cCE("fabsd", eb00bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
21135 cCE("fnegd", eb10b40, 2, (RVD, RVD), vfp_dp_rd_rm),
21136 cCE("fsqrtd", eb10bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
c19d1205
ZW
21137
21138 /* Dyadic operations. */
21d799b5
NC
21139 cCE("faddd", e300b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21140 cCE("fsubd", e300b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21141 cCE("fmuld", e200b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21142 cCE("fdivd", e800b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21143 cCE("fmacd", e000b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21144 cCE("fmscd", e100b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21145 cCE("fnmuld", e200b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21146 cCE("fnmacd", e000b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21147 cCE("fnmscd", e100b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
b99bd4ef 21148
c19d1205 21149 /* Comparisons. */
21d799b5
NC
21150 cCE("fcmpd", eb40b40, 2, (RVD, RVD), vfp_dp_rd_rm),
21151 cCE("fcmpzd", eb50b40, 1, (RVD), vfp_dp_rd),
21152 cCE("fcmped", eb40bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
21153 cCE("fcmpezd", eb50bc0, 1, (RVD), vfp_dp_rd),
c19d1205 21154
c921be7d
NC
21155#undef ARM_VARIANT
21156#define ARM_VARIANT & fpu_vfp_ext_v2
21157
21d799b5
NC
21158 cCE("fmsrr", c400a10, 3, (VRSLST, RR, RR), vfp_sp2_from_reg2),
21159 cCE("fmrrs", c500a10, 3, (RR, RR, VRSLST), vfp_reg2_from_sp2),
21160 cCE("fmdrr", c400b10, 3, (RVD, RR, RR), vfp_dp_rm_rd_rn),
21161 cCE("fmrrd", c500b10, 3, (RR, RR, RVD), vfp_dp_rd_rn_rm),
5287ad62 21162
037e8744
JB
21163/* Instructions which may belong to either the Neon or VFP instruction sets.
21164 Individual encoder functions perform additional architecture checks. */
c921be7d
NC
21165#undef ARM_VARIANT
21166#define ARM_VARIANT & fpu_vfp_ext_v1xd
21167#undef THUMB_VARIANT
21168#define THUMB_VARIANT & fpu_vfp_ext_v1xd
21169
037e8744
JB
21170 /* These mnemonics are unique to VFP. */
21171 NCE(vsqrt, 0, 2, (RVSD, RVSD), vfp_nsyn_sqrt),
21172 NCE(vdiv, 0, 3, (RVSD, RVSD, RVSD), vfp_nsyn_div),
21d799b5
NC
21173 nCE(vnmul, _vnmul, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
21174 nCE(vnmla, _vnmla, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
21175 nCE(vnmls, _vnmls, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
aacf0b33
KT
21176 nCE(vcmp, _vcmp, 2, (RVSD, RSVD_FI0), vfp_nsyn_cmp),
21177 nCE(vcmpe, _vcmpe, 2, (RVSD, RSVD_FI0), vfp_nsyn_cmp),
037e8744
JB
21178 NCE(vpush, 0, 1, (VRSDLST), vfp_nsyn_push),
21179 NCE(vpop, 0, 1, (VRSDLST), vfp_nsyn_pop),
21180 NCE(vcvtz, 0, 2, (RVSD, RVSD), vfp_nsyn_cvtz),
21181
21182 /* Mnemonics shared by Neon and VFP. */
21d799b5
NC
21183 nCEF(vmul, _vmul, 3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mul),
21184 nCEF(vmla, _vmla, 3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
21185 nCEF(vmls, _vmls, 3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
037e8744 21186
21d799b5
NC
21187 nCEF(vadd, _vadd, 3, (RNSDQ, oRNSDQ, RNSDQ), neon_addsub_if_i),
21188 nCEF(vsub, _vsub, 3, (RNSDQ, oRNSDQ, RNSDQ), neon_addsub_if_i),
037e8744
JB
21189
21190 NCEF(vabs, 1b10300, 2, (RNSDQ, RNSDQ), neon_abs_neg),
21191 NCEF(vneg, 1b10380, 2, (RNSDQ, RNSDQ), neon_abs_neg),
21192
55881a11
MGD
21193 NCE(vldm, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
21194 NCE(vldmia, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
21195 NCE(vldmdb, d100b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
21196 NCE(vstm, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
21197 NCE(vstmia, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
21198 NCE(vstmdb, d000b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
4962c51a
MS
21199 NCE(vldr, d100b00, 2, (RVSD, ADDRGLDC), neon_ldr_str),
21200 NCE(vstr, d000b00, 2, (RVSD, ADDRGLDC), neon_ldr_str),
037e8744 21201
5f1af56b 21202 nCEF(vcvt, _vcvt, 3, (RNSDQ, RNSDQ, oI32z), neon_cvt),
e3e535bc 21203 nCEF(vcvtr, _vcvt, 2, (RNSDQ, RNSDQ), neon_cvtr),
c70a8987
MGD
21204 NCEF(vcvtb, eb20a40, 2, (RVSD, RVSD), neon_cvtb),
21205 NCEF(vcvtt, eb20a40, 2, (RVSD, RVSD), neon_cvtt),
f31fef98 21206
037e8744
JB
21207
21208 /* NOTE: All VMOV encoding is special-cased! */
21209 NCE(vmov, 0, 1, (VMOV), neon_mov),
21210 NCE(vmovq, 0, 1, (VMOV), neon_mov),
21211
9db2f6b4
RL
21212#undef ARM_VARIANT
21213#define ARM_VARIANT & arm_ext_fp16
21214#undef THUMB_VARIANT
21215#define THUMB_VARIANT & arm_ext_fp16
21216 /* New instructions added from v8.2, allowing the extraction and insertion of
21217 the upper 16 bits of a 32-bit vector register. */
21218 NCE (vmovx, eb00a40, 2, (RVS, RVS), neon_movhf),
21219 NCE (vins, eb00ac0, 2, (RVS, RVS), neon_movhf),
21220
dec41383
JW
21221 /* New backported fma/fms instructions optional in v8.2. */
21222 NCE (vfmal, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmal),
21223 NCE (vfmsl, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmsl),
21224
c921be7d
NC
21225#undef THUMB_VARIANT
21226#define THUMB_VARIANT & fpu_neon_ext_v1
21227#undef ARM_VARIANT
21228#define ARM_VARIANT & fpu_neon_ext_v1
21229
5287ad62
JB
21230 /* Data processing with three registers of the same length. */
21231 /* integer ops, valid types S8 S16 S32 U8 U16 U32. */
21232 NUF(vaba, 0000710, 3, (RNDQ, RNDQ, RNDQ), neon_dyadic_i_su),
21233 NUF(vabaq, 0000710, 3, (RNQ, RNQ, RNQ), neon_dyadic_i_su),
21234 NUF(vhadd, 0000000, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i_su),
21235 NUF(vhaddq, 0000000, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
21236 NUF(vrhadd, 0000100, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i_su),
21237 NUF(vrhaddq, 0000100, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
21238 NUF(vhsub, 0000200, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i_su),
21239 NUF(vhsubq, 0000200, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
21240 /* integer ops, valid types S8 S16 S32 S64 U8 U16 U32 U64. */
21241 NUF(vqadd, 0000010, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i64_su),
21242 NUF(vqaddq, 0000010, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
21243 NUF(vqsub, 0000210, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i64_su),
21244 NUF(vqsubq, 0000210, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
627907b7
JB
21245 NUF(vrshl, 0000500, 3, (RNDQ, oRNDQ, RNDQ), neon_rshl),
21246 NUF(vrshlq, 0000500, 3, (RNQ, oRNQ, RNQ), neon_rshl),
21247 NUF(vqrshl, 0000510, 3, (RNDQ, oRNDQ, RNDQ), neon_rshl),
21248 NUF(vqrshlq, 0000510, 3, (RNQ, oRNQ, RNQ), neon_rshl),
5287ad62
JB
21249 /* If not immediate, fall back to neon_dyadic_i64_su.
21250 shl_imm should accept I8 I16 I32 I64,
21251 qshl_imm should accept S8 S16 S32 S64 U8 U16 U32 U64. */
21d799b5
NC
21252 nUF(vshl, _vshl, 3, (RNDQ, oRNDQ, RNDQ_I63b), neon_shl_imm),
21253 nUF(vshlq, _vshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_shl_imm),
21254 nUF(vqshl, _vqshl, 3, (RNDQ, oRNDQ, RNDQ_I63b), neon_qshl_imm),
21255 nUF(vqshlq, _vqshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_qshl_imm),
5287ad62 21256 /* Logic ops, types optional & ignored. */
4316f0d2
DG
21257 nUF(vand, _vand, 3, (RNDQ, oRNDQ, RNDQ_Ibig), neon_logic),
21258 nUF(vandq, _vand, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
21259 nUF(vbic, _vbic, 3, (RNDQ, oRNDQ, RNDQ_Ibig), neon_logic),
21260 nUF(vbicq, _vbic, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
21261 nUF(vorr, _vorr, 3, (RNDQ, oRNDQ, RNDQ_Ibig), neon_logic),
21262 nUF(vorrq, _vorr, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
21263 nUF(vorn, _vorn, 3, (RNDQ, oRNDQ, RNDQ_Ibig), neon_logic),
21264 nUF(vornq, _vorn, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
21265 nUF(veor, _veor, 3, (RNDQ, oRNDQ, RNDQ), neon_logic),
21266 nUF(veorq, _veor, 3, (RNQ, oRNQ, RNQ), neon_logic),
5287ad62
JB
21267 /* Bitfield ops, untyped. */
21268 NUF(vbsl, 1100110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
21269 NUF(vbslq, 1100110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
21270 NUF(vbit, 1200110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
21271 NUF(vbitq, 1200110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
21272 NUF(vbif, 1300110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
21273 NUF(vbifq, 1300110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
cc933301 21274 /* Int and float variants, types S8 S16 S32 U8 U16 U32 F16 F32. */
21d799b5
NC
21275 nUF(vabd, _vabd, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_if_su),
21276 nUF(vabdq, _vabd, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21277 nUF(vmax, _vmax, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_if_su),
21278 nUF(vmaxq, _vmax, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21279 nUF(vmin, _vmin, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_if_su),
21280 nUF(vminq, _vmin, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
5287ad62
JB
21281 /* Comparisons. Types S8 S16 S32 U8 U16 U32 F32. Non-immediate versions fall
21282 back to neon_dyadic_if_su. */
21d799b5
NC
21283 nUF(vcge, _vcge, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
21284 nUF(vcgeq, _vcge, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
21285 nUF(vcgt, _vcgt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
21286 nUF(vcgtq, _vcgt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
21287 nUF(vclt, _vclt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
21288 nUF(vcltq, _vclt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
21289 nUF(vcle, _vcle, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
21290 nUF(vcleq, _vcle, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
428e3f1f 21291 /* Comparison. Type I8 I16 I32 F32. */
21d799b5
NC
21292 nUF(vceq, _vceq, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_ceq),
21293 nUF(vceqq, _vceq, 3, (RNQ, oRNQ, RNDQ_I0), neon_ceq),
5287ad62 21294 /* As above, D registers only. */
21d799b5
NC
21295 nUF(vpmax, _vpmax, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
21296 nUF(vpmin, _vpmin, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
5287ad62 21297 /* Int and float variants, signedness unimportant. */
21d799b5
NC
21298 nUF(vmlaq, _vmla, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
21299 nUF(vmlsq, _vmls, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
21300 nUF(vpadd, _vpadd, 3, (RND, oRND, RND), neon_dyadic_if_i_d),
5287ad62 21301 /* Add/sub take types I8 I16 I32 I64 F32. */
21d799b5
NC
21302 nUF(vaddq, _vadd, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
21303 nUF(vsubq, _vsub, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
5287ad62
JB
21304 /* vtst takes sizes 8, 16, 32. */
21305 NUF(vtst, 0000810, 3, (RNDQ, oRNDQ, RNDQ), neon_tst),
21306 NUF(vtstq, 0000810, 3, (RNQ, oRNQ, RNQ), neon_tst),
21307 /* VMUL takes I8 I16 I32 F32 P8. */
21d799b5 21308 nUF(vmulq, _vmul, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mul),
5287ad62 21309 /* VQD{R}MULH takes S16 S32. */
21d799b5
NC
21310 nUF(vqdmulh, _vqdmulh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qdmulh),
21311 nUF(vqdmulhq, _vqdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
21312 nUF(vqrdmulh, _vqrdmulh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qdmulh),
21313 nUF(vqrdmulhq, _vqrdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
5287ad62
JB
21314 NUF(vacge, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
21315 NUF(vacgeq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
21316 NUF(vacgt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
21317 NUF(vacgtq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
92559b5b
PB
21318 NUF(vaclt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
21319 NUF(vacltq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
21320 NUF(vacle, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
21321 NUF(vacleq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
5287ad62
JB
21322 NUF(vrecps, 0000f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
21323 NUF(vrecpsq, 0000f10, 3, (RNQ, oRNQ, RNQ), neon_step),
21324 NUF(vrsqrts, 0200f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
21325 NUF(vrsqrtsq, 0200f10, 3, (RNQ, oRNQ, RNQ), neon_step),
d6b4b13e 21326 /* ARM v8.1 extension. */
643afb90
MW
21327 nUF (vqrdmlah, _vqrdmlah, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qrdmlah),
21328 nUF (vqrdmlahq, _vqrdmlah, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
21329 nUF (vqrdmlsh, _vqrdmlsh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qrdmlah),
21330 nUF (vqrdmlshq, _vqrdmlsh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
5287ad62
JB
21331
21332 /* Two address, int/float. Types S8 S16 S32 F32. */
5287ad62 21333 NUF(vabsq, 1b10300, 2, (RNQ, RNQ), neon_abs_neg),
5287ad62
JB
21334 NUF(vnegq, 1b10380, 2, (RNQ, RNQ), neon_abs_neg),
21335
21336 /* Data processing with two registers and a shift amount. */
21337 /* Right shifts, and variants with rounding.
21338 Types accepted S8 S16 S32 S64 U8 U16 U32 U64. */
21339 NUF(vshr, 0800010, 3, (RNDQ, oRNDQ, I64z), neon_rshift_round_imm),
21340 NUF(vshrq, 0800010, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
21341 NUF(vrshr, 0800210, 3, (RNDQ, oRNDQ, I64z), neon_rshift_round_imm),
21342 NUF(vrshrq, 0800210, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
21343 NUF(vsra, 0800110, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
21344 NUF(vsraq, 0800110, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
21345 NUF(vrsra, 0800310, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
21346 NUF(vrsraq, 0800310, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
21347 /* Shift and insert. Sizes accepted 8 16 32 64. */
21348 NUF(vsli, 1800510, 3, (RNDQ, oRNDQ, I63), neon_sli),
21349 NUF(vsliq, 1800510, 3, (RNQ, oRNQ, I63), neon_sli),
21350 NUF(vsri, 1800410, 3, (RNDQ, oRNDQ, I64), neon_sri),
21351 NUF(vsriq, 1800410, 3, (RNQ, oRNQ, I64), neon_sri),
21352 /* QSHL{U} immediate accepts S8 S16 S32 S64 U8 U16 U32 U64. */
21353 NUF(vqshlu, 1800610, 3, (RNDQ, oRNDQ, I63), neon_qshlu_imm),
21354 NUF(vqshluq, 1800610, 3, (RNQ, oRNQ, I63), neon_qshlu_imm),
21355 /* Right shift immediate, saturating & narrowing, with rounding variants.
21356 Types accepted S16 S32 S64 U16 U32 U64. */
21357 NUF(vqshrn, 0800910, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
21358 NUF(vqrshrn, 0800950, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
21359 /* As above, unsigned. Types accepted S16 S32 S64. */
21360 NUF(vqshrun, 0800810, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
21361 NUF(vqrshrun, 0800850, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
21362 /* Right shift narrowing. Types accepted I16 I32 I64. */
21363 NUF(vshrn, 0800810, 3, (RND, RNQ, I32z), neon_rshift_narrow),
21364 NUF(vrshrn, 0800850, 3, (RND, RNQ, I32z), neon_rshift_narrow),
21365 /* Special case. Types S8 S16 S32 U8 U16 U32. Handles max shift variant. */
21d799b5 21366 nUF(vshll, _vshll, 3, (RNQ, RND, I32), neon_shll),
5287ad62 21367 /* CVT with optional immediate for fixed-point variant. */
21d799b5 21368 nUF(vcvtq, _vcvt, 3, (RNQ, RNQ, oI32b), neon_cvt),
b7fc2769 21369
4316f0d2
DG
21370 nUF(vmvn, _vmvn, 2, (RNDQ, RNDQ_Ibig), neon_mvn),
21371 nUF(vmvnq, _vmvn, 2, (RNQ, RNDQ_Ibig), neon_mvn),
5287ad62
JB
21372
21373 /* Data processing, three registers of different lengths. */
21374 /* Dyadic, long insns. Types S8 S16 S32 U8 U16 U32. */
21375 NUF(vabal, 0800500, 3, (RNQ, RND, RND), neon_abal),
21376 NUF(vabdl, 0800700, 3, (RNQ, RND, RND), neon_dyadic_long),
21377 NUF(vaddl, 0800000, 3, (RNQ, RND, RND), neon_dyadic_long),
21378 NUF(vsubl, 0800200, 3, (RNQ, RND, RND), neon_dyadic_long),
21379 /* If not scalar, fall back to neon_dyadic_long.
21380 Vector types as above, scalar types S16 S32 U16 U32. */
21d799b5
NC
21381 nUF(vmlal, _vmlal, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
21382 nUF(vmlsl, _vmlsl, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
5287ad62
JB
21383 /* Dyadic, widening insns. Types S8 S16 S32 U8 U16 U32. */
21384 NUF(vaddw, 0800100, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
21385 NUF(vsubw, 0800300, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
21386 /* Dyadic, narrowing insns. Types I16 I32 I64. */
21387 NUF(vaddhn, 0800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
21388 NUF(vraddhn, 1800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
21389 NUF(vsubhn, 0800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
21390 NUF(vrsubhn, 1800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
21391 /* Saturating doubling multiplies. Types S16 S32. */
21d799b5
NC
21392 nUF(vqdmlal, _vqdmlal, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
21393 nUF(vqdmlsl, _vqdmlsl, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
21394 nUF(vqdmull, _vqdmull, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
5287ad62
JB
21395 /* VMULL. Vector types S8 S16 S32 U8 U16 U32 P8, scalar types
21396 S16 S32 U16 U32. */
21d799b5 21397 nUF(vmull, _vmull, 3, (RNQ, RND, RND_RNSC), neon_vmull),
5287ad62
JB
21398
21399 /* Extract. Size 8. */
3b8d421e
PB
21400 NUF(vext, 0b00000, 4, (RNDQ, oRNDQ, RNDQ, I15), neon_ext),
21401 NUF(vextq, 0b00000, 4, (RNQ, oRNQ, RNQ, I15), neon_ext),
5287ad62
JB
21402
21403 /* Two registers, miscellaneous. */
21404 /* Reverse. Sizes 8 16 32 (must be < size in opcode). */
21405 NUF(vrev64, 1b00000, 2, (RNDQ, RNDQ), neon_rev),
21406 NUF(vrev64q, 1b00000, 2, (RNQ, RNQ), neon_rev),
21407 NUF(vrev32, 1b00080, 2, (RNDQ, RNDQ), neon_rev),
21408 NUF(vrev32q, 1b00080, 2, (RNQ, RNQ), neon_rev),
21409 NUF(vrev16, 1b00100, 2, (RNDQ, RNDQ), neon_rev),
21410 NUF(vrev16q, 1b00100, 2, (RNQ, RNQ), neon_rev),
21411 /* Vector replicate. Sizes 8 16 32. */
21d799b5
NC
21412 nCE(vdup, _vdup, 2, (RNDQ, RR_RNSC), neon_dup),
21413 nCE(vdupq, _vdup, 2, (RNQ, RR_RNSC), neon_dup),
5287ad62
JB
21414 /* VMOVL. Types S8 S16 S32 U8 U16 U32. */
21415 NUF(vmovl, 0800a10, 2, (RNQ, RND), neon_movl),
21416 /* VMOVN. Types I16 I32 I64. */
21d799b5 21417 nUF(vmovn, _vmovn, 2, (RND, RNQ), neon_movn),
5287ad62 21418 /* VQMOVN. Types S16 S32 S64 U16 U32 U64. */
21d799b5 21419 nUF(vqmovn, _vqmovn, 2, (RND, RNQ), neon_qmovn),
5287ad62 21420 /* VQMOVUN. Types S16 S32 S64. */
21d799b5 21421 nUF(vqmovun, _vqmovun, 2, (RND, RNQ), neon_qmovun),
5287ad62
JB
21422 /* VZIP / VUZP. Sizes 8 16 32. */
21423 NUF(vzip, 1b20180, 2, (RNDQ, RNDQ), neon_zip_uzp),
21424 NUF(vzipq, 1b20180, 2, (RNQ, RNQ), neon_zip_uzp),
21425 NUF(vuzp, 1b20100, 2, (RNDQ, RNDQ), neon_zip_uzp),
21426 NUF(vuzpq, 1b20100, 2, (RNQ, RNQ), neon_zip_uzp),
21427 /* VQABS / VQNEG. Types S8 S16 S32. */
21428 NUF(vqabs, 1b00700, 2, (RNDQ, RNDQ), neon_sat_abs_neg),
21429 NUF(vqabsq, 1b00700, 2, (RNQ, RNQ), neon_sat_abs_neg),
21430 NUF(vqneg, 1b00780, 2, (RNDQ, RNDQ), neon_sat_abs_neg),
21431 NUF(vqnegq, 1b00780, 2, (RNQ, RNQ), neon_sat_abs_neg),
21432 /* Pairwise, lengthening. Types S8 S16 S32 U8 U16 U32. */
21433 NUF(vpadal, 1b00600, 2, (RNDQ, RNDQ), neon_pair_long),
21434 NUF(vpadalq, 1b00600, 2, (RNQ, RNQ), neon_pair_long),
21435 NUF(vpaddl, 1b00200, 2, (RNDQ, RNDQ), neon_pair_long),
21436 NUF(vpaddlq, 1b00200, 2, (RNQ, RNQ), neon_pair_long),
cc933301 21437 /* Reciprocal estimates. Types U32 F16 F32. */
5287ad62
JB
21438 NUF(vrecpe, 1b30400, 2, (RNDQ, RNDQ), neon_recip_est),
21439 NUF(vrecpeq, 1b30400, 2, (RNQ, RNQ), neon_recip_est),
21440 NUF(vrsqrte, 1b30480, 2, (RNDQ, RNDQ), neon_recip_est),
21441 NUF(vrsqrteq, 1b30480, 2, (RNQ, RNQ), neon_recip_est),
21442 /* VCLS. Types S8 S16 S32. */
21443 NUF(vcls, 1b00400, 2, (RNDQ, RNDQ), neon_cls),
21444 NUF(vclsq, 1b00400, 2, (RNQ, RNQ), neon_cls),
21445 /* VCLZ. Types I8 I16 I32. */
21446 NUF(vclz, 1b00480, 2, (RNDQ, RNDQ), neon_clz),
21447 NUF(vclzq, 1b00480, 2, (RNQ, RNQ), neon_clz),
21448 /* VCNT. Size 8. */
21449 NUF(vcnt, 1b00500, 2, (RNDQ, RNDQ), neon_cnt),
21450 NUF(vcntq, 1b00500, 2, (RNQ, RNQ), neon_cnt),
21451 /* Two address, untyped. */
21452 NUF(vswp, 1b20000, 2, (RNDQ, RNDQ), neon_swp),
21453 NUF(vswpq, 1b20000, 2, (RNQ, RNQ), neon_swp),
21454 /* VTRN. Sizes 8 16 32. */
21d799b5
NC
21455 nUF(vtrn, _vtrn, 2, (RNDQ, RNDQ), neon_trn),
21456 nUF(vtrnq, _vtrn, 2, (RNQ, RNQ), neon_trn),
5287ad62
JB
21457
21458 /* Table lookup. Size 8. */
21459 NUF(vtbl, 1b00800, 3, (RND, NRDLST, RND), neon_tbl_tbx),
21460 NUF(vtbx, 1b00840, 3, (RND, NRDLST, RND), neon_tbl_tbx),
21461
c921be7d
NC
21462#undef THUMB_VARIANT
21463#define THUMB_VARIANT & fpu_vfp_v3_or_neon_ext
21464#undef ARM_VARIANT
21465#define ARM_VARIANT & fpu_vfp_v3_or_neon_ext
21466
5287ad62 21467 /* Neon element/structure load/store. */
21d799b5
NC
21468 nUF(vld1, _vld1, 2, (NSTRLST, ADDR), neon_ldx_stx),
21469 nUF(vst1, _vst1, 2, (NSTRLST, ADDR), neon_ldx_stx),
21470 nUF(vld2, _vld2, 2, (NSTRLST, ADDR), neon_ldx_stx),
21471 nUF(vst2, _vst2, 2, (NSTRLST, ADDR), neon_ldx_stx),
21472 nUF(vld3, _vld3, 2, (NSTRLST, ADDR), neon_ldx_stx),
21473 nUF(vst3, _vst3, 2, (NSTRLST, ADDR), neon_ldx_stx),
21474 nUF(vld4, _vld4, 2, (NSTRLST, ADDR), neon_ldx_stx),
21475 nUF(vst4, _vst4, 2, (NSTRLST, ADDR), neon_ldx_stx),
5287ad62 21476
c921be7d 21477#undef THUMB_VARIANT
74db7efb
NC
21478#define THUMB_VARIANT & fpu_vfp_ext_v3xd
21479#undef ARM_VARIANT
21480#define ARM_VARIANT & fpu_vfp_ext_v3xd
62f3b8c8
PB
21481 cCE("fconsts", eb00a00, 2, (RVS, I255), vfp_sp_const),
21482 cCE("fshtos", eba0a40, 2, (RVS, I16z), vfp_sp_conv_16),
21483 cCE("fsltos", eba0ac0, 2, (RVS, I32), vfp_sp_conv_32),
21484 cCE("fuhtos", ebb0a40, 2, (RVS, I16z), vfp_sp_conv_16),
21485 cCE("fultos", ebb0ac0, 2, (RVS, I32), vfp_sp_conv_32),
21486 cCE("ftoshs", ebe0a40, 2, (RVS, I16z), vfp_sp_conv_16),
21487 cCE("ftosls", ebe0ac0, 2, (RVS, I32), vfp_sp_conv_32),
21488 cCE("ftouhs", ebf0a40, 2, (RVS, I16z), vfp_sp_conv_16),
21489 cCE("ftouls", ebf0ac0, 2, (RVS, I32), vfp_sp_conv_32),
21490
74db7efb 21491#undef THUMB_VARIANT
c921be7d
NC
21492#define THUMB_VARIANT & fpu_vfp_ext_v3
21493#undef ARM_VARIANT
21494#define ARM_VARIANT & fpu_vfp_ext_v3
21495
21d799b5 21496 cCE("fconstd", eb00b00, 2, (RVD, I255), vfp_dp_const),
21d799b5 21497 cCE("fshtod", eba0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 21498 cCE("fsltod", eba0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 21499 cCE("fuhtod", ebb0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 21500 cCE("fultod", ebb0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 21501 cCE("ftoshd", ebe0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 21502 cCE("ftosld", ebe0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 21503 cCE("ftouhd", ebf0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 21504 cCE("ftould", ebf0bc0, 2, (RVD, I32), vfp_dp_conv_32),
c19d1205 21505
74db7efb
NC
21506#undef ARM_VARIANT
21507#define ARM_VARIANT & fpu_vfp_ext_fma
21508#undef THUMB_VARIANT
21509#define THUMB_VARIANT & fpu_vfp_ext_fma
62f3b8c8
PB
21510 /* Mnemonics shared by Neon and VFP. These are included in the
21511 VFP FMA variant; NEON and VFP FMA always includes the NEON
21512 FMA instructions. */
21513 nCEF(vfma, _vfma, 3, (RNSDQ, oRNSDQ, RNSDQ), neon_fmac),
21514 nCEF(vfms, _vfms, 3, (RNSDQ, oRNSDQ, RNSDQ), neon_fmac),
21515 /* ffmas/ffmad/ffmss/ffmsd are dummy mnemonics to satisfy gas;
21516 the v form should always be used. */
21517 cCE("ffmas", ea00a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21518 cCE("ffnmas", ea00a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21519 cCE("ffmad", ea00b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21520 cCE("ffnmad", ea00b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21521 nCE(vfnma, _vfnma, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
21522 nCE(vfnms, _vfnms, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
21523
5287ad62 21524#undef THUMB_VARIANT
c921be7d
NC
21525#undef ARM_VARIANT
21526#define ARM_VARIANT & arm_cext_xscale /* Intel XScale extensions. */
21527
21d799b5
NC
21528 cCE("mia", e200010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
21529 cCE("miaph", e280010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
21530 cCE("miabb", e2c0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
21531 cCE("miabt", e2d0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
21532 cCE("miatb", e2e0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
21533 cCE("miatt", e2f0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
21534 cCE("mar", c400000, 3, (RXA, RRnpc, RRnpc), xsc_mar),
21535 cCE("mra", c500000, 3, (RRnpc, RRnpc, RXA), xsc_mra),
c19d1205 21536
c921be7d
NC
21537#undef ARM_VARIANT
21538#define ARM_VARIANT & arm_cext_iwmmxt /* Intel Wireless MMX technology. */
21539
21d799b5
NC
21540 cCE("tandcb", e13f130, 1, (RR), iwmmxt_tandorc),
21541 cCE("tandch", e53f130, 1, (RR), iwmmxt_tandorc),
21542 cCE("tandcw", e93f130, 1, (RR), iwmmxt_tandorc),
21543 cCE("tbcstb", e400010, 2, (RIWR, RR), rn_rd),
21544 cCE("tbcsth", e400050, 2, (RIWR, RR), rn_rd),
21545 cCE("tbcstw", e400090, 2, (RIWR, RR), rn_rd),
21546 cCE("textrcb", e130170, 2, (RR, I7), iwmmxt_textrc),
21547 cCE("textrch", e530170, 2, (RR, I7), iwmmxt_textrc),
21548 cCE("textrcw", e930170, 2, (RR, I7), iwmmxt_textrc),
74db7efb
NC
21549 cCE("textrmub",e100070, 3, (RR, RIWR, I7), iwmmxt_textrm),
21550 cCE("textrmuh",e500070, 3, (RR, RIWR, I7), iwmmxt_textrm),
21551 cCE("textrmuw",e900070, 3, (RR, RIWR, I7), iwmmxt_textrm),
21552 cCE("textrmsb",e100078, 3, (RR, RIWR, I7), iwmmxt_textrm),
21553 cCE("textrmsh",e500078, 3, (RR, RIWR, I7), iwmmxt_textrm),
21554 cCE("textrmsw",e900078, 3, (RR, RIWR, I7), iwmmxt_textrm),
21d799b5
NC
21555 cCE("tinsrb", e600010, 3, (RIWR, RR, I7), iwmmxt_tinsr),
21556 cCE("tinsrh", e600050, 3, (RIWR, RR, I7), iwmmxt_tinsr),
21557 cCE("tinsrw", e600090, 3, (RIWR, RR, I7), iwmmxt_tinsr),
21558 cCE("tmcr", e000110, 2, (RIWC_RIWG, RR), rn_rd),
21559 cCE("tmcrr", c400000, 3, (RIWR, RR, RR), rm_rd_rn),
21560 cCE("tmia", e200010, 3, (RIWR, RR, RR), iwmmxt_tmia),
21561 cCE("tmiaph", e280010, 3, (RIWR, RR, RR), iwmmxt_tmia),
21562 cCE("tmiabb", e2c0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
21563 cCE("tmiabt", e2d0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
21564 cCE("tmiatb", e2e0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
21565 cCE("tmiatt", e2f0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
74db7efb
NC
21566 cCE("tmovmskb",e100030, 2, (RR, RIWR), rd_rn),
21567 cCE("tmovmskh",e500030, 2, (RR, RIWR), rd_rn),
21568 cCE("tmovmskw",e900030, 2, (RR, RIWR), rd_rn),
21d799b5
NC
21569 cCE("tmrc", e100110, 2, (RR, RIWC_RIWG), rd_rn),
21570 cCE("tmrrc", c500000, 3, (RR, RR, RIWR), rd_rn_rm),
21571 cCE("torcb", e13f150, 1, (RR), iwmmxt_tandorc),
21572 cCE("torch", e53f150, 1, (RR), iwmmxt_tandorc),
21573 cCE("torcw", e93f150, 1, (RR), iwmmxt_tandorc),
21574 cCE("waccb", e0001c0, 2, (RIWR, RIWR), rd_rn),
21575 cCE("wacch", e4001c0, 2, (RIWR, RIWR), rd_rn),
21576 cCE("waccw", e8001c0, 2, (RIWR, RIWR), rd_rn),
21577 cCE("waddbss", e300180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21578 cCE("waddb", e000180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21579 cCE("waddbus", e100180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21580 cCE("waddhss", e700180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21581 cCE("waddh", e400180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21582 cCE("waddhus", e500180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21583 cCE("waddwss", eb00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21584 cCE("waddw", e800180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21585 cCE("waddwus", e900180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21586 cCE("waligni", e000020, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_waligni),
74db7efb
NC
21587 cCE("walignr0",e800020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21588 cCE("walignr1",e900020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21589 cCE("walignr2",ea00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21590 cCE("walignr3",eb00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
21591 cCE("wand", e200000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21592 cCE("wandn", e300000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21593 cCE("wavg2b", e800000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21594 cCE("wavg2br", e900000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21595 cCE("wavg2h", ec00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21596 cCE("wavg2hr", ed00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21597 cCE("wcmpeqb", e000060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21598 cCE("wcmpeqh", e400060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21599 cCE("wcmpeqw", e800060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
21600 cCE("wcmpgtub",e100060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21601 cCE("wcmpgtuh",e500060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21602 cCE("wcmpgtuw",e900060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21603 cCE("wcmpgtsb",e300060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21604 cCE("wcmpgtsh",e700060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21605 cCE("wcmpgtsw",eb00060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
21606 cCE("wldrb", c100000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
21607 cCE("wldrh", c500000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
21608 cCE("wldrw", c100100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
21609 cCE("wldrd", c500100, 2, (RIWR, ADDR), iwmmxt_wldstd),
21610 cCE("wmacs", e600100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21611 cCE("wmacsz", e700100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21612 cCE("wmacu", e400100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21613 cCE("wmacuz", e500100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21614 cCE("wmadds", ea00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21615 cCE("wmaddu", e800100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21616 cCE("wmaxsb", e200160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21617 cCE("wmaxsh", e600160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21618 cCE("wmaxsw", ea00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21619 cCE("wmaxub", e000160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21620 cCE("wmaxuh", e400160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21621 cCE("wmaxuw", e800160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21622 cCE("wminsb", e300160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21623 cCE("wminsh", e700160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21624 cCE("wminsw", eb00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21625 cCE("wminub", e100160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21626 cCE("wminuh", e500160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21627 cCE("wminuw", e900160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21628 cCE("wmov", e000000, 2, (RIWR, RIWR), iwmmxt_wmov),
21629 cCE("wmulsm", e300100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21630 cCE("wmulsl", e200100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21631 cCE("wmulum", e100100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21632 cCE("wmulul", e000100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21633 cCE("wor", e000000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
21634 cCE("wpackhss",e700080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21635 cCE("wpackhus",e500080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21636 cCE("wpackwss",eb00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21637 cCE("wpackwus",e900080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21638 cCE("wpackdss",ef00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21639 cCE("wpackdus",ed00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
21640 cCE("wrorh", e700040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21641 cCE("wrorhg", e700148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21642 cCE("wrorw", eb00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21643 cCE("wrorwg", eb00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21644 cCE("wrord", ef00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21645 cCE("wrordg", ef00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21646 cCE("wsadb", e000120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21647 cCE("wsadbz", e100120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21648 cCE("wsadh", e400120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21649 cCE("wsadhz", e500120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21650 cCE("wshufh", e0001e0, 3, (RIWR, RIWR, I255), iwmmxt_wshufh),
21651 cCE("wsllh", e500040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21652 cCE("wsllhg", e500148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21653 cCE("wsllw", e900040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21654 cCE("wsllwg", e900148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21655 cCE("wslld", ed00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21656 cCE("wslldg", ed00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21657 cCE("wsrah", e400040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21658 cCE("wsrahg", e400148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21659 cCE("wsraw", e800040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21660 cCE("wsrawg", e800148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21661 cCE("wsrad", ec00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21662 cCE("wsradg", ec00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21663 cCE("wsrlh", e600040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21664 cCE("wsrlhg", e600148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21665 cCE("wsrlw", ea00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21666 cCE("wsrlwg", ea00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21667 cCE("wsrld", ee00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21668 cCE("wsrldg", ee00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21669 cCE("wstrb", c000000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
21670 cCE("wstrh", c400000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
21671 cCE("wstrw", c000100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
21672 cCE("wstrd", c400100, 2, (RIWR, ADDR), iwmmxt_wldstd),
21673 cCE("wsubbss", e3001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21674 cCE("wsubb", e0001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21675 cCE("wsubbus", e1001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21676 cCE("wsubhss", e7001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21677 cCE("wsubh", e4001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21678 cCE("wsubhus", e5001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21679 cCE("wsubwss", eb001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21680 cCE("wsubw", e8001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21681 cCE("wsubwus", e9001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21682 cCE("wunpckehub",e0000c0, 2, (RIWR, RIWR), rd_rn),
21683 cCE("wunpckehuh",e4000c0, 2, (RIWR, RIWR), rd_rn),
21684 cCE("wunpckehuw",e8000c0, 2, (RIWR, RIWR), rd_rn),
21685 cCE("wunpckehsb",e2000c0, 2, (RIWR, RIWR), rd_rn),
21686 cCE("wunpckehsh",e6000c0, 2, (RIWR, RIWR), rd_rn),
21687 cCE("wunpckehsw",ea000c0, 2, (RIWR, RIWR), rd_rn),
21688 cCE("wunpckihb", e1000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21689 cCE("wunpckihh", e5000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21690 cCE("wunpckihw", e9000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21691 cCE("wunpckelub",e0000e0, 2, (RIWR, RIWR), rd_rn),
21692 cCE("wunpckeluh",e4000e0, 2, (RIWR, RIWR), rd_rn),
21693 cCE("wunpckeluw",e8000e0, 2, (RIWR, RIWR), rd_rn),
21694 cCE("wunpckelsb",e2000e0, 2, (RIWR, RIWR), rd_rn),
21695 cCE("wunpckelsh",e6000e0, 2, (RIWR, RIWR), rd_rn),
21696 cCE("wunpckelsw",ea000e0, 2, (RIWR, RIWR), rd_rn),
21697 cCE("wunpckilb", e1000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21698 cCE("wunpckilh", e5000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21699 cCE("wunpckilw", e9000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21700 cCE("wxor", e100000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21701 cCE("wzero", e300000, 1, (RIWR), iwmmxt_wzero),
c19d1205 21702
c921be7d
NC
21703#undef ARM_VARIANT
21704#define ARM_VARIANT & arm_cext_iwmmxt2 /* Intel Wireless MMX technology, version 2. */
21705
21d799b5
NC
21706 cCE("torvscb", e12f190, 1, (RR), iwmmxt_tandorc),
21707 cCE("torvsch", e52f190, 1, (RR), iwmmxt_tandorc),
21708 cCE("torvscw", e92f190, 1, (RR), iwmmxt_tandorc),
21709 cCE("wabsb", e2001c0, 2, (RIWR, RIWR), rd_rn),
21710 cCE("wabsh", e6001c0, 2, (RIWR, RIWR), rd_rn),
21711 cCE("wabsw", ea001c0, 2, (RIWR, RIWR), rd_rn),
21712 cCE("wabsdiffb", e1001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21713 cCE("wabsdiffh", e5001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21714 cCE("wabsdiffw", e9001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21715 cCE("waddbhusl", e2001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21716 cCE("waddbhusm", e6001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21717 cCE("waddhc", e600180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21718 cCE("waddwc", ea00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21719 cCE("waddsubhx", ea001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21720 cCE("wavg4", e400000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21721 cCE("wavg4r", e500000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21722 cCE("wmaddsn", ee00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21723 cCE("wmaddsx", eb00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21724 cCE("wmaddun", ec00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21725 cCE("wmaddux", e900100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21726 cCE("wmerge", e000080, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_wmerge),
21727 cCE("wmiabb", e0000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21728 cCE("wmiabt", e1000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21729 cCE("wmiatb", e2000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21730 cCE("wmiatt", e3000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21731 cCE("wmiabbn", e4000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21732 cCE("wmiabtn", e5000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21733 cCE("wmiatbn", e6000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21734 cCE("wmiattn", e7000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21735 cCE("wmiawbb", e800120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21736 cCE("wmiawbt", e900120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21737 cCE("wmiawtb", ea00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21738 cCE("wmiawtt", eb00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21739 cCE("wmiawbbn", ec00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21740 cCE("wmiawbtn", ed00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21741 cCE("wmiawtbn", ee00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21742 cCE("wmiawttn", ef00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21743 cCE("wmulsmr", ef00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21744 cCE("wmulumr", ed00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21745 cCE("wmulwumr", ec000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21746 cCE("wmulwsmr", ee000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21747 cCE("wmulwum", ed000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21748 cCE("wmulwsm", ef000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21749 cCE("wmulwl", eb000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21750 cCE("wqmiabb", e8000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21751 cCE("wqmiabt", e9000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21752 cCE("wqmiatb", ea000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21753 cCE("wqmiatt", eb000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21754 cCE("wqmiabbn", ec000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21755 cCE("wqmiabtn", ed000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21756 cCE("wqmiatbn", ee000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21757 cCE("wqmiattn", ef000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21758 cCE("wqmulm", e100080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21759 cCE("wqmulmr", e300080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21760 cCE("wqmulwm", ec000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21761 cCE("wqmulwmr", ee000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21762 cCE("wsubaddhx", ed001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
2d447fca 21763
c921be7d
NC
21764#undef ARM_VARIANT
21765#define ARM_VARIANT & arm_cext_maverick /* Cirrus Maverick instructions. */
21766
21d799b5
NC
21767 cCE("cfldrs", c100400, 2, (RMF, ADDRGLDC), rd_cpaddr),
21768 cCE("cfldrd", c500400, 2, (RMD, ADDRGLDC), rd_cpaddr),
21769 cCE("cfldr32", c100500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
21770 cCE("cfldr64", c500500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
21771 cCE("cfstrs", c000400, 2, (RMF, ADDRGLDC), rd_cpaddr),
21772 cCE("cfstrd", c400400, 2, (RMD, ADDRGLDC), rd_cpaddr),
21773 cCE("cfstr32", c000500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
21774 cCE("cfstr64", c400500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
21775 cCE("cfmvsr", e000450, 2, (RMF, RR), rn_rd),
21776 cCE("cfmvrs", e100450, 2, (RR, RMF), rd_rn),
21777 cCE("cfmvdlr", e000410, 2, (RMD, RR), rn_rd),
21778 cCE("cfmvrdl", e100410, 2, (RR, RMD), rd_rn),
21779 cCE("cfmvdhr", e000430, 2, (RMD, RR), rn_rd),
21780 cCE("cfmvrdh", e100430, 2, (RR, RMD), rd_rn),
74db7efb
NC
21781 cCE("cfmv64lr",e000510, 2, (RMDX, RR), rn_rd),
21782 cCE("cfmvr64l",e100510, 2, (RR, RMDX), rd_rn),
21783 cCE("cfmv64hr",e000530, 2, (RMDX, RR), rn_rd),
21784 cCE("cfmvr64h",e100530, 2, (RR, RMDX), rd_rn),
21785 cCE("cfmval32",e200440, 2, (RMAX, RMFX), rd_rn),
21786 cCE("cfmv32al",e100440, 2, (RMFX, RMAX), rd_rn),
21787 cCE("cfmvam32",e200460, 2, (RMAX, RMFX), rd_rn),
21788 cCE("cfmv32am",e100460, 2, (RMFX, RMAX), rd_rn),
21789 cCE("cfmvah32",e200480, 2, (RMAX, RMFX), rd_rn),
21790 cCE("cfmv32ah",e100480, 2, (RMFX, RMAX), rd_rn),
21d799b5
NC
21791 cCE("cfmva32", e2004a0, 2, (RMAX, RMFX), rd_rn),
21792 cCE("cfmv32a", e1004a0, 2, (RMFX, RMAX), rd_rn),
21793 cCE("cfmva64", e2004c0, 2, (RMAX, RMDX), rd_rn),
21794 cCE("cfmv64a", e1004c0, 2, (RMDX, RMAX), rd_rn),
74db7efb
NC
21795 cCE("cfmvsc32",e2004e0, 2, (RMDS, RMDX), mav_dspsc),
21796 cCE("cfmv32sc",e1004e0, 2, (RMDX, RMDS), rd),
21d799b5
NC
21797 cCE("cfcpys", e000400, 2, (RMF, RMF), rd_rn),
21798 cCE("cfcpyd", e000420, 2, (RMD, RMD), rd_rn),
21799 cCE("cfcvtsd", e000460, 2, (RMD, RMF), rd_rn),
21800 cCE("cfcvtds", e000440, 2, (RMF, RMD), rd_rn),
74db7efb
NC
21801 cCE("cfcvt32s",e000480, 2, (RMF, RMFX), rd_rn),
21802 cCE("cfcvt32d",e0004a0, 2, (RMD, RMFX), rd_rn),
21803 cCE("cfcvt64s",e0004c0, 2, (RMF, RMDX), rd_rn),
21804 cCE("cfcvt64d",e0004e0, 2, (RMD, RMDX), rd_rn),
21805 cCE("cfcvts32",e100580, 2, (RMFX, RMF), rd_rn),
21806 cCE("cfcvtd32",e1005a0, 2, (RMFX, RMD), rd_rn),
21d799b5
NC
21807 cCE("cftruncs32",e1005c0, 2, (RMFX, RMF), rd_rn),
21808 cCE("cftruncd32",e1005e0, 2, (RMFX, RMD), rd_rn),
74db7efb
NC
21809 cCE("cfrshl32",e000550, 3, (RMFX, RMFX, RR), mav_triple),
21810 cCE("cfrshl64",e000570, 3, (RMDX, RMDX, RR), mav_triple),
21d799b5
NC
21811 cCE("cfsh32", e000500, 3, (RMFX, RMFX, I63s), mav_shift),
21812 cCE("cfsh64", e200500, 3, (RMDX, RMDX, I63s), mav_shift),
21813 cCE("cfcmps", e100490, 3, (RR, RMF, RMF), rd_rn_rm),
21814 cCE("cfcmpd", e1004b0, 3, (RR, RMD, RMD), rd_rn_rm),
21815 cCE("cfcmp32", e100590, 3, (RR, RMFX, RMFX), rd_rn_rm),
21816 cCE("cfcmp64", e1005b0, 3, (RR, RMDX, RMDX), rd_rn_rm),
21817 cCE("cfabss", e300400, 2, (RMF, RMF), rd_rn),
21818 cCE("cfabsd", e300420, 2, (RMD, RMD), rd_rn),
21819 cCE("cfnegs", e300440, 2, (RMF, RMF), rd_rn),
21820 cCE("cfnegd", e300460, 2, (RMD, RMD), rd_rn),
21821 cCE("cfadds", e300480, 3, (RMF, RMF, RMF), rd_rn_rm),
21822 cCE("cfaddd", e3004a0, 3, (RMD, RMD, RMD), rd_rn_rm),
21823 cCE("cfsubs", e3004c0, 3, (RMF, RMF, RMF), rd_rn_rm),
21824 cCE("cfsubd", e3004e0, 3, (RMD, RMD, RMD), rd_rn_rm),
21825 cCE("cfmuls", e100400, 3, (RMF, RMF, RMF), rd_rn_rm),
21826 cCE("cfmuld", e100420, 3, (RMD, RMD, RMD), rd_rn_rm),
21827 cCE("cfabs32", e300500, 2, (RMFX, RMFX), rd_rn),
21828 cCE("cfabs64", e300520, 2, (RMDX, RMDX), rd_rn),
21829 cCE("cfneg32", e300540, 2, (RMFX, RMFX), rd_rn),
21830 cCE("cfneg64", e300560, 2, (RMDX, RMDX), rd_rn),
21831 cCE("cfadd32", e300580, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
21832 cCE("cfadd64", e3005a0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
21833 cCE("cfsub32", e3005c0, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
21834 cCE("cfsub64", e3005e0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
21835 cCE("cfmul32", e100500, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
21836 cCE("cfmul64", e100520, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
21837 cCE("cfmac32", e100540, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
21838 cCE("cfmsc32", e100560, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
74db7efb
NC
21839 cCE("cfmadd32",e000600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
21840 cCE("cfmsub32",e100600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
21d799b5
NC
21841 cCE("cfmadda32", e200600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
21842 cCE("cfmsuba32", e300600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
4ed7ed8d 21843
7fadb25d
SD
21844 /* ARMv8.5-A instructions. */
21845#undef ARM_VARIANT
21846#define ARM_VARIANT & arm_ext_sb
21847#undef THUMB_VARIANT
21848#define THUMB_VARIANT & arm_ext_sb
21849 TUF("sb", 57ff070, f3bf8f70, 0, (), noargs, noargs),
21850
dad0c3bf
SD
21851#undef ARM_VARIANT
21852#define ARM_VARIANT & arm_ext_predres
21853#undef THUMB_VARIANT
21854#define THUMB_VARIANT & arm_ext_predres
21855 CE("cfprctx", e070f93, 1, (RRnpc), rd),
21856 CE("dvprctx", e070fb3, 1, (RRnpc), rd),
21857 CE("cpprctx", e070ff3, 1, (RRnpc), rd),
21858
16a1fa25 21859 /* ARMv8-M instructions. */
4ed7ed8d
TP
21860#undef ARM_VARIANT
21861#define ARM_VARIANT NULL
21862#undef THUMB_VARIANT
21863#define THUMB_VARIANT & arm_ext_v8m
cf3cf39d
TP
21864 ToU("sg", e97fe97f, 0, (), noargs),
21865 ToC("blxns", 4784, 1, (RRnpc), t_blx),
21866 ToC("bxns", 4704, 1, (RRnpc), t_bx),
21867 ToC("tt", e840f000, 2, (RRnpc, RRnpc), tt),
21868 ToC("ttt", e840f040, 2, (RRnpc, RRnpc), tt),
21869 ToC("tta", e840f080, 2, (RRnpc, RRnpc), tt),
21870 ToC("ttat", e840f0c0, 2, (RRnpc, RRnpc), tt),
16a1fa25
TP
21871
21872 /* FP for ARMv8-M Mainline. Enabled for ARMv8-M Mainline because the
21873 instructions behave as nop if no VFP is present. */
21874#undef THUMB_VARIANT
21875#define THUMB_VARIANT & arm_ext_v8m_main
cf3cf39d
TP
21876 ToC("vlldm", ec300a00, 1, (RRnpc), rn),
21877 ToC("vlstm", ec200a00, 1, (RRnpc), rn),
4389b29a
AV
21878
21879 /* Armv8.1-M Mainline instructions. */
21880#undef THUMB_VARIANT
21881#define THUMB_VARIANT & arm_ext_v8_1m_main
21882 toC("bf", _bf, 2, (EXPs, EXPs), t_branch_future),
f6b2b12d 21883 toU("bfcsel", _bfcsel, 4, (EXPs, EXPs, EXPs, COND), t_branch_future),
f1c7f421 21884 toC("bfx", _bfx, 2, (EXPs, RRnpcsp), t_branch_future),
65d1bc05 21885 toC("bfl", _bfl, 2, (EXPs, EXPs), t_branch_future),
f1c7f421 21886 toC("bflx", _bflx, 2, (EXPs, RRnpcsp), t_branch_future),
60f993ce
AV
21887
21888 toU("dls", _dls, 2, (LR, RRnpcsp), t_loloop),
21889 toU("wls", _wls, 3, (LR, RRnpcsp, EXP), t_loloop),
21890 toU("le", _le, 2, (oLR, EXP), t_loloop),
4b5a202f
AV
21891
21892 ToC("clrm", e89f0000, 1, (CLRMLST), t_clrm)
c19d1205
ZW
21893};
21894#undef ARM_VARIANT
21895#undef THUMB_VARIANT
21896#undef TCE
c19d1205
ZW
21897#undef TUE
21898#undef TUF
21899#undef TCC
8f06b2d8 21900#undef cCE
e3cb604e
PB
21901#undef cCL
21902#undef C3E
4389b29a 21903#undef C3
c19d1205
ZW
21904#undef CE
21905#undef CM
4389b29a 21906#undef CL
c19d1205
ZW
21907#undef UE
21908#undef UF
21909#undef UT
5287ad62
JB
21910#undef NUF
21911#undef nUF
21912#undef NCE
21913#undef nCE
c19d1205
ZW
21914#undef OPS0
21915#undef OPS1
21916#undef OPS2
21917#undef OPS3
21918#undef OPS4
21919#undef OPS5
21920#undef OPS6
21921#undef do_0
4389b29a
AV
21922#undef ToC
21923#undef toC
21924#undef ToU
f6b2b12d 21925#undef toU
c19d1205
ZW
21926\f
21927/* MD interface: bits in the object file. */
bfae80f2 21928
c19d1205
ZW
21929/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
21930 for use in the a.out file, and stores them in the array pointed to by buf.
21931 This knows about the endian-ness of the target machine and does
21932 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
21933 2 (short) and 4 (long) Floating numbers are put out as a series of
21934 LITTLENUMS (shorts, here at least). */
b99bd4ef 21935
c19d1205
ZW
21936void
21937md_number_to_chars (char * buf, valueT val, int n)
21938{
21939 if (target_big_endian)
21940 number_to_chars_bigendian (buf, val, n);
21941 else
21942 number_to_chars_littleendian (buf, val, n);
bfae80f2
RE
21943}
21944
c19d1205
ZW
21945static valueT
21946md_chars_to_number (char * buf, int n)
bfae80f2 21947{
c19d1205
ZW
21948 valueT result = 0;
21949 unsigned char * where = (unsigned char *) buf;
bfae80f2 21950
c19d1205 21951 if (target_big_endian)
b99bd4ef 21952 {
c19d1205
ZW
21953 while (n--)
21954 {
21955 result <<= 8;
21956 result |= (*where++ & 255);
21957 }
b99bd4ef 21958 }
c19d1205 21959 else
b99bd4ef 21960 {
c19d1205
ZW
21961 while (n--)
21962 {
21963 result <<= 8;
21964 result |= (where[n] & 255);
21965 }
bfae80f2 21966 }
b99bd4ef 21967
c19d1205 21968 return result;
bfae80f2 21969}
b99bd4ef 21970
c19d1205 21971/* MD interface: Sections. */
b99bd4ef 21972
fa94de6b
RM
21973/* Calculate the maximum variable size (i.e., excluding fr_fix)
21974 that an rs_machine_dependent frag may reach. */
21975
21976unsigned int
21977arm_frag_max_var (fragS *fragp)
21978{
21979 /* We only use rs_machine_dependent for variable-size Thumb instructions,
21980 which are either THUMB_SIZE (2) or INSN_SIZE (4).
21981
21982 Note that we generate relaxable instructions even for cases that don't
21983 really need it, like an immediate that's a trivial constant. So we're
21984 overestimating the instruction size for some of those cases. Rather
21985 than putting more intelligence here, it would probably be better to
21986 avoid generating a relaxation frag in the first place when it can be
21987 determined up front that a short instruction will suffice. */
21988
21989 gas_assert (fragp->fr_type == rs_machine_dependent);
21990 return INSN_SIZE;
21991}
21992
0110f2b8
PB
21993/* Estimate the size of a frag before relaxing. Assume everything fits in
21994 2 bytes. */
21995
c19d1205 21996int
0110f2b8 21997md_estimate_size_before_relax (fragS * fragp,
c19d1205
ZW
21998 segT segtype ATTRIBUTE_UNUSED)
21999{
0110f2b8
PB
22000 fragp->fr_var = 2;
22001 return 2;
22002}
22003
22004/* Convert a machine dependent frag. */
22005
22006void
22007md_convert_frag (bfd *abfd, segT asec ATTRIBUTE_UNUSED, fragS *fragp)
22008{
22009 unsigned long insn;
22010 unsigned long old_op;
22011 char *buf;
22012 expressionS exp;
22013 fixS *fixp;
22014 int reloc_type;
22015 int pc_rel;
22016 int opcode;
22017
22018 buf = fragp->fr_literal + fragp->fr_fix;
22019
22020 old_op = bfd_get_16(abfd, buf);
5f4273c7
NC
22021 if (fragp->fr_symbol)
22022 {
0110f2b8
PB
22023 exp.X_op = O_symbol;
22024 exp.X_add_symbol = fragp->fr_symbol;
5f4273c7
NC
22025 }
22026 else
22027 {
0110f2b8 22028 exp.X_op = O_constant;
5f4273c7 22029 }
0110f2b8
PB
22030 exp.X_add_number = fragp->fr_offset;
22031 opcode = fragp->fr_subtype;
22032 switch (opcode)
22033 {
22034 case T_MNEM_ldr_pc:
22035 case T_MNEM_ldr_pc2:
22036 case T_MNEM_ldr_sp:
22037 case T_MNEM_str_sp:
22038 case T_MNEM_ldr:
22039 case T_MNEM_ldrb:
22040 case T_MNEM_ldrh:
22041 case T_MNEM_str:
22042 case T_MNEM_strb:
22043 case T_MNEM_strh:
22044 if (fragp->fr_var == 4)
22045 {
5f4273c7 22046 insn = THUMB_OP32 (opcode);
0110f2b8
PB
22047 if ((old_op >> 12) == 4 || (old_op >> 12) == 9)
22048 {
22049 insn |= (old_op & 0x700) << 4;
22050 }
22051 else
22052 {
22053 insn |= (old_op & 7) << 12;
22054 insn |= (old_op & 0x38) << 13;
22055 }
22056 insn |= 0x00000c00;
22057 put_thumb32_insn (buf, insn);
22058 reloc_type = BFD_RELOC_ARM_T32_OFFSET_IMM;
22059 }
22060 else
22061 {
22062 reloc_type = BFD_RELOC_ARM_THUMB_OFFSET;
22063 }
22064 pc_rel = (opcode == T_MNEM_ldr_pc2);
22065 break;
22066 case T_MNEM_adr:
22067 if (fragp->fr_var == 4)
22068 {
22069 insn = THUMB_OP32 (opcode);
22070 insn |= (old_op & 0xf0) << 4;
22071 put_thumb32_insn (buf, insn);
22072 reloc_type = BFD_RELOC_ARM_T32_ADD_PC12;
22073 }
22074 else
22075 {
22076 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
22077 exp.X_add_number -= 4;
22078 }
22079 pc_rel = 1;
22080 break;
22081 case T_MNEM_mov:
22082 case T_MNEM_movs:
22083 case T_MNEM_cmp:
22084 case T_MNEM_cmn:
22085 if (fragp->fr_var == 4)
22086 {
22087 int r0off = (opcode == T_MNEM_mov
22088 || opcode == T_MNEM_movs) ? 0 : 8;
22089 insn = THUMB_OP32 (opcode);
22090 insn = (insn & 0xe1ffffff) | 0x10000000;
22091 insn |= (old_op & 0x700) << r0off;
22092 put_thumb32_insn (buf, insn);
22093 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
22094 }
22095 else
22096 {
22097 reloc_type = BFD_RELOC_ARM_THUMB_IMM;
22098 }
22099 pc_rel = 0;
22100 break;
22101 case T_MNEM_b:
22102 if (fragp->fr_var == 4)
22103 {
22104 insn = THUMB_OP32(opcode);
22105 put_thumb32_insn (buf, insn);
22106 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH25;
22107 }
22108 else
22109 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH12;
22110 pc_rel = 1;
22111 break;
22112 case T_MNEM_bcond:
22113 if (fragp->fr_var == 4)
22114 {
22115 insn = THUMB_OP32(opcode);
22116 insn |= (old_op & 0xf00) << 14;
22117 put_thumb32_insn (buf, insn);
22118 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH20;
22119 }
22120 else
22121 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH9;
22122 pc_rel = 1;
22123 break;
22124 case T_MNEM_add_sp:
22125 case T_MNEM_add_pc:
22126 case T_MNEM_inc_sp:
22127 case T_MNEM_dec_sp:
22128 if (fragp->fr_var == 4)
22129 {
22130 /* ??? Choose between add and addw. */
22131 insn = THUMB_OP32 (opcode);
22132 insn |= (old_op & 0xf0) << 4;
22133 put_thumb32_insn (buf, insn);
16805f35
PB
22134 if (opcode == T_MNEM_add_pc)
22135 reloc_type = BFD_RELOC_ARM_T32_IMM12;
22136 else
22137 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
0110f2b8
PB
22138 }
22139 else
22140 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
22141 pc_rel = 0;
22142 break;
22143
22144 case T_MNEM_addi:
22145 case T_MNEM_addis:
22146 case T_MNEM_subi:
22147 case T_MNEM_subis:
22148 if (fragp->fr_var == 4)
22149 {
22150 insn = THUMB_OP32 (opcode);
22151 insn |= (old_op & 0xf0) << 4;
22152 insn |= (old_op & 0xf) << 16;
22153 put_thumb32_insn (buf, insn);
16805f35
PB
22154 if (insn & (1 << 20))
22155 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
22156 else
22157 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8
PB
22158 }
22159 else
22160 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
22161 pc_rel = 0;
22162 break;
22163 default:
5f4273c7 22164 abort ();
0110f2b8
PB
22165 }
22166 fixp = fix_new_exp (fragp, fragp->fr_fix, fragp->fr_var, &exp, pc_rel,
21d799b5 22167 (enum bfd_reloc_code_real) reloc_type);
0110f2b8
PB
22168 fixp->fx_file = fragp->fr_file;
22169 fixp->fx_line = fragp->fr_line;
22170 fragp->fr_fix += fragp->fr_var;
3cfdb781
TG
22171
22172 /* Set whether we use thumb-2 ISA based on final relaxation results. */
22173 if (thumb_mode && fragp->fr_var == 4 && no_cpu_selected ()
22174 && !ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_t2))
22175 ARM_MERGE_FEATURE_SETS (arm_arch_used, thumb_arch_used, arm_ext_v6t2);
0110f2b8
PB
22176}
22177
22178/* Return the size of a relaxable immediate operand instruction.
22179 SHIFT and SIZE specify the form of the allowable immediate. */
22180static int
22181relax_immediate (fragS *fragp, int size, int shift)
22182{
22183 offsetT offset;
22184 offsetT mask;
22185 offsetT low;
22186
22187 /* ??? Should be able to do better than this. */
22188 if (fragp->fr_symbol)
22189 return 4;
22190
22191 low = (1 << shift) - 1;
22192 mask = (1 << (shift + size)) - (1 << shift);
22193 offset = fragp->fr_offset;
22194 /* Force misaligned offsets to 32-bit variant. */
22195 if (offset & low)
5e77afaa 22196 return 4;
0110f2b8
PB
22197 if (offset & ~mask)
22198 return 4;
22199 return 2;
22200}
22201
5e77afaa
PB
22202/* Get the address of a symbol during relaxation. */
22203static addressT
5f4273c7 22204relaxed_symbol_addr (fragS *fragp, long stretch)
5e77afaa
PB
22205{
22206 fragS *sym_frag;
22207 addressT addr;
22208 symbolS *sym;
22209
22210 sym = fragp->fr_symbol;
22211 sym_frag = symbol_get_frag (sym);
22212 know (S_GET_SEGMENT (sym) != absolute_section
22213 || sym_frag == &zero_address_frag);
22214 addr = S_GET_VALUE (sym) + fragp->fr_offset;
22215
22216 /* If frag has yet to be reached on this pass, assume it will
22217 move by STRETCH just as we did. If this is not so, it will
22218 be because some frag between grows, and that will force
22219 another pass. */
22220
22221 if (stretch != 0
22222 && sym_frag->relax_marker != fragp->relax_marker)
4396b686
PB
22223 {
22224 fragS *f;
22225
22226 /* Adjust stretch for any alignment frag. Note that if have
22227 been expanding the earlier code, the symbol may be
22228 defined in what appears to be an earlier frag. FIXME:
22229 This doesn't handle the fr_subtype field, which specifies
22230 a maximum number of bytes to skip when doing an
22231 alignment. */
22232 for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next)
22233 {
22234 if (f->fr_type == rs_align || f->fr_type == rs_align_code)
22235 {
22236 if (stretch < 0)
22237 stretch = - ((- stretch)
22238 & ~ ((1 << (int) f->fr_offset) - 1));
22239 else
22240 stretch &= ~ ((1 << (int) f->fr_offset) - 1);
22241 if (stretch == 0)
22242 break;
22243 }
22244 }
22245 if (f != NULL)
22246 addr += stretch;
22247 }
5e77afaa
PB
22248
22249 return addr;
22250}
22251
0110f2b8
PB
22252/* Return the size of a relaxable adr pseudo-instruction or PC-relative
22253 load. */
22254static int
5e77afaa 22255relax_adr (fragS *fragp, asection *sec, long stretch)
0110f2b8
PB
22256{
22257 addressT addr;
22258 offsetT val;
22259
22260 /* Assume worst case for symbols not known to be in the same section. */
974da60d
NC
22261 if (fragp->fr_symbol == NULL
22262 || !S_IS_DEFINED (fragp->fr_symbol)
77db8e2e
NC
22263 || sec != S_GET_SEGMENT (fragp->fr_symbol)
22264 || S_IS_WEAK (fragp->fr_symbol))
0110f2b8
PB
22265 return 4;
22266
5f4273c7 22267 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
22268 addr = fragp->fr_address + fragp->fr_fix;
22269 addr = (addr + 4) & ~3;
5e77afaa 22270 /* Force misaligned targets to 32-bit variant. */
0110f2b8 22271 if (val & 3)
5e77afaa 22272 return 4;
0110f2b8
PB
22273 val -= addr;
22274 if (val < 0 || val > 1020)
22275 return 4;
22276 return 2;
22277}
22278
22279/* Return the size of a relaxable add/sub immediate instruction. */
22280static int
22281relax_addsub (fragS *fragp, asection *sec)
22282{
22283 char *buf;
22284 int op;
22285
22286 buf = fragp->fr_literal + fragp->fr_fix;
22287 op = bfd_get_16(sec->owner, buf);
22288 if ((op & 0xf) == ((op >> 4) & 0xf))
22289 return relax_immediate (fragp, 8, 0);
22290 else
22291 return relax_immediate (fragp, 3, 0);
22292}
22293
e83a675f
RE
22294/* Return TRUE iff the definition of symbol S could be pre-empted
22295 (overridden) at link or load time. */
22296static bfd_boolean
22297symbol_preemptible (symbolS *s)
22298{
22299 /* Weak symbols can always be pre-empted. */
22300 if (S_IS_WEAK (s))
22301 return TRUE;
22302
22303 /* Non-global symbols cannot be pre-empted. */
22304 if (! S_IS_EXTERNAL (s))
22305 return FALSE;
22306
22307#ifdef OBJ_ELF
22308 /* In ELF, a global symbol can be marked protected, or private. In that
22309 case it can't be pre-empted (other definitions in the same link unit
22310 would violate the ODR). */
22311 if (ELF_ST_VISIBILITY (S_GET_OTHER (s)) > STV_DEFAULT)
22312 return FALSE;
22313#endif
22314
22315 /* Other global symbols might be pre-empted. */
22316 return TRUE;
22317}
0110f2b8
PB
22318
22319/* Return the size of a relaxable branch instruction. BITS is the
22320 size of the offset field in the narrow instruction. */
22321
22322static int
5e77afaa 22323relax_branch (fragS *fragp, asection *sec, int bits, long stretch)
0110f2b8
PB
22324{
22325 addressT addr;
22326 offsetT val;
22327 offsetT limit;
22328
22329 /* Assume worst case for symbols not known to be in the same section. */
5f4273c7 22330 if (!S_IS_DEFINED (fragp->fr_symbol)
77db8e2e
NC
22331 || sec != S_GET_SEGMENT (fragp->fr_symbol)
22332 || S_IS_WEAK (fragp->fr_symbol))
0110f2b8
PB
22333 return 4;
22334
267bf995 22335#ifdef OBJ_ELF
e83a675f 22336 /* A branch to a function in ARM state will require interworking. */
267bf995
RR
22337 if (S_IS_DEFINED (fragp->fr_symbol)
22338 && ARM_IS_FUNC (fragp->fr_symbol))
22339 return 4;
e83a675f 22340#endif
0d9b4b55 22341
e83a675f 22342 if (symbol_preemptible (fragp->fr_symbol))
0d9b4b55 22343 return 4;
267bf995 22344
5f4273c7 22345 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
22346 addr = fragp->fr_address + fragp->fr_fix + 4;
22347 val -= addr;
22348
22349 /* Offset is a signed value *2 */
22350 limit = 1 << bits;
22351 if (val >= limit || val < -limit)
22352 return 4;
22353 return 2;
22354}
22355
22356
22357/* Relax a machine dependent frag. This returns the amount by which
22358 the current size of the frag should change. */
22359
22360int
5e77afaa 22361arm_relax_frag (asection *sec, fragS *fragp, long stretch)
0110f2b8
PB
22362{
22363 int oldsize;
22364 int newsize;
22365
22366 oldsize = fragp->fr_var;
22367 switch (fragp->fr_subtype)
22368 {
22369 case T_MNEM_ldr_pc2:
5f4273c7 22370 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
22371 break;
22372 case T_MNEM_ldr_pc:
22373 case T_MNEM_ldr_sp:
22374 case T_MNEM_str_sp:
5f4273c7 22375 newsize = relax_immediate (fragp, 8, 2);
0110f2b8
PB
22376 break;
22377 case T_MNEM_ldr:
22378 case T_MNEM_str:
5f4273c7 22379 newsize = relax_immediate (fragp, 5, 2);
0110f2b8
PB
22380 break;
22381 case T_MNEM_ldrh:
22382 case T_MNEM_strh:
5f4273c7 22383 newsize = relax_immediate (fragp, 5, 1);
0110f2b8
PB
22384 break;
22385 case T_MNEM_ldrb:
22386 case T_MNEM_strb:
5f4273c7 22387 newsize = relax_immediate (fragp, 5, 0);
0110f2b8
PB
22388 break;
22389 case T_MNEM_adr:
5f4273c7 22390 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
22391 break;
22392 case T_MNEM_mov:
22393 case T_MNEM_movs:
22394 case T_MNEM_cmp:
22395 case T_MNEM_cmn:
5f4273c7 22396 newsize = relax_immediate (fragp, 8, 0);
0110f2b8
PB
22397 break;
22398 case T_MNEM_b:
5f4273c7 22399 newsize = relax_branch (fragp, sec, 11, stretch);
0110f2b8
PB
22400 break;
22401 case T_MNEM_bcond:
5f4273c7 22402 newsize = relax_branch (fragp, sec, 8, stretch);
0110f2b8
PB
22403 break;
22404 case T_MNEM_add_sp:
22405 case T_MNEM_add_pc:
22406 newsize = relax_immediate (fragp, 8, 2);
22407 break;
22408 case T_MNEM_inc_sp:
22409 case T_MNEM_dec_sp:
22410 newsize = relax_immediate (fragp, 7, 2);
22411 break;
22412 case T_MNEM_addi:
22413 case T_MNEM_addis:
22414 case T_MNEM_subi:
22415 case T_MNEM_subis:
22416 newsize = relax_addsub (fragp, sec);
22417 break;
22418 default:
5f4273c7 22419 abort ();
0110f2b8 22420 }
5e77afaa
PB
22421
22422 fragp->fr_var = newsize;
22423 /* Freeze wide instructions that are at or before the same location as
22424 in the previous pass. This avoids infinite loops.
5f4273c7
NC
22425 Don't freeze them unconditionally because targets may be artificially
22426 misaligned by the expansion of preceding frags. */
5e77afaa 22427 if (stretch <= 0 && newsize > 2)
0110f2b8 22428 {
0110f2b8 22429 md_convert_frag (sec->owner, sec, fragp);
5f4273c7 22430 frag_wane (fragp);
0110f2b8 22431 }
5e77afaa 22432
0110f2b8 22433 return newsize - oldsize;
c19d1205 22434}
b99bd4ef 22435
c19d1205 22436/* Round up a section size to the appropriate boundary. */
b99bd4ef 22437
c19d1205
ZW
22438valueT
22439md_section_align (segT segment ATTRIBUTE_UNUSED,
22440 valueT size)
22441{
6844c0cc 22442 return size;
bfae80f2 22443}
b99bd4ef 22444
c19d1205
ZW
22445/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
22446 of an rs_align_code fragment. */
22447
22448void
22449arm_handle_align (fragS * fragP)
bfae80f2 22450{
d9235011 22451 static unsigned char const arm_noop[2][2][4] =
e7495e45
NS
22452 {
22453 { /* ARMv1 */
22454 {0x00, 0x00, 0xa0, 0xe1}, /* LE */
22455 {0xe1, 0xa0, 0x00, 0x00}, /* BE */
22456 },
22457 { /* ARMv6k */
22458 {0x00, 0xf0, 0x20, 0xe3}, /* LE */
22459 {0xe3, 0x20, 0xf0, 0x00}, /* BE */
22460 },
22461 };
d9235011 22462 static unsigned char const thumb_noop[2][2][2] =
e7495e45
NS
22463 {
22464 { /* Thumb-1 */
22465 {0xc0, 0x46}, /* LE */
22466 {0x46, 0xc0}, /* BE */
22467 },
22468 { /* Thumb-2 */
22469 {0x00, 0xbf}, /* LE */
22470 {0xbf, 0x00} /* BE */
22471 }
22472 };
d9235011 22473 static unsigned char const wide_thumb_noop[2][4] =
e7495e45
NS
22474 { /* Wide Thumb-2 */
22475 {0xaf, 0xf3, 0x00, 0x80}, /* LE */
22476 {0xf3, 0xaf, 0x80, 0x00}, /* BE */
22477 };
c921be7d 22478
e7495e45 22479 unsigned bytes, fix, noop_size;
c19d1205 22480 char * p;
d9235011
TS
22481 const unsigned char * noop;
22482 const unsigned char *narrow_noop = NULL;
cd000bff
DJ
22483#ifdef OBJ_ELF
22484 enum mstate state;
22485#endif
bfae80f2 22486
c19d1205 22487 if (fragP->fr_type != rs_align_code)
bfae80f2
RE
22488 return;
22489
c19d1205
ZW
22490 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
22491 p = fragP->fr_literal + fragP->fr_fix;
22492 fix = 0;
bfae80f2 22493
c19d1205
ZW
22494 if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
22495 bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
bfae80f2 22496
cd000bff 22497 gas_assert ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) != 0);
8dc2430f 22498
cd000bff 22499 if (fragP->tc_frag_data.thumb_mode & (~ MODE_RECORDED))
a737bd4d 22500 {
7f78eb34
JW
22501 if (ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
22502 ? selected_cpu : arm_arch_none, arm_ext_v6t2))
e7495e45
NS
22503 {
22504 narrow_noop = thumb_noop[1][target_big_endian];
22505 noop = wide_thumb_noop[target_big_endian];
22506 }
c19d1205 22507 else
e7495e45
NS
22508 noop = thumb_noop[0][target_big_endian];
22509 noop_size = 2;
cd000bff
DJ
22510#ifdef OBJ_ELF
22511 state = MAP_THUMB;
22512#endif
7ed4c4c5
NC
22513 }
22514 else
22515 {
7f78eb34
JW
22516 noop = arm_noop[ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
22517 ? selected_cpu : arm_arch_none,
22518 arm_ext_v6k) != 0]
e7495e45
NS
22519 [target_big_endian];
22520 noop_size = 4;
cd000bff
DJ
22521#ifdef OBJ_ELF
22522 state = MAP_ARM;
22523#endif
7ed4c4c5 22524 }
c921be7d 22525
e7495e45 22526 fragP->fr_var = noop_size;
c921be7d 22527
c19d1205 22528 if (bytes & (noop_size - 1))
7ed4c4c5 22529 {
c19d1205 22530 fix = bytes & (noop_size - 1);
cd000bff
DJ
22531#ifdef OBJ_ELF
22532 insert_data_mapping_symbol (state, fragP->fr_fix, fragP, fix);
22533#endif
c19d1205
ZW
22534 memset (p, 0, fix);
22535 p += fix;
22536 bytes -= fix;
a737bd4d 22537 }
a737bd4d 22538
e7495e45
NS
22539 if (narrow_noop)
22540 {
22541 if (bytes & noop_size)
22542 {
22543 /* Insert a narrow noop. */
22544 memcpy (p, narrow_noop, noop_size);
22545 p += noop_size;
22546 bytes -= noop_size;
22547 fix += noop_size;
22548 }
22549
22550 /* Use wide noops for the remainder */
22551 noop_size = 4;
22552 }
22553
c19d1205 22554 while (bytes >= noop_size)
a737bd4d 22555 {
c19d1205
ZW
22556 memcpy (p, noop, noop_size);
22557 p += noop_size;
22558 bytes -= noop_size;
22559 fix += noop_size;
a737bd4d
NC
22560 }
22561
c19d1205 22562 fragP->fr_fix += fix;
a737bd4d
NC
22563}
22564
c19d1205
ZW
22565/* Called from md_do_align. Used to create an alignment
22566 frag in a code section. */
22567
22568void
22569arm_frag_align_code (int n, int max)
bfae80f2 22570{
c19d1205 22571 char * p;
7ed4c4c5 22572
c19d1205 22573 /* We assume that there will never be a requirement
6ec8e702 22574 to support alignments greater than MAX_MEM_FOR_RS_ALIGN_CODE bytes. */
c19d1205 22575 if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
6ec8e702
NC
22576 {
22577 char err_msg[128];
22578
fa94de6b 22579 sprintf (err_msg,
477330fc
RM
22580 _("alignments greater than %d bytes not supported in .text sections."),
22581 MAX_MEM_FOR_RS_ALIGN_CODE + 1);
20203fb9 22582 as_fatal ("%s", err_msg);
6ec8e702 22583 }
bfae80f2 22584
c19d1205
ZW
22585 p = frag_var (rs_align_code,
22586 MAX_MEM_FOR_RS_ALIGN_CODE,
22587 1,
22588 (relax_substateT) max,
22589 (symbolS *) NULL,
22590 (offsetT) n,
22591 (char *) NULL);
22592 *p = 0;
22593}
bfae80f2 22594
8dc2430f
NC
22595/* Perform target specific initialisation of a frag.
22596 Note - despite the name this initialisation is not done when the frag
22597 is created, but only when its type is assigned. A frag can be created
22598 and used a long time before its type is set, so beware of assuming that
33eaf5de 22599 this initialisation is performed first. */
bfae80f2 22600
cd000bff
DJ
22601#ifndef OBJ_ELF
22602void
22603arm_init_frag (fragS * fragP, int max_chars ATTRIBUTE_UNUSED)
22604{
22605 /* Record whether this frag is in an ARM or a THUMB area. */
2e98972e 22606 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
cd000bff
DJ
22607}
22608
22609#else /* OBJ_ELF is defined. */
c19d1205 22610void
cd000bff 22611arm_init_frag (fragS * fragP, int max_chars)
c19d1205 22612{
e8d84ca1 22613 bfd_boolean frag_thumb_mode;
b968d18a 22614
8dc2430f
NC
22615 /* If the current ARM vs THUMB mode has not already
22616 been recorded into this frag then do so now. */
cd000bff 22617 if ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) == 0)
b968d18a
JW
22618 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
22619
e8d84ca1
NC
22620 /* PR 21809: Do not set a mapping state for debug sections
22621 - it just confuses other tools. */
22622 if (bfd_get_section_flags (NULL, now_seg) & SEC_DEBUGGING)
22623 return;
22624
b968d18a 22625 frag_thumb_mode = fragP->tc_frag_data.thumb_mode ^ MODE_RECORDED;
cd000bff 22626
f9c1b181
RL
22627 /* Record a mapping symbol for alignment frags. We will delete this
22628 later if the alignment ends up empty. */
22629 switch (fragP->fr_type)
22630 {
22631 case rs_align:
22632 case rs_align_test:
22633 case rs_fill:
22634 mapping_state_2 (MAP_DATA, max_chars);
22635 break;
22636 case rs_align_code:
b968d18a 22637 mapping_state_2 (frag_thumb_mode ? MAP_THUMB : MAP_ARM, max_chars);
f9c1b181
RL
22638 break;
22639 default:
22640 break;
cd000bff 22641 }
bfae80f2
RE
22642}
22643
c19d1205
ZW
22644/* When we change sections we need to issue a new mapping symbol. */
22645
22646void
22647arm_elf_change_section (void)
bfae80f2 22648{
c19d1205
ZW
22649 /* Link an unlinked unwind index table section to the .text section. */
22650 if (elf_section_type (now_seg) == SHT_ARM_EXIDX
22651 && elf_linked_to_section (now_seg) == NULL)
22652 elf_linked_to_section (now_seg) = text_section;
bfae80f2
RE
22653}
22654
c19d1205
ZW
22655int
22656arm_elf_section_type (const char * str, size_t len)
e45d0630 22657{
c19d1205
ZW
22658 if (len == 5 && strncmp (str, "exidx", 5) == 0)
22659 return SHT_ARM_EXIDX;
e45d0630 22660
c19d1205
ZW
22661 return -1;
22662}
22663\f
22664/* Code to deal with unwinding tables. */
e45d0630 22665
c19d1205 22666static void add_unwind_adjustsp (offsetT);
e45d0630 22667
5f4273c7 22668/* Generate any deferred unwind frame offset. */
e45d0630 22669
bfae80f2 22670static void
c19d1205 22671flush_pending_unwind (void)
bfae80f2 22672{
c19d1205 22673 offsetT offset;
bfae80f2 22674
c19d1205
ZW
22675 offset = unwind.pending_offset;
22676 unwind.pending_offset = 0;
22677 if (offset != 0)
22678 add_unwind_adjustsp (offset);
bfae80f2
RE
22679}
22680
c19d1205
ZW
22681/* Add an opcode to this list for this function. Two-byte opcodes should
22682 be passed as op[0] << 8 | op[1]. The list of opcodes is built in reverse
22683 order. */
22684
bfae80f2 22685static void
c19d1205 22686add_unwind_opcode (valueT op, int length)
bfae80f2 22687{
c19d1205
ZW
22688 /* Add any deferred stack adjustment. */
22689 if (unwind.pending_offset)
22690 flush_pending_unwind ();
bfae80f2 22691
c19d1205 22692 unwind.sp_restored = 0;
bfae80f2 22693
c19d1205 22694 if (unwind.opcode_count + length > unwind.opcode_alloc)
bfae80f2 22695 {
c19d1205
ZW
22696 unwind.opcode_alloc += ARM_OPCODE_CHUNK_SIZE;
22697 if (unwind.opcodes)
325801bd
TS
22698 unwind.opcodes = XRESIZEVEC (unsigned char, unwind.opcodes,
22699 unwind.opcode_alloc);
c19d1205 22700 else
325801bd 22701 unwind.opcodes = XNEWVEC (unsigned char, unwind.opcode_alloc);
bfae80f2 22702 }
c19d1205 22703 while (length > 0)
bfae80f2 22704 {
c19d1205
ZW
22705 length--;
22706 unwind.opcodes[unwind.opcode_count] = op & 0xff;
22707 op >>= 8;
22708 unwind.opcode_count++;
bfae80f2 22709 }
bfae80f2
RE
22710}
22711
c19d1205
ZW
22712/* Add unwind opcodes to adjust the stack pointer. */
22713
bfae80f2 22714static void
c19d1205 22715add_unwind_adjustsp (offsetT offset)
bfae80f2 22716{
c19d1205 22717 valueT op;
bfae80f2 22718
c19d1205 22719 if (offset > 0x200)
bfae80f2 22720 {
c19d1205
ZW
22721 /* We need at most 5 bytes to hold a 32-bit value in a uleb128. */
22722 char bytes[5];
22723 int n;
22724 valueT o;
bfae80f2 22725
c19d1205
ZW
22726 /* Long form: 0xb2, uleb128. */
22727 /* This might not fit in a word so add the individual bytes,
22728 remembering the list is built in reverse order. */
22729 o = (valueT) ((offset - 0x204) >> 2);
22730 if (o == 0)
22731 add_unwind_opcode (0, 1);
bfae80f2 22732
c19d1205
ZW
22733 /* Calculate the uleb128 encoding of the offset. */
22734 n = 0;
22735 while (o)
22736 {
22737 bytes[n] = o & 0x7f;
22738 o >>= 7;
22739 if (o)
22740 bytes[n] |= 0x80;
22741 n++;
22742 }
22743 /* Add the insn. */
22744 for (; n; n--)
22745 add_unwind_opcode (bytes[n - 1], 1);
22746 add_unwind_opcode (0xb2, 1);
22747 }
22748 else if (offset > 0x100)
bfae80f2 22749 {
c19d1205
ZW
22750 /* Two short opcodes. */
22751 add_unwind_opcode (0x3f, 1);
22752 op = (offset - 0x104) >> 2;
22753 add_unwind_opcode (op, 1);
bfae80f2 22754 }
c19d1205
ZW
22755 else if (offset > 0)
22756 {
22757 /* Short opcode. */
22758 op = (offset - 4) >> 2;
22759 add_unwind_opcode (op, 1);
22760 }
22761 else if (offset < 0)
bfae80f2 22762 {
c19d1205
ZW
22763 offset = -offset;
22764 while (offset > 0x100)
bfae80f2 22765 {
c19d1205
ZW
22766 add_unwind_opcode (0x7f, 1);
22767 offset -= 0x100;
bfae80f2 22768 }
c19d1205
ZW
22769 op = ((offset - 4) >> 2) | 0x40;
22770 add_unwind_opcode (op, 1);
bfae80f2 22771 }
bfae80f2
RE
22772}
22773
c19d1205 22774/* Finish the list of unwind opcodes for this function. */
0198d5e6 22775
c19d1205
ZW
22776static void
22777finish_unwind_opcodes (void)
bfae80f2 22778{
c19d1205 22779 valueT op;
bfae80f2 22780
c19d1205 22781 if (unwind.fp_used)
bfae80f2 22782 {
708587a4 22783 /* Adjust sp as necessary. */
c19d1205
ZW
22784 unwind.pending_offset += unwind.fp_offset - unwind.frame_size;
22785 flush_pending_unwind ();
bfae80f2 22786
c19d1205
ZW
22787 /* After restoring sp from the frame pointer. */
22788 op = 0x90 | unwind.fp_reg;
22789 add_unwind_opcode (op, 1);
22790 }
22791 else
22792 flush_pending_unwind ();
bfae80f2
RE
22793}
22794
bfae80f2 22795
c19d1205
ZW
22796/* Start an exception table entry. If idx is nonzero this is an index table
22797 entry. */
bfae80f2
RE
22798
22799static void
c19d1205 22800start_unwind_section (const segT text_seg, int idx)
bfae80f2 22801{
c19d1205
ZW
22802 const char * text_name;
22803 const char * prefix;
22804 const char * prefix_once;
22805 const char * group_name;
c19d1205 22806 char * sec_name;
c19d1205
ZW
22807 int type;
22808 int flags;
22809 int linkonce;
bfae80f2 22810
c19d1205 22811 if (idx)
bfae80f2 22812 {
c19d1205
ZW
22813 prefix = ELF_STRING_ARM_unwind;
22814 prefix_once = ELF_STRING_ARM_unwind_once;
22815 type = SHT_ARM_EXIDX;
bfae80f2 22816 }
c19d1205 22817 else
bfae80f2 22818 {
c19d1205
ZW
22819 prefix = ELF_STRING_ARM_unwind_info;
22820 prefix_once = ELF_STRING_ARM_unwind_info_once;
22821 type = SHT_PROGBITS;
bfae80f2
RE
22822 }
22823
c19d1205
ZW
22824 text_name = segment_name (text_seg);
22825 if (streq (text_name, ".text"))
22826 text_name = "";
22827
22828 if (strncmp (text_name, ".gnu.linkonce.t.",
22829 strlen (".gnu.linkonce.t.")) == 0)
bfae80f2 22830 {
c19d1205
ZW
22831 prefix = prefix_once;
22832 text_name += strlen (".gnu.linkonce.t.");
bfae80f2
RE
22833 }
22834
29a2809e 22835 sec_name = concat (prefix, text_name, (char *) NULL);
bfae80f2 22836
c19d1205
ZW
22837 flags = SHF_ALLOC;
22838 linkonce = 0;
22839 group_name = 0;
bfae80f2 22840
c19d1205
ZW
22841 /* Handle COMDAT group. */
22842 if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
bfae80f2 22843 {
c19d1205
ZW
22844 group_name = elf_group_name (text_seg);
22845 if (group_name == NULL)
22846 {
bd3ba5d1 22847 as_bad (_("Group section `%s' has no group signature"),
c19d1205
ZW
22848 segment_name (text_seg));
22849 ignore_rest_of_line ();
22850 return;
22851 }
22852 flags |= SHF_GROUP;
22853 linkonce = 1;
bfae80f2
RE
22854 }
22855
a91e1603
L
22856 obj_elf_change_section (sec_name, type, 0, flags, 0, group_name,
22857 linkonce, 0);
bfae80f2 22858
5f4273c7 22859 /* Set the section link for index tables. */
c19d1205
ZW
22860 if (idx)
22861 elf_linked_to_section (now_seg) = text_seg;
bfae80f2
RE
22862}
22863
bfae80f2 22864
c19d1205
ZW
22865/* Start an unwind table entry. HAVE_DATA is nonzero if we have additional
22866 personality routine data. Returns zero, or the index table value for
cad0da33 22867 an inline entry. */
c19d1205
ZW
22868
22869static valueT
22870create_unwind_entry (int have_data)
bfae80f2 22871{
c19d1205
ZW
22872 int size;
22873 addressT where;
22874 char *ptr;
22875 /* The current word of data. */
22876 valueT data;
22877 /* The number of bytes left in this word. */
22878 int n;
bfae80f2 22879
c19d1205 22880 finish_unwind_opcodes ();
bfae80f2 22881
c19d1205
ZW
22882 /* Remember the current text section. */
22883 unwind.saved_seg = now_seg;
22884 unwind.saved_subseg = now_subseg;
bfae80f2 22885
c19d1205 22886 start_unwind_section (now_seg, 0);
bfae80f2 22887
c19d1205 22888 if (unwind.personality_routine == NULL)
bfae80f2 22889 {
c19d1205
ZW
22890 if (unwind.personality_index == -2)
22891 {
22892 if (have_data)
5f4273c7 22893 as_bad (_("handlerdata in cantunwind frame"));
c19d1205
ZW
22894 return 1; /* EXIDX_CANTUNWIND. */
22895 }
bfae80f2 22896
c19d1205
ZW
22897 /* Use a default personality routine if none is specified. */
22898 if (unwind.personality_index == -1)
22899 {
22900 if (unwind.opcode_count > 3)
22901 unwind.personality_index = 1;
22902 else
22903 unwind.personality_index = 0;
22904 }
bfae80f2 22905
c19d1205
ZW
22906 /* Space for the personality routine entry. */
22907 if (unwind.personality_index == 0)
22908 {
22909 if (unwind.opcode_count > 3)
22910 as_bad (_("too many unwind opcodes for personality routine 0"));
bfae80f2 22911
c19d1205
ZW
22912 if (!have_data)
22913 {
22914 /* All the data is inline in the index table. */
22915 data = 0x80;
22916 n = 3;
22917 while (unwind.opcode_count > 0)
22918 {
22919 unwind.opcode_count--;
22920 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
22921 n--;
22922 }
bfae80f2 22923
c19d1205
ZW
22924 /* Pad with "finish" opcodes. */
22925 while (n--)
22926 data = (data << 8) | 0xb0;
bfae80f2 22927
c19d1205
ZW
22928 return data;
22929 }
22930 size = 0;
22931 }
22932 else
22933 /* We get two opcodes "free" in the first word. */
22934 size = unwind.opcode_count - 2;
22935 }
22936 else
5011093d 22937 {
cad0da33
NC
22938 /* PR 16765: Missing or misplaced unwind directives can trigger this. */
22939 if (unwind.personality_index != -1)
22940 {
22941 as_bad (_("attempt to recreate an unwind entry"));
22942 return 1;
22943 }
5011093d
NC
22944
22945 /* An extra byte is required for the opcode count. */
22946 size = unwind.opcode_count + 1;
22947 }
bfae80f2 22948
c19d1205
ZW
22949 size = (size + 3) >> 2;
22950 if (size > 0xff)
22951 as_bad (_("too many unwind opcodes"));
bfae80f2 22952
c19d1205
ZW
22953 frag_align (2, 0, 0);
22954 record_alignment (now_seg, 2);
22955 unwind.table_entry = expr_build_dot ();
22956
22957 /* Allocate the table entry. */
22958 ptr = frag_more ((size << 2) + 4);
74929e7b
NC
22959 /* PR 13449: Zero the table entries in case some of them are not used. */
22960 memset (ptr, 0, (size << 2) + 4);
c19d1205 22961 where = frag_now_fix () - ((size << 2) + 4);
bfae80f2 22962
c19d1205 22963 switch (unwind.personality_index)
bfae80f2 22964 {
c19d1205
ZW
22965 case -1:
22966 /* ??? Should this be a PLT generating relocation? */
22967 /* Custom personality routine. */
22968 fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1,
22969 BFD_RELOC_ARM_PREL31);
bfae80f2 22970
c19d1205
ZW
22971 where += 4;
22972 ptr += 4;
bfae80f2 22973
c19d1205 22974 /* Set the first byte to the number of additional words. */
5011093d 22975 data = size > 0 ? size - 1 : 0;
c19d1205
ZW
22976 n = 3;
22977 break;
bfae80f2 22978
c19d1205
ZW
22979 /* ABI defined personality routines. */
22980 case 0:
22981 /* Three opcodes bytes are packed into the first word. */
22982 data = 0x80;
22983 n = 3;
22984 break;
bfae80f2 22985
c19d1205
ZW
22986 case 1:
22987 case 2:
22988 /* The size and first two opcode bytes go in the first word. */
22989 data = ((0x80 + unwind.personality_index) << 8) | size;
22990 n = 2;
22991 break;
bfae80f2 22992
c19d1205
ZW
22993 default:
22994 /* Should never happen. */
22995 abort ();
22996 }
bfae80f2 22997
c19d1205
ZW
22998 /* Pack the opcodes into words (MSB first), reversing the list at the same
22999 time. */
23000 while (unwind.opcode_count > 0)
23001 {
23002 if (n == 0)
23003 {
23004 md_number_to_chars (ptr, data, 4);
23005 ptr += 4;
23006 n = 4;
23007 data = 0;
23008 }
23009 unwind.opcode_count--;
23010 n--;
23011 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
23012 }
23013
23014 /* Finish off the last word. */
23015 if (n < 4)
23016 {
23017 /* Pad with "finish" opcodes. */
23018 while (n--)
23019 data = (data << 8) | 0xb0;
23020
23021 md_number_to_chars (ptr, data, 4);
23022 }
23023
23024 if (!have_data)
23025 {
23026 /* Add an empty descriptor if there is no user-specified data. */
23027 ptr = frag_more (4);
23028 md_number_to_chars (ptr, 0, 4);
23029 }
23030
23031 return 0;
bfae80f2
RE
23032}
23033
f0927246
NC
23034
23035/* Initialize the DWARF-2 unwind information for this procedure. */
23036
23037void
23038tc_arm_frame_initial_instructions (void)
23039{
23040 cfi_add_CFA_def_cfa (REG_SP, 0);
23041}
23042#endif /* OBJ_ELF */
23043
c19d1205
ZW
23044/* Convert REGNAME to a DWARF-2 register number. */
23045
23046int
1df69f4f 23047tc_arm_regname_to_dw2regnum (char *regname)
bfae80f2 23048{
1df69f4f 23049 int reg = arm_reg_parse (&regname, REG_TYPE_RN);
1f5afe1c
NC
23050 if (reg != FAIL)
23051 return reg;
c19d1205 23052
1f5afe1c
NC
23053 /* PR 16694: Allow VFP registers as well. */
23054 reg = arm_reg_parse (&regname, REG_TYPE_VFS);
23055 if (reg != FAIL)
23056 return 64 + reg;
c19d1205 23057
1f5afe1c
NC
23058 reg = arm_reg_parse (&regname, REG_TYPE_VFD);
23059 if (reg != FAIL)
23060 return reg + 256;
23061
0198d5e6 23062 return FAIL;
bfae80f2
RE
23063}
23064
f0927246 23065#ifdef TE_PE
c19d1205 23066void
f0927246 23067tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
bfae80f2 23068{
91d6fa6a 23069 expressionS exp;
bfae80f2 23070
91d6fa6a
NC
23071 exp.X_op = O_secrel;
23072 exp.X_add_symbol = symbol;
23073 exp.X_add_number = 0;
23074 emit_expr (&exp, size);
f0927246
NC
23075}
23076#endif
bfae80f2 23077
c19d1205 23078/* MD interface: Symbol and relocation handling. */
bfae80f2 23079
2fc8bdac
ZW
23080/* Return the address within the segment that a PC-relative fixup is
23081 relative to. For ARM, PC-relative fixups applied to instructions
23082 are generally relative to the location of the fixup plus 8 bytes.
23083 Thumb branches are offset by 4, and Thumb loads relative to PC
23084 require special handling. */
bfae80f2 23085
c19d1205 23086long
2fc8bdac 23087md_pcrel_from_section (fixS * fixP, segT seg)
bfae80f2 23088{
2fc8bdac
ZW
23089 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
23090
23091 /* If this is pc-relative and we are going to emit a relocation
23092 then we just want to put out any pipeline compensation that the linker
53baae48
NC
23093 will need. Otherwise we want to use the calculated base.
23094 For WinCE we skip the bias for externals as well, since this
23095 is how the MS ARM-CE assembler behaves and we want to be compatible. */
5f4273c7 23096 if (fixP->fx_pcrel
2fc8bdac 23097 && ((fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != seg)
53baae48
NC
23098 || (arm_force_relocation (fixP)
23099#ifdef TE_WINCE
23100 && !S_IS_EXTERNAL (fixP->fx_addsy)
23101#endif
23102 )))
2fc8bdac 23103 base = 0;
bfae80f2 23104
267bf995 23105
c19d1205 23106 switch (fixP->fx_r_type)
bfae80f2 23107 {
2fc8bdac
ZW
23108 /* PC relative addressing on the Thumb is slightly odd as the
23109 bottom two bits of the PC are forced to zero for the
23110 calculation. This happens *after* application of the
23111 pipeline offset. However, Thumb adrl already adjusts for
23112 this, so we need not do it again. */
c19d1205 23113 case BFD_RELOC_ARM_THUMB_ADD:
2fc8bdac 23114 return base & ~3;
c19d1205
ZW
23115
23116 case BFD_RELOC_ARM_THUMB_OFFSET:
23117 case BFD_RELOC_ARM_T32_OFFSET_IMM:
e9f89963 23118 case BFD_RELOC_ARM_T32_ADD_PC12:
8f06b2d8 23119 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
2fc8bdac 23120 return (base + 4) & ~3;
c19d1205 23121
2fc8bdac 23122 /* Thumb branches are simply offset by +4. */
e12437dc 23123 case BFD_RELOC_THUMB_PCREL_BRANCH5:
2fc8bdac
ZW
23124 case BFD_RELOC_THUMB_PCREL_BRANCH7:
23125 case BFD_RELOC_THUMB_PCREL_BRANCH9:
23126 case BFD_RELOC_THUMB_PCREL_BRANCH12:
23127 case BFD_RELOC_THUMB_PCREL_BRANCH20:
2fc8bdac 23128 case BFD_RELOC_THUMB_PCREL_BRANCH25:
f6b2b12d 23129 case BFD_RELOC_THUMB_PCREL_BFCSEL:
e5d6e09e 23130 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 23131 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 23132 case BFD_RELOC_ARM_THUMB_BF13:
60f993ce 23133 case BFD_RELOC_ARM_THUMB_LOOP12:
2fc8bdac 23134 return base + 4;
bfae80f2 23135
267bf995 23136 case BFD_RELOC_THUMB_PCREL_BRANCH23:
486499d0
CL
23137 if (fixP->fx_addsy
23138 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 23139 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995 23140 && ARM_IS_FUNC (fixP->fx_addsy)
477330fc
RM
23141 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
23142 base = fixP->fx_where + fixP->fx_frag->fr_address;
267bf995
RR
23143 return base + 4;
23144
00adf2d4
JB
23145 /* BLX is like branches above, but forces the low two bits of PC to
23146 zero. */
486499d0
CL
23147 case BFD_RELOC_THUMB_PCREL_BLX:
23148 if (fixP->fx_addsy
23149 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 23150 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
23151 && THUMB_IS_FUNC (fixP->fx_addsy)
23152 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
23153 base = fixP->fx_where + fixP->fx_frag->fr_address;
00adf2d4
JB
23154 return (base + 4) & ~3;
23155
2fc8bdac
ZW
23156 /* ARM mode branches are offset by +8. However, the Windows CE
23157 loader expects the relocation not to take this into account. */
267bf995 23158 case BFD_RELOC_ARM_PCREL_BLX:
486499d0
CL
23159 if (fixP->fx_addsy
23160 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 23161 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
23162 && ARM_IS_FUNC (fixP->fx_addsy)
23163 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
23164 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 23165 return base + 8;
267bf995 23166
486499d0
CL
23167 case BFD_RELOC_ARM_PCREL_CALL:
23168 if (fixP->fx_addsy
23169 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 23170 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
23171 && THUMB_IS_FUNC (fixP->fx_addsy)
23172 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
23173 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 23174 return base + 8;
267bf995 23175
2fc8bdac 23176 case BFD_RELOC_ARM_PCREL_BRANCH:
39b41c9c 23177 case BFD_RELOC_ARM_PCREL_JUMP:
2fc8bdac 23178 case BFD_RELOC_ARM_PLT32:
c19d1205 23179#ifdef TE_WINCE
5f4273c7 23180 /* When handling fixups immediately, because we have already
477330fc 23181 discovered the value of a symbol, or the address of the frag involved
53baae48 23182 we must account for the offset by +8, as the OS loader will never see the reloc.
477330fc
RM
23183 see fixup_segment() in write.c
23184 The S_IS_EXTERNAL test handles the case of global symbols.
23185 Those need the calculated base, not just the pipe compensation the linker will need. */
53baae48
NC
23186 if (fixP->fx_pcrel
23187 && fixP->fx_addsy != NULL
23188 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
23189 && (S_IS_EXTERNAL (fixP->fx_addsy) || !arm_force_relocation (fixP)))
23190 return base + 8;
2fc8bdac 23191 return base;
c19d1205 23192#else
2fc8bdac 23193 return base + 8;
c19d1205 23194#endif
2fc8bdac 23195
267bf995 23196
2fc8bdac
ZW
23197 /* ARM mode loads relative to PC are also offset by +8. Unlike
23198 branches, the Windows CE loader *does* expect the relocation
23199 to take this into account. */
23200 case BFD_RELOC_ARM_OFFSET_IMM:
23201 case BFD_RELOC_ARM_OFFSET_IMM8:
23202 case BFD_RELOC_ARM_HWLITERAL:
23203 case BFD_RELOC_ARM_LITERAL:
23204 case BFD_RELOC_ARM_CP_OFF_IMM:
23205 return base + 8;
23206
23207
23208 /* Other PC-relative relocations are un-offset. */
23209 default:
23210 return base;
23211 }
bfae80f2
RE
23212}
23213
8b2d793c
NC
23214static bfd_boolean flag_warn_syms = TRUE;
23215
ae8714c2
NC
23216bfd_boolean
23217arm_tc_equal_in_insn (int c ATTRIBUTE_UNUSED, char * name)
bfae80f2 23218{
8b2d793c
NC
23219 /* PR 18347 - Warn if the user attempts to create a symbol with the same
23220 name as an ARM instruction. Whilst strictly speaking it is allowed, it
23221 does mean that the resulting code might be very confusing to the reader.
23222 Also this warning can be triggered if the user omits an operand before
23223 an immediate address, eg:
23224
23225 LDR =foo
23226
23227 GAS treats this as an assignment of the value of the symbol foo to a
23228 symbol LDR, and so (without this code) it will not issue any kind of
23229 warning or error message.
23230
23231 Note - ARM instructions are case-insensitive but the strings in the hash
23232 table are all stored in lower case, so we must first ensure that name is
ae8714c2
NC
23233 lower case too. */
23234 if (flag_warn_syms && arm_ops_hsh)
8b2d793c
NC
23235 {
23236 char * nbuf = strdup (name);
23237 char * p;
23238
23239 for (p = nbuf; *p; p++)
23240 *p = TOLOWER (*p);
23241 if (hash_find (arm_ops_hsh, nbuf) != NULL)
23242 {
23243 static struct hash_control * already_warned = NULL;
23244
23245 if (already_warned == NULL)
23246 already_warned = hash_new ();
23247 /* Only warn about the symbol once. To keep the code
23248 simple we let hash_insert do the lookup for us. */
23249 if (hash_insert (already_warned, name, NULL) == NULL)
ae8714c2 23250 as_warn (_("[-mwarn-syms]: Assignment makes a symbol match an ARM instruction: %s"), name);
8b2d793c
NC
23251 }
23252 else
23253 free (nbuf);
23254 }
3739860c 23255
ae8714c2
NC
23256 return FALSE;
23257}
23258
23259/* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
23260 Otherwise we have no need to default values of symbols. */
23261
23262symbolS *
23263md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
23264{
23265#ifdef OBJ_ELF
23266 if (name[0] == '_' && name[1] == 'G'
23267 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
23268 {
23269 if (!GOT_symbol)
23270 {
23271 if (symbol_find (name))
23272 as_bad (_("GOT already in the symbol table"));
23273
23274 GOT_symbol = symbol_new (name, undefined_section,
23275 (valueT) 0, & zero_address_frag);
23276 }
23277
23278 return GOT_symbol;
23279 }
23280#endif
23281
c921be7d 23282 return NULL;
bfae80f2
RE
23283}
23284
55cf6793 23285/* Subroutine of md_apply_fix. Check to see if an immediate can be
c19d1205
ZW
23286 computed as two separate immediate values, added together. We
23287 already know that this value cannot be computed by just one ARM
23288 instruction. */
23289
23290static unsigned int
23291validate_immediate_twopart (unsigned int val,
23292 unsigned int * highpart)
bfae80f2 23293{
c19d1205
ZW
23294 unsigned int a;
23295 unsigned int i;
bfae80f2 23296
c19d1205
ZW
23297 for (i = 0; i < 32; i += 2)
23298 if (((a = rotate_left (val, i)) & 0xff) != 0)
23299 {
23300 if (a & 0xff00)
23301 {
23302 if (a & ~ 0xffff)
23303 continue;
23304 * highpart = (a >> 8) | ((i + 24) << 7);
23305 }
23306 else if (a & 0xff0000)
23307 {
23308 if (a & 0xff000000)
23309 continue;
23310 * highpart = (a >> 16) | ((i + 16) << 7);
23311 }
23312 else
23313 {
9c2799c2 23314 gas_assert (a & 0xff000000);
c19d1205
ZW
23315 * highpart = (a >> 24) | ((i + 8) << 7);
23316 }
bfae80f2 23317
c19d1205
ZW
23318 return (a & 0xff) | (i << 7);
23319 }
bfae80f2 23320
c19d1205 23321 return FAIL;
bfae80f2
RE
23322}
23323
c19d1205
ZW
23324static int
23325validate_offset_imm (unsigned int val, int hwse)
23326{
23327 if ((hwse && val > 255) || val > 4095)
23328 return FAIL;
23329 return val;
23330}
bfae80f2 23331
55cf6793 23332/* Subroutine of md_apply_fix. Do those data_ops which can take a
c19d1205
ZW
23333 negative immediate constant by altering the instruction. A bit of
23334 a hack really.
23335 MOV <-> MVN
23336 AND <-> BIC
23337 ADC <-> SBC
23338 by inverting the second operand, and
23339 ADD <-> SUB
23340 CMP <-> CMN
23341 by negating the second operand. */
bfae80f2 23342
c19d1205
ZW
23343static int
23344negate_data_op (unsigned long * instruction,
23345 unsigned long value)
bfae80f2 23346{
c19d1205
ZW
23347 int op, new_inst;
23348 unsigned long negated, inverted;
bfae80f2 23349
c19d1205
ZW
23350 negated = encode_arm_immediate (-value);
23351 inverted = encode_arm_immediate (~value);
bfae80f2 23352
c19d1205
ZW
23353 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
23354 switch (op)
bfae80f2 23355 {
c19d1205
ZW
23356 /* First negates. */
23357 case OPCODE_SUB: /* ADD <-> SUB */
23358 new_inst = OPCODE_ADD;
23359 value = negated;
23360 break;
bfae80f2 23361
c19d1205
ZW
23362 case OPCODE_ADD:
23363 new_inst = OPCODE_SUB;
23364 value = negated;
23365 break;
bfae80f2 23366
c19d1205
ZW
23367 case OPCODE_CMP: /* CMP <-> CMN */
23368 new_inst = OPCODE_CMN;
23369 value = negated;
23370 break;
bfae80f2 23371
c19d1205
ZW
23372 case OPCODE_CMN:
23373 new_inst = OPCODE_CMP;
23374 value = negated;
23375 break;
bfae80f2 23376
c19d1205
ZW
23377 /* Now Inverted ops. */
23378 case OPCODE_MOV: /* MOV <-> MVN */
23379 new_inst = OPCODE_MVN;
23380 value = inverted;
23381 break;
bfae80f2 23382
c19d1205
ZW
23383 case OPCODE_MVN:
23384 new_inst = OPCODE_MOV;
23385 value = inverted;
23386 break;
bfae80f2 23387
c19d1205
ZW
23388 case OPCODE_AND: /* AND <-> BIC */
23389 new_inst = OPCODE_BIC;
23390 value = inverted;
23391 break;
bfae80f2 23392
c19d1205
ZW
23393 case OPCODE_BIC:
23394 new_inst = OPCODE_AND;
23395 value = inverted;
23396 break;
bfae80f2 23397
c19d1205
ZW
23398 case OPCODE_ADC: /* ADC <-> SBC */
23399 new_inst = OPCODE_SBC;
23400 value = inverted;
23401 break;
bfae80f2 23402
c19d1205
ZW
23403 case OPCODE_SBC:
23404 new_inst = OPCODE_ADC;
23405 value = inverted;
23406 break;
bfae80f2 23407
c19d1205
ZW
23408 /* We cannot do anything. */
23409 default:
23410 return FAIL;
b99bd4ef
NC
23411 }
23412
c19d1205
ZW
23413 if (value == (unsigned) FAIL)
23414 return FAIL;
23415
23416 *instruction &= OPCODE_MASK;
23417 *instruction |= new_inst << DATA_OP_SHIFT;
23418 return value;
b99bd4ef
NC
23419}
23420
ef8d22e6
PB
23421/* Like negate_data_op, but for Thumb-2. */
23422
23423static unsigned int
16dd5e42 23424thumb32_negate_data_op (offsetT *instruction, unsigned int value)
ef8d22e6
PB
23425{
23426 int op, new_inst;
23427 int rd;
16dd5e42 23428 unsigned int negated, inverted;
ef8d22e6
PB
23429
23430 negated = encode_thumb32_immediate (-value);
23431 inverted = encode_thumb32_immediate (~value);
23432
23433 rd = (*instruction >> 8) & 0xf;
23434 op = (*instruction >> T2_DATA_OP_SHIFT) & 0xf;
23435 switch (op)
23436 {
23437 /* ADD <-> SUB. Includes CMP <-> CMN. */
23438 case T2_OPCODE_SUB:
23439 new_inst = T2_OPCODE_ADD;
23440 value = negated;
23441 break;
23442
23443 case T2_OPCODE_ADD:
23444 new_inst = T2_OPCODE_SUB;
23445 value = negated;
23446 break;
23447
23448 /* ORR <-> ORN. Includes MOV <-> MVN. */
23449 case T2_OPCODE_ORR:
23450 new_inst = T2_OPCODE_ORN;
23451 value = inverted;
23452 break;
23453
23454 case T2_OPCODE_ORN:
23455 new_inst = T2_OPCODE_ORR;
23456 value = inverted;
23457 break;
23458
23459 /* AND <-> BIC. TST has no inverted equivalent. */
23460 case T2_OPCODE_AND:
23461 new_inst = T2_OPCODE_BIC;
23462 if (rd == 15)
23463 value = FAIL;
23464 else
23465 value = inverted;
23466 break;
23467
23468 case T2_OPCODE_BIC:
23469 new_inst = T2_OPCODE_AND;
23470 value = inverted;
23471 break;
23472
23473 /* ADC <-> SBC */
23474 case T2_OPCODE_ADC:
23475 new_inst = T2_OPCODE_SBC;
23476 value = inverted;
23477 break;
23478
23479 case T2_OPCODE_SBC:
23480 new_inst = T2_OPCODE_ADC;
23481 value = inverted;
23482 break;
23483
23484 /* We cannot do anything. */
23485 default:
23486 return FAIL;
23487 }
23488
16dd5e42 23489 if (value == (unsigned int)FAIL)
ef8d22e6
PB
23490 return FAIL;
23491
23492 *instruction &= T2_OPCODE_MASK;
23493 *instruction |= new_inst << T2_DATA_OP_SHIFT;
23494 return value;
23495}
23496
8f06b2d8 23497/* Read a 32-bit thumb instruction from buf. */
0198d5e6 23498
8f06b2d8
PB
23499static unsigned long
23500get_thumb32_insn (char * buf)
23501{
23502 unsigned long insn;
23503 insn = md_chars_to_number (buf, THUMB_SIZE) << 16;
23504 insn |= md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
23505
23506 return insn;
23507}
23508
a8bc6c78
PB
23509/* We usually want to set the low bit on the address of thumb function
23510 symbols. In particular .word foo - . should have the low bit set.
23511 Generic code tries to fold the difference of two symbols to
23512 a constant. Prevent this and force a relocation when the first symbols
23513 is a thumb function. */
c921be7d
NC
23514
23515bfd_boolean
a8bc6c78
PB
23516arm_optimize_expr (expressionS *l, operatorT op, expressionS *r)
23517{
23518 if (op == O_subtract
23519 && l->X_op == O_symbol
23520 && r->X_op == O_symbol
23521 && THUMB_IS_FUNC (l->X_add_symbol))
23522 {
23523 l->X_op = O_subtract;
23524 l->X_op_symbol = r->X_add_symbol;
23525 l->X_add_number -= r->X_add_number;
c921be7d 23526 return TRUE;
a8bc6c78 23527 }
c921be7d 23528
a8bc6c78 23529 /* Process as normal. */
c921be7d 23530 return FALSE;
a8bc6c78
PB
23531}
23532
4a42ebbc
RR
23533/* Encode Thumb2 unconditional branches and calls. The encoding
23534 for the 2 are identical for the immediate values. */
23535
23536static void
23537encode_thumb2_b_bl_offset (char * buf, offsetT value)
23538{
23539#define T2I1I2MASK ((1 << 13) | (1 << 11))
23540 offsetT newval;
23541 offsetT newval2;
23542 addressT S, I1, I2, lo, hi;
23543
23544 S = (value >> 24) & 0x01;
23545 I1 = (value >> 23) & 0x01;
23546 I2 = (value >> 22) & 0x01;
23547 hi = (value >> 12) & 0x3ff;
fa94de6b 23548 lo = (value >> 1) & 0x7ff;
4a42ebbc
RR
23549 newval = md_chars_to_number (buf, THUMB_SIZE);
23550 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
23551 newval |= (S << 10) | hi;
23552 newval2 &= ~T2I1I2MASK;
23553 newval2 |= (((I1 ^ S) << 13) | ((I2 ^ S) << 11) | lo) ^ T2I1I2MASK;
23554 md_number_to_chars (buf, newval, THUMB_SIZE);
23555 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
23556}
23557
c19d1205 23558void
55cf6793 23559md_apply_fix (fixS * fixP,
c19d1205
ZW
23560 valueT * valP,
23561 segT seg)
23562{
23563 offsetT value = * valP;
23564 offsetT newval;
23565 unsigned int newimm;
23566 unsigned long temp;
23567 int sign;
23568 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
b99bd4ef 23569
9c2799c2 23570 gas_assert (fixP->fx_r_type <= BFD_RELOC_UNUSED);
b99bd4ef 23571
c19d1205 23572 /* Note whether this will delete the relocation. */
4962c51a 23573
c19d1205
ZW
23574 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
23575 fixP->fx_done = 1;
b99bd4ef 23576
adbaf948 23577 /* On a 64-bit host, silently truncate 'value' to 32 bits for
5f4273c7 23578 consistency with the behaviour on 32-bit hosts. Remember value
adbaf948
ZW
23579 for emit_reloc. */
23580 value &= 0xffffffff;
23581 value ^= 0x80000000;
5f4273c7 23582 value -= 0x80000000;
adbaf948
ZW
23583
23584 *valP = value;
c19d1205 23585 fixP->fx_addnumber = value;
b99bd4ef 23586
adbaf948
ZW
23587 /* Same treatment for fixP->fx_offset. */
23588 fixP->fx_offset &= 0xffffffff;
23589 fixP->fx_offset ^= 0x80000000;
23590 fixP->fx_offset -= 0x80000000;
23591
c19d1205 23592 switch (fixP->fx_r_type)
b99bd4ef 23593 {
c19d1205
ZW
23594 case BFD_RELOC_NONE:
23595 /* This will need to go in the object file. */
23596 fixP->fx_done = 0;
23597 break;
b99bd4ef 23598
c19d1205
ZW
23599 case BFD_RELOC_ARM_IMMEDIATE:
23600 /* We claim that this fixup has been processed here,
23601 even if in fact we generate an error because we do
23602 not have a reloc for it, so tc_gen_reloc will reject it. */
23603 fixP->fx_done = 1;
b99bd4ef 23604
77db8e2e 23605 if (fixP->fx_addsy)
b99bd4ef 23606 {
77db8e2e 23607 const char *msg = 0;
b99bd4ef 23608
77db8e2e
NC
23609 if (! S_IS_DEFINED (fixP->fx_addsy))
23610 msg = _("undefined symbol %s used as an immediate value");
23611 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
23612 msg = _("symbol %s is in a different section");
23613 else if (S_IS_WEAK (fixP->fx_addsy))
23614 msg = _("symbol %s is weak and may be overridden later");
23615
23616 if (msg)
23617 {
23618 as_bad_where (fixP->fx_file, fixP->fx_line,
23619 msg, S_GET_NAME (fixP->fx_addsy));
23620 break;
23621 }
42e5fcbf
AS
23622 }
23623
c19d1205
ZW
23624 temp = md_chars_to_number (buf, INSN_SIZE);
23625
5e73442d
SL
23626 /* If the offset is negative, we should use encoding A2 for ADR. */
23627 if ((temp & 0xfff0000) == 0x28f0000 && value < 0)
23628 newimm = negate_data_op (&temp, value);
23629 else
23630 {
23631 newimm = encode_arm_immediate (value);
23632
23633 /* If the instruction will fail, see if we can fix things up by
23634 changing the opcode. */
23635 if (newimm == (unsigned int) FAIL)
23636 newimm = negate_data_op (&temp, value);
bada4342
JW
23637 /* MOV accepts both ARM modified immediate (A1 encoding) and
23638 UINT16 (A2 encoding) when possible, MOVW only accepts UINT16.
23639 When disassembling, MOV is preferred when there is no encoding
23640 overlap. */
23641 if (newimm == (unsigned int) FAIL
23642 && ((temp >> DATA_OP_SHIFT) & 0xf) == OPCODE_MOV
23643 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
23644 && !((temp >> SBIT_SHIFT) & 0x1)
23645 && value >= 0 && value <= 0xffff)
23646 {
23647 /* Clear bits[23:20] to change encoding from A1 to A2. */
23648 temp &= 0xff0fffff;
23649 /* Encoding high 4bits imm. Code below will encode the remaining
23650 low 12bits. */
23651 temp |= (value & 0x0000f000) << 4;
23652 newimm = value & 0x00000fff;
23653 }
5e73442d
SL
23654 }
23655
23656 if (newimm == (unsigned int) FAIL)
b99bd4ef 23657 {
c19d1205
ZW
23658 as_bad_where (fixP->fx_file, fixP->fx_line,
23659 _("invalid constant (%lx) after fixup"),
23660 (unsigned long) value);
23661 break;
b99bd4ef 23662 }
b99bd4ef 23663
c19d1205
ZW
23664 newimm |= (temp & 0xfffff000);
23665 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
23666 break;
b99bd4ef 23667
c19d1205
ZW
23668 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
23669 {
23670 unsigned int highpart = 0;
23671 unsigned int newinsn = 0xe1a00000; /* nop. */
b99bd4ef 23672
77db8e2e 23673 if (fixP->fx_addsy)
42e5fcbf 23674 {
77db8e2e 23675 const char *msg = 0;
42e5fcbf 23676
77db8e2e
NC
23677 if (! S_IS_DEFINED (fixP->fx_addsy))
23678 msg = _("undefined symbol %s used as an immediate value");
23679 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
23680 msg = _("symbol %s is in a different section");
23681 else if (S_IS_WEAK (fixP->fx_addsy))
23682 msg = _("symbol %s is weak and may be overridden later");
42e5fcbf 23683
77db8e2e
NC
23684 if (msg)
23685 {
23686 as_bad_where (fixP->fx_file, fixP->fx_line,
23687 msg, S_GET_NAME (fixP->fx_addsy));
23688 break;
23689 }
23690 }
fa94de6b 23691
c19d1205
ZW
23692 newimm = encode_arm_immediate (value);
23693 temp = md_chars_to_number (buf, INSN_SIZE);
b99bd4ef 23694
c19d1205
ZW
23695 /* If the instruction will fail, see if we can fix things up by
23696 changing the opcode. */
23697 if (newimm == (unsigned int) FAIL
23698 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
23699 {
23700 /* No ? OK - try using two ADD instructions to generate
23701 the value. */
23702 newimm = validate_immediate_twopart (value, & highpart);
b99bd4ef 23703
c19d1205
ZW
23704 /* Yes - then make sure that the second instruction is
23705 also an add. */
23706 if (newimm != (unsigned int) FAIL)
23707 newinsn = temp;
23708 /* Still No ? Try using a negated value. */
23709 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
23710 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
23711 /* Otherwise - give up. */
23712 else
23713 {
23714 as_bad_where (fixP->fx_file, fixP->fx_line,
23715 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
23716 (long) value);
23717 break;
23718 }
b99bd4ef 23719
c19d1205
ZW
23720 /* Replace the first operand in the 2nd instruction (which
23721 is the PC) with the destination register. We have
23722 already added in the PC in the first instruction and we
23723 do not want to do it again. */
23724 newinsn &= ~ 0xf0000;
23725 newinsn |= ((newinsn & 0x0f000) << 4);
23726 }
b99bd4ef 23727
c19d1205
ZW
23728 newimm |= (temp & 0xfffff000);
23729 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
b99bd4ef 23730
c19d1205
ZW
23731 highpart |= (newinsn & 0xfffff000);
23732 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
23733 }
23734 break;
b99bd4ef 23735
c19d1205 23736 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
23737 if (!fixP->fx_done && seg->use_rela_p)
23738 value = 0;
1a0670f3 23739 /* Fall through. */
00a97672 23740
c19d1205 23741 case BFD_RELOC_ARM_LITERAL:
26d97720 23742 sign = value > 0;
b99bd4ef 23743
c19d1205
ZW
23744 if (value < 0)
23745 value = - value;
b99bd4ef 23746
c19d1205 23747 if (validate_offset_imm (value, 0) == FAIL)
f03698e6 23748 {
c19d1205
ZW
23749 if (fixP->fx_r_type == BFD_RELOC_ARM_LITERAL)
23750 as_bad_where (fixP->fx_file, fixP->fx_line,
23751 _("invalid literal constant: pool needs to be closer"));
23752 else
23753 as_bad_where (fixP->fx_file, fixP->fx_line,
23754 _("bad immediate value for offset (%ld)"),
23755 (long) value);
23756 break;
f03698e6
RE
23757 }
23758
c19d1205 23759 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
23760 if (value == 0)
23761 newval &= 0xfffff000;
23762 else
23763 {
23764 newval &= 0xff7ff000;
23765 newval |= value | (sign ? INDEX_UP : 0);
23766 }
c19d1205
ZW
23767 md_number_to_chars (buf, newval, INSN_SIZE);
23768 break;
b99bd4ef 23769
c19d1205
ZW
23770 case BFD_RELOC_ARM_OFFSET_IMM8:
23771 case BFD_RELOC_ARM_HWLITERAL:
26d97720 23772 sign = value > 0;
b99bd4ef 23773
c19d1205
ZW
23774 if (value < 0)
23775 value = - value;
b99bd4ef 23776
c19d1205 23777 if (validate_offset_imm (value, 1) == FAIL)
b99bd4ef 23778 {
c19d1205
ZW
23779 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
23780 as_bad_where (fixP->fx_file, fixP->fx_line,
23781 _("invalid literal constant: pool needs to be closer"));
23782 else
427d0db6
RM
23783 as_bad_where (fixP->fx_file, fixP->fx_line,
23784 _("bad immediate value for 8-bit offset (%ld)"),
23785 (long) value);
c19d1205 23786 break;
b99bd4ef
NC
23787 }
23788
c19d1205 23789 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
23790 if (value == 0)
23791 newval &= 0xfffff0f0;
23792 else
23793 {
23794 newval &= 0xff7ff0f0;
23795 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
23796 }
c19d1205
ZW
23797 md_number_to_chars (buf, newval, INSN_SIZE);
23798 break;
b99bd4ef 23799
c19d1205
ZW
23800 case BFD_RELOC_ARM_T32_OFFSET_U8:
23801 if (value < 0 || value > 1020 || value % 4 != 0)
23802 as_bad_where (fixP->fx_file, fixP->fx_line,
23803 _("bad immediate value for offset (%ld)"), (long) value);
23804 value /= 4;
b99bd4ef 23805
c19d1205 23806 newval = md_chars_to_number (buf+2, THUMB_SIZE);
c19d1205
ZW
23807 newval |= value;
23808 md_number_to_chars (buf+2, newval, THUMB_SIZE);
23809 break;
b99bd4ef 23810
c19d1205
ZW
23811 case BFD_RELOC_ARM_T32_OFFSET_IMM:
23812 /* This is a complicated relocation used for all varieties of Thumb32
23813 load/store instruction with immediate offset:
23814
23815 1110 100P u1WL NNNN XXXX YYYY iiii iiii - +/-(U) pre/post(P) 8-bit,
477330fc 23816 *4, optional writeback(W)
c19d1205
ZW
23817 (doubleword load/store)
23818
23819 1111 100S uTTL 1111 XXXX iiii iiii iiii - +/-(U) 12-bit PC-rel
23820 1111 100S 0TTL NNNN XXXX 1Pu1 iiii iiii - +/-(U) pre/post(P) 8-bit
23821 1111 100S 0TTL NNNN XXXX 1110 iiii iiii - positive 8-bit (T instruction)
23822 1111 100S 1TTL NNNN XXXX iiii iiii iiii - positive 12-bit
23823 1111 100S 0TTL NNNN XXXX 1100 iiii iiii - negative 8-bit
23824
23825 Uppercase letters indicate bits that are already encoded at
23826 this point. Lowercase letters are our problem. For the
23827 second block of instructions, the secondary opcode nybble
23828 (bits 8..11) is present, and bit 23 is zero, even if this is
23829 a PC-relative operation. */
23830 newval = md_chars_to_number (buf, THUMB_SIZE);
23831 newval <<= 16;
23832 newval |= md_chars_to_number (buf+THUMB_SIZE, THUMB_SIZE);
b99bd4ef 23833
c19d1205 23834 if ((newval & 0xf0000000) == 0xe0000000)
b99bd4ef 23835 {
c19d1205
ZW
23836 /* Doubleword load/store: 8-bit offset, scaled by 4. */
23837 if (value >= 0)
23838 newval |= (1 << 23);
23839 else
23840 value = -value;
23841 if (value % 4 != 0)
23842 {
23843 as_bad_where (fixP->fx_file, fixP->fx_line,
23844 _("offset not a multiple of 4"));
23845 break;
23846 }
23847 value /= 4;
216d22bc 23848 if (value > 0xff)
c19d1205
ZW
23849 {
23850 as_bad_where (fixP->fx_file, fixP->fx_line,
23851 _("offset out of range"));
23852 break;
23853 }
23854 newval &= ~0xff;
b99bd4ef 23855 }
c19d1205 23856 else if ((newval & 0x000f0000) == 0x000f0000)
b99bd4ef 23857 {
c19d1205
ZW
23858 /* PC-relative, 12-bit offset. */
23859 if (value >= 0)
23860 newval |= (1 << 23);
23861 else
23862 value = -value;
216d22bc 23863 if (value > 0xfff)
c19d1205
ZW
23864 {
23865 as_bad_where (fixP->fx_file, fixP->fx_line,
23866 _("offset out of range"));
23867 break;
23868 }
23869 newval &= ~0xfff;
b99bd4ef 23870 }
c19d1205 23871 else if ((newval & 0x00000100) == 0x00000100)
b99bd4ef 23872 {
c19d1205
ZW
23873 /* Writeback: 8-bit, +/- offset. */
23874 if (value >= 0)
23875 newval |= (1 << 9);
23876 else
23877 value = -value;
216d22bc 23878 if (value > 0xff)
c19d1205
ZW
23879 {
23880 as_bad_where (fixP->fx_file, fixP->fx_line,
23881 _("offset out of range"));
23882 break;
23883 }
23884 newval &= ~0xff;
b99bd4ef 23885 }
c19d1205 23886 else if ((newval & 0x00000f00) == 0x00000e00)
b99bd4ef 23887 {
c19d1205 23888 /* T-instruction: positive 8-bit offset. */
216d22bc 23889 if (value < 0 || value > 0xff)
b99bd4ef 23890 {
c19d1205
ZW
23891 as_bad_where (fixP->fx_file, fixP->fx_line,
23892 _("offset out of range"));
23893 break;
b99bd4ef 23894 }
c19d1205
ZW
23895 newval &= ~0xff;
23896 newval |= value;
b99bd4ef
NC
23897 }
23898 else
b99bd4ef 23899 {
c19d1205
ZW
23900 /* Positive 12-bit or negative 8-bit offset. */
23901 int limit;
23902 if (value >= 0)
b99bd4ef 23903 {
c19d1205
ZW
23904 newval |= (1 << 23);
23905 limit = 0xfff;
23906 }
23907 else
23908 {
23909 value = -value;
23910 limit = 0xff;
23911 }
23912 if (value > limit)
23913 {
23914 as_bad_where (fixP->fx_file, fixP->fx_line,
23915 _("offset out of range"));
23916 break;
b99bd4ef 23917 }
c19d1205 23918 newval &= ~limit;
b99bd4ef 23919 }
b99bd4ef 23920
c19d1205
ZW
23921 newval |= value;
23922 md_number_to_chars (buf, (newval >> 16) & 0xffff, THUMB_SIZE);
23923 md_number_to_chars (buf + THUMB_SIZE, newval & 0xffff, THUMB_SIZE);
23924 break;
404ff6b5 23925
c19d1205
ZW
23926 case BFD_RELOC_ARM_SHIFT_IMM:
23927 newval = md_chars_to_number (buf, INSN_SIZE);
23928 if (((unsigned long) value) > 32
23929 || (value == 32
23930 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
23931 {
23932 as_bad_where (fixP->fx_file, fixP->fx_line,
23933 _("shift expression is too large"));
23934 break;
23935 }
404ff6b5 23936
c19d1205
ZW
23937 if (value == 0)
23938 /* Shifts of zero must be done as lsl. */
23939 newval &= ~0x60;
23940 else if (value == 32)
23941 value = 0;
23942 newval &= 0xfffff07f;
23943 newval |= (value & 0x1f) << 7;
23944 md_number_to_chars (buf, newval, INSN_SIZE);
23945 break;
404ff6b5 23946
c19d1205 23947 case BFD_RELOC_ARM_T32_IMMEDIATE:
16805f35 23948 case BFD_RELOC_ARM_T32_ADD_IMM:
92e90b6e 23949 case BFD_RELOC_ARM_T32_IMM12:
e9f89963 23950 case BFD_RELOC_ARM_T32_ADD_PC12:
c19d1205
ZW
23951 /* We claim that this fixup has been processed here,
23952 even if in fact we generate an error because we do
23953 not have a reloc for it, so tc_gen_reloc will reject it. */
23954 fixP->fx_done = 1;
404ff6b5 23955
c19d1205
ZW
23956 if (fixP->fx_addsy
23957 && ! S_IS_DEFINED (fixP->fx_addsy))
23958 {
23959 as_bad_where (fixP->fx_file, fixP->fx_line,
23960 _("undefined symbol %s used as an immediate value"),
23961 S_GET_NAME (fixP->fx_addsy));
23962 break;
23963 }
404ff6b5 23964
c19d1205
ZW
23965 newval = md_chars_to_number (buf, THUMB_SIZE);
23966 newval <<= 16;
23967 newval |= md_chars_to_number (buf+2, THUMB_SIZE);
404ff6b5 23968
16805f35 23969 newimm = FAIL;
bada4342
JW
23970 if ((fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
23971 /* ARMv8-M Baseline MOV will reach here, but it doesn't support
23972 Thumb2 modified immediate encoding (T2). */
23973 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
16805f35 23974 || fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
ef8d22e6
PB
23975 {
23976 newimm = encode_thumb32_immediate (value);
23977 if (newimm == (unsigned int) FAIL)
23978 newimm = thumb32_negate_data_op (&newval, value);
23979 }
bada4342 23980 if (newimm == (unsigned int) FAIL)
92e90b6e 23981 {
bada4342 23982 if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE)
e9f89963 23983 {
bada4342
JW
23984 /* Turn add/sum into addw/subw. */
23985 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
23986 newval = (newval & 0xfeffffff) | 0x02000000;
23987 /* No flat 12-bit imm encoding for addsw/subsw. */
23988 if ((newval & 0x00100000) == 0)
40f246e3 23989 {
bada4342
JW
23990 /* 12 bit immediate for addw/subw. */
23991 if (value < 0)
23992 {
23993 value = -value;
23994 newval ^= 0x00a00000;
23995 }
23996 if (value > 0xfff)
23997 newimm = (unsigned int) FAIL;
23998 else
23999 newimm = value;
24000 }
24001 }
24002 else
24003 {
24004 /* MOV accepts both Thumb2 modified immediate (T2 encoding) and
24005 UINT16 (T3 encoding), MOVW only accepts UINT16. When
24006 disassembling, MOV is preferred when there is no encoding
db7bf105 24007 overlap. */
bada4342 24008 if (((newval >> T2_DATA_OP_SHIFT) & 0xf) == T2_OPCODE_ORR
db7bf105
NC
24009 /* NOTE: MOV uses the ORR opcode in Thumb 2 mode
24010 but with the Rn field [19:16] set to 1111. */
24011 && (((newval >> 16) & 0xf) == 0xf)
bada4342
JW
24012 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m)
24013 && !((newval >> T2_SBIT_SHIFT) & 0x1)
db7bf105 24014 && value >= 0 && value <= 0xffff)
bada4342
JW
24015 {
24016 /* Toggle bit[25] to change encoding from T2 to T3. */
24017 newval ^= 1 << 25;
24018 /* Clear bits[19:16]. */
24019 newval &= 0xfff0ffff;
24020 /* Encoding high 4bits imm. Code below will encode the
24021 remaining low 12bits. */
24022 newval |= (value & 0x0000f000) << 4;
24023 newimm = value & 0x00000fff;
40f246e3 24024 }
e9f89963 24025 }
92e90b6e 24026 }
cc8a6dd0 24027
c19d1205 24028 if (newimm == (unsigned int)FAIL)
3631a3c8 24029 {
c19d1205
ZW
24030 as_bad_where (fixP->fx_file, fixP->fx_line,
24031 _("invalid constant (%lx) after fixup"),
24032 (unsigned long) value);
24033 break;
3631a3c8
NC
24034 }
24035
c19d1205
ZW
24036 newval |= (newimm & 0x800) << 15;
24037 newval |= (newimm & 0x700) << 4;
24038 newval |= (newimm & 0x0ff);
cc8a6dd0 24039
c19d1205
ZW
24040 md_number_to_chars (buf, (valueT) ((newval >> 16) & 0xffff), THUMB_SIZE);
24041 md_number_to_chars (buf+2, (valueT) (newval & 0xffff), THUMB_SIZE);
24042 break;
a737bd4d 24043
3eb17e6b 24044 case BFD_RELOC_ARM_SMC:
c19d1205
ZW
24045 if (((unsigned long) value) > 0xffff)
24046 as_bad_where (fixP->fx_file, fixP->fx_line,
3eb17e6b 24047 _("invalid smc expression"));
2fc8bdac 24048 newval = md_chars_to_number (buf, INSN_SIZE);
c19d1205
ZW
24049 newval |= (value & 0xf) | ((value & 0xfff0) << 4);
24050 md_number_to_chars (buf, newval, INSN_SIZE);
24051 break;
a737bd4d 24052
90ec0d68
MGD
24053 case BFD_RELOC_ARM_HVC:
24054 if (((unsigned long) value) > 0xffff)
24055 as_bad_where (fixP->fx_file, fixP->fx_line,
24056 _("invalid hvc expression"));
24057 newval = md_chars_to_number (buf, INSN_SIZE);
24058 newval |= (value & 0xf) | ((value & 0xfff0) << 4);
24059 md_number_to_chars (buf, newval, INSN_SIZE);
24060 break;
24061
c19d1205 24062 case BFD_RELOC_ARM_SWI:
adbaf948 24063 if (fixP->tc_fix_data != 0)
c19d1205
ZW
24064 {
24065 if (((unsigned long) value) > 0xff)
24066 as_bad_where (fixP->fx_file, fixP->fx_line,
24067 _("invalid swi expression"));
2fc8bdac 24068 newval = md_chars_to_number (buf, THUMB_SIZE);
c19d1205
ZW
24069 newval |= value;
24070 md_number_to_chars (buf, newval, THUMB_SIZE);
24071 }
24072 else
24073 {
24074 if (((unsigned long) value) > 0x00ffffff)
24075 as_bad_where (fixP->fx_file, fixP->fx_line,
24076 _("invalid swi expression"));
2fc8bdac 24077 newval = md_chars_to_number (buf, INSN_SIZE);
c19d1205
ZW
24078 newval |= value;
24079 md_number_to_chars (buf, newval, INSN_SIZE);
24080 }
24081 break;
a737bd4d 24082
c19d1205
ZW
24083 case BFD_RELOC_ARM_MULTI:
24084 if (((unsigned long) value) > 0xffff)
24085 as_bad_where (fixP->fx_file, fixP->fx_line,
24086 _("invalid expression in load/store multiple"));
24087 newval = value | md_chars_to_number (buf, INSN_SIZE);
24088 md_number_to_chars (buf, newval, INSN_SIZE);
24089 break;
a737bd4d 24090
c19d1205 24091#ifdef OBJ_ELF
39b41c9c 24092 case BFD_RELOC_ARM_PCREL_CALL:
267bf995
RR
24093
24094 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
24095 && fixP->fx_addsy
34e77a92 24096 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
24097 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
24098 && THUMB_IS_FUNC (fixP->fx_addsy))
24099 /* Flip the bl to blx. This is a simple flip
24100 bit here because we generate PCREL_CALL for
24101 unconditional bls. */
24102 {
24103 newval = md_chars_to_number (buf, INSN_SIZE);
24104 newval = newval | 0x10000000;
24105 md_number_to_chars (buf, newval, INSN_SIZE);
24106 temp = 1;
24107 fixP->fx_done = 1;
24108 }
39b41c9c
PB
24109 else
24110 temp = 3;
24111 goto arm_branch_common;
24112
24113 case BFD_RELOC_ARM_PCREL_JUMP:
267bf995
RR
24114 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
24115 && fixP->fx_addsy
34e77a92 24116 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
24117 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
24118 && THUMB_IS_FUNC (fixP->fx_addsy))
24119 {
24120 /* This would map to a bl<cond>, b<cond>,
24121 b<always> to a Thumb function. We
24122 need to force a relocation for this particular
24123 case. */
24124 newval = md_chars_to_number (buf, INSN_SIZE);
24125 fixP->fx_done = 0;
24126 }
1a0670f3 24127 /* Fall through. */
267bf995 24128
2fc8bdac 24129 case BFD_RELOC_ARM_PLT32:
c19d1205 24130#endif
39b41c9c
PB
24131 case BFD_RELOC_ARM_PCREL_BRANCH:
24132 temp = 3;
24133 goto arm_branch_common;
a737bd4d 24134
39b41c9c 24135 case BFD_RELOC_ARM_PCREL_BLX:
267bf995 24136
39b41c9c 24137 temp = 1;
267bf995
RR
24138 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
24139 && fixP->fx_addsy
34e77a92 24140 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
24141 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
24142 && ARM_IS_FUNC (fixP->fx_addsy))
24143 {
24144 /* Flip the blx to a bl and warn. */
24145 const char *name = S_GET_NAME (fixP->fx_addsy);
24146 newval = 0xeb000000;
24147 as_warn_where (fixP->fx_file, fixP->fx_line,
24148 _("blx to '%s' an ARM ISA state function changed to bl"),
24149 name);
24150 md_number_to_chars (buf, newval, INSN_SIZE);
24151 temp = 3;
24152 fixP->fx_done = 1;
24153 }
24154
24155#ifdef OBJ_ELF
24156 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
477330fc 24157 fixP->fx_r_type = BFD_RELOC_ARM_PCREL_CALL;
267bf995
RR
24158#endif
24159
39b41c9c 24160 arm_branch_common:
c19d1205 24161 /* We are going to store value (shifted right by two) in the
39b41c9c
PB
24162 instruction, in a 24 bit, signed field. Bits 26 through 32 either
24163 all clear or all set and bit 0 must be clear. For B/BL bit 1 must
de194d85 24164 also be clear. */
39b41c9c 24165 if (value & temp)
c19d1205 24166 as_bad_where (fixP->fx_file, fixP->fx_line,
2fc8bdac
ZW
24167 _("misaligned branch destination"));
24168 if ((value & (offsetT)0xfe000000) != (offsetT)0
24169 && (value & (offsetT)0xfe000000) != (offsetT)0xfe000000)
08f10d51 24170 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 24171
2fc8bdac 24172 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 24173 {
2fc8bdac
ZW
24174 newval = md_chars_to_number (buf, INSN_SIZE);
24175 newval |= (value >> 2) & 0x00ffffff;
7ae2971b
PB
24176 /* Set the H bit on BLX instructions. */
24177 if (temp == 1)
24178 {
24179 if (value & 2)
24180 newval |= 0x01000000;
24181 else
24182 newval &= ~0x01000000;
24183 }
2fc8bdac 24184 md_number_to_chars (buf, newval, INSN_SIZE);
c19d1205 24185 }
c19d1205 24186 break;
a737bd4d 24187
25fe350b
MS
24188 case BFD_RELOC_THUMB_PCREL_BRANCH7: /* CBZ */
24189 /* CBZ can only branch forward. */
a737bd4d 24190
738755b0 24191 /* Attempts to use CBZ to branch to the next instruction
477330fc
RM
24192 (which, strictly speaking, are prohibited) will be turned into
24193 no-ops.
738755b0
MS
24194
24195 FIXME: It may be better to remove the instruction completely and
24196 perform relaxation. */
24197 if (value == -2)
2fc8bdac
ZW
24198 {
24199 newval = md_chars_to_number (buf, THUMB_SIZE);
738755b0 24200 newval = 0xbf00; /* NOP encoding T1 */
2fc8bdac
ZW
24201 md_number_to_chars (buf, newval, THUMB_SIZE);
24202 }
738755b0
MS
24203 else
24204 {
24205 if (value & ~0x7e)
08f10d51 24206 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
738755b0 24207
477330fc 24208 if (fixP->fx_done || !seg->use_rela_p)
738755b0
MS
24209 {
24210 newval = md_chars_to_number (buf, THUMB_SIZE);
24211 newval |= ((value & 0x3e) << 2) | ((value & 0x40) << 3);
24212 md_number_to_chars (buf, newval, THUMB_SIZE);
24213 }
24214 }
c19d1205 24215 break;
a737bd4d 24216
c19d1205 24217 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
2fc8bdac 24218 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
08f10d51 24219 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 24220
2fc8bdac
ZW
24221 if (fixP->fx_done || !seg->use_rela_p)
24222 {
24223 newval = md_chars_to_number (buf, THUMB_SIZE);
24224 newval |= (value & 0x1ff) >> 1;
24225 md_number_to_chars (buf, newval, THUMB_SIZE);
24226 }
c19d1205 24227 break;
a737bd4d 24228
c19d1205 24229 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
2fc8bdac 24230 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
08f10d51 24231 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 24232
2fc8bdac
ZW
24233 if (fixP->fx_done || !seg->use_rela_p)
24234 {
24235 newval = md_chars_to_number (buf, THUMB_SIZE);
24236 newval |= (value & 0xfff) >> 1;
24237 md_number_to_chars (buf, newval, THUMB_SIZE);
24238 }
c19d1205 24239 break;
a737bd4d 24240
c19d1205 24241 case BFD_RELOC_THUMB_PCREL_BRANCH20:
267bf995
RR
24242 if (fixP->fx_addsy
24243 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 24244 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
24245 && ARM_IS_FUNC (fixP->fx_addsy)
24246 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
24247 {
24248 /* Force a relocation for a branch 20 bits wide. */
24249 fixP->fx_done = 0;
24250 }
08f10d51 24251 if ((value & ~0x1fffff) && ((value & ~0x0fffff) != ~0x0fffff))
2fc8bdac
ZW
24252 as_bad_where (fixP->fx_file, fixP->fx_line,
24253 _("conditional branch out of range"));
404ff6b5 24254
2fc8bdac
ZW
24255 if (fixP->fx_done || !seg->use_rela_p)
24256 {
24257 offsetT newval2;
24258 addressT S, J1, J2, lo, hi;
404ff6b5 24259
2fc8bdac
ZW
24260 S = (value & 0x00100000) >> 20;
24261 J2 = (value & 0x00080000) >> 19;
24262 J1 = (value & 0x00040000) >> 18;
24263 hi = (value & 0x0003f000) >> 12;
24264 lo = (value & 0x00000ffe) >> 1;
6c43fab6 24265
2fc8bdac
ZW
24266 newval = md_chars_to_number (buf, THUMB_SIZE);
24267 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
24268 newval |= (S << 10) | hi;
24269 newval2 |= (J1 << 13) | (J2 << 11) | lo;
24270 md_number_to_chars (buf, newval, THUMB_SIZE);
24271 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
24272 }
c19d1205 24273 break;
6c43fab6 24274
c19d1205 24275 case BFD_RELOC_THUMB_PCREL_BLX:
267bf995
RR
24276 /* If there is a blx from a thumb state function to
24277 another thumb function flip this to a bl and warn
24278 about it. */
24279
24280 if (fixP->fx_addsy
34e77a92 24281 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
24282 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
24283 && THUMB_IS_FUNC (fixP->fx_addsy))
24284 {
24285 const char *name = S_GET_NAME (fixP->fx_addsy);
24286 as_warn_where (fixP->fx_file, fixP->fx_line,
24287 _("blx to Thumb func '%s' from Thumb ISA state changed to bl"),
24288 name);
24289 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
24290 newval = newval | 0x1000;
24291 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
24292 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
24293 fixP->fx_done = 1;
24294 }
24295
24296
24297 goto thumb_bl_common;
24298
c19d1205 24299 case BFD_RELOC_THUMB_PCREL_BRANCH23:
267bf995
RR
24300 /* A bl from Thumb state ISA to an internal ARM state function
24301 is converted to a blx. */
24302 if (fixP->fx_addsy
24303 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 24304 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
24305 && ARM_IS_FUNC (fixP->fx_addsy)
24306 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
24307 {
24308 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
24309 newval = newval & ~0x1000;
24310 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
24311 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BLX;
24312 fixP->fx_done = 1;
24313 }
24314
24315 thumb_bl_common:
24316
2fc8bdac
ZW
24317 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
24318 /* For a BLX instruction, make sure that the relocation is rounded up
24319 to a word boundary. This follows the semantics of the instruction
24320 which specifies that bit 1 of the target address will come from bit
24321 1 of the base address. */
d406f3e4
JB
24322 value = (value + 3) & ~ 3;
24323
24324#ifdef OBJ_ELF
24325 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4
24326 && fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
24327 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
24328#endif
404ff6b5 24329
2b2f5df9
NC
24330 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
24331 {
fc289b0a 24332 if (!(ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)))
2b2f5df9
NC
24333 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
24334 else if ((value & ~0x1ffffff)
24335 && ((value & ~0x1ffffff) != ~0x1ffffff))
24336 as_bad_where (fixP->fx_file, fixP->fx_line,
24337 _("Thumb2 branch out of range"));
24338 }
4a42ebbc
RR
24339
24340 if (fixP->fx_done || !seg->use_rela_p)
24341 encode_thumb2_b_bl_offset (buf, value);
24342
c19d1205 24343 break;
404ff6b5 24344
c19d1205 24345 case BFD_RELOC_THUMB_PCREL_BRANCH25:
08f10d51
NC
24346 if ((value & ~0x0ffffff) && ((value & ~0x0ffffff) != ~0x0ffffff))
24347 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
6c43fab6 24348
2fc8bdac 24349 if (fixP->fx_done || !seg->use_rela_p)
4a42ebbc 24350 encode_thumb2_b_bl_offset (buf, value);
6c43fab6 24351
2fc8bdac 24352 break;
a737bd4d 24353
2fc8bdac
ZW
24354 case BFD_RELOC_8:
24355 if (fixP->fx_done || !seg->use_rela_p)
4b1a927e 24356 *buf = value;
c19d1205 24357 break;
a737bd4d 24358
c19d1205 24359 case BFD_RELOC_16:
2fc8bdac 24360 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 24361 md_number_to_chars (buf, value, 2);
c19d1205 24362 break;
a737bd4d 24363
c19d1205 24364#ifdef OBJ_ELF
0855e32b
NS
24365 case BFD_RELOC_ARM_TLS_CALL:
24366 case BFD_RELOC_ARM_THM_TLS_CALL:
24367 case BFD_RELOC_ARM_TLS_DESCSEQ:
24368 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
0855e32b 24369 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205
ZW
24370 case BFD_RELOC_ARM_TLS_GD32:
24371 case BFD_RELOC_ARM_TLS_LE32:
24372 case BFD_RELOC_ARM_TLS_IE32:
24373 case BFD_RELOC_ARM_TLS_LDM32:
24374 case BFD_RELOC_ARM_TLS_LDO32:
24375 S_SET_THREAD_LOCAL (fixP->fx_addsy);
4b1a927e 24376 break;
6c43fab6 24377
5c5a4843
CL
24378 /* Same handling as above, but with the arm_fdpic guard. */
24379 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
24380 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
24381 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
24382 if (arm_fdpic)
24383 {
24384 S_SET_THREAD_LOCAL (fixP->fx_addsy);
24385 }
24386 else
24387 {
24388 as_bad_where (fixP->fx_file, fixP->fx_line,
24389 _("Relocation supported only in FDPIC mode"));
24390 }
24391 break;
24392
c19d1205
ZW
24393 case BFD_RELOC_ARM_GOT32:
24394 case BFD_RELOC_ARM_GOTOFF:
c19d1205 24395 break;
b43420e6
NC
24396
24397 case BFD_RELOC_ARM_GOT_PREL:
24398 if (fixP->fx_done || !seg->use_rela_p)
477330fc 24399 md_number_to_chars (buf, value, 4);
b43420e6
NC
24400 break;
24401
9a6f4e97
NS
24402 case BFD_RELOC_ARM_TARGET2:
24403 /* TARGET2 is not partial-inplace, so we need to write the
477330fc
RM
24404 addend here for REL targets, because it won't be written out
24405 during reloc processing later. */
9a6f4e97
NS
24406 if (fixP->fx_done || !seg->use_rela_p)
24407 md_number_to_chars (buf, fixP->fx_offset, 4);
24408 break;
188fd7ae
CL
24409
24410 /* Relocations for FDPIC. */
24411 case BFD_RELOC_ARM_GOTFUNCDESC:
24412 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
24413 case BFD_RELOC_ARM_FUNCDESC:
24414 if (arm_fdpic)
24415 {
24416 if (fixP->fx_done || !seg->use_rela_p)
24417 md_number_to_chars (buf, 0, 4);
24418 }
24419 else
24420 {
24421 as_bad_where (fixP->fx_file, fixP->fx_line,
24422 _("Relocation supported only in FDPIC mode"));
24423 }
24424 break;
c19d1205 24425#endif
6c43fab6 24426
c19d1205
ZW
24427 case BFD_RELOC_RVA:
24428 case BFD_RELOC_32:
24429 case BFD_RELOC_ARM_TARGET1:
24430 case BFD_RELOC_ARM_ROSEGREL32:
24431 case BFD_RELOC_ARM_SBREL32:
24432 case BFD_RELOC_32_PCREL:
f0927246
NC
24433#ifdef TE_PE
24434 case BFD_RELOC_32_SECREL:
24435#endif
2fc8bdac 24436 if (fixP->fx_done || !seg->use_rela_p)
53baae48
NC
24437#ifdef TE_WINCE
24438 /* For WinCE we only do this for pcrel fixups. */
24439 if (fixP->fx_done || fixP->fx_pcrel)
24440#endif
24441 md_number_to_chars (buf, value, 4);
c19d1205 24442 break;
6c43fab6 24443
c19d1205
ZW
24444#ifdef OBJ_ELF
24445 case BFD_RELOC_ARM_PREL31:
2fc8bdac 24446 if (fixP->fx_done || !seg->use_rela_p)
c19d1205
ZW
24447 {
24448 newval = md_chars_to_number (buf, 4) & 0x80000000;
24449 if ((value ^ (value >> 1)) & 0x40000000)
24450 {
24451 as_bad_where (fixP->fx_file, fixP->fx_line,
24452 _("rel31 relocation overflow"));
24453 }
24454 newval |= value & 0x7fffffff;
24455 md_number_to_chars (buf, newval, 4);
24456 }
24457 break;
c19d1205 24458#endif
a737bd4d 24459
c19d1205 24460 case BFD_RELOC_ARM_CP_OFF_IMM:
8f06b2d8 24461 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
9db2f6b4
RL
24462 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM)
24463 newval = md_chars_to_number (buf, INSN_SIZE);
24464 else
24465 newval = get_thumb32_insn (buf);
24466 if ((newval & 0x0f200f00) == 0x0d000900)
24467 {
24468 /* This is a fp16 vstr/vldr. The immediate offset in the mnemonic
24469 has permitted values that are multiples of 2, in the range 0
24470 to 510. */
24471 if (value < -510 || value > 510 || (value & 1))
24472 as_bad_where (fixP->fx_file, fixP->fx_line,
24473 _("co-processor offset out of range"));
24474 }
24475 else if (value < -1023 || value > 1023 || (value & 3))
c19d1205
ZW
24476 as_bad_where (fixP->fx_file, fixP->fx_line,
24477 _("co-processor offset out of range"));
24478 cp_off_common:
26d97720 24479 sign = value > 0;
c19d1205
ZW
24480 if (value < 0)
24481 value = -value;
8f06b2d8
PB
24482 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
24483 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
24484 newval = md_chars_to_number (buf, INSN_SIZE);
24485 else
24486 newval = get_thumb32_insn (buf);
26d97720
NS
24487 if (value == 0)
24488 newval &= 0xffffff00;
24489 else
24490 {
24491 newval &= 0xff7fff00;
9db2f6b4
RL
24492 if ((newval & 0x0f200f00) == 0x0d000900)
24493 {
24494 /* This is a fp16 vstr/vldr.
24495
24496 It requires the immediate offset in the instruction is shifted
24497 left by 1 to be a half-word offset.
24498
24499 Here, left shift by 1 first, and later right shift by 2
24500 should get the right offset. */
24501 value <<= 1;
24502 }
26d97720
NS
24503 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
24504 }
8f06b2d8
PB
24505 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
24506 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
24507 md_number_to_chars (buf, newval, INSN_SIZE);
24508 else
24509 put_thumb32_insn (buf, newval);
c19d1205 24510 break;
a737bd4d 24511
c19d1205 24512 case BFD_RELOC_ARM_CP_OFF_IMM_S2:
8f06b2d8 24513 case BFD_RELOC_ARM_T32_CP_OFF_IMM_S2:
c19d1205
ZW
24514 if (value < -255 || value > 255)
24515 as_bad_where (fixP->fx_file, fixP->fx_line,
24516 _("co-processor offset out of range"));
df7849c5 24517 value *= 4;
c19d1205 24518 goto cp_off_common;
6c43fab6 24519
c19d1205
ZW
24520 case BFD_RELOC_ARM_THUMB_OFFSET:
24521 newval = md_chars_to_number (buf, THUMB_SIZE);
24522 /* Exactly what ranges, and where the offset is inserted depends
24523 on the type of instruction, we can establish this from the
24524 top 4 bits. */
24525 switch (newval >> 12)
24526 {
24527 case 4: /* PC load. */
24528 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
24529 forced to zero for these loads; md_pcrel_from has already
24530 compensated for this. */
24531 if (value & 3)
24532 as_bad_where (fixP->fx_file, fixP->fx_line,
24533 _("invalid offset, target not word aligned (0x%08lX)"),
0359e808
NC
24534 (((unsigned long) fixP->fx_frag->fr_address
24535 + (unsigned long) fixP->fx_where) & ~3)
24536 + (unsigned long) value);
a737bd4d 24537
c19d1205
ZW
24538 if (value & ~0x3fc)
24539 as_bad_where (fixP->fx_file, fixP->fx_line,
24540 _("invalid offset, value too big (0x%08lX)"),
24541 (long) value);
a737bd4d 24542
c19d1205
ZW
24543 newval |= value >> 2;
24544 break;
a737bd4d 24545
c19d1205
ZW
24546 case 9: /* SP load/store. */
24547 if (value & ~0x3fc)
24548 as_bad_where (fixP->fx_file, fixP->fx_line,
24549 _("invalid offset, value too big (0x%08lX)"),
24550 (long) value);
24551 newval |= value >> 2;
24552 break;
6c43fab6 24553
c19d1205
ZW
24554 case 6: /* Word load/store. */
24555 if (value & ~0x7c)
24556 as_bad_where (fixP->fx_file, fixP->fx_line,
24557 _("invalid offset, value too big (0x%08lX)"),
24558 (long) value);
24559 newval |= value << 4; /* 6 - 2. */
24560 break;
a737bd4d 24561
c19d1205
ZW
24562 case 7: /* Byte load/store. */
24563 if (value & ~0x1f)
24564 as_bad_where (fixP->fx_file, fixP->fx_line,
24565 _("invalid offset, value too big (0x%08lX)"),
24566 (long) value);
24567 newval |= value << 6;
24568 break;
a737bd4d 24569
c19d1205
ZW
24570 case 8: /* Halfword load/store. */
24571 if (value & ~0x3e)
24572 as_bad_where (fixP->fx_file, fixP->fx_line,
24573 _("invalid offset, value too big (0x%08lX)"),
24574 (long) value);
24575 newval |= value << 5; /* 6 - 1. */
24576 break;
a737bd4d 24577
c19d1205
ZW
24578 default:
24579 as_bad_where (fixP->fx_file, fixP->fx_line,
24580 "Unable to process relocation for thumb opcode: %lx",
24581 (unsigned long) newval);
24582 break;
24583 }
24584 md_number_to_chars (buf, newval, THUMB_SIZE);
24585 break;
a737bd4d 24586
c19d1205
ZW
24587 case BFD_RELOC_ARM_THUMB_ADD:
24588 /* This is a complicated relocation, since we use it for all of
24589 the following immediate relocations:
a737bd4d 24590
c19d1205
ZW
24591 3bit ADD/SUB
24592 8bit ADD/SUB
24593 9bit ADD/SUB SP word-aligned
24594 10bit ADD PC/SP word-aligned
a737bd4d 24595
c19d1205
ZW
24596 The type of instruction being processed is encoded in the
24597 instruction field:
a737bd4d 24598
c19d1205
ZW
24599 0x8000 SUB
24600 0x00F0 Rd
24601 0x000F Rs
24602 */
24603 newval = md_chars_to_number (buf, THUMB_SIZE);
24604 {
24605 int rd = (newval >> 4) & 0xf;
24606 int rs = newval & 0xf;
24607 int subtract = !!(newval & 0x8000);
a737bd4d 24608
c19d1205
ZW
24609 /* Check for HI regs, only very restricted cases allowed:
24610 Adjusting SP, and using PC or SP to get an address. */
24611 if ((rd > 7 && (rd != REG_SP || rs != REG_SP))
24612 || (rs > 7 && rs != REG_SP && rs != REG_PC))
24613 as_bad_where (fixP->fx_file, fixP->fx_line,
24614 _("invalid Hi register with immediate"));
a737bd4d 24615
c19d1205
ZW
24616 /* If value is negative, choose the opposite instruction. */
24617 if (value < 0)
24618 {
24619 value = -value;
24620 subtract = !subtract;
24621 if (value < 0)
24622 as_bad_where (fixP->fx_file, fixP->fx_line,
24623 _("immediate value out of range"));
24624 }
a737bd4d 24625
c19d1205
ZW
24626 if (rd == REG_SP)
24627 {
75c11999 24628 if (value & ~0x1fc)
c19d1205
ZW
24629 as_bad_where (fixP->fx_file, fixP->fx_line,
24630 _("invalid immediate for stack address calculation"));
24631 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
24632 newval |= value >> 2;
24633 }
24634 else if (rs == REG_PC || rs == REG_SP)
24635 {
c12d2c9d
NC
24636 /* PR gas/18541. If the addition is for a defined symbol
24637 within range of an ADR instruction then accept it. */
24638 if (subtract
24639 && value == 4
24640 && fixP->fx_addsy != NULL)
24641 {
24642 subtract = 0;
24643
24644 if (! S_IS_DEFINED (fixP->fx_addsy)
24645 || S_GET_SEGMENT (fixP->fx_addsy) != seg
24646 || S_IS_WEAK (fixP->fx_addsy))
24647 {
24648 as_bad_where (fixP->fx_file, fixP->fx_line,
24649 _("address calculation needs a strongly defined nearby symbol"));
24650 }
24651 else
24652 {
24653 offsetT v = fixP->fx_where + fixP->fx_frag->fr_address;
24654
24655 /* Round up to the next 4-byte boundary. */
24656 if (v & 3)
24657 v = (v + 3) & ~ 3;
24658 else
24659 v += 4;
24660 v = S_GET_VALUE (fixP->fx_addsy) - v;
24661
24662 if (v & ~0x3fc)
24663 {
24664 as_bad_where (fixP->fx_file, fixP->fx_line,
24665 _("symbol too far away"));
24666 }
24667 else
24668 {
24669 fixP->fx_done = 1;
24670 value = v;
24671 }
24672 }
24673 }
24674
c19d1205
ZW
24675 if (subtract || value & ~0x3fc)
24676 as_bad_where (fixP->fx_file, fixP->fx_line,
24677 _("invalid immediate for address calculation (value = 0x%08lX)"),
5fc177c8 24678 (unsigned long) (subtract ? - value : value));
c19d1205
ZW
24679 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
24680 newval |= rd << 8;
24681 newval |= value >> 2;
24682 }
24683 else if (rs == rd)
24684 {
24685 if (value & ~0xff)
24686 as_bad_where (fixP->fx_file, fixP->fx_line,
24687 _("immediate value out of range"));
24688 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
24689 newval |= (rd << 8) | value;
24690 }
24691 else
24692 {
24693 if (value & ~0x7)
24694 as_bad_where (fixP->fx_file, fixP->fx_line,
24695 _("immediate value out of range"));
24696 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
24697 newval |= rd | (rs << 3) | (value << 6);
24698 }
24699 }
24700 md_number_to_chars (buf, newval, THUMB_SIZE);
24701 break;
a737bd4d 24702
c19d1205
ZW
24703 case BFD_RELOC_ARM_THUMB_IMM:
24704 newval = md_chars_to_number (buf, THUMB_SIZE);
24705 if (value < 0 || value > 255)
24706 as_bad_where (fixP->fx_file, fixP->fx_line,
4e6e072b 24707 _("invalid immediate: %ld is out of range"),
c19d1205
ZW
24708 (long) value);
24709 newval |= value;
24710 md_number_to_chars (buf, newval, THUMB_SIZE);
24711 break;
a737bd4d 24712
c19d1205
ZW
24713 case BFD_RELOC_ARM_THUMB_SHIFT:
24714 /* 5bit shift value (0..32). LSL cannot take 32. */
24715 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf83f;
24716 temp = newval & 0xf800;
24717 if (value < 0 || value > 32 || (value == 32 && temp == T_OPCODE_LSL_I))
24718 as_bad_where (fixP->fx_file, fixP->fx_line,
24719 _("invalid shift value: %ld"), (long) value);
24720 /* Shifts of zero must be encoded as LSL. */
24721 if (value == 0)
24722 newval = (newval & 0x003f) | T_OPCODE_LSL_I;
24723 /* Shifts of 32 are encoded as zero. */
24724 else if (value == 32)
24725 value = 0;
24726 newval |= value << 6;
24727 md_number_to_chars (buf, newval, THUMB_SIZE);
24728 break;
a737bd4d 24729
c19d1205
ZW
24730 case BFD_RELOC_VTABLE_INHERIT:
24731 case BFD_RELOC_VTABLE_ENTRY:
24732 fixP->fx_done = 0;
24733 return;
6c43fab6 24734
b6895b4f
PB
24735 case BFD_RELOC_ARM_MOVW:
24736 case BFD_RELOC_ARM_MOVT:
24737 case BFD_RELOC_ARM_THUMB_MOVW:
24738 case BFD_RELOC_ARM_THUMB_MOVT:
24739 if (fixP->fx_done || !seg->use_rela_p)
24740 {
24741 /* REL format relocations are limited to a 16-bit addend. */
24742 if (!fixP->fx_done)
24743 {
39623e12 24744 if (value < -0x8000 || value > 0x7fff)
b6895b4f 24745 as_bad_where (fixP->fx_file, fixP->fx_line,
ff5075ca 24746 _("offset out of range"));
b6895b4f
PB
24747 }
24748 else if (fixP->fx_r_type == BFD_RELOC_ARM_MOVT
24749 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
24750 {
24751 value >>= 16;
24752 }
24753
24754 if (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
24755 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
24756 {
24757 newval = get_thumb32_insn (buf);
24758 newval &= 0xfbf08f00;
24759 newval |= (value & 0xf000) << 4;
24760 newval |= (value & 0x0800) << 15;
24761 newval |= (value & 0x0700) << 4;
24762 newval |= (value & 0x00ff);
24763 put_thumb32_insn (buf, newval);
24764 }
24765 else
24766 {
24767 newval = md_chars_to_number (buf, 4);
24768 newval &= 0xfff0f000;
24769 newval |= value & 0x0fff;
24770 newval |= (value & 0xf000) << 4;
24771 md_number_to_chars (buf, newval, 4);
24772 }
24773 }
24774 return;
24775
72d98d16
MG
24776 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
24777 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
24778 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
24779 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
24780 gas_assert (!fixP->fx_done);
24781 {
24782 bfd_vma insn;
24783 bfd_boolean is_mov;
24784 bfd_vma encoded_addend = value;
24785
24786 /* Check that addend can be encoded in instruction. */
24787 if (!seg->use_rela_p && (value < 0 || value > 255))
24788 as_bad_where (fixP->fx_file, fixP->fx_line,
24789 _("the offset 0x%08lX is not representable"),
24790 (unsigned long) encoded_addend);
24791
24792 /* Extract the instruction. */
24793 insn = md_chars_to_number (buf, THUMB_SIZE);
24794 is_mov = (insn & 0xf800) == 0x2000;
24795
24796 /* Encode insn. */
24797 if (is_mov)
24798 {
24799 if (!seg->use_rela_p)
24800 insn |= encoded_addend;
24801 }
24802 else
24803 {
24804 int rd, rs;
24805
24806 /* Extract the instruction. */
24807 /* Encoding is the following
24808 0x8000 SUB
24809 0x00F0 Rd
24810 0x000F Rs
24811 */
24812 /* The following conditions must be true :
24813 - ADD
24814 - Rd == Rs
24815 - Rd <= 7
24816 */
24817 rd = (insn >> 4) & 0xf;
24818 rs = insn & 0xf;
24819 if ((insn & 0x8000) || (rd != rs) || rd > 7)
24820 as_bad_where (fixP->fx_file, fixP->fx_line,
24821 _("Unable to process relocation for thumb opcode: %lx"),
24822 (unsigned long) insn);
24823
24824 /* Encode as ADD immediate8 thumb 1 code. */
24825 insn = 0x3000 | (rd << 8);
24826
24827 /* Place the encoded addend into the first 8 bits of the
24828 instruction. */
24829 if (!seg->use_rela_p)
24830 insn |= encoded_addend;
24831 }
24832
24833 /* Update the instruction. */
24834 md_number_to_chars (buf, insn, THUMB_SIZE);
24835 }
24836 break;
24837
4962c51a
MS
24838 case BFD_RELOC_ARM_ALU_PC_G0_NC:
24839 case BFD_RELOC_ARM_ALU_PC_G0:
24840 case BFD_RELOC_ARM_ALU_PC_G1_NC:
24841 case BFD_RELOC_ARM_ALU_PC_G1:
24842 case BFD_RELOC_ARM_ALU_PC_G2:
24843 case BFD_RELOC_ARM_ALU_SB_G0_NC:
24844 case BFD_RELOC_ARM_ALU_SB_G0:
24845 case BFD_RELOC_ARM_ALU_SB_G1_NC:
24846 case BFD_RELOC_ARM_ALU_SB_G1:
24847 case BFD_RELOC_ARM_ALU_SB_G2:
9c2799c2 24848 gas_assert (!fixP->fx_done);
4962c51a
MS
24849 if (!seg->use_rela_p)
24850 {
477330fc
RM
24851 bfd_vma insn;
24852 bfd_vma encoded_addend;
3ca4a8ec 24853 bfd_vma addend_abs = llabs (value);
477330fc
RM
24854
24855 /* Check that the absolute value of the addend can be
24856 expressed as an 8-bit constant plus a rotation. */
24857 encoded_addend = encode_arm_immediate (addend_abs);
24858 if (encoded_addend == (unsigned int) FAIL)
4962c51a 24859 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
24860 _("the offset 0x%08lX is not representable"),
24861 (unsigned long) addend_abs);
24862
24863 /* Extract the instruction. */
24864 insn = md_chars_to_number (buf, INSN_SIZE);
24865
24866 /* If the addend is positive, use an ADD instruction.
24867 Otherwise use a SUB. Take care not to destroy the S bit. */
24868 insn &= 0xff1fffff;
24869 if (value < 0)
24870 insn |= 1 << 22;
24871 else
24872 insn |= 1 << 23;
24873
24874 /* Place the encoded addend into the first 12 bits of the
24875 instruction. */
24876 insn &= 0xfffff000;
24877 insn |= encoded_addend;
24878
24879 /* Update the instruction. */
24880 md_number_to_chars (buf, insn, INSN_SIZE);
4962c51a
MS
24881 }
24882 break;
24883
24884 case BFD_RELOC_ARM_LDR_PC_G0:
24885 case BFD_RELOC_ARM_LDR_PC_G1:
24886 case BFD_RELOC_ARM_LDR_PC_G2:
24887 case BFD_RELOC_ARM_LDR_SB_G0:
24888 case BFD_RELOC_ARM_LDR_SB_G1:
24889 case BFD_RELOC_ARM_LDR_SB_G2:
9c2799c2 24890 gas_assert (!fixP->fx_done);
4962c51a 24891 if (!seg->use_rela_p)
477330fc
RM
24892 {
24893 bfd_vma insn;
3ca4a8ec 24894 bfd_vma addend_abs = llabs (value);
4962c51a 24895
477330fc
RM
24896 /* Check that the absolute value of the addend can be
24897 encoded in 12 bits. */
24898 if (addend_abs >= 0x1000)
4962c51a 24899 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
24900 _("bad offset 0x%08lX (only 12 bits available for the magnitude)"),
24901 (unsigned long) addend_abs);
24902
24903 /* Extract the instruction. */
24904 insn = md_chars_to_number (buf, INSN_SIZE);
24905
24906 /* If the addend is negative, clear bit 23 of the instruction.
24907 Otherwise set it. */
24908 if (value < 0)
24909 insn &= ~(1 << 23);
24910 else
24911 insn |= 1 << 23;
24912
24913 /* Place the absolute value of the addend into the first 12 bits
24914 of the instruction. */
24915 insn &= 0xfffff000;
24916 insn |= addend_abs;
24917
24918 /* Update the instruction. */
24919 md_number_to_chars (buf, insn, INSN_SIZE);
24920 }
4962c51a
MS
24921 break;
24922
24923 case BFD_RELOC_ARM_LDRS_PC_G0:
24924 case BFD_RELOC_ARM_LDRS_PC_G1:
24925 case BFD_RELOC_ARM_LDRS_PC_G2:
24926 case BFD_RELOC_ARM_LDRS_SB_G0:
24927 case BFD_RELOC_ARM_LDRS_SB_G1:
24928 case BFD_RELOC_ARM_LDRS_SB_G2:
9c2799c2 24929 gas_assert (!fixP->fx_done);
4962c51a 24930 if (!seg->use_rela_p)
477330fc
RM
24931 {
24932 bfd_vma insn;
3ca4a8ec 24933 bfd_vma addend_abs = llabs (value);
4962c51a 24934
477330fc
RM
24935 /* Check that the absolute value of the addend can be
24936 encoded in 8 bits. */
24937 if (addend_abs >= 0x100)
4962c51a 24938 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
24939 _("bad offset 0x%08lX (only 8 bits available for the magnitude)"),
24940 (unsigned long) addend_abs);
24941
24942 /* Extract the instruction. */
24943 insn = md_chars_to_number (buf, INSN_SIZE);
24944
24945 /* If the addend is negative, clear bit 23 of the instruction.
24946 Otherwise set it. */
24947 if (value < 0)
24948 insn &= ~(1 << 23);
24949 else
24950 insn |= 1 << 23;
24951
24952 /* Place the first four bits of the absolute value of the addend
24953 into the first 4 bits of the instruction, and the remaining
24954 four into bits 8 .. 11. */
24955 insn &= 0xfffff0f0;
24956 insn |= (addend_abs & 0xf) | ((addend_abs & 0xf0) << 4);
24957
24958 /* Update the instruction. */
24959 md_number_to_chars (buf, insn, INSN_SIZE);
24960 }
4962c51a
MS
24961 break;
24962
24963 case BFD_RELOC_ARM_LDC_PC_G0:
24964 case BFD_RELOC_ARM_LDC_PC_G1:
24965 case BFD_RELOC_ARM_LDC_PC_G2:
24966 case BFD_RELOC_ARM_LDC_SB_G0:
24967 case BFD_RELOC_ARM_LDC_SB_G1:
24968 case BFD_RELOC_ARM_LDC_SB_G2:
9c2799c2 24969 gas_assert (!fixP->fx_done);
4962c51a 24970 if (!seg->use_rela_p)
477330fc
RM
24971 {
24972 bfd_vma insn;
3ca4a8ec 24973 bfd_vma addend_abs = llabs (value);
4962c51a 24974
477330fc
RM
24975 /* Check that the absolute value of the addend is a multiple of
24976 four and, when divided by four, fits in 8 bits. */
24977 if (addend_abs & 0x3)
4962c51a 24978 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
24979 _("bad offset 0x%08lX (must be word-aligned)"),
24980 (unsigned long) addend_abs);
4962c51a 24981
477330fc 24982 if ((addend_abs >> 2) > 0xff)
4962c51a 24983 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
24984 _("bad offset 0x%08lX (must be an 8-bit number of words)"),
24985 (unsigned long) addend_abs);
24986
24987 /* Extract the instruction. */
24988 insn = md_chars_to_number (buf, INSN_SIZE);
24989
24990 /* If the addend is negative, clear bit 23 of the instruction.
24991 Otherwise set it. */
24992 if (value < 0)
24993 insn &= ~(1 << 23);
24994 else
24995 insn |= 1 << 23;
24996
24997 /* Place the addend (divided by four) into the first eight
24998 bits of the instruction. */
24999 insn &= 0xfffffff0;
25000 insn |= addend_abs >> 2;
25001
25002 /* Update the instruction. */
25003 md_number_to_chars (buf, insn, INSN_SIZE);
25004 }
4962c51a
MS
25005 break;
25006
e12437dc
AV
25007 case BFD_RELOC_THUMB_PCREL_BRANCH5:
25008 if (fixP->fx_addsy
25009 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25010 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
25011 && ARM_IS_FUNC (fixP->fx_addsy)
25012 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
25013 {
25014 /* Force a relocation for a branch 5 bits wide. */
25015 fixP->fx_done = 0;
25016 }
25017 if (v8_1_branch_value_check (value, 5, FALSE) == FAIL)
25018 as_bad_where (fixP->fx_file, fixP->fx_line,
25019 BAD_BRANCH_OFF);
25020
25021 if (fixP->fx_done || !seg->use_rela_p)
25022 {
25023 addressT boff = value >> 1;
25024
25025 newval = md_chars_to_number (buf, THUMB_SIZE);
25026 newval |= (boff << 7);
25027 md_number_to_chars (buf, newval, THUMB_SIZE);
25028 }
25029 break;
25030
f6b2b12d
AV
25031 case BFD_RELOC_THUMB_PCREL_BFCSEL:
25032 if (fixP->fx_addsy
25033 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25034 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
25035 && ARM_IS_FUNC (fixP->fx_addsy)
25036 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
25037 {
25038 fixP->fx_done = 0;
25039 }
25040 if ((value & ~0x7f) && ((value & ~0x3f) != ~0x3f))
25041 as_bad_where (fixP->fx_file, fixP->fx_line,
25042 _("branch out of range"));
25043
25044 if (fixP->fx_done || !seg->use_rela_p)
25045 {
25046 newval = md_chars_to_number (buf, THUMB_SIZE);
25047
25048 addressT boff = ((newval & 0x0780) >> 7) << 1;
25049 addressT diff = value - boff;
25050
25051 if (diff == 4)
25052 {
25053 newval |= 1 << 1; /* T bit. */
25054 }
25055 else if (diff != 2)
25056 {
25057 as_bad_where (fixP->fx_file, fixP->fx_line,
25058 _("out of range label-relative fixup value"));
25059 }
25060 md_number_to_chars (buf, newval, THUMB_SIZE);
25061 }
25062 break;
25063
e5d6e09e
AV
25064 case BFD_RELOC_ARM_THUMB_BF17:
25065 if (fixP->fx_addsy
25066 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25067 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
25068 && ARM_IS_FUNC (fixP->fx_addsy)
25069 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
25070 {
25071 /* Force a relocation for a branch 17 bits wide. */
25072 fixP->fx_done = 0;
25073 }
25074
25075 if (v8_1_branch_value_check (value, 17, TRUE) == FAIL)
25076 as_bad_where (fixP->fx_file, fixP->fx_line,
25077 BAD_BRANCH_OFF);
25078
25079 if (fixP->fx_done || !seg->use_rela_p)
25080 {
25081 offsetT newval2;
25082 addressT immA, immB, immC;
25083
25084 immA = (value & 0x0001f000) >> 12;
25085 immB = (value & 0x00000ffc) >> 2;
25086 immC = (value & 0x00000002) >> 1;
25087
25088 newval = md_chars_to_number (buf, THUMB_SIZE);
25089 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
25090 newval |= immA;
25091 newval2 |= (immC << 11) | (immB << 1);
25092 md_number_to_chars (buf, newval, THUMB_SIZE);
25093 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
25094 }
25095 break;
25096
1caf72a5
AV
25097 case BFD_RELOC_ARM_THUMB_BF19:
25098 if (fixP->fx_addsy
25099 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25100 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
25101 && ARM_IS_FUNC (fixP->fx_addsy)
25102 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
25103 {
25104 /* Force a relocation for a branch 19 bits wide. */
25105 fixP->fx_done = 0;
25106 }
25107
25108 if (v8_1_branch_value_check (value, 19, TRUE) == FAIL)
25109 as_bad_where (fixP->fx_file, fixP->fx_line,
25110 BAD_BRANCH_OFF);
25111
25112 if (fixP->fx_done || !seg->use_rela_p)
25113 {
25114 offsetT newval2;
25115 addressT immA, immB, immC;
25116
25117 immA = (value & 0x0007f000) >> 12;
25118 immB = (value & 0x00000ffc) >> 2;
25119 immC = (value & 0x00000002) >> 1;
25120
25121 newval = md_chars_to_number (buf, THUMB_SIZE);
25122 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
25123 newval |= immA;
25124 newval2 |= (immC << 11) | (immB << 1);
25125 md_number_to_chars (buf, newval, THUMB_SIZE);
25126 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
25127 }
25128 break;
25129
1889da70
AV
25130 case BFD_RELOC_ARM_THUMB_BF13:
25131 if (fixP->fx_addsy
25132 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25133 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
25134 && ARM_IS_FUNC (fixP->fx_addsy)
25135 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
25136 {
25137 /* Force a relocation for a branch 13 bits wide. */
25138 fixP->fx_done = 0;
25139 }
25140
25141 if (v8_1_branch_value_check (value, 13, TRUE) == FAIL)
25142 as_bad_where (fixP->fx_file, fixP->fx_line,
25143 BAD_BRANCH_OFF);
25144
25145 if (fixP->fx_done || !seg->use_rela_p)
25146 {
25147 offsetT newval2;
25148 addressT immA, immB, immC;
25149
25150 immA = (value & 0x00001000) >> 12;
25151 immB = (value & 0x00000ffc) >> 2;
25152 immC = (value & 0x00000002) >> 1;
25153
25154 newval = md_chars_to_number (buf, THUMB_SIZE);
25155 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
25156 newval |= immA;
25157 newval2 |= (immC << 11) | (immB << 1);
25158 md_number_to_chars (buf, newval, THUMB_SIZE);
25159 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
25160 }
25161 break;
25162
60f993ce
AV
25163 case BFD_RELOC_ARM_THUMB_LOOP12:
25164 if (fixP->fx_addsy
25165 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25166 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
25167 && ARM_IS_FUNC (fixP->fx_addsy)
25168 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
25169 {
25170 /* Force a relocation for a branch 12 bits wide. */
25171 fixP->fx_done = 0;
25172 }
25173
25174 bfd_vma insn = get_thumb32_insn (buf);
25175 /* le lr, <label> or le <label> */
25176 if (((insn & 0xffffffff) == 0xf00fc001)
25177 || ((insn & 0xffffffff) == 0xf02fc001))
25178 value = -value;
25179
25180 if (v8_1_branch_value_check (value, 12, FALSE) == FAIL)
25181 as_bad_where (fixP->fx_file, fixP->fx_line,
25182 BAD_BRANCH_OFF);
25183 if (fixP->fx_done || !seg->use_rela_p)
25184 {
25185 addressT imml, immh;
25186
25187 immh = (value & 0x00000ffc) >> 2;
25188 imml = (value & 0x00000002) >> 1;
25189
25190 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
25191 newval |= (imml << 11) | (immh << 1);
25192 md_number_to_chars (buf + THUMB_SIZE, newval, THUMB_SIZE);
25193 }
25194 break;
25195
845b51d6
PB
25196 case BFD_RELOC_ARM_V4BX:
25197 /* This will need to go in the object file. */
25198 fixP->fx_done = 0;
25199 break;
25200
c19d1205
ZW
25201 case BFD_RELOC_UNUSED:
25202 default:
25203 as_bad_where (fixP->fx_file, fixP->fx_line,
25204 _("bad relocation fixup type (%d)"), fixP->fx_r_type);
25205 }
6c43fab6
RE
25206}
25207
c19d1205
ZW
25208/* Translate internal representation of relocation info to BFD target
25209 format. */
a737bd4d 25210
c19d1205 25211arelent *
00a97672 25212tc_gen_reloc (asection *section, fixS *fixp)
a737bd4d 25213{
c19d1205
ZW
25214 arelent * reloc;
25215 bfd_reloc_code_real_type code;
a737bd4d 25216
325801bd 25217 reloc = XNEW (arelent);
a737bd4d 25218
325801bd 25219 reloc->sym_ptr_ptr = XNEW (asymbol *);
c19d1205
ZW
25220 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
25221 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
a737bd4d 25222
2fc8bdac 25223 if (fixp->fx_pcrel)
00a97672
RS
25224 {
25225 if (section->use_rela_p)
25226 fixp->fx_offset -= md_pcrel_from_section (fixp, section);
25227 else
25228 fixp->fx_offset = reloc->address;
25229 }
c19d1205 25230 reloc->addend = fixp->fx_offset;
a737bd4d 25231
c19d1205 25232 switch (fixp->fx_r_type)
a737bd4d 25233 {
c19d1205
ZW
25234 case BFD_RELOC_8:
25235 if (fixp->fx_pcrel)
25236 {
25237 code = BFD_RELOC_8_PCREL;
25238 break;
25239 }
1a0670f3 25240 /* Fall through. */
a737bd4d 25241
c19d1205
ZW
25242 case BFD_RELOC_16:
25243 if (fixp->fx_pcrel)
25244 {
25245 code = BFD_RELOC_16_PCREL;
25246 break;
25247 }
1a0670f3 25248 /* Fall through. */
6c43fab6 25249
c19d1205
ZW
25250 case BFD_RELOC_32:
25251 if (fixp->fx_pcrel)
25252 {
25253 code = BFD_RELOC_32_PCREL;
25254 break;
25255 }
1a0670f3 25256 /* Fall through. */
a737bd4d 25257
b6895b4f
PB
25258 case BFD_RELOC_ARM_MOVW:
25259 if (fixp->fx_pcrel)
25260 {
25261 code = BFD_RELOC_ARM_MOVW_PCREL;
25262 break;
25263 }
1a0670f3 25264 /* Fall through. */
b6895b4f
PB
25265
25266 case BFD_RELOC_ARM_MOVT:
25267 if (fixp->fx_pcrel)
25268 {
25269 code = BFD_RELOC_ARM_MOVT_PCREL;
25270 break;
25271 }
1a0670f3 25272 /* Fall through. */
b6895b4f
PB
25273
25274 case BFD_RELOC_ARM_THUMB_MOVW:
25275 if (fixp->fx_pcrel)
25276 {
25277 code = BFD_RELOC_ARM_THUMB_MOVW_PCREL;
25278 break;
25279 }
1a0670f3 25280 /* Fall through. */
b6895b4f
PB
25281
25282 case BFD_RELOC_ARM_THUMB_MOVT:
25283 if (fixp->fx_pcrel)
25284 {
25285 code = BFD_RELOC_ARM_THUMB_MOVT_PCREL;
25286 break;
25287 }
1a0670f3 25288 /* Fall through. */
b6895b4f 25289
c19d1205
ZW
25290 case BFD_RELOC_NONE:
25291 case BFD_RELOC_ARM_PCREL_BRANCH:
25292 case BFD_RELOC_ARM_PCREL_BLX:
25293 case BFD_RELOC_RVA:
25294 case BFD_RELOC_THUMB_PCREL_BRANCH7:
25295 case BFD_RELOC_THUMB_PCREL_BRANCH9:
25296 case BFD_RELOC_THUMB_PCREL_BRANCH12:
25297 case BFD_RELOC_THUMB_PCREL_BRANCH20:
25298 case BFD_RELOC_THUMB_PCREL_BRANCH23:
25299 case BFD_RELOC_THUMB_PCREL_BRANCH25:
c19d1205
ZW
25300 case BFD_RELOC_VTABLE_ENTRY:
25301 case BFD_RELOC_VTABLE_INHERIT:
f0927246
NC
25302#ifdef TE_PE
25303 case BFD_RELOC_32_SECREL:
25304#endif
c19d1205
ZW
25305 code = fixp->fx_r_type;
25306 break;
a737bd4d 25307
00adf2d4
JB
25308 case BFD_RELOC_THUMB_PCREL_BLX:
25309#ifdef OBJ_ELF
25310 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
25311 code = BFD_RELOC_THUMB_PCREL_BRANCH23;
25312 else
25313#endif
25314 code = BFD_RELOC_THUMB_PCREL_BLX;
25315 break;
25316
c19d1205
ZW
25317 case BFD_RELOC_ARM_LITERAL:
25318 case BFD_RELOC_ARM_HWLITERAL:
25319 /* If this is called then the a literal has
25320 been referenced across a section boundary. */
25321 as_bad_where (fixp->fx_file, fixp->fx_line,
25322 _("literal referenced across section boundary"));
25323 return NULL;
a737bd4d 25324
c19d1205 25325#ifdef OBJ_ELF
0855e32b
NS
25326 case BFD_RELOC_ARM_TLS_CALL:
25327 case BFD_RELOC_ARM_THM_TLS_CALL:
25328 case BFD_RELOC_ARM_TLS_DESCSEQ:
25329 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
c19d1205
ZW
25330 case BFD_RELOC_ARM_GOT32:
25331 case BFD_RELOC_ARM_GOTOFF:
b43420e6 25332 case BFD_RELOC_ARM_GOT_PREL:
c19d1205
ZW
25333 case BFD_RELOC_ARM_PLT32:
25334 case BFD_RELOC_ARM_TARGET1:
25335 case BFD_RELOC_ARM_ROSEGREL32:
25336 case BFD_RELOC_ARM_SBREL32:
25337 case BFD_RELOC_ARM_PREL31:
25338 case BFD_RELOC_ARM_TARGET2:
c19d1205 25339 case BFD_RELOC_ARM_TLS_LDO32:
39b41c9c
PB
25340 case BFD_RELOC_ARM_PCREL_CALL:
25341 case BFD_RELOC_ARM_PCREL_JUMP:
4962c51a
MS
25342 case BFD_RELOC_ARM_ALU_PC_G0_NC:
25343 case BFD_RELOC_ARM_ALU_PC_G0:
25344 case BFD_RELOC_ARM_ALU_PC_G1_NC:
25345 case BFD_RELOC_ARM_ALU_PC_G1:
25346 case BFD_RELOC_ARM_ALU_PC_G2:
25347 case BFD_RELOC_ARM_LDR_PC_G0:
25348 case BFD_RELOC_ARM_LDR_PC_G1:
25349 case BFD_RELOC_ARM_LDR_PC_G2:
25350 case BFD_RELOC_ARM_LDRS_PC_G0:
25351 case BFD_RELOC_ARM_LDRS_PC_G1:
25352 case BFD_RELOC_ARM_LDRS_PC_G2:
25353 case BFD_RELOC_ARM_LDC_PC_G0:
25354 case BFD_RELOC_ARM_LDC_PC_G1:
25355 case BFD_RELOC_ARM_LDC_PC_G2:
25356 case BFD_RELOC_ARM_ALU_SB_G0_NC:
25357 case BFD_RELOC_ARM_ALU_SB_G0:
25358 case BFD_RELOC_ARM_ALU_SB_G1_NC:
25359 case BFD_RELOC_ARM_ALU_SB_G1:
25360 case BFD_RELOC_ARM_ALU_SB_G2:
25361 case BFD_RELOC_ARM_LDR_SB_G0:
25362 case BFD_RELOC_ARM_LDR_SB_G1:
25363 case BFD_RELOC_ARM_LDR_SB_G2:
25364 case BFD_RELOC_ARM_LDRS_SB_G0:
25365 case BFD_RELOC_ARM_LDRS_SB_G1:
25366 case BFD_RELOC_ARM_LDRS_SB_G2:
25367 case BFD_RELOC_ARM_LDC_SB_G0:
25368 case BFD_RELOC_ARM_LDC_SB_G1:
25369 case BFD_RELOC_ARM_LDC_SB_G2:
845b51d6 25370 case BFD_RELOC_ARM_V4BX:
72d98d16
MG
25371 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
25372 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
25373 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
25374 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
188fd7ae
CL
25375 case BFD_RELOC_ARM_GOTFUNCDESC:
25376 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
25377 case BFD_RELOC_ARM_FUNCDESC:
e5d6e09e 25378 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 25379 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 25380 case BFD_RELOC_ARM_THUMB_BF13:
c19d1205
ZW
25381 code = fixp->fx_r_type;
25382 break;
a737bd4d 25383
0855e32b 25384 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205 25385 case BFD_RELOC_ARM_TLS_GD32:
5c5a4843 25386 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
75c11999 25387 case BFD_RELOC_ARM_TLS_LE32:
c19d1205 25388 case BFD_RELOC_ARM_TLS_IE32:
5c5a4843 25389 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
c19d1205 25390 case BFD_RELOC_ARM_TLS_LDM32:
5c5a4843 25391 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
c19d1205
ZW
25392 /* BFD will include the symbol's address in the addend.
25393 But we don't want that, so subtract it out again here. */
25394 if (!S_IS_COMMON (fixp->fx_addsy))
25395 reloc->addend -= (*reloc->sym_ptr_ptr)->value;
25396 code = fixp->fx_r_type;
25397 break;
25398#endif
a737bd4d 25399
c19d1205
ZW
25400 case BFD_RELOC_ARM_IMMEDIATE:
25401 as_bad_where (fixp->fx_file, fixp->fx_line,
25402 _("internal relocation (type: IMMEDIATE) not fixed up"));
25403 return NULL;
a737bd4d 25404
c19d1205
ZW
25405 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
25406 as_bad_where (fixp->fx_file, fixp->fx_line,
25407 _("ADRL used for a symbol not defined in the same file"));
25408 return NULL;
a737bd4d 25409
e12437dc 25410 case BFD_RELOC_THUMB_PCREL_BRANCH5:
f6b2b12d 25411 case BFD_RELOC_THUMB_PCREL_BFCSEL:
60f993ce 25412 case BFD_RELOC_ARM_THUMB_LOOP12:
e12437dc
AV
25413 as_bad_where (fixp->fx_file, fixp->fx_line,
25414 _("%s used for a symbol not defined in the same file"),
25415 bfd_get_reloc_code_name (fixp->fx_r_type));
25416 return NULL;
25417
c19d1205 25418 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
25419 if (section->use_rela_p)
25420 {
25421 code = fixp->fx_r_type;
25422 break;
25423 }
25424
c19d1205
ZW
25425 if (fixp->fx_addsy != NULL
25426 && !S_IS_DEFINED (fixp->fx_addsy)
25427 && S_IS_LOCAL (fixp->fx_addsy))
a737bd4d 25428 {
c19d1205
ZW
25429 as_bad_where (fixp->fx_file, fixp->fx_line,
25430 _("undefined local label `%s'"),
25431 S_GET_NAME (fixp->fx_addsy));
25432 return NULL;
a737bd4d
NC
25433 }
25434
c19d1205
ZW
25435 as_bad_where (fixp->fx_file, fixp->fx_line,
25436 _("internal_relocation (type: OFFSET_IMM) not fixed up"));
25437 return NULL;
a737bd4d 25438
c19d1205
ZW
25439 default:
25440 {
e0471c16 25441 const char * type;
6c43fab6 25442
c19d1205
ZW
25443 switch (fixp->fx_r_type)
25444 {
25445 case BFD_RELOC_NONE: type = "NONE"; break;
25446 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
25447 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
3eb17e6b 25448 case BFD_RELOC_ARM_SMC: type = "SMC"; break;
c19d1205
ZW
25449 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
25450 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
25451 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
db187cb9 25452 case BFD_RELOC_ARM_T32_OFFSET_IMM: type = "T32_OFFSET_IMM"; break;
8f06b2d8 25453 case BFD_RELOC_ARM_T32_CP_OFF_IMM: type = "T32_CP_OFF_IMM"; break;
c19d1205
ZW
25454 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
25455 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
25456 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
25457 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
25458 default: type = _("<unknown>"); break;
25459 }
25460 as_bad_where (fixp->fx_file, fixp->fx_line,
25461 _("cannot represent %s relocation in this object file format"),
25462 type);
25463 return NULL;
25464 }
a737bd4d 25465 }
6c43fab6 25466
c19d1205
ZW
25467#ifdef OBJ_ELF
25468 if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
25469 && GOT_symbol
25470 && fixp->fx_addsy == GOT_symbol)
25471 {
25472 code = BFD_RELOC_ARM_GOTPC;
25473 reloc->addend = fixp->fx_offset = reloc->address;
25474 }
25475#endif
6c43fab6 25476
c19d1205 25477 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
6c43fab6 25478
c19d1205
ZW
25479 if (reloc->howto == NULL)
25480 {
25481 as_bad_where (fixp->fx_file, fixp->fx_line,
25482 _("cannot represent %s relocation in this object file format"),
25483 bfd_get_reloc_code_name (code));
25484 return NULL;
25485 }
6c43fab6 25486
c19d1205
ZW
25487 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
25488 vtable entry to be used in the relocation's section offset. */
25489 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
25490 reloc->address = fixp->fx_offset;
6c43fab6 25491
c19d1205 25492 return reloc;
6c43fab6
RE
25493}
25494
c19d1205 25495/* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6c43fab6 25496
c19d1205
ZW
25497void
25498cons_fix_new_arm (fragS * frag,
25499 int where,
25500 int size,
62ebcb5c
AM
25501 expressionS * exp,
25502 bfd_reloc_code_real_type reloc)
6c43fab6 25503{
c19d1205 25504 int pcrel = 0;
6c43fab6 25505
c19d1205
ZW
25506 /* Pick a reloc.
25507 FIXME: @@ Should look at CPU word size. */
25508 switch (size)
25509 {
25510 case 1:
62ebcb5c 25511 reloc = BFD_RELOC_8;
c19d1205
ZW
25512 break;
25513 case 2:
62ebcb5c 25514 reloc = BFD_RELOC_16;
c19d1205
ZW
25515 break;
25516 case 4:
25517 default:
62ebcb5c 25518 reloc = BFD_RELOC_32;
c19d1205
ZW
25519 break;
25520 case 8:
62ebcb5c 25521 reloc = BFD_RELOC_64;
c19d1205
ZW
25522 break;
25523 }
6c43fab6 25524
f0927246
NC
25525#ifdef TE_PE
25526 if (exp->X_op == O_secrel)
25527 {
25528 exp->X_op = O_symbol;
62ebcb5c 25529 reloc = BFD_RELOC_32_SECREL;
f0927246
NC
25530 }
25531#endif
25532
62ebcb5c 25533 fix_new_exp (frag, where, size, exp, pcrel, reloc);
c19d1205 25534}
6c43fab6 25535
4343666d 25536#if defined (OBJ_COFF)
c19d1205
ZW
25537void
25538arm_validate_fix (fixS * fixP)
6c43fab6 25539{
c19d1205
ZW
25540 /* If the destination of the branch is a defined symbol which does not have
25541 the THUMB_FUNC attribute, then we must be calling a function which has
25542 the (interfacearm) attribute. We look for the Thumb entry point to that
25543 function and change the branch to refer to that function instead. */
25544 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
25545 && fixP->fx_addsy != NULL
25546 && S_IS_DEFINED (fixP->fx_addsy)
25547 && ! THUMB_IS_FUNC (fixP->fx_addsy))
6c43fab6 25548 {
c19d1205 25549 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
6c43fab6 25550 }
c19d1205
ZW
25551}
25552#endif
6c43fab6 25553
267bf995 25554
c19d1205
ZW
25555int
25556arm_force_relocation (struct fix * fixp)
25557{
25558#if defined (OBJ_COFF) && defined (TE_PE)
25559 if (fixp->fx_r_type == BFD_RELOC_RVA)
25560 return 1;
25561#endif
6c43fab6 25562
267bf995
RR
25563 /* In case we have a call or a branch to a function in ARM ISA mode from
25564 a thumb function or vice-versa force the relocation. These relocations
25565 are cleared off for some cores that might have blx and simple transformations
25566 are possible. */
25567
25568#ifdef OBJ_ELF
25569 switch (fixp->fx_r_type)
25570 {
25571 case BFD_RELOC_ARM_PCREL_JUMP:
25572 case BFD_RELOC_ARM_PCREL_CALL:
25573 case BFD_RELOC_THUMB_PCREL_BLX:
25574 if (THUMB_IS_FUNC (fixp->fx_addsy))
25575 return 1;
25576 break;
25577
25578 case BFD_RELOC_ARM_PCREL_BLX:
25579 case BFD_RELOC_THUMB_PCREL_BRANCH25:
25580 case BFD_RELOC_THUMB_PCREL_BRANCH20:
25581 case BFD_RELOC_THUMB_PCREL_BRANCH23:
25582 if (ARM_IS_FUNC (fixp->fx_addsy))
25583 return 1;
25584 break;
25585
25586 default:
25587 break;
25588 }
25589#endif
25590
b5884301
PB
25591 /* Resolve these relocations even if the symbol is extern or weak.
25592 Technically this is probably wrong due to symbol preemption.
25593 In practice these relocations do not have enough range to be useful
25594 at dynamic link time, and some code (e.g. in the Linux kernel)
25595 expects these references to be resolved. */
c19d1205
ZW
25596 if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
25597 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
b5884301 25598 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM8
0110f2b8 25599 || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE
b5884301
PB
25600 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
25601 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2
25602 || fixp->fx_r_type == BFD_RELOC_ARM_THUMB_OFFSET
16805f35 25603 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM
0110f2b8
PB
25604 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
25605 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMM12
b5884301
PB
25606 || fixp->fx_r_type == BFD_RELOC_ARM_T32_OFFSET_IMM
25607 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_PC12
25608 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM
25609 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM_S2)
c19d1205 25610 return 0;
a737bd4d 25611
4962c51a
MS
25612 /* Always leave these relocations for the linker. */
25613 if ((fixp->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
25614 && fixp->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
25615 || fixp->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
25616 return 1;
25617
f0291e4c
PB
25618 /* Always generate relocations against function symbols. */
25619 if (fixp->fx_r_type == BFD_RELOC_32
25620 && fixp->fx_addsy
25621 && (symbol_get_bfdsym (fixp->fx_addsy)->flags & BSF_FUNCTION))
25622 return 1;
25623
c19d1205 25624 return generic_force_reloc (fixp);
404ff6b5
AH
25625}
25626
0ffdc86c 25627#if defined (OBJ_ELF) || defined (OBJ_COFF)
e28387c3
PB
25628/* Relocations against function names must be left unadjusted,
25629 so that the linker can use this information to generate interworking
25630 stubs. The MIPS version of this function
c19d1205
ZW
25631 also prevents relocations that are mips-16 specific, but I do not
25632 know why it does this.
404ff6b5 25633
c19d1205
ZW
25634 FIXME:
25635 There is one other problem that ought to be addressed here, but
25636 which currently is not: Taking the address of a label (rather
25637 than a function) and then later jumping to that address. Such
25638 addresses also ought to have their bottom bit set (assuming that
25639 they reside in Thumb code), but at the moment they will not. */
404ff6b5 25640
c19d1205
ZW
25641bfd_boolean
25642arm_fix_adjustable (fixS * fixP)
404ff6b5 25643{
c19d1205
ZW
25644 if (fixP->fx_addsy == NULL)
25645 return 1;
404ff6b5 25646
e28387c3
PB
25647 /* Preserve relocations against symbols with function type. */
25648 if (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_FUNCTION)
c921be7d 25649 return FALSE;
e28387c3 25650
c19d1205
ZW
25651 if (THUMB_IS_FUNC (fixP->fx_addsy)
25652 && fixP->fx_subsy == NULL)
c921be7d 25653 return FALSE;
a737bd4d 25654
c19d1205
ZW
25655 /* We need the symbol name for the VTABLE entries. */
25656 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
25657 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
c921be7d 25658 return FALSE;
404ff6b5 25659
c19d1205
ZW
25660 /* Don't allow symbols to be discarded on GOT related relocs. */
25661 if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
25662 || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
25663 || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
25664 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32
5c5a4843 25665 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32_FDPIC
c19d1205
ZW
25666 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LE32
25667 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32
5c5a4843 25668 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32_FDPIC
c19d1205 25669 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32
5c5a4843 25670 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32_FDPIC
c19d1205 25671 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDO32
0855e32b
NS
25672 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GOTDESC
25673 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_CALL
25674 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_CALL
25675 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_DESCSEQ
25676 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_DESCSEQ
c19d1205 25677 || fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
c921be7d 25678 return FALSE;
a737bd4d 25679
4962c51a
MS
25680 /* Similarly for group relocations. */
25681 if ((fixP->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
25682 && fixP->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
25683 || fixP->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
c921be7d 25684 return FALSE;
4962c51a 25685
79947c54
CD
25686 /* MOVW/MOVT REL relocations have limited offsets, so keep the symbols. */
25687 if (fixP->fx_r_type == BFD_RELOC_ARM_MOVW
25688 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT
25689 || fixP->fx_r_type == BFD_RELOC_ARM_MOVW_PCREL
25690 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT_PCREL
25691 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
25692 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT
25693 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW_PCREL
25694 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT_PCREL)
c921be7d 25695 return FALSE;
79947c54 25696
72d98d16
MG
25697 /* BFD_RELOC_ARM_THUMB_ALU_ABS_Gx_NC relocations have VERY limited
25698 offsets, so keep these symbols. */
25699 if (fixP->fx_r_type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
25700 && fixP->fx_r_type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
25701 return FALSE;
25702
c921be7d 25703 return TRUE;
a737bd4d 25704}
0ffdc86c
NC
25705#endif /* defined (OBJ_ELF) || defined (OBJ_COFF) */
25706
25707#ifdef OBJ_ELF
c19d1205
ZW
25708const char *
25709elf32_arm_target_format (void)
404ff6b5 25710{
c19d1205
ZW
25711#ifdef TE_SYMBIAN
25712 return (target_big_endian
25713 ? "elf32-bigarm-symbian"
25714 : "elf32-littlearm-symbian");
25715#elif defined (TE_VXWORKS)
25716 return (target_big_endian
25717 ? "elf32-bigarm-vxworks"
25718 : "elf32-littlearm-vxworks");
b38cadfb
NC
25719#elif defined (TE_NACL)
25720 return (target_big_endian
25721 ? "elf32-bigarm-nacl"
25722 : "elf32-littlearm-nacl");
c19d1205 25723#else
18a20338
CL
25724 if (arm_fdpic)
25725 {
25726 if (target_big_endian)
25727 return "elf32-bigarm-fdpic";
25728 else
25729 return "elf32-littlearm-fdpic";
25730 }
c19d1205 25731 else
18a20338
CL
25732 {
25733 if (target_big_endian)
25734 return "elf32-bigarm";
25735 else
25736 return "elf32-littlearm";
25737 }
c19d1205 25738#endif
404ff6b5
AH
25739}
25740
c19d1205
ZW
25741void
25742armelf_frob_symbol (symbolS * symp,
25743 int * puntp)
404ff6b5 25744{
c19d1205
ZW
25745 elf_frob_symbol (symp, puntp);
25746}
25747#endif
404ff6b5 25748
c19d1205 25749/* MD interface: Finalization. */
a737bd4d 25750
c19d1205
ZW
25751void
25752arm_cleanup (void)
25753{
25754 literal_pool * pool;
a737bd4d 25755
e07e6e58
NC
25756 /* Ensure that all the IT blocks are properly closed. */
25757 check_it_blocks_finished ();
25758
c19d1205
ZW
25759 for (pool = list_of_pools; pool; pool = pool->next)
25760 {
5f4273c7 25761 /* Put it at the end of the relevant section. */
c19d1205
ZW
25762 subseg_set (pool->section, pool->sub_section);
25763#ifdef OBJ_ELF
25764 arm_elf_change_section ();
25765#endif
25766 s_ltorg (0);
25767 }
404ff6b5
AH
25768}
25769
cd000bff
DJ
25770#ifdef OBJ_ELF
25771/* Remove any excess mapping symbols generated for alignment frags in
25772 SEC. We may have created a mapping symbol before a zero byte
25773 alignment; remove it if there's a mapping symbol after the
25774 alignment. */
25775static void
25776check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
25777 void *dummy ATTRIBUTE_UNUSED)
25778{
25779 segment_info_type *seginfo = seg_info (sec);
25780 fragS *fragp;
25781
25782 if (seginfo == NULL || seginfo->frchainP == NULL)
25783 return;
25784
25785 for (fragp = seginfo->frchainP->frch_root;
25786 fragp != NULL;
25787 fragp = fragp->fr_next)
25788 {
25789 symbolS *sym = fragp->tc_frag_data.last_map;
25790 fragS *next = fragp->fr_next;
25791
25792 /* Variable-sized frags have been converted to fixed size by
25793 this point. But if this was variable-sized to start with,
25794 there will be a fixed-size frag after it. So don't handle
25795 next == NULL. */
25796 if (sym == NULL || next == NULL)
25797 continue;
25798
25799 if (S_GET_VALUE (sym) < next->fr_address)
25800 /* Not at the end of this frag. */
25801 continue;
25802 know (S_GET_VALUE (sym) == next->fr_address);
25803
25804 do
25805 {
25806 if (next->tc_frag_data.first_map != NULL)
25807 {
25808 /* Next frag starts with a mapping symbol. Discard this
25809 one. */
25810 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
25811 break;
25812 }
25813
25814 if (next->fr_next == NULL)
25815 {
25816 /* This mapping symbol is at the end of the section. Discard
25817 it. */
25818 know (next->fr_fix == 0 && next->fr_var == 0);
25819 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
25820 break;
25821 }
25822
25823 /* As long as we have empty frags without any mapping symbols,
25824 keep looking. */
25825 /* If the next frag is non-empty and does not start with a
25826 mapping symbol, then this mapping symbol is required. */
25827 if (next->fr_address != next->fr_next->fr_address)
25828 break;
25829
25830 next = next->fr_next;
25831 }
25832 while (next != NULL);
25833 }
25834}
25835#endif
25836
c19d1205
ZW
25837/* Adjust the symbol table. This marks Thumb symbols as distinct from
25838 ARM ones. */
404ff6b5 25839
c19d1205
ZW
25840void
25841arm_adjust_symtab (void)
404ff6b5 25842{
c19d1205
ZW
25843#ifdef OBJ_COFF
25844 symbolS * sym;
404ff6b5 25845
c19d1205
ZW
25846 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
25847 {
25848 if (ARM_IS_THUMB (sym))
25849 {
25850 if (THUMB_IS_FUNC (sym))
25851 {
25852 /* Mark the symbol as a Thumb function. */
25853 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
25854 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
25855 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
404ff6b5 25856
c19d1205
ZW
25857 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
25858 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
25859 else
25860 as_bad (_("%s: unexpected function type: %d"),
25861 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
25862 }
25863 else switch (S_GET_STORAGE_CLASS (sym))
25864 {
25865 case C_EXT:
25866 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
25867 break;
25868 case C_STAT:
25869 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
25870 break;
25871 case C_LABEL:
25872 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
25873 break;
25874 default:
25875 /* Do nothing. */
25876 break;
25877 }
25878 }
a737bd4d 25879
c19d1205
ZW
25880 if (ARM_IS_INTERWORK (sym))
25881 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
404ff6b5 25882 }
c19d1205
ZW
25883#endif
25884#ifdef OBJ_ELF
25885 symbolS * sym;
25886 char bind;
404ff6b5 25887
c19d1205 25888 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
404ff6b5 25889 {
c19d1205
ZW
25890 if (ARM_IS_THUMB (sym))
25891 {
25892 elf_symbol_type * elf_sym;
404ff6b5 25893
c19d1205
ZW
25894 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
25895 bind = ELF_ST_BIND (elf_sym->internal_elf_sym.st_info);
404ff6b5 25896
b0796911
PB
25897 if (! bfd_is_arm_special_symbol_name (elf_sym->symbol.name,
25898 BFD_ARM_SPECIAL_SYM_TYPE_ANY))
c19d1205
ZW
25899 {
25900 /* If it's a .thumb_func, declare it as so,
25901 otherwise tag label as .code 16. */
25902 if (THUMB_IS_FUNC (sym))
39d911fc
TP
25903 ARM_SET_SYM_BRANCH_TYPE (elf_sym->internal_elf_sym.st_target_internal,
25904 ST_BRANCH_TO_THUMB);
3ba67470 25905 else if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
c19d1205
ZW
25906 elf_sym->internal_elf_sym.st_info =
25907 ELF_ST_INFO (bind, STT_ARM_16BIT);
25908 }
25909 }
25910 }
cd000bff
DJ
25911
25912 /* Remove any overlapping mapping symbols generated by alignment frags. */
25913 bfd_map_over_sections (stdoutput, check_mapping_symbols, (char *) 0);
709001e9
MM
25914 /* Now do generic ELF adjustments. */
25915 elf_adjust_symtab ();
c19d1205 25916#endif
404ff6b5
AH
25917}
25918
c19d1205 25919/* MD interface: Initialization. */
404ff6b5 25920
a737bd4d 25921static void
c19d1205 25922set_constant_flonums (void)
a737bd4d 25923{
c19d1205 25924 int i;
404ff6b5 25925
c19d1205
ZW
25926 for (i = 0; i < NUM_FLOAT_VALS; i++)
25927 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
25928 abort ();
a737bd4d 25929}
404ff6b5 25930
3e9e4fcf
JB
25931/* Auto-select Thumb mode if it's the only available instruction set for the
25932 given architecture. */
25933
25934static void
25935autoselect_thumb_from_cpu_variant (void)
25936{
25937 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
25938 opcode_select (16);
25939}
25940
c19d1205
ZW
25941void
25942md_begin (void)
a737bd4d 25943{
c19d1205
ZW
25944 unsigned mach;
25945 unsigned int i;
404ff6b5 25946
c19d1205
ZW
25947 if ( (arm_ops_hsh = hash_new ()) == NULL
25948 || (arm_cond_hsh = hash_new ()) == NULL
25949 || (arm_shift_hsh = hash_new ()) == NULL
25950 || (arm_psr_hsh = hash_new ()) == NULL
62b3e311 25951 || (arm_v7m_psr_hsh = hash_new ()) == NULL
c19d1205 25952 || (arm_reg_hsh = hash_new ()) == NULL
62b3e311
PB
25953 || (arm_reloc_hsh = hash_new ()) == NULL
25954 || (arm_barrier_opt_hsh = hash_new ()) == NULL)
c19d1205
ZW
25955 as_fatal (_("virtual memory exhausted"));
25956
25957 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
d3ce72d0 25958 hash_insert (arm_ops_hsh, insns[i].template_name, (void *) (insns + i));
c19d1205 25959 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
d3ce72d0 25960 hash_insert (arm_cond_hsh, conds[i].template_name, (void *) (conds + i));
c19d1205 25961 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
5a49b8ac 25962 hash_insert (arm_shift_hsh, shift_names[i].name, (void *) (shift_names + i));
c19d1205 25963 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
d3ce72d0 25964 hash_insert (arm_psr_hsh, psrs[i].template_name, (void *) (psrs + i));
62b3e311 25965 for (i = 0; i < sizeof (v7m_psrs) / sizeof (struct asm_psr); i++)
d3ce72d0 25966 hash_insert (arm_v7m_psr_hsh, v7m_psrs[i].template_name,
477330fc 25967 (void *) (v7m_psrs + i));
c19d1205 25968 for (i = 0; i < sizeof (reg_names) / sizeof (struct reg_entry); i++)
5a49b8ac 25969 hash_insert (arm_reg_hsh, reg_names[i].name, (void *) (reg_names + i));
62b3e311
PB
25970 for (i = 0;
25971 i < sizeof (barrier_opt_names) / sizeof (struct asm_barrier_opt);
25972 i++)
d3ce72d0 25973 hash_insert (arm_barrier_opt_hsh, barrier_opt_names[i].template_name,
5a49b8ac 25974 (void *) (barrier_opt_names + i));
c19d1205 25975#ifdef OBJ_ELF
3da1d841
NC
25976 for (i = 0; i < ARRAY_SIZE (reloc_names); i++)
25977 {
25978 struct reloc_entry * entry = reloc_names + i;
25979
25980 if (arm_is_eabi() && entry->reloc == BFD_RELOC_ARM_PLT32)
25981 /* This makes encode_branch() use the EABI versions of this relocation. */
25982 entry->reloc = BFD_RELOC_UNUSED;
25983
25984 hash_insert (arm_reloc_hsh, entry->name, (void *) entry);
25985 }
c19d1205
ZW
25986#endif
25987
25988 set_constant_flonums ();
404ff6b5 25989
c19d1205
ZW
25990 /* Set the cpu variant based on the command-line options. We prefer
25991 -mcpu= over -march= if both are set (as for GCC); and we prefer
25992 -mfpu= over any other way of setting the floating point unit.
25993 Use of legacy options with new options are faulted. */
e74cfd16 25994 if (legacy_cpu)
404ff6b5 25995 {
e74cfd16 25996 if (mcpu_cpu_opt || march_cpu_opt)
c19d1205
ZW
25997 as_bad (_("use of old and new-style options to set CPU type"));
25998
4d354d8b 25999 selected_arch = *legacy_cpu;
404ff6b5 26000 }
4d354d8b
TP
26001 else if (mcpu_cpu_opt)
26002 {
26003 selected_arch = *mcpu_cpu_opt;
26004 selected_ext = *mcpu_ext_opt;
26005 }
26006 else if (march_cpu_opt)
c168ce07 26007 {
4d354d8b
TP
26008 selected_arch = *march_cpu_opt;
26009 selected_ext = *march_ext_opt;
c168ce07 26010 }
4d354d8b 26011 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
404ff6b5 26012
e74cfd16 26013 if (legacy_fpu)
c19d1205 26014 {
e74cfd16 26015 if (mfpu_opt)
c19d1205 26016 as_bad (_("use of old and new-style options to set FPU type"));
03b1477f 26017
4d354d8b 26018 selected_fpu = *legacy_fpu;
03b1477f 26019 }
4d354d8b
TP
26020 else if (mfpu_opt)
26021 selected_fpu = *mfpu_opt;
26022 else
03b1477f 26023 {
45eb4c1b
NS
26024#if !(defined (EABI_DEFAULT) || defined (TE_LINUX) \
26025 || defined (TE_NetBSD) || defined (TE_VXWORKS))
39c2da32
RE
26026 /* Some environments specify a default FPU. If they don't, infer it
26027 from the processor. */
e74cfd16 26028 if (mcpu_fpu_opt)
4d354d8b 26029 selected_fpu = *mcpu_fpu_opt;
e7da50fa 26030 else if (march_fpu_opt)
4d354d8b 26031 selected_fpu = *march_fpu_opt;
39c2da32 26032#else
4d354d8b 26033 selected_fpu = fpu_default;
39c2da32 26034#endif
03b1477f
RE
26035 }
26036
4d354d8b 26037 if (ARM_FEATURE_ZERO (selected_fpu))
03b1477f 26038 {
4d354d8b
TP
26039 if (!no_cpu_selected ())
26040 selected_fpu = fpu_default;
03b1477f 26041 else
4d354d8b 26042 selected_fpu = fpu_arch_fpa;
03b1477f
RE
26043 }
26044
ee065d83 26045#ifdef CPU_DEFAULT
4d354d8b 26046 if (ARM_FEATURE_ZERO (selected_arch))
ee065d83 26047 {
4d354d8b
TP
26048 selected_arch = cpu_default;
26049 selected_cpu = selected_arch;
ee065d83 26050 }
4d354d8b 26051 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
e74cfd16 26052#else
4d354d8b
TP
26053 /* Autodection of feature mode: allow all features in cpu_variant but leave
26054 selected_cpu unset. It will be set in aeabi_set_public_attributes ()
26055 after all instruction have been processed and we can decide what CPU
26056 should be selected. */
26057 if (ARM_FEATURE_ZERO (selected_arch))
26058 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
ee065d83 26059 else
4d354d8b 26060 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83 26061#endif
03b1477f 26062
3e9e4fcf
JB
26063 autoselect_thumb_from_cpu_variant ();
26064
e74cfd16 26065 arm_arch_used = thumb_arch_used = arm_arch_none;
ee065d83 26066
f17c130b 26067#if defined OBJ_COFF || defined OBJ_ELF
b99bd4ef 26068 {
7cc69913
NC
26069 unsigned int flags = 0;
26070
26071#if defined OBJ_ELF
26072 flags = meabi_flags;
d507cf36
PB
26073
26074 switch (meabi_flags)
33a392fb 26075 {
d507cf36 26076 case EF_ARM_EABI_UNKNOWN:
7cc69913 26077#endif
d507cf36
PB
26078 /* Set the flags in the private structure. */
26079 if (uses_apcs_26) flags |= F_APCS26;
26080 if (support_interwork) flags |= F_INTERWORK;
26081 if (uses_apcs_float) flags |= F_APCS_FLOAT;
c19d1205 26082 if (pic_code) flags |= F_PIC;
e74cfd16 26083 if (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_any_hard))
7cc69913
NC
26084 flags |= F_SOFT_FLOAT;
26085
d507cf36
PB
26086 switch (mfloat_abi_opt)
26087 {
26088 case ARM_FLOAT_ABI_SOFT:
26089 case ARM_FLOAT_ABI_SOFTFP:
26090 flags |= F_SOFT_FLOAT;
26091 break;
33a392fb 26092
d507cf36
PB
26093 case ARM_FLOAT_ABI_HARD:
26094 if (flags & F_SOFT_FLOAT)
26095 as_bad (_("hard-float conflicts with specified fpu"));
26096 break;
26097 }
03b1477f 26098
e74cfd16
PB
26099 /* Using pure-endian doubles (even if soft-float). */
26100 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_endian_pure))
7cc69913 26101 flags |= F_VFP_FLOAT;
f17c130b 26102
fde78edd 26103#if defined OBJ_ELF
e74cfd16 26104 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_maverick))
d507cf36 26105 flags |= EF_ARM_MAVERICK_FLOAT;
d507cf36
PB
26106 break;
26107
8cb51566 26108 case EF_ARM_EABI_VER4:
3a4a14e9 26109 case EF_ARM_EABI_VER5:
c19d1205 26110 /* No additional flags to set. */
d507cf36
PB
26111 break;
26112
26113 default:
26114 abort ();
26115 }
7cc69913 26116#endif
b99bd4ef
NC
26117 bfd_set_private_flags (stdoutput, flags);
26118
26119 /* We have run out flags in the COFF header to encode the
26120 status of ATPCS support, so instead we create a dummy,
c19d1205 26121 empty, debug section called .arm.atpcs. */
b99bd4ef
NC
26122 if (atpcs)
26123 {
26124 asection * sec;
26125
26126 sec = bfd_make_section (stdoutput, ".arm.atpcs");
26127
26128 if (sec != NULL)
26129 {
26130 bfd_set_section_flags
26131 (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
26132 bfd_set_section_size (stdoutput, sec, 0);
26133 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
26134 }
26135 }
7cc69913 26136 }
f17c130b 26137#endif
b99bd4ef
NC
26138
26139 /* Record the CPU type as well. */
2d447fca
JM
26140 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2))
26141 mach = bfd_mach_arm_iWMMXt2;
26142 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt))
e16bb312 26143 mach = bfd_mach_arm_iWMMXt;
e74cfd16 26144 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_xscale))
b99bd4ef 26145 mach = bfd_mach_arm_XScale;
e74cfd16 26146 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_maverick))
fde78edd 26147 mach = bfd_mach_arm_ep9312;
e74cfd16 26148 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5e))
b99bd4ef 26149 mach = bfd_mach_arm_5TE;
e74cfd16 26150 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5))
b99bd4ef 26151 {
e74cfd16 26152 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
26153 mach = bfd_mach_arm_5T;
26154 else
26155 mach = bfd_mach_arm_5;
26156 }
e74cfd16 26157 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4))
b99bd4ef 26158 {
e74cfd16 26159 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
26160 mach = bfd_mach_arm_4T;
26161 else
26162 mach = bfd_mach_arm_4;
26163 }
e74cfd16 26164 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3m))
b99bd4ef 26165 mach = bfd_mach_arm_3M;
e74cfd16
PB
26166 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3))
26167 mach = bfd_mach_arm_3;
26168 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2s))
26169 mach = bfd_mach_arm_2a;
26170 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2))
26171 mach = bfd_mach_arm_2;
26172 else
26173 mach = bfd_mach_arm_unknown;
b99bd4ef
NC
26174
26175 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
26176}
26177
c19d1205 26178/* Command line processing. */
b99bd4ef 26179
c19d1205
ZW
26180/* md_parse_option
26181 Invocation line includes a switch not recognized by the base assembler.
26182 See if it's a processor-specific option.
b99bd4ef 26183
c19d1205
ZW
26184 This routine is somewhat complicated by the need for backwards
26185 compatibility (since older releases of gcc can't be changed).
26186 The new options try to make the interface as compatible as
26187 possible with GCC.
b99bd4ef 26188
c19d1205 26189 New options (supported) are:
b99bd4ef 26190
c19d1205
ZW
26191 -mcpu=<cpu name> Assemble for selected processor
26192 -march=<architecture name> Assemble for selected architecture
26193 -mfpu=<fpu architecture> Assemble for selected FPU.
26194 -EB/-mbig-endian Big-endian
26195 -EL/-mlittle-endian Little-endian
26196 -k Generate PIC code
26197 -mthumb Start in Thumb mode
26198 -mthumb-interwork Code supports ARM/Thumb interworking
b99bd4ef 26199
278df34e 26200 -m[no-]warn-deprecated Warn about deprecated features
8b2d793c 26201 -m[no-]warn-syms Warn when symbols match instructions
267bf995 26202
c19d1205 26203 For now we will also provide support for:
b99bd4ef 26204
c19d1205
ZW
26205 -mapcs-32 32-bit Program counter
26206 -mapcs-26 26-bit Program counter
26207 -macps-float Floats passed in FP registers
26208 -mapcs-reentrant Reentrant code
26209 -matpcs
26210 (sometime these will probably be replaced with -mapcs=<list of options>
26211 and -matpcs=<list of options>)
b99bd4ef 26212
c19d1205
ZW
26213 The remaining options are only supported for back-wards compatibility.
26214 Cpu variants, the arm part is optional:
26215 -m[arm]1 Currently not supported.
26216 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
26217 -m[arm]3 Arm 3 processor
26218 -m[arm]6[xx], Arm 6 processors
26219 -m[arm]7[xx][t][[d]m] Arm 7 processors
26220 -m[arm]8[10] Arm 8 processors
26221 -m[arm]9[20][tdmi] Arm 9 processors
26222 -mstrongarm[110[0]] StrongARM processors
26223 -mxscale XScale processors
26224 -m[arm]v[2345[t[e]]] Arm architectures
26225 -mall All (except the ARM1)
26226 FP variants:
26227 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
26228 -mfpe-old (No float load/store multiples)
26229 -mvfpxd VFP Single precision
26230 -mvfp All VFP
26231 -mno-fpu Disable all floating point instructions
b99bd4ef 26232
c19d1205
ZW
26233 The following CPU names are recognized:
26234 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
26235 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
26236 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
26237 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
26238 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
26239 arm10t arm10e, arm1020t, arm1020e, arm10200e,
26240 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
b99bd4ef 26241
c19d1205 26242 */
b99bd4ef 26243
c19d1205 26244const char * md_shortopts = "m:k";
b99bd4ef 26245
c19d1205
ZW
26246#ifdef ARM_BI_ENDIAN
26247#define OPTION_EB (OPTION_MD_BASE + 0)
26248#define OPTION_EL (OPTION_MD_BASE + 1)
b99bd4ef 26249#else
c19d1205
ZW
26250#if TARGET_BYTES_BIG_ENDIAN
26251#define OPTION_EB (OPTION_MD_BASE + 0)
b99bd4ef 26252#else
c19d1205
ZW
26253#define OPTION_EL (OPTION_MD_BASE + 1)
26254#endif
b99bd4ef 26255#endif
845b51d6 26256#define OPTION_FIX_V4BX (OPTION_MD_BASE + 2)
18a20338 26257#define OPTION_FDPIC (OPTION_MD_BASE + 3)
b99bd4ef 26258
c19d1205 26259struct option md_longopts[] =
b99bd4ef 26260{
c19d1205
ZW
26261#ifdef OPTION_EB
26262 {"EB", no_argument, NULL, OPTION_EB},
26263#endif
26264#ifdef OPTION_EL
26265 {"EL", no_argument, NULL, OPTION_EL},
b99bd4ef 26266#endif
845b51d6 26267 {"fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX},
18a20338
CL
26268#ifdef OBJ_ELF
26269 {"fdpic", no_argument, NULL, OPTION_FDPIC},
26270#endif
c19d1205
ZW
26271 {NULL, no_argument, NULL, 0}
26272};
b99bd4ef 26273
c19d1205 26274size_t md_longopts_size = sizeof (md_longopts);
b99bd4ef 26275
c19d1205 26276struct arm_option_table
b99bd4ef 26277{
0198d5e6
TC
26278 const char * option; /* Option name to match. */
26279 const char * help; /* Help information. */
26280 int * var; /* Variable to change. */
26281 int value; /* What to change it to. */
26282 const char * deprecated; /* If non-null, print this message. */
c19d1205 26283};
b99bd4ef 26284
c19d1205
ZW
26285struct arm_option_table arm_opts[] =
26286{
26287 {"k", N_("generate PIC code"), &pic_code, 1, NULL},
26288 {"mthumb", N_("assemble Thumb code"), &thumb_mode, 1, NULL},
26289 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
26290 &support_interwork, 1, NULL},
26291 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
26292 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
26293 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
26294 1, NULL},
26295 {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
26296 {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
26297 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
26298 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 0,
26299 NULL},
b99bd4ef 26300
c19d1205
ZW
26301 /* These are recognized by the assembler, but have no affect on code. */
26302 {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
26303 {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
278df34e
NS
26304
26305 {"mwarn-deprecated", NULL, &warn_on_deprecated, 1, NULL},
26306 {"mno-warn-deprecated", N_("do not warn on use of deprecated feature"),
26307 &warn_on_deprecated, 0, NULL},
8b2d793c
NC
26308 {"mwarn-syms", N_("warn about symbols that match instruction names [default]"), (int *) (& flag_warn_syms), TRUE, NULL},
26309 {"mno-warn-syms", N_("disable warnings about symobls that match instructions"), (int *) (& flag_warn_syms), FALSE, NULL},
e74cfd16
PB
26310 {NULL, NULL, NULL, 0, NULL}
26311};
26312
26313struct arm_legacy_option_table
26314{
0198d5e6
TC
26315 const char * option; /* Option name to match. */
26316 const arm_feature_set ** var; /* Variable to change. */
26317 const arm_feature_set value; /* What to change it to. */
26318 const char * deprecated; /* If non-null, print this message. */
e74cfd16 26319};
b99bd4ef 26320
e74cfd16
PB
26321const struct arm_legacy_option_table arm_legacy_opts[] =
26322{
c19d1205
ZW
26323 /* DON'T add any new processors to this list -- we want the whole list
26324 to go away... Add them to the processors table instead. */
e74cfd16
PB
26325 {"marm1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
26326 {"m1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
26327 {"marm2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
26328 {"m2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
26329 {"marm250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
26330 {"m250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
26331 {"marm3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
26332 {"m3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
26333 {"marm6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
26334 {"m6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
26335 {"marm600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
26336 {"m600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
26337 {"marm610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
26338 {"m610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
26339 {"marm620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
26340 {"m620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
26341 {"marm7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
26342 {"m7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
26343 {"marm70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
26344 {"m70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
26345 {"marm700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
26346 {"m700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
26347 {"marm700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
26348 {"m700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
26349 {"marm710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
26350 {"m710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
26351 {"marm710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
26352 {"m710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
26353 {"marm720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
26354 {"m720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
26355 {"marm7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
26356 {"m7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
26357 {"marm7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
26358 {"m7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
26359 {"marm7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
26360 {"m7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
26361 {"marm7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
26362 {"m7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
26363 {"marm7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
26364 {"m7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
26365 {"marm7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
26366 {"m7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
26367 {"marm7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
26368 {"m7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
26369 {"marm7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
26370 {"m7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
26371 {"marm7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
26372 {"m7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
26373 {"marm7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
26374 {"m7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
26375 {"marm710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
26376 {"m710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
26377 {"marm720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
26378 {"m720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
26379 {"marm740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
26380 {"m740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
26381 {"marm8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
26382 {"m8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
26383 {"marm810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
26384 {"m810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
26385 {"marm9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
26386 {"m9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
26387 {"marm9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
26388 {"m9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
26389 {"marm920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
26390 {"m920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
26391 {"marm940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
26392 {"m940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
26393 {"mstrongarm", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")},
26394 {"mstrongarm110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 26395 N_("use -mcpu=strongarm110")},
e74cfd16 26396 {"mstrongarm1100", &legacy_cpu, ARM_ARCH_V4,
c19d1205 26397 N_("use -mcpu=strongarm1100")},
e74cfd16 26398 {"mstrongarm1110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 26399 N_("use -mcpu=strongarm1110")},
e74cfd16
PB
26400 {"mxscale", &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
26401 {"miwmmxt", &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
26402 {"mall", &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
7ed4c4c5 26403
c19d1205 26404 /* Architecture variants -- don't add any more to this list either. */
e74cfd16
PB
26405 {"mv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
26406 {"marmv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
26407 {"mv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
26408 {"marmv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
26409 {"mv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
26410 {"marmv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
26411 {"mv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
26412 {"marmv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
26413 {"mv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
26414 {"marmv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
26415 {"mv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
26416 {"marmv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
26417 {"mv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
26418 {"marmv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
26419 {"mv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
26420 {"marmv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
26421 {"mv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
26422 {"marmv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
7ed4c4c5 26423
c19d1205 26424 /* Floating point variants -- don't add any more to this list either. */
0198d5e6
TC
26425 {"mfpe-old", &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
26426 {"mfpa10", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
26427 {"mfpa11", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
26428 {"mno-fpu", &legacy_fpu, ARM_ARCH_NONE,
c19d1205 26429 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
7ed4c4c5 26430
e74cfd16 26431 {NULL, NULL, ARM_ARCH_NONE, NULL}
c19d1205 26432};
7ed4c4c5 26433
c19d1205 26434struct arm_cpu_option_table
7ed4c4c5 26435{
0198d5e6
TC
26436 const char * name;
26437 size_t name_len;
26438 const arm_feature_set value;
26439 const arm_feature_set ext;
c19d1205
ZW
26440 /* For some CPUs we assume an FPU unless the user explicitly sets
26441 -mfpu=... */
0198d5e6 26442 const arm_feature_set default_fpu;
ee065d83
PB
26443 /* The canonical name of the CPU, or NULL to use NAME converted to upper
26444 case. */
0198d5e6 26445 const char * canonical_name;
c19d1205 26446};
7ed4c4c5 26447
c19d1205
ZW
26448/* This list should, at a minimum, contain all the cpu names
26449 recognized by GCC. */
996b5569 26450#define ARM_CPU_OPT(N, CN, V, E, DF) { N, sizeof (N) - 1, V, E, DF, CN }
0198d5e6 26451
e74cfd16 26452static const struct arm_cpu_option_table arm_cpus[] =
c19d1205 26453{
996b5569
TP
26454 ARM_CPU_OPT ("all", NULL, ARM_ANY,
26455 ARM_ARCH_NONE,
26456 FPU_ARCH_FPA),
26457 ARM_CPU_OPT ("arm1", NULL, ARM_ARCH_V1,
26458 ARM_ARCH_NONE,
26459 FPU_ARCH_FPA),
26460 ARM_CPU_OPT ("arm2", NULL, ARM_ARCH_V2,
26461 ARM_ARCH_NONE,
26462 FPU_ARCH_FPA),
26463 ARM_CPU_OPT ("arm250", NULL, ARM_ARCH_V2S,
26464 ARM_ARCH_NONE,
26465 FPU_ARCH_FPA),
26466 ARM_CPU_OPT ("arm3", NULL, ARM_ARCH_V2S,
26467 ARM_ARCH_NONE,
26468 FPU_ARCH_FPA),
26469 ARM_CPU_OPT ("arm6", NULL, ARM_ARCH_V3,
26470 ARM_ARCH_NONE,
26471 FPU_ARCH_FPA),
26472 ARM_CPU_OPT ("arm60", NULL, ARM_ARCH_V3,
26473 ARM_ARCH_NONE,
26474 FPU_ARCH_FPA),
26475 ARM_CPU_OPT ("arm600", NULL, ARM_ARCH_V3,
26476 ARM_ARCH_NONE,
26477 FPU_ARCH_FPA),
26478 ARM_CPU_OPT ("arm610", NULL, ARM_ARCH_V3,
26479 ARM_ARCH_NONE,
26480 FPU_ARCH_FPA),
26481 ARM_CPU_OPT ("arm620", NULL, ARM_ARCH_V3,
26482 ARM_ARCH_NONE,
26483 FPU_ARCH_FPA),
26484 ARM_CPU_OPT ("arm7", NULL, ARM_ARCH_V3,
26485 ARM_ARCH_NONE,
26486 FPU_ARCH_FPA),
26487 ARM_CPU_OPT ("arm7m", NULL, ARM_ARCH_V3M,
26488 ARM_ARCH_NONE,
26489 FPU_ARCH_FPA),
26490 ARM_CPU_OPT ("arm7d", NULL, ARM_ARCH_V3,
26491 ARM_ARCH_NONE,
26492 FPU_ARCH_FPA),
26493 ARM_CPU_OPT ("arm7dm", NULL, ARM_ARCH_V3M,
26494 ARM_ARCH_NONE,
26495 FPU_ARCH_FPA),
26496 ARM_CPU_OPT ("arm7di", NULL, ARM_ARCH_V3,
26497 ARM_ARCH_NONE,
26498 FPU_ARCH_FPA),
26499 ARM_CPU_OPT ("arm7dmi", NULL, ARM_ARCH_V3M,
26500 ARM_ARCH_NONE,
26501 FPU_ARCH_FPA),
26502 ARM_CPU_OPT ("arm70", NULL, ARM_ARCH_V3,
26503 ARM_ARCH_NONE,
26504 FPU_ARCH_FPA),
26505 ARM_CPU_OPT ("arm700", NULL, ARM_ARCH_V3,
26506 ARM_ARCH_NONE,
26507 FPU_ARCH_FPA),
26508 ARM_CPU_OPT ("arm700i", NULL, ARM_ARCH_V3,
26509 ARM_ARCH_NONE,
26510 FPU_ARCH_FPA),
26511 ARM_CPU_OPT ("arm710", NULL, ARM_ARCH_V3,
26512 ARM_ARCH_NONE,
26513 FPU_ARCH_FPA),
26514 ARM_CPU_OPT ("arm710t", NULL, ARM_ARCH_V4T,
26515 ARM_ARCH_NONE,
26516 FPU_ARCH_FPA),
26517 ARM_CPU_OPT ("arm720", NULL, ARM_ARCH_V3,
26518 ARM_ARCH_NONE,
26519 FPU_ARCH_FPA),
26520 ARM_CPU_OPT ("arm720t", NULL, ARM_ARCH_V4T,
26521 ARM_ARCH_NONE,
26522 FPU_ARCH_FPA),
26523 ARM_CPU_OPT ("arm740t", NULL, ARM_ARCH_V4T,
26524 ARM_ARCH_NONE,
26525 FPU_ARCH_FPA),
26526 ARM_CPU_OPT ("arm710c", NULL, ARM_ARCH_V3,
26527 ARM_ARCH_NONE,
26528 FPU_ARCH_FPA),
26529 ARM_CPU_OPT ("arm7100", NULL, ARM_ARCH_V3,
26530 ARM_ARCH_NONE,
26531 FPU_ARCH_FPA),
26532 ARM_CPU_OPT ("arm7500", NULL, ARM_ARCH_V3,
26533 ARM_ARCH_NONE,
26534 FPU_ARCH_FPA),
26535 ARM_CPU_OPT ("arm7500fe", NULL, ARM_ARCH_V3,
26536 ARM_ARCH_NONE,
26537 FPU_ARCH_FPA),
26538 ARM_CPU_OPT ("arm7t", NULL, ARM_ARCH_V4T,
26539 ARM_ARCH_NONE,
26540 FPU_ARCH_FPA),
26541 ARM_CPU_OPT ("arm7tdmi", NULL, ARM_ARCH_V4T,
26542 ARM_ARCH_NONE,
26543 FPU_ARCH_FPA),
26544 ARM_CPU_OPT ("arm7tdmi-s", NULL, ARM_ARCH_V4T,
26545 ARM_ARCH_NONE,
26546 FPU_ARCH_FPA),
26547 ARM_CPU_OPT ("arm8", NULL, ARM_ARCH_V4,
26548 ARM_ARCH_NONE,
26549 FPU_ARCH_FPA),
26550 ARM_CPU_OPT ("arm810", NULL, ARM_ARCH_V4,
26551 ARM_ARCH_NONE,
26552 FPU_ARCH_FPA),
26553 ARM_CPU_OPT ("strongarm", NULL, ARM_ARCH_V4,
26554 ARM_ARCH_NONE,
26555 FPU_ARCH_FPA),
26556 ARM_CPU_OPT ("strongarm1", NULL, ARM_ARCH_V4,
26557 ARM_ARCH_NONE,
26558 FPU_ARCH_FPA),
26559 ARM_CPU_OPT ("strongarm110", NULL, ARM_ARCH_V4,
26560 ARM_ARCH_NONE,
26561 FPU_ARCH_FPA),
26562 ARM_CPU_OPT ("strongarm1100", NULL, ARM_ARCH_V4,
26563 ARM_ARCH_NONE,
26564 FPU_ARCH_FPA),
26565 ARM_CPU_OPT ("strongarm1110", NULL, ARM_ARCH_V4,
26566 ARM_ARCH_NONE,
26567 FPU_ARCH_FPA),
26568 ARM_CPU_OPT ("arm9", NULL, ARM_ARCH_V4T,
26569 ARM_ARCH_NONE,
26570 FPU_ARCH_FPA),
26571 ARM_CPU_OPT ("arm920", "ARM920T", ARM_ARCH_V4T,
26572 ARM_ARCH_NONE,
26573 FPU_ARCH_FPA),
26574 ARM_CPU_OPT ("arm920t", NULL, ARM_ARCH_V4T,
26575 ARM_ARCH_NONE,
26576 FPU_ARCH_FPA),
26577 ARM_CPU_OPT ("arm922t", NULL, ARM_ARCH_V4T,
26578 ARM_ARCH_NONE,
26579 FPU_ARCH_FPA),
26580 ARM_CPU_OPT ("arm940t", NULL, ARM_ARCH_V4T,
26581 ARM_ARCH_NONE,
26582 FPU_ARCH_FPA),
26583 ARM_CPU_OPT ("arm9tdmi", NULL, ARM_ARCH_V4T,
26584 ARM_ARCH_NONE,
26585 FPU_ARCH_FPA),
26586 ARM_CPU_OPT ("fa526", NULL, ARM_ARCH_V4,
26587 ARM_ARCH_NONE,
26588 FPU_ARCH_FPA),
26589 ARM_CPU_OPT ("fa626", NULL, ARM_ARCH_V4,
26590 ARM_ARCH_NONE,
26591 FPU_ARCH_FPA),
26592
c19d1205
ZW
26593 /* For V5 or later processors we default to using VFP; but the user
26594 should really set the FPU type explicitly. */
996b5569
TP
26595 ARM_CPU_OPT ("arm9e-r0", NULL, ARM_ARCH_V5TExP,
26596 ARM_ARCH_NONE,
26597 FPU_ARCH_VFP_V2),
26598 ARM_CPU_OPT ("arm9e", NULL, ARM_ARCH_V5TE,
26599 ARM_ARCH_NONE,
26600 FPU_ARCH_VFP_V2),
26601 ARM_CPU_OPT ("arm926ej", "ARM926EJ-S", ARM_ARCH_V5TEJ,
26602 ARM_ARCH_NONE,
26603 FPU_ARCH_VFP_V2),
26604 ARM_CPU_OPT ("arm926ejs", "ARM926EJ-S", ARM_ARCH_V5TEJ,
26605 ARM_ARCH_NONE,
26606 FPU_ARCH_VFP_V2),
26607 ARM_CPU_OPT ("arm926ej-s", NULL, ARM_ARCH_V5TEJ,
26608 ARM_ARCH_NONE,
26609 FPU_ARCH_VFP_V2),
26610 ARM_CPU_OPT ("arm946e-r0", NULL, ARM_ARCH_V5TExP,
26611 ARM_ARCH_NONE,
26612 FPU_ARCH_VFP_V2),
26613 ARM_CPU_OPT ("arm946e", "ARM946E-S", ARM_ARCH_V5TE,
26614 ARM_ARCH_NONE,
26615 FPU_ARCH_VFP_V2),
26616 ARM_CPU_OPT ("arm946e-s", NULL, ARM_ARCH_V5TE,
26617 ARM_ARCH_NONE,
26618 FPU_ARCH_VFP_V2),
26619 ARM_CPU_OPT ("arm966e-r0", NULL, ARM_ARCH_V5TExP,
26620 ARM_ARCH_NONE,
26621 FPU_ARCH_VFP_V2),
26622 ARM_CPU_OPT ("arm966e", "ARM966E-S", ARM_ARCH_V5TE,
26623 ARM_ARCH_NONE,
26624 FPU_ARCH_VFP_V2),
26625 ARM_CPU_OPT ("arm966e-s", NULL, ARM_ARCH_V5TE,
26626 ARM_ARCH_NONE,
26627 FPU_ARCH_VFP_V2),
26628 ARM_CPU_OPT ("arm968e-s", NULL, ARM_ARCH_V5TE,
26629 ARM_ARCH_NONE,
26630 FPU_ARCH_VFP_V2),
26631 ARM_CPU_OPT ("arm10t", NULL, ARM_ARCH_V5T,
26632 ARM_ARCH_NONE,
26633 FPU_ARCH_VFP_V1),
26634 ARM_CPU_OPT ("arm10tdmi", NULL, ARM_ARCH_V5T,
26635 ARM_ARCH_NONE,
26636 FPU_ARCH_VFP_V1),
26637 ARM_CPU_OPT ("arm10e", NULL, ARM_ARCH_V5TE,
26638 ARM_ARCH_NONE,
26639 FPU_ARCH_VFP_V2),
26640 ARM_CPU_OPT ("arm1020", "ARM1020E", ARM_ARCH_V5TE,
26641 ARM_ARCH_NONE,
26642 FPU_ARCH_VFP_V2),
26643 ARM_CPU_OPT ("arm1020t", NULL, ARM_ARCH_V5T,
26644 ARM_ARCH_NONE,
26645 FPU_ARCH_VFP_V1),
26646 ARM_CPU_OPT ("arm1020e", NULL, ARM_ARCH_V5TE,
26647 ARM_ARCH_NONE,
26648 FPU_ARCH_VFP_V2),
26649 ARM_CPU_OPT ("arm1022e", NULL, ARM_ARCH_V5TE,
26650 ARM_ARCH_NONE,
26651 FPU_ARCH_VFP_V2),
26652 ARM_CPU_OPT ("arm1026ejs", "ARM1026EJ-S", ARM_ARCH_V5TEJ,
26653 ARM_ARCH_NONE,
26654 FPU_ARCH_VFP_V2),
26655 ARM_CPU_OPT ("arm1026ej-s", NULL, ARM_ARCH_V5TEJ,
26656 ARM_ARCH_NONE,
26657 FPU_ARCH_VFP_V2),
26658 ARM_CPU_OPT ("fa606te", NULL, ARM_ARCH_V5TE,
26659 ARM_ARCH_NONE,
26660 FPU_ARCH_VFP_V2),
26661 ARM_CPU_OPT ("fa616te", NULL, ARM_ARCH_V5TE,
26662 ARM_ARCH_NONE,
26663 FPU_ARCH_VFP_V2),
26664 ARM_CPU_OPT ("fa626te", NULL, ARM_ARCH_V5TE,
26665 ARM_ARCH_NONE,
26666 FPU_ARCH_VFP_V2),
26667 ARM_CPU_OPT ("fmp626", NULL, ARM_ARCH_V5TE,
26668 ARM_ARCH_NONE,
26669 FPU_ARCH_VFP_V2),
26670 ARM_CPU_OPT ("fa726te", NULL, ARM_ARCH_V5TE,
26671 ARM_ARCH_NONE,
26672 FPU_ARCH_VFP_V2),
26673 ARM_CPU_OPT ("arm1136js", "ARM1136J-S", ARM_ARCH_V6,
26674 ARM_ARCH_NONE,
26675 FPU_NONE),
26676 ARM_CPU_OPT ("arm1136j-s", NULL, ARM_ARCH_V6,
26677 ARM_ARCH_NONE,
26678 FPU_NONE),
26679 ARM_CPU_OPT ("arm1136jfs", "ARM1136JF-S", ARM_ARCH_V6,
26680 ARM_ARCH_NONE,
26681 FPU_ARCH_VFP_V2),
26682 ARM_CPU_OPT ("arm1136jf-s", NULL, ARM_ARCH_V6,
26683 ARM_ARCH_NONE,
26684 FPU_ARCH_VFP_V2),
26685 ARM_CPU_OPT ("mpcore", "MPCore", ARM_ARCH_V6K,
26686 ARM_ARCH_NONE,
26687 FPU_ARCH_VFP_V2),
26688 ARM_CPU_OPT ("mpcorenovfp", "MPCore", ARM_ARCH_V6K,
26689 ARM_ARCH_NONE,
26690 FPU_NONE),
26691 ARM_CPU_OPT ("arm1156t2-s", NULL, ARM_ARCH_V6T2,
26692 ARM_ARCH_NONE,
26693 FPU_NONE),
26694 ARM_CPU_OPT ("arm1156t2f-s", NULL, ARM_ARCH_V6T2,
26695 ARM_ARCH_NONE,
26696 FPU_ARCH_VFP_V2),
26697 ARM_CPU_OPT ("arm1176jz-s", NULL, ARM_ARCH_V6KZ,
26698 ARM_ARCH_NONE,
26699 FPU_NONE),
26700 ARM_CPU_OPT ("arm1176jzf-s", NULL, ARM_ARCH_V6KZ,
26701 ARM_ARCH_NONE,
26702 FPU_ARCH_VFP_V2),
26703 ARM_CPU_OPT ("cortex-a5", "Cortex-A5", ARM_ARCH_V7A,
26704 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
26705 FPU_NONE),
26706 ARM_CPU_OPT ("cortex-a7", "Cortex-A7", ARM_ARCH_V7VE,
26707 ARM_ARCH_NONE,
26708 FPU_ARCH_NEON_VFP_V4),
26709 ARM_CPU_OPT ("cortex-a8", "Cortex-A8", ARM_ARCH_V7A,
26710 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
26711 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
26712 ARM_CPU_OPT ("cortex-a9", "Cortex-A9", ARM_ARCH_V7A,
26713 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
26714 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
26715 ARM_CPU_OPT ("cortex-a12", "Cortex-A12", ARM_ARCH_V7VE,
26716 ARM_ARCH_NONE,
26717 FPU_ARCH_NEON_VFP_V4),
26718 ARM_CPU_OPT ("cortex-a15", "Cortex-A15", ARM_ARCH_V7VE,
26719 ARM_ARCH_NONE,
26720 FPU_ARCH_NEON_VFP_V4),
26721 ARM_CPU_OPT ("cortex-a17", "Cortex-A17", ARM_ARCH_V7VE,
26722 ARM_ARCH_NONE,
26723 FPU_ARCH_NEON_VFP_V4),
26724 ARM_CPU_OPT ("cortex-a32", "Cortex-A32", ARM_ARCH_V8A,
26725 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26726 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
26727 ARM_CPU_OPT ("cortex-a35", "Cortex-A35", ARM_ARCH_V8A,
26728 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26729 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
26730 ARM_CPU_OPT ("cortex-a53", "Cortex-A53", ARM_ARCH_V8A,
26731 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26732 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
26733 ARM_CPU_OPT ("cortex-a55", "Cortex-A55", ARM_ARCH_V8_2A,
26734 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 26735 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569
TP
26736 ARM_CPU_OPT ("cortex-a57", "Cortex-A57", ARM_ARCH_V8A,
26737 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26738 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
26739 ARM_CPU_OPT ("cortex-a72", "Cortex-A72", ARM_ARCH_V8A,
26740 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26741 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
26742 ARM_CPU_OPT ("cortex-a73", "Cortex-A73", ARM_ARCH_V8A,
26743 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26744 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
26745 ARM_CPU_OPT ("cortex-a75", "Cortex-A75", ARM_ARCH_V8_2A,
26746 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 26747 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
7ebd1359 26748 ARM_CPU_OPT ("cortex-a76", "Cortex-A76", ARM_ARCH_V8_2A,
26749 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
26750 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
ef8df4ca
KT
26751 ARM_CPU_OPT ("ares", "Ares", ARM_ARCH_V8_2A,
26752 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
26753 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569
TP
26754 ARM_CPU_OPT ("cortex-r4", "Cortex-R4", ARM_ARCH_V7R,
26755 ARM_ARCH_NONE,
26756 FPU_NONE),
26757 ARM_CPU_OPT ("cortex-r4f", "Cortex-R4F", ARM_ARCH_V7R,
26758 ARM_ARCH_NONE,
26759 FPU_ARCH_VFP_V3D16),
26760 ARM_CPU_OPT ("cortex-r5", "Cortex-R5", ARM_ARCH_V7R,
26761 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
26762 FPU_NONE),
26763 ARM_CPU_OPT ("cortex-r7", "Cortex-R7", ARM_ARCH_V7R,
26764 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
26765 FPU_ARCH_VFP_V3D16),
26766 ARM_CPU_OPT ("cortex-r8", "Cortex-R8", ARM_ARCH_V7R,
26767 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
26768 FPU_ARCH_VFP_V3D16),
0cda1e19
TP
26769 ARM_CPU_OPT ("cortex-r52", "Cortex-R52", ARM_ARCH_V8R,
26770 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26771 FPU_ARCH_NEON_VFP_ARMV8),
996b5569
TP
26772 ARM_CPU_OPT ("cortex-m33", "Cortex-M33", ARM_ARCH_V8M_MAIN,
26773 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
26774 FPU_NONE),
26775 ARM_CPU_OPT ("cortex-m23", "Cortex-M23", ARM_ARCH_V8M_BASE,
26776 ARM_ARCH_NONE,
26777 FPU_NONE),
26778 ARM_CPU_OPT ("cortex-m7", "Cortex-M7", ARM_ARCH_V7EM,
26779 ARM_ARCH_NONE,
26780 FPU_NONE),
26781 ARM_CPU_OPT ("cortex-m4", "Cortex-M4", ARM_ARCH_V7EM,
26782 ARM_ARCH_NONE,
26783 FPU_NONE),
26784 ARM_CPU_OPT ("cortex-m3", "Cortex-M3", ARM_ARCH_V7M,
26785 ARM_ARCH_NONE,
26786 FPU_NONE),
26787 ARM_CPU_OPT ("cortex-m1", "Cortex-M1", ARM_ARCH_V6SM,
26788 ARM_ARCH_NONE,
26789 FPU_NONE),
26790 ARM_CPU_OPT ("cortex-m0", "Cortex-M0", ARM_ARCH_V6SM,
26791 ARM_ARCH_NONE,
26792 FPU_NONE),
26793 ARM_CPU_OPT ("cortex-m0plus", "Cortex-M0+", ARM_ARCH_V6SM,
26794 ARM_ARCH_NONE,
26795 FPU_NONE),
26796 ARM_CPU_OPT ("exynos-m1", "Samsung Exynos M1", ARM_ARCH_V8A,
26797 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26798 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
83f43c83
KT
26799 ARM_CPU_OPT ("neoverse-n1", "Neoverse N1", ARM_ARCH_V8_2A,
26800 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
26801 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
c19d1205 26802 /* ??? XSCALE is really an architecture. */
996b5569
TP
26803 ARM_CPU_OPT ("xscale", NULL, ARM_ARCH_XSCALE,
26804 ARM_ARCH_NONE,
26805 FPU_ARCH_VFP_V2),
26806
c19d1205 26807 /* ??? iwmmxt is not a processor. */
996b5569
TP
26808 ARM_CPU_OPT ("iwmmxt", NULL, ARM_ARCH_IWMMXT,
26809 ARM_ARCH_NONE,
26810 FPU_ARCH_VFP_V2),
26811 ARM_CPU_OPT ("iwmmxt2", NULL, ARM_ARCH_IWMMXT2,
26812 ARM_ARCH_NONE,
26813 FPU_ARCH_VFP_V2),
26814 ARM_CPU_OPT ("i80200", NULL, ARM_ARCH_XSCALE,
26815 ARM_ARCH_NONE,
26816 FPU_ARCH_VFP_V2),
26817
0198d5e6 26818 /* Maverick. */
996b5569
TP
26819 ARM_CPU_OPT ("ep9312", "ARM920T",
26820 ARM_FEATURE_LOW (ARM_AEXT_V4T, ARM_CEXT_MAVERICK),
26821 ARM_ARCH_NONE, FPU_ARCH_MAVERICK),
26822
da4339ed 26823 /* Marvell processors. */
996b5569
TP
26824 ARM_CPU_OPT ("marvell-pj4", NULL, ARM_ARCH_V7A,
26825 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
26826 FPU_ARCH_VFP_V3D16),
26827 ARM_CPU_OPT ("marvell-whitney", NULL, ARM_ARCH_V7A,
26828 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
26829 FPU_ARCH_NEON_VFP_V4),
da4339ed 26830
996b5569
TP
26831 /* APM X-Gene family. */
26832 ARM_CPU_OPT ("xgene1", "APM X-Gene 1", ARM_ARCH_V8A,
26833 ARM_ARCH_NONE,
26834 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
26835 ARM_CPU_OPT ("xgene2", "APM X-Gene 2", ARM_ARCH_V8A,
26836 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26837 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
26838
26839 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 26840};
f3bad469 26841#undef ARM_CPU_OPT
7ed4c4c5 26842
34ef62f4
AV
26843struct arm_ext_table
26844{
26845 const char * name;
26846 size_t name_len;
26847 const arm_feature_set merge;
26848 const arm_feature_set clear;
26849};
26850
c19d1205 26851struct arm_arch_option_table
7ed4c4c5 26852{
34ef62f4
AV
26853 const char * name;
26854 size_t name_len;
26855 const arm_feature_set value;
26856 const arm_feature_set default_fpu;
26857 const struct arm_ext_table * ext_table;
26858};
26859
26860/* Used to add support for +E and +noE extension. */
26861#define ARM_EXT(E, M, C) { E, sizeof (E) - 1, M, C }
26862/* Used to add support for a +E extension. */
26863#define ARM_ADD(E, M) { E, sizeof(E) - 1, M, ARM_ARCH_NONE }
26864/* Used to add support for a +noE extension. */
26865#define ARM_REMOVE(E, C) { E, sizeof(E) -1, ARM_ARCH_NONE, C }
26866
26867#define ALL_FP ARM_FEATURE (0, ARM_EXT2_FP16_INST | ARM_EXT2_FP16_FML, \
26868 ~0 & ~FPU_ENDIAN_PURE)
26869
26870static const struct arm_ext_table armv5te_ext_table[] =
26871{
26872 ARM_EXT ("fp", FPU_ARCH_VFP_V2, ALL_FP),
26873 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
26874};
26875
26876static const struct arm_ext_table armv7_ext_table[] =
26877{
26878 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
26879 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
26880};
26881
26882static const struct arm_ext_table armv7ve_ext_table[] =
26883{
26884 ARM_EXT ("fp", FPU_ARCH_VFP_V4D16, ALL_FP),
26885 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16),
26886 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
26887 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
26888 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
26889 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16), /* Alias for +fp. */
26890 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
26891
26892 ARM_EXT ("simd", FPU_ARCH_NEON_VFP_V4,
26893 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
26894
26895 /* Aliases for +simd. */
26896 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
26897
26898 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
26899 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
26900 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
26901
26902 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
26903};
26904
26905static const struct arm_ext_table armv7a_ext_table[] =
26906{
26907 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
26908 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
26909 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
26910 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
26911 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
26912 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16),
26913 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
26914
26915 ARM_EXT ("simd", FPU_ARCH_VFP_V3_PLUS_NEON_V1,
26916 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
26917
26918 /* Aliases for +simd. */
26919 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
26920 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
26921
26922 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
26923 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
26924
26925 ARM_ADD ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP)),
26926 ARM_ADD ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC)),
26927 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
26928};
26929
26930static const struct arm_ext_table armv7r_ext_table[] =
26931{
26932 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V3xD),
26933 ARM_ADD ("vfpv3xd", FPU_ARCH_VFP_V3xD), /* Alias for +fp.sp. */
26934 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
26935 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
26936 ARM_ADD ("vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16),
26937 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
26938 ARM_EXT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
26939 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV)),
26940 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
26941};
26942
26943static const struct arm_ext_table armv7em_ext_table[] =
26944{
26945 ARM_EXT ("fp", FPU_ARCH_VFP_V4_SP_D16, ALL_FP),
26946 /* Alias for +fp, used to be known as fpv4-sp-d16. */
26947 ARM_ADD ("vfpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16),
26948 ARM_ADD ("fpv5", FPU_ARCH_VFP_V5_SP_D16),
26949 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
26950 ARM_ADD ("fpv5-d16", FPU_ARCH_VFP_V5D16),
26951 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
26952};
26953
26954static const struct arm_ext_table armv8a_ext_table[] =
26955{
26956 ARM_ADD ("crc", ARCH_CRC_ARMV8),
26957 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
26958 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
26959 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
26960
26961 /* Armv8-a does not allow an FP implementation without SIMD, so the user
26962 should use the +simd option to turn on FP. */
26963 ARM_REMOVE ("fp", ALL_FP),
26964 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
26965 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
26966 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
26967};
26968
26969
26970static const struct arm_ext_table armv81a_ext_table[] =
26971{
26972 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
26973 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
26974 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
26975
26976 /* Armv8-a does not allow an FP implementation without SIMD, so the user
26977 should use the +simd option to turn on FP. */
26978 ARM_REMOVE ("fp", ALL_FP),
26979 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
26980 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
26981 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
26982};
26983
26984static const struct arm_ext_table armv82a_ext_table[] =
26985{
26986 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
26987 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_2_FP16),
26988 ARM_ADD ("fp16fml", FPU_ARCH_NEON_VFP_ARMV8_2_FP16FML),
26989 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
26990 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
26991 ARM_ADD ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
26992
26993 /* Armv8-a does not allow an FP implementation without SIMD, so the user
26994 should use the +simd option to turn on FP. */
26995 ARM_REMOVE ("fp", ALL_FP),
26996 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
26997 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
26998 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
26999};
27000
27001static const struct arm_ext_table armv84a_ext_table[] =
27002{
27003 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
27004 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
27005 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
27006 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
27007
27008 /* Armv8-a does not allow an FP implementation without SIMD, so the user
27009 should use the +simd option to turn on FP. */
27010 ARM_REMOVE ("fp", ALL_FP),
27011 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
27012 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
27013 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27014};
27015
27016static const struct arm_ext_table armv85a_ext_table[] =
27017{
27018 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
27019 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
27020 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
27021 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
27022
27023 /* Armv8-a does not allow an FP implementation without SIMD, so the user
27024 should use the +simd option to turn on FP. */
27025 ARM_REMOVE ("fp", ALL_FP),
27026 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27027};
27028
27029static const struct arm_ext_table armv8m_main_ext_table[] =
27030{
27031 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
27032 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP)),
27033 ARM_EXT ("fp", FPU_ARCH_VFP_V5_SP_D16, ALL_FP),
27034 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
27035 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27036};
27037
e0991585
AV
27038static const struct arm_ext_table armv8_1m_main_ext_table[] =
27039{
27040 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
27041 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP)),
27042 ARM_EXT ("fp",
27043 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
27044 FPU_VFP_V5_SP_D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA),
27045 ALL_FP),
27046 ARM_ADD ("fp.dp",
27047 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
27048 FPU_VFP_V5D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
27049 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27050};
27051
34ef62f4
AV
27052static const struct arm_ext_table armv8r_ext_table[] =
27053{
27054 ARM_ADD ("crc", ARCH_CRC_ARMV8),
27055 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
27056 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
27057 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
27058 ARM_REMOVE ("fp", ALL_FP),
27059 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V5_SP_D16),
27060 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
c19d1205 27061};
7ed4c4c5 27062
c19d1205
ZW
27063/* This list should, at a minimum, contain all the architecture names
27064 recognized by GCC. */
34ef62f4
AV
27065#define ARM_ARCH_OPT(N, V, DF) { N, sizeof (N) - 1, V, DF, NULL }
27066#define ARM_ARCH_OPT2(N, V, DF, ext) \
27067 { N, sizeof (N) - 1, V, DF, ext##_ext_table }
0198d5e6 27068
e74cfd16 27069static const struct arm_arch_option_table arm_archs[] =
c19d1205 27070{
497d849d
TP
27071 ARM_ARCH_OPT ("all", ARM_ANY, FPU_ARCH_FPA),
27072 ARM_ARCH_OPT ("armv1", ARM_ARCH_V1, FPU_ARCH_FPA),
27073 ARM_ARCH_OPT ("armv2", ARM_ARCH_V2, FPU_ARCH_FPA),
27074 ARM_ARCH_OPT ("armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA),
27075 ARM_ARCH_OPT ("armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA),
27076 ARM_ARCH_OPT ("armv3", ARM_ARCH_V3, FPU_ARCH_FPA),
27077 ARM_ARCH_OPT ("armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA),
27078 ARM_ARCH_OPT ("armv4", ARM_ARCH_V4, FPU_ARCH_FPA),
27079 ARM_ARCH_OPT ("armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA),
27080 ARM_ARCH_OPT ("armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA),
27081 ARM_ARCH_OPT ("armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA),
27082 ARM_ARCH_OPT ("armv5", ARM_ARCH_V5, FPU_ARCH_VFP),
27083 ARM_ARCH_OPT ("armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP),
27084 ARM_ARCH_OPT ("armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP),
34ef62f4
AV
27085 ARM_ARCH_OPT2 ("armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP, armv5te),
27086 ARM_ARCH_OPT2 ("armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP, armv5te),
27087 ARM_ARCH_OPT2 ("armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP, armv5te),
27088 ARM_ARCH_OPT2 ("armv6", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
27089 ARM_ARCH_OPT2 ("armv6j", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
27090 ARM_ARCH_OPT2 ("armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP, armv5te),
27091 ARM_ARCH_OPT2 ("armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP, armv5te),
f33026a9
MW
27092 /* The official spelling of this variant is ARMv6KZ, the name "armv6zk" is
27093 kept to preserve existing behaviour. */
34ef62f4
AV
27094 ARM_ARCH_OPT2 ("armv6kz", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
27095 ARM_ARCH_OPT2 ("armv6zk", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
27096 ARM_ARCH_OPT2 ("armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP, armv5te),
27097 ARM_ARCH_OPT2 ("armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP, armv5te),
27098 ARM_ARCH_OPT2 ("armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP, armv5te),
f33026a9
MW
27099 /* The official spelling of this variant is ARMv6KZ, the name "armv6zkt2" is
27100 kept to preserve existing behaviour. */
34ef62f4
AV
27101 ARM_ARCH_OPT2 ("armv6kzt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
27102 ARM_ARCH_OPT2 ("armv6zkt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
497d849d
TP
27103 ARM_ARCH_OPT ("armv6-m", ARM_ARCH_V6M, FPU_ARCH_VFP),
27104 ARM_ARCH_OPT ("armv6s-m", ARM_ARCH_V6SM, FPU_ARCH_VFP),
34ef62f4 27105 ARM_ARCH_OPT2 ("armv7", ARM_ARCH_V7, FPU_ARCH_VFP, armv7),
c450d570
PB
27106 /* The official spelling of the ARMv7 profile variants is the dashed form.
27107 Accept the non-dashed form for compatibility with old toolchains. */
34ef62f4
AV
27108 ARM_ARCH_OPT2 ("armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
27109 ARM_ARCH_OPT2 ("armv7ve", ARM_ARCH_V7VE, FPU_ARCH_VFP, armv7ve),
27110 ARM_ARCH_OPT2 ("armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 27111 ARM_ARCH_OPT ("armv7m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4
AV
27112 ARM_ARCH_OPT2 ("armv7-a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
27113 ARM_ARCH_OPT2 ("armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 27114 ARM_ARCH_OPT ("armv7-m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4 27115 ARM_ARCH_OPT2 ("armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP, armv7em),
497d849d 27116 ARM_ARCH_OPT ("armv8-m.base", ARM_ARCH_V8M_BASE, FPU_ARCH_VFP),
34ef62f4
AV
27117 ARM_ARCH_OPT2 ("armv8-m.main", ARM_ARCH_V8M_MAIN, FPU_ARCH_VFP,
27118 armv8m_main),
e0991585
AV
27119 ARM_ARCH_OPT2 ("armv8.1-m.main", ARM_ARCH_V8_1M_MAIN, FPU_ARCH_VFP,
27120 armv8_1m_main),
34ef62f4
AV
27121 ARM_ARCH_OPT2 ("armv8-a", ARM_ARCH_V8A, FPU_ARCH_VFP, armv8a),
27122 ARM_ARCH_OPT2 ("armv8.1-a", ARM_ARCH_V8_1A, FPU_ARCH_VFP, armv81a),
27123 ARM_ARCH_OPT2 ("armv8.2-a", ARM_ARCH_V8_2A, FPU_ARCH_VFP, armv82a),
27124 ARM_ARCH_OPT2 ("armv8.3-a", ARM_ARCH_V8_3A, FPU_ARCH_VFP, armv82a),
27125 ARM_ARCH_OPT2 ("armv8-r", ARM_ARCH_V8R, FPU_ARCH_VFP, armv8r),
27126 ARM_ARCH_OPT2 ("armv8.4-a", ARM_ARCH_V8_4A, FPU_ARCH_VFP, armv84a),
27127 ARM_ARCH_OPT2 ("armv8.5-a", ARM_ARCH_V8_5A, FPU_ARCH_VFP, armv85a),
497d849d
TP
27128 ARM_ARCH_OPT ("xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP),
27129 ARM_ARCH_OPT ("iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP),
27130 ARM_ARCH_OPT ("iwmmxt2", ARM_ARCH_IWMMXT2, FPU_ARCH_VFP),
34ef62f4 27131 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 27132};
f3bad469 27133#undef ARM_ARCH_OPT
7ed4c4c5 27134
69133863 27135/* ISA extensions in the co-processor and main instruction set space. */
0198d5e6 27136
69133863 27137struct arm_option_extension_value_table
c19d1205 27138{
0198d5e6
TC
27139 const char * name;
27140 size_t name_len;
27141 const arm_feature_set merge_value;
27142 const arm_feature_set clear_value;
d942732e
TP
27143 /* List of architectures for which an extension is available. ARM_ARCH_NONE
27144 indicates that an extension is available for all architectures while
27145 ARM_ANY marks an empty entry. */
0198d5e6 27146 const arm_feature_set allowed_archs[2];
c19d1205 27147};
7ed4c4c5 27148
0198d5e6
TC
27149/* The following table must be in alphabetical order with a NULL last entry. */
27150
d942732e
TP
27151#define ARM_EXT_OPT(N, M, C, AA) { N, sizeof (N) - 1, M, C, { AA, ARM_ANY } }
27152#define ARM_EXT_OPT2(N, M, C, AA1, AA2) { N, sizeof (N) - 1, M, C, {AA1, AA2} }
0198d5e6 27153
34ef62f4
AV
27154/* DEPRECATED: Refrain from using this table to add any new extensions, instead
27155 use the context sensitive approach using arm_ext_table's. */
69133863 27156static const struct arm_option_extension_value_table arm_extensions[] =
c19d1205 27157{
823d2571
TG
27158 ARM_EXT_OPT ("crc", ARCH_CRC_ARMV8, ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
27159 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
bca38921 27160 ARM_EXT_OPT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
823d2571
TG
27161 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8),
27162 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
c604a79a
JW
27163 ARM_EXT_OPT ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8,
27164 ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD),
27165 ARM_ARCH_V8_2A),
15afaa63
TP
27166 ARM_EXT_OPT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
27167 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
27168 ARM_FEATURE_CORE (ARM_EXT_V7M, ARM_EXT2_V8M)),
823d2571
TG
27169 ARM_EXT_OPT ("fp", FPU_ARCH_VFP_ARMV8, ARM_FEATURE_COPROC (FPU_VFP_ARMV8),
27170 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
b8ec4e87
JW
27171 ARM_EXT_OPT ("fp16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
27172 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
27173 ARM_ARCH_V8_2A),
01f48020
TC
27174 ARM_EXT_OPT ("fp16fml", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
27175 | ARM_EXT2_FP16_FML),
27176 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
27177 | ARM_EXT2_FP16_FML),
27178 ARM_ARCH_V8_2A),
d942732e 27179 ARM_EXT_OPT2 ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
823d2571 27180 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
d942732e
TP
27181 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
27182 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
3d030cdb
TP
27183 /* Duplicate entry for the purpose of allowing ARMv7 to match in presence of
27184 Thumb divide instruction. Due to this having the same name as the
27185 previous entry, this will be ignored when doing command-line parsing and
27186 only considered by build attribute selection code. */
27187 ARM_EXT_OPT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
27188 ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
27189 ARM_FEATURE_CORE_LOW (ARM_EXT_V7)),
823d2571 27190 ARM_EXT_OPT ("iwmmxt",ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT),
d942732e 27191 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT), ARM_ARCH_NONE),
823d2571 27192 ARM_EXT_OPT ("iwmmxt2", ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2),
d942732e 27193 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2), ARM_ARCH_NONE),
823d2571 27194 ARM_EXT_OPT ("maverick", ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK),
d942732e
TP
27195 ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK), ARM_ARCH_NONE),
27196 ARM_EXT_OPT2 ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
823d2571 27197 ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
d942732e
TP
27198 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
27199 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
823d2571
TG
27200 ARM_EXT_OPT ("os", ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
27201 ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
27202 ARM_FEATURE_CORE_LOW (ARM_EXT_V6M)),
ddfded2f
MW
27203 ARM_EXT_OPT ("pan", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN),
27204 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_PAN, 0),
ced40572 27205 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
dad0c3bf
SD
27206 ARM_EXT_OPT ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
27207 ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
27208 ARM_ARCH_V8A),
4d1464f2
MW
27209 ARM_EXT_OPT ("ras", ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS),
27210 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_RAS, 0),
ced40572 27211 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
643afb90
MW
27212 ARM_EXT_OPT ("rdma", FPU_ARCH_NEON_VFP_ARMV8_1,
27213 ARM_FEATURE_COPROC (FPU_NEON_ARMV8 | FPU_NEON_EXT_RDMA),
ced40572 27214 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
7fadb25d
SD
27215 ARM_EXT_OPT ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
27216 ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
27217 ARM_ARCH_V8A),
d942732e 27218 ARM_EXT_OPT2 ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
823d2571 27219 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
d942732e
TP
27220 ARM_FEATURE_CORE_LOW (ARM_EXT_V6K),
27221 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
643afb90
MW
27222 ARM_EXT_OPT ("simd", FPU_ARCH_NEON_VFP_ARMV8,
27223 ARM_FEATURE_COPROC (FPU_NEON_ARMV8),
27224 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
823d2571
TG
27225 ARM_EXT_OPT ("virt", ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT | ARM_EXT_ADIV
27226 | ARM_EXT_DIV),
27227 ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT),
27228 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
27229 ARM_EXT_OPT ("xscale",ARM_FEATURE_COPROC (ARM_CEXT_XSCALE),
d942732e
TP
27230 ARM_FEATURE_COPROC (ARM_CEXT_XSCALE), ARM_ARCH_NONE),
27231 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, { ARM_ARCH_NONE, ARM_ARCH_NONE } }
69133863 27232};
f3bad469 27233#undef ARM_EXT_OPT
69133863
MGD
27234
27235/* ISA floating-point and Advanced SIMD extensions. */
27236struct arm_option_fpu_value_table
27237{
0198d5e6
TC
27238 const char * name;
27239 const arm_feature_set value;
c19d1205 27240};
7ed4c4c5 27241
c19d1205
ZW
27242/* This list should, at a minimum, contain all the fpu names
27243 recognized by GCC. */
69133863 27244static const struct arm_option_fpu_value_table arm_fpus[] =
c19d1205
ZW
27245{
27246 {"softfpa", FPU_NONE},
27247 {"fpe", FPU_ARCH_FPE},
27248 {"fpe2", FPU_ARCH_FPE},
27249 {"fpe3", FPU_ARCH_FPA}, /* Third release supports LFM/SFM. */
27250 {"fpa", FPU_ARCH_FPA},
27251 {"fpa10", FPU_ARCH_FPA},
27252 {"fpa11", FPU_ARCH_FPA},
27253 {"arm7500fe", FPU_ARCH_FPA},
27254 {"softvfp", FPU_ARCH_VFP},
27255 {"softvfp+vfp", FPU_ARCH_VFP_V2},
27256 {"vfp", FPU_ARCH_VFP_V2},
27257 {"vfp9", FPU_ARCH_VFP_V2},
d5e0ba9c 27258 {"vfp3", FPU_ARCH_VFP_V3}, /* Undocumented, use vfpv3. */
c19d1205
ZW
27259 {"vfp10", FPU_ARCH_VFP_V2},
27260 {"vfp10-r0", FPU_ARCH_VFP_V1},
27261 {"vfpxd", FPU_ARCH_VFP_V1xD},
b1cc4aeb
PB
27262 {"vfpv2", FPU_ARCH_VFP_V2},
27263 {"vfpv3", FPU_ARCH_VFP_V3},
62f3b8c8 27264 {"vfpv3-fp16", FPU_ARCH_VFP_V3_FP16},
b1cc4aeb 27265 {"vfpv3-d16", FPU_ARCH_VFP_V3D16},
62f3b8c8
PB
27266 {"vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16},
27267 {"vfpv3xd", FPU_ARCH_VFP_V3xD},
27268 {"vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16},
c19d1205
ZW
27269 {"arm1020t", FPU_ARCH_VFP_V1},
27270 {"arm1020e", FPU_ARCH_VFP_V2},
d5e0ba9c 27271 {"arm1136jfs", FPU_ARCH_VFP_V2}, /* Undocumented, use arm1136jf-s. */
c19d1205
ZW
27272 {"arm1136jf-s", FPU_ARCH_VFP_V2},
27273 {"maverick", FPU_ARCH_MAVERICK},
d5e0ba9c 27274 {"neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
d3375ddd 27275 {"neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
8e79c3df 27276 {"neon-fp16", FPU_ARCH_NEON_FP16},
62f3b8c8
PB
27277 {"vfpv4", FPU_ARCH_VFP_V4},
27278 {"vfpv4-d16", FPU_ARCH_VFP_V4D16},
ada65aa3 27279 {"fpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16},
a715796b
TG
27280 {"fpv5-d16", FPU_ARCH_VFP_V5D16},
27281 {"fpv5-sp-d16", FPU_ARCH_VFP_V5_SP_D16},
62f3b8c8 27282 {"neon-vfpv4", FPU_ARCH_NEON_VFP_V4},
bca38921
MGD
27283 {"fp-armv8", FPU_ARCH_VFP_ARMV8},
27284 {"neon-fp-armv8", FPU_ARCH_NEON_VFP_ARMV8},
27285 {"crypto-neon-fp-armv8",
27286 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8},
d6b4b13e 27287 {"neon-fp-armv8.1", FPU_ARCH_NEON_VFP_ARMV8_1},
081e4c7d
MW
27288 {"crypto-neon-fp-armv8.1",
27289 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1},
e74cfd16
PB
27290 {NULL, ARM_ARCH_NONE}
27291};
27292
27293struct arm_option_value_table
27294{
e0471c16 27295 const char *name;
e74cfd16 27296 long value;
c19d1205 27297};
7ed4c4c5 27298
e74cfd16 27299static const struct arm_option_value_table arm_float_abis[] =
c19d1205
ZW
27300{
27301 {"hard", ARM_FLOAT_ABI_HARD},
27302 {"softfp", ARM_FLOAT_ABI_SOFTFP},
27303 {"soft", ARM_FLOAT_ABI_SOFT},
e74cfd16 27304 {NULL, 0}
c19d1205 27305};
7ed4c4c5 27306
c19d1205 27307#ifdef OBJ_ELF
3a4a14e9 27308/* We only know how to output GNU and ver 4/5 (AAELF) formats. */
e74cfd16 27309static const struct arm_option_value_table arm_eabis[] =
c19d1205
ZW
27310{
27311 {"gnu", EF_ARM_EABI_UNKNOWN},
27312 {"4", EF_ARM_EABI_VER4},
3a4a14e9 27313 {"5", EF_ARM_EABI_VER5},
e74cfd16 27314 {NULL, 0}
c19d1205
ZW
27315};
27316#endif
7ed4c4c5 27317
c19d1205
ZW
27318struct arm_long_option_table
27319{
0198d5e6 27320 const char * option; /* Substring to match. */
e0471c16 27321 const char * help; /* Help information. */
17b9d67d 27322 int (* func) (const char * subopt); /* Function to decode sub-option. */
e0471c16 27323 const char * deprecated; /* If non-null, print this message. */
c19d1205 27324};
7ed4c4c5 27325
c921be7d 27326static bfd_boolean
c168ce07 27327arm_parse_extension (const char *str, const arm_feature_set *opt_set,
34ef62f4
AV
27328 arm_feature_set *ext_set,
27329 const struct arm_ext_table *ext_table)
7ed4c4c5 27330{
69133863 27331 /* We insist on extensions being specified in alphabetical order, and with
fa94de6b
RM
27332 extensions being added before being removed. We achieve this by having
27333 the global ARM_EXTENSIONS table in alphabetical order, and using the
69133863 27334 ADDING_VALUE variable to indicate whether we are adding an extension (1)
fa94de6b 27335 or removing it (0) and only allowing it to change in the order
69133863
MGD
27336 -1 -> 1 -> 0. */
27337 const struct arm_option_extension_value_table * opt = NULL;
d942732e 27338 const arm_feature_set arm_any = ARM_ANY;
69133863
MGD
27339 int adding_value = -1;
27340
c19d1205 27341 while (str != NULL && *str != 0)
7ed4c4c5 27342 {
82b8a785 27343 const char *ext;
f3bad469 27344 size_t len;
7ed4c4c5 27345
c19d1205
ZW
27346 if (*str != '+')
27347 {
27348 as_bad (_("invalid architectural extension"));
c921be7d 27349 return FALSE;
c19d1205 27350 }
7ed4c4c5 27351
c19d1205
ZW
27352 str++;
27353 ext = strchr (str, '+');
7ed4c4c5 27354
c19d1205 27355 if (ext != NULL)
f3bad469 27356 len = ext - str;
c19d1205 27357 else
f3bad469 27358 len = strlen (str);
7ed4c4c5 27359
f3bad469 27360 if (len >= 2 && strncmp (str, "no", 2) == 0)
69133863
MGD
27361 {
27362 if (adding_value != 0)
27363 {
27364 adding_value = 0;
27365 opt = arm_extensions;
27366 }
27367
f3bad469 27368 len -= 2;
69133863
MGD
27369 str += 2;
27370 }
f3bad469 27371 else if (len > 0)
69133863
MGD
27372 {
27373 if (adding_value == -1)
27374 {
27375 adding_value = 1;
27376 opt = arm_extensions;
27377 }
27378 else if (adding_value != 1)
27379 {
27380 as_bad (_("must specify extensions to add before specifying "
27381 "those to remove"));
27382 return FALSE;
27383 }
27384 }
27385
f3bad469 27386 if (len == 0)
c19d1205
ZW
27387 {
27388 as_bad (_("missing architectural extension"));
c921be7d 27389 return FALSE;
c19d1205 27390 }
7ed4c4c5 27391
69133863
MGD
27392 gas_assert (adding_value != -1);
27393 gas_assert (opt != NULL);
27394
34ef62f4
AV
27395 if (ext_table != NULL)
27396 {
27397 const struct arm_ext_table * ext_opt = ext_table;
27398 bfd_boolean found = FALSE;
27399 for (; ext_opt->name != NULL; ext_opt++)
27400 if (ext_opt->name_len == len
27401 && strncmp (ext_opt->name, str, len) == 0)
27402 {
27403 if (adding_value)
27404 {
27405 if (ARM_FEATURE_ZERO (ext_opt->merge))
27406 /* TODO: Option not supported. When we remove the
27407 legacy table this case should error out. */
27408 continue;
27409
27410 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, ext_opt->merge);
27411 }
27412 else
27413 {
27414 if (ARM_FEATURE_ZERO (ext_opt->clear))
27415 /* TODO: Option not supported. When we remove the
27416 legacy table this case should error out. */
27417 continue;
27418 ARM_CLEAR_FEATURE (*ext_set, *ext_set, ext_opt->clear);
27419 }
27420 found = TRUE;
27421 break;
27422 }
27423 if (found)
27424 {
27425 str = ext;
27426 continue;
27427 }
27428 }
27429
69133863
MGD
27430 /* Scan over the options table trying to find an exact match. */
27431 for (; opt->name != NULL; opt++)
f3bad469 27432 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 27433 {
d942732e
TP
27434 int i, nb_allowed_archs =
27435 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
69133863 27436 /* Check we can apply the extension to this architecture. */
d942732e
TP
27437 for (i = 0; i < nb_allowed_archs; i++)
27438 {
27439 /* Empty entry. */
27440 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_any))
27441 continue;
c168ce07 27442 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *opt_set))
d942732e
TP
27443 break;
27444 }
27445 if (i == nb_allowed_archs)
69133863
MGD
27446 {
27447 as_bad (_("extension does not apply to the base architecture"));
27448 return FALSE;
27449 }
27450
27451 /* Add or remove the extension. */
27452 if (adding_value)
4d354d8b 27453 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, opt->merge_value);
69133863 27454 else
4d354d8b 27455 ARM_CLEAR_FEATURE (*ext_set, *ext_set, opt->clear_value);
69133863 27456
3d030cdb
TP
27457 /* Allowing Thumb division instructions for ARMv7 in autodetection
27458 rely on this break so that duplicate extensions (extensions
27459 with the same name as a previous extension in the list) are not
27460 considered for command-line parsing. */
c19d1205
ZW
27461 break;
27462 }
7ed4c4c5 27463
c19d1205
ZW
27464 if (opt->name == NULL)
27465 {
69133863
MGD
27466 /* Did we fail to find an extension because it wasn't specified in
27467 alphabetical order, or because it does not exist? */
27468
27469 for (opt = arm_extensions; opt->name != NULL; opt++)
f3bad469 27470 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
69133863
MGD
27471 break;
27472
27473 if (opt->name == NULL)
27474 as_bad (_("unknown architectural extension `%s'"), str);
27475 else
27476 as_bad (_("architectural extensions must be specified in "
27477 "alphabetical order"));
27478
c921be7d 27479 return FALSE;
c19d1205 27480 }
69133863
MGD
27481 else
27482 {
27483 /* We should skip the extension we've just matched the next time
27484 round. */
27485 opt++;
27486 }
7ed4c4c5 27487
c19d1205
ZW
27488 str = ext;
27489 };
7ed4c4c5 27490
c921be7d 27491 return TRUE;
c19d1205 27492}
7ed4c4c5 27493
c921be7d 27494static bfd_boolean
17b9d67d 27495arm_parse_cpu (const char *str)
7ed4c4c5 27496{
f3bad469 27497 const struct arm_cpu_option_table *opt;
82b8a785 27498 const char *ext = strchr (str, '+');
f3bad469 27499 size_t len;
7ed4c4c5 27500
c19d1205 27501 if (ext != NULL)
f3bad469 27502 len = ext - str;
7ed4c4c5 27503 else
f3bad469 27504 len = strlen (str);
7ed4c4c5 27505
f3bad469 27506 if (len == 0)
7ed4c4c5 27507 {
c19d1205 27508 as_bad (_("missing cpu name `%s'"), str);
c921be7d 27509 return FALSE;
7ed4c4c5
NC
27510 }
27511
c19d1205 27512 for (opt = arm_cpus; opt->name != NULL; opt++)
f3bad469 27513 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 27514 {
c168ce07 27515 mcpu_cpu_opt = &opt->value;
4d354d8b
TP
27516 if (mcpu_ext_opt == NULL)
27517 mcpu_ext_opt = XNEW (arm_feature_set);
27518 *mcpu_ext_opt = opt->ext;
e74cfd16 27519 mcpu_fpu_opt = &opt->default_fpu;
ee065d83 27520 if (opt->canonical_name)
ef8e6722
JW
27521 {
27522 gas_assert (sizeof selected_cpu_name > strlen (opt->canonical_name));
27523 strcpy (selected_cpu_name, opt->canonical_name);
27524 }
ee065d83
PB
27525 else
27526 {
f3bad469 27527 size_t i;
c921be7d 27528
ef8e6722
JW
27529 if (len >= sizeof selected_cpu_name)
27530 len = (sizeof selected_cpu_name) - 1;
27531
f3bad469 27532 for (i = 0; i < len; i++)
ee065d83
PB
27533 selected_cpu_name[i] = TOUPPER (opt->name[i]);
27534 selected_cpu_name[i] = 0;
27535 }
7ed4c4c5 27536
c19d1205 27537 if (ext != NULL)
34ef62f4 27538 return arm_parse_extension (ext, mcpu_cpu_opt, mcpu_ext_opt, NULL);
7ed4c4c5 27539
c921be7d 27540 return TRUE;
c19d1205 27541 }
7ed4c4c5 27542
c19d1205 27543 as_bad (_("unknown cpu `%s'"), str);
c921be7d 27544 return FALSE;
7ed4c4c5
NC
27545}
27546
c921be7d 27547static bfd_boolean
17b9d67d 27548arm_parse_arch (const char *str)
7ed4c4c5 27549{
e74cfd16 27550 const struct arm_arch_option_table *opt;
82b8a785 27551 const char *ext = strchr (str, '+');
f3bad469 27552 size_t len;
7ed4c4c5 27553
c19d1205 27554 if (ext != NULL)
f3bad469 27555 len = ext - str;
7ed4c4c5 27556 else
f3bad469 27557 len = strlen (str);
7ed4c4c5 27558
f3bad469 27559 if (len == 0)
7ed4c4c5 27560 {
c19d1205 27561 as_bad (_("missing architecture name `%s'"), str);
c921be7d 27562 return FALSE;
7ed4c4c5
NC
27563 }
27564
c19d1205 27565 for (opt = arm_archs; opt->name != NULL; opt++)
f3bad469 27566 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 27567 {
e74cfd16 27568 march_cpu_opt = &opt->value;
4d354d8b
TP
27569 if (march_ext_opt == NULL)
27570 march_ext_opt = XNEW (arm_feature_set);
27571 *march_ext_opt = arm_arch_none;
e74cfd16 27572 march_fpu_opt = &opt->default_fpu;
5f4273c7 27573 strcpy (selected_cpu_name, opt->name);
7ed4c4c5 27574
c19d1205 27575 if (ext != NULL)
34ef62f4
AV
27576 return arm_parse_extension (ext, march_cpu_opt, march_ext_opt,
27577 opt->ext_table);
7ed4c4c5 27578
c921be7d 27579 return TRUE;
c19d1205
ZW
27580 }
27581
27582 as_bad (_("unknown architecture `%s'\n"), str);
c921be7d 27583 return FALSE;
7ed4c4c5 27584}
eb043451 27585
c921be7d 27586static bfd_boolean
17b9d67d 27587arm_parse_fpu (const char * str)
c19d1205 27588{
69133863 27589 const struct arm_option_fpu_value_table * opt;
b99bd4ef 27590
c19d1205
ZW
27591 for (opt = arm_fpus; opt->name != NULL; opt++)
27592 if (streq (opt->name, str))
27593 {
e74cfd16 27594 mfpu_opt = &opt->value;
c921be7d 27595 return TRUE;
c19d1205 27596 }
b99bd4ef 27597
c19d1205 27598 as_bad (_("unknown floating point format `%s'\n"), str);
c921be7d 27599 return FALSE;
c19d1205
ZW
27600}
27601
c921be7d 27602static bfd_boolean
17b9d67d 27603arm_parse_float_abi (const char * str)
b99bd4ef 27604{
e74cfd16 27605 const struct arm_option_value_table * opt;
b99bd4ef 27606
c19d1205
ZW
27607 for (opt = arm_float_abis; opt->name != NULL; opt++)
27608 if (streq (opt->name, str))
27609 {
27610 mfloat_abi_opt = opt->value;
c921be7d 27611 return TRUE;
c19d1205 27612 }
cc8a6dd0 27613
c19d1205 27614 as_bad (_("unknown floating point abi `%s'\n"), str);
c921be7d 27615 return FALSE;
c19d1205 27616}
b99bd4ef 27617
c19d1205 27618#ifdef OBJ_ELF
c921be7d 27619static bfd_boolean
17b9d67d 27620arm_parse_eabi (const char * str)
c19d1205 27621{
e74cfd16 27622 const struct arm_option_value_table *opt;
cc8a6dd0 27623
c19d1205
ZW
27624 for (opt = arm_eabis; opt->name != NULL; opt++)
27625 if (streq (opt->name, str))
27626 {
27627 meabi_flags = opt->value;
c921be7d 27628 return TRUE;
c19d1205
ZW
27629 }
27630 as_bad (_("unknown EABI `%s'\n"), str);
c921be7d 27631 return FALSE;
c19d1205
ZW
27632}
27633#endif
cc8a6dd0 27634
c921be7d 27635static bfd_boolean
17b9d67d 27636arm_parse_it_mode (const char * str)
e07e6e58 27637{
c921be7d 27638 bfd_boolean ret = TRUE;
e07e6e58
NC
27639
27640 if (streq ("arm", str))
27641 implicit_it_mode = IMPLICIT_IT_MODE_ARM;
27642 else if (streq ("thumb", str))
27643 implicit_it_mode = IMPLICIT_IT_MODE_THUMB;
27644 else if (streq ("always", str))
27645 implicit_it_mode = IMPLICIT_IT_MODE_ALWAYS;
27646 else if (streq ("never", str))
27647 implicit_it_mode = IMPLICIT_IT_MODE_NEVER;
27648 else
27649 {
27650 as_bad (_("unknown implicit IT mode `%s', should be "\
477330fc 27651 "arm, thumb, always, or never."), str);
c921be7d 27652 ret = FALSE;
e07e6e58
NC
27653 }
27654
27655 return ret;
27656}
27657
2e6976a8 27658static bfd_boolean
17b9d67d 27659arm_ccs_mode (const char * unused ATTRIBUTE_UNUSED)
2e6976a8
DG
27660{
27661 codecomposer_syntax = TRUE;
27662 arm_comment_chars[0] = ';';
27663 arm_line_separator_chars[0] = 0;
27664 return TRUE;
27665}
27666
c19d1205
ZW
27667struct arm_long_option_table arm_long_opts[] =
27668{
27669 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
27670 arm_parse_cpu, NULL},
27671 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
27672 arm_parse_arch, NULL},
27673 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
27674 arm_parse_fpu, NULL},
27675 {"mfloat-abi=", N_("<abi>\t assemble for floating point ABI <abi>"),
27676 arm_parse_float_abi, NULL},
27677#ifdef OBJ_ELF
7fac0536 27678 {"meabi=", N_("<ver>\t\t assemble for eabi version <ver>"),
c19d1205
ZW
27679 arm_parse_eabi, NULL},
27680#endif
e07e6e58
NC
27681 {"mimplicit-it=", N_("<mode>\t controls implicit insertion of IT instructions"),
27682 arm_parse_it_mode, NULL},
2e6976a8
DG
27683 {"mccs", N_("\t\t\t TI CodeComposer Studio syntax compatibility mode"),
27684 arm_ccs_mode, NULL},
c19d1205
ZW
27685 {NULL, NULL, 0, NULL}
27686};
cc8a6dd0 27687
c19d1205 27688int
17b9d67d 27689md_parse_option (int c, const char * arg)
c19d1205
ZW
27690{
27691 struct arm_option_table *opt;
e74cfd16 27692 const struct arm_legacy_option_table *fopt;
c19d1205 27693 struct arm_long_option_table *lopt;
b99bd4ef 27694
c19d1205 27695 switch (c)
b99bd4ef 27696 {
c19d1205
ZW
27697#ifdef OPTION_EB
27698 case OPTION_EB:
27699 target_big_endian = 1;
27700 break;
27701#endif
cc8a6dd0 27702
c19d1205
ZW
27703#ifdef OPTION_EL
27704 case OPTION_EL:
27705 target_big_endian = 0;
27706 break;
27707#endif
b99bd4ef 27708
845b51d6
PB
27709 case OPTION_FIX_V4BX:
27710 fix_v4bx = TRUE;
27711 break;
27712
18a20338
CL
27713#ifdef OBJ_ELF
27714 case OPTION_FDPIC:
27715 arm_fdpic = TRUE;
27716 break;
27717#endif /* OBJ_ELF */
27718
c19d1205
ZW
27719 case 'a':
27720 /* Listing option. Just ignore these, we don't support additional
27721 ones. */
27722 return 0;
b99bd4ef 27723
c19d1205
ZW
27724 default:
27725 for (opt = arm_opts; opt->option != NULL; opt++)
27726 {
27727 if (c == opt->option[0]
27728 && ((arg == NULL && opt->option[1] == 0)
27729 || streq (arg, opt->option + 1)))
27730 {
c19d1205 27731 /* If the option is deprecated, tell the user. */
278df34e 27732 if (warn_on_deprecated && opt->deprecated != NULL)
c19d1205
ZW
27733 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
27734 arg ? arg : "", _(opt->deprecated));
b99bd4ef 27735
c19d1205
ZW
27736 if (opt->var != NULL)
27737 *opt->var = opt->value;
cc8a6dd0 27738
c19d1205
ZW
27739 return 1;
27740 }
27741 }
b99bd4ef 27742
e74cfd16
PB
27743 for (fopt = arm_legacy_opts; fopt->option != NULL; fopt++)
27744 {
27745 if (c == fopt->option[0]
27746 && ((arg == NULL && fopt->option[1] == 0)
27747 || streq (arg, fopt->option + 1)))
27748 {
e74cfd16 27749 /* If the option is deprecated, tell the user. */
278df34e 27750 if (warn_on_deprecated && fopt->deprecated != NULL)
e74cfd16
PB
27751 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
27752 arg ? arg : "", _(fopt->deprecated));
e74cfd16
PB
27753
27754 if (fopt->var != NULL)
27755 *fopt->var = &fopt->value;
27756
27757 return 1;
27758 }
27759 }
27760
c19d1205
ZW
27761 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
27762 {
27763 /* These options are expected to have an argument. */
27764 if (c == lopt->option[0]
27765 && arg != NULL
27766 && strncmp (arg, lopt->option + 1,
27767 strlen (lopt->option + 1)) == 0)
27768 {
c19d1205 27769 /* If the option is deprecated, tell the user. */
278df34e 27770 if (warn_on_deprecated && lopt->deprecated != NULL)
c19d1205
ZW
27771 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
27772 _(lopt->deprecated));
b99bd4ef 27773
c19d1205
ZW
27774 /* Call the sup-option parser. */
27775 return lopt->func (arg + strlen (lopt->option) - 1);
27776 }
27777 }
a737bd4d 27778
c19d1205
ZW
27779 return 0;
27780 }
a394c00f 27781
c19d1205
ZW
27782 return 1;
27783}
a394c00f 27784
c19d1205
ZW
27785void
27786md_show_usage (FILE * fp)
a394c00f 27787{
c19d1205
ZW
27788 struct arm_option_table *opt;
27789 struct arm_long_option_table *lopt;
a394c00f 27790
c19d1205 27791 fprintf (fp, _(" ARM-specific assembler options:\n"));
a394c00f 27792
c19d1205
ZW
27793 for (opt = arm_opts; opt->option != NULL; opt++)
27794 if (opt->help != NULL)
27795 fprintf (fp, " -%-23s%s\n", opt->option, _(opt->help));
a394c00f 27796
c19d1205
ZW
27797 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
27798 if (lopt->help != NULL)
27799 fprintf (fp, " -%s%s\n", lopt->option, _(lopt->help));
a394c00f 27800
c19d1205
ZW
27801#ifdef OPTION_EB
27802 fprintf (fp, _("\
27803 -EB assemble code for a big-endian cpu\n"));
a394c00f
NC
27804#endif
27805
c19d1205
ZW
27806#ifdef OPTION_EL
27807 fprintf (fp, _("\
27808 -EL assemble code for a little-endian cpu\n"));
a737bd4d 27809#endif
845b51d6
PB
27810
27811 fprintf (fp, _("\
27812 --fix-v4bx Allow BX in ARMv4 code\n"));
18a20338
CL
27813
27814#ifdef OBJ_ELF
27815 fprintf (fp, _("\
27816 --fdpic generate an FDPIC object file\n"));
27817#endif /* OBJ_ELF */
c19d1205 27818}
ee065d83 27819
ee065d83 27820#ifdef OBJ_ELF
0198d5e6 27821
62b3e311
PB
27822typedef struct
27823{
27824 int val;
27825 arm_feature_set flags;
27826} cpu_arch_ver_table;
27827
2c6b98ea
TP
27828/* Mapping from CPU features to EABI CPU arch values. Table must be sorted
27829 chronologically for architectures, with an exception for ARMv6-M and
27830 ARMv6S-M due to legacy reasons. No new architecture should have a
27831 special case. This allows for build attribute selection results to be
27832 stable when new architectures are added. */
62b3e311
PB
27833static const cpu_arch_ver_table cpu_arch_ver[] =
27834{
031254f2
AV
27835 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V1},
27836 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2},
27837 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2S},
27838 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3},
27839 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3M},
27840 {TAG_CPU_ARCH_V4, ARM_ARCH_V4xM},
27841 {TAG_CPU_ARCH_V4, ARM_ARCH_V4},
27842 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4TxM},
27843 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4T},
27844 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5xM},
27845 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5},
27846 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5TxM},
27847 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5T},
27848 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TExP},
27849 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TE},
27850 {TAG_CPU_ARCH_V5TEJ, ARM_ARCH_V5TEJ},
27851 {TAG_CPU_ARCH_V6, ARM_ARCH_V6},
27852 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6Z},
27853 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6KZ},
27854 {TAG_CPU_ARCH_V6K, ARM_ARCH_V6K},
27855 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6T2},
27856 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KT2},
27857 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6ZT2},
27858 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KZT2},
2c6b98ea
TP
27859
27860 /* When assembling a file with only ARMv6-M or ARMv6S-M instruction, GNU as
27861 always selected build attributes to match those of ARMv6-M
27862 (resp. ARMv6S-M). However, due to these architectures being a strict
27863 subset of ARMv7-M in terms of instructions available, ARMv7-M attributes
27864 would be selected when fully respecting chronology of architectures.
27865 It is thus necessary to make a special case of ARMv6-M and ARMv6S-M and
27866 move them before ARMv7 architectures. */
031254f2
AV
27867 {TAG_CPU_ARCH_V6_M, ARM_ARCH_V6M},
27868 {TAG_CPU_ARCH_V6S_M, ARM_ARCH_V6SM},
27869
27870 {TAG_CPU_ARCH_V7, ARM_ARCH_V7},
27871 {TAG_CPU_ARCH_V7, ARM_ARCH_V7A},
27872 {TAG_CPU_ARCH_V7, ARM_ARCH_V7R},
27873 {TAG_CPU_ARCH_V7, ARM_ARCH_V7M},
27874 {TAG_CPU_ARCH_V7, ARM_ARCH_V7VE},
27875 {TAG_CPU_ARCH_V7E_M, ARM_ARCH_V7EM},
27876 {TAG_CPU_ARCH_V8, ARM_ARCH_V8A},
27877 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_1A},
27878 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_2A},
27879 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_3A},
27880 {TAG_CPU_ARCH_V8M_BASE, ARM_ARCH_V8M_BASE},
27881 {TAG_CPU_ARCH_V8M_MAIN, ARM_ARCH_V8M_MAIN},
27882 {TAG_CPU_ARCH_V8R, ARM_ARCH_V8R},
27883 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_4A},
27884 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_5A},
27885 {TAG_CPU_ARCH_V8_1M_MAIN, ARM_ARCH_V8_1M_MAIN},
27886 {-1, ARM_ARCH_NONE}
62b3e311
PB
27887};
27888
ee3c0378 27889/* Set an attribute if it has not already been set by the user. */
0198d5e6 27890
ee3c0378
AS
27891static void
27892aeabi_set_attribute_int (int tag, int value)
27893{
27894 if (tag < 1
27895 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
27896 || !attributes_set_explicitly[tag])
27897 bfd_elf_add_proc_attr_int (stdoutput, tag, value);
27898}
27899
27900static void
27901aeabi_set_attribute_string (int tag, const char *value)
27902{
27903 if (tag < 1
27904 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
27905 || !attributes_set_explicitly[tag])
27906 bfd_elf_add_proc_attr_string (stdoutput, tag, value);
27907}
27908
2c6b98ea
TP
27909/* Return whether features in the *NEEDED feature set are available via
27910 extensions for the architecture whose feature set is *ARCH_FSET. */
0198d5e6 27911
2c6b98ea
TP
27912static bfd_boolean
27913have_ext_for_needed_feat_p (const arm_feature_set *arch_fset,
27914 const arm_feature_set *needed)
27915{
27916 int i, nb_allowed_archs;
27917 arm_feature_set ext_fset;
27918 const struct arm_option_extension_value_table *opt;
27919
27920 ext_fset = arm_arch_none;
27921 for (opt = arm_extensions; opt->name != NULL; opt++)
27922 {
27923 /* Extension does not provide any feature we need. */
27924 if (!ARM_CPU_HAS_FEATURE (*needed, opt->merge_value))
27925 continue;
27926
27927 nb_allowed_archs =
27928 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
27929 for (i = 0; i < nb_allowed_archs; i++)
27930 {
27931 /* Empty entry. */
27932 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_arch_any))
27933 break;
27934
27935 /* Extension is available, add it. */
27936 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *arch_fset))
27937 ARM_MERGE_FEATURE_SETS (ext_fset, ext_fset, opt->merge_value);
27938 }
27939 }
27940
27941 /* Can we enable all features in *needed? */
27942 return ARM_FSET_CPU_SUBSET (*needed, ext_fset);
27943}
27944
27945/* Select value for Tag_CPU_arch and Tag_CPU_arch_profile build attributes for
27946 a given architecture feature set *ARCH_EXT_FSET including extension feature
27947 set *EXT_FSET. Selection logic used depend on EXACT_MATCH:
27948 - if true, check for an exact match of the architecture modulo extensions;
27949 - otherwise, select build attribute value of the first superset
27950 architecture released so that results remains stable when new architectures
27951 are added.
27952 For -march/-mcpu=all the build attribute value of the most featureful
27953 architecture is returned. Tag_CPU_arch_profile result is returned in
27954 PROFILE. */
0198d5e6 27955
2c6b98ea
TP
27956static int
27957get_aeabi_cpu_arch_from_fset (const arm_feature_set *arch_ext_fset,
27958 const arm_feature_set *ext_fset,
27959 char *profile, int exact_match)
27960{
27961 arm_feature_set arch_fset;
27962 const cpu_arch_ver_table *p_ver, *p_ver_ret = NULL;
27963
27964 /* Select most featureful architecture with all its extensions if building
27965 for -march=all as the feature sets used to set build attributes. */
27966 if (ARM_FEATURE_EQUAL (*arch_ext_fset, arm_arch_any))
27967 {
27968 /* Force revisiting of decision for each new architecture. */
031254f2 27969 gas_assert (MAX_TAG_CPU_ARCH <= TAG_CPU_ARCH_V8_1M_MAIN);
2c6b98ea
TP
27970 *profile = 'A';
27971 return TAG_CPU_ARCH_V8;
27972 }
27973
27974 ARM_CLEAR_FEATURE (arch_fset, *arch_ext_fset, *ext_fset);
27975
27976 for (p_ver = cpu_arch_ver; p_ver->val != -1; p_ver++)
27977 {
27978 arm_feature_set known_arch_fset;
27979
27980 ARM_CLEAR_FEATURE (known_arch_fset, p_ver->flags, fpu_any);
27981 if (exact_match)
27982 {
27983 /* Base architecture match user-specified architecture and
27984 extensions, eg. ARMv6S-M matching -march=armv6-m+os. */
27985 if (ARM_FEATURE_EQUAL (*arch_ext_fset, known_arch_fset))
27986 {
27987 p_ver_ret = p_ver;
27988 goto found;
27989 }
27990 /* Base architecture match user-specified architecture only
27991 (eg. ARMv6-M in the same case as above). Record it in case we
27992 find a match with above condition. */
27993 else if (p_ver_ret == NULL
27994 && ARM_FEATURE_EQUAL (arch_fset, known_arch_fset))
27995 p_ver_ret = p_ver;
27996 }
27997 else
27998 {
27999
28000 /* Architecture has all features wanted. */
28001 if (ARM_FSET_CPU_SUBSET (arch_fset, known_arch_fset))
28002 {
28003 arm_feature_set added_fset;
28004
28005 /* Compute features added by this architecture over the one
28006 recorded in p_ver_ret. */
28007 if (p_ver_ret != NULL)
28008 ARM_CLEAR_FEATURE (added_fset, known_arch_fset,
28009 p_ver_ret->flags);
28010 /* First architecture that match incl. with extensions, or the
28011 only difference in features over the recorded match is
28012 features that were optional and are now mandatory. */
28013 if (p_ver_ret == NULL
28014 || ARM_FSET_CPU_SUBSET (added_fset, arch_fset))
28015 {
28016 p_ver_ret = p_ver;
28017 goto found;
28018 }
28019 }
28020 else if (p_ver_ret == NULL)
28021 {
28022 arm_feature_set needed_ext_fset;
28023
28024 ARM_CLEAR_FEATURE (needed_ext_fset, arch_fset, known_arch_fset);
28025
28026 /* Architecture has all features needed when using some
28027 extensions. Record it and continue searching in case there
28028 exist an architecture providing all needed features without
28029 the need for extensions (eg. ARMv6S-M Vs ARMv6-M with
28030 OS extension). */
28031 if (have_ext_for_needed_feat_p (&known_arch_fset,
28032 &needed_ext_fset))
28033 p_ver_ret = p_ver;
28034 }
28035 }
28036 }
28037
28038 if (p_ver_ret == NULL)
28039 return -1;
28040
28041found:
28042 /* Tag_CPU_arch_profile. */
28043 if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7a)
28044 || ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8)
28045 || (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_atomics)
28046 && !ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8m_m_only)))
28047 *profile = 'A';
28048 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7r))
28049 *profile = 'R';
28050 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_m))
28051 *profile = 'M';
28052 else
28053 *profile = '\0';
28054 return p_ver_ret->val;
28055}
28056
ee065d83 28057/* Set the public EABI object attributes. */
0198d5e6 28058
c168ce07 28059static void
ee065d83
PB
28060aeabi_set_public_attributes (void)
28061{
b90d5ba0 28062 char profile = '\0';
2c6b98ea 28063 int arch = -1;
90ec0d68 28064 int virt_sec = 0;
bca38921 28065 int fp16_optional = 0;
2c6b98ea
TP
28066 int skip_exact_match = 0;
28067 arm_feature_set flags, flags_arch, flags_ext;
ee065d83 28068
54bab281
TP
28069 /* Autodetection mode, choose the architecture based the instructions
28070 actually used. */
28071 if (no_cpu_selected ())
28072 {
28073 ARM_MERGE_FEATURE_SETS (flags, arm_arch_used, thumb_arch_used);
ddd7f988 28074
54bab281
TP
28075 if (ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any))
28076 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v1);
ddd7f988 28077
54bab281
TP
28078 if (ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_any))
28079 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v4t);
ddd7f988 28080
54bab281 28081 /* Code run during relaxation relies on selected_cpu being set. */
4d354d8b
TP
28082 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
28083 flags_ext = arm_arch_none;
28084 ARM_CLEAR_FEATURE (selected_arch, flags_arch, flags_ext);
28085 selected_ext = flags_ext;
54bab281
TP
28086 selected_cpu = flags;
28087 }
28088 /* Otherwise, choose the architecture based on the capabilities of the
28089 requested cpu. */
28090 else
4d354d8b
TP
28091 {
28092 ARM_MERGE_FEATURE_SETS (flags_arch, selected_arch, selected_ext);
28093 ARM_CLEAR_FEATURE (flags_arch, flags_arch, fpu_any);
28094 flags_ext = selected_ext;
28095 flags = selected_cpu;
28096 }
28097 ARM_MERGE_FEATURE_SETS (flags, flags, selected_fpu);
7f78eb34 28098
ddd7f988 28099 /* Allow the user to override the reported architecture. */
4d354d8b 28100 if (!ARM_FEATURE_ZERO (selected_object_arch))
7a1d4c38 28101 {
4d354d8b 28102 ARM_CLEAR_FEATURE (flags_arch, selected_object_arch, fpu_any);
2c6b98ea 28103 flags_ext = arm_arch_none;
7a1d4c38 28104 }
2c6b98ea 28105 else
4d354d8b 28106 skip_exact_match = ARM_FEATURE_EQUAL (selected_cpu, arm_arch_any);
2c6b98ea
TP
28107
28108 /* When this function is run again after relaxation has happened there is no
28109 way to determine whether an architecture or CPU was specified by the user:
28110 - selected_cpu is set above for relaxation to work;
28111 - march_cpu_opt is not set if only -mcpu or .cpu is used;
28112 - mcpu_cpu_opt is set to arm_arch_any for autodetection.
28113 Therefore, if not in -march=all case we first try an exact match and fall
28114 back to autodetection. */
28115 if (!skip_exact_match)
28116 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 1);
28117 if (arch == -1)
28118 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 0);
28119 if (arch == -1)
28120 as_bad (_("no architecture contains all the instructions used\n"));
9e3c6df6 28121
ee065d83
PB
28122 /* Tag_CPU_name. */
28123 if (selected_cpu_name[0])
28124 {
91d6fa6a 28125 char *q;
ee065d83 28126
91d6fa6a
NC
28127 q = selected_cpu_name;
28128 if (strncmp (q, "armv", 4) == 0)
ee065d83
PB
28129 {
28130 int i;
5f4273c7 28131
91d6fa6a
NC
28132 q += 4;
28133 for (i = 0; q[i]; i++)
28134 q[i] = TOUPPER (q[i]);
ee065d83 28135 }
91d6fa6a 28136 aeabi_set_attribute_string (Tag_CPU_name, q);
ee065d83 28137 }
62f3b8c8 28138
ee065d83 28139 /* Tag_CPU_arch. */
ee3c0378 28140 aeabi_set_attribute_int (Tag_CPU_arch, arch);
62f3b8c8 28141
62b3e311 28142 /* Tag_CPU_arch_profile. */
69239280
MGD
28143 if (profile != '\0')
28144 aeabi_set_attribute_int (Tag_CPU_arch_profile, profile);
62f3b8c8 28145
15afaa63 28146 /* Tag_DSP_extension. */
4d354d8b 28147 if (ARM_CPU_HAS_FEATURE (selected_ext, arm_ext_dsp))
6c290d53 28148 aeabi_set_attribute_int (Tag_DSP_extension, 1);
15afaa63 28149
2c6b98ea 28150 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
ee065d83 28151 /* Tag_ARM_ISA_use. */
ee3c0378 28152 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v1)
2c6b98ea 28153 || ARM_FEATURE_ZERO (flags_arch))
ee3c0378 28154 aeabi_set_attribute_int (Tag_ARM_ISA_use, 1);
62f3b8c8 28155
ee065d83 28156 /* Tag_THUMB_ISA_use. */
ee3c0378 28157 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v4t)
2c6b98ea 28158 || ARM_FEATURE_ZERO (flags_arch))
4ed7ed8d
TP
28159 {
28160 int thumb_isa_use;
28161
28162 if (!ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
16a1fa25 28163 && ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m_m_only))
4ed7ed8d
TP
28164 thumb_isa_use = 3;
28165 else if (ARM_CPU_HAS_FEATURE (flags, arm_arch_t2))
28166 thumb_isa_use = 2;
28167 else
28168 thumb_isa_use = 1;
28169 aeabi_set_attribute_int (Tag_THUMB_ISA_use, thumb_isa_use);
28170 }
62f3b8c8 28171
ee065d83 28172 /* Tag_VFP_arch. */
a715796b
TG
28173 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_armv8xd))
28174 aeabi_set_attribute_int (Tag_VFP_arch,
28175 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
28176 ? 7 : 8);
bca38921 28177 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_fma))
62f3b8c8
PB
28178 aeabi_set_attribute_int (Tag_VFP_arch,
28179 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
28180 ? 5 : 6);
28181 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32))
bca38921
MGD
28182 {
28183 fp16_optional = 1;
28184 aeabi_set_attribute_int (Tag_VFP_arch, 3);
28185 }
ada65aa3 28186 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v3xd))
bca38921
MGD
28187 {
28188 aeabi_set_attribute_int (Tag_VFP_arch, 4);
28189 fp16_optional = 1;
28190 }
ee3c0378
AS
28191 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v2))
28192 aeabi_set_attribute_int (Tag_VFP_arch, 2);
28193 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1)
477330fc 28194 || ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd))
ee3c0378 28195 aeabi_set_attribute_int (Tag_VFP_arch, 1);
62f3b8c8 28196
4547cb56
NC
28197 /* Tag_ABI_HardFP_use. */
28198 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd)
28199 && !ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1))
28200 aeabi_set_attribute_int (Tag_ABI_HardFP_use, 1);
28201
ee065d83 28202 /* Tag_WMMX_arch. */
ee3c0378
AS
28203 if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt2))
28204 aeabi_set_attribute_int (Tag_WMMX_arch, 2);
28205 else if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt))
28206 aeabi_set_attribute_int (Tag_WMMX_arch, 1);
62f3b8c8 28207
ee3c0378 28208 /* Tag_Advanced_SIMD_arch (formerly Tag_NEON_arch). */
9411fd44
MW
28209 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v8_1))
28210 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 4);
28211 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_armv8))
bca38921
MGD
28212 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 3);
28213 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v1))
28214 {
28215 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_fma))
28216 {
28217 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 2);
28218 }
28219 else
28220 {
28221 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 1);
28222 fp16_optional = 1;
28223 }
28224 }
fa94de6b 28225
ee3c0378 28226 /* Tag_VFP_HP_extension (formerly Tag_NEON_FP16_arch). */
bca38921 28227 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_fp16) && fp16_optional)
ee3c0378 28228 aeabi_set_attribute_int (Tag_VFP_HP_extension, 1);
4547cb56 28229
69239280
MGD
28230 /* Tag_DIV_use.
28231
28232 We set Tag_DIV_use to two when integer divide instructions have been used
28233 in ARM state, or when Thumb integer divide instructions have been used,
28234 but we have no architecture profile set, nor have we any ARM instructions.
28235
4ed7ed8d
TP
28236 For ARMv8-A and ARMv8-M we set the tag to 0 as integer divide is implied
28237 by the base architecture.
bca38921 28238
69239280 28239 For new architectures we will have to check these tests. */
031254f2 28240 gas_assert (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
4ed7ed8d
TP
28241 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
28242 || ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m))
bca38921
MGD
28243 aeabi_set_attribute_int (Tag_DIV_use, 0);
28244 else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_adiv)
28245 || (profile == '\0'
28246 && ARM_CPU_HAS_FEATURE (flags, arm_ext_div)
28247 && !ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any)))
eea54501 28248 aeabi_set_attribute_int (Tag_DIV_use, 2);
60e5ef9f
MGD
28249
28250 /* Tag_MP_extension_use. */
28251 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_mp))
28252 aeabi_set_attribute_int (Tag_MPextension_use, 1);
f4c65163
MGD
28253
28254 /* Tag Virtualization_use. */
28255 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_sec))
90ec0d68
MGD
28256 virt_sec |= 1;
28257 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_virt))
28258 virt_sec |= 2;
28259 if (virt_sec != 0)
28260 aeabi_set_attribute_int (Tag_Virtualization_use, virt_sec);
ee065d83
PB
28261}
28262
c168ce07
TP
28263/* Post relaxation hook. Recompute ARM attributes now that relaxation is
28264 finished and free extension feature bits which will not be used anymore. */
0198d5e6 28265
c168ce07
TP
28266void
28267arm_md_post_relax (void)
28268{
28269 aeabi_set_public_attributes ();
4d354d8b
TP
28270 XDELETE (mcpu_ext_opt);
28271 mcpu_ext_opt = NULL;
28272 XDELETE (march_ext_opt);
28273 march_ext_opt = NULL;
c168ce07
TP
28274}
28275
104d59d1 28276/* Add the default contents for the .ARM.attributes section. */
0198d5e6 28277
ee065d83
PB
28278void
28279arm_md_end (void)
28280{
ee065d83
PB
28281 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
28282 return;
28283
28284 aeabi_set_public_attributes ();
ee065d83 28285}
8463be01 28286#endif /* OBJ_ELF */
ee065d83 28287
ee065d83
PB
28288/* Parse a .cpu directive. */
28289
28290static void
28291s_arm_cpu (int ignored ATTRIBUTE_UNUSED)
28292{
e74cfd16 28293 const struct arm_cpu_option_table *opt;
ee065d83
PB
28294 char *name;
28295 char saved_char;
28296
28297 name = input_line_pointer;
5f4273c7 28298 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
28299 input_line_pointer++;
28300 saved_char = *input_line_pointer;
28301 *input_line_pointer = 0;
28302
28303 /* Skip the first "all" entry. */
28304 for (opt = arm_cpus + 1; opt->name != NULL; opt++)
28305 if (streq (opt->name, name))
28306 {
4d354d8b
TP
28307 selected_arch = opt->value;
28308 selected_ext = opt->ext;
28309 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
ee065d83 28310 if (opt->canonical_name)
5f4273c7 28311 strcpy (selected_cpu_name, opt->canonical_name);
ee065d83
PB
28312 else
28313 {
28314 int i;
28315 for (i = 0; opt->name[i]; i++)
28316 selected_cpu_name[i] = TOUPPER (opt->name[i]);
f3bad469 28317
ee065d83
PB
28318 selected_cpu_name[i] = 0;
28319 }
4d354d8b
TP
28320 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
28321
ee065d83
PB
28322 *input_line_pointer = saved_char;
28323 demand_empty_rest_of_line ();
28324 return;
28325 }
28326 as_bad (_("unknown cpu `%s'"), name);
28327 *input_line_pointer = saved_char;
28328 ignore_rest_of_line ();
28329}
28330
ee065d83
PB
28331/* Parse a .arch directive. */
28332
28333static void
28334s_arm_arch (int ignored ATTRIBUTE_UNUSED)
28335{
e74cfd16 28336 const struct arm_arch_option_table *opt;
ee065d83
PB
28337 char saved_char;
28338 char *name;
28339
28340 name = input_line_pointer;
5f4273c7 28341 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
28342 input_line_pointer++;
28343 saved_char = *input_line_pointer;
28344 *input_line_pointer = 0;
28345
28346 /* Skip the first "all" entry. */
28347 for (opt = arm_archs + 1; opt->name != NULL; opt++)
28348 if (streq (opt->name, name))
28349 {
4d354d8b
TP
28350 selected_arch = opt->value;
28351 selected_ext = arm_arch_none;
28352 selected_cpu = selected_arch;
5f4273c7 28353 strcpy (selected_cpu_name, opt->name);
4d354d8b 28354 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83
PB
28355 *input_line_pointer = saved_char;
28356 demand_empty_rest_of_line ();
28357 return;
28358 }
28359
28360 as_bad (_("unknown architecture `%s'\n"), name);
28361 *input_line_pointer = saved_char;
28362 ignore_rest_of_line ();
28363}
28364
7a1d4c38
PB
28365/* Parse a .object_arch directive. */
28366
28367static void
28368s_arm_object_arch (int ignored ATTRIBUTE_UNUSED)
28369{
28370 const struct arm_arch_option_table *opt;
28371 char saved_char;
28372 char *name;
28373
28374 name = input_line_pointer;
5f4273c7 28375 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
7a1d4c38
PB
28376 input_line_pointer++;
28377 saved_char = *input_line_pointer;
28378 *input_line_pointer = 0;
28379
28380 /* Skip the first "all" entry. */
28381 for (opt = arm_archs + 1; opt->name != NULL; opt++)
28382 if (streq (opt->name, name))
28383 {
4d354d8b 28384 selected_object_arch = opt->value;
7a1d4c38
PB
28385 *input_line_pointer = saved_char;
28386 demand_empty_rest_of_line ();
28387 return;
28388 }
28389
28390 as_bad (_("unknown architecture `%s'\n"), name);
28391 *input_line_pointer = saved_char;
28392 ignore_rest_of_line ();
28393}
28394
69133863
MGD
28395/* Parse a .arch_extension directive. */
28396
28397static void
28398s_arm_arch_extension (int ignored ATTRIBUTE_UNUSED)
28399{
28400 const struct arm_option_extension_value_table *opt;
28401 char saved_char;
28402 char *name;
28403 int adding_value = 1;
28404
28405 name = input_line_pointer;
28406 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
28407 input_line_pointer++;
28408 saved_char = *input_line_pointer;
28409 *input_line_pointer = 0;
28410
28411 if (strlen (name) >= 2
28412 && strncmp (name, "no", 2) == 0)
28413 {
28414 adding_value = 0;
28415 name += 2;
28416 }
28417
28418 for (opt = arm_extensions; opt->name != NULL; opt++)
28419 if (streq (opt->name, name))
28420 {
d942732e
TP
28421 int i, nb_allowed_archs =
28422 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[i]);
28423 for (i = 0; i < nb_allowed_archs; i++)
28424 {
28425 /* Empty entry. */
4d354d8b 28426 if (ARM_CPU_IS_ANY (opt->allowed_archs[i]))
d942732e 28427 continue;
4d354d8b 28428 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], selected_arch))
d942732e
TP
28429 break;
28430 }
28431
28432 if (i == nb_allowed_archs)
69133863
MGD
28433 {
28434 as_bad (_("architectural extension `%s' is not allowed for the "
28435 "current base architecture"), name);
28436 break;
28437 }
28438
28439 if (adding_value)
4d354d8b 28440 ARM_MERGE_FEATURE_SETS (selected_ext, selected_ext,
5a70a223 28441 opt->merge_value);
69133863 28442 else
4d354d8b 28443 ARM_CLEAR_FEATURE (selected_ext, selected_ext, opt->clear_value);
69133863 28444
4d354d8b
TP
28445 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
28446 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
69133863
MGD
28447 *input_line_pointer = saved_char;
28448 demand_empty_rest_of_line ();
3d030cdb
TP
28449 /* Allowing Thumb division instructions for ARMv7 in autodetection rely
28450 on this return so that duplicate extensions (extensions with the
28451 same name as a previous extension in the list) are not considered
28452 for command-line parsing. */
69133863
MGD
28453 return;
28454 }
28455
28456 if (opt->name == NULL)
e673710a 28457 as_bad (_("unknown architecture extension `%s'\n"), name);
69133863
MGD
28458
28459 *input_line_pointer = saved_char;
28460 ignore_rest_of_line ();
28461}
28462
ee065d83
PB
28463/* Parse a .fpu directive. */
28464
28465static void
28466s_arm_fpu (int ignored ATTRIBUTE_UNUSED)
28467{
69133863 28468 const struct arm_option_fpu_value_table *opt;
ee065d83
PB
28469 char saved_char;
28470 char *name;
28471
28472 name = input_line_pointer;
5f4273c7 28473 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
28474 input_line_pointer++;
28475 saved_char = *input_line_pointer;
28476 *input_line_pointer = 0;
5f4273c7 28477
ee065d83
PB
28478 for (opt = arm_fpus; opt->name != NULL; opt++)
28479 if (streq (opt->name, name))
28480 {
4d354d8b
TP
28481 selected_fpu = opt->value;
28482#ifndef CPU_DEFAULT
28483 if (no_cpu_selected ())
28484 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
28485 else
28486#endif
28487 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83
PB
28488 *input_line_pointer = saved_char;
28489 demand_empty_rest_of_line ();
28490 return;
28491 }
28492
28493 as_bad (_("unknown floating point format `%s'\n"), name);
28494 *input_line_pointer = saved_char;
28495 ignore_rest_of_line ();
28496}
ee065d83 28497
794ba86a 28498/* Copy symbol information. */
f31fef98 28499
794ba86a
DJ
28500void
28501arm_copy_symbol_attributes (symbolS *dest, symbolS *src)
28502{
28503 ARM_GET_FLAG (dest) = ARM_GET_FLAG (src);
28504}
e04befd0 28505
f31fef98 28506#ifdef OBJ_ELF
e04befd0
AS
28507/* Given a symbolic attribute NAME, return the proper integer value.
28508 Returns -1 if the attribute is not known. */
f31fef98 28509
e04befd0
AS
28510int
28511arm_convert_symbolic_attribute (const char *name)
28512{
f31fef98
NC
28513 static const struct
28514 {
28515 const char * name;
28516 const int tag;
28517 }
28518 attribute_table[] =
28519 {
28520 /* When you modify this table you should
28521 also modify the list in doc/c-arm.texi. */
e04befd0 28522#define T(tag) {#tag, tag}
f31fef98
NC
28523 T (Tag_CPU_raw_name),
28524 T (Tag_CPU_name),
28525 T (Tag_CPU_arch),
28526 T (Tag_CPU_arch_profile),
28527 T (Tag_ARM_ISA_use),
28528 T (Tag_THUMB_ISA_use),
75375b3e 28529 T (Tag_FP_arch),
f31fef98
NC
28530 T (Tag_VFP_arch),
28531 T (Tag_WMMX_arch),
28532 T (Tag_Advanced_SIMD_arch),
28533 T (Tag_PCS_config),
28534 T (Tag_ABI_PCS_R9_use),
28535 T (Tag_ABI_PCS_RW_data),
28536 T (Tag_ABI_PCS_RO_data),
28537 T (Tag_ABI_PCS_GOT_use),
28538 T (Tag_ABI_PCS_wchar_t),
28539 T (Tag_ABI_FP_rounding),
28540 T (Tag_ABI_FP_denormal),
28541 T (Tag_ABI_FP_exceptions),
28542 T (Tag_ABI_FP_user_exceptions),
28543 T (Tag_ABI_FP_number_model),
75375b3e 28544 T (Tag_ABI_align_needed),
f31fef98 28545 T (Tag_ABI_align8_needed),
75375b3e 28546 T (Tag_ABI_align_preserved),
f31fef98
NC
28547 T (Tag_ABI_align8_preserved),
28548 T (Tag_ABI_enum_size),
28549 T (Tag_ABI_HardFP_use),
28550 T (Tag_ABI_VFP_args),
28551 T (Tag_ABI_WMMX_args),
28552 T (Tag_ABI_optimization_goals),
28553 T (Tag_ABI_FP_optimization_goals),
28554 T (Tag_compatibility),
28555 T (Tag_CPU_unaligned_access),
75375b3e 28556 T (Tag_FP_HP_extension),
f31fef98
NC
28557 T (Tag_VFP_HP_extension),
28558 T (Tag_ABI_FP_16bit_format),
cd21e546
MGD
28559 T (Tag_MPextension_use),
28560 T (Tag_DIV_use),
f31fef98
NC
28561 T (Tag_nodefaults),
28562 T (Tag_also_compatible_with),
28563 T (Tag_conformance),
28564 T (Tag_T2EE_use),
28565 T (Tag_Virtualization_use),
15afaa63 28566 T (Tag_DSP_extension),
cd21e546 28567 /* We deliberately do not include Tag_MPextension_use_legacy. */
e04befd0 28568#undef T
f31fef98 28569 };
e04befd0
AS
28570 unsigned int i;
28571
28572 if (name == NULL)
28573 return -1;
28574
f31fef98 28575 for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
c921be7d 28576 if (streq (name, attribute_table[i].name))
e04befd0
AS
28577 return attribute_table[i].tag;
28578
28579 return -1;
28580}
267bf995 28581
93ef582d
NC
28582/* Apply sym value for relocations only in the case that they are for
28583 local symbols in the same segment as the fixup and you have the
28584 respective architectural feature for blx and simple switches. */
0198d5e6 28585
267bf995 28586int
93ef582d 28587arm_apply_sym_value (struct fix * fixP, segT this_seg)
267bf995
RR
28588{
28589 if (fixP->fx_addsy
28590 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
93ef582d
NC
28591 /* PR 17444: If the local symbol is in a different section then a reloc
28592 will always be generated for it, so applying the symbol value now
28593 will result in a double offset being stored in the relocation. */
28594 && (S_GET_SEGMENT (fixP->fx_addsy) == this_seg)
34e77a92 28595 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE))
267bf995
RR
28596 {
28597 switch (fixP->fx_r_type)
28598 {
28599 case BFD_RELOC_ARM_PCREL_BLX:
28600 case BFD_RELOC_THUMB_PCREL_BRANCH23:
28601 if (ARM_IS_FUNC (fixP->fx_addsy))
28602 return 1;
28603 break;
28604
28605 case BFD_RELOC_ARM_PCREL_CALL:
28606 case BFD_RELOC_THUMB_PCREL_BLX:
28607 if (THUMB_IS_FUNC (fixP->fx_addsy))
93ef582d 28608 return 1;
267bf995
RR
28609 break;
28610
28611 default:
28612 break;
28613 }
28614
28615 }
28616 return 0;
28617}
f31fef98 28618#endif /* OBJ_ELF */