2002-01-19 Keith Walker <keith.walker@arm.com>
[deliverable/binutils-gdb.git] / gas / config / tc-arm.c
1 /* tc-arm.c -- Assemble for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modified by David Taylor (dtaylor@armltd.co.uk)
6 Cirrus coprocessor mods by Aldy Hernandez (aldyh@redhat.com)
7
8 This file is part of GAS, the GNU Assembler.
9
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to the Free
22 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 02111-1307, USA. */
24
25 #include <string.h>
26 #define NO_RELOC 0
27 #include "as.h"
28 #include "safe-ctype.h"
29
30 /* Need TARGET_CPU. */
31 #include "config.h"
32 #include "subsegs.h"
33 #include "obstack.h"
34 #include "symbols.h"
35 #include "listing.h"
36
37 #ifdef OBJ_ELF
38 #include "elf/arm.h"
39 #include "dwarf2dbg.h"
40 #endif
41
42 /* XXX Set this to 1 after the next binutils release */
43 #define WARN_DEPRECATED 0
44
45 /* The following bitmasks control CPU extensions: */
46 #define ARM_EXT_V1 0x00000001 /* All processors (core set). */
47 #define ARM_EXT_V2 0x00000002 /* Multiply instructions. */
48 #define ARM_EXT_V2S 0x00000004 /* SWP instructions. */
49 #define ARM_EXT_V3 0x00000008 /* MSR MRS. */
50 #define ARM_EXT_V3M 0x00000010 /* Allow long multiplies. */
51 #define ARM_EXT_V4 0x00000020 /* Allow half word loads. */
52 #define ARM_EXT_V4T 0x00000040 /* Thumb v1. */
53 #define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */
54 #define ARM_EXT_V5T 0x00000100 /* Thumb v2. */
55 #define ARM_EXT_V5ExP 0x00000200 /* DSP core set. */
56 #define ARM_EXT_V5E 0x00000400 /* DSP Double transfers. */
57
58 /* Co-processor space extensions. */
59 #define ARM_CEXT_XSCALE 0x00800000 /* Allow MIA etc. */
60 #define ARM_CEXT_MAVERICK 0x00400000 /* Use Cirrus/DSP coprocessor. */
61
62 /* Architectures are the sum of the base and extensions. The ARM ARM (rev E)
63 defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
64 ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE. To these we add
65 three more to cover cores prior to ARM6. Finally, there are cores which
66 implement further extensions in the co-processor space. */
67 #define ARM_ARCH_V1 ARM_EXT_V1
68 #define ARM_ARCH_V2 (ARM_ARCH_V1 | ARM_EXT_V2)
69 #define ARM_ARCH_V2S (ARM_ARCH_V2 | ARM_EXT_V2S)
70 #define ARM_ARCH_V3 (ARM_ARCH_V2S | ARM_EXT_V3)
71 #define ARM_ARCH_V3M (ARM_ARCH_V3 | ARM_EXT_V3M)
72 #define ARM_ARCH_V4xM (ARM_ARCH_V3 | ARM_EXT_V4)
73 #define ARM_ARCH_V4 (ARM_ARCH_V3M | ARM_EXT_V4)
74 #define ARM_ARCH_V4TxM (ARM_ARCH_V4xM | ARM_EXT_V4T)
75 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_EXT_V4T)
76 #define ARM_ARCH_V5xM (ARM_ARCH_V4xM | ARM_EXT_V5)
77 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
78 #define ARM_ARCH_V5TxM (ARM_ARCH_V5xM | ARM_EXT_V4T | ARM_EXT_V5T)
79 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_EXT_V4T | ARM_EXT_V5T)
80 #define ARM_ARCH_V5TExP (ARM_ARCH_V5T | ARM_EXT_V5ExP)
81 #define ARM_ARCH_V5TE (ARM_ARCH_V5TExP | ARM_EXT_V5E)
82
83 /* Processors with specific extensions in the co-processor space. */
84 #define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_CEXT_XSCALE)
85
86 /* Some useful combinations: */
87 #define ARM_ANY 0x0000ffff /* Any basic core. */
88 #define ARM_ALL 0x00ffffff /* Any core + co-processor */
89 #define CPROC_ANY 0x00ff0000 /* Any co-processor */
90 #define FPU_ANY 0xff000000 /* Note this is ~ARM_ALL. */
91
92
93 #define FPU_FPA_EXT_V1 0x80000000 /* Base FPA instruction set. */
94 #define FPU_FPA_EXT_V2 0x40000000 /* LFM/SFM. */
95 #define FPU_VFP_EXT_NONE 0x20000000 /* Use VFP word-ordering. */
96 #define FPU_VFP_EXT_V1xD 0x10000000 /* Base VFP instruction set. */
97 #define FPU_VFP_EXT_V1 0x08000000 /* Double-precision insns. */
98 #define FPU_VFP_EXT_V2 0x04000000 /* ARM10E VFPr1. */
99 #define FPU_NONE 0
100
101 #define FPU_ARCH_FPE FPU_FPA_EXT_V1
102 #define FPU_ARCH_FPA (FPU_ARCH_FPE | FPU_FPA_EXT_V2)
103
104 #define FPU_ARCH_VFP FPU_VFP_EXT_NONE
105 #define FPU_ARCH_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_NONE)
106 #define FPU_ARCH_VFP_V1 (FPU_ARCH_VFP_V1xD | FPU_VFP_EXT_V1)
107 #define FPU_ARCH_VFP_V2 (FPU_ARCH_VFP_V1 | FPU_VFP_EXT_V2)
108
109 /* Types of processor to assemble for. */
110 #define ARM_1 ARM_ARCH_V1
111 #define ARM_2 ARM_ARCH_V2
112 #define ARM_3 ARM_ARCH_V2S
113 #define ARM_250 ARM_ARCH_V2S
114 #define ARM_6 ARM_ARCH_V3
115 #define ARM_7 ARM_ARCH_V3
116 #define ARM_8 ARM_ARCH_V4
117 #define ARM_9 ARM_ARCH_V4T
118 #define ARM_STRONG ARM_ARCH_V4
119 #define ARM_CPU_MASK 0x0000000f /* XXX? */
120
121 #ifndef CPU_DEFAULT
122 #if defined __XSCALE__
123 #define CPU_DEFAULT (ARM_ARCH_XSCALE)
124 #else
125 #if defined __thumb__
126 #define CPU_DEFAULT (ARM_ARCH_V5T)
127 #else
128 #define CPU_DEFAULT ARM_ANY
129 #endif
130 #endif
131 #endif
132
133 /* For backwards compatibility we default to the FPA. */
134 #ifndef FPU_DEFAULT
135 #define FPU_DEFAULT FPU_ARCH_FPA
136 #endif
137
138 #define streq(a, b) (strcmp (a, b) == 0)
139 #define skip_whitespace(str) while (*(str) == ' ') ++(str)
140
141 static unsigned long cpu_variant;
142 static int target_oabi = 0;
143
144 /* Flags stored in private area of BFD structure. */
145 static int uses_apcs_26 = false;
146 static int atpcs = false;
147 static int support_interwork = false;
148 static int uses_apcs_float = false;
149 static int pic_code = false;
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. */
154 static int legacy_cpu = -1;
155 static int legacy_fpu = -1;
156
157 static int mcpu_cpu_opt = -1;
158 static int mcpu_fpu_opt = -1;
159 static int march_cpu_opt = -1;
160 static int march_fpu_opt = -1;
161 static int mfpu_opt = -1;
162
163 /* This array holds the chars that always start a comment. If the
164 pre-processor is disabled, these aren't very useful. */
165 const char comment_chars[] = "@";
166
167 /* This array holds the chars that only start a comment at the beginning of
168 a line. If the line seems to have the form '# 123 filename'
169 .line and .file directives will appear in the pre-processed output. */
170 /* Note that input_file.c hand checks for '#' at the beginning of the
171 first line of the input file. This is because the compiler outputs
172 #NO_APP at the beginning of its output. */
173 /* Also note that comments like this one will always work. */
174 const char line_comment_chars[] = "#";
175
176 const char line_separator_chars[] = ";";
177
178 /* Chars that can be used to separate mant
179 from exp in floating point numbers. */
180 const char EXP_CHARS[] = "eE";
181
182 /* Chars that mean this number is a floating point constant. */
183 /* As in 0f12.456 */
184 /* or 0d1.2345e12 */
185
186 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
187
188 /* Prefix characters that indicate the start of an immediate
189 value. */
190 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
191
192 #ifdef OBJ_ELF
193 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
194 symbolS * GOT_symbol;
195 #endif
196
197 /* Size of relocation record. */
198 const int md_reloc_size = 8;
199
200 /* 0: assemble for ARM,
201 1: assemble for Thumb,
202 2: assemble for Thumb even though target CPU does not support thumb
203 instructions. */
204 static int thumb_mode = 0;
205
206 typedef struct arm_fix
207 {
208 int thumb_mode;
209 } arm_fix_data;
210
211 struct arm_it
212 {
213 const char * error;
214 unsigned long instruction;
215 int size;
216 struct
217 {
218 bfd_reloc_code_real_type type;
219 expressionS exp;
220 int pc_rel;
221 } reloc;
222 };
223
224 struct arm_it inst;
225
226 enum asm_shift_index
227 {
228 SHIFT_LSL = 0,
229 SHIFT_LSR,
230 SHIFT_ASR,
231 SHIFT_ROR,
232 SHIFT_RRX
233 };
234
235 struct asm_shift_properties
236 {
237 enum asm_shift_index index;
238 unsigned long bit_field;
239 unsigned int allows_0 : 1;
240 unsigned int allows_32 : 1;
241 };
242
243 static const struct asm_shift_properties shift_properties [] =
244 {
245 { SHIFT_LSL, 0, 1, 0},
246 { SHIFT_LSR, 0x20, 0, 1},
247 { SHIFT_ASR, 0x40, 0, 1},
248 { SHIFT_ROR, 0x60, 0, 0},
249 { SHIFT_RRX, 0x60, 0, 0}
250 };
251
252 struct asm_shift_name
253 {
254 const char * name;
255 const struct asm_shift_properties * properties;
256 };
257
258 static const struct asm_shift_name shift_names [] =
259 {
260 { "asl", shift_properties + SHIFT_LSL },
261 { "lsl", shift_properties + SHIFT_LSL },
262 { "lsr", shift_properties + SHIFT_LSR },
263 { "asr", shift_properties + SHIFT_ASR },
264 { "ror", shift_properties + SHIFT_ROR },
265 { "rrx", shift_properties + SHIFT_RRX },
266 { "ASL", shift_properties + SHIFT_LSL },
267 { "LSL", shift_properties + SHIFT_LSL },
268 { "LSR", shift_properties + SHIFT_LSR },
269 { "ASR", shift_properties + SHIFT_ASR },
270 { "ROR", shift_properties + SHIFT_ROR },
271 { "RRX", shift_properties + SHIFT_RRX }
272 };
273
274 #define NO_SHIFT_RESTRICT 1
275 #define SHIFT_RESTRICT 0
276
277 #define NUM_FLOAT_VALS 8
278
279 const char * fp_const[] =
280 {
281 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
282 };
283
284 /* Number of littlenums required to hold an extended precision number. */
285 #define MAX_LITTLENUMS 6
286
287 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
288
289 #define FAIL (-1)
290 #define SUCCESS (0)
291
292 /* Whether a Co-processor load/store operation accepts write-back forms. */
293 #define CP_WB_OK 1
294 #define CP_NO_WB 0
295
296 #define SUFF_S 1
297 #define SUFF_D 2
298 #define SUFF_E 3
299 #define SUFF_P 4
300
301 #define CP_T_X 0x00008000
302 #define CP_T_Y 0x00400000
303 #define CP_T_Pre 0x01000000
304 #define CP_T_UD 0x00800000
305 #define CP_T_WB 0x00200000
306
307 #define CONDS_BIT 0x00100000
308 #define LOAD_BIT 0x00100000
309
310 #define DOUBLE_LOAD_FLAG 0x00000001
311
312 struct asm_cond
313 {
314 const char * template;
315 unsigned long value;
316 };
317
318 #define COND_ALWAYS 0xe0000000
319 #define COND_MASK 0xf0000000
320
321 static const struct asm_cond conds[] =
322 {
323 {"eq", 0x00000000},
324 {"ne", 0x10000000},
325 {"cs", 0x20000000}, {"hs", 0x20000000},
326 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
327 {"mi", 0x40000000},
328 {"pl", 0x50000000},
329 {"vs", 0x60000000},
330 {"vc", 0x70000000},
331 {"hi", 0x80000000},
332 {"ls", 0x90000000},
333 {"ge", 0xa0000000},
334 {"lt", 0xb0000000},
335 {"gt", 0xc0000000},
336 {"le", 0xd0000000},
337 {"al", 0xe0000000},
338 {"nv", 0xf0000000}
339 };
340
341 struct asm_psr
342 {
343 const char * template;
344 boolean cpsr;
345 unsigned long field;
346 };
347
348 /* The bit that distnguishes CPSR and SPSR. */
349 #define SPSR_BIT (1 << 22)
350
351 /* How many bits to shift the PSR_xxx bits up by. */
352 #define PSR_SHIFT 16
353
354 #define PSR_c (1 << 0)
355 #define PSR_x (1 << 1)
356 #define PSR_s (1 << 2)
357 #define PSR_f (1 << 3)
358
359 static const struct asm_psr psrs[] =
360 {
361 {"CPSR", true, PSR_c | PSR_f},
362 {"CPSR_all", true, PSR_c | PSR_f},
363 {"SPSR", false, PSR_c | PSR_f},
364 {"SPSR_all", false, PSR_c | PSR_f},
365 {"CPSR_flg", true, PSR_f},
366 {"CPSR_f", true, PSR_f},
367 {"SPSR_flg", false, PSR_f},
368 {"SPSR_f", false, PSR_f},
369 {"CPSR_c", true, PSR_c},
370 {"CPSR_ctl", true, PSR_c},
371 {"SPSR_c", false, PSR_c},
372 {"SPSR_ctl", false, PSR_c},
373 {"CPSR_x", true, PSR_x},
374 {"CPSR_s", true, PSR_s},
375 {"SPSR_x", false, PSR_x},
376 {"SPSR_s", false, PSR_s},
377 /* Combinations of flags. */
378 {"CPSR_fs", true, PSR_f | PSR_s},
379 {"CPSR_fx", true, PSR_f | PSR_x},
380 {"CPSR_fc", true, PSR_f | PSR_c},
381 {"CPSR_sf", true, PSR_s | PSR_f},
382 {"CPSR_sx", true, PSR_s | PSR_x},
383 {"CPSR_sc", true, PSR_s | PSR_c},
384 {"CPSR_xf", true, PSR_x | PSR_f},
385 {"CPSR_xs", true, PSR_x | PSR_s},
386 {"CPSR_xc", true, PSR_x | PSR_c},
387 {"CPSR_cf", true, PSR_c | PSR_f},
388 {"CPSR_cs", true, PSR_c | PSR_s},
389 {"CPSR_cx", true, PSR_c | PSR_x},
390 {"CPSR_fsx", true, PSR_f | PSR_s | PSR_x},
391 {"CPSR_fsc", true, PSR_f | PSR_s | PSR_c},
392 {"CPSR_fxs", true, PSR_f | PSR_x | PSR_s},
393 {"CPSR_fxc", true, PSR_f | PSR_x | PSR_c},
394 {"CPSR_fcs", true, PSR_f | PSR_c | PSR_s},
395 {"CPSR_fcx", true, PSR_f | PSR_c | PSR_x},
396 {"CPSR_sfx", true, PSR_s | PSR_f | PSR_x},
397 {"CPSR_sfc", true, PSR_s | PSR_f | PSR_c},
398 {"CPSR_sxf", true, PSR_s | PSR_x | PSR_f},
399 {"CPSR_sxc", true, PSR_s | PSR_x | PSR_c},
400 {"CPSR_scf", true, PSR_s | PSR_c | PSR_f},
401 {"CPSR_scx", true, PSR_s | PSR_c | PSR_x},
402 {"CPSR_xfs", true, PSR_x | PSR_f | PSR_s},
403 {"CPSR_xfc", true, PSR_x | PSR_f | PSR_c},
404 {"CPSR_xsf", true, PSR_x | PSR_s | PSR_f},
405 {"CPSR_xsc", true, PSR_x | PSR_s | PSR_c},
406 {"CPSR_xcf", true, PSR_x | PSR_c | PSR_f},
407 {"CPSR_xcs", true, PSR_x | PSR_c | PSR_s},
408 {"CPSR_cfs", true, PSR_c | PSR_f | PSR_s},
409 {"CPSR_cfx", true, PSR_c | PSR_f | PSR_x},
410 {"CPSR_csf", true, PSR_c | PSR_s | PSR_f},
411 {"CPSR_csx", true, PSR_c | PSR_s | PSR_x},
412 {"CPSR_cxf", true, PSR_c | PSR_x | PSR_f},
413 {"CPSR_cxs", true, PSR_c | PSR_x | PSR_s},
414 {"CPSR_fsxc", true, PSR_f | PSR_s | PSR_x | PSR_c},
415 {"CPSR_fscx", true, PSR_f | PSR_s | PSR_c | PSR_x},
416 {"CPSR_fxsc", true, PSR_f | PSR_x | PSR_s | PSR_c},
417 {"CPSR_fxcs", true, PSR_f | PSR_x | PSR_c | PSR_s},
418 {"CPSR_fcsx", true, PSR_f | PSR_c | PSR_s | PSR_x},
419 {"CPSR_fcxs", true, PSR_f | PSR_c | PSR_x | PSR_s},
420 {"CPSR_sfxc", true, PSR_s | PSR_f | PSR_x | PSR_c},
421 {"CPSR_sfcx", true, PSR_s | PSR_f | PSR_c | PSR_x},
422 {"CPSR_sxfc", true, PSR_s | PSR_x | PSR_f | PSR_c},
423 {"CPSR_sxcf", true, PSR_s | PSR_x | PSR_c | PSR_f},
424 {"CPSR_scfx", true, PSR_s | PSR_c | PSR_f | PSR_x},
425 {"CPSR_scxf", true, PSR_s | PSR_c | PSR_x | PSR_f},
426 {"CPSR_xfsc", true, PSR_x | PSR_f | PSR_s | PSR_c},
427 {"CPSR_xfcs", true, PSR_x | PSR_f | PSR_c | PSR_s},
428 {"CPSR_xsfc", true, PSR_x | PSR_s | PSR_f | PSR_c},
429 {"CPSR_xscf", true, PSR_x | PSR_s | PSR_c | PSR_f},
430 {"CPSR_xcfs", true, PSR_x | PSR_c | PSR_f | PSR_s},
431 {"CPSR_xcsf", true, PSR_x | PSR_c | PSR_s | PSR_f},
432 {"CPSR_cfsx", true, PSR_c | PSR_f | PSR_s | PSR_x},
433 {"CPSR_cfxs", true, PSR_c | PSR_f | PSR_x | PSR_s},
434 {"CPSR_csfx", true, PSR_c | PSR_s | PSR_f | PSR_x},
435 {"CPSR_csxf", true, PSR_c | PSR_s | PSR_x | PSR_f},
436 {"CPSR_cxfs", true, PSR_c | PSR_x | PSR_f | PSR_s},
437 {"CPSR_cxsf", true, PSR_c | PSR_x | PSR_s | PSR_f},
438 {"SPSR_fs", false, PSR_f | PSR_s},
439 {"SPSR_fx", false, PSR_f | PSR_x},
440 {"SPSR_fc", false, PSR_f | PSR_c},
441 {"SPSR_sf", false, PSR_s | PSR_f},
442 {"SPSR_sx", false, PSR_s | PSR_x},
443 {"SPSR_sc", false, PSR_s | PSR_c},
444 {"SPSR_xf", false, PSR_x | PSR_f},
445 {"SPSR_xs", false, PSR_x | PSR_s},
446 {"SPSR_xc", false, PSR_x | PSR_c},
447 {"SPSR_cf", false, PSR_c | PSR_f},
448 {"SPSR_cs", false, PSR_c | PSR_s},
449 {"SPSR_cx", false, PSR_c | PSR_x},
450 {"SPSR_fsx", false, PSR_f | PSR_s | PSR_x},
451 {"SPSR_fsc", false, PSR_f | PSR_s | PSR_c},
452 {"SPSR_fxs", false, PSR_f | PSR_x | PSR_s},
453 {"SPSR_fxc", false, PSR_f | PSR_x | PSR_c},
454 {"SPSR_fcs", false, PSR_f | PSR_c | PSR_s},
455 {"SPSR_fcx", false, PSR_f | PSR_c | PSR_x},
456 {"SPSR_sfx", false, PSR_s | PSR_f | PSR_x},
457 {"SPSR_sfc", false, PSR_s | PSR_f | PSR_c},
458 {"SPSR_sxf", false, PSR_s | PSR_x | PSR_f},
459 {"SPSR_sxc", false, PSR_s | PSR_x | PSR_c},
460 {"SPSR_scf", false, PSR_s | PSR_c | PSR_f},
461 {"SPSR_scx", false, PSR_s | PSR_c | PSR_x},
462 {"SPSR_xfs", false, PSR_x | PSR_f | PSR_s},
463 {"SPSR_xfc", false, PSR_x | PSR_f | PSR_c},
464 {"SPSR_xsf", false, PSR_x | PSR_s | PSR_f},
465 {"SPSR_xsc", false, PSR_x | PSR_s | PSR_c},
466 {"SPSR_xcf", false, PSR_x | PSR_c | PSR_f},
467 {"SPSR_xcs", false, PSR_x | PSR_c | PSR_s},
468 {"SPSR_cfs", false, PSR_c | PSR_f | PSR_s},
469 {"SPSR_cfx", false, PSR_c | PSR_f | PSR_x},
470 {"SPSR_csf", false, PSR_c | PSR_s | PSR_f},
471 {"SPSR_csx", false, PSR_c | PSR_s | PSR_x},
472 {"SPSR_cxf", false, PSR_c | PSR_x | PSR_f},
473 {"SPSR_cxs", false, PSR_c | PSR_x | PSR_s},
474 {"SPSR_fsxc", false, PSR_f | PSR_s | PSR_x | PSR_c},
475 {"SPSR_fscx", false, PSR_f | PSR_s | PSR_c | PSR_x},
476 {"SPSR_fxsc", false, PSR_f | PSR_x | PSR_s | PSR_c},
477 {"SPSR_fxcs", false, PSR_f | PSR_x | PSR_c | PSR_s},
478 {"SPSR_fcsx", false, PSR_f | PSR_c | PSR_s | PSR_x},
479 {"SPSR_fcxs", false, PSR_f | PSR_c | PSR_x | PSR_s},
480 {"SPSR_sfxc", false, PSR_s | PSR_f | PSR_x | PSR_c},
481 {"SPSR_sfcx", false, PSR_s | PSR_f | PSR_c | PSR_x},
482 {"SPSR_sxfc", false, PSR_s | PSR_x | PSR_f | PSR_c},
483 {"SPSR_sxcf", false, PSR_s | PSR_x | PSR_c | PSR_f},
484 {"SPSR_scfx", false, PSR_s | PSR_c | PSR_f | PSR_x},
485 {"SPSR_scxf", false, PSR_s | PSR_c | PSR_x | PSR_f},
486 {"SPSR_xfsc", false, PSR_x | PSR_f | PSR_s | PSR_c},
487 {"SPSR_xfcs", false, PSR_x | PSR_f | PSR_c | PSR_s},
488 {"SPSR_xsfc", false, PSR_x | PSR_s | PSR_f | PSR_c},
489 {"SPSR_xscf", false, PSR_x | PSR_s | PSR_c | PSR_f},
490 {"SPSR_xcfs", false, PSR_x | PSR_c | PSR_f | PSR_s},
491 {"SPSR_xcsf", false, PSR_x | PSR_c | PSR_s | PSR_f},
492 {"SPSR_cfsx", false, PSR_c | PSR_f | PSR_s | PSR_x},
493 {"SPSR_cfxs", false, PSR_c | PSR_f | PSR_x | PSR_s},
494 {"SPSR_csfx", false, PSR_c | PSR_s | PSR_f | PSR_x},
495 {"SPSR_csxf", false, PSR_c | PSR_s | PSR_x | PSR_f},
496 {"SPSR_cxfs", false, PSR_c | PSR_x | PSR_f | PSR_s},
497 {"SPSR_cxsf", false, PSR_c | PSR_x | PSR_s | PSR_f},
498 };
499
500 enum vfp_dp_reg_pos
501 {
502 VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
503 };
504
505 enum vfp_sp_reg_pos
506 {
507 VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
508 };
509
510 enum vfp_ldstm_type
511 {
512 VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
513 };
514
515 /* VFP system registers. */
516 struct vfp_reg
517 {
518 const char *name;
519 unsigned long regno;
520 };
521
522 static const struct vfp_reg vfp_regs[] =
523 {
524 {"fpsid", 0x00000000},
525 {"FPSID", 0x00000000},
526 {"fpscr", 0x00010000},
527 {"FPSCR", 0x00010000},
528 {"fpexc", 0x00080000},
529 {"FPEXC", 0x00080000}
530 };
531
532 /* Structure for a hash table entry for a register. */
533 struct reg_entry
534 {
535 const char * name;
536 int number;
537 };
538
539 /* Some well known registers that we refer to directly elsewhere. */
540 #define REG_SP 13
541 #define REG_LR 14
542 #define REG_PC 15
543
544 /* These are the standard names. Users can add aliases with .req. */
545 /* Integer Register Numbers. */
546 static const struct reg_entry rn_table[] =
547 {
548 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
549 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
550 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
551 {"r12", 12}, {"r13", REG_SP}, {"r14", REG_LR}, {"r15", REG_PC},
552 /* ATPCS Synonyms. */
553 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
554 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7},
555 {"v5", 8}, {"v6", 9}, {"v7", 10}, {"v8", 11},
556 /* Well-known aliases. */
557 {"wr", 7},
558 {"sb", 9}, {"sl", 10}, {"fp", 11},
559 {"ip", 12}, {"sp", REG_SP}, {"lr", REG_LR}, {"pc", REG_PC},
560 {NULL, 0}
561 };
562
563 /* Co-processor Numbers. */
564 static const struct reg_entry cp_table[] =
565 {
566 {"p0", 0}, {"p1", 1}, {"p2", 2}, {"p3", 3},
567 {"p4", 4}, {"p5", 5}, {"p6", 6}, {"p7", 7},
568 {"p8", 8}, {"p9", 9}, {"p10", 10}, {"p11", 11},
569 {"p12", 12}, {"p13", 13}, {"p14", 14}, {"p15", 15},
570 {NULL, 0}
571 };
572
573 /* Co-processor Register Numbers. */
574 static const struct reg_entry cn_table[] =
575 {
576 {"c0", 0}, {"c1", 1}, {"c2", 2}, {"c3", 3},
577 {"c4", 4}, {"c5", 5}, {"c6", 6}, {"c7", 7},
578 {"c8", 8}, {"c9", 9}, {"c10", 10}, {"c11", 11},
579 {"c12", 12}, {"c13", 13}, {"c14", 14}, {"c15", 15},
580 /* Not really valid, but kept for back-wards compatibility. */
581 {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
582 {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
583 {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
584 {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
585 {NULL, 0}
586 };
587
588 /* FPA Registers. */
589 static const struct reg_entry fn_table[] =
590 {
591 {"f0", 0}, {"f1", 1}, {"f2", 2}, {"f3", 3},
592 {"f4", 4}, {"f5", 5}, {"f6", 6}, {"f7", 7},
593 {NULL, 0}
594 };
595
596 /* VFP SP Registers. */
597 static const struct reg_entry sn_table[] =
598 {
599 {"s0", 0}, {"s1", 1}, {"s2", 2}, {"s3", 3},
600 {"s4", 4}, {"s5", 5}, {"s6", 6}, {"s7", 7},
601 {"s8", 8}, {"s9", 9}, {"s10", 10}, {"s11", 11},
602 {"s12", 12}, {"s13", 13}, {"s14", 14}, {"s15", 15},
603 {"s16", 16}, {"s17", 17}, {"s18", 18}, {"s19", 19},
604 {"s20", 20}, {"s21", 21}, {"s22", 22}, {"s23", 23},
605 {"s24", 24}, {"s25", 25}, {"s26", 26}, {"s27", 27},
606 {"s28", 28}, {"s29", 29}, {"s30", 30}, {"s31", 31},
607 {NULL, 0}
608 };
609
610 /* VFP DP Registers. */
611 static const struct reg_entry dn_table[] =
612 {
613 {"d0", 0}, {"d1", 1}, {"d2", 2}, {"d3", 3},
614 {"d4", 4}, {"d5", 5}, {"d6", 6}, {"d7", 7},
615 {"d8", 8}, {"d9", 9}, {"d10", 10}, {"d11", 11},
616 {"d12", 12}, {"d13", 13}, {"d14", 14}, {"d15", 15},
617 {NULL, 0}
618 };
619
620 /* Cirrus DSP coprocessor registers. */
621 static const struct reg_entry mav_mvf_table[] =
622 {
623 {"mvf0", 0}, {"mvf1", 1}, {"mvf2", 2}, {"mvf3", 3},
624 {"mvf4", 4}, {"mvf5", 5}, {"mvf6", 6}, {"mvf7", 7},
625 {"mvf8", 8}, {"mvf9", 9}, {"mvf10", 10}, {"mvf11", 11},
626 {"mvf12", 12}, {"mvf13", 13}, {"mvf14", 14}, {"mvf15", 15},
627 {NULL, 0}
628 };
629
630 static const struct reg_entry mav_mvd_table[] =
631 {
632 {"mvd0", 0}, {"mvd1", 1}, {"mvd2", 2}, {"mvd3", 3},
633 {"mvd4", 4}, {"mvd5", 5}, {"mvd6", 6}, {"mvd7", 7},
634 {"mvd8", 8}, {"mvd9", 9}, {"mvd10", 10}, {"mvd11", 11},
635 {"mvd12", 12}, {"mvd13", 13}, {"mvd14", 14}, {"mvd15", 15},
636 {NULL, 0}
637 };
638
639 static const struct reg_entry mav_mvfx_table[] =
640 {
641 {"mvfx0", 0}, {"mvfx1", 1}, {"mvfx2", 2}, {"mvfx3", 3},
642 {"mvfx4", 4}, {"mvfx5", 5}, {"mvfx6", 6}, {"mvfx7", 7},
643 {"mvfx8", 8}, {"mvfx9", 9}, {"mvfx10", 10}, {"mvfx11", 11},
644 {"mvfx12", 12}, {"mvfx13", 13}, {"mvfx14", 14}, {"mvfx15", 15},
645 {NULL, 0}
646 };
647
648 static const struct reg_entry mav_mvdx_table[] =
649 {
650 {"mvdx0", 0}, {"mvdx1", 1}, {"mvdx2", 2}, {"mvdx3", 3},
651 {"mvdx4", 4}, {"mvdx5", 5}, {"mvdx6", 6}, {"mvdx7", 7},
652 {"mvdx8", 8}, {"mvdx9", 9}, {"mvdx10", 10}, {"mvdx11", 11},
653 {"mvdx12", 12}, {"mvdx13", 13}, {"mvdx14", 14}, {"mvdx15", 15},
654 {NULL, 0}
655 };
656
657 static const struct reg_entry mav_mvax_table[] =
658 {
659 {"mvax0", 0}, {"mvax1", 1}, {"mvax2", 2}, {"mvax3", 3},
660 {NULL, 0}
661 };
662
663 static const struct reg_entry mav_dspsc_table[] =
664 {
665 {"dspsc", 0},
666 {NULL, 0}
667 };
668
669 struct reg_map
670 {
671 const struct reg_entry *names;
672 int max_regno;
673 struct hash_control *htab;
674 const char *expected;
675 };
676
677 struct reg_map all_reg_maps[] =
678 {
679 {rn_table, 15, NULL, N_("ARM register expected")},
680 {cp_table, 15, NULL, N_("bad or missing co-processor number")},
681 {cn_table, 15, NULL, N_("co-processor register expected")},
682 {fn_table, 7, NULL, N_("FPA register expected")},
683 {sn_table, 31, NULL, N_("VFP single precision register expected")},
684 {dn_table, 15, NULL, N_("VFP double precision register expected")},
685 {mav_mvf_table, 15, NULL, N_("Maverick MVF register expected")},
686 {mav_mvd_table, 15, NULL, N_("Maverick MVD register expected")},
687 {mav_mvfx_table, 15, NULL, N_("Maverick MVFX register expected")},
688 {mav_mvdx_table, 15, NULL, N_("Maverick MVFX register expected")},
689 {mav_mvax_table, 3, NULL, N_("Maverick MVAX register expected")},
690 {mav_dspsc_table, 0, NULL, N_("Maverick DSPSC register expected")},
691 };
692
693 /* Enumeration matching entries in table above. */
694 enum arm_reg_type
695 {
696 REG_TYPE_RN = 0,
697 #define REG_TYPE_FIRST REG_TYPE_RN
698 REG_TYPE_CP = 1,
699 REG_TYPE_CN = 2,
700 REG_TYPE_FN = 3,
701 REG_TYPE_SN = 4,
702 REG_TYPE_DN = 5,
703 REG_TYPE_MVF = 6,
704 REG_TYPE_MVD = 7,
705 REG_TYPE_MVFX = 8,
706 REG_TYPE_MVDX = 9,
707 REG_TYPE_MVAX = 10,
708 REG_TYPE_DSPSC = 11,
709
710 REG_TYPE_MAX = 12
711 };
712
713 /* Functions called by parser. */
714 /* ARM instructions. */
715 static void do_arit PARAMS ((char *));
716 static void do_cmp PARAMS ((char *));
717 static void do_mov PARAMS ((char *));
718 static void do_ldst PARAMS ((char *));
719 static void do_ldstt PARAMS ((char *));
720 static void do_ldmstm PARAMS ((char *));
721 static void do_branch PARAMS ((char *));
722 static void do_swi PARAMS ((char *));
723
724 /* Pseudo Op codes. */
725 static void do_adr PARAMS ((char *));
726 static void do_adrl PARAMS ((char *));
727 static void do_empty PARAMS ((char *));
728
729 /* ARM v2. */
730 static void do_mul PARAMS ((char *));
731 static void do_mla PARAMS ((char *));
732
733 /* ARM v2S. */
734 static void do_swap PARAMS ((char *));
735
736 /* ARM v3. */
737 static void do_msr PARAMS ((char *));
738 static void do_mrs PARAMS ((char *));
739
740 /* ARM v3M. */
741 static void do_mull PARAMS ((char *));
742
743 /* ARM v4. */
744 static void do_ldstv4 PARAMS ((char *));
745
746 /* ARM v4T. */
747 static void do_bx PARAMS ((char *));
748
749 /* ARM v5. */
750 static void do_blx PARAMS ((char *));
751 static void do_bkpt PARAMS ((char *));
752 static void do_clz PARAMS ((char *));
753 static void do_lstc2 PARAMS ((char *));
754 static void do_cdp2 PARAMS ((char *));
755 static void do_co_reg2 PARAMS ((char *));
756
757 /* ARM v5ExP. */
758 static void do_smla PARAMS ((char *));
759 static void do_smlal PARAMS ((char *));
760 static void do_smul PARAMS ((char *));
761 static void do_qadd PARAMS ((char *));
762
763 /* ARM v5E. */
764 static void do_pld PARAMS ((char *));
765 static void do_ldrd PARAMS ((char *));
766 static void do_co_reg2c PARAMS ((char *));
767
768 /* Coprocessor Instructions. */
769 static void do_cdp PARAMS ((char *));
770 static void do_lstc PARAMS ((char *));
771 static void do_co_reg PARAMS ((char *));
772
773 /* FPA instructions. */
774 static void do_fpa_ctrl PARAMS ((char *));
775 static void do_fpa_ldst PARAMS ((char *));
776 static void do_fpa_ldmstm PARAMS ((char *));
777 static void do_fpa_dyadic PARAMS ((char *));
778 static void do_fpa_monadic PARAMS ((char *));
779 static void do_fpa_cmp PARAMS ((char *));
780 static void do_fpa_from_reg PARAMS ((char *));
781 static void do_fpa_to_reg PARAMS ((char *));
782
783 /* VFP instructions. */
784 static void do_vfp_sp_monadic PARAMS ((char *));
785 static void do_vfp_dp_monadic PARAMS ((char *));
786 static void do_vfp_sp_dyadic PARAMS ((char *));
787 static void do_vfp_dp_dyadic PARAMS ((char *));
788 static void do_vfp_reg_from_sp PARAMS ((char *));
789 static void do_vfp_sp_from_reg PARAMS ((char *));
790 static void do_vfp_sp_reg2 PARAMS ((char *));
791 static void do_vfp_reg_from_dp PARAMS ((char *));
792 static void do_vfp_reg2_from_dp PARAMS ((char *));
793 static void do_vfp_dp_from_reg PARAMS ((char *));
794 static void do_vfp_dp_from_reg2 PARAMS ((char *));
795 static void do_vfp_reg_from_ctrl PARAMS ((char *));
796 static void do_vfp_ctrl_from_reg PARAMS ((char *));
797 static void do_vfp_sp_ldst PARAMS ((char *));
798 static void do_vfp_dp_ldst PARAMS ((char *));
799 static void do_vfp_sp_ldstmia PARAMS ((char *));
800 static void do_vfp_sp_ldstmdb PARAMS ((char *));
801 static void do_vfp_dp_ldstmia PARAMS ((char *));
802 static void do_vfp_dp_ldstmdb PARAMS ((char *));
803 static void do_vfp_xp_ldstmia PARAMS ((char *));
804 static void do_vfp_xp_ldstmdb PARAMS ((char *));
805 static void do_vfp_sp_compare_z PARAMS ((char *));
806 static void do_vfp_dp_compare_z PARAMS ((char *));
807 static void do_vfp_dp_sp_cvt PARAMS ((char *));
808 static void do_vfp_sp_dp_cvt PARAMS ((char *));
809
810 /* XScale. */
811 static void do_mia PARAMS ((char *));
812 static void do_mar PARAMS ((char *));
813 static void do_mra PARAMS ((char *));
814
815 /* Maverick. */
816 static void do_c_binops PARAMS ((char *, int, enum arm_reg_type,
817 enum arm_reg_type));
818 static void do_c_binops_1a PARAMS ((char *));
819 static void do_c_binops_1b PARAMS ((char *));
820 static void do_c_binops_1c PARAMS ((char *));
821 static void do_c_binops_1d PARAMS ((char *));
822 static void do_c_binops_1e PARAMS ((char *));
823 static void do_c_binops_1f PARAMS ((char *));
824 static void do_c_binops_1g PARAMS ((char *));
825 static void do_c_binops_1h PARAMS ((char *));
826 static void do_c_binops_1i PARAMS ((char *));
827 static void do_c_binops_1j PARAMS ((char *));
828 static void do_c_binops_1k PARAMS ((char *));
829 static void do_c_binops_1l PARAMS ((char *));
830 static void do_c_binops_1m PARAMS ((char *));
831 static void do_c_binops_1n PARAMS ((char *));
832 static void do_c_binops_1o PARAMS ((char *));
833 static void do_c_binops_2a PARAMS ((char *));
834 static void do_c_binops_2b PARAMS ((char *));
835 static void do_c_binops_2c PARAMS ((char *));
836 static void do_c_binops_3a PARAMS ((char *));
837 static void do_c_binops_3b PARAMS ((char *));
838 static void do_c_binops_3c PARAMS ((char *));
839 static void do_c_binops_3d PARAMS ((char *));
840 static void do_c_triple PARAMS ((char *, int, enum arm_reg_type,
841 enum arm_reg_type,
842 enum arm_reg_type));
843 static void do_c_triple_4a PARAMS ((char *));
844 static void do_c_triple_4b PARAMS ((char *));
845 static void do_c_triple_5a PARAMS ((char *));
846 static void do_c_triple_5b PARAMS ((char *));
847 static void do_c_triple_5c PARAMS ((char *));
848 static void do_c_triple_5d PARAMS ((char *));
849 static void do_c_triple_5e PARAMS ((char *));
850 static void do_c_triple_5f PARAMS ((char *));
851 static void do_c_triple_5g PARAMS ((char *));
852 static void do_c_triple_5h PARAMS ((char *));
853 static void do_c_quad PARAMS ((char *, int, enum arm_reg_type,
854 enum arm_reg_type,
855 enum arm_reg_type,
856 enum arm_reg_type));
857 static void do_c_quad_6a PARAMS ((char *));
858 static void do_c_quad_6b PARAMS ((char *));
859 static void do_c_dspsc_1 PARAMS ((char *));
860 static void do_c_dspsc_2 PARAMS ((char *));
861 static void do_c_shift PARAMS ((char *, enum arm_reg_type,
862 enum arm_reg_type));
863 static void do_c_shift_1 PARAMS ((char *));
864 static void do_c_shift_2 PARAMS ((char *));
865 static void do_c_ldst PARAMS ((char *, enum arm_reg_type));
866 static void do_c_ldst_1 PARAMS ((char *));
867 static void do_c_ldst_2 PARAMS ((char *));
868 static void do_c_ldst_3 PARAMS ((char *));
869 static void do_c_ldst_4 PARAMS ((char *));
870
871 static int cirrus_reg_required_here PARAMS ((char **, int,
872 enum arm_reg_type));
873 static int cirrus_parse_offset PARAMS ((char **, int *));
874
875 static void fix_new_arm PARAMS ((fragS *, int, short, expressionS *,
876 int, int));
877 static int arm_reg_parse PARAMS ((char **, struct hash_control *));
878 static enum arm_reg_type arm_reg_parse_any PARAMS ((char *));
879 static const struct asm_psr * arm_psr_parse PARAMS ((char **));
880 static void symbol_locate PARAMS ((symbolS *, const char *, segT, valueT,
881 fragS *));
882 static int add_to_lit_pool PARAMS ((void));
883 static unsigned validate_immediate PARAMS ((unsigned));
884 static unsigned validate_immediate_twopart PARAMS ((unsigned int,
885 unsigned int *));
886 static int validate_offset_imm PARAMS ((unsigned int, int));
887 static void opcode_select PARAMS ((int));
888 static void end_of_line PARAMS ((char *));
889 static int reg_required_here PARAMS ((char **, int));
890 static int psr_required_here PARAMS ((char **));
891 static int co_proc_number PARAMS ((char **));
892 static int cp_opc_expr PARAMS ((char **, int, int));
893 static int cp_reg_required_here PARAMS ((char **, int));
894 static int fp_reg_required_here PARAMS ((char **, int));
895 static int vfp_sp_reg_required_here PARAMS ((char **, enum vfp_sp_reg_pos));
896 static int vfp_dp_reg_required_here PARAMS ((char **, enum vfp_dp_reg_pos));
897 static void vfp_sp_ldstm PARAMS ((char *, enum vfp_ldstm_type));
898 static void vfp_dp_ldstm PARAMS ((char *, enum vfp_ldstm_type));
899 static long vfp_sp_reg_list PARAMS ((char **, enum vfp_sp_reg_pos));
900 static long vfp_dp_reg_list PARAMS ((char **));
901 static int vfp_psr_required_here PARAMS ((char **str));
902 static const struct vfp_reg *vfp_psr_parse PARAMS ((char **str));
903 static int cp_address_offset PARAMS ((char **));
904 static int cp_address_required_here PARAMS ((char **, int));
905 static int my_get_float_expression PARAMS ((char **));
906 static int skip_past_comma PARAMS ((char **));
907 static int walk_no_bignums PARAMS ((symbolS *));
908 static int negate_data_op PARAMS ((unsigned long *, unsigned long));
909 static int data_op2 PARAMS ((char **));
910 static int fp_op2 PARAMS ((char **));
911 static long reg_list PARAMS ((char **));
912 static void thumb_load_store PARAMS ((char *, int, int));
913 static int decode_shift PARAMS ((char **, int));
914 static int ldst_extend PARAMS ((char **));
915 static int ldst_extend_v4 PARAMS ((char **));
916 static void thumb_add_sub PARAMS ((char *, int));
917 static void insert_reg PARAMS ((const struct reg_entry *,
918 struct hash_control *));
919 static void thumb_shift PARAMS ((char *, int));
920 static void thumb_mov_compare PARAMS ((char *, int));
921 static void build_arm_ops_hsh PARAMS ((void));
922 static void set_constant_flonums PARAMS ((void));
923 static valueT md_chars_to_number PARAMS ((char *, int));
924 static void build_reg_hsh PARAMS ((struct reg_map *));
925 static void insert_reg_alias PARAMS ((char *, int, struct hash_control *));
926 static int create_register_alias PARAMS ((char *, char *));
927 static void output_inst PARAMS ((const char *));
928 static int accum0_required_here PARAMS ((char **));
929 static int ld_mode_required_here PARAMS ((char **));
930 static void do_branch25 PARAMS ((char *));
931 static symbolS * find_real_start PARAMS ((symbolS *));
932 #ifdef OBJ_ELF
933 static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
934 #endif
935
936 /* ARM instructions take 4bytes in the object file, Thumb instructions
937 take 2: */
938 #define INSN_SIZE 4
939
940 /* "INSN<cond> X,Y" where X:bit12, Y:bit16. */
941 #define CIRRUS_MODE1 0x100c
942
943 /* "INSN<cond> X,Y" where X:bit16, Y:bit12. */
944 #define CIRRUS_MODE2 0x0c10
945
946 /* "INSN<cond> X,Y" where X:0, Y:bit16. */
947 #define CIRRUS_MODE3 0x1000
948
949 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12. */
950 #define CIRRUS_MODE4 0x0c0010
951
952 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0. */
953 #define CIRRUS_MODE5 0x00100c
954
955 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0. */
956 #define CIRRUS_MODE6 0x00100c05
957
958 struct asm_opcode
959 {
960 /* Basic string to match. */
961 const char * template;
962
963 /* Basic instruction code. */
964 unsigned long value;
965
966 /* Offset into the template where the condition code (if any) will be.
967 If zero, then the instruction is never conditional. */
968 unsigned cond_offset;
969
970 /* Which architecture variant provides this instruction. */
971 unsigned long variant;
972
973 /* Function to call to parse args. */
974 void (* parms) PARAMS ((char *));
975 };
976
977 static const struct asm_opcode insns[] =
978 {
979 /* Core ARM Instructions. */
980 {"and", 0xe0000000, 3, ARM_EXT_V1, do_arit},
981 {"ands", 0xe0100000, 3, ARM_EXT_V1, do_arit},
982 {"eor", 0xe0200000, 3, ARM_EXT_V1, do_arit},
983 {"eors", 0xe0300000, 3, ARM_EXT_V1, do_arit},
984 {"sub", 0xe0400000, 3, ARM_EXT_V1, do_arit},
985 {"subs", 0xe0500000, 3, ARM_EXT_V1, do_arit},
986 {"rsb", 0xe0600000, 3, ARM_EXT_V1, do_arit},
987 {"rsbs", 0xe0700000, 3, ARM_EXT_V1, do_arit},
988 {"add", 0xe0800000, 3, ARM_EXT_V1, do_arit},
989 {"adds", 0xe0900000, 3, ARM_EXT_V1, do_arit},
990 {"adc", 0xe0a00000, 3, ARM_EXT_V1, do_arit},
991 {"adcs", 0xe0b00000, 3, ARM_EXT_V1, do_arit},
992 {"sbc", 0xe0c00000, 3, ARM_EXT_V1, do_arit},
993 {"sbcs", 0xe0d00000, 3, ARM_EXT_V1, do_arit},
994 {"rsc", 0xe0e00000, 3, ARM_EXT_V1, do_arit},
995 {"rscs", 0xe0f00000, 3, ARM_EXT_V1, do_arit},
996 {"orr", 0xe1800000, 3, ARM_EXT_V1, do_arit},
997 {"orrs", 0xe1900000, 3, ARM_EXT_V1, do_arit},
998 {"bic", 0xe1c00000, 3, ARM_EXT_V1, do_arit},
999 {"bics", 0xe1d00000, 3, ARM_EXT_V1, do_arit},
1000
1001 {"tst", 0xe1100000, 3, ARM_EXT_V1, do_cmp},
1002 {"tsts", 0xe1100000, 3, ARM_EXT_V1, do_cmp},
1003 {"tstp", 0xe110f000, 3, ARM_EXT_V1, do_cmp},
1004 {"teq", 0xe1300000, 3, ARM_EXT_V1, do_cmp},
1005 {"teqs", 0xe1300000, 3, ARM_EXT_V1, do_cmp},
1006 {"teqp", 0xe130f000, 3, ARM_EXT_V1, do_cmp},
1007 {"cmp", 0xe1500000, 3, ARM_EXT_V1, do_cmp},
1008 {"cmps", 0xe1500000, 3, ARM_EXT_V1, do_cmp},
1009 {"cmpp", 0xe150f000, 3, ARM_EXT_V1, do_cmp},
1010 {"cmn", 0xe1700000, 3, ARM_EXT_V1, do_cmp},
1011 {"cmns", 0xe1700000, 3, ARM_EXT_V1, do_cmp},
1012 {"cmnp", 0xe170f000, 3, ARM_EXT_V1, do_cmp},
1013
1014 {"mov", 0xe1a00000, 3, ARM_EXT_V1, do_mov},
1015 {"movs", 0xe1b00000, 3, ARM_EXT_V1, do_mov},
1016 {"mvn", 0xe1e00000, 3, ARM_EXT_V1, do_mov},
1017 {"mvns", 0xe1f00000, 3, ARM_EXT_V1, do_mov},
1018
1019 {"ldr", 0xe4100000, 3, ARM_EXT_V1, do_ldst},
1020 {"ldrb", 0xe4500000, 3, ARM_EXT_V1, do_ldst},
1021 {"ldrt", 0xe4300000, 3, ARM_EXT_V1, do_ldstt},
1022 {"ldrbt", 0xe4700000, 3, ARM_EXT_V1, do_ldstt},
1023 {"str", 0xe4000000, 3, ARM_EXT_V1, do_ldst},
1024 {"strb", 0xe4400000, 3, ARM_EXT_V1, do_ldst},
1025 {"strt", 0xe4200000, 3, ARM_EXT_V1, do_ldstt},
1026 {"strbt", 0xe4600000, 3, ARM_EXT_V1, do_ldstt},
1027
1028 {"stmia", 0xe8800000, 3, ARM_EXT_V1, do_ldmstm},
1029 {"stmib", 0xe9800000, 3, ARM_EXT_V1, do_ldmstm},
1030 {"stmda", 0xe8000000, 3, ARM_EXT_V1, do_ldmstm},
1031 {"stmdb", 0xe9000000, 3, ARM_EXT_V1, do_ldmstm},
1032 {"stmfd", 0xe9000000, 3, ARM_EXT_V1, do_ldmstm},
1033 {"stmfa", 0xe9800000, 3, ARM_EXT_V1, do_ldmstm},
1034 {"stmea", 0xe8800000, 3, ARM_EXT_V1, do_ldmstm},
1035 {"stmed", 0xe8000000, 3, ARM_EXT_V1, do_ldmstm},
1036
1037 {"ldmia", 0xe8900000, 3, ARM_EXT_V1, do_ldmstm},
1038 {"ldmib", 0xe9900000, 3, ARM_EXT_V1, do_ldmstm},
1039 {"ldmda", 0xe8100000, 3, ARM_EXT_V1, do_ldmstm},
1040 {"ldmdb", 0xe9100000, 3, ARM_EXT_V1, do_ldmstm},
1041 {"ldmfd", 0xe8900000, 3, ARM_EXT_V1, do_ldmstm},
1042 {"ldmfa", 0xe8100000, 3, ARM_EXT_V1, do_ldmstm},
1043 {"ldmea", 0xe9100000, 3, ARM_EXT_V1, do_ldmstm},
1044 {"ldmed", 0xe9900000, 3, ARM_EXT_V1, do_ldmstm},
1045
1046 {"swi", 0xef000000, 3, ARM_EXT_V1, do_swi},
1047 #ifdef TE_WINCE
1048 /* XXX This is the wrong place to do this. Think multi-arch. */
1049 {"bl", 0xeb000000, 2, ARM_EXT_V1, do_branch},
1050 {"b", 0xea000000, 1, ARM_EXT_V1, do_branch},
1051 #else
1052 {"bl", 0xebfffffe, 2, ARM_EXT_V1, do_branch},
1053 {"b", 0xeafffffe, 1, ARM_EXT_V1, do_branch},
1054 #endif
1055
1056 /* Pseudo ops. */
1057 {"adr", 0xe28f0000, 3, ARM_EXT_V1, do_adr},
1058 {"adrl", 0xe28f0000, 3, ARM_EXT_V1, do_adrl},
1059 {"nop", 0xe1a00000, 3, ARM_EXT_V1, do_empty},
1060
1061 /* ARM 2 multiplies. */
1062 {"mul", 0xe0000090, 3, ARM_EXT_V2, do_mul},
1063 {"muls", 0xe0100090, 3, ARM_EXT_V2, do_mul},
1064 {"mla", 0xe0200090, 3, ARM_EXT_V2, do_mla},
1065 {"mlas", 0xe0300090, 3, ARM_EXT_V2, do_mla},
1066
1067 /* Generic copressor instructions. */
1068 {"cdp", 0xee000000, 3, ARM_EXT_V2, do_cdp},
1069 {"ldc", 0xec100000, 3, ARM_EXT_V2, do_lstc},
1070 {"ldcl", 0xec500000, 3, ARM_EXT_V2, do_lstc},
1071 {"stc", 0xec000000, 3, ARM_EXT_V2, do_lstc},
1072 {"stcl", 0xec400000, 3, ARM_EXT_V2, do_lstc},
1073 {"mcr", 0xee000010, 3, ARM_EXT_V2, do_co_reg},
1074 {"mrc", 0xee100010, 3, ARM_EXT_V2, do_co_reg},
1075
1076 /* ARM 3 - swp instructions. */
1077 {"swp", 0xe1000090, 3, ARM_EXT_V2S, do_swap},
1078 {"swpb", 0xe1400090, 3, ARM_EXT_V2S, do_swap},
1079
1080 /* ARM 6 Status register instructions. */
1081 {"mrs", 0xe10f0000, 3, ARM_EXT_V3, do_mrs},
1082 {"msr", 0xe120f000, 3, ARM_EXT_V3, do_msr},
1083 /* ScottB: our code uses 0xe128f000 for msr.
1084 NickC: but this is wrong because the bits 16 through 19 are
1085 handled by the PSR_xxx defines above. */
1086
1087 /* ARM 7M long multiplies. */
1088 {"smull", 0xe0c00090, 5, ARM_EXT_V3M, do_mull},
1089 {"smulls", 0xe0d00090, 5, ARM_EXT_V3M, do_mull},
1090 {"umull", 0xe0800090, 5, ARM_EXT_V3M, do_mull},
1091 {"umulls", 0xe0900090, 5, ARM_EXT_V3M, do_mull},
1092 {"smlal", 0xe0e00090, 5, ARM_EXT_V3M, do_mull},
1093 {"smlals", 0xe0f00090, 5, ARM_EXT_V3M, do_mull},
1094 {"umlal", 0xe0a00090, 5, ARM_EXT_V3M, do_mull},
1095 {"umlals", 0xe0b00090, 5, ARM_EXT_V3M, do_mull},
1096
1097 /* ARM Architecture 4. */
1098 {"ldrh", 0xe01000b0, 3, ARM_EXT_V4, do_ldstv4},
1099 {"ldrsh", 0xe01000f0, 3, ARM_EXT_V4, do_ldstv4},
1100 {"ldrsb", 0xe01000d0, 3, ARM_EXT_V4, do_ldstv4},
1101 {"strh", 0xe00000b0, 3, ARM_EXT_V4, do_ldstv4},
1102
1103 /* ARM Architecture 4T. */
1104 /* Note: bx (and blx) are required on V5, even if the processor does
1105 not support Thumb. */
1106 {"bx", 0xe12fff10, 2, ARM_EXT_V4T | ARM_EXT_V5, do_bx},
1107
1108 /* ARM Architecture 5. */
1109 /* Note: blx has 2 variants, so the .value is set dynamically.
1110 Only one of the variants has conditional execution. */
1111 {"blx", 0xe0000000, 3, ARM_EXT_V5, do_blx},
1112 {"clz", 0xe16f0f10, 3, ARM_EXT_V5, do_clz},
1113 {"bkpt", 0xe1200070, 0, ARM_EXT_V5, do_bkpt},
1114 {"ldc2", 0xfc100000, 0, ARM_EXT_V5, do_lstc2},
1115 {"ldc2l", 0xfc500000, 0, ARM_EXT_V5, do_lstc2},
1116 {"stc2", 0xfc000000, 0, ARM_EXT_V5, do_lstc2},
1117 {"stc2l", 0xfc400000, 0, ARM_EXT_V5, do_lstc2},
1118 {"cdp2", 0xfe000000, 0, ARM_EXT_V5, do_cdp2},
1119 {"mcr2", 0xfe000010, 0, ARM_EXT_V5, do_co_reg2},
1120 {"mrc2", 0xfe100010, 0, ARM_EXT_V5, do_co_reg2},
1121
1122 /* ARM Architecture 5ExP. */
1123 {"smlabb", 0xe1000080, 6, ARM_EXT_V5ExP, do_smla},
1124 {"smlatb", 0xe10000a0, 6, ARM_EXT_V5ExP, do_smla},
1125 {"smlabt", 0xe10000c0, 6, ARM_EXT_V5ExP, do_smla},
1126 {"smlatt", 0xe10000e0, 6, ARM_EXT_V5ExP, do_smla},
1127
1128 {"smlawb", 0xe1200080, 6, ARM_EXT_V5ExP, do_smla},
1129 {"smlawt", 0xe12000c0, 6, ARM_EXT_V5ExP, do_smla},
1130
1131 {"smlalbb", 0xe1400080, 7, ARM_EXT_V5ExP, do_smlal},
1132 {"smlaltb", 0xe14000a0, 7, ARM_EXT_V5ExP, do_smlal},
1133 {"smlalbt", 0xe14000c0, 7, ARM_EXT_V5ExP, do_smlal},
1134 {"smlaltt", 0xe14000e0, 7, ARM_EXT_V5ExP, do_smlal},
1135
1136 {"smulbb", 0xe1600080, 6, ARM_EXT_V5ExP, do_smul},
1137 {"smultb", 0xe16000a0, 6, ARM_EXT_V5ExP, do_smul},
1138 {"smulbt", 0xe16000c0, 6, ARM_EXT_V5ExP, do_smul},
1139 {"smultt", 0xe16000e0, 6, ARM_EXT_V5ExP, do_smul},
1140
1141 {"smulwb", 0xe12000a0, 6, ARM_EXT_V5ExP, do_smul},
1142 {"smulwt", 0xe12000e0, 6, ARM_EXT_V5ExP, do_smul},
1143
1144 {"qadd", 0xe1000050, 4, ARM_EXT_V5ExP, do_qadd},
1145 {"qdadd", 0xe1400050, 5, ARM_EXT_V5ExP, do_qadd},
1146 {"qsub", 0xe1200050, 4, ARM_EXT_V5ExP, do_qadd},
1147 {"qdsub", 0xe1600050, 5, ARM_EXT_V5ExP, do_qadd},
1148
1149 /* ARM Architecture 5E. */
1150 {"pld", 0xf450f000, 0, ARM_EXT_V5E, do_pld},
1151 {"ldrd", 0xe00000d0, 3, ARM_EXT_V5E, do_ldrd},
1152 {"strd", 0xe00000f0, 3, ARM_EXT_V5E, do_ldrd},
1153
1154 {"mcrr", 0xec400000, 4, ARM_EXT_V5E, do_co_reg2c},
1155 {"mrrc", 0xec500000, 4, ARM_EXT_V5E, do_co_reg2c},
1156
1157 /* Core FPA instruction set (V1). */
1158 {"wfs", 0xee200110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1159 {"rfs", 0xee300110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1160 {"wfc", 0xee400110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1161 {"rfc", 0xee500110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1162
1163 {"ldfs", 0xec100100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1164 {"ldfd", 0xec108100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1165 {"ldfe", 0xec500100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1166 {"ldfp", 0xec508100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1167
1168 {"stfs", 0xec000100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1169 {"stfd", 0xec008100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1170 {"stfe", 0xec400100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1171 {"stfp", 0xec408100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1172
1173 {"mvfs", 0xee008100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1174 {"mvfsp", 0xee008120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1175 {"mvfsm", 0xee008140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1176 {"mvfsz", 0xee008160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1177 {"mvfd", 0xee008180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1178 {"mvfdp", 0xee0081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1179 {"mvfdm", 0xee0081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1180 {"mvfdz", 0xee0081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1181 {"mvfe", 0xee088100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1182 {"mvfep", 0xee088120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1183 {"mvfem", 0xee088140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1184 {"mvfez", 0xee088160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1185
1186 {"mnfs", 0xee108100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1187 {"mnfsp", 0xee108120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1188 {"mnfsm", 0xee108140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1189 {"mnfsz", 0xee108160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1190 {"mnfd", 0xee108180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1191 {"mnfdp", 0xee1081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1192 {"mnfdm", 0xee1081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1193 {"mnfdz", 0xee1081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1194 {"mnfe", 0xee188100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1195 {"mnfep", 0xee188120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1196 {"mnfem", 0xee188140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1197 {"mnfez", 0xee188160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1198
1199 {"abss", 0xee208100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1200 {"abssp", 0xee208120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1201 {"abssm", 0xee208140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1202 {"abssz", 0xee208160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1203 {"absd", 0xee208180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1204 {"absdp", 0xee2081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1205 {"absdm", 0xee2081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1206 {"absdz", 0xee2081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1207 {"abse", 0xee288100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1208 {"absep", 0xee288120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1209 {"absem", 0xee288140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1210 {"absez", 0xee288160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1211
1212 {"rnds", 0xee308100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1213 {"rndsp", 0xee308120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1214 {"rndsm", 0xee308140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1215 {"rndsz", 0xee308160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1216 {"rndd", 0xee308180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1217 {"rnddp", 0xee3081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1218 {"rnddm", 0xee3081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1219 {"rnddz", 0xee3081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1220 {"rnde", 0xee388100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1221 {"rndep", 0xee388120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1222 {"rndem", 0xee388140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1223 {"rndez", 0xee388160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1224
1225 {"sqts", 0xee408100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1226 {"sqtsp", 0xee408120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1227 {"sqtsm", 0xee408140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1228 {"sqtsz", 0xee408160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1229 {"sqtd", 0xee408180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1230 {"sqtdp", 0xee4081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1231 {"sqtdm", 0xee4081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1232 {"sqtdz", 0xee4081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1233 {"sqte", 0xee488100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1234 {"sqtep", 0xee488120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1235 {"sqtem", 0xee488140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1236 {"sqtez", 0xee488160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1237
1238 {"logs", 0xee508100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1239 {"logsp", 0xee508120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1240 {"logsm", 0xee508140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1241 {"logsz", 0xee508160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1242 {"logd", 0xee508180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1243 {"logdp", 0xee5081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1244 {"logdm", 0xee5081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1245 {"logdz", 0xee5081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1246 {"loge", 0xee588100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1247 {"logep", 0xee588120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1248 {"logem", 0xee588140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1249 {"logez", 0xee588160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1250
1251 {"lgns", 0xee608100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1252 {"lgnsp", 0xee608120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1253 {"lgnsm", 0xee608140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1254 {"lgnsz", 0xee608160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1255 {"lgnd", 0xee608180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1256 {"lgndp", 0xee6081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1257 {"lgndm", 0xee6081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1258 {"lgndz", 0xee6081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1259 {"lgne", 0xee688100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1260 {"lgnep", 0xee688120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1261 {"lgnem", 0xee688140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1262 {"lgnez", 0xee688160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1263
1264 {"exps", 0xee708100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1265 {"expsp", 0xee708120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1266 {"expsm", 0xee708140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1267 {"expsz", 0xee708160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1268 {"expd", 0xee708180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1269 {"expdp", 0xee7081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1270 {"expdm", 0xee7081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1271 {"expdz", 0xee7081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1272 {"expe", 0xee788100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1273 {"expep", 0xee788120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1274 {"expem", 0xee788140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1275 {"expdz", 0xee788160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1276
1277 {"sins", 0xee808100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1278 {"sinsp", 0xee808120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1279 {"sinsm", 0xee808140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1280 {"sinsz", 0xee808160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1281 {"sind", 0xee808180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1282 {"sindp", 0xee8081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1283 {"sindm", 0xee8081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1284 {"sindz", 0xee8081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1285 {"sine", 0xee888100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1286 {"sinep", 0xee888120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1287 {"sinem", 0xee888140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1288 {"sinez", 0xee888160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1289
1290 {"coss", 0xee908100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1291 {"cossp", 0xee908120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1292 {"cossm", 0xee908140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1293 {"cossz", 0xee908160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1294 {"cosd", 0xee908180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1295 {"cosdp", 0xee9081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1296 {"cosdm", 0xee9081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1297 {"cosdz", 0xee9081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1298 {"cose", 0xee988100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1299 {"cosep", 0xee988120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1300 {"cosem", 0xee988140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1301 {"cosez", 0xee988160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1302
1303 {"tans", 0xeea08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1304 {"tansp", 0xeea08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1305 {"tansm", 0xeea08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1306 {"tansz", 0xeea08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1307 {"tand", 0xeea08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1308 {"tandp", 0xeea081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1309 {"tandm", 0xeea081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1310 {"tandz", 0xeea081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1311 {"tane", 0xeea88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1312 {"tanep", 0xeea88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1313 {"tanem", 0xeea88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1314 {"tanez", 0xeea88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1315
1316 {"asns", 0xeeb08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1317 {"asnsp", 0xeeb08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1318 {"asnsm", 0xeeb08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1319 {"asnsz", 0xeeb08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1320 {"asnd", 0xeeb08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1321 {"asndp", 0xeeb081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1322 {"asndm", 0xeeb081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1323 {"asndz", 0xeeb081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1324 {"asne", 0xeeb88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1325 {"asnep", 0xeeb88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1326 {"asnem", 0xeeb88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1327 {"asnez", 0xeeb88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1328
1329 {"acss", 0xeec08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1330 {"acssp", 0xeec08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1331 {"acssm", 0xeec08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1332 {"acssz", 0xeec08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1333 {"acsd", 0xeec08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1334 {"acsdp", 0xeec081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1335 {"acsdm", 0xeec081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1336 {"acsdz", 0xeec081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1337 {"acse", 0xeec88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1338 {"acsep", 0xeec88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1339 {"acsem", 0xeec88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1340 {"acsez", 0xeec88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1341
1342 {"atns", 0xeed08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1343 {"atnsp", 0xeed08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1344 {"atnsm", 0xeed08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1345 {"atnsz", 0xeed08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1346 {"atnd", 0xeed08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1347 {"atndp", 0xeed081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1348 {"atndm", 0xeed081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1349 {"atndz", 0xeed081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1350 {"atne", 0xeed88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1351 {"atnep", 0xeed88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1352 {"atnem", 0xeed88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1353 {"atnez", 0xeed88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1354
1355 {"urds", 0xeee08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1356 {"urdsp", 0xeee08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1357 {"urdsm", 0xeee08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1358 {"urdsz", 0xeee08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1359 {"urdd", 0xeee08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1360 {"urddp", 0xeee081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1361 {"urddm", 0xeee081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1362 {"urddz", 0xeee081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1363 {"urde", 0xeee88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1364 {"urdep", 0xeee88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1365 {"urdem", 0xeee88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1366 {"urdez", 0xeee88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1367
1368 {"nrms", 0xeef08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1369 {"nrmsp", 0xeef08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1370 {"nrmsm", 0xeef08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1371 {"nrmsz", 0xeef08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1372 {"nrmd", 0xeef08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1373 {"nrmdp", 0xeef081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1374 {"nrmdm", 0xeef081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1375 {"nrmdz", 0xeef081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1376 {"nrme", 0xeef88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1377 {"nrmep", 0xeef88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1378 {"nrmem", 0xeef88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1379 {"nrmez", 0xeef88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1380
1381 {"adfs", 0xee000100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1382 {"adfsp", 0xee000120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1383 {"adfsm", 0xee000140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1384 {"adfsz", 0xee000160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1385 {"adfd", 0xee000180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1386 {"adfdp", 0xee0001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1387 {"adfdm", 0xee0001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1388 {"adfdz", 0xee0001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1389 {"adfe", 0xee080100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1390 {"adfep", 0xee080120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1391 {"adfem", 0xee080140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1392 {"adfez", 0xee080160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1393
1394 {"sufs", 0xee200100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1395 {"sufsp", 0xee200120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1396 {"sufsm", 0xee200140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1397 {"sufsz", 0xee200160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1398 {"sufd", 0xee200180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1399 {"sufdp", 0xee2001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1400 {"sufdm", 0xee2001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1401 {"sufdz", 0xee2001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1402 {"sufe", 0xee280100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1403 {"sufep", 0xee280120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1404 {"sufem", 0xee280140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1405 {"sufez", 0xee280160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1406
1407 {"rsfs", 0xee300100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1408 {"rsfsp", 0xee300120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1409 {"rsfsm", 0xee300140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1410 {"rsfsz", 0xee300160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1411 {"rsfd", 0xee300180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1412 {"rsfdp", 0xee3001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1413 {"rsfdm", 0xee3001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1414 {"rsfdz", 0xee3001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1415 {"rsfe", 0xee380100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1416 {"rsfep", 0xee380120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1417 {"rsfem", 0xee380140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1418 {"rsfez", 0xee380160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1419
1420 {"mufs", 0xee100100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1421 {"mufsp", 0xee100120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1422 {"mufsm", 0xee100140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1423 {"mufsz", 0xee100160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1424 {"mufd", 0xee100180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1425 {"mufdp", 0xee1001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1426 {"mufdm", 0xee1001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1427 {"mufdz", 0xee1001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1428 {"mufe", 0xee180100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1429 {"mufep", 0xee180120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1430 {"mufem", 0xee180140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1431 {"mufez", 0xee180160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1432
1433 {"dvfs", 0xee400100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1434 {"dvfsp", 0xee400120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1435 {"dvfsm", 0xee400140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1436 {"dvfsz", 0xee400160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1437 {"dvfd", 0xee400180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1438 {"dvfdp", 0xee4001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1439 {"dvfdm", 0xee4001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1440 {"dvfdz", 0xee4001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1441 {"dvfe", 0xee480100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1442 {"dvfep", 0xee480120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1443 {"dvfem", 0xee480140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1444 {"dvfez", 0xee480160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1445
1446 {"rdfs", 0xee500100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1447 {"rdfsp", 0xee500120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1448 {"rdfsm", 0xee500140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1449 {"rdfsz", 0xee500160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1450 {"rdfd", 0xee500180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1451 {"rdfdp", 0xee5001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1452 {"rdfdm", 0xee5001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1453 {"rdfdz", 0xee5001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1454 {"rdfe", 0xee580100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1455 {"rdfep", 0xee580120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1456 {"rdfem", 0xee580140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1457 {"rdfez", 0xee580160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1458
1459 {"pows", 0xee600100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1460 {"powsp", 0xee600120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1461 {"powsm", 0xee600140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1462 {"powsz", 0xee600160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1463 {"powd", 0xee600180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1464 {"powdp", 0xee6001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1465 {"powdm", 0xee6001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1466 {"powdz", 0xee6001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1467 {"powe", 0xee680100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1468 {"powep", 0xee680120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1469 {"powem", 0xee680140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1470 {"powez", 0xee680160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1471
1472 {"rpws", 0xee700100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1473 {"rpwsp", 0xee700120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1474 {"rpwsm", 0xee700140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1475 {"rpwsz", 0xee700160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1476 {"rpwd", 0xee700180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1477 {"rpwdp", 0xee7001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1478 {"rpwdm", 0xee7001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1479 {"rpwdz", 0xee7001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1480 {"rpwe", 0xee780100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1481 {"rpwep", 0xee780120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1482 {"rpwem", 0xee780140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1483 {"rpwez", 0xee780160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1484
1485 {"rmfs", 0xee800100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1486 {"rmfsp", 0xee800120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1487 {"rmfsm", 0xee800140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1488 {"rmfsz", 0xee800160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1489 {"rmfd", 0xee800180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1490 {"rmfdp", 0xee8001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1491 {"rmfdm", 0xee8001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1492 {"rmfdz", 0xee8001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1493 {"rmfe", 0xee880100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1494 {"rmfep", 0xee880120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1495 {"rmfem", 0xee880140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1496 {"rmfez", 0xee880160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1497
1498 {"fmls", 0xee900100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1499 {"fmlsp", 0xee900120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1500 {"fmlsm", 0xee900140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1501 {"fmlsz", 0xee900160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1502 {"fmld", 0xee900180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1503 {"fmldp", 0xee9001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1504 {"fmldm", 0xee9001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1505 {"fmldz", 0xee9001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1506 {"fmle", 0xee980100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1507 {"fmlep", 0xee980120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1508 {"fmlem", 0xee980140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1509 {"fmlez", 0xee980160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1510
1511 {"fdvs", 0xeea00100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1512 {"fdvsp", 0xeea00120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1513 {"fdvsm", 0xeea00140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1514 {"fdvsz", 0xeea00160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1515 {"fdvd", 0xeea00180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1516 {"fdvdp", 0xeea001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1517 {"fdvdm", 0xeea001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1518 {"fdvdz", 0xeea001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1519 {"fdve", 0xeea80100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1520 {"fdvep", 0xeea80120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1521 {"fdvem", 0xeea80140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1522 {"fdvez", 0xeea80160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1523
1524 {"frds", 0xeeb00100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1525 {"frdsp", 0xeeb00120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1526 {"frdsm", 0xeeb00140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1527 {"frdsz", 0xeeb00160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1528 {"frdd", 0xeeb00180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1529 {"frddp", 0xeeb001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1530 {"frddm", 0xeeb001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1531 {"frddz", 0xeeb001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1532 {"frde", 0xeeb80100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1533 {"frdep", 0xeeb80120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1534 {"frdem", 0xeeb80140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1535 {"frdez", 0xeeb80160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1536
1537 {"pols", 0xeec00100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1538 {"polsp", 0xeec00120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1539 {"polsm", 0xeec00140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1540 {"polsz", 0xeec00160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1541 {"pold", 0xeec00180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1542 {"poldp", 0xeec001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1543 {"poldm", 0xeec001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1544 {"poldz", 0xeec001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1545 {"pole", 0xeec80100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1546 {"polep", 0xeec80120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1547 {"polem", 0xeec80140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1548 {"polez", 0xeec80160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1549
1550 {"cmf", 0xee90f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1551 {"cmfe", 0xeed0f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1552 {"cnf", 0xeeb0f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1553 {"cnfe", 0xeef0f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1554 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
1555 not be an optional suffix, but part of the instruction. To be
1556 compatible, we accept either. */
1557 {"cmfe", 0xeed0f110, 4, FPU_FPA_EXT_V1, do_fpa_cmp},
1558 {"cnfe", 0xeef0f110, 4, FPU_FPA_EXT_V1, do_fpa_cmp},
1559
1560 {"flts", 0xee000110, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1561 {"fltsp", 0xee000130, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1562 {"fltsm", 0xee000150, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1563 {"fltsz", 0xee000170, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1564 {"fltd", 0xee000190, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1565 {"fltdp", 0xee0001b0, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1566 {"fltdm", 0xee0001d0, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1567 {"fltdz", 0xee0001f0, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1568 {"flte", 0xee080110, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1569 {"fltep", 0xee080130, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1570 {"fltem", 0xee080150, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1571 {"fltez", 0xee080170, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1572
1573 /* The implementation of the FIX instruction is broken on some
1574 assemblers, in that it accepts a precision specifier as well as a
1575 rounding specifier, despite the fact that this is meaningless.
1576 To be more compatible, we accept it as well, though of course it
1577 does not set any bits. */
1578 {"fix", 0xee100110, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1579 {"fixp", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1580 {"fixm", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1581 {"fixz", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1582 {"fixsp", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1583 {"fixsm", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1584 {"fixsz", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1585 {"fixdp", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1586 {"fixdm", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1587 {"fixdz", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1588 {"fixep", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1589 {"fixem", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1590 {"fixez", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1591
1592 /* Instructions that were new with the real FPA, call them V2. */
1593 {"lfm", 0xec100200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1594 {"lfmfd", 0xec900200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1595 {"lfmea", 0xed100200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1596 {"sfm", 0xec000200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1597 {"sfmfd", 0xed000200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1598 {"sfmea", 0xec800200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1599
1600 /* VFP V1xD (single precision). */
1601 /* Moves and type conversions. */
1602 {"fcpys", 0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1603 {"fmrs", 0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
1604 {"fmsr", 0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
1605 {"fmstat", 0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
1606 {"fsitos", 0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1607 {"fuitos", 0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1608 {"ftosis", 0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1609 {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1610 {"ftouis", 0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1611 {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1612 {"fmrx", 0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
1613 {"fmxr", 0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
1614
1615 /* Memory operations. */
1616 {"flds", 0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1617 {"fsts", 0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1618 {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1619 {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1620 {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1621 {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1622 {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1623 {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1624 {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1625 {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1626 {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1627 {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1628 {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1629 {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1630 {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1631 {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1632 {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1633 {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1634
1635 /* Monadic operations. */
1636 {"fabss", 0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1637 {"fnegs", 0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1638 {"fsqrts", 0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1639
1640 /* Dyadic operations. */
1641 {"fadds", 0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1642 {"fsubs", 0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1643 {"fmuls", 0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1644 {"fdivs", 0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1645 {"fmacs", 0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1646 {"fmscs", 0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1647 {"fnmuls", 0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1648 {"fnmacs", 0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1649 {"fnmscs", 0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1650
1651 /* Comparisons. */
1652 {"fcmps", 0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1653 {"fcmpzs", 0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1654 {"fcmpes", 0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1655 {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1656
1657 /* VFP V1 (Double precision). */
1658 /* Moves and type conversions. */
1659 {"fcpyd", 0xeeb00b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1660 {"fcvtds", 0xeeb70ac0, 6, FPU_VFP_EXT_V1, do_vfp_dp_sp_cvt},
1661 {"fcvtsd", 0xeeb70bc0, 6, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1662 {"fmdhr", 0xee200b10, 5, FPU_VFP_EXT_V1, do_vfp_dp_from_reg},
1663 {"fmdlr", 0xee000b10, 5, FPU_VFP_EXT_V1, do_vfp_dp_from_reg},
1664 {"fmrdh", 0xee300b10, 5, FPU_VFP_EXT_V1, do_vfp_reg_from_dp},
1665 {"fmrdl", 0xee100b10, 5, FPU_VFP_EXT_V1, do_vfp_reg_from_dp},
1666 {"fsitod", 0xeeb80bc0, 6, FPU_VFP_EXT_V1, do_vfp_dp_sp_cvt},
1667 {"fuitod", 0xeeb80b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_sp_cvt},
1668 {"ftosid", 0xeebd0b40, 6, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1669 {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1670 {"ftouid", 0xeebc0b40, 6, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1671 {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1672
1673 /* Memory operations. */
1674 {"fldd", 0xed100b00, 4, FPU_VFP_EXT_V1, do_vfp_dp_ldst},
1675 {"fstd", 0xed000b00, 4, FPU_VFP_EXT_V1, do_vfp_dp_ldst},
1676 {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1677 {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1678 {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1679 {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1680 {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1681 {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1682 {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1683 {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1684
1685 /* Monadic operations. */
1686 {"fabsd", 0xeeb00bc0, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1687 {"fnegd", 0xeeb10b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1688 {"fsqrtd", 0xeeb10bc0, 6, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1689
1690 /* Dyadic operations. */
1691 {"faddd", 0xee300b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1692 {"fsubd", 0xee300b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1693 {"fmuld", 0xee200b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1694 {"fdivd", 0xee800b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1695 {"fmacd", 0xee000b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1696 {"fmscd", 0xee100b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1697 {"fnmuld", 0xee200b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1698 {"fnmacd", 0xee000b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1699 {"fnmscd", 0xee100b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1700
1701 /* Comparisons. */
1702 {"fcmpd", 0xeeb40b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1703 {"fcmpzd", 0xeeb50b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_compare_z},
1704 {"fcmped", 0xeeb40bc0, 6, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1705 {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1, do_vfp_dp_compare_z},
1706
1707 /* VFP V2. */
1708 {"fmsrr", 0xec400a10, 5, FPU_VFP_EXT_V2, do_vfp_sp_reg2},
1709 {"fmrrs", 0xec500a10, 5, FPU_VFP_EXT_V2, do_vfp_sp_reg2},
1710 {"fmdrr", 0xec400b10, 5, FPU_VFP_EXT_V2, do_vfp_dp_from_reg2},
1711 {"fmrrd", 0xec500b10, 5, FPU_VFP_EXT_V2, do_vfp_reg2_from_dp},
1712
1713 /* Intel XScale extensions to ARM V5 ISA. (All use CP0). */
1714 {"mia", 0xee200010, 3, ARM_CEXT_XSCALE, do_mia},
1715 {"miaph", 0xee280010, 5, ARM_CEXT_XSCALE, do_mia},
1716 {"miabb", 0xee2c0010, 5, ARM_CEXT_XSCALE, do_mia},
1717 {"miabt", 0xee2d0010, 5, ARM_CEXT_XSCALE, do_mia},
1718 {"miatb", 0xee2e0010, 5, ARM_CEXT_XSCALE, do_mia},
1719 {"miatt", 0xee2f0010, 5, ARM_CEXT_XSCALE, do_mia},
1720 {"mar", 0xec400000, 3, ARM_CEXT_XSCALE, do_mar},
1721 {"mra", 0xec500000, 3, ARM_CEXT_XSCALE, do_mra},
1722
1723 /* Cirrus DSP instructions. */
1724 {"cfldrs", 0xec100400, 6, ARM_CEXT_MAVERICK, do_c_ldst_1},
1725 {"cfldrd", 0xec500400, 6, ARM_CEXT_MAVERICK, do_c_ldst_2},
1726 {"cfldr32", 0xec100500, 7, ARM_CEXT_MAVERICK, do_c_ldst_3},
1727 {"cfldr64", 0xec500500, 7, ARM_CEXT_MAVERICK, do_c_ldst_4},
1728 {"cfstrs", 0xec000400, 6, ARM_CEXT_MAVERICK, do_c_ldst_1},
1729 {"cfstrd", 0xec400400, 6, ARM_CEXT_MAVERICK, do_c_ldst_2},
1730 {"cfstr32", 0xec000500, 7, ARM_CEXT_MAVERICK, do_c_ldst_3},
1731 {"cfstr64", 0xec400500, 7, ARM_CEXT_MAVERICK, do_c_ldst_4},
1732 {"cfmvsr", 0xee000450, 6, ARM_CEXT_MAVERICK, do_c_binops_2a},
1733 {"cfmvrs", 0xee100450, 6, ARM_CEXT_MAVERICK, do_c_binops_1a},
1734 {"cfmvdlr", 0xee000410, 7, ARM_CEXT_MAVERICK, do_c_binops_2b},
1735 {"cfmvrdl", 0xee100410, 7, ARM_CEXT_MAVERICK, do_c_binops_1b},
1736 {"cfmvdhr", 0xee000430, 7, ARM_CEXT_MAVERICK, do_c_binops_2b},
1737 {"cfmvrdh", 0xee100430, 7, ARM_CEXT_MAVERICK, do_c_binops_1b},
1738 {"cfmv64lr", 0xee000510, 8, ARM_CEXT_MAVERICK, do_c_binops_2c},
1739 {"cfmvr64l", 0xee100510, 8, ARM_CEXT_MAVERICK, do_c_binops_1c},
1740 {"cfmv64hr", 0xee000530, 8, ARM_CEXT_MAVERICK, do_c_binops_2c},
1741 {"cfmvr64h", 0xee100530, 8, ARM_CEXT_MAVERICK, do_c_binops_1c},
1742 {"cfmval32", 0xee100610, 8, ARM_CEXT_MAVERICK, do_c_binops_3a},
1743 {"cfmv32al", 0xee000610, 8, ARM_CEXT_MAVERICK, do_c_binops_3b},
1744 {"cfmvam32", 0xee100630, 8, ARM_CEXT_MAVERICK, do_c_binops_3a},
1745 {"cfmv32am", 0xee000630, 8, ARM_CEXT_MAVERICK, do_c_binops_3b},
1746 {"cfmvah32", 0xee100650, 8, ARM_CEXT_MAVERICK, do_c_binops_3a},
1747 {"cfmv32ah", 0xee000650, 8, ARM_CEXT_MAVERICK, do_c_binops_3b},
1748 {"cfmva32", 0xee100670, 7, ARM_CEXT_MAVERICK, do_c_binops_3a},
1749 {"cfmv32a", 0xee000670, 7, ARM_CEXT_MAVERICK, do_c_binops_3b},
1750 {"cfmva64", 0xee100690, 7, ARM_CEXT_MAVERICK, do_c_binops_3c},
1751 {"cfmv64a", 0xee000690, 7, ARM_CEXT_MAVERICK, do_c_binops_3d},
1752 {"cfmvsc32", 0xee1006b0, 8, ARM_CEXT_MAVERICK, do_c_dspsc_1},
1753 {"cfmv32sc", 0xee0006b0, 8, ARM_CEXT_MAVERICK, do_c_dspsc_2},
1754 {"cfcpys", 0xee000400, 6, ARM_CEXT_MAVERICK, do_c_binops_1d},
1755 {"cfcpyd", 0xee000420, 6, ARM_CEXT_MAVERICK, do_c_binops_1e},
1756 {"cfcvtsd", 0xee000460, 7, ARM_CEXT_MAVERICK, do_c_binops_1f},
1757 {"cfcvtds", 0xee000440, 7, ARM_CEXT_MAVERICK, do_c_binops_1g},
1758 {"cfcvt32s", 0xee000480, 8, ARM_CEXT_MAVERICK, do_c_binops_1h},
1759 {"cfcvt32d", 0xee0004a0, 8, ARM_CEXT_MAVERICK, do_c_binops_1i},
1760 {"cfcvt64s", 0xee0004c0, 8, ARM_CEXT_MAVERICK, do_c_binops_1j},
1761 {"cfcvt64d", 0xee0004e0, 8, ARM_CEXT_MAVERICK, do_c_binops_1k},
1762 {"cfcvts32", 0xee100580, 8, ARM_CEXT_MAVERICK, do_c_binops_1l},
1763 {"cfcvtd32", 0xee1005a0, 8, ARM_CEXT_MAVERICK, do_c_binops_1m},
1764 {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_c_binops_1l},
1765 {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_c_binops_1m},
1766 {"cfrshl32", 0xee000550, 8, ARM_CEXT_MAVERICK, do_c_triple_4a},
1767 {"cfrshl64", 0xee000570, 8, ARM_CEXT_MAVERICK, do_c_triple_4b},
1768 {"cfsh32", 0xee000500, 6, ARM_CEXT_MAVERICK, do_c_shift_1},
1769 {"cfsh64", 0xee200500, 6, ARM_CEXT_MAVERICK, do_c_shift_2},
1770 {"cfcmps", 0xee100490, 6, ARM_CEXT_MAVERICK, do_c_triple_5a},
1771 {"cfcmpd", 0xee1004b0, 6, ARM_CEXT_MAVERICK, do_c_triple_5b},
1772 {"cfcmp32", 0xee100590, 7, ARM_CEXT_MAVERICK, do_c_triple_5c},
1773 {"cfcmp64", 0xee1005b0, 7, ARM_CEXT_MAVERICK, do_c_triple_5d},
1774 {"cfabss", 0xee300400, 6, ARM_CEXT_MAVERICK, do_c_binops_1d},
1775 {"cfabsd", 0xee300420, 6, ARM_CEXT_MAVERICK, do_c_binops_1e},
1776 {"cfnegs", 0xee300440, 6, ARM_CEXT_MAVERICK, do_c_binops_1d},
1777 {"cfnegd", 0xee300460, 6, ARM_CEXT_MAVERICK, do_c_binops_1e},
1778 {"cfadds", 0xee300480, 6, ARM_CEXT_MAVERICK, do_c_triple_5e},
1779 {"cfaddd", 0xee3004a0, 6, ARM_CEXT_MAVERICK, do_c_triple_5f},
1780 {"cfsubs", 0xee3004c0, 6, ARM_CEXT_MAVERICK, do_c_triple_5e},
1781 {"cfsubd", 0xee3004e0, 6, ARM_CEXT_MAVERICK, do_c_triple_5f},
1782 {"cfmuls", 0xee100400, 6, ARM_CEXT_MAVERICK, do_c_triple_5e},
1783 {"cfmuld", 0xee100420, 6, ARM_CEXT_MAVERICK, do_c_triple_5f},
1784 {"cfabs32", 0xee300500, 7, ARM_CEXT_MAVERICK, do_c_binops_1n},
1785 {"cfabs64", 0xee300520, 7, ARM_CEXT_MAVERICK, do_c_binops_1o},
1786 {"cfneg32", 0xee300540, 7, ARM_CEXT_MAVERICK, do_c_binops_1n},
1787 {"cfneg64", 0xee300560, 7, ARM_CEXT_MAVERICK, do_c_binops_1o},
1788 {"cfadd32", 0xee300580, 7, ARM_CEXT_MAVERICK, do_c_triple_5g},
1789 {"cfadd64", 0xee3005a0, 7, ARM_CEXT_MAVERICK, do_c_triple_5h},
1790 {"cfsub32", 0xee3005c0, 7, ARM_CEXT_MAVERICK, do_c_triple_5g},
1791 {"cfsub64", 0xee3005e0, 7, ARM_CEXT_MAVERICK, do_c_triple_5h},
1792 {"cfmul32", 0xee100500, 7, ARM_CEXT_MAVERICK, do_c_triple_5g},
1793 {"cfmul64", 0xee100520, 7, ARM_CEXT_MAVERICK, do_c_triple_5h},
1794 {"cfmac32", 0xee100540, 7, ARM_CEXT_MAVERICK, do_c_triple_5g},
1795 {"cfmsc32", 0xee100560, 7, ARM_CEXT_MAVERICK, do_c_triple_5g},
1796 {"cfmadd32", 0xee000600, 8, ARM_CEXT_MAVERICK, do_c_quad_6a},
1797 {"cfmsub32", 0xee100600, 8, ARM_CEXT_MAVERICK, do_c_quad_6a},
1798 {"cfmadda32", 0xee200600, 9, ARM_CEXT_MAVERICK, do_c_quad_6b},
1799 {"cfmsuba32", 0xee300600, 9, ARM_CEXT_MAVERICK, do_c_quad_6b},
1800 };
1801
1802 /* Defines for various bits that we will want to toggle. */
1803 #define INST_IMMEDIATE 0x02000000
1804 #define OFFSET_REG 0x02000000
1805 #define HWOFFSET_IMM 0x00400000
1806 #define SHIFT_BY_REG 0x00000010
1807 #define PRE_INDEX 0x01000000
1808 #define INDEX_UP 0x00800000
1809 #define WRITE_BACK 0x00200000
1810 #define LDM_TYPE_2_OR_3 0x00400000
1811
1812 #define LITERAL_MASK 0xf000f000
1813 #define OPCODE_MASK 0xfe1fffff
1814 #define V4_STR_BIT 0x00000020
1815
1816 #define DATA_OP_SHIFT 21
1817
1818 /* Codes to distinguish the arithmetic instructions. */
1819 #define OPCODE_AND 0
1820 #define OPCODE_EOR 1
1821 #define OPCODE_SUB 2
1822 #define OPCODE_RSB 3
1823 #define OPCODE_ADD 4
1824 #define OPCODE_ADC 5
1825 #define OPCODE_SBC 6
1826 #define OPCODE_RSC 7
1827 #define OPCODE_TST 8
1828 #define OPCODE_TEQ 9
1829 #define OPCODE_CMP 10
1830 #define OPCODE_CMN 11
1831 #define OPCODE_ORR 12
1832 #define OPCODE_MOV 13
1833 #define OPCODE_BIC 14
1834 #define OPCODE_MVN 15
1835
1836 /* Thumb v1 (ARMv4T). */
1837 static void do_t_nop PARAMS ((char *));
1838 static void do_t_arit PARAMS ((char *));
1839 static void do_t_add PARAMS ((char *));
1840 static void do_t_asr PARAMS ((char *));
1841 static void do_t_branch9 PARAMS ((char *));
1842 static void do_t_branch12 PARAMS ((char *));
1843 static void do_t_branch23 PARAMS ((char *));
1844 static void do_t_bx PARAMS ((char *));
1845 static void do_t_compare PARAMS ((char *));
1846 static void do_t_ldmstm PARAMS ((char *));
1847 static void do_t_ldr PARAMS ((char *));
1848 static void do_t_ldrb PARAMS ((char *));
1849 static void do_t_ldrh PARAMS ((char *));
1850 static void do_t_lds PARAMS ((char *));
1851 static void do_t_lsl PARAMS ((char *));
1852 static void do_t_lsr PARAMS ((char *));
1853 static void do_t_mov PARAMS ((char *));
1854 static void do_t_push_pop PARAMS ((char *));
1855 static void do_t_str PARAMS ((char *));
1856 static void do_t_strb PARAMS ((char *));
1857 static void do_t_strh PARAMS ((char *));
1858 static void do_t_sub PARAMS ((char *));
1859 static void do_t_swi PARAMS ((char *));
1860 static void do_t_adr PARAMS ((char *));
1861
1862 /* Thumb v2 (ARMv5T). */
1863 static void do_t_blx PARAMS ((char *));
1864 static void do_t_bkpt PARAMS ((char *));
1865
1866 #define T_OPCODE_MUL 0x4340
1867 #define T_OPCODE_TST 0x4200
1868 #define T_OPCODE_CMN 0x42c0
1869 #define T_OPCODE_NEG 0x4240
1870 #define T_OPCODE_MVN 0x43c0
1871
1872 #define T_OPCODE_ADD_R3 0x1800
1873 #define T_OPCODE_SUB_R3 0x1a00
1874 #define T_OPCODE_ADD_HI 0x4400
1875 #define T_OPCODE_ADD_ST 0xb000
1876 #define T_OPCODE_SUB_ST 0xb080
1877 #define T_OPCODE_ADD_SP 0xa800
1878 #define T_OPCODE_ADD_PC 0xa000
1879 #define T_OPCODE_ADD_I8 0x3000
1880 #define T_OPCODE_SUB_I8 0x3800
1881 #define T_OPCODE_ADD_I3 0x1c00
1882 #define T_OPCODE_SUB_I3 0x1e00
1883
1884 #define T_OPCODE_ASR_R 0x4100
1885 #define T_OPCODE_LSL_R 0x4080
1886 #define T_OPCODE_LSR_R 0x40c0
1887 #define T_OPCODE_ASR_I 0x1000
1888 #define T_OPCODE_LSL_I 0x0000
1889 #define T_OPCODE_LSR_I 0x0800
1890
1891 #define T_OPCODE_MOV_I8 0x2000
1892 #define T_OPCODE_CMP_I8 0x2800
1893 #define T_OPCODE_CMP_LR 0x4280
1894 #define T_OPCODE_MOV_HR 0x4600
1895 #define T_OPCODE_CMP_HR 0x4500
1896
1897 #define T_OPCODE_LDR_PC 0x4800
1898 #define T_OPCODE_LDR_SP 0x9800
1899 #define T_OPCODE_STR_SP 0x9000
1900 #define T_OPCODE_LDR_IW 0x6800
1901 #define T_OPCODE_STR_IW 0x6000
1902 #define T_OPCODE_LDR_IH 0x8800
1903 #define T_OPCODE_STR_IH 0x8000
1904 #define T_OPCODE_LDR_IB 0x7800
1905 #define T_OPCODE_STR_IB 0x7000
1906 #define T_OPCODE_LDR_RW 0x5800
1907 #define T_OPCODE_STR_RW 0x5000
1908 #define T_OPCODE_LDR_RH 0x5a00
1909 #define T_OPCODE_STR_RH 0x5200
1910 #define T_OPCODE_LDR_RB 0x5c00
1911 #define T_OPCODE_STR_RB 0x5400
1912
1913 #define T_OPCODE_PUSH 0xb400
1914 #define T_OPCODE_POP 0xbc00
1915
1916 #define T_OPCODE_BRANCH 0xe7fe
1917
1918 static int thumb_reg PARAMS ((char ** str, int hi_lo));
1919
1920 #define THUMB_SIZE 2 /* Size of thumb instruction. */
1921 #define THUMB_REG_LO 0x1
1922 #define THUMB_REG_HI 0x2
1923 #define THUMB_REG_ANY 0x3
1924
1925 #define THUMB_H1 0x0080
1926 #define THUMB_H2 0x0040
1927
1928 #define THUMB_ASR 0
1929 #define THUMB_LSL 1
1930 #define THUMB_LSR 2
1931
1932 #define THUMB_MOVE 0
1933 #define THUMB_COMPARE 1
1934
1935 #define THUMB_LOAD 0
1936 #define THUMB_STORE 1
1937
1938 #define THUMB_PP_PC_LR 0x0100
1939
1940 /* These three are used for immediate shifts, do not alter. */
1941 #define THUMB_WORD 2
1942 #define THUMB_HALFWORD 1
1943 #define THUMB_BYTE 0
1944
1945 struct thumb_opcode
1946 {
1947 /* Basic string to match. */
1948 const char * template;
1949
1950 /* Basic instruction code. */
1951 unsigned long value;
1952
1953 int size;
1954
1955 /* Which CPU variants this exists for. */
1956 unsigned long variant;
1957
1958 /* Function to call to parse args. */
1959 void (* parms) PARAMS ((char *));
1960 };
1961
1962 static const struct thumb_opcode tinsns[] =
1963 {
1964 /* Thumb v1 (ARMv4T). */
1965 {"adc", 0x4140, 2, ARM_EXT_V4T, do_t_arit},
1966 {"add", 0x0000, 2, ARM_EXT_V4T, do_t_add},
1967 {"and", 0x4000, 2, ARM_EXT_V4T, do_t_arit},
1968 {"asr", 0x0000, 2, ARM_EXT_V4T, do_t_asr},
1969 {"b", T_OPCODE_BRANCH, 2, ARM_EXT_V4T, do_t_branch12},
1970 {"beq", 0xd0fe, 2, ARM_EXT_V4T, do_t_branch9},
1971 {"bne", 0xd1fe, 2, ARM_EXT_V4T, do_t_branch9},
1972 {"bcs", 0xd2fe, 2, ARM_EXT_V4T, do_t_branch9},
1973 {"bhs", 0xd2fe, 2, ARM_EXT_V4T, do_t_branch9},
1974 {"bcc", 0xd3fe, 2, ARM_EXT_V4T, do_t_branch9},
1975 {"bul", 0xd3fe, 2, ARM_EXT_V4T, do_t_branch9},
1976 {"blo", 0xd3fe, 2, ARM_EXT_V4T, do_t_branch9},
1977 {"bmi", 0xd4fe, 2, ARM_EXT_V4T, do_t_branch9},
1978 {"bpl", 0xd5fe, 2, ARM_EXT_V4T, do_t_branch9},
1979 {"bvs", 0xd6fe, 2, ARM_EXT_V4T, do_t_branch9},
1980 {"bvc", 0xd7fe, 2, ARM_EXT_V4T, do_t_branch9},
1981 {"bhi", 0xd8fe, 2, ARM_EXT_V4T, do_t_branch9},
1982 {"bls", 0xd9fe, 2, ARM_EXT_V4T, do_t_branch9},
1983 {"bge", 0xdafe, 2, ARM_EXT_V4T, do_t_branch9},
1984 {"blt", 0xdbfe, 2, ARM_EXT_V4T, do_t_branch9},
1985 {"bgt", 0xdcfe, 2, ARM_EXT_V4T, do_t_branch9},
1986 {"ble", 0xddfe, 2, ARM_EXT_V4T, do_t_branch9},
1987 {"bal", 0xdefe, 2, ARM_EXT_V4T, do_t_branch9},
1988 {"bic", 0x4380, 2, ARM_EXT_V4T, do_t_arit},
1989 {"bl", 0xf7fffffe, 4, ARM_EXT_V4T, do_t_branch23},
1990 {"bx", 0x4700, 2, ARM_EXT_V4T, do_t_bx},
1991 {"cmn", T_OPCODE_CMN, 2, ARM_EXT_V4T, do_t_arit},
1992 {"cmp", 0x0000, 2, ARM_EXT_V4T, do_t_compare},
1993 {"eor", 0x4040, 2, ARM_EXT_V4T, do_t_arit},
1994 {"ldmia", 0xc800, 2, ARM_EXT_V4T, do_t_ldmstm},
1995 {"ldr", 0x0000, 2, ARM_EXT_V4T, do_t_ldr},
1996 {"ldrb", 0x0000, 2, ARM_EXT_V4T, do_t_ldrb},
1997 {"ldrh", 0x0000, 2, ARM_EXT_V4T, do_t_ldrh},
1998 {"ldrsb", 0x5600, 2, ARM_EXT_V4T, do_t_lds},
1999 {"ldrsh", 0x5e00, 2, ARM_EXT_V4T, do_t_lds},
2000 {"ldsb", 0x5600, 2, ARM_EXT_V4T, do_t_lds},
2001 {"ldsh", 0x5e00, 2, ARM_EXT_V4T, do_t_lds},
2002 {"lsl", 0x0000, 2, ARM_EXT_V4T, do_t_lsl},
2003 {"lsr", 0x0000, 2, ARM_EXT_V4T, do_t_lsr},
2004 {"mov", 0x0000, 2, ARM_EXT_V4T, do_t_mov},
2005 {"mul", T_OPCODE_MUL, 2, ARM_EXT_V4T, do_t_arit},
2006 {"mvn", T_OPCODE_MVN, 2, ARM_EXT_V4T, do_t_arit},
2007 {"neg", T_OPCODE_NEG, 2, ARM_EXT_V4T, do_t_arit},
2008 {"orr", 0x4300, 2, ARM_EXT_V4T, do_t_arit},
2009 {"pop", 0xbc00, 2, ARM_EXT_V4T, do_t_push_pop},
2010 {"push", 0xb400, 2, ARM_EXT_V4T, do_t_push_pop},
2011 {"ror", 0x41c0, 2, ARM_EXT_V4T, do_t_arit},
2012 {"sbc", 0x4180, 2, ARM_EXT_V4T, do_t_arit},
2013 {"stmia", 0xc000, 2, ARM_EXT_V4T, do_t_ldmstm},
2014 {"str", 0x0000, 2, ARM_EXT_V4T, do_t_str},
2015 {"strb", 0x0000, 2, ARM_EXT_V4T, do_t_strb},
2016 {"strh", 0x0000, 2, ARM_EXT_V4T, do_t_strh},
2017 {"swi", 0xdf00, 2, ARM_EXT_V4T, do_t_swi},
2018 {"sub", 0x0000, 2, ARM_EXT_V4T, do_t_sub},
2019 {"tst", T_OPCODE_TST, 2, ARM_EXT_V4T, do_t_arit},
2020 /* Pseudo ops: */
2021 {"adr", 0x0000, 2, ARM_EXT_V4T, do_t_adr},
2022 {"nop", 0x46C0, 2, ARM_EXT_V4T, do_t_nop}, /* mov r8,r8 */
2023 /* Thumb v2 (ARMv5T). */
2024 {"blx", 0, 0, ARM_EXT_V5T, do_t_blx},
2025 {"bkpt", 0xbe00, 2, ARM_EXT_V5T, do_t_bkpt},
2026 };
2027
2028 #define BAD_ARGS _("bad arguments to instruction")
2029 #define BAD_PC _("r15 not allowed here")
2030 #define BAD_COND _("instruction is not conditional")
2031 #define ERR_NO_ACCUM _("acc0 expected")
2032
2033 static struct hash_control * arm_ops_hsh = NULL;
2034 static struct hash_control * arm_tops_hsh = NULL;
2035 static struct hash_control * arm_cond_hsh = NULL;
2036 static struct hash_control * arm_shift_hsh = NULL;
2037 static struct hash_control * arm_psr_hsh = NULL;
2038
2039 /* This table describes all the machine specific pseudo-ops the assembler
2040 has to support. The fields are:
2041 pseudo-op name without dot
2042 function to call to execute this pseudo-op
2043 Integer arg to pass to the function. */
2044
2045 static void s_req PARAMS ((int));
2046 static void s_align PARAMS ((int));
2047 static void s_bss PARAMS ((int));
2048 static void s_even PARAMS ((int));
2049 static void s_ltorg PARAMS ((int));
2050 static void s_arm PARAMS ((int));
2051 static void s_thumb PARAMS ((int));
2052 static void s_code PARAMS ((int));
2053 static void s_force_thumb PARAMS ((int));
2054 static void s_thumb_func PARAMS ((int));
2055 static void s_thumb_set PARAMS ((int));
2056 static void arm_s_text PARAMS ((int));
2057 static void arm_s_data PARAMS ((int));
2058 #ifdef OBJ_ELF
2059 static void arm_s_section PARAMS ((int));
2060 static void s_arm_elf_cons PARAMS ((int));
2061 #endif
2062
2063 static int my_get_expression PARAMS ((expressionS *, char **));
2064
2065 const pseudo_typeS md_pseudo_table[] =
2066 {
2067 /* Never called becasue '.req' does not start line. */
2068 { "req", s_req, 0 },
2069 { "bss", s_bss, 0 },
2070 { "align", s_align, 0 },
2071 { "arm", s_arm, 0 },
2072 { "thumb", s_thumb, 0 },
2073 { "code", s_code, 0 },
2074 { "force_thumb", s_force_thumb, 0 },
2075 { "thumb_func", s_thumb_func, 0 },
2076 { "thumb_set", s_thumb_set, 0 },
2077 { "even", s_even, 0 },
2078 { "ltorg", s_ltorg, 0 },
2079 { "pool", s_ltorg, 0 },
2080 /* Allow for the effect of section changes. */
2081 { "text", arm_s_text, 0 },
2082 { "data", arm_s_data, 0 },
2083 #ifdef OBJ_ELF
2084 { "section", arm_s_section, 0 },
2085 { "section.s", arm_s_section, 0 },
2086 { "sect", arm_s_section, 0 },
2087 { "sect.s", arm_s_section, 0 },
2088 { "word", s_arm_elf_cons, 4 },
2089 { "long", s_arm_elf_cons, 4 },
2090 { "file", dwarf2_directive_file, 0 },
2091 { "loc", dwarf2_directive_loc, 0 },
2092 #else
2093 { "word", cons, 4},
2094 #endif
2095 { "extend", float_cons, 'x' },
2096 { "ldouble", float_cons, 'x' },
2097 { "packed", float_cons, 'p' },
2098 { 0, 0, 0 }
2099 };
2100
2101 /* Other internal functions. */
2102 static int arm_parse_extension PARAMS ((char *, int *));
2103 static int arm_parse_cpu PARAMS ((char *));
2104 static int arm_parse_arch PARAMS ((char *));
2105 static int arm_parse_fpu PARAMS ((char *));
2106
2107 /* Stuff needed to resolve the label ambiguity
2108 As:
2109 ...
2110 label: <insn>
2111 may differ from:
2112 ...
2113 label:
2114 <insn>
2115 */
2116
2117 symbolS * last_label_seen;
2118 static int label_is_thumb_function_name = false;
2119
2120 /* Literal stuff. */
2121
2122 #define MAX_LITERAL_POOL_SIZE 1024
2123
2124 typedef struct literalS
2125 {
2126 struct expressionS exp;
2127 struct arm_it * inst;
2128 } literalT;
2129
2130 literalT literals[MAX_LITERAL_POOL_SIZE];
2131
2132 /* Next free entry in the pool. */
2133 int next_literal_pool_place = 0;
2134
2135 /* Next literal pool number. */
2136 int lit_pool_num = 1;
2137
2138 symbolS * current_poolP = NULL;
2139
2140 static int
2141 add_to_lit_pool ()
2142 {
2143 int lit_count = 0;
2144
2145 if (current_poolP == NULL)
2146 current_poolP = symbol_create (FAKE_LABEL_NAME, undefined_section,
2147 (valueT) 0, &zero_address_frag);
2148
2149 /* Check if this literal value is already in the pool: */
2150 while (lit_count < next_literal_pool_place)
2151 {
2152 if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op
2153 && inst.reloc.exp.X_op == O_constant
2154 && (literals[lit_count].exp.X_add_number
2155 == inst.reloc.exp.X_add_number)
2156 && literals[lit_count].exp.X_unsigned == inst.reloc.exp.X_unsigned)
2157 break;
2158
2159 if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op
2160 && inst.reloc.exp.X_op == O_symbol
2161 && (literals[lit_count].exp.X_add_number
2162 == inst.reloc.exp.X_add_number)
2163 && (literals[lit_count].exp.X_add_symbol
2164 == inst.reloc.exp.X_add_symbol)
2165 && (literals[lit_count].exp.X_op_symbol
2166 == inst.reloc.exp.X_op_symbol))
2167 break;
2168
2169 lit_count++;
2170 }
2171
2172 if (lit_count == next_literal_pool_place) /* New entry. */
2173 {
2174 if (next_literal_pool_place >= MAX_LITERAL_POOL_SIZE)
2175 {
2176 inst.error = _("literal pool overflow");
2177 return FAIL;
2178 }
2179
2180 literals[next_literal_pool_place].exp = inst.reloc.exp;
2181 lit_count = next_literal_pool_place++;
2182 }
2183
2184 inst.reloc.exp.X_op = O_symbol;
2185 inst.reloc.exp.X_add_number = (lit_count) * 4 - 8;
2186 inst.reloc.exp.X_add_symbol = current_poolP;
2187
2188 return SUCCESS;
2189 }
2190
2191 /* Can't use symbol_new here, so have to create a symbol and then at
2192 a later date assign it a value. Thats what these functions do. */
2193
2194 static void
2195 symbol_locate (symbolP, name, segment, valu, frag)
2196 symbolS * symbolP;
2197 const char * name; /* It is copied, the caller can modify. */
2198 segT segment; /* Segment identifier (SEG_<something>). */
2199 valueT valu; /* Symbol value. */
2200 fragS * frag; /* Associated fragment. */
2201 {
2202 unsigned int name_length;
2203 char * preserved_copy_of_name;
2204
2205 name_length = strlen (name) + 1; /* +1 for \0. */
2206 obstack_grow (&notes, name, name_length);
2207 preserved_copy_of_name = obstack_finish (&notes);
2208 #ifdef STRIP_UNDERSCORE
2209 if (preserved_copy_of_name[0] == '_')
2210 preserved_copy_of_name++;
2211 #endif
2212
2213 #ifdef tc_canonicalize_symbol_name
2214 preserved_copy_of_name =
2215 tc_canonicalize_symbol_name (preserved_copy_of_name);
2216 #endif
2217
2218 S_SET_NAME (symbolP, preserved_copy_of_name);
2219
2220 S_SET_SEGMENT (symbolP, segment);
2221 S_SET_VALUE (symbolP, valu);
2222 symbol_clear_list_pointers(symbolP);
2223
2224 symbol_set_frag (symbolP, frag);
2225
2226 /* Link to end of symbol chain. */
2227 {
2228 extern int symbol_table_frozen;
2229 if (symbol_table_frozen)
2230 abort ();
2231 }
2232
2233 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
2234
2235 obj_symbol_new_hook (symbolP);
2236
2237 #ifdef tc_symbol_new_hook
2238 tc_symbol_new_hook (symbolP);
2239 #endif
2240
2241 #ifdef DEBUG_SYMS
2242 verify_symbol_chain (symbol_rootP, symbol_lastP);
2243 #endif /* DEBUG_SYMS */
2244 }
2245
2246 /* Check that an immediate is valid.
2247 If so, convert it to the right format. */
2248
2249 static unsigned int
2250 validate_immediate (val)
2251 unsigned int val;
2252 {
2253 unsigned int a;
2254 unsigned int i;
2255
2256 #define rotate_left(v, n) (v << n | v >> (32 - n))
2257
2258 for (i = 0; i < 32; i += 2)
2259 if ((a = rotate_left (val, i)) <= 0xff)
2260 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
2261
2262 return FAIL;
2263 }
2264
2265 /* Check to see if an immediate can be computed as two seperate immediate
2266 values, added together. We already know that this value cannot be
2267 computed by just one ARM instruction. */
2268
2269 static unsigned int
2270 validate_immediate_twopart (val, highpart)
2271 unsigned int val;
2272 unsigned int * highpart;
2273 {
2274 unsigned int a;
2275 unsigned int i;
2276
2277 for (i = 0; i < 32; i += 2)
2278 if (((a = rotate_left (val, i)) & 0xff) != 0)
2279 {
2280 if (a & 0xff00)
2281 {
2282 if (a & ~ 0xffff)
2283 continue;
2284 * highpart = (a >> 8) | ((i + 24) << 7);
2285 }
2286 else if (a & 0xff0000)
2287 {
2288 if (a & 0xff000000)
2289 continue;
2290 * highpart = (a >> 16) | ((i + 16) << 7);
2291 }
2292 else
2293 {
2294 assert (a & 0xff000000);
2295 * highpart = (a >> 24) | ((i + 8) << 7);
2296 }
2297
2298 return (a & 0xff) | (i << 7);
2299 }
2300
2301 return FAIL;
2302 }
2303
2304 static int
2305 validate_offset_imm (val, hwse)
2306 unsigned int val;
2307 int hwse;
2308 {
2309 if ((hwse && val > 255) || val > 4095)
2310 return FAIL;
2311 return val;
2312 }
2313
2314 static void
2315 s_req (a)
2316 int a ATTRIBUTE_UNUSED;
2317 {
2318 as_bad (_("invalid syntax for .req directive"));
2319 }
2320
2321 static void
2322 s_bss (ignore)
2323 int ignore ATTRIBUTE_UNUSED;
2324 {
2325 /* We don't support putting frags in the BSS segment, we fake it by
2326 marking in_bss, then looking at s_skip for clues. */
2327 subseg_set (bss_section, 0);
2328 demand_empty_rest_of_line ();
2329 }
2330
2331 static void
2332 s_even (ignore)
2333 int ignore ATTRIBUTE_UNUSED;
2334 {
2335 /* Never make frag if expect extra pass. */
2336 if (!need_pass_2)
2337 frag_align (1, 0, 0);
2338
2339 record_alignment (now_seg, 1);
2340
2341 demand_empty_rest_of_line ();
2342 }
2343
2344 static void
2345 s_ltorg (ignored)
2346 int ignored ATTRIBUTE_UNUSED;
2347 {
2348 int lit_count = 0;
2349 char sym_name[20];
2350
2351 if (current_poolP == NULL)
2352 return;
2353
2354 /* Align pool as you have word accesses.
2355 Only make a frag if we have to. */
2356 if (!need_pass_2)
2357 frag_align (2, 0, 0);
2358
2359 record_alignment (now_seg, 2);
2360
2361 sprintf (sym_name, "$$lit_\002%x", lit_pool_num++);
2362
2363 symbol_locate (current_poolP, sym_name, now_seg,
2364 (valueT) frag_now_fix (), frag_now);
2365 symbol_table_insert (current_poolP);
2366
2367 ARM_SET_THUMB (current_poolP, thumb_mode);
2368
2369 #if defined OBJ_COFF || defined OBJ_ELF
2370 ARM_SET_INTERWORK (current_poolP, support_interwork);
2371 #endif
2372
2373 while (lit_count < next_literal_pool_place)
2374 /* First output the expression in the instruction to the pool. */
2375 emit_expr (&(literals[lit_count++].exp), 4); /* .word */
2376
2377 next_literal_pool_place = 0;
2378 current_poolP = NULL;
2379 }
2380
2381 /* Same as s_align_ptwo but align 0 => align 2. */
2382
2383 static void
2384 s_align (unused)
2385 int unused ATTRIBUTE_UNUSED;
2386 {
2387 register int temp;
2388 register long temp_fill;
2389 long max_alignment = 15;
2390
2391 temp = get_absolute_expression ();
2392 if (temp > max_alignment)
2393 as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
2394 else if (temp < 0)
2395 {
2396 as_bad (_("alignment negative. 0 assumed."));
2397 temp = 0;
2398 }
2399
2400 if (*input_line_pointer == ',')
2401 {
2402 input_line_pointer++;
2403 temp_fill = get_absolute_expression ();
2404 }
2405 else
2406 temp_fill = 0;
2407
2408 if (!temp)
2409 temp = 2;
2410
2411 /* Only make a frag if we HAVE to. */
2412 if (temp && !need_pass_2)
2413 frag_align (temp, (int) temp_fill, 0);
2414 demand_empty_rest_of_line ();
2415
2416 record_alignment (now_seg, temp);
2417 }
2418
2419 static void
2420 s_force_thumb (ignore)
2421 int ignore ATTRIBUTE_UNUSED;
2422 {
2423 /* If we are not already in thumb mode go into it, EVEN if
2424 the target processor does not support thumb instructions.
2425 This is used by gcc/config/arm/lib1funcs.asm for example
2426 to compile interworking support functions even if the
2427 target processor should not support interworking. */
2428 if (! thumb_mode)
2429 {
2430 thumb_mode = 2;
2431
2432 record_alignment (now_seg, 1);
2433 }
2434
2435 demand_empty_rest_of_line ();
2436 }
2437
2438 static void
2439 s_thumb_func (ignore)
2440 int ignore ATTRIBUTE_UNUSED;
2441 {
2442 if (! thumb_mode)
2443 opcode_select (16);
2444
2445 /* The following label is the name/address of the start of a Thumb function.
2446 We need to know this for the interworking support. */
2447 label_is_thumb_function_name = true;
2448
2449 demand_empty_rest_of_line ();
2450 }
2451
2452 /* Perform a .set directive, but also mark the alias as
2453 being a thumb function. */
2454
2455 static void
2456 s_thumb_set (equiv)
2457 int equiv;
2458 {
2459 /* XXX the following is a duplicate of the code for s_set() in read.c
2460 We cannot just call that code as we need to get at the symbol that
2461 is created. */
2462 register char * name;
2463 register char delim;
2464 register char * end_name;
2465 register symbolS * symbolP;
2466
2467 /* Especial apologies for the random logic:
2468 This just grew, and could be parsed much more simply!
2469 Dean - in haste. */
2470 name = input_line_pointer;
2471 delim = get_symbol_end ();
2472 end_name = input_line_pointer;
2473 *end_name = delim;
2474
2475 SKIP_WHITESPACE ();
2476
2477 if (*input_line_pointer != ',')
2478 {
2479 *end_name = 0;
2480 as_bad (_("expected comma after name \"%s\""), name);
2481 *end_name = delim;
2482 ignore_rest_of_line ();
2483 return;
2484 }
2485
2486 input_line_pointer++;
2487 *end_name = 0;
2488
2489 if (name[0] == '.' && name[1] == '\0')
2490 {
2491 /* XXX - this should not happen to .thumb_set. */
2492 abort ();
2493 }
2494
2495 if ((symbolP = symbol_find (name)) == NULL
2496 && (symbolP = md_undefined_symbol (name)) == NULL)
2497 {
2498 #ifndef NO_LISTING
2499 /* When doing symbol listings, play games with dummy fragments living
2500 outside the normal fragment chain to record the file and line info
2501 for this symbol. */
2502 if (listing & LISTING_SYMBOLS)
2503 {
2504 extern struct list_info_struct * listing_tail;
2505 fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS));
2506
2507 memset (dummy_frag, 0, sizeof (fragS));
2508 dummy_frag->fr_type = rs_fill;
2509 dummy_frag->line = listing_tail;
2510 symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
2511 dummy_frag->fr_symbol = symbolP;
2512 }
2513 else
2514 #endif
2515 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
2516
2517 #ifdef OBJ_COFF
2518 /* "set" symbols are local unless otherwise specified. */
2519 SF_SET_LOCAL (symbolP);
2520 #endif /* OBJ_COFF */
2521 } /* Make a new symbol. */
2522
2523 symbol_table_insert (symbolP);
2524
2525 * end_name = delim;
2526
2527 if (equiv
2528 && S_IS_DEFINED (symbolP)
2529 && S_GET_SEGMENT (symbolP) != reg_section)
2530 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
2531
2532 pseudo_set (symbolP);
2533
2534 demand_empty_rest_of_line ();
2535
2536 /* XXX Now we come to the Thumb specific bit of code. */
2537
2538 THUMB_SET_FUNC (symbolP, 1);
2539 ARM_SET_THUMB (symbolP, 1);
2540 #if defined OBJ_ELF || defined OBJ_COFF
2541 ARM_SET_INTERWORK (symbolP, support_interwork);
2542 #endif
2543 }
2544
2545 /* If we change section we must dump the literal pool first. */
2546
2547 static void
2548 arm_s_text (ignore)
2549 int ignore;
2550 {
2551 if (now_seg != text_section)
2552 s_ltorg (0);
2553
2554 #ifdef OBJ_ELF
2555 obj_elf_text (ignore);
2556 #else
2557 s_text (ignore);
2558 #endif
2559 }
2560
2561 static void
2562 arm_s_data (ignore)
2563 int ignore;
2564 {
2565 if (flag_readonly_data_in_text)
2566 {
2567 if (now_seg != text_section)
2568 s_ltorg (0);
2569 }
2570 else if (now_seg != data_section)
2571 s_ltorg (0);
2572
2573 #ifdef OBJ_ELF
2574 obj_elf_data (ignore);
2575 #else
2576 s_data (ignore);
2577 #endif
2578 }
2579
2580 #ifdef OBJ_ELF
2581 static void
2582 arm_s_section (ignore)
2583 int ignore;
2584 {
2585 s_ltorg (0);
2586
2587 obj_elf_section (ignore);
2588 }
2589 #endif
2590
2591 static void
2592 opcode_select (width)
2593 int width;
2594 {
2595 switch (width)
2596 {
2597 case 16:
2598 if (! thumb_mode)
2599 {
2600 if (! (cpu_variant & ARM_EXT_V4T))
2601 as_bad (_("selected processor does not support THUMB opcodes"));
2602
2603 thumb_mode = 1;
2604 /* No need to force the alignment, since we will have been
2605 coming from ARM mode, which is word-aligned. */
2606 record_alignment (now_seg, 1);
2607 }
2608 break;
2609
2610 case 32:
2611 if (thumb_mode)
2612 {
2613 if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
2614 as_bad (_("selected processor does not support ARM opcodes"));
2615
2616 thumb_mode = 0;
2617
2618 if (!need_pass_2)
2619 frag_align (2, 0, 0);
2620
2621 record_alignment (now_seg, 1);
2622 }
2623 break;
2624
2625 default:
2626 as_bad (_("invalid instruction size selected (%d)"), width);
2627 }
2628 }
2629
2630 static void
2631 s_arm (ignore)
2632 int ignore ATTRIBUTE_UNUSED;
2633 {
2634 opcode_select (32);
2635 demand_empty_rest_of_line ();
2636 }
2637
2638 static void
2639 s_thumb (ignore)
2640 int ignore ATTRIBUTE_UNUSED;
2641 {
2642 opcode_select (16);
2643 demand_empty_rest_of_line ();
2644 }
2645
2646 static void
2647 s_code (unused)
2648 int unused ATTRIBUTE_UNUSED;
2649 {
2650 register int temp;
2651
2652 temp = get_absolute_expression ();
2653 switch (temp)
2654 {
2655 case 16:
2656 case 32:
2657 opcode_select (temp);
2658 break;
2659
2660 default:
2661 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
2662 }
2663 }
2664
2665 static void
2666 end_of_line (str)
2667 char *str;
2668 {
2669 skip_whitespace (str);
2670
2671 if (*str != '\0' && !inst.error)
2672 inst.error = _("garbage following instruction");
2673 }
2674
2675 static int
2676 skip_past_comma (str)
2677 char ** str;
2678 {
2679 char * p = * str, c;
2680 int comma = 0;
2681
2682 while ((c = *p) == ' ' || c == ',')
2683 {
2684 p++;
2685 if (c == ',' && comma++)
2686 return FAIL;
2687 }
2688
2689 if (c == '\0')
2690 return FAIL;
2691
2692 *str = p;
2693 return comma ? SUCCESS : FAIL;
2694 }
2695
2696 /* A standard register must be given at this point.
2697 SHIFT is the place to put it in inst.instruction.
2698 Restores input start point on error.
2699 Returns the reg#, or FAIL. */
2700
2701 static int
2702 reg_required_here (str, shift)
2703 char ** str;
2704 int shift;
2705 {
2706 static char buff [128]; /* XXX */
2707 int reg;
2708 char * start = * str;
2709
2710 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
2711 {
2712 if (shift >= 0)
2713 inst.instruction |= reg << shift;
2714 return reg;
2715 }
2716
2717 /* Restore the start point, we may have got a reg of the wrong class. */
2718 *str = start;
2719
2720 /* In the few cases where we might be able to accept something else
2721 this error can be overridden. */
2722 sprintf (buff, _("register expected, not '%.100s'"), start);
2723 inst.error = buff;
2724
2725 return FAIL;
2726 }
2727
2728 static const struct asm_psr *
2729 arm_psr_parse (ccp)
2730 register char ** ccp;
2731 {
2732 char * start = * ccp;
2733 char c;
2734 char * p;
2735 const struct asm_psr * psr;
2736
2737 p = start;
2738
2739 /* Skip to the end of the next word in the input stream. */
2740 do
2741 {
2742 c = *p++;
2743 }
2744 while (ISALPHA (c) || c == '_');
2745
2746 /* Terminate the word. */
2747 *--p = 0;
2748
2749 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
2750 feature for ease of use and backwards compatibility. */
2751 if (!strncmp (start, "cpsr", 4))
2752 strncpy (start, "CPSR", 4);
2753 else if (!strncmp (start, "spsr", 4))
2754 strncpy (start, "SPSR", 4);
2755
2756 /* Now locate the word in the psr hash table. */
2757 psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
2758
2759 /* Restore the input stream. */
2760 *p = c;
2761
2762 /* If we found a valid match, advance the
2763 stream pointer past the end of the word. */
2764 *ccp = p;
2765
2766 return psr;
2767 }
2768
2769 /* Parse the input looking for a PSR flag. */
2770
2771 static int
2772 psr_required_here (str)
2773 char ** str;
2774 {
2775 char * start = * str;
2776 const struct asm_psr * psr;
2777
2778 psr = arm_psr_parse (str);
2779
2780 if (psr)
2781 {
2782 /* If this is the SPSR that is being modified, set the R bit. */
2783 if (! psr->cpsr)
2784 inst.instruction |= SPSR_BIT;
2785
2786 /* Set the psr flags in the MSR instruction. */
2787 inst.instruction |= psr->field << PSR_SHIFT;
2788
2789 return SUCCESS;
2790 }
2791
2792 /* In the few cases where we might be able to accept
2793 something else this error can be overridden. */
2794 inst.error = _("flag for {c}psr instruction expected");
2795
2796 /* Restore the start point. */
2797 *str = start;
2798 return FAIL;
2799 }
2800
2801 static int
2802 co_proc_number (str)
2803 char **str;
2804 {
2805 int processor, pchar;
2806 char *start;
2807
2808 skip_whitespace (*str);
2809 start = *str;
2810
2811 /* The data sheet seems to imply that just a number on its own is valid
2812 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
2813 accept either. */
2814 if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
2815 == FAIL)
2816 {
2817 *str = start;
2818
2819 pchar = *(*str)++;
2820 if (pchar >= '0' && pchar <= '9')
2821 {
2822 processor = pchar - '0';
2823 if (**str >= '0' && **str <= '9')
2824 {
2825 processor = processor * 10 + *(*str)++ - '0';
2826 if (processor > 15)
2827 {
2828 inst.error = _("illegal co-processor number");
2829 return FAIL;
2830 }
2831 }
2832 }
2833 else
2834 {
2835 inst.error = _("bad or missing co-processor number");
2836 return FAIL;
2837 }
2838 }
2839
2840 inst.instruction |= processor << 8;
2841 return SUCCESS;
2842 }
2843
2844 static int
2845 cp_opc_expr (str, where, length)
2846 char ** str;
2847 int where;
2848 int length;
2849 {
2850 expressionS expr;
2851
2852 skip_whitespace (* str);
2853
2854 memset (&expr, '\0', sizeof (expr));
2855
2856 if (my_get_expression (&expr, str))
2857 return FAIL;
2858 if (expr.X_op != O_constant)
2859 {
2860 inst.error = _("bad or missing expression");
2861 return FAIL;
2862 }
2863
2864 if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
2865 {
2866 inst.error = _("immediate co-processor expression too large");
2867 return FAIL;
2868 }
2869
2870 inst.instruction |= expr.X_add_number << where;
2871 return SUCCESS;
2872 }
2873
2874 static int
2875 cp_reg_required_here (str, where)
2876 char ** str;
2877 int where;
2878 {
2879 int reg;
2880 char * start = *str;
2881
2882 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
2883 {
2884 inst.instruction |= reg << where;
2885 return reg;
2886 }
2887
2888 /* In the few cases where we might be able to accept something else
2889 this error can be overridden. */
2890 inst.error = _("co-processor register expected");
2891
2892 /* Restore the start point. */
2893 *str = start;
2894 return FAIL;
2895 }
2896
2897 static int
2898 fp_reg_required_here (str, where)
2899 char ** str;
2900 int where;
2901 {
2902 int reg;
2903 char * start = * str;
2904
2905 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
2906 {
2907 inst.instruction |= reg << where;
2908 return reg;
2909 }
2910
2911 /* In the few cases where we might be able to accept something else
2912 this error can be overridden. */
2913 inst.error = _("floating point register expected");
2914
2915 /* Restore the start point. */
2916 *str = start;
2917 return FAIL;
2918 }
2919
2920 static int
2921 cp_address_offset (str)
2922 char ** str;
2923 {
2924 int offset;
2925
2926 skip_whitespace (* str);
2927
2928 if (! is_immediate_prefix (**str))
2929 {
2930 inst.error = _("immediate expression expected");
2931 return FAIL;
2932 }
2933
2934 (*str)++;
2935
2936 if (my_get_expression (& inst.reloc.exp, str))
2937 return FAIL;
2938
2939 if (inst.reloc.exp.X_op == O_constant)
2940 {
2941 offset = inst.reloc.exp.X_add_number;
2942
2943 if (offset & 3)
2944 {
2945 inst.error = _("co-processor address must be word aligned");
2946 return FAIL;
2947 }
2948
2949 if (offset > 1023 || offset < -1023)
2950 {
2951 inst.error = _("offset too large");
2952 return FAIL;
2953 }
2954
2955 if (offset >= 0)
2956 inst.instruction |= INDEX_UP;
2957 else
2958 offset = -offset;
2959
2960 inst.instruction |= offset >> 2;
2961 }
2962 else
2963 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
2964
2965 return SUCCESS;
2966 }
2967
2968 static int
2969 cp_address_required_here (str, wb_ok)
2970 char ** str;
2971 int wb_ok;
2972 {
2973 char * p = * str;
2974 int pre_inc = 0;
2975 int write_back = 0;
2976
2977 if (*p == '[')
2978 {
2979 int reg;
2980
2981 p++;
2982 skip_whitespace (p);
2983
2984 if ((reg = reg_required_here (& p, 16)) == FAIL)
2985 return FAIL;
2986
2987 skip_whitespace (p);
2988
2989 if (*p == ']')
2990 {
2991 p++;
2992
2993 if (wb_ok && skip_past_comma (& p) == SUCCESS)
2994 {
2995 /* [Rn], #expr */
2996 write_back = WRITE_BACK;
2997
2998 if (reg == REG_PC)
2999 {
3000 inst.error = _("pc may not be used in post-increment");
3001 return FAIL;
3002 }
3003
3004 if (cp_address_offset (& p) == FAIL)
3005 return FAIL;
3006 }
3007 else
3008 pre_inc = PRE_INDEX | INDEX_UP;
3009 }
3010 else
3011 {
3012 /* '['Rn, #expr']'[!] */
3013
3014 if (skip_past_comma (& p) == FAIL)
3015 {
3016 inst.error = _("pre-indexed expression expected");
3017 return FAIL;
3018 }
3019
3020 pre_inc = PRE_INDEX;
3021
3022 if (cp_address_offset (& p) == FAIL)
3023 return FAIL;
3024
3025 skip_whitespace (p);
3026
3027 if (*p++ != ']')
3028 {
3029 inst.error = _("missing ]");
3030 return FAIL;
3031 }
3032
3033 skip_whitespace (p);
3034
3035 if (wb_ok && *p == '!')
3036 {
3037 if (reg == REG_PC)
3038 {
3039 inst.error = _("pc may not be used with write-back");
3040 return FAIL;
3041 }
3042
3043 p++;
3044 write_back = WRITE_BACK;
3045 }
3046 }
3047 }
3048 else
3049 {
3050 if (my_get_expression (&inst.reloc.exp, &p))
3051 return FAIL;
3052
3053 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3054 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
3055 inst.reloc.pc_rel = 1;
3056 inst.instruction |= (REG_PC << 16);
3057 pre_inc = PRE_INDEX;
3058 }
3059
3060 inst.instruction |= write_back | pre_inc;
3061 *str = p;
3062 return SUCCESS;
3063 }
3064
3065 static void
3066 do_empty (str)
3067 char * str;
3068 {
3069 /* Do nothing really. */
3070 end_of_line (str);
3071 return;
3072 }
3073
3074 static void
3075 do_mrs (str)
3076 char *str;
3077 {
3078 int skip = 0;
3079
3080 /* Only one syntax. */
3081 skip_whitespace (str);
3082
3083 if (reg_required_here (&str, 12) == FAIL)
3084 {
3085 inst.error = BAD_ARGS;
3086 return;
3087 }
3088
3089 if (skip_past_comma (&str) == FAIL)
3090 {
3091 inst.error = _("comma expected after register name");
3092 return;
3093 }
3094
3095 skip_whitespace (str);
3096
3097 if ( strcmp (str, "CPSR") == 0
3098 || strcmp (str, "SPSR") == 0
3099 /* Lower case versions for backwards compatability. */
3100 || strcmp (str, "cpsr") == 0
3101 || strcmp (str, "spsr") == 0)
3102 skip = 4;
3103
3104 /* This is for backwards compatability with older toolchains. */
3105 else if ( strcmp (str, "cpsr_all") == 0
3106 || strcmp (str, "spsr_all") == 0)
3107 skip = 8;
3108 else
3109 {
3110 inst.error = _("CPSR or SPSR expected");
3111 return;
3112 }
3113
3114 if (* str == 's' || * str == 'S')
3115 inst.instruction |= SPSR_BIT;
3116 str += skip;
3117
3118 end_of_line (str);
3119 }
3120
3121 /* Two possible forms:
3122 "{C|S}PSR_<field>, Rm",
3123 "{C|S}PSR_f, #expression". */
3124
3125 static void
3126 do_msr (str)
3127 char * str;
3128 {
3129 skip_whitespace (str);
3130
3131 if (psr_required_here (& str) == FAIL)
3132 return;
3133
3134 if (skip_past_comma (& str) == FAIL)
3135 {
3136 inst.error = _("comma missing after psr flags");
3137 return;
3138 }
3139
3140 skip_whitespace (str);
3141
3142 if (reg_required_here (& str, 0) != FAIL)
3143 {
3144 inst.error = NULL;
3145 end_of_line (str);
3146 return;
3147 }
3148
3149 if (! is_immediate_prefix (* str))
3150 {
3151 inst.error =
3152 _("only a register or immediate value can follow a psr flag");
3153 return;
3154 }
3155
3156 str ++;
3157 inst.error = NULL;
3158
3159 if (my_get_expression (& inst.reloc.exp, & str))
3160 {
3161 inst.error =
3162 _("only a register or immediate value can follow a psr flag");
3163 return;
3164 }
3165
3166 #if 0 /* The first edition of the ARM architecture manual stated that
3167 writing anything other than the flags with an immediate operation
3168 had UNPREDICTABLE effects. This constraint was removed in the
3169 second edition of the specification. */
3170 if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5
3171 && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
3172 {
3173 inst.error = _("immediate value cannot be used to set this field");
3174 return;
3175 }
3176 #endif
3177
3178 inst.instruction |= INST_IMMEDIATE;
3179
3180 if (inst.reloc.exp.X_add_symbol)
3181 {
3182 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
3183 inst.reloc.pc_rel = 0;
3184 }
3185 else
3186 {
3187 unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
3188
3189 if (value == (unsigned) FAIL)
3190 {
3191 inst.error = _("invalid constant");
3192 return;
3193 }
3194
3195 inst.instruction |= value;
3196 }
3197
3198 inst.error = NULL;
3199 end_of_line (str);
3200 }
3201
3202 /* Long Multiply Parser
3203 UMULL RdLo, RdHi, Rm, Rs
3204 SMULL RdLo, RdHi, Rm, Rs
3205 UMLAL RdLo, RdHi, Rm, Rs
3206 SMLAL RdLo, RdHi, Rm, Rs. */
3207
3208 static void
3209 do_mull (str)
3210 char * str;
3211 {
3212 int rdlo, rdhi, rm, rs;
3213
3214 /* Only one format "rdlo, rdhi, rm, rs". */
3215 skip_whitespace (str);
3216
3217 if ((rdlo = reg_required_here (&str, 12)) == FAIL)
3218 {
3219 inst.error = BAD_ARGS;
3220 return;
3221 }
3222
3223 if (skip_past_comma (&str) == FAIL
3224 || (rdhi = reg_required_here (&str, 16)) == FAIL)
3225 {
3226 inst.error = BAD_ARGS;
3227 return;
3228 }
3229
3230 if (skip_past_comma (&str) == FAIL
3231 || (rm = reg_required_here (&str, 0)) == FAIL)
3232 {
3233 inst.error = BAD_ARGS;
3234 return;
3235 }
3236
3237 /* rdhi, rdlo and rm must all be different. */
3238 if (rdlo == rdhi || rdlo == rm || rdhi == rm)
3239 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
3240
3241 if (skip_past_comma (&str) == FAIL
3242 || (rs = reg_required_here (&str, 8)) == FAIL)
3243 {
3244 inst.error = BAD_ARGS;
3245 return;
3246 }
3247
3248 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
3249 {
3250 inst.error = BAD_PC;
3251 return;
3252 }
3253
3254 end_of_line (str);
3255 return;
3256 }
3257
3258 static void
3259 do_mul (str)
3260 char * str;
3261 {
3262 int rd, rm;
3263
3264 /* Only one format "rd, rm, rs". */
3265 skip_whitespace (str);
3266
3267 if ((rd = reg_required_here (&str, 16)) == FAIL)
3268 {
3269 inst.error = BAD_ARGS;
3270 return;
3271 }
3272
3273 if (rd == REG_PC)
3274 {
3275 inst.error = BAD_PC;
3276 return;
3277 }
3278
3279 if (skip_past_comma (&str) == FAIL
3280 || (rm = reg_required_here (&str, 0)) == FAIL)
3281 {
3282 inst.error = BAD_ARGS;
3283 return;
3284 }
3285
3286 if (rm == REG_PC)
3287 {
3288 inst.error = BAD_PC;
3289 return;
3290 }
3291
3292 if (rm == rd)
3293 as_tsktsk (_("rd and rm should be different in mul"));
3294
3295 if (skip_past_comma (&str) == FAIL
3296 || (rm = reg_required_here (&str, 8)) == FAIL)
3297 {
3298 inst.error = BAD_ARGS;
3299 return;
3300 }
3301
3302 if (rm == REG_PC)
3303 {
3304 inst.error = BAD_PC;
3305 return;
3306 }
3307
3308 end_of_line (str);
3309 return;
3310 }
3311
3312 static void
3313 do_mla (str)
3314 char * str;
3315 {
3316 int rd, rm;
3317
3318 /* Only one format "rd, rm, rs, rn". */
3319 skip_whitespace (str);
3320
3321 if ((rd = reg_required_here (&str, 16)) == FAIL)
3322 {
3323 inst.error = BAD_ARGS;
3324 return;
3325 }
3326
3327 if (rd == REG_PC)
3328 {
3329 inst.error = BAD_PC;
3330 return;
3331 }
3332
3333 if (skip_past_comma (&str) == FAIL
3334 || (rm = reg_required_here (&str, 0)) == FAIL)
3335 {
3336 inst.error = BAD_ARGS;
3337 return;
3338 }
3339
3340 if (rm == REG_PC)
3341 {
3342 inst.error = BAD_PC;
3343 return;
3344 }
3345
3346 if (rm == rd)
3347 as_tsktsk (_("rd and rm should be different in mla"));
3348
3349 if (skip_past_comma (&str) == FAIL
3350 || (rd = reg_required_here (&str, 8)) == FAIL
3351 || skip_past_comma (&str) == FAIL
3352 || (rm = reg_required_here (&str, 12)) == FAIL)
3353 {
3354 inst.error = BAD_ARGS;
3355 return;
3356 }
3357
3358 if (rd == REG_PC || rm == REG_PC)
3359 {
3360 inst.error = BAD_PC;
3361 return;
3362 }
3363
3364 end_of_line (str);
3365 return;
3366 }
3367
3368 /* Expects *str -> the characters "acc0", possibly with leading blanks.
3369 Advances *str to the next non-alphanumeric.
3370 Returns 0, or else FAIL (in which case sets inst.error).
3371
3372 (In a future XScale, there may be accumulators other than zero.
3373 At that time this routine and its callers can be upgraded to suit.) */
3374
3375 static int
3376 accum0_required_here (str)
3377 char ** str;
3378 {
3379 static char buff [128]; /* Note the address is taken. Hence, static. */
3380 char * p = * str;
3381 char c;
3382 int result = 0; /* The accum number. */
3383
3384 skip_whitespace (p);
3385
3386 *str = p; /* Advance caller's string pointer too. */
3387 c = *p++;
3388 while (ISALNUM (c))
3389 c = *p++;
3390
3391 *--p = 0; /* Aap nul into input buffer at non-alnum. */
3392
3393 if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
3394 {
3395 sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
3396 inst.error = buff;
3397 result = FAIL;
3398 }
3399
3400 *p = c; /* Unzap. */
3401 *str = p; /* Caller's string pointer to after match. */
3402 return result;
3403 }
3404
3405 /* Expects **str -> after a comma. May be leading blanks.
3406 Advances *str, recognizing a load mode, and setting inst.instruction.
3407 Returns rn, or else FAIL (in which case may set inst.error
3408 and not advance str)
3409
3410 Note: doesn't know Rd, so no err checks that require such knowledge. */
3411
3412 static int
3413 ld_mode_required_here (string)
3414 char ** string;
3415 {
3416 char * str = * string;
3417 int rn;
3418 int pre_inc = 0;
3419
3420 skip_whitespace (str);
3421
3422 if (* str == '[')
3423 {
3424 str++;
3425
3426 skip_whitespace (str);
3427
3428 if ((rn = reg_required_here (& str, 16)) == FAIL)
3429 return FAIL;
3430
3431 skip_whitespace (str);
3432
3433 if (* str == ']')
3434 {
3435 str ++;
3436
3437 if (skip_past_comma (& str) == SUCCESS)
3438 {
3439 /* [Rn],... (post inc) */
3440 if (ldst_extend_v4 (&str) == FAIL)
3441 return FAIL;
3442 }
3443 else /* [Rn] */
3444 {
3445 skip_whitespace (str);
3446
3447 if (* str == '!')
3448 {
3449 str ++;
3450 inst.instruction |= WRITE_BACK;
3451 }
3452
3453 inst.instruction |= INDEX_UP | HWOFFSET_IMM;
3454 pre_inc = 1;
3455 }
3456 }
3457 else /* [Rn,...] */
3458 {
3459 if (skip_past_comma (& str) == FAIL)
3460 {
3461 inst.error = _("pre-indexed expression expected");
3462 return FAIL;
3463 }
3464
3465 pre_inc = 1;
3466
3467 if (ldst_extend_v4 (&str) == FAIL)
3468 return FAIL;
3469
3470 skip_whitespace (str);
3471
3472 if (* str ++ != ']')
3473 {
3474 inst.error = _("missing ]");
3475 return FAIL;
3476 }
3477
3478 skip_whitespace (str);
3479
3480 if (* str == '!')
3481 {
3482 str ++;
3483 inst.instruction |= WRITE_BACK;
3484 }
3485 }
3486 }
3487 else if (* str == '=') /* ldr's "r,=label" syntax */
3488 /* We should never reach here, because <text> = <expression> is
3489 caught gas/read.c read_a_source_file() as a .set operation. */
3490 return FAIL;
3491 else /* PC +- 8 bit immediate offset. */
3492 {
3493 if (my_get_expression (& inst.reloc.exp, & str))
3494 return FAIL;
3495
3496 inst.instruction |= HWOFFSET_IMM; /* The I bit. */
3497 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
3498 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
3499 inst.reloc.pc_rel = 1;
3500 inst.instruction |= (REG_PC << 16);
3501
3502 rn = REG_PC;
3503 pre_inc = 1;
3504 }
3505
3506 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
3507 * string = str;
3508
3509 return rn;
3510 }
3511
3512 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
3513 SMLAxy{cond} Rd,Rm,Rs,Rn
3514 SMLAWy{cond} Rd,Rm,Rs,Rn
3515 Error if any register is R15. */
3516
3517 static void
3518 do_smla (str)
3519 char * str;
3520 {
3521 int rd, rm, rs, rn;
3522
3523 skip_whitespace (str);
3524
3525 if ((rd = reg_required_here (& str, 16)) == FAIL
3526 || skip_past_comma (& str) == FAIL
3527 || (rm = reg_required_here (& str, 0)) == FAIL
3528 || skip_past_comma (& str) == FAIL
3529 || (rs = reg_required_here (& str, 8)) == FAIL
3530 || skip_past_comma (& str) == FAIL
3531 || (rn = reg_required_here (& str, 12)) == FAIL)
3532 inst.error = BAD_ARGS;
3533
3534 else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
3535 inst.error = BAD_PC;
3536
3537 else
3538 end_of_line (str);
3539 }
3540
3541 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
3542 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
3543 Error if any register is R15.
3544 Warning if Rdlo == Rdhi. */
3545
3546 static void
3547 do_smlal (str)
3548 char * str;
3549 {
3550 int rdlo, rdhi, rm, rs;
3551
3552 skip_whitespace (str);
3553
3554 if ((rdlo = reg_required_here (& str, 12)) == FAIL
3555 || skip_past_comma (& str) == FAIL
3556 || (rdhi = reg_required_here (& str, 16)) == FAIL
3557 || skip_past_comma (& str) == FAIL
3558 || (rm = reg_required_here (& str, 0)) == FAIL
3559 || skip_past_comma (& str) == FAIL
3560 || (rs = reg_required_here (& str, 8)) == FAIL)
3561 {
3562 inst.error = BAD_ARGS;
3563 return;
3564 }
3565
3566 if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
3567 {
3568 inst.error = BAD_PC;
3569 return;
3570 }
3571
3572 if (rdlo == rdhi)
3573 as_tsktsk (_("rdhi and rdlo must be different"));
3574
3575 end_of_line (str);
3576 }
3577
3578 /* ARM V5E (El Segundo) signed-multiply (argument parse)
3579 SMULxy{cond} Rd,Rm,Rs
3580 Error if any register is R15. */
3581
3582 static void
3583 do_smul (str)
3584 char * str;
3585 {
3586 int rd, rm, rs;
3587
3588 skip_whitespace (str);
3589
3590 if ((rd = reg_required_here (& str, 16)) == FAIL
3591 || skip_past_comma (& str) == FAIL
3592 || (rm = reg_required_here (& str, 0)) == FAIL
3593 || skip_past_comma (& str) == FAIL
3594 || (rs = reg_required_here (& str, 8)) == FAIL)
3595 inst.error = BAD_ARGS;
3596
3597 else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
3598 inst.error = BAD_PC;
3599
3600 else
3601 end_of_line (str);
3602 }
3603
3604 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
3605 Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
3606 Error if any register is R15. */
3607
3608 static void
3609 do_qadd (str)
3610 char * str;
3611 {
3612 int rd, rm, rn;
3613
3614 skip_whitespace (str);
3615
3616 if ((rd = reg_required_here (& str, 12)) == FAIL
3617 || skip_past_comma (& str) == FAIL
3618 || (rm = reg_required_here (& str, 0)) == FAIL
3619 || skip_past_comma (& str) == FAIL
3620 || (rn = reg_required_here (& str, 16)) == FAIL)
3621 inst.error = BAD_ARGS;
3622
3623 else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
3624 inst.error = BAD_PC;
3625
3626 else
3627 end_of_line (str);
3628 }
3629
3630 /* ARM V5E (el Segundo)
3631 MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3632 MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3633
3634 These are equivalent to the XScale instructions MAR and MRA,
3635 respectively, when coproc == 0, opcode == 0, and CRm == 0.
3636
3637 Result unpredicatable if Rd or Rn is R15. */
3638
3639 static void
3640 do_co_reg2c (str)
3641 char * str;
3642 {
3643 int rd, rn;
3644
3645 skip_whitespace (str);
3646
3647 if (co_proc_number (& str) == FAIL)
3648 {
3649 if (!inst.error)
3650 inst.error = BAD_ARGS;
3651 return;
3652 }
3653
3654 if (skip_past_comma (& str) == FAIL
3655 || cp_opc_expr (& str, 4, 4) == FAIL)
3656 {
3657 if (!inst.error)
3658 inst.error = BAD_ARGS;
3659 return;
3660 }
3661
3662 if (skip_past_comma (& str) == FAIL
3663 || (rd = reg_required_here (& str, 12)) == FAIL)
3664 {
3665 if (!inst.error)
3666 inst.error = BAD_ARGS;
3667 return;
3668 }
3669
3670 if (skip_past_comma (& str) == FAIL
3671 || (rn = reg_required_here (& str, 16)) == FAIL)
3672 {
3673 if (!inst.error)
3674 inst.error = BAD_ARGS;
3675 return;
3676 }
3677
3678 /* Unpredictable result if rd or rn is R15. */
3679 if (rd == REG_PC || rn == REG_PC)
3680 as_tsktsk
3681 (_("Warning: instruction unpredictable when using r15"));
3682
3683 if (skip_past_comma (& str) == FAIL
3684 || cp_reg_required_here (& str, 0) == FAIL)
3685 {
3686 if (!inst.error)
3687 inst.error = BAD_ARGS;
3688 return;
3689 }
3690
3691 end_of_line (str);
3692 }
3693
3694 /* ARM V5 count-leading-zeroes instruction (argument parse)
3695 CLZ{<cond>} <Rd>, <Rm>
3696 Condition defaults to COND_ALWAYS.
3697 Error if Rd or Rm are R15. */
3698
3699 static void
3700 do_clz (str)
3701 char * str;
3702 {
3703 int rd, rm;
3704
3705 skip_whitespace (str);
3706
3707 if (((rd = reg_required_here (& str, 12)) == FAIL)
3708 || (skip_past_comma (& str) == FAIL)
3709 || ((rm = reg_required_here (& str, 0)) == FAIL))
3710 inst.error = BAD_ARGS;
3711
3712 else if (rd == REG_PC || rm == REG_PC )
3713 inst.error = BAD_PC;
3714
3715 else
3716 end_of_line (str);
3717 }
3718
3719 /* ARM V5 (argument parse)
3720 LDC2{L} <coproc>, <CRd>, <addressing mode>
3721 STC2{L} <coproc>, <CRd>, <addressing mode>
3722 Instruction is not conditional, and has 0xf in the codition field.
3723 Otherwise, it's the same as LDC/STC. */
3724
3725 static void
3726 do_lstc2 (str)
3727 char * str;
3728 {
3729 skip_whitespace (str);
3730
3731 if (co_proc_number (& str) == FAIL)
3732 {
3733 if (!inst.error)
3734 inst.error = BAD_ARGS;
3735 }
3736 else if (skip_past_comma (& str) == FAIL
3737 || cp_reg_required_here (& str, 12) == FAIL)
3738 {
3739 if (!inst.error)
3740 inst.error = BAD_ARGS;
3741 }
3742 else if (skip_past_comma (& str) == FAIL
3743 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
3744 {
3745 if (! inst.error)
3746 inst.error = BAD_ARGS;
3747 }
3748 else
3749 end_of_line (str);
3750 }
3751
3752 /* ARM V5 (argument parse)
3753 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
3754 Instruction is not conditional, and has 0xf in the condition field.
3755 Otherwise, it's the same as CDP. */
3756
3757 static void
3758 do_cdp2 (str)
3759 char * str;
3760 {
3761 skip_whitespace (str);
3762
3763 if (co_proc_number (& str) == FAIL)
3764 {
3765 if (!inst.error)
3766 inst.error = BAD_ARGS;
3767 return;
3768 }
3769
3770 if (skip_past_comma (& str) == FAIL
3771 || cp_opc_expr (& str, 20,4) == FAIL)
3772 {
3773 if (!inst.error)
3774 inst.error = BAD_ARGS;
3775 return;
3776 }
3777
3778 if (skip_past_comma (& str) == FAIL
3779 || cp_reg_required_here (& str, 12) == FAIL)
3780 {
3781 if (!inst.error)
3782 inst.error = BAD_ARGS;
3783 return;
3784 }
3785
3786 if (skip_past_comma (& str) == FAIL
3787 || cp_reg_required_here (& str, 16) == FAIL)
3788 {
3789 if (!inst.error)
3790 inst.error = BAD_ARGS;
3791 return;
3792 }
3793
3794 if (skip_past_comma (& str) == FAIL
3795 || cp_reg_required_here (& str, 0) == FAIL)
3796 {
3797 if (!inst.error)
3798 inst.error = BAD_ARGS;
3799 return;
3800 }
3801
3802 if (skip_past_comma (& str) == SUCCESS)
3803 {
3804 if (cp_opc_expr (& str, 5, 3) == FAIL)
3805 {
3806 if (!inst.error)
3807 inst.error = BAD_ARGS;
3808 return;
3809 }
3810 }
3811
3812 end_of_line (str);
3813 }
3814
3815 /* ARM V5 (argument parse)
3816 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3817 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3818 Instruction is not conditional, and has 0xf in the condition field.
3819 Otherwise, it's the same as MCR/MRC. */
3820
3821 static void
3822 do_co_reg2 (str)
3823 char * str;
3824 {
3825 skip_whitespace (str);
3826
3827 if (co_proc_number (& str) == FAIL)
3828 {
3829 if (!inst.error)
3830 inst.error = BAD_ARGS;
3831 return;
3832 }
3833
3834 if (skip_past_comma (& str) == FAIL
3835 || cp_opc_expr (& str, 21, 3) == FAIL)
3836 {
3837 if (!inst.error)
3838 inst.error = BAD_ARGS;
3839 return;
3840 }
3841
3842 if (skip_past_comma (& str) == FAIL
3843 || reg_required_here (& str, 12) == FAIL)
3844 {
3845 if (!inst.error)
3846 inst.error = BAD_ARGS;
3847 return;
3848 }
3849
3850 if (skip_past_comma (& str) == FAIL
3851 || cp_reg_required_here (& str, 16) == FAIL)
3852 {
3853 if (!inst.error)
3854 inst.error = BAD_ARGS;
3855 return;
3856 }
3857
3858 if (skip_past_comma (& str) == FAIL
3859 || cp_reg_required_here (& str, 0) == FAIL)
3860 {
3861 if (!inst.error)
3862 inst.error = BAD_ARGS;
3863 return;
3864 }
3865
3866 if (skip_past_comma (& str) == SUCCESS)
3867 {
3868 if (cp_opc_expr (& str, 5, 3) == FAIL)
3869 {
3870 if (!inst.error)
3871 inst.error = BAD_ARGS;
3872 return;
3873 }
3874 }
3875
3876 end_of_line (str);
3877 }
3878
3879 /* THUMB V5 breakpoint instruction (argument parse)
3880 BKPT <immed_8>. */
3881
3882 static void
3883 do_t_bkpt (str)
3884 char * str;
3885 {
3886 expressionS expr;
3887 unsigned long number;
3888
3889 skip_whitespace (str);
3890
3891 /* Allow optional leading '#'. */
3892 if (is_immediate_prefix (*str))
3893 str ++;
3894
3895 memset (& expr, '\0', sizeof (expr));
3896 if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
3897 {
3898 inst.error = _("bad or missing expression");
3899 return;
3900 }
3901
3902 number = expr.X_add_number;
3903
3904 /* Check it fits an 8 bit unsigned. */
3905 if (number != (number & 0xff))
3906 {
3907 inst.error = _("immediate value out of range");
3908 return;
3909 }
3910
3911 inst.instruction |= number;
3912
3913 end_of_line (str);
3914 }
3915
3916 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
3917 Expects inst.instruction is set for BLX(1).
3918 Note: this is cloned from do_branch, and the reloc changed to be a
3919 new one that can cope with setting one extra bit (the H bit). */
3920
3921 static void
3922 do_branch25 (str)
3923 char * str;
3924 {
3925 if (my_get_expression (& inst.reloc.exp, & str))
3926 return;
3927
3928 #ifdef OBJ_ELF
3929 {
3930 char * save_in;
3931
3932 /* ScottB: February 5, 1998 */
3933 /* Check to see of PLT32 reloc required for the instruction. */
3934
3935 /* arm_parse_reloc() works on input_line_pointer.
3936 We actually want to parse the operands to the branch instruction
3937 passed in 'str'. Save the input pointer and restore it later. */
3938 save_in = input_line_pointer;
3939 input_line_pointer = str;
3940
3941 if (inst.reloc.exp.X_op == O_symbol
3942 && *str == '('
3943 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
3944 {
3945 inst.reloc.type = BFD_RELOC_ARM_PLT32;
3946 inst.reloc.pc_rel = 0;
3947 /* Modify str to point to after parsed operands, otherwise
3948 end_of_line() will complain about the (PLT) left in str. */
3949 str = input_line_pointer;
3950 }
3951 else
3952 {
3953 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
3954 inst.reloc.pc_rel = 1;
3955 }
3956
3957 input_line_pointer = save_in;
3958 }
3959 #else
3960 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
3961 inst.reloc.pc_rel = 1;
3962 #endif /* OBJ_ELF */
3963
3964 end_of_line (str);
3965 }
3966
3967 /* ARM V5 branch-link-exchange instruction (argument parse)
3968 BLX <target_addr> ie BLX(1)
3969 BLX{<condition>} <Rm> ie BLX(2)
3970 Unfortunately, there are two different opcodes for this mnemonic.
3971 So, the insns[].value is not used, and the code here zaps values
3972 into inst.instruction.
3973 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
3974
3975 static void
3976 do_blx (str)
3977 char * str;
3978 {
3979 char * mystr = str;
3980 int rm;
3981
3982 skip_whitespace (mystr);
3983 rm = reg_required_here (& mystr, 0);
3984
3985 /* The above may set inst.error. Ignore his opinion. */
3986 inst.error = 0;
3987
3988 if (rm != FAIL)
3989 {
3990 /* Arg is a register.
3991 Use the condition code our caller put in inst.instruction.
3992 Pass ourselves off as a BX with a funny opcode. */
3993 inst.instruction |= 0x012fff30;
3994 do_bx (str);
3995 }
3996 else
3997 {
3998 /* This must be is BLX <target address>, no condition allowed. */
3999 if (inst.instruction != COND_ALWAYS)
4000 {
4001 inst.error = BAD_COND;
4002 return;
4003 }
4004
4005 inst.instruction = 0xfafffffe;
4006
4007 /* Process like a B/BL, but with a different reloc.
4008 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
4009 do_branch25 (str);
4010 }
4011 }
4012
4013 /* ARM V5 Thumb BLX (argument parse)
4014 BLX <target_addr> which is BLX(1)
4015 BLX <Rm> which is BLX(2)
4016 Unfortunately, there are two different opcodes for this mnemonic.
4017 So, the tinsns[].value is not used, and the code here zaps values
4018 into inst.instruction. */
4019
4020 static void
4021 do_t_blx (str)
4022 char * str;
4023 {
4024 char * mystr = str;
4025 int rm;
4026
4027 skip_whitespace (mystr);
4028 inst.instruction = 0x4780;
4029
4030 /* Note that this call is to the ARM register recognizer. BLX(2)
4031 uses the ARM register space, not the Thumb one, so a call to
4032 thumb_reg() would be wrong. */
4033 rm = reg_required_here (& mystr, 3);
4034 inst.error = 0;
4035
4036 if (rm != FAIL)
4037 {
4038 /* It's BLX(2). The .instruction was zapped with rm & is final. */
4039 inst.size = 2;
4040 }
4041 else
4042 {
4043 /* No ARM register. This must be BLX(1). Change the .instruction. */
4044 inst.instruction = 0xf7ffeffe;
4045 inst.size = 4;
4046
4047 if (my_get_expression (& inst.reloc.exp, & mystr))
4048 return;
4049
4050 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX;
4051 inst.reloc.pc_rel = 1;
4052 }
4053
4054 end_of_line (mystr);
4055 }
4056
4057 /* ARM V5 breakpoint instruction (argument parse)
4058 BKPT <16 bit unsigned immediate>
4059 Instruction is not conditional.
4060 The bit pattern given in insns[] has the COND_ALWAYS condition,
4061 and it is an error if the caller tried to override that. */
4062
4063 static void
4064 do_bkpt (str)
4065 char * str;
4066 {
4067 expressionS expr;
4068 unsigned long number;
4069
4070 skip_whitespace (str);
4071
4072 /* Allow optional leading '#'. */
4073 if (is_immediate_prefix (* str))
4074 str++;
4075
4076 memset (& expr, '\0', sizeof (expr));
4077
4078 if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
4079 {
4080 inst.error = _("bad or missing expression");
4081 return;
4082 }
4083
4084 number = expr.X_add_number;
4085
4086 /* Check it fits a 16 bit unsigned. */
4087 if (number != (number & 0xffff))
4088 {
4089 inst.error = _("immediate value out of range");
4090 return;
4091 }
4092
4093 /* Top 12 of 16 bits to bits 19:8. */
4094 inst.instruction |= (number & 0xfff0) << 4;
4095
4096 /* Bottom 4 of 16 bits to bits 3:0. */
4097 inst.instruction |= number & 0xf;
4098
4099 end_of_line (str);
4100 }
4101
4102 /* Xscale multiply-accumulate (argument parse)
4103 MIAcc acc0,Rm,Rs
4104 MIAPHcc acc0,Rm,Rs
4105 MIAxycc acc0,Rm,Rs. */
4106
4107 static void
4108 do_mia (str)
4109 char * str;
4110 {
4111 int rs;
4112 int rm;
4113
4114 if (accum0_required_here (& str) == FAIL)
4115 inst.error = ERR_NO_ACCUM;
4116
4117 else if (skip_past_comma (& str) == FAIL
4118 || (rm = reg_required_here (& str, 0)) == FAIL)
4119 inst.error = BAD_ARGS;
4120
4121 else if (skip_past_comma (& str) == FAIL
4122 || (rs = reg_required_here (& str, 12)) == FAIL)
4123 inst.error = BAD_ARGS;
4124
4125 /* inst.instruction has now been zapped with both rm and rs. */
4126 else if (rm == REG_PC || rs == REG_PC)
4127 inst.error = BAD_PC; /* Undefined result if rm or rs is R15. */
4128
4129 else
4130 end_of_line (str);
4131 }
4132
4133 /* Xscale move-accumulator-register (argument parse)
4134
4135 MARcc acc0,RdLo,RdHi. */
4136
4137 static void
4138 do_mar (str)
4139 char * str;
4140 {
4141 int rdlo, rdhi;
4142
4143 if (accum0_required_here (& str) == FAIL)
4144 inst.error = ERR_NO_ACCUM;
4145
4146 else if (skip_past_comma (& str) == FAIL
4147 || (rdlo = reg_required_here (& str, 12)) == FAIL)
4148 inst.error = BAD_ARGS;
4149
4150 else if (skip_past_comma (& str) == FAIL
4151 || (rdhi = reg_required_here (& str, 16)) == FAIL)
4152 inst.error = BAD_ARGS;
4153
4154 /* inst.instruction has now been zapped with both rdlo and rdhi. */
4155 else if (rdlo == REG_PC || rdhi == REG_PC)
4156 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
4157
4158 else
4159 end_of_line (str);
4160 }
4161
4162 /* Xscale move-register-accumulator (argument parse)
4163
4164 MRAcc RdLo,RdHi,acc0. */
4165
4166 static void
4167 do_mra (str)
4168 char * str;
4169 {
4170 int rdlo;
4171 int rdhi;
4172
4173 skip_whitespace (str);
4174
4175 if ((rdlo = reg_required_here (& str, 12)) == FAIL)
4176 inst.error = BAD_ARGS;
4177
4178 else if (skip_past_comma (& str) == FAIL
4179 || (rdhi = reg_required_here (& str, 16)) == FAIL)
4180 inst.error = BAD_ARGS;
4181
4182 else if (skip_past_comma (& str) == FAIL
4183 || accum0_required_here (& str) == FAIL)
4184 inst.error = ERR_NO_ACCUM;
4185
4186 /* inst.instruction has now been zapped with both rdlo and rdhi. */
4187 else if (rdlo == rdhi)
4188 inst.error = BAD_ARGS; /* Undefined result if 2 writes to same reg. */
4189
4190 else if (rdlo == REG_PC || rdhi == REG_PC)
4191 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
4192 else
4193 end_of_line (str);
4194 }
4195
4196 /* ARMv5TE: Preload-Cache
4197
4198 PLD <addr_mode>
4199
4200 Syntactically, like LDR with B=1, W=0, L=1. */
4201
4202 static void
4203 do_pld (str)
4204 char * str;
4205 {
4206 int rd;
4207
4208 skip_whitespace (str);
4209
4210 if (* str != '[')
4211 {
4212 inst.error = _("'[' expected after PLD mnemonic");
4213 return;
4214 }
4215
4216 ++str;
4217 skip_whitespace (str);
4218
4219 if ((rd = reg_required_here (& str, 16)) == FAIL)
4220 return;
4221
4222 skip_whitespace (str);
4223
4224 if (*str == ']')
4225 {
4226 /* [Rn], ... ? */
4227 ++str;
4228 skip_whitespace (str);
4229
4230 /* Post-indexed addressing is not allowed with PLD. */
4231 if (skip_past_comma (&str) == SUCCESS)
4232 {
4233 inst.error
4234 = _("post-indexed expression used in preload instruction");
4235 return;
4236 }
4237 else if (*str == '!') /* [Rn]! */
4238 {
4239 inst.error = _("writeback used in preload instruction");
4240 ++str;
4241 }
4242 else /* [Rn] */
4243 inst.instruction |= INDEX_UP | PRE_INDEX;
4244 }
4245 else /* [Rn, ...] */
4246 {
4247 if (skip_past_comma (& str) == FAIL)
4248 {
4249 inst.error = _("pre-indexed expression expected");
4250 return;
4251 }
4252
4253 if (ldst_extend (&str) == FAIL)
4254 return;
4255
4256 skip_whitespace (str);
4257
4258 if (* str != ']')
4259 {
4260 inst.error = _("missing ]");
4261 return;
4262 }
4263
4264 ++ str;
4265 skip_whitespace (str);
4266
4267 if (* str == '!') /* [Rn]! */
4268 {
4269 inst.error = _("writeback used in preload instruction");
4270 ++ str;
4271 }
4272
4273 inst.instruction |= PRE_INDEX;
4274 }
4275
4276 end_of_line (str);
4277 }
4278
4279 /* ARMv5TE load-consecutive (argument parse)
4280 Mode is like LDRH.
4281
4282 LDRccD R, mode
4283 STRccD R, mode. */
4284
4285 static void
4286 do_ldrd (str)
4287 char * str;
4288 {
4289 int rd;
4290 int rn;
4291
4292 skip_whitespace (str);
4293
4294 if ((rd = reg_required_here (& str, 12)) == FAIL)
4295 {
4296 inst.error = BAD_ARGS;
4297 return;
4298 }
4299
4300 if (skip_past_comma (& str) == FAIL
4301 || (rn = ld_mode_required_here (& str)) == FAIL)
4302 {
4303 if (!inst.error)
4304 inst.error = BAD_ARGS;
4305 return;
4306 }
4307
4308 /* inst.instruction has now been zapped with Rd and the addressing mode. */
4309 if (rd & 1) /* Unpredictable result if Rd is odd. */
4310 {
4311 inst.error = _("destination register must be even");
4312 return;
4313 }
4314
4315 if (rd == REG_LR)
4316 {
4317 inst.error = _("r14 not allowed here");
4318 return;
4319 }
4320
4321 if (((rd == rn) || (rd + 1 == rn))
4322 && ((inst.instruction & WRITE_BACK)
4323 || (!(inst.instruction & PRE_INDEX))))
4324 as_warn (_("pre/post-indexing used when modified address register is destination"));
4325
4326 /* For an index-register load, the index register must not overlap the
4327 destination (even if not write-back). */
4328 if ((inst.instruction & V4_STR_BIT) == 0
4329 && (inst.instruction & HWOFFSET_IMM) == 0)
4330 {
4331 int rm = inst.instruction & 0x0000000f;
4332
4333 if (rm == rd || (rm == rd + 1))
4334 as_warn (_("ldrd destination registers must not overlap index register"));
4335 }
4336
4337 end_of_line (str);
4338 }
4339
4340 /* Returns the index into fp_values of a floating point number,
4341 or -1 if not in the table. */
4342
4343 static int
4344 my_get_float_expression (str)
4345 char ** str;
4346 {
4347 LITTLENUM_TYPE words[MAX_LITTLENUMS];
4348 char * save_in;
4349 expressionS exp;
4350 int i;
4351 int j;
4352
4353 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
4354
4355 /* Look for a raw floating point number. */
4356 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
4357 && is_end_of_line[(unsigned char) *save_in])
4358 {
4359 for (i = 0; i < NUM_FLOAT_VALS; i++)
4360 {
4361 for (j = 0; j < MAX_LITTLENUMS; j++)
4362 {
4363 if (words[j] != fp_values[i][j])
4364 break;
4365 }
4366
4367 if (j == MAX_LITTLENUMS)
4368 {
4369 *str = save_in;
4370 return i;
4371 }
4372 }
4373 }
4374
4375 /* Try and parse a more complex expression, this will probably fail
4376 unless the code uses a floating point prefix (eg "0f"). */
4377 save_in = input_line_pointer;
4378 input_line_pointer = *str;
4379 if (expression (&exp) == absolute_section
4380 && exp.X_op == O_big
4381 && exp.X_add_number < 0)
4382 {
4383 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
4384 Ditto for 15. */
4385 if (gen_to_words (words, 5, (long) 15) == 0)
4386 {
4387 for (i = 0; i < NUM_FLOAT_VALS; i++)
4388 {
4389 for (j = 0; j < MAX_LITTLENUMS; j++)
4390 {
4391 if (words[j] != fp_values[i][j])
4392 break;
4393 }
4394
4395 if (j == MAX_LITTLENUMS)
4396 {
4397 *str = input_line_pointer;
4398 input_line_pointer = save_in;
4399 return i;
4400 }
4401 }
4402 }
4403 }
4404
4405 *str = input_line_pointer;
4406 input_line_pointer = save_in;
4407 return -1;
4408 }
4409
4410 /* Return true if anything in the expression is a bignum. */
4411
4412 static int
4413 walk_no_bignums (sp)
4414 symbolS * sp;
4415 {
4416 if (symbol_get_value_expression (sp)->X_op == O_big)
4417 return 1;
4418
4419 if (symbol_get_value_expression (sp)->X_add_symbol)
4420 {
4421 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
4422 || (symbol_get_value_expression (sp)->X_op_symbol
4423 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
4424 }
4425
4426 return 0;
4427 }
4428
4429 static int in_my_get_expression = 0;
4430
4431 static int
4432 my_get_expression (ep, str)
4433 expressionS * ep;
4434 char ** str;
4435 {
4436 char * save_in;
4437 segT seg;
4438
4439 save_in = input_line_pointer;
4440 input_line_pointer = *str;
4441 in_my_get_expression = 1;
4442 seg = expression (ep);
4443 in_my_get_expression = 0;
4444
4445 if (ep->X_op == O_illegal)
4446 {
4447 /* We found a bad expression in md_operand(). */
4448 *str = input_line_pointer;
4449 input_line_pointer = save_in;
4450 return 1;
4451 }
4452
4453 #ifdef OBJ_AOUT
4454 if (seg != absolute_section
4455 && seg != text_section
4456 && seg != data_section
4457 && seg != bss_section
4458 && seg != undefined_section)
4459 {
4460 inst.error = _("bad_segment");
4461 *str = input_line_pointer;
4462 input_line_pointer = save_in;
4463 return 1;
4464 }
4465 #endif
4466
4467 /* Get rid of any bignums now, so that we don't generate an error for which
4468 we can't establish a line number later on. Big numbers are never valid
4469 in instructions, which is where this routine is always called. */
4470 if (ep->X_op == O_big
4471 || (ep->X_add_symbol
4472 && (walk_no_bignums (ep->X_add_symbol)
4473 || (ep->X_op_symbol
4474 && walk_no_bignums (ep->X_op_symbol)))))
4475 {
4476 inst.error = _("invalid constant");
4477 *str = input_line_pointer;
4478 input_line_pointer = save_in;
4479 return 1;
4480 }
4481
4482 *str = input_line_pointer;
4483 input_line_pointer = save_in;
4484 return 0;
4485 }
4486
4487 /* We handle all bad expressions here, so that we can report the faulty
4488 instruction in the error message. */
4489 void
4490 md_operand (expr)
4491 expressionS *expr;
4492 {
4493 if (in_my_get_expression)
4494 {
4495 expr->X_op = O_illegal;
4496 if (inst.error == NULL)
4497 inst.error = _("bad expression");
4498 }
4499 }
4500
4501 /* UNRESTRICT should be one if <shift> <register> is permitted for this
4502 instruction. */
4503
4504 static int
4505 decode_shift (str, unrestrict)
4506 char ** str;
4507 int unrestrict;
4508 {
4509 const struct asm_shift_name * shift;
4510 char * p;
4511 char c;
4512
4513 skip_whitespace (* str);
4514
4515 for (p = * str; ISALPHA (* p); p ++)
4516 ;
4517
4518 if (p == * str)
4519 {
4520 inst.error = _("shift expression expected");
4521 return FAIL;
4522 }
4523
4524 c = * p;
4525 * p = '\0';
4526 shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
4527 * p = c;
4528
4529 if (shift == NULL)
4530 {
4531 inst.error = _("shift expression expected");
4532 return FAIL;
4533 }
4534
4535 assert (shift->properties->index == shift_properties[shift->properties->index].index);
4536
4537 if (shift->properties->index == SHIFT_RRX)
4538 {
4539 * str = p;
4540 inst.instruction |= shift->properties->bit_field;
4541 return SUCCESS;
4542 }
4543
4544 skip_whitespace (p);
4545
4546 if (unrestrict && reg_required_here (& p, 8) != FAIL)
4547 {
4548 inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
4549 * str = p;
4550 return SUCCESS;
4551 }
4552 else if (! is_immediate_prefix (* p))
4553 {
4554 inst.error = (unrestrict
4555 ? _("shift requires register or #expression")
4556 : _("shift requires #expression"));
4557 * str = p;
4558 return FAIL;
4559 }
4560
4561 inst.error = NULL;
4562 p ++;
4563
4564 if (my_get_expression (& inst.reloc.exp, & p))
4565 return FAIL;
4566
4567 /* Validate some simple #expressions. */
4568 if (inst.reloc.exp.X_op == O_constant)
4569 {
4570 unsigned num = inst.reloc.exp.X_add_number;
4571
4572 /* Reject operations greater than 32. */
4573 if (num > 32
4574 /* Reject a shift of 0 unless the mode allows it. */
4575 || (num == 0 && shift->properties->allows_0 == 0)
4576 /* Reject a shift of 32 unless the mode allows it. */
4577 || (num == 32 && shift->properties->allows_32 == 0)
4578 )
4579 {
4580 /* As a special case we allow a shift of zero for
4581 modes that do not support it to be recoded as an
4582 logical shift left of zero (ie nothing). We warn
4583 about this though. */
4584 if (num == 0)
4585 {
4586 as_warn (_("shift of 0 ignored."));
4587 shift = & shift_names[0];
4588 assert (shift->properties->index == SHIFT_LSL);
4589 }
4590 else
4591 {
4592 inst.error = _("invalid immediate shift");
4593 return FAIL;
4594 }
4595 }
4596
4597 /* Shifts of 32 are encoded as 0, for those shifts that
4598 support it. */
4599 if (num == 32)
4600 num = 0;
4601
4602 inst.instruction |= (num << 7) | shift->properties->bit_field;
4603 }
4604 else
4605 {
4606 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
4607 inst.reloc.pc_rel = 0;
4608 inst.instruction |= shift->properties->bit_field;
4609 }
4610
4611 * str = p;
4612 return SUCCESS;
4613 }
4614
4615 /* Do those data_ops which can take a negative immediate constant
4616 by altering the instuction. A bit of a hack really.
4617 MOV <-> MVN
4618 AND <-> BIC
4619 ADC <-> SBC
4620 by inverting the second operand, and
4621 ADD <-> SUB
4622 CMP <-> CMN
4623 by negating the second operand. */
4624
4625 static int
4626 negate_data_op (instruction, value)
4627 unsigned long * instruction;
4628 unsigned long value;
4629 {
4630 int op, new_inst;
4631 unsigned long negated, inverted;
4632
4633 negated = validate_immediate (-value);
4634 inverted = validate_immediate (~value);
4635
4636 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
4637 switch (op)
4638 {
4639 /* First negates. */
4640 case OPCODE_SUB: /* ADD <-> SUB */
4641 new_inst = OPCODE_ADD;
4642 value = negated;
4643 break;
4644
4645 case OPCODE_ADD:
4646 new_inst = OPCODE_SUB;
4647 value = negated;
4648 break;
4649
4650 case OPCODE_CMP: /* CMP <-> CMN */
4651 new_inst = OPCODE_CMN;
4652 value = negated;
4653 break;
4654
4655 case OPCODE_CMN:
4656 new_inst = OPCODE_CMP;
4657 value = negated;
4658 break;
4659
4660 /* Now Inverted ops. */
4661 case OPCODE_MOV: /* MOV <-> MVN */
4662 new_inst = OPCODE_MVN;
4663 value = inverted;
4664 break;
4665
4666 case OPCODE_MVN:
4667 new_inst = OPCODE_MOV;
4668 value = inverted;
4669 break;
4670
4671 case OPCODE_AND: /* AND <-> BIC */
4672 new_inst = OPCODE_BIC;
4673 value = inverted;
4674 break;
4675
4676 case OPCODE_BIC:
4677 new_inst = OPCODE_AND;
4678 value = inverted;
4679 break;
4680
4681 case OPCODE_ADC: /* ADC <-> SBC */
4682 new_inst = OPCODE_SBC;
4683 value = inverted;
4684 break;
4685
4686 case OPCODE_SBC:
4687 new_inst = OPCODE_ADC;
4688 value = inverted;
4689 break;
4690
4691 /* We cannot do anything. */
4692 default:
4693 return FAIL;
4694 }
4695
4696 if (value == (unsigned) FAIL)
4697 return FAIL;
4698
4699 *instruction &= OPCODE_MASK;
4700 *instruction |= new_inst << DATA_OP_SHIFT;
4701 return value;
4702 }
4703
4704 static int
4705 data_op2 (str)
4706 char ** str;
4707 {
4708 int value;
4709 expressionS expr;
4710
4711 skip_whitespace (* str);
4712
4713 if (reg_required_here (str, 0) != FAIL)
4714 {
4715 if (skip_past_comma (str) == SUCCESS)
4716 /* Shift operation on register. */
4717 return decode_shift (str, NO_SHIFT_RESTRICT);
4718
4719 return SUCCESS;
4720 }
4721 else
4722 {
4723 /* Immediate expression. */
4724 if (is_immediate_prefix (**str))
4725 {
4726 (*str)++;
4727 inst.error = NULL;
4728
4729 if (my_get_expression (&inst.reloc.exp, str))
4730 return FAIL;
4731
4732 if (inst.reloc.exp.X_add_symbol)
4733 {
4734 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
4735 inst.reloc.pc_rel = 0;
4736 }
4737 else
4738 {
4739 if (skip_past_comma (str) == SUCCESS)
4740 {
4741 /* #x, y -- ie explicit rotation by Y. */
4742 if (my_get_expression (&expr, str))
4743 return FAIL;
4744
4745 if (expr.X_op != O_constant)
4746 {
4747 inst.error = _("constant expression expected");
4748 return FAIL;
4749 }
4750
4751 /* Rotate must be a multiple of 2. */
4752 if (((unsigned) expr.X_add_number) > 30
4753 || (expr.X_add_number & 1) != 0
4754 || ((unsigned) inst.reloc.exp.X_add_number) > 255)
4755 {
4756 inst.error = _("invalid constant");
4757 return FAIL;
4758 }
4759 inst.instruction |= INST_IMMEDIATE;
4760 inst.instruction |= inst.reloc.exp.X_add_number;
4761 inst.instruction |= expr.X_add_number << 7;
4762 return SUCCESS;
4763 }
4764
4765 /* Implicit rotation, select a suitable one. */
4766 value = validate_immediate (inst.reloc.exp.X_add_number);
4767
4768 if (value == FAIL)
4769 {
4770 /* Can't be done. Perhaps the code reads something like
4771 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
4772 if ((value = negate_data_op (&inst.instruction,
4773 inst.reloc.exp.X_add_number))
4774 == FAIL)
4775 {
4776 inst.error = _("invalid constant");
4777 return FAIL;
4778 }
4779 }
4780
4781 inst.instruction |= value;
4782 }
4783
4784 inst.instruction |= INST_IMMEDIATE;
4785 return SUCCESS;
4786 }
4787
4788 (*str)++;
4789 inst.error = _("register or shift expression expected");
4790 return FAIL;
4791 }
4792 }
4793
4794 static int
4795 fp_op2 (str)
4796 char ** str;
4797 {
4798 skip_whitespace (* str);
4799
4800 if (fp_reg_required_here (str, 0) != FAIL)
4801 return SUCCESS;
4802 else
4803 {
4804 /* Immediate expression. */
4805 if (*((*str)++) == '#')
4806 {
4807 int i;
4808
4809 inst.error = NULL;
4810
4811 skip_whitespace (* str);
4812
4813 /* First try and match exact strings, this is to guarantee
4814 that some formats will work even for cross assembly. */
4815
4816 for (i = 0; fp_const[i]; i++)
4817 {
4818 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
4819 {
4820 char *start = *str;
4821
4822 *str += strlen (fp_const[i]);
4823 if (is_end_of_line[(unsigned char) **str])
4824 {
4825 inst.instruction |= i + 8;
4826 return SUCCESS;
4827 }
4828 *str = start;
4829 }
4830 }
4831
4832 /* Just because we didn't get a match doesn't mean that the
4833 constant isn't valid, just that it is in a format that we
4834 don't automatically recognize. Try parsing it with
4835 the standard expression routines. */
4836 if ((i = my_get_float_expression (str)) >= 0)
4837 {
4838 inst.instruction |= i + 8;
4839 return SUCCESS;
4840 }
4841
4842 inst.error = _("invalid floating point immediate expression");
4843 return FAIL;
4844 }
4845 inst.error =
4846 _("floating point register or immediate expression expected");
4847 return FAIL;
4848 }
4849 }
4850
4851 static void
4852 do_arit (str)
4853 char * str;
4854 {
4855 skip_whitespace (str);
4856
4857 if (reg_required_here (&str, 12) == FAIL
4858 || skip_past_comma (&str) == FAIL
4859 || reg_required_here (&str, 16) == FAIL
4860 || skip_past_comma (&str) == FAIL
4861 || data_op2 (&str) == FAIL)
4862 {
4863 if (!inst.error)
4864 inst.error = BAD_ARGS;
4865 return;
4866 }
4867
4868 end_of_line (str);
4869 return;
4870 }
4871
4872 static void
4873 do_adr (str)
4874 char * str;
4875 {
4876 /* This is a pseudo-op of the form "adr rd, label" to be converted
4877 into a relative address of the form "add rd, pc, #label-.-8". */
4878 skip_whitespace (str);
4879
4880 if (reg_required_here (&str, 12) == FAIL
4881 || skip_past_comma (&str) == FAIL
4882 || my_get_expression (&inst.reloc.exp, &str))
4883 {
4884 if (!inst.error)
4885 inst.error = BAD_ARGS;
4886 return;
4887 }
4888
4889 /* Frag hacking will turn this into a sub instruction if the offset turns
4890 out to be negative. */
4891 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
4892 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust. */
4893 inst.reloc.pc_rel = 1;
4894
4895 end_of_line (str);
4896 }
4897
4898 static void
4899 do_adrl (str)
4900 char * str;
4901 {
4902 /* This is a pseudo-op of the form "adrl rd, label" to be converted
4903 into a relative address of the form:
4904 add rd, pc, #low(label-.-8)"
4905 add rd, rd, #high(label-.-8)" */
4906
4907 skip_whitespace (str);
4908
4909 if (reg_required_here (&str, 12) == FAIL
4910 || skip_past_comma (&str) == FAIL
4911 || my_get_expression (&inst.reloc.exp, &str))
4912 {
4913 if (!inst.error)
4914 inst.error = BAD_ARGS;
4915
4916 return;
4917 }
4918
4919 end_of_line (str);
4920 /* Frag hacking will turn this into a sub instruction if the offset turns
4921 out to be negative. */
4922 inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
4923 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
4924 inst.reloc.pc_rel = 1;
4925 inst.size = INSN_SIZE * 2;
4926
4927 return;
4928 }
4929
4930 static void
4931 do_cmp (str)
4932 char * str;
4933 {
4934 skip_whitespace (str);
4935
4936 if (reg_required_here (&str, 16) == FAIL)
4937 {
4938 if (!inst.error)
4939 inst.error = BAD_ARGS;
4940 return;
4941 }
4942
4943 if (skip_past_comma (&str) == FAIL
4944 || data_op2 (&str) == FAIL)
4945 {
4946 if (!inst.error)
4947 inst.error = BAD_ARGS;
4948 return;
4949 }
4950
4951 end_of_line (str);
4952 return;
4953 }
4954
4955 static void
4956 do_mov (str)
4957 char * str;
4958 {
4959 skip_whitespace (str);
4960
4961 if (reg_required_here (&str, 12) == FAIL)
4962 {
4963 if (!inst.error)
4964 inst.error = BAD_ARGS;
4965 return;
4966 }
4967
4968 if (skip_past_comma (&str) == FAIL
4969 || data_op2 (&str) == FAIL)
4970 {
4971 if (!inst.error)
4972 inst.error = BAD_ARGS;
4973 return;
4974 }
4975
4976 end_of_line (str);
4977 return;
4978 }
4979
4980 static int
4981 ldst_extend (str)
4982 char ** str;
4983 {
4984 int add = INDEX_UP;
4985
4986 switch (**str)
4987 {
4988 case '#':
4989 case '$':
4990 (*str)++;
4991 if (my_get_expression (& inst.reloc.exp, str))
4992 return FAIL;
4993
4994 if (inst.reloc.exp.X_op == O_constant)
4995 {
4996 int value = inst.reloc.exp.X_add_number;
4997
4998 if (value < -4095 || value > 4095)
4999 {
5000 inst.error = _("address offset too large");
5001 return FAIL;
5002 }
5003
5004 if (value < 0)
5005 {
5006 value = -value;
5007 add = 0;
5008 }
5009
5010 inst.instruction |= add | value;
5011 }
5012 else
5013 {
5014 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
5015 inst.reloc.pc_rel = 0;
5016 }
5017 return SUCCESS;
5018
5019 case '-':
5020 add = 0;
5021 /* Fall through. */
5022
5023 case '+':
5024 (*str)++;
5025 /* Fall through. */
5026
5027 default:
5028 if (reg_required_here (str, 0) == FAIL)
5029 return FAIL;
5030
5031 inst.instruction |= add | OFFSET_REG;
5032 if (skip_past_comma (str) == SUCCESS)
5033 return decode_shift (str, SHIFT_RESTRICT);
5034
5035 return SUCCESS;
5036 }
5037 }
5038
5039 static void
5040 do_ldst (str)
5041 char * str;
5042 {
5043 int pre_inc = 0;
5044 int conflict_reg;
5045 int value;
5046
5047 skip_whitespace (str);
5048
5049 if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
5050 {
5051 if (!inst.error)
5052 inst.error = BAD_ARGS;
5053 return;
5054 }
5055
5056 if (skip_past_comma (&str) == FAIL)
5057 {
5058 inst.error = _("address expected");
5059 return;
5060 }
5061
5062 if (*str == '[')
5063 {
5064 int reg;
5065
5066 str++;
5067
5068 skip_whitespace (str);
5069
5070 if ((reg = reg_required_here (&str, 16)) == FAIL)
5071 return;
5072
5073 /* Conflicts can occur on stores as well as loads. */
5074 conflict_reg = (conflict_reg == reg);
5075
5076 skip_whitespace (str);
5077
5078 if (*str == ']')
5079 {
5080 str ++;
5081
5082 if (skip_past_comma (&str) == SUCCESS)
5083 {
5084 /* [Rn],... (post inc) */
5085 if (ldst_extend (&str) == FAIL)
5086 return;
5087 if (conflict_reg)
5088 as_warn (_("%s register same as write-back base"),
5089 ((inst.instruction & LOAD_BIT)
5090 ? _("destination") : _("source")));
5091 }
5092 else
5093 {
5094 /* [Rn] */
5095 skip_whitespace (str);
5096
5097 if (*str == '!')
5098 {
5099 if (conflict_reg)
5100 as_warn (_("%s register same as write-back base"),
5101 ((inst.instruction & LOAD_BIT)
5102 ? _("destination") : _("source")));
5103 str++;
5104 inst.instruction |= WRITE_BACK;
5105 }
5106
5107 inst.instruction |= INDEX_UP;
5108 pre_inc = 1;
5109 }
5110 }
5111 else
5112 {
5113 /* [Rn,...] */
5114 if (skip_past_comma (&str) == FAIL)
5115 {
5116 inst.error = _("pre-indexed expression expected");
5117 return;
5118 }
5119
5120 pre_inc = 1;
5121 if (ldst_extend (&str) == FAIL)
5122 return;
5123
5124 skip_whitespace (str);
5125
5126 if (*str++ != ']')
5127 {
5128 inst.error = _("missing ]");
5129 return;
5130 }
5131
5132 skip_whitespace (str);
5133
5134 if (*str == '!')
5135 {
5136 if (conflict_reg)
5137 as_warn (_("%s register same as write-back base"),
5138 ((inst.instruction & LOAD_BIT)
5139 ? _("destination") : _("source")));
5140 str++;
5141 inst.instruction |= WRITE_BACK;
5142 }
5143 }
5144 }
5145 else if (*str == '=')
5146 {
5147 if ((inst.instruction & LOAD_BIT) == 0)
5148 {
5149 inst.error = _("invalid pseudo operation");
5150 return;
5151 }
5152
5153 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
5154 str++;
5155
5156 skip_whitespace (str);
5157
5158 if (my_get_expression (&inst.reloc.exp, &str))
5159 return;
5160
5161 if (inst.reloc.exp.X_op != O_constant
5162 && inst.reloc.exp.X_op != O_symbol)
5163 {
5164 inst.error = _("constant expression expected");
5165 return;
5166 }
5167
5168 if (inst.reloc.exp.X_op == O_constant)
5169 {
5170 value = validate_immediate (inst.reloc.exp.X_add_number);
5171
5172 if (value != FAIL)
5173 {
5174 /* This can be done with a mov instruction. */
5175 inst.instruction &= LITERAL_MASK;
5176 inst.instruction |= (INST_IMMEDIATE
5177 | (OPCODE_MOV << DATA_OP_SHIFT));
5178 inst.instruction |= value & 0xfff;
5179 end_of_line (str);
5180 return;
5181 }
5182
5183 value = validate_immediate (~inst.reloc.exp.X_add_number);
5184
5185 if (value != FAIL)
5186 {
5187 /* This can be done with a mvn instruction. */
5188 inst.instruction &= LITERAL_MASK;
5189 inst.instruction |= (INST_IMMEDIATE
5190 | (OPCODE_MVN << DATA_OP_SHIFT));
5191 inst.instruction |= value & 0xfff;
5192 end_of_line (str);
5193 return;
5194 }
5195 }
5196
5197 /* Insert into literal pool. */
5198 if (add_to_lit_pool () == FAIL)
5199 {
5200 if (!inst.error)
5201 inst.error = _("literal pool insertion failed");
5202 return;
5203 }
5204
5205 /* Change the instruction exp to point to the pool. */
5206 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
5207 inst.reloc.pc_rel = 1;
5208 inst.instruction |= (REG_PC << 16);
5209 pre_inc = 1;
5210 }
5211 else
5212 {
5213 if (my_get_expression (&inst.reloc.exp, &str))
5214 return;
5215
5216 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
5217 #ifndef TE_WINCE
5218 /* PC rel adjust. */
5219 inst.reloc.exp.X_add_number -= 8;
5220 #endif
5221 inst.reloc.pc_rel = 1;
5222 inst.instruction |= (REG_PC << 16);
5223 pre_inc = 1;
5224 }
5225
5226 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
5227 end_of_line (str);
5228 return;
5229 }
5230
5231 static void
5232 do_ldstt (str)
5233 char * str;
5234 {
5235 int conflict_reg;
5236
5237 skip_whitespace (str);
5238
5239 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
5240 {
5241 if (!inst.error)
5242 inst.error = BAD_ARGS;
5243 return;
5244 }
5245
5246 if (skip_past_comma (& str) == FAIL)
5247 {
5248 inst.error = _("address expected");
5249 return;
5250 }
5251
5252 if (*str == '[')
5253 {
5254 int reg;
5255
5256 str++;
5257
5258 skip_whitespace (str);
5259
5260 if ((reg = reg_required_here (&str, 16)) == FAIL)
5261 return;
5262
5263 /* ldrt/strt always use post-indexed addressing, so if the base is
5264 the same as Rd, we warn. */
5265 if (conflict_reg == reg)
5266 as_warn (_("%s register same as write-back base"),
5267 ((inst.instruction & LOAD_BIT)
5268 ? _("destination") : _("source")));
5269
5270 skip_whitespace (str);
5271
5272 if (*str == ']')
5273 {
5274 str ++;
5275
5276 if (skip_past_comma (&str) == SUCCESS)
5277 {
5278 /* [Rn],... (post inc) */
5279 if (ldst_extend (&str) == FAIL)
5280 return;
5281 }
5282 else
5283 {
5284 /* [Rn] */
5285 skip_whitespace (str);
5286
5287 /* Skip a write-back '!'. */
5288 if (*str == '!')
5289 str++;
5290
5291 inst.instruction |= INDEX_UP;
5292 }
5293 }
5294 else
5295 {
5296 inst.error = _("post-indexed expression expected");
5297 return;
5298 }
5299 }
5300 else
5301 {
5302 inst.error = _("post-indexed expression expected");
5303 return;
5304 }
5305
5306 end_of_line (str);
5307 return;
5308 }
5309
5310 static int
5311 ldst_extend_v4 (str)
5312 char ** str;
5313 {
5314 int add = INDEX_UP;
5315
5316 switch (**str)
5317 {
5318 case '#':
5319 case '$':
5320 (*str)++;
5321 if (my_get_expression (& inst.reloc.exp, str))
5322 return FAIL;
5323
5324 if (inst.reloc.exp.X_op == O_constant)
5325 {
5326 int value = inst.reloc.exp.X_add_number;
5327
5328 if (value < -255 || value > 255)
5329 {
5330 inst.error = _("address offset too large");
5331 return FAIL;
5332 }
5333
5334 if (value < 0)
5335 {
5336 value = -value;
5337 add = 0;
5338 }
5339
5340 /* Halfword and signextension instructions have the
5341 immediate value split across bits 11..8 and bits 3..0. */
5342 inst.instruction |= (add | HWOFFSET_IMM
5343 | ((value >> 4) << 8) | (value & 0xF));
5344 }
5345 else
5346 {
5347 inst.instruction |= HWOFFSET_IMM;
5348 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
5349 inst.reloc.pc_rel = 0;
5350 }
5351 return SUCCESS;
5352
5353 case '-':
5354 add = 0;
5355 /* Fall through. */
5356
5357 case '+':
5358 (*str)++;
5359 /* Fall through. */
5360
5361 default:
5362 if (reg_required_here (str, 0) == FAIL)
5363 return FAIL;
5364
5365 inst.instruction |= add;
5366 return SUCCESS;
5367 }
5368 }
5369
5370 /* Halfword and signed-byte load/store operations. */
5371 static void
5372 do_ldstv4 (str)
5373 char * str;
5374 {
5375 int pre_inc = 0;
5376 int conflict_reg;
5377 int value;
5378
5379 skip_whitespace (str);
5380
5381 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
5382 {
5383 if (!inst.error)
5384 inst.error = BAD_ARGS;
5385 return;
5386 }
5387
5388 if (skip_past_comma (& str) == FAIL)
5389 {
5390 inst.error = _("address expected");
5391 return;
5392 }
5393
5394 if (*str == '[')
5395 {
5396 int reg;
5397
5398 str++;
5399
5400 skip_whitespace (str);
5401
5402 if ((reg = reg_required_here (&str, 16)) == FAIL)
5403 return;
5404
5405 /* Conflicts can occur on stores as well as loads. */
5406 conflict_reg = (conflict_reg == reg);
5407
5408 skip_whitespace (str);
5409
5410 if (*str == ']')
5411 {
5412 str ++;
5413
5414 if (skip_past_comma (&str) == SUCCESS)
5415 {
5416 /* [Rn],... (post inc) */
5417 if (ldst_extend_v4 (&str) == FAIL)
5418 return;
5419 if (conflict_reg)
5420 as_warn (_("%s register same as write-back base"),
5421 ((inst.instruction & LOAD_BIT)
5422 ? _("destination") : _("source")));
5423 }
5424 else
5425 {
5426 /* [Rn] */
5427 inst.instruction |= HWOFFSET_IMM;
5428
5429 skip_whitespace (str);
5430
5431 if (*str == '!')
5432 {
5433 if (conflict_reg)
5434 as_warn (_("%s register same as write-back base"),
5435 ((inst.instruction & LOAD_BIT)
5436 ? _("destination") : _("source")));
5437 str++;
5438 inst.instruction |= WRITE_BACK;
5439 }
5440
5441 inst.instruction |= INDEX_UP;
5442 pre_inc = 1;
5443 }
5444 }
5445 else
5446 {
5447 /* [Rn,...] */
5448 if (skip_past_comma (&str) == FAIL)
5449 {
5450 inst.error = _("pre-indexed expression expected");
5451 return;
5452 }
5453
5454 pre_inc = 1;
5455 if (ldst_extend_v4 (&str) == FAIL)
5456 return;
5457
5458 skip_whitespace (str);
5459
5460 if (*str++ != ']')
5461 {
5462 inst.error = _("missing ]");
5463 return;
5464 }
5465
5466 skip_whitespace (str);
5467
5468 if (*str == '!')
5469 {
5470 if (conflict_reg)
5471 as_warn (_("%s register same as write-back base"),
5472 ((inst.instruction & LOAD_BIT)
5473 ? _("destination") : _("source")));
5474 str++;
5475 inst.instruction |= WRITE_BACK;
5476 }
5477 }
5478 }
5479 else if (*str == '=')
5480 {
5481 if ((inst.instruction & LOAD_BIT) == 0)
5482 {
5483 inst.error = _("invalid pseudo operation");
5484 return;
5485 }
5486
5487 /* XXX Does this work correctly for half-word/byte ops? */
5488 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
5489 str++;
5490
5491 skip_whitespace (str);
5492
5493 if (my_get_expression (&inst.reloc.exp, &str))
5494 return;
5495
5496 if (inst.reloc.exp.X_op != O_constant
5497 && inst.reloc.exp.X_op != O_symbol)
5498 {
5499 inst.error = _("constant expression expected");
5500 return;
5501 }
5502
5503 if (inst.reloc.exp.X_op == O_constant)
5504 {
5505 value = validate_immediate (inst.reloc.exp.X_add_number);
5506
5507 if (value != FAIL)
5508 {
5509 /* This can be done with a mov instruction. */
5510 inst.instruction &= LITERAL_MASK;
5511 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
5512 inst.instruction |= value & 0xfff;
5513 end_of_line (str);
5514 return;
5515 }
5516
5517 value = validate_immediate (~ inst.reloc.exp.X_add_number);
5518
5519 if (value != FAIL)
5520 {
5521 /* This can be done with a mvn instruction. */
5522 inst.instruction &= LITERAL_MASK;
5523 inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
5524 inst.instruction |= value & 0xfff;
5525 end_of_line (str);
5526 return;
5527 }
5528 }
5529
5530 /* Insert into literal pool. */
5531 if (add_to_lit_pool () == FAIL)
5532 {
5533 if (!inst.error)
5534 inst.error = _("literal pool insertion failed");
5535 return;
5536 }
5537
5538 /* Change the instruction exp to point to the pool. */
5539 inst.instruction |= HWOFFSET_IMM;
5540 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
5541 inst.reloc.pc_rel = 1;
5542 inst.instruction |= (REG_PC << 16);
5543 pre_inc = 1;
5544 }
5545 else
5546 {
5547 if (my_get_expression (&inst.reloc.exp, &str))
5548 return;
5549
5550 inst.instruction |= HWOFFSET_IMM;
5551 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
5552 #ifndef TE_WINCE
5553 /* PC rel adjust. */
5554 inst.reloc.exp.X_add_number -= 8;
5555 #endif
5556 inst.reloc.pc_rel = 1;
5557 inst.instruction |= (REG_PC << 16);
5558 pre_inc = 1;
5559 }
5560
5561 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
5562 end_of_line (str);
5563 return;
5564 }
5565
5566 static long
5567 reg_list (strp)
5568 char ** strp;
5569 {
5570 char * str = * strp;
5571 long range = 0;
5572 int another_range;
5573
5574 /* We come back here if we get ranges concatenated by '+' or '|'. */
5575 do
5576 {
5577 another_range = 0;
5578
5579 if (*str == '{')
5580 {
5581 int in_range = 0;
5582 int cur_reg = -1;
5583
5584 str++;
5585 do
5586 {
5587 int reg;
5588
5589 skip_whitespace (str);
5590
5591 if ((reg = reg_required_here (& str, -1)) == FAIL)
5592 return FAIL;
5593
5594 if (in_range)
5595 {
5596 int i;
5597
5598 if (reg <= cur_reg)
5599 {
5600 inst.error = _("bad range in register list");
5601 return FAIL;
5602 }
5603
5604 for (i = cur_reg + 1; i < reg; i++)
5605 {
5606 if (range & (1 << i))
5607 as_tsktsk
5608 (_("Warning: duplicated register (r%d) in register list"),
5609 i);
5610 else
5611 range |= 1 << i;
5612 }
5613 in_range = 0;
5614 }
5615
5616 if (range & (1 << reg))
5617 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
5618 reg);
5619 else if (reg <= cur_reg)
5620 as_tsktsk (_("Warning: register range not in ascending order"));
5621
5622 range |= 1 << reg;
5623 cur_reg = reg;
5624 }
5625 while (skip_past_comma (&str) != FAIL
5626 || (in_range = 1, *str++ == '-'));
5627 str--;
5628 skip_whitespace (str);
5629
5630 if (*str++ != '}')
5631 {
5632 inst.error = _("missing `}'");
5633 return FAIL;
5634 }
5635 }
5636 else
5637 {
5638 expressionS expr;
5639
5640 if (my_get_expression (&expr, &str))
5641 return FAIL;
5642
5643 if (expr.X_op == O_constant)
5644 {
5645 if (expr.X_add_number
5646 != (expr.X_add_number & 0x0000ffff))
5647 {
5648 inst.error = _("invalid register mask");
5649 return FAIL;
5650 }
5651
5652 if ((range & expr.X_add_number) != 0)
5653 {
5654 int regno = range & expr.X_add_number;
5655
5656 regno &= -regno;
5657 regno = (1 << regno) - 1;
5658 as_tsktsk
5659 (_("Warning: duplicated register (r%d) in register list"),
5660 regno);
5661 }
5662
5663 range |= expr.X_add_number;
5664 }
5665 else
5666 {
5667 if (inst.reloc.type != 0)
5668 {
5669 inst.error = _("expression too complex");
5670 return FAIL;
5671 }
5672
5673 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
5674 inst.reloc.type = BFD_RELOC_ARM_MULTI;
5675 inst.reloc.pc_rel = 0;
5676 }
5677 }
5678
5679 skip_whitespace (str);
5680
5681 if (*str == '|' || *str == '+')
5682 {
5683 str++;
5684 another_range = 1;
5685 }
5686 }
5687 while (another_range);
5688
5689 *strp = str;
5690 return range;
5691 }
5692
5693 static void
5694 do_ldmstm (str)
5695 char * str;
5696 {
5697 int base_reg;
5698 long range;
5699
5700 skip_whitespace (str);
5701
5702 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
5703 return;
5704
5705 if (base_reg == REG_PC)
5706 {
5707 inst.error = _("r15 not allowed as base register");
5708 return;
5709 }
5710
5711 skip_whitespace (str);
5712
5713 if (*str == '!')
5714 {
5715 inst.instruction |= WRITE_BACK;
5716 str++;
5717 }
5718
5719 if (skip_past_comma (&str) == FAIL
5720 || (range = reg_list (&str)) == FAIL)
5721 {
5722 if (! inst.error)
5723 inst.error = BAD_ARGS;
5724 return;
5725 }
5726
5727 if (*str == '^')
5728 {
5729 str++;
5730 inst.instruction |= LDM_TYPE_2_OR_3;
5731 }
5732
5733 inst.instruction |= range;
5734 end_of_line (str);
5735 return;
5736 }
5737
5738 static void
5739 do_swi (str)
5740 char * str;
5741 {
5742 skip_whitespace (str);
5743
5744 /* Allow optional leading '#'. */
5745 if (is_immediate_prefix (*str))
5746 str++;
5747
5748 if (my_get_expression (& inst.reloc.exp, & str))
5749 return;
5750
5751 inst.reloc.type = BFD_RELOC_ARM_SWI;
5752 inst.reloc.pc_rel = 0;
5753 end_of_line (str);
5754
5755 return;
5756 }
5757
5758 static void
5759 do_swap (str)
5760 char * str;
5761 {
5762 int reg;
5763
5764 skip_whitespace (str);
5765
5766 if ((reg = reg_required_here (&str, 12)) == FAIL)
5767 return;
5768
5769 if (reg == REG_PC)
5770 {
5771 inst.error = _("r15 not allowed in swap");
5772 return;
5773 }
5774
5775 if (skip_past_comma (&str) == FAIL
5776 || (reg = reg_required_here (&str, 0)) == FAIL)
5777 {
5778 if (!inst.error)
5779 inst.error = BAD_ARGS;
5780 return;
5781 }
5782
5783 if (reg == REG_PC)
5784 {
5785 inst.error = _("r15 not allowed in swap");
5786 return;
5787 }
5788
5789 if (skip_past_comma (&str) == FAIL
5790 || *str++ != '[')
5791 {
5792 inst.error = BAD_ARGS;
5793 return;
5794 }
5795
5796 skip_whitespace (str);
5797
5798 if ((reg = reg_required_here (&str, 16)) == FAIL)
5799 return;
5800
5801 if (reg == REG_PC)
5802 {
5803 inst.error = BAD_PC;
5804 return;
5805 }
5806
5807 skip_whitespace (str);
5808
5809 if (*str++ != ']')
5810 {
5811 inst.error = _("missing ]");
5812 return;
5813 }
5814
5815 end_of_line (str);
5816 return;
5817 }
5818
5819 static void
5820 do_branch (str)
5821 char * str;
5822 {
5823 if (my_get_expression (&inst.reloc.exp, &str))
5824 return;
5825
5826 #ifdef OBJ_ELF
5827 {
5828 char * save_in;
5829
5830 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
5831 required for the instruction. */
5832
5833 /* arm_parse_reloc () works on input_line_pointer.
5834 We actually want to parse the operands to the branch instruction
5835 passed in 'str'. Save the input pointer and restore it later. */
5836 save_in = input_line_pointer;
5837 input_line_pointer = str;
5838 if (inst.reloc.exp.X_op == O_symbol
5839 && *str == '('
5840 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
5841 {
5842 inst.reloc.type = BFD_RELOC_ARM_PLT32;
5843 inst.reloc.pc_rel = 0;
5844 /* Modify str to point to after parsed operands, otherwise
5845 end_of_line() will complain about the (PLT) left in str. */
5846 str = input_line_pointer;
5847 }
5848 else
5849 {
5850 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
5851 inst.reloc.pc_rel = 1;
5852 }
5853 input_line_pointer = save_in;
5854 }
5855 #else
5856 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
5857 inst.reloc.pc_rel = 1;
5858 #endif /* OBJ_ELF */
5859
5860 end_of_line (str);
5861 return;
5862 }
5863
5864 static void
5865 do_bx (str)
5866 char * str;
5867 {
5868 int reg;
5869
5870 skip_whitespace (str);
5871
5872 if ((reg = reg_required_here (&str, 0)) == FAIL)
5873 {
5874 inst.error = BAD_ARGS;
5875 return;
5876 }
5877
5878 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
5879 if (reg == REG_PC)
5880 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
5881
5882 end_of_line (str);
5883 }
5884
5885 static void
5886 do_cdp (str)
5887 char * str;
5888 {
5889 /* Co-processor data operation.
5890 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
5891 skip_whitespace (str);
5892
5893 if (co_proc_number (&str) == FAIL)
5894 {
5895 if (!inst.error)
5896 inst.error = BAD_ARGS;
5897 return;
5898 }
5899
5900 if (skip_past_comma (&str) == FAIL
5901 || cp_opc_expr (&str, 20,4) == FAIL)
5902 {
5903 if (!inst.error)
5904 inst.error = BAD_ARGS;
5905 return;
5906 }
5907
5908 if (skip_past_comma (&str) == FAIL
5909 || cp_reg_required_here (&str, 12) == FAIL)
5910 {
5911 if (!inst.error)
5912 inst.error = BAD_ARGS;
5913 return;
5914 }
5915
5916 if (skip_past_comma (&str) == FAIL
5917 || cp_reg_required_here (&str, 16) == FAIL)
5918 {
5919 if (!inst.error)
5920 inst.error = BAD_ARGS;
5921 return;
5922 }
5923
5924 if (skip_past_comma (&str) == FAIL
5925 || cp_reg_required_here (&str, 0) == FAIL)
5926 {
5927 if (!inst.error)
5928 inst.error = BAD_ARGS;
5929 return;
5930 }
5931
5932 if (skip_past_comma (&str) == SUCCESS)
5933 {
5934 if (cp_opc_expr (&str, 5, 3) == FAIL)
5935 {
5936 if (!inst.error)
5937 inst.error = BAD_ARGS;
5938 return;
5939 }
5940 }
5941
5942 end_of_line (str);
5943 return;
5944 }
5945
5946 static void
5947 do_lstc (str)
5948 char * str;
5949 {
5950 /* Co-processor register load/store.
5951 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
5952
5953 skip_whitespace (str);
5954
5955 if (co_proc_number (&str) == FAIL)
5956 {
5957 if (!inst.error)
5958 inst.error = BAD_ARGS;
5959 return;
5960 }
5961
5962 if (skip_past_comma (&str) == FAIL
5963 || cp_reg_required_here (&str, 12) == FAIL)
5964 {
5965 if (!inst.error)
5966 inst.error = BAD_ARGS;
5967 return;
5968 }
5969
5970 if (skip_past_comma (&str) == FAIL
5971 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
5972 {
5973 if (! inst.error)
5974 inst.error = BAD_ARGS;
5975 return;
5976 }
5977
5978 end_of_line (str);
5979 return;
5980 }
5981
5982 static void
5983 do_co_reg (str)
5984 char * str;
5985 {
5986 /* Co-processor register transfer.
5987 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
5988
5989 skip_whitespace (str);
5990
5991 if (co_proc_number (&str) == FAIL)
5992 {
5993 if (!inst.error)
5994 inst.error = BAD_ARGS;
5995 return;
5996 }
5997
5998 if (skip_past_comma (&str) == FAIL
5999 || cp_opc_expr (&str, 21, 3) == FAIL)
6000 {
6001 if (!inst.error)
6002 inst.error = BAD_ARGS;
6003 return;
6004 }
6005
6006 if (skip_past_comma (&str) == FAIL
6007 || reg_required_here (&str, 12) == FAIL)
6008 {
6009 if (!inst.error)
6010 inst.error = BAD_ARGS;
6011 return;
6012 }
6013
6014 if (skip_past_comma (&str) == FAIL
6015 || cp_reg_required_here (&str, 16) == FAIL)
6016 {
6017 if (!inst.error)
6018 inst.error = BAD_ARGS;
6019 return;
6020 }
6021
6022 if (skip_past_comma (&str) == FAIL
6023 || cp_reg_required_here (&str, 0) == FAIL)
6024 {
6025 if (!inst.error)
6026 inst.error = BAD_ARGS;
6027 return;
6028 }
6029
6030 if (skip_past_comma (&str) == SUCCESS)
6031 {
6032 if (cp_opc_expr (&str, 5, 3) == FAIL)
6033 {
6034 if (!inst.error)
6035 inst.error = BAD_ARGS;
6036 return;
6037 }
6038 }
6039
6040 end_of_line (str);
6041 return;
6042 }
6043
6044 static void
6045 do_fpa_ctrl (str)
6046 char * str;
6047 {
6048 /* FP control registers.
6049 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
6050
6051 skip_whitespace (str);
6052
6053 if (reg_required_here (&str, 12) == FAIL)
6054 {
6055 if (!inst.error)
6056 inst.error = BAD_ARGS;
6057 return;
6058 }
6059
6060 end_of_line (str);
6061 return;
6062 }
6063
6064 static void
6065 do_fpa_ldst (str)
6066 char * str;
6067 {
6068 skip_whitespace (str);
6069
6070 if (fp_reg_required_here (&str, 12) == FAIL)
6071 {
6072 if (!inst.error)
6073 inst.error = BAD_ARGS;
6074 return;
6075 }
6076
6077 if (skip_past_comma (&str) == FAIL
6078 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
6079 {
6080 if (!inst.error)
6081 inst.error = BAD_ARGS;
6082 return;
6083 }
6084
6085 end_of_line (str);
6086 }
6087
6088 static void
6089 do_fpa_ldmstm (str)
6090 char * str;
6091 {
6092 int num_regs;
6093
6094 skip_whitespace (str);
6095
6096 if (fp_reg_required_here (&str, 12) == FAIL)
6097 {
6098 if (! inst.error)
6099 inst.error = BAD_ARGS;
6100 return;
6101 }
6102
6103 /* Get Number of registers to transfer. */
6104 if (skip_past_comma (&str) == FAIL
6105 || my_get_expression (&inst.reloc.exp, &str))
6106 {
6107 if (! inst.error)
6108 inst.error = _("constant expression expected");
6109 return;
6110 }
6111
6112 if (inst.reloc.exp.X_op != O_constant)
6113 {
6114 inst.error = _("constant value required for number of registers");
6115 return;
6116 }
6117
6118 num_regs = inst.reloc.exp.X_add_number;
6119
6120 if (num_regs < 1 || num_regs > 4)
6121 {
6122 inst.error = _("number of registers must be in the range [1:4]");
6123 return;
6124 }
6125
6126 switch (num_regs)
6127 {
6128 case 1:
6129 inst.instruction |= CP_T_X;
6130 break;
6131 case 2:
6132 inst.instruction |= CP_T_Y;
6133 break;
6134 case 3:
6135 inst.instruction |= CP_T_Y | CP_T_X;
6136 break;
6137 case 4:
6138 break;
6139 default:
6140 abort ();
6141 }
6142
6143 if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format. */
6144 {
6145 int reg;
6146 int write_back;
6147 int offset;
6148
6149 /* The instruction specified "ea" or "fd", so we can only accept
6150 [Rn]{!}. The instruction does not really support stacking or
6151 unstacking, so we have to emulate these by setting appropriate
6152 bits and offsets. */
6153 if (skip_past_comma (&str) == FAIL
6154 || *str != '[')
6155 {
6156 if (! inst.error)
6157 inst.error = BAD_ARGS;
6158 return;
6159 }
6160
6161 str++;
6162 skip_whitespace (str);
6163
6164 if ((reg = reg_required_here (&str, 16)) == FAIL)
6165 return;
6166
6167 skip_whitespace (str);
6168
6169 if (*str != ']')
6170 {
6171 inst.error = BAD_ARGS;
6172 return;
6173 }
6174
6175 str++;
6176 if (*str == '!')
6177 {
6178 write_back = 1;
6179 str++;
6180 if (reg == REG_PC)
6181 {
6182 inst.error =
6183 _("r15 not allowed as base register with write-back");
6184 return;
6185 }
6186 }
6187 else
6188 write_back = 0;
6189
6190 if (inst.instruction & CP_T_Pre)
6191 {
6192 /* Pre-decrement. */
6193 offset = 3 * num_regs;
6194 if (write_back)
6195 inst.instruction |= CP_T_WB;
6196 }
6197 else
6198 {
6199 /* Post-increment. */
6200 if (write_back)
6201 {
6202 inst.instruction |= CP_T_WB;
6203 offset = 3 * num_regs;
6204 }
6205 else
6206 {
6207 /* No write-back, so convert this into a standard pre-increment
6208 instruction -- aesthetically more pleasing. */
6209 inst.instruction |= CP_T_Pre | CP_T_UD;
6210 offset = 0;
6211 }
6212 }
6213
6214 inst.instruction |= offset;
6215 }
6216 else if (skip_past_comma (&str) == FAIL
6217 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
6218 {
6219 if (! inst.error)
6220 inst.error = BAD_ARGS;
6221 return;
6222 }
6223
6224 end_of_line (str);
6225 }
6226
6227 static void
6228 do_fpa_dyadic (str)
6229 char * str;
6230 {
6231 skip_whitespace (str);
6232
6233 if (fp_reg_required_here (&str, 12) == FAIL)
6234 {
6235 if (! inst.error)
6236 inst.error = BAD_ARGS;
6237 return;
6238 }
6239
6240 if (skip_past_comma (&str) == FAIL
6241 || fp_reg_required_here (&str, 16) == FAIL)
6242 {
6243 if (! inst.error)
6244 inst.error = BAD_ARGS;
6245 return;
6246 }
6247
6248 if (skip_past_comma (&str) == FAIL
6249 || fp_op2 (&str) == FAIL)
6250 {
6251 if (! inst.error)
6252 inst.error = BAD_ARGS;
6253 return;
6254 }
6255
6256 end_of_line (str);
6257 return;
6258 }
6259
6260 static void
6261 do_fpa_monadic (str)
6262 char * str;
6263 {
6264 skip_whitespace (str);
6265
6266 if (fp_reg_required_here (&str, 12) == FAIL)
6267 {
6268 if (! inst.error)
6269 inst.error = BAD_ARGS;
6270 return;
6271 }
6272
6273 if (skip_past_comma (&str) == FAIL
6274 || fp_op2 (&str) == FAIL)
6275 {
6276 if (! inst.error)
6277 inst.error = BAD_ARGS;
6278 return;
6279 }
6280
6281 end_of_line (str);
6282 return;
6283 }
6284
6285 static void
6286 do_fpa_cmp (str)
6287 char * str;
6288 {
6289 skip_whitespace (str);
6290
6291 if (fp_reg_required_here (&str, 16) == FAIL)
6292 {
6293 if (! inst.error)
6294 inst.error = BAD_ARGS;
6295 return;
6296 }
6297
6298 if (skip_past_comma (&str) == FAIL
6299 || fp_op2 (&str) == FAIL)
6300 {
6301 if (! inst.error)
6302 inst.error = BAD_ARGS;
6303 return;
6304 }
6305
6306 end_of_line (str);
6307 return;
6308 }
6309
6310 static void
6311 do_fpa_from_reg (str)
6312 char * str;
6313 {
6314 skip_whitespace (str);
6315
6316 if (fp_reg_required_here (&str, 16) == FAIL)
6317 {
6318 if (! inst.error)
6319 inst.error = BAD_ARGS;
6320 return;
6321 }
6322
6323 if (skip_past_comma (&str) == FAIL
6324 || reg_required_here (&str, 12) == FAIL)
6325 {
6326 if (! inst.error)
6327 inst.error = BAD_ARGS;
6328 return;
6329 }
6330
6331 end_of_line (str);
6332 return;
6333 }
6334
6335 static void
6336 do_fpa_to_reg (str)
6337 char * str;
6338 {
6339 skip_whitespace (str);
6340
6341 if (reg_required_here (&str, 12) == FAIL)
6342 return;
6343
6344 if (skip_past_comma (&str) == FAIL
6345 || fp_reg_required_here (&str, 0) == FAIL)
6346 {
6347 if (! inst.error)
6348 inst.error = BAD_ARGS;
6349 return;
6350 }
6351
6352 end_of_line (str);
6353 return;
6354 }
6355
6356 static int
6357 vfp_sp_reg_required_here (str, pos)
6358 char **str;
6359 enum vfp_sp_reg_pos pos;
6360 {
6361 int reg;
6362 char *start = *str;
6363
6364 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
6365 {
6366 switch (pos)
6367 {
6368 case VFP_REG_Sd:
6369 inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
6370 break;
6371
6372 case VFP_REG_Sn:
6373 inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
6374 break;
6375
6376 case VFP_REG_Sm:
6377 inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
6378 break;
6379
6380 default:
6381 abort ();
6382 }
6383 return reg;
6384 }
6385
6386 /* In the few cases where we might be able to accept something else
6387 this error can be overridden. */
6388 inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
6389
6390 /* Restore the start point. */
6391 *str = start;
6392 return FAIL;
6393 }
6394
6395 static int
6396 vfp_dp_reg_required_here (str, pos)
6397 char **str;
6398 enum vfp_sp_reg_pos pos;
6399 {
6400 int reg;
6401 char *start = *str;
6402
6403 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
6404 {
6405 switch (pos)
6406 {
6407 case VFP_REG_Dd:
6408 inst.instruction |= reg << 12;
6409 break;
6410
6411 case VFP_REG_Dn:
6412 inst.instruction |= reg << 16;
6413 break;
6414
6415 case VFP_REG_Dm:
6416 inst.instruction |= reg << 0;
6417 break;
6418
6419 default:
6420 abort ();
6421 }
6422 return reg;
6423 }
6424
6425 /* In the few cases where we might be able to accept something else
6426 this error can be overridden. */
6427 inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
6428
6429 /* Restore the start point. */
6430 *str = start;
6431 return FAIL;
6432 }
6433
6434 static void
6435 do_vfp_sp_monadic (str)
6436 char *str;
6437 {
6438 skip_whitespace (str);
6439
6440 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
6441 return;
6442
6443 if (skip_past_comma (&str) == FAIL
6444 || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
6445 {
6446 if (! inst.error)
6447 inst.error = BAD_ARGS;
6448 return;
6449 }
6450
6451 end_of_line (str);
6452 return;
6453 }
6454
6455 static void
6456 do_vfp_dp_monadic (str)
6457 char *str;
6458 {
6459 skip_whitespace (str);
6460
6461 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
6462 return;
6463
6464 if (skip_past_comma (&str) == FAIL
6465 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
6466 {
6467 if (! inst.error)
6468 inst.error = BAD_ARGS;
6469 return;
6470 }
6471
6472 end_of_line (str);
6473 return;
6474 }
6475
6476 static void
6477 do_vfp_sp_dyadic (str)
6478 char *str;
6479 {
6480 skip_whitespace (str);
6481
6482 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
6483 return;
6484
6485 if (skip_past_comma (&str) == FAIL
6486 || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
6487 || skip_past_comma (&str) == FAIL
6488 || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
6489 {
6490 if (! inst.error)
6491 inst.error = BAD_ARGS;
6492 return;
6493 }
6494
6495 end_of_line (str);
6496 return;
6497 }
6498
6499 static void
6500 do_vfp_dp_dyadic (str)
6501 char *str;
6502 {
6503 skip_whitespace (str);
6504
6505 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
6506 return;
6507
6508 if (skip_past_comma (&str) == FAIL
6509 || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
6510 || skip_past_comma (&str) == FAIL
6511 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
6512 {
6513 if (! inst.error)
6514 inst.error = BAD_ARGS;
6515 return;
6516 }
6517
6518 end_of_line (str);
6519 return;
6520 }
6521
6522 static void
6523 do_vfp_reg_from_sp (str)
6524 char *str;
6525 {
6526 skip_whitespace (str);
6527
6528 if (reg_required_here (&str, 12) == FAIL)
6529 return;
6530
6531 if (skip_past_comma (&str) == FAIL
6532 || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
6533 {
6534 if (! inst.error)
6535 inst.error = BAD_ARGS;
6536 return;
6537 }
6538
6539 end_of_line (str);
6540 return;
6541 }
6542
6543 static void
6544 do_vfp_sp_reg2 (str)
6545 char *str;
6546 {
6547 skip_whitespace (str);
6548
6549 if (reg_required_here (&str, 12) == FAIL)
6550 return;
6551
6552 if (skip_past_comma (&str) == FAIL
6553 || reg_required_here (&str, 16) == FAIL
6554 || skip_past_comma (&str) == FAIL)
6555 {
6556 if (! inst.error)
6557 inst.error = BAD_ARGS;
6558 return;
6559 }
6560
6561 /* We require exactly two consecutive SP registers. */
6562 if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
6563 {
6564 if (! inst.error)
6565 inst.error = _("only two consecutive VFP SP registers allowed here");
6566 }
6567
6568 end_of_line (str);
6569 return;
6570 }
6571
6572 static void
6573 do_vfp_sp_from_reg (str)
6574 char *str;
6575 {
6576 skip_whitespace (str);
6577
6578 if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
6579 return;
6580
6581 if (skip_past_comma (&str) == FAIL
6582 || reg_required_here (&str, 12) == FAIL)
6583 {
6584 if (! inst.error)
6585 inst.error = BAD_ARGS;
6586 return;
6587 }
6588
6589 end_of_line (str);
6590 return;
6591 }
6592
6593 static void
6594 do_vfp_reg_from_dp (str)
6595 char *str;
6596 {
6597 skip_whitespace (str);
6598
6599 if (reg_required_here (&str, 12) == FAIL)
6600 return;
6601
6602 if (skip_past_comma (&str) == FAIL
6603 || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
6604 {
6605 if (! inst.error)
6606 inst.error = BAD_ARGS;
6607 return;
6608 }
6609
6610 end_of_line (str);
6611 return;
6612 }
6613
6614 static void
6615 do_vfp_reg2_from_dp (str)
6616 char *str;
6617 {
6618 skip_whitespace (str);
6619
6620 if (reg_required_here (&str, 12) == FAIL)
6621 return;
6622
6623 if (skip_past_comma (&str) == FAIL
6624 || reg_required_here (&str, 16) == FAIL
6625 || skip_past_comma (&str) == FAIL
6626 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
6627 {
6628 if (! inst.error)
6629 inst.error = BAD_ARGS;
6630 return;
6631 }
6632
6633 end_of_line (str);
6634 return;
6635 }
6636
6637 static void
6638 do_vfp_dp_from_reg (str)
6639 char *str;
6640 {
6641 skip_whitespace (str);
6642
6643 if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
6644 return;
6645
6646 if (skip_past_comma (&str) == FAIL
6647 || reg_required_here (&str, 12) == FAIL)
6648 {
6649 if (! inst.error)
6650 inst.error = BAD_ARGS;
6651 return;
6652 }
6653
6654 end_of_line (str);
6655 return;
6656 }
6657
6658 static void
6659 do_vfp_dp_from_reg2 (str)
6660 char *str;
6661 {
6662 skip_whitespace (str);
6663
6664 if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
6665 return;
6666
6667 if (skip_past_comma (&str) == FAIL
6668 || reg_required_here (&str, 12) == FAIL
6669 || skip_past_comma (&str) == FAIL
6670 || reg_required_here (&str, 16))
6671 {
6672 if (! inst.error)
6673 inst.error = BAD_ARGS;
6674 return;
6675 }
6676
6677 end_of_line (str);
6678 return;
6679 }
6680
6681 static const struct vfp_reg *
6682 vfp_psr_parse (str)
6683 char **str;
6684 {
6685 char *start = *str;
6686 char c;
6687 char *p;
6688 const struct vfp_reg *vreg;
6689
6690 p = start;
6691
6692 /* Find the end of the current token. */
6693 do
6694 {
6695 c = *p++;
6696 }
6697 while (ISALPHA (c));
6698
6699 /* Mark it. */
6700 *--p = 0;
6701
6702 for (vreg = vfp_regs + 0;
6703 vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
6704 vreg++)
6705 {
6706 if (strcmp (start, vreg->name) == 0)
6707 {
6708 *p = c;
6709 *str = p;
6710 return vreg;
6711 }
6712 }
6713
6714 *p = c;
6715 return NULL;
6716 }
6717
6718 static int
6719 vfp_psr_required_here (str)
6720 char **str;
6721 {
6722 char *start = *str;
6723 const struct vfp_reg *vreg;
6724
6725 vreg = vfp_psr_parse (str);
6726
6727 if (vreg)
6728 {
6729 inst.instruction |= vreg->regno;
6730 return SUCCESS;
6731 }
6732
6733 inst.error = _("VFP system register expected");
6734
6735 *str = start;
6736 return FAIL;
6737 }
6738
6739 static void
6740 do_vfp_reg_from_ctrl (str)
6741 char *str;
6742 {
6743 skip_whitespace (str);
6744
6745 if (reg_required_here (&str, 12) == FAIL)
6746 return;
6747
6748 if (skip_past_comma (&str) == FAIL
6749 || vfp_psr_required_here (&str) == FAIL)
6750 {
6751 if (! inst.error)
6752 inst.error = BAD_ARGS;
6753 return;
6754 }
6755
6756 end_of_line (str);
6757 return;
6758 }
6759
6760 static void
6761 do_vfp_ctrl_from_reg (str)
6762 char *str;
6763 {
6764 skip_whitespace (str);
6765
6766 if (vfp_psr_required_here (&str) == FAIL)
6767 return;
6768
6769 if (skip_past_comma (&str) == FAIL
6770 || reg_required_here (&str, 12) == FAIL)
6771 {
6772 if (! inst.error)
6773 inst.error = BAD_ARGS;
6774 return;
6775 }
6776
6777 end_of_line (str);
6778 return;
6779 }
6780
6781 static void
6782 do_vfp_sp_ldst (str)
6783 char *str;
6784 {
6785 skip_whitespace (str);
6786
6787 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
6788 {
6789 if (!inst.error)
6790 inst.error = BAD_ARGS;
6791 return;
6792 }
6793
6794 if (skip_past_comma (&str) == FAIL
6795 || cp_address_required_here (&str, CP_NO_WB) == FAIL)
6796 {
6797 if (!inst.error)
6798 inst.error = BAD_ARGS;
6799 return;
6800 }
6801
6802 end_of_line (str);
6803 return;
6804 }
6805
6806 static void
6807 do_vfp_dp_ldst (str)
6808 char *str;
6809 {
6810 skip_whitespace (str);
6811
6812 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
6813 {
6814 if (!inst.error)
6815 inst.error = BAD_ARGS;
6816 return;
6817 }
6818
6819 if (skip_past_comma (&str) == FAIL
6820 || cp_address_required_here (&str, CP_NO_WB) == FAIL)
6821 {
6822 if (!inst.error)
6823 inst.error = BAD_ARGS;
6824 return;
6825 }
6826
6827 end_of_line (str);
6828 return;
6829 }
6830
6831 /* Parse and encode a VFP SP register list, storing the initial
6832 register in position POS and returning the range as the result. If
6833 the string is invalid return FAIL (an invalid range). */
6834 static long
6835 vfp_sp_reg_list (str, pos)
6836 char **str;
6837 enum vfp_sp_reg_pos pos;
6838 {
6839 long range = 0;
6840 int base_reg = 0;
6841 int new_base;
6842 long base_bits = 0;
6843 int count = 0;
6844 long tempinst;
6845 unsigned long mask = 0;
6846 int warned = 0;
6847
6848 if (**str != '{')
6849 return FAIL;
6850
6851 (*str)++;
6852 skip_whitespace (*str);
6853
6854 tempinst = inst.instruction;
6855
6856 do
6857 {
6858 inst.instruction = 0;
6859
6860 if ((new_base = vfp_sp_reg_required_here (str, pos)) == FAIL)
6861 return FAIL;
6862
6863 if (count == 0 || base_reg > new_base)
6864 {
6865 base_reg = new_base;
6866 base_bits = inst.instruction;
6867 }
6868
6869 if (mask & (1 << new_base))
6870 {
6871 inst.error = _("invalid register list");
6872 return FAIL;
6873 }
6874
6875 if ((mask >> new_base) != 0 && ! warned)
6876 {
6877 as_tsktsk (_("register list not in ascending order"));
6878 warned = 1;
6879 }
6880
6881 mask |= 1 << new_base;
6882 count++;
6883
6884 skip_whitespace (*str);
6885
6886 if (**str == '-') /* We have the start of a range expression */
6887 {
6888 int high_range;
6889
6890 (*str)++;
6891
6892 if ((high_range
6893 = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab))
6894 == FAIL)
6895 {
6896 inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
6897 return FAIL;
6898 }
6899
6900 if (high_range <= new_base)
6901 {
6902 inst.error = _("register range not in ascending order");
6903 return FAIL;
6904 }
6905
6906 for (new_base++; new_base <= high_range; new_base++)
6907 {
6908 if (mask & (1 << new_base))
6909 {
6910 inst.error = _("invalid register list");
6911 return FAIL;
6912 }
6913
6914 mask |= 1 << new_base;
6915 count++;
6916 }
6917 }
6918 }
6919 while (skip_past_comma (str) != FAIL);
6920
6921 if (**str != '}')
6922 {
6923 inst.error = _("invalid register list");
6924 return FAIL;
6925 }
6926
6927 (*str)++;
6928
6929 range = count;
6930
6931 /* Sanity check -- should have raised a parse error above. */
6932 if (count == 0 || count > 32)
6933 abort();
6934
6935 /* Final test -- the registers must be consecutive. */
6936 while (count--)
6937 {
6938 if ((mask & (1 << base_reg++)) == 0)
6939 {
6940 inst.error = _("non-contiguous register range");
6941 return FAIL;
6942 }
6943 }
6944
6945 inst.instruction = tempinst | base_bits;
6946 return range;
6947 }
6948
6949 static long
6950 vfp_dp_reg_list (str)
6951 char **str;
6952 {
6953 long range = 0;
6954 int base_reg = 0;
6955 int new_base;
6956 int count = 0;
6957 long tempinst;
6958 unsigned long mask = 0;
6959 int warned = 0;
6960
6961 if (**str != '{')
6962 return FAIL;
6963
6964 (*str)++;
6965 skip_whitespace (*str);
6966
6967 tempinst = inst.instruction;
6968
6969 do
6970 {
6971 inst.instruction = 0;
6972
6973 if ((new_base = vfp_dp_reg_required_here (str, VFP_REG_Dd)) == FAIL)
6974 return FAIL;
6975
6976 if (count == 0 || base_reg > new_base)
6977 {
6978 base_reg = new_base;
6979 range = inst.instruction;
6980 }
6981
6982 if (mask & (1 << new_base))
6983 {
6984 inst.error = _("invalid register list");
6985 return FAIL;
6986 }
6987
6988 if ((mask >> new_base) != 0 && ! warned)
6989 {
6990 as_tsktsk (_("register list not in ascending order"));
6991 warned = 1;
6992 }
6993
6994 mask |= 1 << new_base;
6995 count++;
6996
6997 skip_whitespace (*str);
6998
6999 if (**str == '-') /* We have the start of a range expression */
7000 {
7001 int high_range;
7002
7003 (*str)++;
7004
7005 if ((high_range
7006 = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab))
7007 == FAIL)
7008 {
7009 inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
7010 return FAIL;
7011 }
7012
7013 if (high_range <= new_base)
7014 {
7015 inst.error = _("register range not in ascending order");
7016 return FAIL;
7017 }
7018
7019 for (new_base++; new_base <= high_range; new_base++)
7020 {
7021 if (mask & (1 << new_base))
7022 {
7023 inst.error = _("invalid register list");
7024 return FAIL;
7025 }
7026
7027 mask |= 1 << new_base;
7028 count++;
7029 }
7030 }
7031 }
7032 while (skip_past_comma (str) != FAIL);
7033
7034 if (**str != '}')
7035 {
7036 inst.error = _("invalid register list");
7037 return FAIL;
7038 }
7039
7040 (*str)++;
7041
7042 range |= 2 * count;
7043
7044 /* Sanity check -- should have raised a parse error above. */
7045 if (count == 0 || count > 16)
7046 abort();
7047
7048 /* Final test -- the registers must be consecutive. */
7049 while (count--)
7050 {
7051 if ((mask & (1 << base_reg++)) == 0)
7052 {
7053 inst.error = _("non-contiguous register range");
7054 return FAIL;
7055 }
7056 }
7057
7058 inst.instruction = tempinst;
7059 return range;
7060 }
7061
7062 static void
7063 vfp_sp_ldstm(str, ldstm_type)
7064 char *str;
7065 enum vfp_ldstm_type ldstm_type;
7066 {
7067 long range;
7068
7069 skip_whitespace (str);
7070
7071 if (reg_required_here (&str, 16) == FAIL)
7072 return;
7073
7074 skip_whitespace (str);
7075
7076 if (*str == '!')
7077 {
7078 inst.instruction |= WRITE_BACK;
7079 str++;
7080 }
7081 else if (ldstm_type != VFP_LDSTMIA)
7082 {
7083 inst.error = _("this addressing mode requires base-register writeback");
7084 return;
7085 }
7086
7087 if (skip_past_comma (&str) == FAIL
7088 || (range = vfp_sp_reg_list (&str, VFP_REG_Sd)) == FAIL)
7089 {
7090 if (!inst.error)
7091 inst.error = BAD_ARGS;
7092 return;
7093 }
7094
7095 inst.instruction |= range;
7096 end_of_line (str);
7097 }
7098
7099 static void
7100 vfp_dp_ldstm(str, ldstm_type)
7101 char *str;
7102 enum vfp_ldstm_type ldstm_type;
7103 {
7104 long range;
7105
7106 skip_whitespace (str);
7107
7108 if (reg_required_here (&str, 16) == FAIL)
7109 return;
7110
7111 skip_whitespace (str);
7112
7113 if (*str == '!')
7114 {
7115 inst.instruction |= WRITE_BACK;
7116 str++;
7117 }
7118 else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
7119 {
7120 inst.error = _("this addressing mode requires base-register writeback");
7121 return;
7122 }
7123
7124 if (skip_past_comma (&str) == FAIL
7125 || (range = vfp_dp_reg_list (&str)) == FAIL)
7126 {
7127 if (!inst.error)
7128 inst.error = BAD_ARGS;
7129 return;
7130 }
7131
7132 if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
7133 range += 1;
7134
7135 inst.instruction |= range;
7136 end_of_line (str);
7137 }
7138
7139 static void
7140 do_vfp_sp_ldstmia (str)
7141 char *str;
7142 {
7143 vfp_sp_ldstm (str, VFP_LDSTMIA);
7144 }
7145
7146 static void
7147 do_vfp_sp_ldstmdb (str)
7148 char *str;
7149 {
7150 vfp_sp_ldstm (str, VFP_LDSTMDB);
7151 }
7152
7153 static void
7154 do_vfp_dp_ldstmia (str)
7155 char *str;
7156 {
7157 vfp_dp_ldstm (str, VFP_LDSTMIA);
7158 }
7159
7160 static void
7161 do_vfp_dp_ldstmdb (str)
7162 char *str;
7163 {
7164 vfp_dp_ldstm (str, VFP_LDSTMDB);
7165 }
7166
7167 static void
7168 do_vfp_xp_ldstmia (str)
7169 char *str;
7170 {
7171 vfp_dp_ldstm (str, VFP_LDSTMIAX);
7172 }
7173
7174 static void
7175 do_vfp_xp_ldstmdb (str)
7176 char *str;
7177 {
7178 vfp_dp_ldstm (str, VFP_LDSTMDBX);
7179 }
7180
7181 static void
7182 do_vfp_sp_compare_z (str)
7183 char *str;
7184 {
7185 skip_whitespace (str);
7186
7187 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7188 {
7189 if (!inst.error)
7190 inst.error = BAD_ARGS;
7191 return;
7192 }
7193
7194 end_of_line (str);
7195 return;
7196 }
7197
7198 static void
7199 do_vfp_dp_compare_z (str)
7200 char *str;
7201 {
7202 skip_whitespace (str);
7203
7204 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7205 {
7206 if (!inst.error)
7207 inst.error = BAD_ARGS;
7208 return;
7209 }
7210
7211 end_of_line (str);
7212 return;
7213 }
7214
7215 static void
7216 do_vfp_dp_sp_cvt (str)
7217 char *str;
7218 {
7219 skip_whitespace (str);
7220
7221 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7222 return;
7223
7224 if (skip_past_comma (&str) == FAIL
7225 || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7226 {
7227 if (! inst.error)
7228 inst.error = BAD_ARGS;
7229 return;
7230 }
7231
7232 end_of_line (str);
7233 return;
7234 }
7235
7236 static void
7237 do_vfp_sp_dp_cvt (str)
7238 char *str;
7239 {
7240 skip_whitespace (str);
7241
7242 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7243 return;
7244
7245 if (skip_past_comma (&str) == FAIL
7246 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7247 {
7248 if (! inst.error)
7249 inst.error = BAD_ARGS;
7250 return;
7251 }
7252
7253 end_of_line (str);
7254 return;
7255 }
7256
7257 /* Thumb specific routines. */
7258
7259 /* Parse and validate that a register is of the right form, this saves
7260 repeated checking of this information in many similar cases.
7261 Unlike the 32-bit case we do not insert the register into the opcode
7262 here, since the position is often unknown until the full instruction
7263 has been parsed. */
7264
7265 static int
7266 thumb_reg (strp, hi_lo)
7267 char ** strp;
7268 int hi_lo;
7269 {
7270 int reg;
7271
7272 if ((reg = reg_required_here (strp, -1)) == FAIL)
7273 return FAIL;
7274
7275 switch (hi_lo)
7276 {
7277 case THUMB_REG_LO:
7278 if (reg > 7)
7279 {
7280 inst.error = _("lo register required");
7281 return FAIL;
7282 }
7283 break;
7284
7285 case THUMB_REG_HI:
7286 if (reg < 8)
7287 {
7288 inst.error = _("hi register required");
7289 return FAIL;
7290 }
7291 break;
7292
7293 default:
7294 break;
7295 }
7296
7297 return reg;
7298 }
7299
7300 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
7301 was SUB. */
7302
7303 static void
7304 thumb_add_sub (str, subtract)
7305 char * str;
7306 int subtract;
7307 {
7308 int Rd, Rs, Rn = FAIL;
7309
7310 skip_whitespace (str);
7311
7312 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
7313 || skip_past_comma (&str) == FAIL)
7314 {
7315 if (! inst.error)
7316 inst.error = BAD_ARGS;
7317 return;
7318 }
7319
7320 if (is_immediate_prefix (*str))
7321 {
7322 Rs = Rd;
7323 str++;
7324 if (my_get_expression (&inst.reloc.exp, &str))
7325 return;
7326 }
7327 else
7328 {
7329 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
7330 return;
7331
7332 if (skip_past_comma (&str) == FAIL)
7333 {
7334 /* Two operand format, shuffle the registers
7335 and pretend there are 3. */
7336 Rn = Rs;
7337 Rs = Rd;
7338 }
7339 else if (is_immediate_prefix (*str))
7340 {
7341 str++;
7342 if (my_get_expression (&inst.reloc.exp, &str))
7343 return;
7344 }
7345 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
7346 return;
7347 }
7348
7349 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
7350 for the latter case, EXPR contains the immediate that was found. */
7351 if (Rn != FAIL)
7352 {
7353 /* All register format. */
7354 if (Rd > 7 || Rs > 7 || Rn > 7)
7355 {
7356 if (Rs != Rd)
7357 {
7358 inst.error = _("dest and source1 must be the same register");
7359 return;
7360 }
7361
7362 /* Can't do this for SUB. */
7363 if (subtract)
7364 {
7365 inst.error = _("subtract valid only on lo regs");
7366 return;
7367 }
7368
7369 inst.instruction = (T_OPCODE_ADD_HI
7370 | (Rd > 7 ? THUMB_H1 : 0)
7371 | (Rn > 7 ? THUMB_H2 : 0));
7372 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
7373 }
7374 else
7375 {
7376 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
7377 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
7378 }
7379 }
7380 else
7381 {
7382 /* Immediate expression, now things start to get nasty. */
7383
7384 /* First deal with HI regs, only very restricted cases allowed:
7385 Adjusting SP, and using PC or SP to get an address. */
7386 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
7387 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
7388 {
7389 inst.error = _("invalid Hi register with immediate");
7390 return;
7391 }
7392
7393 if (inst.reloc.exp.X_op != O_constant)
7394 {
7395 /* Value isn't known yet, all we can do is store all the fragments
7396 we know about in the instruction and let the reloc hacking
7397 work it all out. */
7398 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
7399 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
7400 }
7401 else
7402 {
7403 int offset = inst.reloc.exp.X_add_number;
7404
7405 if (subtract)
7406 offset = -offset;
7407
7408 if (offset < 0)
7409 {
7410 offset = -offset;
7411 subtract = 1;
7412
7413 /* Quick check, in case offset is MIN_INT. */
7414 if (offset < 0)
7415 {
7416 inst.error = _("immediate value out of range");
7417 return;
7418 }
7419 }
7420 else
7421 subtract = 0;
7422
7423 if (Rd == REG_SP)
7424 {
7425 if (offset & ~0x1fc)
7426 {
7427 inst.error = _("invalid immediate value for stack adjust");
7428 return;
7429 }
7430 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
7431 inst.instruction |= offset >> 2;
7432 }
7433 else if (Rs == REG_PC || Rs == REG_SP)
7434 {
7435 if (subtract
7436 || (offset & ~0x3fc))
7437 {
7438 inst.error = _("invalid immediate for address calculation");
7439 return;
7440 }
7441 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
7442 : T_OPCODE_ADD_SP);
7443 inst.instruction |= (Rd << 8) | (offset >> 2);
7444 }
7445 else if (Rs == Rd)
7446 {
7447 if (offset & ~0xff)
7448 {
7449 inst.error = _("immediate value out of range");
7450 return;
7451 }
7452 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
7453 inst.instruction |= (Rd << 8) | offset;
7454 }
7455 else
7456 {
7457 if (offset & ~0x7)
7458 {
7459 inst.error = _("immediate value out of range");
7460 return;
7461 }
7462 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
7463 inst.instruction |= Rd | (Rs << 3) | (offset << 6);
7464 }
7465 }
7466 }
7467
7468 end_of_line (str);
7469 }
7470
7471 static void
7472 thumb_shift (str, shift)
7473 char * str;
7474 int shift;
7475 {
7476 int Rd, Rs, Rn = FAIL;
7477
7478 skip_whitespace (str);
7479
7480 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
7481 || skip_past_comma (&str) == FAIL)
7482 {
7483 if (! inst.error)
7484 inst.error = BAD_ARGS;
7485 return;
7486 }
7487
7488 if (is_immediate_prefix (*str))
7489 {
7490 /* Two operand immediate format, set Rs to Rd. */
7491 Rs = Rd;
7492 str ++;
7493 if (my_get_expression (&inst.reloc.exp, &str))
7494 return;
7495 }
7496 else
7497 {
7498 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
7499 return;
7500
7501 if (skip_past_comma (&str) == FAIL)
7502 {
7503 /* Two operand format, shuffle the registers
7504 and pretend there are 3. */
7505 Rn = Rs;
7506 Rs = Rd;
7507 }
7508 else if (is_immediate_prefix (*str))
7509 {
7510 str++;
7511 if (my_get_expression (&inst.reloc.exp, &str))
7512 return;
7513 }
7514 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
7515 return;
7516 }
7517
7518 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
7519 for the latter case, EXPR contains the immediate that was found. */
7520
7521 if (Rn != FAIL)
7522 {
7523 if (Rs != Rd)
7524 {
7525 inst.error = _("source1 and dest must be same register");
7526 return;
7527 }
7528
7529 switch (shift)
7530 {
7531 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
7532 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
7533 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
7534 }
7535
7536 inst.instruction |= Rd | (Rn << 3);
7537 }
7538 else
7539 {
7540 switch (shift)
7541 {
7542 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
7543 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
7544 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
7545 }
7546
7547 if (inst.reloc.exp.X_op != O_constant)
7548 {
7549 /* Value isn't known yet, create a dummy reloc and let reloc
7550 hacking fix it up. */
7551 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
7552 }
7553 else
7554 {
7555 unsigned shift_value = inst.reloc.exp.X_add_number;
7556
7557 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
7558 {
7559 inst.error = _("invalid immediate for shift");
7560 return;
7561 }
7562
7563 /* Shifts of zero are handled by converting to LSL. */
7564 if (shift_value == 0)
7565 inst.instruction = T_OPCODE_LSL_I;
7566
7567 /* Shifts of 32 are encoded as a shift of zero. */
7568 if (shift_value == 32)
7569 shift_value = 0;
7570
7571 inst.instruction |= shift_value << 6;
7572 }
7573
7574 inst.instruction |= Rd | (Rs << 3);
7575 }
7576
7577 end_of_line (str);
7578 }
7579
7580 static void
7581 thumb_mov_compare (str, move)
7582 char * str;
7583 int move;
7584 {
7585 int Rd, Rs = FAIL;
7586
7587 skip_whitespace (str);
7588
7589 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
7590 || skip_past_comma (&str) == FAIL)
7591 {
7592 if (! inst.error)
7593 inst.error = BAD_ARGS;
7594 return;
7595 }
7596
7597 if (is_immediate_prefix (*str))
7598 {
7599 str++;
7600 if (my_get_expression (&inst.reloc.exp, &str))
7601 return;
7602 }
7603 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
7604 return;
7605
7606 if (Rs != FAIL)
7607 {
7608 if (Rs < 8 && Rd < 8)
7609 {
7610 if (move == THUMB_MOVE)
7611 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
7612 since a MOV instruction produces unpredictable results. */
7613 inst.instruction = T_OPCODE_ADD_I3;
7614 else
7615 inst.instruction = T_OPCODE_CMP_LR;
7616 inst.instruction |= Rd | (Rs << 3);
7617 }
7618 else
7619 {
7620 if (move == THUMB_MOVE)
7621 inst.instruction = T_OPCODE_MOV_HR;
7622 else
7623 inst.instruction = T_OPCODE_CMP_HR;
7624
7625 if (Rd > 7)
7626 inst.instruction |= THUMB_H1;
7627
7628 if (Rs > 7)
7629 inst.instruction |= THUMB_H2;
7630
7631 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
7632 }
7633 }
7634 else
7635 {
7636 if (Rd > 7)
7637 {
7638 inst.error = _("only lo regs allowed with immediate");
7639 return;
7640 }
7641
7642 if (move == THUMB_MOVE)
7643 inst.instruction = T_OPCODE_MOV_I8;
7644 else
7645 inst.instruction = T_OPCODE_CMP_I8;
7646
7647 inst.instruction |= Rd << 8;
7648
7649 if (inst.reloc.exp.X_op != O_constant)
7650 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
7651 else
7652 {
7653 unsigned value = inst.reloc.exp.X_add_number;
7654
7655 if (value > 255)
7656 {
7657 inst.error = _("invalid immediate");
7658 return;
7659 }
7660
7661 inst.instruction |= value;
7662 }
7663 }
7664
7665 end_of_line (str);
7666 }
7667
7668 static void
7669 thumb_load_store (str, load_store, size)
7670 char * str;
7671 int load_store;
7672 int size;
7673 {
7674 int Rd, Rb, Ro = FAIL;
7675
7676 skip_whitespace (str);
7677
7678 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
7679 || skip_past_comma (&str) == FAIL)
7680 {
7681 if (! inst.error)
7682 inst.error = BAD_ARGS;
7683 return;
7684 }
7685
7686 if (*str == '[')
7687 {
7688 str++;
7689 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
7690 return;
7691
7692 if (skip_past_comma (&str) != FAIL)
7693 {
7694 if (is_immediate_prefix (*str))
7695 {
7696 str++;
7697 if (my_get_expression (&inst.reloc.exp, &str))
7698 return;
7699 }
7700 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
7701 return;
7702 }
7703 else
7704 {
7705 inst.reloc.exp.X_op = O_constant;
7706 inst.reloc.exp.X_add_number = 0;
7707 }
7708
7709 if (*str != ']')
7710 {
7711 inst.error = _("expected ']'");
7712 return;
7713 }
7714 str++;
7715 }
7716 else if (*str == '=')
7717 {
7718 if (load_store != THUMB_LOAD)
7719 {
7720 inst.error = _("invalid pseudo operation");
7721 return;
7722 }
7723
7724 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
7725 str++;
7726
7727 skip_whitespace (str);
7728
7729 if (my_get_expression (& inst.reloc.exp, & str))
7730 return;
7731
7732 end_of_line (str);
7733
7734 if ( inst.reloc.exp.X_op != O_constant
7735 && inst.reloc.exp.X_op != O_symbol)
7736 {
7737 inst.error = "Constant expression expected";
7738 return;
7739 }
7740
7741 if (inst.reloc.exp.X_op == O_constant
7742 && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
7743 {
7744 /* This can be done with a mov instruction. */
7745
7746 inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8);
7747 inst.instruction |= inst.reloc.exp.X_add_number;
7748 return;
7749 }
7750
7751 /* Insert into literal pool. */
7752 if (add_to_lit_pool () == FAIL)
7753 {
7754 if (!inst.error)
7755 inst.error = "literal pool insertion failed";
7756 return;
7757 }
7758
7759 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
7760 inst.reloc.pc_rel = 1;
7761 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
7762 /* Adjust ARM pipeline offset to Thumb. */
7763 inst.reloc.exp.X_add_number += 4;
7764
7765 return;
7766 }
7767 else
7768 {
7769 if (my_get_expression (&inst.reloc.exp, &str))
7770 return;
7771
7772 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
7773 inst.reloc.pc_rel = 1;
7774 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset. */
7775 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
7776 end_of_line (str);
7777 return;
7778 }
7779
7780 if (Rb == REG_PC || Rb == REG_SP)
7781 {
7782 if (size != THUMB_WORD)
7783 {
7784 inst.error = _("byte or halfword not valid for base register");
7785 return;
7786 }
7787 else if (Rb == REG_PC && load_store != THUMB_LOAD)
7788 {
7789 inst.error = _("r15 based store not allowed");
7790 return;
7791 }
7792 else if (Ro != FAIL)
7793 {
7794 inst.error = _("invalid base register for register offset");
7795 return;
7796 }
7797
7798 if (Rb == REG_PC)
7799 inst.instruction = T_OPCODE_LDR_PC;
7800 else if (load_store == THUMB_LOAD)
7801 inst.instruction = T_OPCODE_LDR_SP;
7802 else
7803 inst.instruction = T_OPCODE_STR_SP;
7804
7805 inst.instruction |= Rd << 8;
7806 if (inst.reloc.exp.X_op == O_constant)
7807 {
7808 unsigned offset = inst.reloc.exp.X_add_number;
7809
7810 if (offset & ~0x3fc)
7811 {
7812 inst.error = _("invalid offset");
7813 return;
7814 }
7815
7816 inst.instruction |= offset >> 2;
7817 }
7818 else
7819 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
7820 }
7821 else if (Rb > 7)
7822 {
7823 inst.error = _("invalid base register in load/store");
7824 return;
7825 }
7826 else if (Ro == FAIL)
7827 {
7828 /* Immediate offset. */
7829 if (size == THUMB_WORD)
7830 inst.instruction = (load_store == THUMB_LOAD
7831 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
7832 else if (size == THUMB_HALFWORD)
7833 inst.instruction = (load_store == THUMB_LOAD
7834 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
7835 else
7836 inst.instruction = (load_store == THUMB_LOAD
7837 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
7838
7839 inst.instruction |= Rd | (Rb << 3);
7840
7841 if (inst.reloc.exp.X_op == O_constant)
7842 {
7843 unsigned offset = inst.reloc.exp.X_add_number;
7844
7845 if (offset & ~(0x1f << size))
7846 {
7847 inst.error = _("invalid offset");
7848 return;
7849 }
7850 inst.instruction |= (offset >> size) << 6;
7851 }
7852 else
7853 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
7854 }
7855 else
7856 {
7857 /* Register offset. */
7858 if (size == THUMB_WORD)
7859 inst.instruction = (load_store == THUMB_LOAD
7860 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
7861 else if (size == THUMB_HALFWORD)
7862 inst.instruction = (load_store == THUMB_LOAD
7863 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
7864 else
7865 inst.instruction = (load_store == THUMB_LOAD
7866 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
7867
7868 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
7869 }
7870
7871 end_of_line (str);
7872 }
7873
7874 /* A register must be given at this point.
7875
7876 Shift is the place to put it in inst.instruction.
7877
7878 Restores input start point on err.
7879 Returns the reg#, or FAIL. */
7880
7881 static int
7882 cirrus_reg_required_here (str, shift, regtype)
7883 char ** str;
7884 int shift;
7885 enum arm_reg_type regtype;
7886 {
7887 int reg;
7888 char *start = *str;
7889
7890 if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
7891 {
7892 if (shift >= 0)
7893 inst.instruction |= reg << shift;
7894
7895 return reg;
7896 }
7897
7898 /* Restore the start point. */
7899 *str = start;
7900
7901 /* In the few cases where we might be able to accept something else
7902 this error can be overridden. */
7903 inst.error = _(all_reg_maps[regtype].expected);
7904
7905 return FAIL;
7906 }
7907
7908 /* Cirrus Instructions. */
7909
7910 /* Wrapper functions. */
7911
7912 static void
7913 do_c_binops_1a (str)
7914 char * str;
7915 {
7916 do_c_binops (str, CIRRUS_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
7917 }
7918
7919 static void
7920 do_c_binops_1b (str)
7921 char * str;
7922 {
7923 do_c_binops (str, CIRRUS_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
7924 }
7925
7926 static void
7927 do_c_binops_1c (str)
7928 char * str;
7929 {
7930 do_c_binops (str, CIRRUS_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
7931 }
7932
7933 static void
7934 do_c_binops_1d (str)
7935 char * str;
7936 {
7937 do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
7938 }
7939
7940 static void
7941 do_c_binops_1e (str)
7942 char * str;
7943 {
7944 do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
7945 }
7946
7947 static void
7948 do_c_binops_1f (str)
7949 char * str;
7950 {
7951 do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
7952 }
7953
7954 static void
7955 do_c_binops_1g (str)
7956 char * str;
7957 {
7958 do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
7959 }
7960
7961 static void
7962 do_c_binops_1h (str)
7963 char * str;
7964 {
7965 do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
7966 }
7967
7968 static void
7969 do_c_binops_1i (str)
7970 char * str;
7971 {
7972 do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
7973 }
7974
7975 static void
7976 do_c_binops_1j (str)
7977 char * str;
7978 {
7979 do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
7980 }
7981
7982 static void
7983 do_c_binops_1k (str)
7984 char * str;
7985 {
7986 do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
7987 }
7988
7989 static void
7990 do_c_binops_1l (str)
7991 char * str;
7992 {
7993 do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
7994 }
7995
7996 static void
7997 do_c_binops_1m (str)
7998 char * str;
7999 {
8000 do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
8001 }
8002
8003 static void
8004 do_c_binops_1n (str)
8005 char * str;
8006 {
8007 do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
8008 }
8009
8010 static void
8011 do_c_binops_1o (str)
8012 char * str;
8013 {
8014 do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
8015 }
8016
8017 static void
8018 do_c_binops_2a (str)
8019 char * str;
8020 {
8021 do_c_binops (str, CIRRUS_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
8022 }
8023
8024 static void
8025 do_c_binops_2b (str)
8026 char * str;
8027 {
8028 do_c_binops (str, CIRRUS_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
8029 }
8030
8031 static void
8032 do_c_binops_2c (str)
8033 char * str;
8034 {
8035 do_c_binops (str, CIRRUS_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
8036 }
8037
8038 static void
8039 do_c_binops_3a (str)
8040 char * str;
8041 {
8042 do_c_binops (str, CIRRUS_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
8043 }
8044
8045 static void
8046 do_c_binops_3b (str)
8047 char * str;
8048 {
8049 do_c_binops (str, CIRRUS_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
8050 }
8051
8052 static void
8053 do_c_binops_3c (str)
8054 char * str;
8055 {
8056 do_c_binops (str, CIRRUS_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
8057 }
8058
8059 static void
8060 do_c_binops_3d (str)
8061 char * str;
8062 {
8063 do_c_binops (str, CIRRUS_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
8064 }
8065
8066 static void
8067 do_c_triple_4a (str)
8068 char * str;
8069 {
8070 do_c_triple (str, CIRRUS_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
8071 }
8072
8073 static void
8074 do_c_triple_4b (str)
8075 char * str;
8076 {
8077 do_c_triple (str, CIRRUS_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
8078 }
8079
8080 static void
8081 do_c_triple_5a (str)
8082 char * str;
8083 {
8084 do_c_triple (str, CIRRUS_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
8085 }
8086
8087 static void
8088 do_c_triple_5b (str)
8089 char * str;
8090 {
8091 do_c_triple (str, CIRRUS_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
8092 }
8093
8094 static void
8095 do_c_triple_5c (str)
8096 char * str;
8097 {
8098 do_c_triple (str, CIRRUS_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
8099 }
8100
8101 static void
8102 do_c_triple_5d (str)
8103 char * str;
8104 {
8105 do_c_triple (str, CIRRUS_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
8106 }
8107
8108 static void
8109 do_c_triple_5e (str)
8110 char * str;
8111 {
8112 do_c_triple (str, CIRRUS_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
8113 }
8114
8115 static void
8116 do_c_triple_5f (str)
8117 char * str;
8118 {
8119 do_c_triple (str, CIRRUS_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
8120 }
8121
8122 static void
8123 do_c_triple_5g (str)
8124 char * str;
8125 {
8126 do_c_triple (str, CIRRUS_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
8127 }
8128
8129 static void
8130 do_c_triple_5h (str)
8131 char * str;
8132 {
8133 do_c_triple (str, CIRRUS_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
8134 }
8135
8136 static void
8137 do_c_quad_6a (str)
8138 char * str;
8139 {
8140 do_c_quad (str, CIRRUS_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
8141 REG_TYPE_MVFX);
8142 }
8143
8144 static void
8145 do_c_quad_6b (str)
8146 char * str;
8147 {
8148 do_c_quad (str, CIRRUS_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
8149 REG_TYPE_MVFX);
8150 }
8151
8152 /* cfmvsc32<cond> DSPSC,MVFX[15:0]. */
8153 static void
8154 do_c_dspsc_1 (str)
8155 char * str;
8156 {
8157 skip_whitespace (str);
8158
8159 /* cfmvsc32. */
8160 if (cirrus_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
8161 || skip_past_comma (&str) == FAIL
8162 || cirrus_reg_required_here (&str, 16, REG_TYPE_MVFX) == FAIL)
8163 {
8164 if (!inst.error)
8165 inst.error = BAD_ARGS;
8166
8167 return;
8168 }
8169
8170 end_of_line (str);
8171 }
8172
8173 /* cfmv32sc<cond> MVFX[15:0],DSPSC. */
8174 static void
8175 do_c_dspsc_2 (str)
8176 char * str;
8177 {
8178 skip_whitespace (str);
8179
8180 /* cfmv32sc. */
8181 if (cirrus_reg_required_here (&str, 0, REG_TYPE_MVFX) == FAIL
8182 || skip_past_comma (&str) == FAIL
8183 || cirrus_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
8184 {
8185 if (!inst.error)
8186 inst.error = BAD_ARGS;
8187
8188 return;
8189 }
8190
8191 end_of_line (str);
8192 }
8193
8194 static void
8195 do_c_shift_1 (str)
8196 char * str;
8197 {
8198 do_c_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
8199 }
8200
8201 static void
8202 do_c_shift_2 (str)
8203 char * str;
8204 {
8205 do_c_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
8206 }
8207
8208 static void
8209 do_c_ldst_1 (str)
8210 char * str;
8211 {
8212 do_c_ldst (str, REG_TYPE_MVF);
8213 }
8214
8215 static void
8216 do_c_ldst_2 (str)
8217 char * str;
8218 {
8219 do_c_ldst (str, REG_TYPE_MVD);
8220 }
8221
8222 static void
8223 do_c_ldst_3 (str)
8224 char * str;
8225 {
8226 do_c_ldst (str, REG_TYPE_MVFX);
8227 }
8228
8229 static void
8230 do_c_ldst_4 (str)
8231 char * str;
8232 {
8233 do_c_ldst (str, REG_TYPE_MVDX);
8234 }
8235
8236 /* Isnsn like "foo X,Y". */
8237
8238 static void
8239 do_c_binops (str, mode, reg0, reg1)
8240 char * str;
8241 int mode;
8242 enum arm_reg_type reg0;
8243 enum arm_reg_type reg1;
8244 {
8245 int shift0, shift1;
8246
8247 shift0 = mode & 0xff;
8248 shift1 = (mode >> 8) & 0xff;
8249
8250 skip_whitespace (str);
8251
8252 if (cirrus_reg_required_here (&str, shift0, reg0) == FAIL
8253 || skip_past_comma (&str) == FAIL
8254 || cirrus_reg_required_here (&str, shift1, reg1) == FAIL)
8255 {
8256 if (!inst.error)
8257 inst.error = BAD_ARGS;
8258 }
8259 else
8260 end_of_line (str);
8261 }
8262
8263 /* Isnsn like "foo X,Y,Z". */
8264
8265 static void
8266 do_c_triple (str, mode, reg0, reg1, reg2)
8267 char * str;
8268 int mode;
8269 enum arm_reg_type reg0;
8270 enum arm_reg_type reg1;
8271 enum arm_reg_type reg2;
8272 {
8273 int shift0, shift1, shift2;
8274
8275 shift0 = mode & 0xff;
8276 shift1 = (mode >> 8) & 0xff;
8277 shift2 = (mode >> 16) & 0xff;
8278
8279 skip_whitespace (str);
8280
8281 if (cirrus_reg_required_here (&str, shift0, reg0) == FAIL
8282 || skip_past_comma (&str) == FAIL
8283 || cirrus_reg_required_here (&str, shift1, reg1) == FAIL
8284 || skip_past_comma (&str) == FAIL
8285 || cirrus_reg_required_here (&str, shift2, reg2) == FAIL)
8286 {
8287 if (!inst.error)
8288 inst.error = BAD_ARGS;
8289 }
8290 else
8291 end_of_line (str);
8292 }
8293
8294 /* Isnsn like "foo W,X,Y,Z".
8295 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
8296
8297 static void
8298 do_c_quad (str, mode, reg0, reg1, reg2, reg3)
8299 char * str;
8300 int mode;
8301 enum arm_reg_type reg0;
8302 enum arm_reg_type reg1;
8303 enum arm_reg_type reg2;
8304 enum arm_reg_type reg3;
8305 {
8306 int shift0, shift1, shift2, shift3;
8307
8308 shift0= mode & 0xff;
8309 shift1 = (mode >> 8) & 0xff;
8310 shift2 = (mode >> 16) & 0xff;
8311 shift3 = (mode >> 24) & 0xff;
8312
8313 skip_whitespace (str);
8314
8315 if (cirrus_reg_required_here (&str, shift0, reg0) == FAIL
8316 || skip_past_comma (&str) == FAIL
8317 || cirrus_reg_required_here (&str, shift1, reg1) == FAIL
8318 || skip_past_comma (&str) == FAIL
8319 || cirrus_reg_required_here (&str, shift2, reg2) == FAIL
8320 || skip_past_comma (&str) == FAIL
8321 || cirrus_reg_required_here (&str, shift3, reg3) == FAIL)
8322 {
8323 if (!inst.error)
8324 inst.error = BAD_ARGS;
8325 }
8326 else
8327 end_of_line (str);
8328 }
8329
8330 /* Cirrus shift immediate instructions.
8331 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
8332 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
8333
8334 static void
8335 do_c_shift (str, reg0, reg1)
8336 char * str;
8337 enum arm_reg_type reg0;
8338 enum arm_reg_type reg1;
8339 {
8340 int error;
8341 int imm, neg = 0;
8342
8343 skip_whitespace (str);
8344
8345 error = 0;
8346
8347 if (cirrus_reg_required_here (&str, 12, reg0) == FAIL
8348 || skip_past_comma (&str) == FAIL
8349 || cirrus_reg_required_here (&str, 16, reg1) == FAIL
8350 || skip_past_comma (&str) == FAIL)
8351 {
8352 if (!inst.error)
8353 inst.error = BAD_ARGS;
8354 return;
8355 }
8356
8357 /* Calculate the immediate operand.
8358 The operand is a 7bit signed number. */
8359 skip_whitespace (str);
8360
8361 if (*str == '#')
8362 ++str;
8363
8364 if (!ISDIGIT (*str) && *str != '-')
8365 {
8366 inst.error = _("expecting immediate, 7bit operand");
8367 return;
8368 }
8369
8370 if (*str == '-')
8371 {
8372 neg = 1;
8373 ++str;
8374 }
8375
8376 for (imm = 0; *str && ISDIGIT (*str); ++str)
8377 imm = imm * 10 + *str - '0';
8378
8379 if (imm > 64)
8380 {
8381 inst.error = _("immediate out of range");
8382 return;
8383 }
8384
8385 /* Make negative imm's into 7bit signed numbers. */
8386 if (neg)
8387 {
8388 imm = -imm;
8389 imm &= 0x0000007f;
8390 }
8391
8392 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
8393 Bits 5-7 of the insn should have bits 4-6 of the immediate.
8394 Bit 4 should be 0. */
8395 imm = (imm & 0xf) | ((imm & 0x70) << 1);
8396
8397 inst.instruction |= imm;
8398 end_of_line (str);
8399 }
8400
8401 static int
8402 cirrus_parse_offset (str, negative)
8403 char ** str;
8404 int *negative;
8405 {
8406 char * p = *str;
8407 int offset;
8408
8409 *negative = 0;
8410
8411 skip_whitespace (p);
8412
8413 if (*p == '#')
8414 ++p;
8415
8416 if (*p == '-')
8417 {
8418 *negative = 1;
8419 ++p;
8420 }
8421
8422 if (!ISDIGIT (*p))
8423 {
8424 inst.error = _("offset expected");
8425 return 0;
8426 }
8427
8428 for (offset = 0; *p && ISDIGIT (*p); ++p)
8429 offset = offset * 10 + *p - '0';
8430
8431 if (offset > 0xff)
8432 {
8433 inst.error = _("offset out of range");
8434 return 0;
8435 }
8436
8437 *str = p;
8438
8439 return *negative ? -offset : offset;
8440 }
8441
8442 /* Cirrus load/store instructions.
8443 <insn><cond> CRd,[Rn,<offset>]{!}.
8444 <insn><cond> CRd,[Rn],<offset>. */
8445
8446 static void
8447 do_c_ldst (str, reg0)
8448 char * str;
8449 enum arm_reg_type reg0;
8450 {
8451 int offset, negative;
8452
8453 skip_whitespace (str);
8454
8455 if (cirrus_reg_required_here (&str, 12, reg0) == FAIL
8456 || skip_past_comma (&str) == FAIL
8457 || *str++ != '['
8458 || reg_required_here (&str, 16) == FAIL)
8459 goto fail_ldst;
8460
8461 if (skip_past_comma (&str) == SUCCESS)
8462 {
8463 /* You are here: "<offset>]{!}". */
8464 inst.instruction |= PRE_INDEX;
8465
8466 offset = cirrus_parse_offset (&str, &negative);
8467
8468 if (inst.error)
8469 return;
8470
8471 if (*str++ != ']')
8472 {
8473 inst.error = _("missing ]");
8474 return;
8475 }
8476
8477 if (*str == '!')
8478 {
8479 inst.instruction |= WRITE_BACK;
8480 ++str;
8481 }
8482 }
8483 else
8484 {
8485 /* You are here: "], <offset>". */
8486 if (*str++ != ']')
8487 {
8488 inst.error = _("missing ]");
8489 return;
8490 }
8491
8492 if (skip_past_comma (&str) == FAIL
8493 || (offset = cirrus_parse_offset (&str, &negative), inst.error))
8494 goto fail_ldst;
8495
8496 inst.instruction |= CP_T_WB; /* Post indexed, set bit W. */
8497 }
8498
8499 if (negative)
8500 offset = -offset;
8501 else
8502 inst.instruction |= CP_T_UD; /* Postive, so set bit U. */
8503
8504 inst.instruction |= offset >> 2;
8505 end_of_line (str);
8506 return;
8507
8508 fail_ldst:
8509 if (!inst.error)
8510 inst.error = BAD_ARGS;
8511 return;
8512 }
8513
8514 static void
8515 do_t_nop (str)
8516 char * str;
8517 {
8518 /* Do nothing. */
8519 end_of_line (str);
8520 return;
8521 }
8522
8523 /* Handle the Format 4 instructions that do not have equivalents in other
8524 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
8525 BIC and MVN. */
8526
8527 static void
8528 do_t_arit (str)
8529 char * str;
8530 {
8531 int Rd, Rs, Rn;
8532
8533 skip_whitespace (str);
8534
8535 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8536 || skip_past_comma (&str) == FAIL
8537 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8538 {
8539 inst.error = BAD_ARGS;
8540 return;
8541 }
8542
8543 if (skip_past_comma (&str) != FAIL)
8544 {
8545 /* Three operand format not allowed for TST, CMN, NEG and MVN.
8546 (It isn't allowed for CMP either, but that isn't handled by this
8547 function.) */
8548 if (inst.instruction == T_OPCODE_TST
8549 || inst.instruction == T_OPCODE_CMN
8550 || inst.instruction == T_OPCODE_NEG
8551 || inst.instruction == T_OPCODE_MVN)
8552 {
8553 inst.error = BAD_ARGS;
8554 return;
8555 }
8556
8557 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8558 return;
8559
8560 if (Rs != Rd)
8561 {
8562 inst.error = _("dest and source1 must be the same register");
8563 return;
8564 }
8565 Rs = Rn;
8566 }
8567
8568 if (inst.instruction == T_OPCODE_MUL
8569 && Rs == Rd)
8570 as_tsktsk (_("Rs and Rd must be different in MUL"));
8571
8572 inst.instruction |= Rd | (Rs << 3);
8573 end_of_line (str);
8574 }
8575
8576 static void
8577 do_t_add (str)
8578 char * str;
8579 {
8580 thumb_add_sub (str, 0);
8581 }
8582
8583 static void
8584 do_t_asr (str)
8585 char * str;
8586 {
8587 thumb_shift (str, THUMB_ASR);
8588 }
8589
8590 static void
8591 do_t_branch9 (str)
8592 char * str;
8593 {
8594 if (my_get_expression (&inst.reloc.exp, &str))
8595 return;
8596 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
8597 inst.reloc.pc_rel = 1;
8598 end_of_line (str);
8599 }
8600
8601 static void
8602 do_t_branch12 (str)
8603 char * str;
8604 {
8605 if (my_get_expression (&inst.reloc.exp, &str))
8606 return;
8607 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
8608 inst.reloc.pc_rel = 1;
8609 end_of_line (str);
8610 }
8611
8612 /* Find the real, Thumb encoded start of a Thumb function. */
8613
8614 static symbolS *
8615 find_real_start (symbolP)
8616 symbolS * symbolP;
8617 {
8618 char * real_start;
8619 const char * name = S_GET_NAME (symbolP);
8620 symbolS * new_target;
8621
8622 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
8623 #define STUB_NAME ".real_start_of"
8624
8625 if (name == NULL)
8626 abort ();
8627
8628 /* Names that start with '.' are local labels, not function entry points.
8629 The compiler may generate BL instructions to these labels because it
8630 needs to perform a branch to a far away location. */
8631 if (name[0] == '.')
8632 return symbolP;
8633
8634 real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
8635 sprintf (real_start, "%s%s", STUB_NAME, name);
8636
8637 new_target = symbol_find (real_start);
8638
8639 if (new_target == NULL)
8640 {
8641 as_warn ("Failed to find real start of function: %s\n", name);
8642 new_target = symbolP;
8643 }
8644
8645 free (real_start);
8646
8647 return new_target;
8648 }
8649
8650 static void
8651 do_t_branch23 (str)
8652 char * str;
8653 {
8654 if (my_get_expression (& inst.reloc.exp, & str))
8655 return;
8656
8657 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
8658 inst.reloc.pc_rel = 1;
8659 end_of_line (str);
8660
8661 /* If the destination of the branch is a defined symbol which does not have
8662 the THUMB_FUNC attribute, then we must be calling a function which has
8663 the (interfacearm) attribute. We look for the Thumb entry point to that
8664 function and change the branch to refer to that function instead. */
8665 if ( inst.reloc.exp.X_op == O_symbol
8666 && inst.reloc.exp.X_add_symbol != NULL
8667 && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
8668 && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
8669 inst.reloc.exp.X_add_symbol =
8670 find_real_start (inst.reloc.exp.X_add_symbol);
8671 }
8672
8673 static void
8674 do_t_bx (str)
8675 char * str;
8676 {
8677 int reg;
8678
8679 skip_whitespace (str);
8680
8681 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8682 return;
8683
8684 /* This sets THUMB_H2 from the top bit of reg. */
8685 inst.instruction |= reg << 3;
8686
8687 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
8688 should cause the alignment to be checked once it is known. This is
8689 because BX PC only works if the instruction is word aligned. */
8690
8691 end_of_line (str);
8692 }
8693
8694 static void
8695 do_t_compare (str)
8696 char * str;
8697 {
8698 thumb_mov_compare (str, THUMB_COMPARE);
8699 }
8700
8701 static void
8702 do_t_ldmstm (str)
8703 char * str;
8704 {
8705 int Rb;
8706 long range;
8707
8708 skip_whitespace (str);
8709
8710 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8711 return;
8712
8713 if (*str != '!')
8714 as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
8715 else
8716 str++;
8717
8718 if (skip_past_comma (&str) == FAIL
8719 || (range = reg_list (&str)) == FAIL)
8720 {
8721 if (! inst.error)
8722 inst.error = BAD_ARGS;
8723 return;
8724 }
8725
8726 if (inst.reloc.type != BFD_RELOC_NONE)
8727 {
8728 /* This really doesn't seem worth it. */
8729 inst.reloc.type = BFD_RELOC_NONE;
8730 inst.error = _("expression too complex");
8731 return;
8732 }
8733
8734 if (range & ~0xff)
8735 {
8736 inst.error = _("only lo-regs valid in load/store multiple");
8737 return;
8738 }
8739
8740 inst.instruction |= (Rb << 8) | range;
8741 end_of_line (str);
8742 }
8743
8744 static void
8745 do_t_ldr (str)
8746 char * str;
8747 {
8748 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
8749 }
8750
8751 static void
8752 do_t_ldrb (str)
8753 char * str;
8754 {
8755 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
8756 }
8757
8758 static void
8759 do_t_ldrh (str)
8760 char * str;
8761 {
8762 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
8763 }
8764
8765 static void
8766 do_t_lds (str)
8767 char * str;
8768 {
8769 int Rd, Rb, Ro;
8770
8771 skip_whitespace (str);
8772
8773 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8774 || skip_past_comma (&str) == FAIL
8775 || *str++ != '['
8776 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8777 || skip_past_comma (&str) == FAIL
8778 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8779 || *str++ != ']')
8780 {
8781 if (! inst.error)
8782 inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
8783 return;
8784 }
8785
8786 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
8787 end_of_line (str);
8788 }
8789
8790 static void
8791 do_t_lsl (str)
8792 char * str;
8793 {
8794 thumb_shift (str, THUMB_LSL);
8795 }
8796
8797 static void
8798 do_t_lsr (str)
8799 char * str;
8800 {
8801 thumb_shift (str, THUMB_LSR);
8802 }
8803
8804 static void
8805 do_t_mov (str)
8806 char * str;
8807 {
8808 thumb_mov_compare (str, THUMB_MOVE);
8809 }
8810
8811 static void
8812 do_t_push_pop (str)
8813 char * str;
8814 {
8815 long range;
8816
8817 skip_whitespace (str);
8818
8819 if ((range = reg_list (&str)) == FAIL)
8820 {
8821 if (! inst.error)
8822 inst.error = BAD_ARGS;
8823 return;
8824 }
8825
8826 if (inst.reloc.type != BFD_RELOC_NONE)
8827 {
8828 /* This really doesn't seem worth it. */
8829 inst.reloc.type = BFD_RELOC_NONE;
8830 inst.error = _("expression too complex");
8831 return;
8832 }
8833
8834 if (range & ~0xff)
8835 {
8836 if ((inst.instruction == T_OPCODE_PUSH
8837 && (range & ~0xff) == 1 << REG_LR)
8838 || (inst.instruction == T_OPCODE_POP
8839 && (range & ~0xff) == 1 << REG_PC))
8840 {
8841 inst.instruction |= THUMB_PP_PC_LR;
8842 range &= 0xff;
8843 }
8844 else
8845 {
8846 inst.error = _("invalid register list to push/pop instruction");
8847 return;
8848 }
8849 }
8850
8851 inst.instruction |= range;
8852 end_of_line (str);
8853 }
8854
8855 static void
8856 do_t_str (str)
8857 char * str;
8858 {
8859 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
8860 }
8861
8862 static void
8863 do_t_strb (str)
8864 char * str;
8865 {
8866 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
8867 }
8868
8869 static void
8870 do_t_strh (str)
8871 char * str;
8872 {
8873 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
8874 }
8875
8876 static void
8877 do_t_sub (str)
8878 char * str;
8879 {
8880 thumb_add_sub (str, 1);
8881 }
8882
8883 static void
8884 do_t_swi (str)
8885 char * str;
8886 {
8887 skip_whitespace (str);
8888
8889 if (my_get_expression (&inst.reloc.exp, &str))
8890 return;
8891
8892 inst.reloc.type = BFD_RELOC_ARM_SWI;
8893 end_of_line (str);
8894 return;
8895 }
8896
8897 static void
8898 do_t_adr (str)
8899 char * str;
8900 {
8901 int reg;
8902
8903 /* This is a pseudo-op of the form "adr rd, label" to be converted
8904 into a relative address of the form "add rd, pc, #label-.-4". */
8905 skip_whitespace (str);
8906
8907 /* Store Rd in temporary location inside instruction. */
8908 if ((reg = reg_required_here (&str, 4)) == FAIL
8909 || (reg > 7) /* For Thumb reg must be r0..r7. */
8910 || skip_past_comma (&str) == FAIL
8911 || my_get_expression (&inst.reloc.exp, &str))
8912 {
8913 if (!inst.error)
8914 inst.error = BAD_ARGS;
8915 return;
8916 }
8917
8918 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
8919 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
8920 inst.reloc.pc_rel = 1;
8921 inst.instruction |= REG_PC; /* Rd is already placed into the instruction. */
8922
8923 end_of_line (str);
8924 }
8925
8926 static void
8927 insert_reg (r, htab)
8928 const struct reg_entry *r;
8929 struct hash_control *htab;
8930 {
8931 int len = strlen (r->name) + 2;
8932 char * buf = (char *) xmalloc (len);
8933 char * buf2 = (char *) xmalloc (len);
8934 int i = 0;
8935
8936 #ifdef REGISTER_PREFIX
8937 buf[i++] = REGISTER_PREFIX;
8938 #endif
8939
8940 strcpy (buf + i, r->name);
8941
8942 for (i = 0; buf[i]; i++)
8943 buf2[i] = TOUPPER (buf[i]);
8944
8945 buf2[i] = '\0';
8946
8947 hash_insert (htab, buf, (PTR) r);
8948 hash_insert (htab, buf2, (PTR) r);
8949 }
8950
8951 static void
8952 build_reg_hsh (map)
8953 struct reg_map *map;
8954 {
8955 const struct reg_entry *r;
8956
8957 if ((map->htab = hash_new ()) == NULL)
8958 as_fatal (_("virtual memory exhausted"));
8959
8960 for (r = map->names; r->name != NULL; r++)
8961 insert_reg (r, map->htab);
8962 }
8963
8964 static void
8965 insert_reg_alias (str, regnum, htab)
8966 char *str;
8967 int regnum;
8968 struct hash_control *htab;
8969 {
8970 struct reg_entry *new =
8971 (struct reg_entry *) xmalloc (sizeof (struct reg_entry));
8972 char *name = xmalloc (strlen (str) + 1);
8973 strcpy (name, str);
8974
8975 new->name = name;
8976 new->number = regnum;
8977
8978 hash_insert (htab, name, (PTR) new);
8979 }
8980
8981 /* Look for the .req directive. This is of the form:
8982
8983 newname .req existing_name
8984
8985 If we find one, or if it looks sufficiently like one that we want to
8986 handle any error here, return non-zero. Otherwise return zero. */
8987 static int
8988 create_register_alias (newname, p)
8989 char *newname;
8990 char *p;
8991 {
8992 char *q;
8993 char c;
8994
8995 q = p;
8996 skip_whitespace (q);
8997
8998 c = *p;
8999 *p = '\0';
9000
9001 if (*q && !strncmp (q, ".req ", 5))
9002 {
9003 char *copy_of_str;
9004 char *r;
9005
9006 #ifdef IGNORE_OPCODE_CASE
9007 newname = original_case_string;
9008 #endif
9009 copy_of_str = newname;
9010
9011 q += 4;
9012 skip_whitespace (q);
9013
9014 for (r = q; *r != '\0'; r++)
9015 if (*r == ' ')
9016 break;
9017
9018 if (r != q)
9019 {
9020 enum arm_reg_type new_type, old_type;
9021 int old_regno;
9022 char d = *r;
9023
9024 *r = '\0';
9025 old_type = arm_reg_parse_any (q);
9026 *r = d;
9027
9028 new_type = arm_reg_parse_any (newname);
9029
9030 if (new_type == REG_TYPE_MAX)
9031 {
9032 if (old_type != REG_TYPE_MAX)
9033 {
9034 old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
9035 insert_reg_alias (newname, old_regno,
9036 all_reg_maps[old_type].htab);
9037 }
9038 else
9039 as_warn (_("register '%s' does not exist\n"), q);
9040 }
9041 else if (old_type == REG_TYPE_MAX)
9042 {
9043 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
9044 copy_of_str, q);
9045 }
9046 else
9047 {
9048 /* Do not warn about redefinitions to the same alias. */
9049 if (new_type != old_type
9050 || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
9051 != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
9052 as_warn (_("ignoring redefinition of register alias '%s'"),
9053 copy_of_str);
9054
9055 }
9056 }
9057 else
9058 as_warn (_("ignoring incomplete .req pseuso op"));
9059
9060 *p = c;
9061 return 1;
9062 }
9063 *p = c;
9064 return 0;
9065 }
9066
9067 static void
9068 set_constant_flonums ()
9069 {
9070 int i;
9071
9072 for (i = 0; i < NUM_FLOAT_VALS; i++)
9073 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
9074 abort ();
9075 }
9076
9077 /* Iterate over the base tables to create the instruction patterns. */
9078 static void
9079 build_arm_ops_hsh ()
9080 {
9081 unsigned int i;
9082 unsigned int j;
9083 static struct obstack insn_obstack;
9084
9085 obstack_begin (&insn_obstack, 4000);
9086
9087 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
9088 {
9089 const struct asm_opcode *insn = insns + i;
9090
9091 if (insn->cond_offset != 0)
9092 {
9093 /* Insn supports conditional execution. Build the varaints
9094 and insert them in the hash table. */
9095 for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
9096 {
9097 unsigned len = strlen (insn->template);
9098 struct asm_opcode *new;
9099 char *template;
9100
9101 new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
9102 /* All condition codes are two characters. */
9103 template = obstack_alloc (&insn_obstack, len + 3);
9104
9105 strncpy (template, insn->template, insn->cond_offset);
9106 strcpy (template + insn->cond_offset, conds[j].template);
9107 if (len > insn->cond_offset)
9108 strcpy (template + insn->cond_offset + 2,
9109 insn->template + insn->cond_offset);
9110 new->template = template;
9111 new->cond_offset = 0;
9112 new->variant = insn->variant;
9113 new->parms = insn->parms;
9114 new->value = (insn->value & ~COND_MASK) | conds[j].value;
9115
9116 hash_insert (arm_ops_hsh, new->template, (PTR) new);
9117 }
9118 }
9119 /* Finally, insert the unconditional insn in the table directly;
9120 no need to build a copy. */
9121 hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
9122 }
9123 }
9124
9125 void
9126 md_begin ()
9127 {
9128 unsigned mach;
9129 unsigned int i;
9130
9131 if ( (arm_ops_hsh = hash_new ()) == NULL
9132 || (arm_tops_hsh = hash_new ()) == NULL
9133 || (arm_cond_hsh = hash_new ()) == NULL
9134 || (arm_shift_hsh = hash_new ()) == NULL
9135 || (arm_psr_hsh = hash_new ()) == NULL)
9136 as_fatal (_("virtual memory exhausted"));
9137
9138 build_arm_ops_hsh ();
9139 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
9140 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
9141 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
9142 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
9143 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
9144 hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
9145 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
9146 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
9147
9148 for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
9149 build_reg_hsh (all_reg_maps + i);
9150
9151 set_constant_flonums ();
9152
9153 /* Set the cpu variant based on the command-line options. We prefer
9154 -mcpu= over -march= if both are set (as for GCC); and we prefer
9155 -mfpu= over any other way of setting the floating point unit.
9156 Use of legacy options with new options are faulted. */
9157 if (legacy_cpu != -1)
9158 {
9159 if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
9160 as_bad (_("use of old and new-style options to set CPU type"));
9161
9162 mcpu_cpu_opt = legacy_cpu;
9163 }
9164 else if (mcpu_cpu_opt == -1)
9165 mcpu_cpu_opt = march_cpu_opt;
9166
9167 if (legacy_fpu != -1)
9168 {
9169 if (mfpu_opt != -1)
9170 as_bad (_("use of old and new-style options to set FPU type"));
9171
9172 mfpu_opt = legacy_fpu;
9173 }
9174 else if (mfpu_opt == -1)
9175 {
9176 if (mcpu_fpu_opt != -1)
9177 mfpu_opt = mcpu_fpu_opt;
9178 else
9179 mfpu_opt = march_fpu_opt;
9180 }
9181
9182 if (mfpu_opt == -1)
9183 {
9184 if (mcpu_cpu_opt == -1)
9185 mfpu_opt = FPU_DEFAULT;
9186 else if (mcpu_cpu_opt & ARM_EXT_V5)
9187 mfpu_opt = FPU_ARCH_VFP_V2;
9188 else
9189 mfpu_opt = FPU_ARCH_FPA;
9190 }
9191
9192 if (mcpu_cpu_opt == -1)
9193 mcpu_cpu_opt = CPU_DEFAULT;
9194
9195 cpu_variant = mcpu_cpu_opt | mfpu_opt;
9196
9197 #if defined OBJ_COFF || defined OBJ_ELF
9198 {
9199 unsigned int flags = 0;
9200
9201 /* Set the flags in the private structure. */
9202 if (uses_apcs_26) flags |= F_APCS26;
9203 if (support_interwork) flags |= F_INTERWORK;
9204 if (uses_apcs_float) flags |= F_APCS_FLOAT;
9205 if (pic_code) flags |= F_PIC;
9206 if ((cpu_variant & FPU_ANY) == FPU_NONE
9207 || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only. */
9208 flags |= F_SOFT_FLOAT;
9209 /* Using VFP conventions (even if soft-float). */
9210 if (cpu_variant & FPU_VFP_EXT_NONE) flags |= F_VFP_FLOAT;
9211
9212
9213 bfd_set_private_flags (stdoutput, flags);
9214
9215 /* We have run out flags in the COFF header to encode the
9216 status of ATPCS support, so instead we create a dummy,
9217 empty, debug section called .arm.atpcs. */
9218 if (atpcs)
9219 {
9220 asection * sec;
9221
9222 sec = bfd_make_section (stdoutput, ".arm.atpcs");
9223
9224 if (sec != NULL)
9225 {
9226 bfd_set_section_flags
9227 (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
9228 bfd_set_section_size (stdoutput, sec, 0);
9229 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
9230 }
9231 }
9232 }
9233 #endif
9234
9235 /* Record the CPU type as well. */
9236 switch (cpu_variant & ARM_CPU_MASK)
9237 {
9238 case ARM_2:
9239 mach = bfd_mach_arm_2;
9240 break;
9241
9242 case ARM_3: /* Also ARM_250. */
9243 mach = bfd_mach_arm_2a;
9244 break;
9245
9246 case ARM_6: /* Also ARM_7. */
9247 mach = bfd_mach_arm_3;
9248 break;
9249
9250 default:
9251 mach = bfd_mach_arm_4;
9252 break;
9253 }
9254
9255 /* Catch special cases. */
9256 if (cpu_variant & ARM_CEXT_XSCALE)
9257 mach = bfd_mach_arm_XScale;
9258 else if (cpu_variant & ARM_EXT_V5E)
9259 mach = bfd_mach_arm_5TE;
9260 else if (cpu_variant & ARM_EXT_V5)
9261 {
9262 if (cpu_variant & ARM_EXT_V4T)
9263 mach = bfd_mach_arm_5T;
9264 else
9265 mach = bfd_mach_arm_5;
9266 }
9267 else if (cpu_variant & ARM_EXT_V4)
9268 {
9269 if (cpu_variant & ARM_EXT_V4T)
9270 mach = bfd_mach_arm_4T;
9271 else
9272 mach = bfd_mach_arm_4;
9273 }
9274 else if (cpu_variant & ARM_EXT_V3M)
9275 mach = bfd_mach_arm_3M;
9276
9277 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
9278 }
9279
9280 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
9281 for use in the a.out file, and stores them in the array pointed to by buf.
9282 This knows about the endian-ness of the target machine and does
9283 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
9284 2 (short) and 4 (long) Floating numbers are put out as a series of
9285 LITTLENUMS (shorts, here at least). */
9286
9287 void
9288 md_number_to_chars (buf, val, n)
9289 char * buf;
9290 valueT val;
9291 int n;
9292 {
9293 if (target_big_endian)
9294 number_to_chars_bigendian (buf, val, n);
9295 else
9296 number_to_chars_littleendian (buf, val, n);
9297 }
9298
9299 static valueT
9300 md_chars_to_number (buf, n)
9301 char * buf;
9302 int n;
9303 {
9304 valueT result = 0;
9305 unsigned char * where = (unsigned char *) buf;
9306
9307 if (target_big_endian)
9308 {
9309 while (n--)
9310 {
9311 result <<= 8;
9312 result |= (*where++ & 255);
9313 }
9314 }
9315 else
9316 {
9317 while (n--)
9318 {
9319 result <<= 8;
9320 result |= (where[n] & 255);
9321 }
9322 }
9323
9324 return result;
9325 }
9326
9327 /* Turn a string in input_line_pointer into a floating point constant
9328 of type TYPE, and store the appropriate bytes in *LITP. The number
9329 of LITTLENUMS emitted is stored in *SIZEP. An error message is
9330 returned, or NULL on OK.
9331
9332 Note that fp constants aren't represent in the normal way on the ARM.
9333 In big endian mode, things are as expected. However, in little endian
9334 mode fp constants are big-endian word-wise, and little-endian byte-wise
9335 within the words. For example, (double) 1.1 in big endian mode is
9336 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
9337 the byte sequence 99 99 f1 3f 9a 99 99 99.
9338
9339 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
9340
9341 char *
9342 md_atof (type, litP, sizeP)
9343 char type;
9344 char * litP;
9345 int * sizeP;
9346 {
9347 int prec;
9348 LITTLENUM_TYPE words[MAX_LITTLENUMS];
9349 char *t;
9350 int i;
9351
9352 switch (type)
9353 {
9354 case 'f':
9355 case 'F':
9356 case 's':
9357 case 'S':
9358 prec = 2;
9359 break;
9360
9361 case 'd':
9362 case 'D':
9363 case 'r':
9364 case 'R':
9365 prec = 4;
9366 break;
9367
9368 case 'x':
9369 case 'X':
9370 prec = 6;
9371 break;
9372
9373 case 'p':
9374 case 'P':
9375 prec = 6;
9376 break;
9377
9378 default:
9379 *sizeP = 0;
9380 return _("bad call to MD_ATOF()");
9381 }
9382
9383 t = atof_ieee (input_line_pointer, type, words);
9384 if (t)
9385 input_line_pointer = t;
9386 *sizeP = prec * 2;
9387
9388 if (target_big_endian)
9389 {
9390 for (i = 0; i < prec; i++)
9391 {
9392 md_number_to_chars (litP, (valueT) words[i], 2);
9393 litP += 2;
9394 }
9395 }
9396 else
9397 {
9398 if (cpu_variant & FPU_ARCH_VFP)
9399 for (i = prec - 1; i >= 0; i--)
9400 {
9401 md_number_to_chars (litP, (valueT) words[i], 2);
9402 litP += 2;
9403 }
9404 else
9405 /* For a 4 byte float the order of elements in `words' is 1 0.
9406 For an 8 byte float the order is 1 0 3 2. */
9407 for (i = 0; i < prec; i += 2)
9408 {
9409 md_number_to_chars (litP, (valueT) words[i + 1], 2);
9410 md_number_to_chars (litP + 2, (valueT) words[i], 2);
9411 litP += 4;
9412 }
9413 }
9414
9415 return 0;
9416 }
9417
9418 /* The knowledge of the PC's pipeline offset is built into the insns
9419 themselves. */
9420
9421 long
9422 md_pcrel_from (fixP)
9423 fixS * fixP;
9424 {
9425 if (fixP->fx_addsy
9426 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
9427 && fixP->fx_subsy == NULL)
9428 return 0;
9429
9430 if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
9431 {
9432 /* PC relative addressing on the Thumb is slightly odd
9433 as the bottom two bits of the PC are forced to zero
9434 for the calculation. */
9435 return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
9436 }
9437
9438 #ifdef TE_WINCE
9439 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
9440 so we un-adjust here to compensate for the accomodation. */
9441 return fixP->fx_where + fixP->fx_frag->fr_address + 8;
9442 #else
9443 return fixP->fx_where + fixP->fx_frag->fr_address;
9444 #endif
9445 }
9446
9447 /* Round up a section size to the appropriate boundary. */
9448
9449 valueT
9450 md_section_align (segment, size)
9451 segT segment ATTRIBUTE_UNUSED;
9452 valueT size;
9453 {
9454 #ifdef OBJ_ELF
9455 return size;
9456 #else
9457 /* Round all sects to multiple of 4. */
9458 return (size + 3) & ~3;
9459 #endif
9460 }
9461
9462 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
9463 Otherwise we have no need to default values of symbols. */
9464
9465 symbolS *
9466 md_undefined_symbol (name)
9467 char * name ATTRIBUTE_UNUSED;
9468 {
9469 #ifdef OBJ_ELF
9470 if (name[0] == '_' && name[1] == 'G'
9471 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
9472 {
9473 if (!GOT_symbol)
9474 {
9475 if (symbol_find (name))
9476 as_bad ("GOT already in the symbol table");
9477
9478 GOT_symbol = symbol_new (name, undefined_section,
9479 (valueT) 0, & zero_address_frag);
9480 }
9481
9482 return GOT_symbol;
9483 }
9484 #endif
9485
9486 return 0;
9487 }
9488
9489 /* arm_reg_parse () := if it looks like a register, return its token and
9490 advance the pointer. */
9491
9492 static int
9493 arm_reg_parse (ccp, htab)
9494 register char ** ccp;
9495 struct hash_control *htab;
9496 {
9497 char * start = * ccp;
9498 char c;
9499 char * p;
9500 struct reg_entry * reg;
9501
9502 #ifdef REGISTER_PREFIX
9503 if (*start != REGISTER_PREFIX)
9504 return FAIL;
9505 p = start + 1;
9506 #else
9507 p = start;
9508 #ifdef OPTIONAL_REGISTER_PREFIX
9509 if (*p == OPTIONAL_REGISTER_PREFIX)
9510 p++, start++;
9511 #endif
9512 #endif
9513 if (!ISALPHA (*p) || !is_name_beginner (*p))
9514 return FAIL;
9515
9516 c = *p++;
9517 while (ISALPHA (c) || ISDIGIT (c) || c == '_')
9518 c = *p++;
9519
9520 *--p = 0;
9521 reg = (struct reg_entry *) hash_find (htab, start);
9522 *p = c;
9523
9524 if (reg)
9525 {
9526 *ccp = p;
9527 return reg->number;
9528 }
9529
9530 return FAIL;
9531 }
9532
9533 /* Search for the following register name in each of the possible reg name
9534 tables. Return the classification if found, or REG_TYPE_MAX if not
9535 present. */
9536 static enum arm_reg_type
9537 arm_reg_parse_any (cp)
9538 char *cp;
9539 {
9540 int i;
9541
9542 for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
9543 if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
9544 return (enum arm_reg_type) i;
9545
9546 return REG_TYPE_MAX;
9547 }
9548
9549 void
9550 md_apply_fix3 (fixP, valP, seg)
9551 fixS * fixP;
9552 valueT * valP;
9553 segT seg;
9554 {
9555 offsetT value = * valP;
9556 offsetT newval;
9557 unsigned int newimm;
9558 unsigned long temp;
9559 int sign;
9560 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
9561 arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
9562
9563 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
9564
9565 /* Note whether this will delete the relocation. */
9566 #if 0
9567 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
9568 doesn't work fully.) */
9569 if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
9570 && !fixP->fx_pcrel)
9571 #else
9572 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
9573 #endif
9574 fixP->fx_done = 1;
9575
9576 /* If this symbol is in a different section then we need to leave it for
9577 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
9578 so we have to undo it's effects here. */
9579 if (fixP->fx_pcrel)
9580 {
9581 if (fixP->fx_addsy != NULL
9582 && S_IS_DEFINED (fixP->fx_addsy)
9583 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
9584 {
9585 if (target_oabi
9586 && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
9587 || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
9588 ))
9589 value = 0;
9590 else
9591 value += md_pcrel_from (fixP);
9592 }
9593 }
9594
9595 /* Remember value for emit_reloc. */
9596 fixP->fx_addnumber = value;
9597
9598 switch (fixP->fx_r_type)
9599 {
9600 case BFD_RELOC_ARM_IMMEDIATE:
9601 newimm = validate_immediate (value);
9602 temp = md_chars_to_number (buf, INSN_SIZE);
9603
9604 /* If the instruction will fail, see if we can fix things up by
9605 changing the opcode. */
9606 if (newimm == (unsigned int) FAIL
9607 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
9608 {
9609 as_bad_where (fixP->fx_file, fixP->fx_line,
9610 _("invalid constant (%lx) after fixup"),
9611 (unsigned long) value);
9612 break;
9613 }
9614
9615 newimm |= (temp & 0xfffff000);
9616 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
9617 break;
9618
9619 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
9620 {
9621 unsigned int highpart = 0;
9622 unsigned int newinsn = 0xe1a00000; /* nop. */
9623 newimm = validate_immediate (value);
9624 temp = md_chars_to_number (buf, INSN_SIZE);
9625
9626 /* If the instruction will fail, see if we can fix things up by
9627 changing the opcode. */
9628 if (newimm == (unsigned int) FAIL
9629 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
9630 {
9631 /* No ? OK - try using two ADD instructions to generate
9632 the value. */
9633 newimm = validate_immediate_twopart (value, & highpart);
9634
9635 /* Yes - then make sure that the second instruction is
9636 also an add. */
9637 if (newimm != (unsigned int) FAIL)
9638 newinsn = temp;
9639 /* Still No ? Try using a negated value. */
9640 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
9641 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
9642 /* Otherwise - give up. */
9643 else
9644 {
9645 as_bad_where (fixP->fx_file, fixP->fx_line,
9646 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
9647 value);
9648 break;
9649 }
9650
9651 /* Replace the first operand in the 2nd instruction (which
9652 is the PC) with the destination register. We have
9653 already added in the PC in the first instruction and we
9654 do not want to do it again. */
9655 newinsn &= ~ 0xf0000;
9656 newinsn |= ((newinsn & 0x0f000) << 4);
9657 }
9658
9659 newimm |= (temp & 0xfffff000);
9660 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
9661
9662 highpart |= (newinsn & 0xfffff000);
9663 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
9664 }
9665 break;
9666
9667 case BFD_RELOC_ARM_OFFSET_IMM:
9668 sign = value >= 0;
9669
9670 if (value < 0)
9671 value = - value;
9672
9673 if (validate_offset_imm (value, 0) == FAIL)
9674 {
9675 as_bad_where (fixP->fx_file, fixP->fx_line,
9676 _("bad immediate value for offset (%ld)"),
9677 (long) value);
9678 break;
9679 }
9680
9681 newval = md_chars_to_number (buf, INSN_SIZE);
9682 newval &= 0xff7ff000;
9683 newval |= value | (sign ? INDEX_UP : 0);
9684 md_number_to_chars (buf, newval, INSN_SIZE);
9685 break;
9686
9687 case BFD_RELOC_ARM_OFFSET_IMM8:
9688 case BFD_RELOC_ARM_HWLITERAL:
9689 sign = value >= 0;
9690
9691 if (value < 0)
9692 value = - value;
9693
9694 if (validate_offset_imm (value, 1) == FAIL)
9695 {
9696 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
9697 as_bad_where (fixP->fx_file, fixP->fx_line,
9698 _("invalid literal constant: pool needs to be closer"));
9699 else
9700 as_bad (_("bad immediate value for half-word offset (%ld)"),
9701 (long) value);
9702 break;
9703 }
9704
9705 newval = md_chars_to_number (buf, INSN_SIZE);
9706 newval &= 0xff7ff0f0;
9707 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
9708 md_number_to_chars (buf, newval, INSN_SIZE);
9709 break;
9710
9711 case BFD_RELOC_ARM_LITERAL:
9712 sign = value >= 0;
9713
9714 if (value < 0)
9715 value = - value;
9716
9717 if (validate_offset_imm (value, 0) == FAIL)
9718 {
9719 as_bad_where (fixP->fx_file, fixP->fx_line,
9720 _("invalid literal constant: pool needs to be closer"));
9721 break;
9722 }
9723
9724 newval = md_chars_to_number (buf, INSN_SIZE);
9725 newval &= 0xff7ff000;
9726 newval |= value | (sign ? INDEX_UP : 0);
9727 md_number_to_chars (buf, newval, INSN_SIZE);
9728 break;
9729
9730 case BFD_RELOC_ARM_SHIFT_IMM:
9731 newval = md_chars_to_number (buf, INSN_SIZE);
9732 if (((unsigned long) value) > 32
9733 || (value == 32
9734 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
9735 {
9736 as_bad_where (fixP->fx_file, fixP->fx_line,
9737 _("shift expression is too large"));
9738 break;
9739 }
9740
9741 if (value == 0)
9742 /* Shifts of zero must be done as lsl. */
9743 newval &= ~0x60;
9744 else if (value == 32)
9745 value = 0;
9746 newval &= 0xfffff07f;
9747 newval |= (value & 0x1f) << 7;
9748 md_number_to_chars (buf, newval, INSN_SIZE);
9749 break;
9750
9751 case BFD_RELOC_ARM_SWI:
9752 if (arm_data->thumb_mode)
9753 {
9754 if (((unsigned long) value) > 0xff)
9755 as_bad_where (fixP->fx_file, fixP->fx_line,
9756 _("invalid swi expression"));
9757 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
9758 newval |= value;
9759 md_number_to_chars (buf, newval, THUMB_SIZE);
9760 }
9761 else
9762 {
9763 if (((unsigned long) value) > 0x00ffffff)
9764 as_bad_where (fixP->fx_file, fixP->fx_line,
9765 _("invalid swi expression"));
9766 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
9767 newval |= value;
9768 md_number_to_chars (buf, newval, INSN_SIZE);
9769 }
9770 break;
9771
9772 case BFD_RELOC_ARM_MULTI:
9773 if (((unsigned long) value) > 0xffff)
9774 as_bad_where (fixP->fx_file, fixP->fx_line,
9775 _("invalid expression in load/store multiple"));
9776 newval = value | md_chars_to_number (buf, INSN_SIZE);
9777 md_number_to_chars (buf, newval, INSN_SIZE);
9778 break;
9779
9780 case BFD_RELOC_ARM_PCREL_BRANCH:
9781 newval = md_chars_to_number (buf, INSN_SIZE);
9782
9783 /* Sign-extend a 24-bit number. */
9784 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
9785
9786 #ifdef OBJ_ELF
9787 if (! target_oabi)
9788 value = fixP->fx_offset;
9789 #endif
9790
9791 /* We are going to store value (shifted right by two) in the
9792 instruction, in a 24 bit, signed field. Thus we need to check
9793 that none of the top 8 bits of the shifted value (top 7 bits of
9794 the unshifted, unsigned value) are set, or that they are all set. */
9795 if ((value & ~ ((offsetT) 0x1ffffff)) != 0
9796 && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
9797 {
9798 #ifdef OBJ_ELF
9799 /* Normally we would be stuck at this point, since we cannot store
9800 the absolute address that is the destination of the branch in the
9801 24 bits of the branch instruction. If however, we happen to know
9802 that the destination of the branch is in the same section as the
9803 branch instruciton itself, then we can compute the relocation for
9804 ourselves and not have to bother the linker with it.
9805
9806 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
9807 because I have not worked out how to do this for OBJ_COFF or
9808 target_oabi. */
9809 if (! target_oabi
9810 && fixP->fx_addsy != NULL
9811 && S_IS_DEFINED (fixP->fx_addsy)
9812 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
9813 {
9814 /* Get pc relative value to go into the branch. */
9815 value = * valP;
9816
9817 /* Permit a backward branch provided that enough bits
9818 are set. Allow a forwards branch, provided that
9819 enough bits are clear. */
9820 if ( (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
9821 || (value & ~ ((offsetT) 0x1ffffff)) == 0)
9822 fixP->fx_done = 1;
9823 }
9824
9825 if (! fixP->fx_done)
9826 #endif
9827 as_bad_where (fixP->fx_file, fixP->fx_line,
9828 _("GAS can't handle same-section branch dest >= 0x04000000"));
9829 }
9830
9831 value >>= 2;
9832 value += SEXT24 (newval);
9833
9834 if ( (value & ~ ((offsetT) 0xffffff)) != 0
9835 && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
9836 as_bad_where (fixP->fx_file, fixP->fx_line,
9837 _("out of range branch"));
9838
9839 newval = (value & 0x00ffffff) | (newval & 0xff000000);
9840 md_number_to_chars (buf, newval, INSN_SIZE);
9841 break;
9842
9843 case BFD_RELOC_ARM_PCREL_BLX:
9844 {
9845 offsetT hbit;
9846 newval = md_chars_to_number (buf, INSN_SIZE);
9847
9848 #ifdef OBJ_ELF
9849 if (! target_oabi)
9850 value = fixP->fx_offset;
9851 #endif
9852 hbit = (value >> 1) & 1;
9853 value = (value >> 2) & 0x00ffffff;
9854 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
9855 newval = value | (newval & 0xfe000000) | (hbit << 24);
9856 md_number_to_chars (buf, newval, INSN_SIZE);
9857 }
9858 break;
9859
9860 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
9861 newval = md_chars_to_number (buf, THUMB_SIZE);
9862 {
9863 addressT diff = (newval & 0xff) << 1;
9864 if (diff & 0x100)
9865 diff |= ~0xff;
9866
9867 value += diff;
9868 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
9869 as_bad_where (fixP->fx_file, fixP->fx_line,
9870 _("branch out of range"));
9871 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
9872 }
9873 md_number_to_chars (buf, newval, THUMB_SIZE);
9874 break;
9875
9876 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
9877 newval = md_chars_to_number (buf, THUMB_SIZE);
9878 {
9879 addressT diff = (newval & 0x7ff) << 1;
9880 if (diff & 0x800)
9881 diff |= ~0x7ff;
9882
9883 value += diff;
9884 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
9885 as_bad_where (fixP->fx_file, fixP->fx_line,
9886 _("branch out of range"));
9887 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
9888 }
9889 md_number_to_chars (buf, newval, THUMB_SIZE);
9890 break;
9891
9892 case BFD_RELOC_THUMB_PCREL_BLX:
9893 case BFD_RELOC_THUMB_PCREL_BRANCH23:
9894 {
9895 offsetT newval2;
9896 addressT diff;
9897
9898 newval = md_chars_to_number (buf, THUMB_SIZE);
9899 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
9900 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
9901 if (diff & 0x400000)
9902 diff |= ~0x3fffff;
9903 #ifdef OBJ_ELF
9904 value = fixP->fx_offset;
9905 #endif
9906 value += diff;
9907 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
9908 as_bad_where (fixP->fx_file, fixP->fx_line,
9909 _("branch with link out of range"));
9910
9911 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
9912 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
9913 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
9914 /* Remove bit zero of the adjusted offset. Bit zero can only be
9915 set if the upper insn is at a half-word boundary, since the
9916 destination address, an ARM instruction, must always be on a
9917 word boundary. The semantics of the BLX (1) instruction, however,
9918 are that bit zero in the offset must always be zero, and the
9919 corresponding bit one in the target address will be set from bit
9920 one of the source address. */
9921 newval2 &= ~1;
9922 md_number_to_chars (buf, newval, THUMB_SIZE);
9923 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
9924 }
9925 break;
9926
9927 case BFD_RELOC_8:
9928 if (fixP->fx_done || fixP->fx_pcrel)
9929 md_number_to_chars (buf, value, 1);
9930 #ifdef OBJ_ELF
9931 else if (!target_oabi)
9932 {
9933 value = fixP->fx_offset;
9934 md_number_to_chars (buf, value, 1);
9935 }
9936 #endif
9937 break;
9938
9939 case BFD_RELOC_16:
9940 if (fixP->fx_done || fixP->fx_pcrel)
9941 md_number_to_chars (buf, value, 2);
9942 #ifdef OBJ_ELF
9943 else if (!target_oabi)
9944 {
9945 value = fixP->fx_offset;
9946 md_number_to_chars (buf, value, 2);
9947 }
9948 #endif
9949 break;
9950
9951 #ifdef OBJ_ELF
9952 case BFD_RELOC_ARM_GOT32:
9953 case BFD_RELOC_ARM_GOTOFF:
9954 md_number_to_chars (buf, 0, 4);
9955 break;
9956 #endif
9957
9958 case BFD_RELOC_RVA:
9959 case BFD_RELOC_32:
9960 if (fixP->fx_done || fixP->fx_pcrel)
9961 md_number_to_chars (buf, value, 4);
9962 #ifdef OBJ_ELF
9963 else if (!target_oabi)
9964 {
9965 value = fixP->fx_offset;
9966 md_number_to_chars (buf, value, 4);
9967 }
9968 #endif
9969 break;
9970
9971 #ifdef OBJ_ELF
9972 case BFD_RELOC_ARM_PLT32:
9973 /* It appears the instruction is fully prepared at this point. */
9974 break;
9975 #endif
9976
9977 case BFD_RELOC_ARM_GOTPC:
9978 md_number_to_chars (buf, value, 4);
9979 break;
9980
9981 case BFD_RELOC_ARM_CP_OFF_IMM:
9982 sign = value >= 0;
9983 if (value < -1023 || value > 1023 || (value & 3))
9984 as_bad_where (fixP->fx_file, fixP->fx_line,
9985 _("illegal value for co-processor offset"));
9986 if (value < 0)
9987 value = -value;
9988 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
9989 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
9990 md_number_to_chars (buf, newval, INSN_SIZE);
9991 break;
9992
9993 case BFD_RELOC_ARM_THUMB_OFFSET:
9994 newval = md_chars_to_number (buf, THUMB_SIZE);
9995 /* Exactly what ranges, and where the offset is inserted depends
9996 on the type of instruction, we can establish this from the
9997 top 4 bits. */
9998 switch (newval >> 12)
9999 {
10000 case 4: /* PC load. */
10001 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
10002 forced to zero for these loads, so we will need to round
10003 up the offset if the instruction address is not word
10004 aligned (since the final address produced must be, and
10005 we can only describe word-aligned immediate offsets). */
10006
10007 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
10008 as_bad_where (fixP->fx_file, fixP->fx_line,
10009 _("invalid offset, target not word aligned (0x%08X)"),
10010 (unsigned int) (fixP->fx_frag->fr_address
10011 + fixP->fx_where + value));
10012
10013 if ((value + 2) & ~0x3fe)
10014 as_bad_where (fixP->fx_file, fixP->fx_line,
10015 _("invalid offset, value too big (0x%08lX)"), value);
10016
10017 /* Round up, since pc will be rounded down. */
10018 newval |= (value + 2) >> 2;
10019 break;
10020
10021 case 9: /* SP load/store. */
10022 if (value & ~0x3fc)
10023 as_bad_where (fixP->fx_file, fixP->fx_line,
10024 _("invalid offset, value too big (0x%08lX)"), value);
10025 newval |= value >> 2;
10026 break;
10027
10028 case 6: /* Word load/store. */
10029 if (value & ~0x7c)
10030 as_bad_where (fixP->fx_file, fixP->fx_line,
10031 _("invalid offset, value too big (0x%08lX)"), value);
10032 newval |= value << 4; /* 6 - 2. */
10033 break;
10034
10035 case 7: /* Byte load/store. */
10036 if (value & ~0x1f)
10037 as_bad_where (fixP->fx_file, fixP->fx_line,
10038 _("invalid offset, value too big (0x%08lX)"), value);
10039 newval |= value << 6;
10040 break;
10041
10042 case 8: /* Halfword load/store. */
10043 if (value & ~0x3e)
10044 as_bad_where (fixP->fx_file, fixP->fx_line,
10045 _("invalid offset, value too big (0x%08lX)"), value);
10046 newval |= value << 5; /* 6 - 1. */
10047 break;
10048
10049 default:
10050 as_bad_where (fixP->fx_file, fixP->fx_line,
10051 "Unable to process relocation for thumb opcode: %lx",
10052 (unsigned long) newval);
10053 break;
10054 }
10055 md_number_to_chars (buf, newval, THUMB_SIZE);
10056 break;
10057
10058 case BFD_RELOC_ARM_THUMB_ADD:
10059 /* This is a complicated relocation, since we use it for all of
10060 the following immediate relocations:
10061
10062 3bit ADD/SUB
10063 8bit ADD/SUB
10064 9bit ADD/SUB SP word-aligned
10065 10bit ADD PC/SP word-aligned
10066
10067 The type of instruction being processed is encoded in the
10068 instruction field:
10069
10070 0x8000 SUB
10071 0x00F0 Rd
10072 0x000F Rs
10073 */
10074 newval = md_chars_to_number (buf, THUMB_SIZE);
10075 {
10076 int rd = (newval >> 4) & 0xf;
10077 int rs = newval & 0xf;
10078 int subtract = newval & 0x8000;
10079
10080 if (rd == REG_SP)
10081 {
10082 if (value & ~0x1fc)
10083 as_bad_where (fixP->fx_file, fixP->fx_line,
10084 _("invalid immediate for stack address calculation"));
10085 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
10086 newval |= value >> 2;
10087 }
10088 else if (rs == REG_PC || rs == REG_SP)
10089 {
10090 if (subtract ||
10091 value & ~0x3fc)
10092 as_bad_where (fixP->fx_file, fixP->fx_line,
10093 _("invalid immediate for address calculation (value = 0x%08lX)"),
10094 (unsigned long) value);
10095 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
10096 newval |= rd << 8;
10097 newval |= value >> 2;
10098 }
10099 else if (rs == rd)
10100 {
10101 if (value & ~0xff)
10102 as_bad_where (fixP->fx_file, fixP->fx_line,
10103 _("invalid 8bit immediate"));
10104 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
10105 newval |= (rd << 8) | value;
10106 }
10107 else
10108 {
10109 if (value & ~0x7)
10110 as_bad_where (fixP->fx_file, fixP->fx_line,
10111 _("invalid 3bit immediate"));
10112 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
10113 newval |= rd | (rs << 3) | (value << 6);
10114 }
10115 }
10116 md_number_to_chars (buf, newval, THUMB_SIZE);
10117 break;
10118
10119 case BFD_RELOC_ARM_THUMB_IMM:
10120 newval = md_chars_to_number (buf, THUMB_SIZE);
10121 switch (newval >> 11)
10122 {
10123 case 0x04: /* 8bit immediate MOV. */
10124 case 0x05: /* 8bit immediate CMP. */
10125 if (value < 0 || value > 255)
10126 as_bad_where (fixP->fx_file, fixP->fx_line,
10127 _("invalid immediate: %ld is too large"),
10128 (long) value);
10129 newval |= value;
10130 break;
10131
10132 default:
10133 abort ();
10134 }
10135 md_number_to_chars (buf, newval, THUMB_SIZE);
10136 break;
10137
10138 case BFD_RELOC_ARM_THUMB_SHIFT:
10139 /* 5bit shift value (0..31). */
10140 if (value < 0 || value > 31)
10141 as_bad_where (fixP->fx_file, fixP->fx_line,
10142 _("illegal Thumb shift value: %ld"), (long) value);
10143 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
10144 newval |= value << 6;
10145 md_number_to_chars (buf, newval, THUMB_SIZE);
10146 break;
10147
10148 case BFD_RELOC_VTABLE_INHERIT:
10149 case BFD_RELOC_VTABLE_ENTRY:
10150 fixP->fx_done = 0;
10151 return;
10152
10153 case BFD_RELOC_NONE:
10154 default:
10155 as_bad_where (fixP->fx_file, fixP->fx_line,
10156 _("bad relocation fixup type (%d)"), fixP->fx_r_type);
10157 }
10158 }
10159
10160 /* Translate internal representation of relocation info to BFD target
10161 format. */
10162
10163 arelent *
10164 tc_gen_reloc (section, fixp)
10165 asection * section ATTRIBUTE_UNUSED;
10166 fixS * fixp;
10167 {
10168 arelent * reloc;
10169 bfd_reloc_code_real_type code;
10170
10171 reloc = (arelent *) xmalloc (sizeof (arelent));
10172
10173 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
10174 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
10175 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
10176
10177 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
10178 #ifndef OBJ_ELF
10179 if (fixp->fx_pcrel == 0)
10180 reloc->addend = fixp->fx_offset;
10181 else
10182 reloc->addend = fixp->fx_offset = reloc->address;
10183 #else /* OBJ_ELF */
10184 reloc->addend = fixp->fx_offset;
10185 #endif
10186
10187 switch (fixp->fx_r_type)
10188 {
10189 case BFD_RELOC_8:
10190 if (fixp->fx_pcrel)
10191 {
10192 code = BFD_RELOC_8_PCREL;
10193 break;
10194 }
10195
10196 case BFD_RELOC_16:
10197 if (fixp->fx_pcrel)
10198 {
10199 code = BFD_RELOC_16_PCREL;
10200 break;
10201 }
10202
10203 case BFD_RELOC_32:
10204 if (fixp->fx_pcrel)
10205 {
10206 code = BFD_RELOC_32_PCREL;
10207 break;
10208 }
10209
10210 case BFD_RELOC_ARM_PCREL_BRANCH:
10211 case BFD_RELOC_ARM_PCREL_BLX:
10212 case BFD_RELOC_RVA:
10213 case BFD_RELOC_THUMB_PCREL_BRANCH9:
10214 case BFD_RELOC_THUMB_PCREL_BRANCH12:
10215 case BFD_RELOC_THUMB_PCREL_BRANCH23:
10216 case BFD_RELOC_THUMB_PCREL_BLX:
10217 case BFD_RELOC_VTABLE_ENTRY:
10218 case BFD_RELOC_VTABLE_INHERIT:
10219 code = fixp->fx_r_type;
10220 break;
10221
10222 case BFD_RELOC_ARM_LITERAL:
10223 case BFD_RELOC_ARM_HWLITERAL:
10224 /* If this is called then the a literal has been referenced across
10225 a section boundary - possibly due to an implicit dump. */
10226 as_bad_where (fixp->fx_file, fixp->fx_line,
10227 _("literal referenced across section boundary (Implicit dump?)"));
10228 return NULL;
10229
10230 #ifdef OBJ_ELF
10231 case BFD_RELOC_ARM_GOT32:
10232 case BFD_RELOC_ARM_GOTOFF:
10233 case BFD_RELOC_ARM_PLT32:
10234 code = fixp->fx_r_type;
10235 break;
10236 #endif
10237
10238 case BFD_RELOC_ARM_IMMEDIATE:
10239 as_bad_where (fixp->fx_file, fixp->fx_line,
10240 _("internal relocation (type %d) not fixed up (IMMEDIATE)"),
10241 fixp->fx_r_type);
10242 return NULL;
10243
10244 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
10245 as_bad_where (fixp->fx_file, fixp->fx_line,
10246 _("ADRL used for a symbol not defined in the same file"));
10247 return NULL;
10248
10249 case BFD_RELOC_ARM_OFFSET_IMM:
10250 as_bad_where (fixp->fx_file, fixp->fx_line,
10251 _("internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
10252 fixp->fx_r_type);
10253 return NULL;
10254
10255 default:
10256 {
10257 char * type;
10258
10259 switch (fixp->fx_r_type)
10260 {
10261 case BFD_RELOC_ARM_IMMEDIATE: type = "IMMEDIATE"; break;
10262 case BFD_RELOC_ARM_OFFSET_IMM: type = "OFFSET_IMM"; break;
10263 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
10264 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
10265 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
10266 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
10267 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
10268 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
10269 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
10270 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
10271 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
10272 default: type = _("<unknown>"); break;
10273 }
10274 as_bad_where (fixp->fx_file, fixp->fx_line,
10275 _("cannot represent %s relocation in this object file format"),
10276 type);
10277 return NULL;
10278 }
10279 }
10280
10281 #ifdef OBJ_ELF
10282 if (code == BFD_RELOC_32_PCREL
10283 && GOT_symbol
10284 && fixp->fx_addsy == GOT_symbol)
10285 {
10286 code = BFD_RELOC_ARM_GOTPC;
10287 reloc->addend = fixp->fx_offset = reloc->address;
10288 }
10289 #endif
10290
10291 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
10292
10293 if (reloc->howto == NULL)
10294 {
10295 as_bad_where (fixp->fx_file, fixp->fx_line,
10296 _("cannot represent %s relocation in this object file format"),
10297 bfd_get_reloc_code_name (code));
10298 return NULL;
10299 }
10300
10301 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
10302 vtable entry to be used in the relocation's section offset. */
10303 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
10304 reloc->address = fixp->fx_offset;
10305
10306 return reloc;
10307 }
10308
10309 int
10310 md_estimate_size_before_relax (fragP, segtype)
10311 fragS * fragP ATTRIBUTE_UNUSED;
10312 segT segtype ATTRIBUTE_UNUSED;
10313 {
10314 as_fatal (_("md_estimate_size_before_relax\n"));
10315 return 1;
10316 }
10317
10318 static void
10319 output_inst (str)
10320 const char *str;
10321 {
10322 char * to = NULL;
10323
10324 if (inst.error)
10325 {
10326 as_bad ("%s -- `%s'", inst.error, str);
10327 return;
10328 }
10329
10330 to = frag_more (inst.size);
10331
10332 if (thumb_mode && (inst.size > THUMB_SIZE))
10333 {
10334 assert (inst.size == (2 * THUMB_SIZE));
10335 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
10336 md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
10337 }
10338 else if (inst.size > INSN_SIZE)
10339 {
10340 assert (inst.size == (2 * INSN_SIZE));
10341 md_number_to_chars (to, inst.instruction, INSN_SIZE);
10342 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
10343 }
10344 else
10345 md_number_to_chars (to, inst.instruction, inst.size);
10346
10347 if (inst.reloc.type != BFD_RELOC_NONE)
10348 fix_new_arm (frag_now, to - frag_now->fr_literal,
10349 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
10350 inst.reloc.type);
10351
10352 #ifdef OBJ_ELF
10353 dwarf2_emit_insn (inst.size);
10354 #endif
10355 }
10356
10357 void
10358 md_assemble (str)
10359 char * str;
10360 {
10361 char c;
10362 char *p;
10363 char *start;
10364
10365 /* Align the instruction.
10366 This may not be the right thing to do but ... */
10367 #if 0
10368 arm_align (2, 0);
10369 #endif
10370 listing_prev_line (); /* Defined in listing.h. */
10371
10372 /* Align the previous label if needed. */
10373 if (last_label_seen != NULL)
10374 {
10375 symbol_set_frag (last_label_seen, frag_now);
10376 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
10377 S_SET_SEGMENT (last_label_seen, now_seg);
10378 }
10379
10380 memset (&inst, '\0', sizeof (inst));
10381 inst.reloc.type = BFD_RELOC_NONE;
10382
10383 skip_whitespace (str);
10384
10385 /* Scan up to the end of the op-code, which must end in white space or
10386 end of string. */
10387 for (start = p = str; *p != '\0'; p++)
10388 if (*p == ' ')
10389 break;
10390
10391 if (p == str)
10392 {
10393 as_bad (_("no operator -- statement `%s'\n"), str);
10394 return;
10395 }
10396
10397 if (thumb_mode)
10398 {
10399 const struct thumb_opcode * opcode;
10400
10401 c = *p;
10402 *p = '\0';
10403 opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
10404 *p = c;
10405
10406 if (opcode)
10407 {
10408 /* Check that this instruction is supported for this CPU. */
10409 if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
10410 {
10411 as_bad (_("selected processor does not support `%s'"), str);
10412 return;
10413 }
10414
10415 inst.instruction = opcode->value;
10416 inst.size = opcode->size;
10417 (*opcode->parms) (p);
10418 output_inst (str);
10419 return;
10420 }
10421 }
10422 else
10423 {
10424 const struct asm_opcode * opcode;
10425
10426 c = *p;
10427 *p = '\0';
10428 opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
10429 *p = c;
10430
10431 if (opcode)
10432 {
10433 /* Check that this instruction is supported for this CPU. */
10434 if ((opcode->variant & cpu_variant) == 0)
10435 {
10436 as_bad (_("selected processor does not support `%s'"), str);
10437 return;
10438 }
10439
10440 inst.instruction = opcode->value;
10441 inst.size = INSN_SIZE;
10442 (*opcode->parms) (p);
10443 output_inst (str);
10444 return;
10445 }
10446 }
10447
10448 /* It wasn't an instruction, but it might be a register alias of the form
10449 alias .req reg. */
10450 if (create_register_alias (str, p))
10451 return;
10452
10453 as_bad (_("bad instruction `%s'"), start);
10454 }
10455
10456 /* md_parse_option
10457 Invocation line includes a switch not recognized by the base assembler.
10458 See if it's a processor-specific option.
10459
10460 This routine is somewhat complicated by the need for backwards
10461 compatibility (since older releases of gcc can't be changed).
10462 The new options try to make the interface as compatible as
10463 possible with GCC.
10464
10465 New options (supported) are:
10466
10467 -mcpu=<cpu name> Assemble for selected processor
10468 -march=<architecture name> Assemble for selected architecture
10469 -mfpu=<fpu architecture> Assemble for selected FPU.
10470 -EB/-mbig-endian Big-endian
10471 -EL/-mlittle-endian Little-endian
10472 -k Generate PIC code
10473 -mthumb Start in Thumb mode
10474 -mthumb-interwork Code supports ARM/Thumb interworking
10475
10476 For now we will also provide support for
10477
10478 -mapcs-32 32-bit Program counter
10479 -mapcs-26 26-bit Program counter
10480 -macps-float Floats passed in FP registers
10481 -mapcs-reentrant Reentrant code
10482 -matpcs
10483 (sometime these will probably be replaced with -mapcs=<list of options>
10484 and -matpcs=<list of options>)
10485
10486 The remaining options are only supported for back-wards compatibility.
10487 Cpu variants, the arm part is optional:
10488 -m[arm]1 Currently not supported.
10489 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
10490 -m[arm]3 Arm 3 processor
10491 -m[arm]6[xx], Arm 6 processors
10492 -m[arm]7[xx][t][[d]m] Arm 7 processors
10493 -m[arm]8[10] Arm 8 processors
10494 -m[arm]9[20][tdmi] Arm 9 processors
10495 -marm9e Allow Cirrus/DSP instructions
10496 -mstrongarm[110[0]] StrongARM processors
10497 -mxscale XScale processors
10498 -m[arm]v[2345[t[e]]] Arm architectures
10499 -mall All (except the ARM1)
10500 FP variants:
10501 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
10502 -mfpe-old (No float load/store multiples)
10503 -mvfpxd VFP Single precision
10504 -mvfp All VFP
10505 -mno-fpu Disable all floating point instructions
10506
10507 The following CPU names are recognized:
10508 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
10509 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
10510 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
10511 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
10512 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
10513 arm10t arm10e, arm1020t, arm1020e, arm10200e,
10514 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
10515
10516 */
10517
10518 CONST char * md_shortopts = "m:k";
10519
10520 #ifdef ARM_BI_ENDIAN
10521 #define OPTION_EB (OPTION_MD_BASE + 0)
10522 #define OPTION_EL (OPTION_MD_BASE + 1)
10523 #else
10524 #if TARGET_BYTES_BIG_ENDIAN
10525 #define OPTION_EB (OPTION_MD_BASE + 0)
10526 #else
10527 #define OPTION_EL (OPTION_MD_BASE + 1)
10528 #endif
10529 #endif
10530
10531 struct option md_longopts[] =
10532 {
10533 #ifdef OPTION_EB
10534 {"EB", no_argument, NULL, OPTION_EB},
10535 #endif
10536 #ifdef OPTION_EL
10537 {"EL", no_argument, NULL, OPTION_EL},
10538 #endif
10539 {NULL, no_argument, NULL, 0}
10540 };
10541
10542 size_t md_longopts_size = sizeof (md_longopts);
10543
10544 struct arm_option_table
10545 {
10546 char *option; /* Option name to match. */
10547 char *help; /* Help information. */
10548 int *var; /* Variable to change. */
10549 int value; /* What to change it to. */
10550 char *deprecated; /* If non-null, print this message. */
10551 };
10552
10553 struct arm_option_table arm_opts[] =
10554 {
10555 {"k", N_("generate PIC code"), &pic_code, 1, NULL},
10556 {"mthumb", N_("assemble Thumb code"), &thumb_mode, 1, NULL},
10557 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
10558 &support_interwork, 1, NULL},
10559 {"moabi", N_("use old ABI (ELF only)"), &target_oabi, 1, NULL},
10560 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
10561 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
10562 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
10563 1, NULL},
10564 {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
10565 {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
10566 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
10567 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 1,
10568 NULL},
10569
10570 /* These are recognized by the assembler, but have no affect on code. */
10571 {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
10572 {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
10573
10574 /* DON'T add any new processors to this list -- we want the whole list
10575 to go away... Add them to the processors table instead. */
10576 {"marm1", NULL, &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
10577 {"m1", NULL, &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
10578 {"marm2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
10579 {"m2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
10580 {"marm250", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
10581 {"m250", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
10582 {"marm3", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
10583 {"m3", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
10584 {"marm6", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
10585 {"m6", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
10586 {"marm600", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
10587 {"m600", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
10588 {"marm610", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
10589 {"m610", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
10590 {"marm620", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
10591 {"m620", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
10592 {"marm7", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
10593 {"m7", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
10594 {"marm70", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
10595 {"m70", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
10596 {"marm700", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
10597 {"m700", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
10598 {"marm700i", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
10599 {"m700i", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
10600 {"marm710", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
10601 {"m710", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
10602 {"marm710c", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
10603 {"m710c", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
10604 {"marm720", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
10605 {"m720", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
10606 {"marm7d", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
10607 {"m7d", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
10608 {"marm7di", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
10609 {"m7di", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
10610 {"marm7m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
10611 {"m7m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
10612 {"marm7dm", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
10613 {"m7dm", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
10614 {"marm7dmi", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
10615 {"m7dmi", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
10616 {"marm7100", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
10617 {"m7100", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
10618 {"marm7500", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
10619 {"m7500", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
10620 {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
10621 {"m7500fe", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
10622 {"marm7t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
10623 {"m7t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
10624 {"marm7tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
10625 {"m7tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
10626 {"marm710t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
10627 {"m710t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
10628 {"marm720t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
10629 {"m720t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
10630 {"marm740t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
10631 {"m740t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
10632 {"marm8", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
10633 {"m8", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
10634 {"marm810", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
10635 {"m810", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
10636 {"marm9", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
10637 {"m9", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
10638 {"marm9tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
10639 {"m9tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
10640 {"marm920", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
10641 {"m920", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
10642 {"marm940", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
10643 {"m940", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
10644 {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")},
10645 {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
10646 N_("use -mcpu=strongarm110")},
10647 {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
10648 N_("use -mcpu=strongarm1100")},
10649 {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
10650 N_("use -mcpu=strongarm1110")},
10651 {"mxscale", NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
10652 {"mall", NULL, &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
10653
10654 /* Architecture variants -- don't add any more to this list either. */
10655 {"mv2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
10656 {"marmv2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
10657 {"mv2a", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
10658 {"marmv2a", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
10659 {"mv3", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
10660 {"marmv3", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
10661 {"mv3m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
10662 {"marmv3m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
10663 {"mv4", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
10664 {"marmv4", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
10665 {"mv4t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
10666 {"marmv4t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
10667 {"mv5", NULL, &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
10668 {"marmv5", NULL, &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
10669 {"mv5t", NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
10670 {"marmv5t", NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
10671 {"mv5e", NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
10672 {"marmv5e", NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
10673
10674 /* Floating point variants -- don't add any more to this list either. */
10675 {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
10676 {"mfpa10", NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
10677 {"mfpa11", NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
10678 {"mno-fpu", NULL, &legacy_fpu, 0,
10679 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
10680
10681 {NULL, NULL, NULL, 0, NULL}
10682 };
10683
10684 struct arm_cpu_option_table
10685 {
10686 char *name;
10687 int value;
10688 /* For some CPUs we assume an FPU unless the user explicitly sets
10689 -mfpu=... */
10690 int default_fpu;
10691 };
10692
10693 /* This list should, at a minimum, contain all the cpu names
10694 recognized by GCC. */
10695 static struct arm_cpu_option_table arm_cpus[] =
10696 {
10697 {"all", ARM_ANY, FPU_ARCH_FPA},
10698 {"arm1", ARM_ARCH_V1, FPU_ARCH_FPA},
10699 {"arm2", ARM_ARCH_V2, FPU_ARCH_FPA},
10700 {"arm250", ARM_ARCH_V2S, FPU_ARCH_FPA},
10701 {"arm3", ARM_ARCH_V2S, FPU_ARCH_FPA},
10702 {"arm6", ARM_ARCH_V3, FPU_ARCH_FPA},
10703 {"arm60", ARM_ARCH_V3, FPU_ARCH_FPA},
10704 {"arm600", ARM_ARCH_V3, FPU_ARCH_FPA},
10705 {"arm610", ARM_ARCH_V3, FPU_ARCH_FPA},
10706 {"arm620", ARM_ARCH_V3, FPU_ARCH_FPA},
10707 {"arm7", ARM_ARCH_V3, FPU_ARCH_FPA},
10708 {"arm7m", ARM_ARCH_V3M, FPU_ARCH_FPA},
10709 {"arm7d", ARM_ARCH_V3, FPU_ARCH_FPA},
10710 {"arm7dm", ARM_ARCH_V3M, FPU_ARCH_FPA},
10711 {"arm7di", ARM_ARCH_V3, FPU_ARCH_FPA},
10712 {"arm7dmi", ARM_ARCH_V3M, FPU_ARCH_FPA},
10713 {"arm70", ARM_ARCH_V3, FPU_ARCH_FPA},
10714 {"arm700", ARM_ARCH_V3, FPU_ARCH_FPA},
10715 {"arm700i", ARM_ARCH_V3, FPU_ARCH_FPA},
10716 {"arm710", ARM_ARCH_V3, FPU_ARCH_FPA},
10717 {"arm710t", ARM_ARCH_V4T, FPU_ARCH_FPA},
10718 {"arm720", ARM_ARCH_V3, FPU_ARCH_FPA},
10719 {"arm720t", ARM_ARCH_V4T, FPU_ARCH_FPA},
10720 {"arm740t", ARM_ARCH_V4T, FPU_ARCH_FPA},
10721 {"arm710c", ARM_ARCH_V3, FPU_ARCH_FPA},
10722 {"arm7100", ARM_ARCH_V3, FPU_ARCH_FPA},
10723 {"arm7500", ARM_ARCH_V3, FPU_ARCH_FPA},
10724 {"arm7500fe", ARM_ARCH_V3, FPU_ARCH_FPA},
10725 {"arm7t", ARM_ARCH_V4T, FPU_ARCH_FPA},
10726 {"arm7tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA},
10727 {"arm8", ARM_ARCH_V4, FPU_ARCH_FPA},
10728 {"arm810", ARM_ARCH_V4, FPU_ARCH_FPA},
10729 {"strongarm", ARM_ARCH_V4, FPU_ARCH_FPA},
10730 {"strongarm1", ARM_ARCH_V4, FPU_ARCH_FPA},
10731 {"strongarm110", ARM_ARCH_V4, FPU_ARCH_FPA},
10732 {"strongarm1100", ARM_ARCH_V4, FPU_ARCH_FPA},
10733 {"strongarm1110", ARM_ARCH_V4, FPU_ARCH_FPA},
10734 {"arm9", ARM_ARCH_V4T, FPU_ARCH_FPA},
10735 {"arm920", ARM_ARCH_V4T, FPU_ARCH_FPA},
10736 {"arm920t", ARM_ARCH_V4T, FPU_ARCH_FPA},
10737 {"arm922t", ARM_ARCH_V4T, FPU_ARCH_FPA},
10738 {"arm940t", ARM_ARCH_V4T, FPU_ARCH_FPA},
10739 {"arm9tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA},
10740 /* For V5 or later processors we default to using VFP; but the user
10741 should really set the FPU type explicitly. */
10742 {"arm9e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
10743 {"arm9e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
10744 {"arm946e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
10745 {"arm946e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
10746 {"arm966e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
10747 {"arm966e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
10748 {"arm10t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1},
10749 {"arm10e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
10750 {"arm1020", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
10751 {"arm1020t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1},
10752 {"arm1020e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
10753 /* ??? XSCALE is really an architecture. */
10754 {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
10755 {"i80200", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
10756 /* Maverick */
10757 {"ep9312", ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_NONE},
10758 {NULL, 0, 0}
10759 };
10760
10761 struct arm_arch_option_table
10762 {
10763 char *name;
10764 int value;
10765 int default_fpu;
10766 };
10767
10768 /* This list should, at a minimum, contain all the architecture names
10769 recognized by GCC. */
10770 static struct arm_arch_option_table arm_archs[] =
10771 {
10772 {"all", ARM_ANY, FPU_ARCH_FPA},
10773 {"armv1", ARM_ARCH_V1, FPU_ARCH_FPA},
10774 {"armv2", ARM_ARCH_V2, FPU_ARCH_FPA},
10775 {"armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA},
10776 {"armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA},
10777 {"armv3", ARM_ARCH_V3, FPU_ARCH_FPA},
10778 {"armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA},
10779 {"armv4", ARM_ARCH_V4, FPU_ARCH_FPA},
10780 {"armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA},
10781 {"armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA},
10782 {"armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA},
10783 {"armv5", ARM_ARCH_V5, FPU_ARCH_VFP},
10784 {"armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP},
10785 {"armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP},
10786 {"armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP},
10787 {"armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP},
10788 {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP},
10789 {NULL, 0, 0}
10790 };
10791
10792 /* ISA extensions in the co-processor space. */
10793 struct arm_arch_extension_table
10794 {
10795 char *name;
10796 int value;
10797 };
10798
10799 static struct arm_arch_extension_table arm_extensions[] =
10800 {
10801 {"maverick", ARM_CEXT_MAVERICK},
10802 {"xscale", ARM_CEXT_XSCALE},
10803 {NULL, 0}
10804 };
10805
10806 struct arm_fpu_option_table
10807 {
10808 char *name;
10809 int value;
10810 };
10811
10812 /* This list should, at a minimum, contain all the fpu names
10813 recognized by GCC. */
10814 static struct arm_fpu_option_table arm_fpus[] =
10815 {
10816 {"softfpa", FPU_NONE},
10817 {"fpe", FPU_ARCH_FPE},
10818 {"fpe2", FPU_ARCH_FPE},
10819 {"fpe3", FPU_ARCH_FPA}, /* Third release supports LFM/SFM. */
10820 {"fpa", FPU_ARCH_FPA},
10821 {"fpa10", FPU_ARCH_FPA},
10822 {"fpa11", FPU_ARCH_FPA},
10823 {"arm7500fe", FPU_ARCH_FPA},
10824 {"softvfp", FPU_ARCH_VFP},
10825 {"softvfp+vfp", FPU_ARCH_VFP_V2},
10826 {"vfp", FPU_ARCH_VFP_V2},
10827 {"vfp9", FPU_ARCH_VFP_V2},
10828 {"vfp10", FPU_ARCH_VFP_V2},
10829 {"vfp10-r0", FPU_ARCH_VFP_V1},
10830 {"vfpxd", FPU_ARCH_VFP_V1xD},
10831 {"arm1020t", FPU_ARCH_VFP_V1},
10832 {"arm1020e", FPU_ARCH_VFP_V2},
10833 {NULL, 0}
10834 };
10835
10836 struct arm_long_option_table
10837 {
10838 char *option; /* Substring to match. */
10839 char *help; /* Help information. */
10840 int (*func) PARAMS ((char *subopt)); /* Function to decode sub-option. */
10841 char *deprecated; /* If non-null, print this message. */
10842 };
10843
10844 static int
10845 arm_parse_extension (str, opt_p)
10846 char *str;
10847 int *opt_p;
10848 {
10849 while (str != NULL && *str != 0)
10850 {
10851 struct arm_arch_extension_table *opt;
10852 char *ext;
10853 int optlen;
10854
10855 if (*str != '+')
10856 {
10857 as_bad (_("invalid architectural extension"));
10858 return 0;
10859 }
10860
10861 str++;
10862 ext = strchr (str, '+');
10863
10864 if (ext != NULL)
10865 optlen = ext - str;
10866 else
10867 optlen = strlen (str);
10868
10869 if (optlen == 0)
10870 {
10871 as_bad (_("missing architectural extension"));
10872 return 0;
10873 }
10874
10875 for (opt = arm_extensions; opt->name != NULL; opt++)
10876 if (strncmp (opt->name, str, optlen) == 0)
10877 {
10878 *opt_p |= opt->value;
10879 break;
10880 }
10881
10882 if (opt->name == NULL)
10883 {
10884 as_bad (_("unknown architectural extnsion `%s'"), str);
10885 return 0;
10886 }
10887
10888 str = ext;
10889 };
10890
10891 return 1;
10892 }
10893
10894 static int
10895 arm_parse_cpu (str)
10896 char *str;
10897 {
10898 struct arm_cpu_option_table *opt;
10899 char *ext = strchr (str, '+');
10900 int optlen;
10901
10902 if (ext != NULL)
10903 optlen = ext - str;
10904 else
10905 optlen = strlen (str);
10906
10907 if (optlen == 0)
10908 {
10909 as_bad (_("missing cpu name `%s'"), str);
10910 return 0;
10911 }
10912
10913 for (opt = arm_cpus; opt->name != NULL; opt++)
10914 if (strncmp (opt->name, str, optlen) == 0)
10915 {
10916 mcpu_cpu_opt = opt->value;
10917 mcpu_fpu_opt = opt->default_fpu;
10918
10919 if (ext != NULL)
10920 return arm_parse_extension (ext, &mcpu_cpu_opt);
10921
10922 return 1;
10923 }
10924
10925 as_bad (_("unknown cpu `%s'"), str);
10926 return 0;
10927 }
10928
10929 static int
10930 arm_parse_arch (str)
10931 char *str;
10932 {
10933 struct arm_arch_option_table *opt;
10934 char *ext = strchr (str, '+');
10935 int optlen;
10936
10937 if (ext != NULL)
10938 optlen = ext - str;
10939 else
10940 optlen = strlen (str);
10941
10942 if (optlen == 0)
10943 {
10944 as_bad (_("missing architecture name `%s'"), str);
10945 return 0;
10946 }
10947
10948
10949 for (opt = arm_archs; opt->name != NULL; opt++)
10950 if (strcmp (opt->name, str) == 0)
10951 {
10952 march_cpu_opt = opt->value;
10953 march_fpu_opt = opt->default_fpu;
10954
10955 if (ext != NULL)
10956 return arm_parse_extension (ext, &march_cpu_opt);
10957
10958 return 1;
10959 }
10960
10961 as_bad (_("unknown architecture `%s'\n"), str);
10962 return 0;
10963 }
10964
10965 static int
10966 arm_parse_fpu (str)
10967 char *str;
10968 {
10969 struct arm_fpu_option_table *opt;
10970
10971 for (opt = arm_fpus; opt->name != NULL; opt++)
10972 if (strcmp (opt->name, str) == 0)
10973 {
10974 mfpu_opt = opt->value;
10975 return 1;
10976 }
10977
10978 as_bad (_("unknown floating point format `%s'\n"), str);
10979 return 0;
10980 }
10981
10982 struct arm_long_option_table arm_long_opts[] =
10983 {
10984 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
10985 arm_parse_cpu, NULL},
10986 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
10987 arm_parse_arch, NULL},
10988 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
10989 arm_parse_fpu, NULL},
10990 {NULL, NULL, 0, NULL}
10991 };
10992
10993 int
10994 md_parse_option (c, arg)
10995 int c;
10996 char * arg;
10997 {
10998 struct arm_option_table *opt;
10999 struct arm_long_option_table *lopt;
11000
11001 switch (c)
11002 {
11003 #ifdef OPTION_EB
11004 case OPTION_EB:
11005 target_big_endian = 1;
11006 break;
11007 #endif
11008
11009 #ifdef OPTION_EL
11010 case OPTION_EL:
11011 target_big_endian = 0;
11012 break;
11013 #endif
11014
11015 case 'a':
11016 /* Listing option. Just ignore these, we don't support additional
11017 ones. */
11018 return 0;
11019
11020 default:
11021 for (opt = arm_opts; opt->option != NULL; opt++)
11022 {
11023 if (c == opt->option[0]
11024 && ((arg == NULL && opt->option[1] == 0)
11025 || strcmp (arg, opt->option + 1) == 0))
11026 {
11027 #if WARN_DEPRECATED
11028 /* If the option is deprecated, tell the user. */
11029 if (opt->deprecated != NULL)
11030 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
11031 arg ? arg : "", _(opt->deprecated));
11032 #endif
11033
11034 if (opt->var != NULL)
11035 *opt->var = opt->value;
11036
11037 return 1;
11038 }
11039 }
11040
11041 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
11042 {
11043 /* These options are expected to have an argument. */
11044 if (c == lopt->option[0]
11045 && arg != NULL
11046 && strncmp (arg, lopt->option + 1,
11047 strlen (lopt->option + 1)) == 0)
11048 {
11049 #if WARN_DEPRECATED
11050 /* If the option is deprecated, tell the user. */
11051 if (lopt->deprecated != NULL)
11052 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
11053 _(lopt->deprecated));
11054 #endif
11055
11056 /* Call the sup-option parser. */
11057 return (*lopt->func)(arg + strlen (lopt->option) - 1);
11058 }
11059 }
11060
11061 as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : "");
11062 return 0;
11063 }
11064
11065 return 1;
11066 }
11067
11068 void
11069 md_show_usage (fp)
11070 FILE * fp;
11071 {
11072 struct arm_option_table *opt;
11073 struct arm_long_option_table *lopt;
11074
11075 fprintf (fp, _(" ARM-specific assembler options:\n"));
11076
11077 for (opt = arm_opts; opt->option != NULL; opt++)
11078 if (opt->help != NULL)
11079 fprintf (fp, " -%-23s%s\n", opt->option, _(opt->help));
11080
11081 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
11082 if (lopt->help != NULL)
11083 fprintf (fp, " -%s%s\n", lopt->option, _(lopt->help));
11084
11085 #ifdef OPTION_EB
11086 fprintf (fp, _("\
11087 -EB assemble code for a big-endian cpu\n"));
11088 #endif
11089
11090 #ifdef OPTION_EL
11091 fprintf (fp, _("\
11092 -EL assemble code for a little-endian cpu\n"));
11093 #endif
11094 }
11095
11096 /* We need to be able to fix up arbitrary expressions in some statements.
11097 This is so that we can handle symbols that are an arbitrary distance from
11098 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
11099 which returns part of an address in a form which will be valid for
11100 a data instruction. We do this by pushing the expression into a symbol
11101 in the expr_section, and creating a fix for that. */
11102
11103 static void
11104 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
11105 fragS * frag;
11106 int where;
11107 short int size;
11108 expressionS * exp;
11109 int pc_rel;
11110 int reloc;
11111 {
11112 fixS * new_fix;
11113 arm_fix_data * arm_data;
11114
11115 switch (exp->X_op)
11116 {
11117 case O_constant:
11118 case O_symbol:
11119 case O_add:
11120 case O_subtract:
11121 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
11122 break;
11123
11124 default:
11125 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
11126 pc_rel, reloc);
11127 break;
11128 }
11129
11130 /* Mark whether the fix is to a THUMB instruction, or an ARM
11131 instruction. */
11132 arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
11133 new_fix->tc_fix_data = (PTR) arm_data;
11134 arm_data->thumb_mode = thumb_mode;
11135
11136 return;
11137 }
11138
11139 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
11140
11141 void
11142 cons_fix_new_arm (frag, where, size, exp)
11143 fragS * frag;
11144 int where;
11145 int size;
11146 expressionS * exp;
11147 {
11148 bfd_reloc_code_real_type type;
11149 int pcrel = 0;
11150
11151 /* Pick a reloc.
11152 FIXME: @@ Should look at CPU word size. */
11153 switch (size)
11154 {
11155 case 1:
11156 type = BFD_RELOC_8;
11157 break;
11158 case 2:
11159 type = BFD_RELOC_16;
11160 break;
11161 case 4:
11162 default:
11163 type = BFD_RELOC_32;
11164 break;
11165 case 8:
11166 type = BFD_RELOC_64;
11167 break;
11168 }
11169
11170 fix_new_exp (frag, where, (int) size, exp, pcrel, type);
11171 }
11172
11173 /* A good place to do this, although this was probably not intended
11174 for this kind of use. We need to dump the literal pool before
11175 references are made to a null symbol pointer. */
11176
11177 void
11178 arm_cleanup ()
11179 {
11180 if (current_poolP == NULL)
11181 return;
11182
11183 /* Put it at the end of text section. */
11184 subseg_set (text_section, 0);
11185 s_ltorg (0);
11186 listing_prev_line ();
11187 }
11188
11189 void
11190 arm_start_line_hook ()
11191 {
11192 last_label_seen = NULL;
11193 }
11194
11195 void
11196 arm_frob_label (sym)
11197 symbolS * sym;
11198 {
11199 last_label_seen = sym;
11200
11201 ARM_SET_THUMB (sym, thumb_mode);
11202
11203 #if defined OBJ_COFF || defined OBJ_ELF
11204 ARM_SET_INTERWORK (sym, support_interwork);
11205 #endif
11206
11207 /* Note - do not allow local symbols (.Lxxx) to be labeled
11208 as Thumb functions. This is because these labels, whilst
11209 they exist inside Thumb code, are not the entry points for
11210 possible ARM->Thumb calls. Also, these labels can be used
11211 as part of a computed goto or switch statement. eg gcc
11212 can generate code that looks like this:
11213
11214 ldr r2, [pc, .Laaa]
11215 lsl r3, r3, #2
11216 ldr r2, [r3, r2]
11217 mov pc, r2
11218
11219 .Lbbb: .word .Lxxx
11220 .Lccc: .word .Lyyy
11221 ..etc...
11222 .Laaa: .word Lbbb
11223
11224 The first instruction loads the address of the jump table.
11225 The second instruction converts a table index into a byte offset.
11226 The third instruction gets the jump address out of the table.
11227 The fourth instruction performs the jump.
11228
11229 If the address stored at .Laaa is that of a symbol which has the
11230 Thumb_Func bit set, then the linker will arrange for this address
11231 to have the bottom bit set, which in turn would mean that the
11232 address computation performed by the third instruction would end
11233 up with the bottom bit set. Since the ARM is capable of unaligned
11234 word loads, the instruction would then load the incorrect address
11235 out of the jump table, and chaos would ensue. */
11236 if (label_is_thumb_function_name
11237 && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
11238 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
11239 {
11240 /* When the address of a Thumb function is taken the bottom
11241 bit of that address should be set. This will allow
11242 interworking between Arm and Thumb functions to work
11243 correctly. */
11244
11245 THUMB_SET_FUNC (sym, 1);
11246
11247 label_is_thumb_function_name = false;
11248 }
11249 }
11250
11251 /* Adjust the symbol table. This marks Thumb symbols as distinct from
11252 ARM ones. */
11253
11254 void
11255 arm_adjust_symtab ()
11256 {
11257 #ifdef OBJ_COFF
11258 symbolS * sym;
11259
11260 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
11261 {
11262 if (ARM_IS_THUMB (sym))
11263 {
11264 if (THUMB_IS_FUNC (sym))
11265 {
11266 /* Mark the symbol as a Thumb function. */
11267 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
11268 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
11269 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
11270
11271 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
11272 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
11273 else
11274 as_bad (_("%s: unexpected function type: %d"),
11275 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
11276 }
11277 else switch (S_GET_STORAGE_CLASS (sym))
11278 {
11279 case C_EXT:
11280 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
11281 break;
11282 case C_STAT:
11283 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
11284 break;
11285 case C_LABEL:
11286 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
11287 break;
11288 default:
11289 /* Do nothing. */
11290 break;
11291 }
11292 }
11293
11294 if (ARM_IS_INTERWORK (sym))
11295 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
11296 }
11297 #endif
11298 #ifdef OBJ_ELF
11299 symbolS * sym;
11300 char bind;
11301
11302 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
11303 {
11304 if (ARM_IS_THUMB (sym))
11305 {
11306 elf_symbol_type * elf_sym;
11307
11308 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
11309 bind = ELF_ST_BIND (elf_sym);
11310
11311 /* If it's a .thumb_func, declare it as so,
11312 otherwise tag label as .code 16. */
11313 if (THUMB_IS_FUNC (sym))
11314 elf_sym->internal_elf_sym.st_info =
11315 ELF_ST_INFO (bind, STT_ARM_TFUNC);
11316 else
11317 elf_sym->internal_elf_sym.st_info =
11318 ELF_ST_INFO (bind, STT_ARM_16BIT);
11319 }
11320 }
11321 #endif
11322 }
11323
11324 int
11325 arm_data_in_code ()
11326 {
11327 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
11328 {
11329 *input_line_pointer = '/';
11330 input_line_pointer += 5;
11331 *input_line_pointer = 0;
11332 return 1;
11333 }
11334
11335 return 0;
11336 }
11337
11338 char *
11339 arm_canonicalize_symbol_name (name)
11340 char * name;
11341 {
11342 int len;
11343
11344 if (thumb_mode && (len = strlen (name)) > 5
11345 && streq (name + len - 5, "/data"))
11346 *(name + len - 5) = 0;
11347
11348 return name;
11349 }
11350
11351 boolean
11352 arm_validate_fix (fixP)
11353 fixS * fixP;
11354 {
11355 /* If the destination of the branch is a defined symbol which does not have
11356 the THUMB_FUNC attribute, then we must be calling a function which has
11357 the (interfacearm) attribute. We look for the Thumb entry point to that
11358 function and change the branch to refer to that function instead. */
11359 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
11360 && fixP->fx_addsy != NULL
11361 && S_IS_DEFINED (fixP->fx_addsy)
11362 && ! THUMB_IS_FUNC (fixP->fx_addsy))
11363 {
11364 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
11365 return true;
11366 }
11367
11368 return false;
11369 }
11370
11371 #ifdef OBJ_COFF
11372 /* This is a little hack to help the gas/arm/adrl.s test. It prevents
11373 local labels from being added to the output symbol table when they
11374 are used with the ADRL pseudo op. The ADRL relocation should always
11375 be resolved before the binbary is emitted, so it is safe to say that
11376 it is adjustable. */
11377
11378 boolean
11379 arm_fix_adjustable (fixP)
11380 fixS * fixP;
11381 {
11382 if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
11383 return 1;
11384 return 0;
11385 }
11386 #endif
11387 #ifdef OBJ_ELF
11388 /* Relocations against Thumb function names must be left unadjusted,
11389 so that the linker can use this information to correctly set the
11390 bottom bit of their addresses. The MIPS version of this function
11391 also prevents relocations that are mips-16 specific, but I do not
11392 know why it does this.
11393
11394 FIXME:
11395 There is one other problem that ought to be addressed here, but
11396 which currently is not: Taking the address of a label (rather
11397 than a function) and then later jumping to that address. Such
11398 addresses also ought to have their bottom bit set (assuming that
11399 they reside in Thumb code), but at the moment they will not. */
11400
11401 boolean
11402 arm_fix_adjustable (fixP)
11403 fixS * fixP;
11404 {
11405 if (fixP->fx_addsy == NULL)
11406 return 1;
11407
11408 /* Prevent all adjustments to global symbols. */
11409 if (S_IS_EXTERN (fixP->fx_addsy))
11410 return 0;
11411
11412 if (S_IS_WEAK (fixP->fx_addsy))
11413 return 0;
11414
11415 if (THUMB_IS_FUNC (fixP->fx_addsy)
11416 && fixP->fx_subsy == NULL)
11417 return 0;
11418
11419 /* We need the symbol name for the VTABLE entries. */
11420 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
11421 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
11422 return 0;
11423
11424 return 1;
11425 }
11426
11427 const char *
11428 elf32_arm_target_format ()
11429 {
11430 if (target_big_endian)
11431 {
11432 if (target_oabi)
11433 return "elf32-bigarm-oabi";
11434 else
11435 return "elf32-bigarm";
11436 }
11437 else
11438 {
11439 if (target_oabi)
11440 return "elf32-littlearm-oabi";
11441 else
11442 return "elf32-littlearm";
11443 }
11444 }
11445
11446 void
11447 armelf_frob_symbol (symp, puntp)
11448 symbolS * symp;
11449 int * puntp;
11450 {
11451 elf_frob_symbol (symp, puntp);
11452 }
11453
11454 int
11455 arm_force_relocation (fixp)
11456 struct fix * fixp;
11457 {
11458 if ( fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
11459 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
11460 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
11461 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
11462 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
11463 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
11464 return 1;
11465
11466 return 0;
11467 }
11468
11469 static bfd_reloc_code_real_type
11470 arm_parse_reloc ()
11471 {
11472 char id [16];
11473 char * ip;
11474 unsigned int i;
11475 static struct
11476 {
11477 char * str;
11478 int len;
11479 bfd_reloc_code_real_type reloc;
11480 }
11481 reloc_map[] =
11482 {
11483 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
11484 MAP ("(got)", BFD_RELOC_ARM_GOT32),
11485 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
11486 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
11487 branch instructions generated by GCC for PLT relocs. */
11488 MAP ("(plt)", BFD_RELOC_ARM_PLT32),
11489 { NULL, 0, BFD_RELOC_UNUSED }
11490 #undef MAP
11491 };
11492
11493 for (i = 0, ip = input_line_pointer;
11494 i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
11495 i++, ip++)
11496 id[i] = TOLOWER (*ip);
11497
11498 for (i = 0; reloc_map[i].str; i++)
11499 if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
11500 break;
11501
11502 input_line_pointer += reloc_map[i].len;
11503
11504 return reloc_map[i].reloc;
11505 }
11506
11507 static void
11508 s_arm_elf_cons (nbytes)
11509 int nbytes;
11510 {
11511 expressionS exp;
11512
11513 #ifdef md_flush_pending_output
11514 md_flush_pending_output ();
11515 #endif
11516
11517 if (is_it_end_of_statement ())
11518 {
11519 demand_empty_rest_of_line ();
11520 return;
11521 }
11522
11523 #ifdef md_cons_align
11524 md_cons_align (nbytes);
11525 #endif
11526
11527 do
11528 {
11529 bfd_reloc_code_real_type reloc;
11530
11531 expression (& exp);
11532
11533 if (exp.X_op == O_symbol
11534 && * input_line_pointer == '('
11535 && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
11536 {
11537 reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
11538 int size = bfd_get_reloc_size (howto);
11539
11540 if (size > nbytes)
11541 as_bad ("%s relocations do not fit in %d bytes",
11542 howto->name, nbytes);
11543 else
11544 {
11545 register char *p = frag_more ((int) nbytes);
11546 int offset = nbytes - size;
11547
11548 fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
11549 &exp, 0, reloc);
11550 }
11551 }
11552 else
11553 emit_expr (&exp, (unsigned int) nbytes);
11554 }
11555 while (*input_line_pointer++ == ',');
11556
11557 /* Put terminator back into stream. */
11558 input_line_pointer --;
11559 demand_empty_rest_of_line ();
11560 }
11561
11562 #endif /* OBJ_ELF */
11563
11564 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
11565 of an rs_align_code fragment. */
11566
11567 void
11568 arm_handle_align (fragP)
11569 fragS *fragP;
11570 {
11571 static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
11572 static char const thumb_noop[2] = { 0xc0, 0x46 };
11573 static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
11574 static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
11575
11576 int bytes, fix, noop_size;
11577 char * p;
11578 const char * noop;
11579
11580 if (fragP->fr_type != rs_align_code)
11581 return;
11582
11583 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
11584 p = fragP->fr_literal + fragP->fr_fix;
11585 fix = 0;
11586
11587 if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
11588 bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
11589
11590 if (fragP->tc_frag_data)
11591 {
11592 if (target_big_endian)
11593 noop = thumb_bigend_noop;
11594 else
11595 noop = thumb_noop;
11596 noop_size = sizeof (thumb_noop);
11597 }
11598 else
11599 {
11600 if (target_big_endian)
11601 noop = arm_bigend_noop;
11602 else
11603 noop = arm_noop;
11604 noop_size = sizeof (arm_noop);
11605 }
11606
11607 if (bytes & (noop_size - 1))
11608 {
11609 fix = bytes & (noop_size - 1);
11610 memset (p, 0, fix);
11611 p += fix;
11612 bytes -= fix;
11613 }
11614
11615 while (bytes >= noop_size)
11616 {
11617 memcpy (p, noop, noop_size);
11618 p += noop_size;
11619 bytes -= noop_size;
11620 fix += noop_size;
11621 }
11622
11623 fragP->fr_fix += fix;
11624 fragP->fr_var = noop_size;
11625 }
11626
11627 /* Called from md_do_align. Used to create an alignment
11628 frag in a code section. */
11629
11630 void
11631 arm_frag_align_code (n, max)
11632 int n;
11633 int max;
11634 {
11635 char * p;
11636
11637 /* We assume that there will never be a requirment
11638 to support alignments greater than 32 bytes. */
11639 if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
11640 as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
11641
11642 p = frag_var (rs_align_code,
11643 MAX_MEM_FOR_RS_ALIGN_CODE,
11644 1,
11645 (relax_substateT) max,
11646 (symbolS *) NULL,
11647 (offsetT) n,
11648 (char *) NULL);
11649 *p = 0;
11650
11651 }
11652
11653 /* Perform target specific initialisation of a frag. */
11654
11655 void
11656 arm_init_frag (fragP)
11657 fragS *fragP;
11658 {
11659 /* Record whether this frag is in an ARM or a THUMB area. */
11660 fragP->tc_frag_data = thumb_mode;
11661 }
This page took 0.286207 seconds and 5 git commands to generate.