1218822Sdim/* ARM assembler/disassembler support.
2218822Sdim   Copyright 2004 Free Software Foundation, Inc.
360484Sobrien
4218822Sdim   This file is part of GDB and GAS.
560484Sobrien
6218822Sdim   GDB and GAS are free software; you can redistribute it and/or
7218822Sdim   modify it under the terms of the GNU General Public License as
8218822Sdim   published by the Free Software Foundation; either version 1, or (at
9218822Sdim   your option) any later version.
1060484Sobrien
11218822Sdim   GDB and GAS are distributed in the hope that it will be useful, but
12218822Sdim   WITHOUT ANY WARRANTY; without even the implied warranty of
13218822Sdim   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14218822Sdim   General Public License for more details.
1560484Sobrien
16218822Sdim   You should have received a copy of the GNU General Public License
17218822Sdim   along with GDB or GAS; see the file COPYING.  If not, write to the
18218822Sdim   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19218822Sdim   02110-1301, USA.  */
2060484Sobrien
21218822Sdim/* The following bitmasks control CPU extensions:  */
22218822Sdim#define ARM_EXT_V1	 0x00000001	/* All processors (core set).  */
23218822Sdim#define ARM_EXT_V2	 0x00000002	/* Multiply instructions.  */
24218822Sdim#define ARM_EXT_V2S	 0x00000004	/* SWP instructions.       */
25218822Sdim#define ARM_EXT_V3	 0x00000008	/* MSR MRS.                */
26218822Sdim#define ARM_EXT_V3M	 0x00000010	/* Allow long multiplies.  */
27218822Sdim#define ARM_EXT_V4	 0x00000020	/* Allow half word loads.  */
28218822Sdim#define ARM_EXT_V4T	 0x00000040	/* Thumb.                  */
29218822Sdim#define ARM_EXT_V5	 0x00000080	/* Allow CLZ, etc.         */
30218822Sdim#define ARM_EXT_V5T	 0x00000100	/* Improved interworking.  */
31218822Sdim#define ARM_EXT_V5ExP	 0x00000200	/* DSP core set.           */
32218822Sdim#define ARM_EXT_V5E	 0x00000400	/* DSP Double transfers.   */
33218822Sdim#define ARM_EXT_V5J	 0x00000800	/* Jazelle extension.	   */
34218822Sdim#define ARM_EXT_V6       0x00001000     /* ARM V6.                 */
35218822Sdim#define ARM_EXT_V6K      0x00002000     /* ARM V6K.                */
36218822Sdim#define ARM_EXT_V6Z      0x00004000     /* ARM V6Z.                */
37218822Sdim#define ARM_EXT_V6T2	 0x00008000	/* Thumb-2.                */
38218822Sdim#define ARM_EXT_DIV	 0x00010000	/* Integer division.       */
39218822Sdim/* The 'M' in Arm V7M stands for Microcontroller.
40218822Sdim   On earlier architecture variants it stands for Multiply.  */
41218822Sdim#define ARM_EXT_V5E_NOTM 0x00020000	/* Arm V5E but not Arm V7M. */
42218822Sdim#define ARM_EXT_V6_NOTM	 0x00040000	/* Arm V6 but not Arm V7M. */
43218822Sdim#define ARM_EXT_V7	 0x00080000	/* Arm V7.                 */
44218822Sdim#define ARM_EXT_V7A	 0x00100000	/* Arm V7A.                */
45218822Sdim#define ARM_EXT_V7R	 0x00200000	/* Arm V7R.                */
46218822Sdim#define ARM_EXT_V7M	 0x00400000	/* Arm V7M.                */
4760484Sobrien
48218822Sdim/* Co-processor space extensions.  */
49218822Sdim#define ARM_CEXT_XSCALE   0x00000001	/* Allow MIA etc.          */
50218822Sdim#define ARM_CEXT_MAVERICK 0x00000002	/* Use Cirrus/DSP coprocessor.  */
51218822Sdim#define ARM_CEXT_IWMMXT   0x00000004    /* Intel Wireless MMX technology coprocessor.   */
52218822Sdim#define ARM_CEXT_IWMMXT2  0x00000008    /* Intel Wireless MMX technology coprocessor version 2.   */
5360484Sobrien
54218822Sdim#define FPU_ENDIAN_PURE	 0x80000000	/* Pure-endian doubles.	      */
55218822Sdim#define FPU_ENDIAN_BIG	 0		/* Double words-big-endian.   */
56218822Sdim#define FPU_FPA_EXT_V1	 0x40000000	/* Base FPA instruction set.  */
57218822Sdim#define FPU_FPA_EXT_V2	 0x20000000	/* LFM/SFM.		      */
58218822Sdim#define FPU_MAVERICK	 0x10000000	/* Cirrus Maverick.	      */
59218822Sdim#define FPU_VFP_EXT_V1xD 0x08000000	/* Base VFP instruction set.  */
60218822Sdim#define FPU_VFP_EXT_V1	 0x04000000	/* Double-precision insns.    */
61218822Sdim#define FPU_VFP_EXT_V2	 0x02000000	/* ARM10E VFPr1.	      */
62218822Sdim#define FPU_VFP_EXT_V3	 0x01000000	/* VFPv3 insns.	              */
63218822Sdim#define FPU_NEON_EXT_V1	 0x00800000	/* Neon (SIMD) insns.	      */
6460484Sobrien
65218822Sdim/* Architectures are the sum of the base and extensions.  The ARM ARM (rev E)
66218822Sdim   defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
67218822Sdim   ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE.  To these we add
68218822Sdim   three more to cover cores prior to ARM6.  Finally, there are cores which
69218822Sdim   implement further extensions in the co-processor space.  */
70218822Sdim#define ARM_AEXT_V1			  ARM_EXT_V1
71218822Sdim#define ARM_AEXT_V2	(ARM_AEXT_V1	| ARM_EXT_V2)
72218822Sdim#define ARM_AEXT_V2S	(ARM_AEXT_V2	| ARM_EXT_V2S)
73218822Sdim#define ARM_AEXT_V3	(ARM_AEXT_V2S	| ARM_EXT_V3)
74218822Sdim#define ARM_AEXT_V3M	(ARM_AEXT_V3	| ARM_EXT_V3M)
75218822Sdim#define ARM_AEXT_V4xM	(ARM_AEXT_V3	| ARM_EXT_V4)
76218822Sdim#define ARM_AEXT_V4	(ARM_AEXT_V3M	| ARM_EXT_V4)
77218822Sdim#define ARM_AEXT_V4TxM	(ARM_AEXT_V4xM	| ARM_EXT_V4T)
78218822Sdim#define ARM_AEXT_V4T	(ARM_AEXT_V4	| ARM_EXT_V4T)
79218822Sdim#define ARM_AEXT_V5xM	(ARM_AEXT_V4xM	| ARM_EXT_V5)
80218822Sdim#define ARM_AEXT_V5	(ARM_AEXT_V4	| ARM_EXT_V5)
81218822Sdim#define ARM_AEXT_V5TxM	(ARM_AEXT_V5xM	| ARM_EXT_V4T | ARM_EXT_V5T)
82218822Sdim#define ARM_AEXT_V5T	(ARM_AEXT_V5	| ARM_EXT_V4T | ARM_EXT_V5T)
83218822Sdim#define ARM_AEXT_V5TExP	(ARM_AEXT_V5T	| ARM_EXT_V5ExP)
84218822Sdim#define ARM_AEXT_V5TE	(ARM_AEXT_V5TExP | ARM_EXT_V5E)
85218822Sdim#define ARM_AEXT_V5TEJ	(ARM_AEXT_V5TE	| ARM_EXT_V5J)
86218822Sdim#define ARM_AEXT_V6     (ARM_AEXT_V5TEJ | ARM_EXT_V6)
87218822Sdim#define ARM_AEXT_V6K    (ARM_AEXT_V6    | ARM_EXT_V6K)
88218822Sdim#define ARM_AEXT_V6Z    (ARM_AEXT_V6    | ARM_EXT_V6Z)
89218822Sdim#define ARM_AEXT_V6ZK   (ARM_AEXT_V6    | ARM_EXT_V6K | ARM_EXT_V6Z)
90218822Sdim#define ARM_AEXT_V6T2   (ARM_AEXT_V6    | ARM_EXT_V6T2 | ARM_EXT_V6_NOTM)
91218822Sdim#define ARM_AEXT_V6KT2  (ARM_AEXT_V6T2 | ARM_EXT_V6K)
92218822Sdim#define ARM_AEXT_V6ZT2  (ARM_AEXT_V6T2 | ARM_EXT_V6Z)
93218822Sdim#define ARM_AEXT_V6ZKT2 (ARM_AEXT_V6T2 | ARM_EXT_V6K | ARM_EXT_V6Z)
94218822Sdim#define ARM_AEXT_V7_ARM	(ARM_AEXT_V6ZKT2 | ARM_EXT_V7)
95218822Sdim#define ARM_AEXT_V7A	(ARM_AEXT_V7_ARM | ARM_EXT_V7A)
96218822Sdim#define ARM_AEXT_V7R	(ARM_AEXT_V7_ARM | ARM_EXT_V7R | ARM_EXT_DIV)
97218822Sdim#define ARM_AEXT_NOTM \
98218822Sdim  (ARM_AEXT_V4 | ARM_EXT_V5ExP | ARM_EXT_V5J | ARM_EXT_V6_NOTM)
99218822Sdim#define ARM_AEXT_V7M \
100218822Sdim  ((ARM_AEXT_V7_ARM | ARM_EXT_V7M | ARM_EXT_DIV) & ~(ARM_AEXT_NOTM))
101218822Sdim#define ARM_AEXT_V7 (ARM_AEXT_V7A & ARM_AEXT_V7R & ARM_AEXT_V7M)
10260484Sobrien
103218822Sdim/* Processors with specific extensions in the co-processor space.  */
104218822Sdim#define ARM_ARCH_XSCALE	ARM_FEATURE (ARM_AEXT_V5TE, ARM_CEXT_XSCALE)
105218822Sdim#define ARM_ARCH_IWMMXT	\
106218822Sdim ARM_FEATURE (ARM_AEXT_V5TE, ARM_CEXT_XSCALE | ARM_CEXT_IWMMXT)
107218822Sdim#define ARM_ARCH_IWMMXT2	\
108218822Sdim ARM_FEATURE (ARM_AEXT_V5TE, ARM_CEXT_XSCALE | ARM_CEXT_IWMMXT | ARM_CEXT_IWMMXT2)
10960484Sobrien
110218822Sdim#define FPU_VFP_V1xD	(FPU_VFP_EXT_V1xD | FPU_ENDIAN_PURE)
111218822Sdim#define FPU_VFP_V1	(FPU_VFP_V1xD | FPU_VFP_EXT_V1)
112218822Sdim#define FPU_VFP_V2	(FPU_VFP_V1 | FPU_VFP_EXT_V2)
113218822Sdim#define FPU_VFP_V3	(FPU_VFP_V2 | FPU_VFP_EXT_V3)
114218822Sdim#define FPU_VFP_HARD	(FPU_VFP_EXT_V1xD | FPU_VFP_EXT_V1 | FPU_VFP_EXT_V2 \
115218822Sdim                         | FPU_VFP_EXT_V3 | FPU_NEON_EXT_V1)
116218822Sdim#define FPU_FPA		(FPU_FPA_EXT_V1 | FPU_FPA_EXT_V2)
11760484Sobrien
118218822Sdim/* Deprecated */
119218822Sdim#define FPU_ARCH_VFP	ARM_FEATURE (0, FPU_ENDIAN_PURE)
12060484Sobrien
121218822Sdim#define FPU_ARCH_FPE	ARM_FEATURE (0, FPU_FPA_EXT_V1)
122218822Sdim#define FPU_ARCH_FPA	ARM_FEATURE (0, FPU_FPA)
12360484Sobrien
124218822Sdim#define FPU_ARCH_VFP_V1xD ARM_FEATURE (0, FPU_VFP_V1xD)
125218822Sdim#define FPU_ARCH_VFP_V1	  ARM_FEATURE (0, FPU_VFP_V1)
126218822Sdim#define FPU_ARCH_VFP_V2	  ARM_FEATURE (0, FPU_VFP_V2)
127218822Sdim#define FPU_ARCH_VFP_V3	  ARM_FEATURE (0, FPU_VFP_V3)
128218822Sdim#define FPU_ARCH_NEON_V1  ARM_FEATURE (0, FPU_NEON_EXT_V1)
129218822Sdim#define FPU_ARCH_VFP_V3_PLUS_NEON_V1 \
130218822Sdim  ARM_FEATURE (0, FPU_VFP_V3 | FPU_NEON_EXT_V1)
131218822Sdim#define FPU_ARCH_VFP_HARD ARM_FEATURE (0, FPU_VFP_HARD)
13260484Sobrien
133218822Sdim#define FPU_ARCH_ENDIAN_PURE ARM_FEATURE (0, FPU_ENDIAN_PURE)
13460484Sobrien
135218822Sdim#define FPU_ARCH_MAVERICK ARM_FEATURE (0, FPU_MAVERICK)
13660484Sobrien
137218822Sdim#define ARM_ARCH_V1	ARM_FEATURE (ARM_AEXT_V1, 0)
138218822Sdim#define ARM_ARCH_V2	ARM_FEATURE (ARM_AEXT_V2, 0)
139218822Sdim#define ARM_ARCH_V2S	ARM_FEATURE (ARM_AEXT_V2S, 0)
140218822Sdim#define ARM_ARCH_V3	ARM_FEATURE (ARM_AEXT_V3, 0)
141218822Sdim#define ARM_ARCH_V3M	ARM_FEATURE (ARM_AEXT_V3M, 0)
142218822Sdim#define ARM_ARCH_V4xM	ARM_FEATURE (ARM_AEXT_V4xM, 0)
143218822Sdim#define ARM_ARCH_V4	ARM_FEATURE (ARM_AEXT_V4, 0)
144218822Sdim#define ARM_ARCH_V4TxM	ARM_FEATURE (ARM_AEXT_V4TxM, 0)
145218822Sdim#define ARM_ARCH_V4T	ARM_FEATURE (ARM_AEXT_V4T, 0)
146218822Sdim#define ARM_ARCH_V5xM	ARM_FEATURE (ARM_AEXT_V5xM, 0)
147218822Sdim#define ARM_ARCH_V5	ARM_FEATURE (ARM_AEXT_V5, 0)
148218822Sdim#define ARM_ARCH_V5TxM	ARM_FEATURE (ARM_AEXT_V5TxM, 0)
149218822Sdim#define ARM_ARCH_V5T	ARM_FEATURE (ARM_AEXT_V5T, 0)
150218822Sdim#define ARM_ARCH_V5TExP	ARM_FEATURE (ARM_AEXT_V5TExP, 0)
151218822Sdim#define ARM_ARCH_V5TE	ARM_FEATURE (ARM_AEXT_V5TE, 0)
152218822Sdim#define ARM_ARCH_V5TEJ	ARM_FEATURE (ARM_AEXT_V5TEJ, 0)
153218822Sdim#define ARM_ARCH_V6	ARM_FEATURE (ARM_AEXT_V6, 0)
154218822Sdim#define ARM_ARCH_V6K	ARM_FEATURE (ARM_AEXT_V6K, 0)
155218822Sdim#define ARM_ARCH_V6Z	ARM_FEATURE (ARM_AEXT_V6Z, 0)
156218822Sdim#define ARM_ARCH_V6ZK	ARM_FEATURE (ARM_AEXT_V6ZK, 0)
157218822Sdim#define ARM_ARCH_V6T2	ARM_FEATURE (ARM_AEXT_V6T2, 0)
158218822Sdim#define ARM_ARCH_V6KT2	ARM_FEATURE (ARM_AEXT_V6KT2, 0)
159218822Sdim#define ARM_ARCH_V6ZT2	ARM_FEATURE (ARM_AEXT_V6ZT2, 0)
160218822Sdim#define ARM_ARCH_V6ZKT2	ARM_FEATURE (ARM_AEXT_V6ZKT2, 0)
161218822Sdim#define ARM_ARCH_V7	ARM_FEATURE (ARM_AEXT_V7, 0)
162218822Sdim#define ARM_ARCH_V7A	ARM_FEATURE (ARM_AEXT_V7A, 0)
163218822Sdim#define ARM_ARCH_V7R	ARM_FEATURE (ARM_AEXT_V7R, 0)
164218822Sdim#define ARM_ARCH_V7M	ARM_FEATURE (ARM_AEXT_V7M, 0)
16560484Sobrien
166218822Sdim/* Some useful combinations:  */
167218822Sdim#define ARM_ARCH_NONE	ARM_FEATURE (0, 0)
168218822Sdim#define FPU_NONE	ARM_FEATURE (0, 0)
169218822Sdim#define ARM_ANY		ARM_FEATURE (-1, 0)	/* Any basic core.  */
170218822Sdim#define FPU_ANY_HARD	ARM_FEATURE (0, FPU_FPA | FPU_VFP_HARD | FPU_MAVERICK)
171218822Sdim#define ARM_ARCH_THUMB2 ARM_FEATURE (ARM_EXT_V6T2 | ARM_EXT_V7 | ARM_EXT_V7A | ARM_EXT_V7R | ARM_EXT_V7M | ARM_EXT_DIV, 0)
17260484Sobrien
173218822Sdim/* There are too many feature bits to fit in a single word, so use a
174218822Sdim   structure.  For simplicity we put all core features in one word and
175218822Sdim   everything else in the other.  */
176218822Sdimtypedef struct
177218822Sdim{
178218822Sdim  unsigned long core;
179218822Sdim  unsigned long coproc;
180218822Sdim} arm_feature_set;
18160484Sobrien
182218822Sdim#define ARM_CPU_HAS_FEATURE(CPU,FEAT) \
183218822Sdim  (((CPU).core & (FEAT).core) != 0 || ((CPU).coproc & (FEAT).coproc) != 0)
18460484Sobrien
185218822Sdim#define ARM_MERGE_FEATURE_SETS(TARG,F1,F2)	\
186218822Sdim  do {						\
187218822Sdim    (TARG).core = (F1).core | (F2).core;	\
188218822Sdim    (TARG).coproc = (F1).coproc | (F2).coproc;	\
189218822Sdim  } while (0)
19060484Sobrien
191218822Sdim#define ARM_CLEAR_FEATURE(TARG,F1,F2)		\
192218822Sdim  do {						\
193218822Sdim    (TARG).core = (F1).core &~ (F2).core;	\
194218822Sdim    (TARG).coproc = (F1).coproc &~ (F2).coproc;	\
195218822Sdim  } while (0)
19660484Sobrien
197218822Sdim#define ARM_FEATURE(core, coproc) {(core), (coproc)}
198