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