Added support for storing ARM Procedure Calling Standard variant, and ARM
[deliverable/binutils-gdb.git] / gas / config / tc-arm.c
CommitLineData
590c50d8
ILT
1/* tc-arm.c -- Assemble for the ARM
2 Copyright (C) 1994, 95, 96, 1997 Free Software Foundation, Inc.
338a7060
DE
3 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
4 Modified by David Taylor (dtaylor@armltd.co.uk)
5
338a7060
DE
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
590c50d8
ILT
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
338a7060
DE
22
23#include <ctype.h>
24#include <string.h>
25#define NO_RELOC 0
26#include "as.h"
27
28/* need TARGET_CPU */
29#include "config.h"
30#include "subsegs.h"
31#include "obstack.h"
32#include "symbols.h"
33#include "listing.h"
34
35/* ??? This is currently unused. */
36#ifdef __STDC__
37#define internalError() \
38 as_fatal ("ARM Internal Error, line %d, %s", __LINE__, __FILE__)
39#else
40#define internalError() as_fatal ("ARM Internal Error")
41#endif
42
43/* Types of processor to assemble for. */
44#define ARM_1 0x00000001
45#define ARM_2 0x00000002
338a7060 46#define ARM_3 0x00000004
590c50d8 47#define ARM_250 ARM_3
338a7060 48#define ARM_6 0x00000008
590c50d8 49#define ARM_7 ARM_6 /* same core instruction set */
46686c78 50#define ARM_CPU_MASK 0x0000000f
c479fc62
JSC
51
52/* The following bitmasks control CPU extensions (ARM7 onwards): */
53#define ARM_LONGMUL 0x00000010 /* allow long multiplies */
590c50d8
ILT
54#define ARM_ARCH4 0x00000020
55#define ARM_THUMB ARM_ARCH4
338a7060
DE
56
57/* Some useful combinations: */
58#define ARM_ANY 0x00ffffff
59#define ARM_2UP 0x00fffffe
60#define ARM_ALL ARM_2UP /* Not arm1 only */
61#define ARM_3UP 0x00fffffc
c479fc62 62#define ARM_6UP 0x00fffff8 /* Includes ARM7 */
338a7060
DE
63
64#define FPU_CORE 0x80000000
65#define FPU_FPA10 0x40000000
66#define FPU_FPA11 0x40000000
67#define FPU_NONE 0
68
69/* Some useful combinations */
70#define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
71#define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
72
73#ifndef CPU_DEFAULT
74#define CPU_DEFAULT ARM_ALL
75#endif
76
77#ifndef FPU_DEFAULT
78#define FPU_DEFAULT FPU_ALL
79#endif
80
46686c78
NC
81static unsigned long cpu_variant = CPU_DEFAULT | FPU_DEFAULT;
82
83/* Flags stored in private area of BFD COFF structure */
84static boolean uses_apcs_26 = false;
338a7060
DE
85
86/* This array holds the chars that always start a comment. If the
87 pre-processor is disabled, these aren't very useful */
88CONST char comment_chars[] = "@";
89
90/* This array holds the chars that only start a comment at the beginning of
91 a line. If the line seems to have the form '# 123 filename'
92 .line and .file directives will appear in the pre-processed output */
93/* Note that input_file.c hand checks for '#' at the beginning of the
94 first line of the input file. This is because the compiler outputs
95 #NO_APP at the beginning of its output. */
96/* Also note that comments like this one will always work. */
97CONST char line_comment_chars[] = "#";
98
99CONST char line_separator_chars[] = "";
100
101/* Chars that can be used to separate mant from exp in floating point nums */
102CONST char EXP_CHARS[] = "eE";
103
104/* Chars that mean this number is a floating point constant */
105/* As in 0f12.456 */
106/* or 0d1.2345e12 */
107
108CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP";
109
590c50d8
ILT
110CONST int md_reloc_size = 8; /* Size of relocation record */
111
112static int thumb_mode = 0; /* non-zero if assembling thumb instructions */
113
114typedef struct arm_fix
115{
116 int thumb_mode;
117} arm_fix_data;
338a7060
DE
118
119struct arm_it
120{
121 CONST char *error;
122 unsigned long instruction;
123 int suffix;
590c50d8 124 int size;
338a7060
DE
125 struct
126 {
127 bfd_reloc_code_real_type type;
128 expressionS exp;
129 int pc_rel;
130 } reloc;
131};
132
133struct arm_it inst;
134
135struct asm_shift
136{
137 CONST char *template;
138 unsigned long value;
139};
140
141static CONST struct asm_shift shift[] =
142{
143 {"asl", 0},
144 {"lsl", 0},
145 {"lsr", 0x00000020},
146 {"asr", 0x00000040},
147 {"ror", 0x00000060},
148 {"rrx", 0x00000060},
149 {"ASL", 0},
150 {"LSL", 0},
151 {"LSR", 0x00000020},
152 {"ASR", 0x00000040},
153 {"ROR", 0x00000060},
154 {"RRX", 0x00000060}
155};
156
157#define NO_SHIFT_RESTRICT 1
158#define SHIFT_RESTRICT 0
159
160#define NUM_FLOAT_VALS 8
161
162CONST char *fp_const[] =
163{
164 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
165};
166
167/* Number of littlenums required to hold an extended precision number */
168#define MAX_LITTLENUMS 6
169
170LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
171
172#define FAIL (-1)
173#define SUCCESS (0)
174
175#define SUFF_S 1
176#define SUFF_D 2
177#define SUFF_E 3
178#define SUFF_P 4
179
180#define CP_T_X 0x00008000
181#define CP_T_Y 0x00400000
182#define CP_T_Pre 0x01000000
183#define CP_T_UD 0x00800000
184#define CP_T_WB 0x00200000
185
590c50d8
ILT
186#define CONDS_BIT (0x00100000)
187#define LOAD_BIT (0x00100000)
338a7060
DE
188#define TRANS_BIT (0x00200000)
189
190struct asm_cond
191{
192 CONST char *template;
193 unsigned long value;
194};
195
196/* This is to save a hash look-up in the common case */
197#define COND_ALWAYS 0xe0000000
198
199static CONST struct asm_cond conds[] =
200{
201 {"eq", 0x00000000},
202 {"ne", 0x10000000},
203 {"cs", 0x20000000}, {"hs", 0x20000000},
204 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
205 {"mi", 0x40000000},
206 {"pl", 0x50000000},
207 {"vs", 0x60000000},
208 {"vc", 0x70000000},
209 {"hi", 0x80000000},
210 {"ls", 0x90000000},
211 {"ge", 0xa0000000},
212 {"lt", 0xb0000000},
213 {"gt", 0xc0000000},
214 {"le", 0xd0000000},
215 {"al", 0xe0000000},
216 {"nv", 0xf0000000}
217};
218
590c50d8
ILT
219/* Warning: If the top bit of the set_bits is set, then the standard
220 instruction bitmask is ignored, and the new bitmask is taken from
221 the set_bits: */
338a7060
DE
222struct asm_flg
223{
224 CONST char *template; /* Basic flag string */
225 unsigned long set_bits; /* Bits to set */
226};
227
228static CONST struct asm_flg s_flag[] =
229{
590c50d8
ILT
230 {"s", CONDS_BIT},
231 {NULL, 0}
232};
233
234static CONST struct asm_flg ldr_flags[] =
235{
236 {"b", 0x00400000},
237 {"t", TRANS_BIT},
238 {"bt", 0x00400000 | TRANS_BIT},
239 {"h", 0x801000b0},
240 {"sh", 0x801000f0},
241 {"sb", 0x801000d0},
242 {NULL, 0}
338a7060
DE
243};
244
590c50d8 245static CONST struct asm_flg str_flags[] =
338a7060 246{
590c50d8
ILT
247 {"b", 0x00400000},
248 {"t", TRANS_BIT},
249 {"bt", 0x00400000 | TRANS_BIT},
250 {"h", 0x800000b0},
251 {NULL, 0}
338a7060
DE
252};
253
254static CONST struct asm_flg byte_flag[] =
255{
590c50d8
ILT
256 {"b", 0x00400000},
257 {NULL, 0}
338a7060
DE
258};
259
260static CONST struct asm_flg cmp_flags[] =
261{
590c50d8
ILT
262 {"s", CONDS_BIT},
263 {"p", 0x0010f000},
264 {NULL, 0}
338a7060
DE
265};
266
267static CONST struct asm_flg ldm_flags[] =
268{
590c50d8
ILT
269 {"ed", 0x01800000},
270 {"fd", 0x00800000},
271 {"ea", 0x01000000},
272 {"fa", 0x08000000},
273 {"ib", 0x01800000},
274 {"ia", 0x00800000},
275 {"db", 0x01000000},
276 {"da", 0x08000000},
277 {NULL, 0}
338a7060
DE
278};
279
280static CONST struct asm_flg stm_flags[] =
281{
590c50d8
ILT
282 {"ed", 0x08000000},
283 {"fd", 0x01000000},
284 {"ea", 0x00800000},
285 {"fa", 0x01800000},
286 {"ib", 0x01800000},
287 {"ia", 0x00800000},
288 {"db", 0x01000000},
289 {"da", 0x08000000},
290 {NULL, 0}
338a7060
DE
291};
292
293static CONST struct asm_flg lfm_flags[] =
294{
590c50d8
ILT
295 {"fd", 0x00800000},
296 {"ea", 0x01000000},
297 {NULL, 0}
338a7060
DE
298};
299
300static CONST struct asm_flg sfm_flags[] =
301{
590c50d8
ILT
302 {"fd", 0x01000000},
303 {"ea", 0x00800000},
304 {NULL, 0}
338a7060
DE
305};
306
307static CONST struct asm_flg round_flags[] =
308{
590c50d8
ILT
309 {"p", 0x00000020},
310 {"m", 0x00000040},
311 {"z", 0x00000060},
312 {NULL, 0}
313};
314
315/* The implementation of the FIX instruction is broken on some assemblers,
316 in that it accepts a precision specifier as well as a rounding specifier,
317 despite the fact that this is meaningless. To be more compatible, we
318 accept it as well, though of course it does not set any bits. */
319static CONST struct asm_flg fix_flags[] =
320{
321 {"p", 0x00000020},
322 {"m", 0x00000040},
323 {"z", 0x00000060},
324 {"sp", 0x00000020},
325 {"sm", 0x00000040},
326 {"sz", 0x00000060},
327 {"dp", 0x00000020},
328 {"dm", 0x00000040},
329 {"dz", 0x00000060},
330 {"ep", 0x00000020},
331 {"em", 0x00000040},
332 {"ez", 0x00000060},
333 {NULL, 0}
338a7060
DE
334};
335
336static CONST struct asm_flg except_flag[] =
337{
590c50d8
ILT
338 {"e", 0x00400000},
339 {NULL, 0}
338a7060
DE
340};
341
342static CONST struct asm_flg cplong_flag[] =
343{
590c50d8
ILT
344 {"l", 0x00400000},
345 {NULL, 0}
338a7060
DE
346};
347
348struct asm_psr
349{
350 CONST char *template;
351 unsigned long number;
352};
353
354#define PSR_ALL 0x00010000
355
356static CONST struct asm_psr psrs[] =
357{
358 /* Valid <psr>'s */
359 {"cpsr", 0},
360 {"cpsr_all", 0},
361 {"spsr", 1},
362 {"spsr_all", 1},
363
364 /* Valid <psrf>'s */
365 {"cpsr_flg", 2},
366 {"spsr_flg", 3}
367};
368
369/* Functions called by parser */
370/* ARM instructions */
371static void do_arit PARAMS ((char *operands, unsigned long flags));
372static void do_cmp PARAMS ((char *operands, unsigned long flags));
373static void do_mov PARAMS ((char *operands, unsigned long flags));
374static void do_ldst PARAMS ((char *operands, unsigned long flags));
375static void do_ldmstm PARAMS ((char *operands, unsigned long flags));
376static void do_branch PARAMS ((char *operands, unsigned long flags));
377static void do_swi PARAMS ((char *operands, unsigned long flags));
378/* Pseudo Op codes */
379static void do_adr PARAMS ((char *operands, unsigned long flags));
380static void do_nop PARAMS ((char *operands, unsigned long flags));
381/* ARM 2 */
382static void do_mul PARAMS ((char *operands, unsigned long flags));
383static void do_mla PARAMS ((char *operands, unsigned long flags));
384/* ARM 3 */
385static void do_swap PARAMS ((char *operands, unsigned long flags));
386/* ARM 6 */
387static void do_msr PARAMS ((char *operands, unsigned long flags));
388static void do_mrs PARAMS ((char *operands, unsigned long flags));
c479fc62 389/* ARM 7M */
338a7060 390static void do_mull PARAMS ((char *operands, unsigned long flags));
590c50d8
ILT
391/* ARM THUMB */
392static void do_bx PARAMS ((char *operands, unsigned long flags));
c479fc62 393
338a7060
DE
394/* Coprocessor Instructions */
395static void do_cdp PARAMS ((char *operands, unsigned long flags));
396static void do_lstc PARAMS ((char *operands, unsigned long flags));
397static void do_co_reg PARAMS ((char *operands, unsigned long flags));
398static void do_fp_ctrl PARAMS ((char *operands, unsigned long flags));
399static void do_fp_ldst PARAMS ((char *operands, unsigned long flags));
400static void do_fp_ldmstm PARAMS ((char *operands, unsigned long flags));
401static void do_fp_dyadic PARAMS ((char *operands, unsigned long flags));
402static void do_fp_monadic PARAMS ((char *operands, unsigned long flags));
403static void do_fp_cmp PARAMS ((char *operands, unsigned long flags));
404static void do_fp_from_reg PARAMS ((char *operands, unsigned long flags));
405static void do_fp_to_reg PARAMS ((char *operands, unsigned long flags));
406
407static void fix_new_arm PARAMS ((fragS *frag, int where,
408 short int size, expressionS *exp,
409 int pc_rel, int reloc));
410static int arm_reg_parse PARAMS ((char **ccp));
411static int arm_psr_parse PARAMS ((char **ccp));
412
c479fc62 413/* ARM instructions take 4bytes in the object file, Thumb instructions
590c50d8
ILT
414 take 2: */
415#define INSN_SIZE 4
338a7060
DE
416
417/* LONGEST_INST is the longest basic instruction name without conditions or
418 * flags.
590c50d8 419 * ARM7M has 4 of length 5
338a7060
DE
420 */
421
422#define LONGEST_INST 5
423
424struct asm_opcode
425{
426 CONST char *template; /* Basic string to match */
427 unsigned long value; /* Basic instruction code */
428 CONST char *comp_suffix; /* Compulsory suffix that must follow conds */
429 CONST struct asm_flg *flags; /* Bits to toggle if flag 'n' set */
430 unsigned long variants; /* Which CPU variants this exists for */
431 void (*parms)(); /* Function to call to parse args */
432};
433
434static CONST struct asm_opcode insns[] =
435{
436/* ARM Instructions */
437 {"and", 0x00000000, NULL, s_flag, ARM_ANY, do_arit},
438 {"eor", 0x00200000, NULL, s_flag, ARM_ANY, do_arit},
439 {"sub", 0x00400000, NULL, s_flag, ARM_ANY, do_arit},
440 {"rsb", 0x00600000, NULL, s_flag, ARM_ANY, do_arit},
441 {"add", 0x00800000, NULL, s_flag, ARM_ANY, do_arit},
442 {"adc", 0x00a00000, NULL, s_flag, ARM_ANY, do_arit},
443 {"sbc", 0x00c00000, NULL, s_flag, ARM_ANY, do_arit},
444 {"rsc", 0x00e00000, NULL, s_flag, ARM_ANY, do_arit},
445 {"orr", 0x01800000, NULL, s_flag, ARM_ANY, do_arit},
446 {"bic", 0x01c00000, NULL, s_flag, ARM_ANY, do_arit},
447 {"tst", 0x01000000, NULL, cmp_flags, ARM_ANY, do_cmp},
448 {"teq", 0x01200000, NULL, cmp_flags, ARM_ANY, do_cmp},
449 {"cmp", 0x01400000, NULL, cmp_flags, ARM_ANY, do_cmp},
450 {"cmn", 0x01600000, NULL, cmp_flags, ARM_ANY, do_cmp},
451 {"mov", 0x01a00000, NULL, s_flag, ARM_ANY, do_mov},
452 {"mvn", 0x01e00000, NULL, s_flag, ARM_ANY, do_mov},
590c50d8
ILT
453 {"str", 0x04000000, NULL, str_flags, ARM_ANY, do_ldst},
454 {"ldr", 0x04100000, NULL, ldr_flags, ARM_ANY, do_ldst},
338a7060
DE
455 {"stm", 0x08000000, NULL, stm_flags, ARM_ANY, do_ldmstm},
456 {"ldm", 0x08100000, NULL, ldm_flags, ARM_ANY, do_ldmstm},
457 {"swi", 0x0f000000, NULL, NULL, ARM_ANY, do_swi},
590c50d8
ILT
458 {"bl", 0x0bfffffe, NULL, NULL, ARM_ANY, do_branch},
459 {"b", 0x0afffffe, NULL, NULL, ARM_ANY, do_branch},
338a7060
DE
460
461/* Pseudo ops */
462 {"adr", 0x028f0000, NULL, NULL, ARM_ANY, do_adr},
463 {"nop", 0x01a00000, NULL, NULL, ARM_ANY, do_nop},
464
465/* ARM 2 multiplies */
466 {"mul", 0x00000090, NULL, s_flag, ARM_2UP, do_mul},
467 {"mla", 0x00200090, NULL, s_flag, ARM_2UP, do_mla},
468
469/* ARM 3 - swp instructions */
470 {"swp", 0x01000090, NULL, byte_flag, ARM_3UP, do_swap},
471
472/* ARM 6 Coprocessor instructions */
473 {"mrs", 0x010f0000, NULL, NULL, ARM_6UP, do_mrs},
474 {"msr", 0x0128f000, NULL, NULL, ARM_6UP, do_msr},
475
c479fc62 476/* ARM 7M long multiplies - need signed/unsigned flags! */
338a7060
DE
477 {"smull", 0x00c00090, NULL, s_flag, ARM_LONGMUL, do_mull},
478 {"umull", 0x00800090, NULL, s_flag, ARM_LONGMUL, do_mull},
479 {"smlal", 0x00e00090, NULL, s_flag, ARM_LONGMUL, do_mull},
480 {"umlal", 0x00a00090, NULL, s_flag, ARM_LONGMUL, do_mull},
481
590c50d8
ILT
482/* ARM THUMB interworking */
483 {"bx", 0x012fff10, NULL, NULL, ARM_THUMB, do_bx},
484
338a7060
DE
485/* Floating point instructions */
486 {"wfs", 0x0e200110, NULL, NULL, FPU_ALL, do_fp_ctrl},
487 {"rfs", 0x0e300110, NULL, NULL, FPU_ALL, do_fp_ctrl},
488 {"wfc", 0x0e400110, NULL, NULL, FPU_ALL, do_fp_ctrl},
489 {"rfc", 0x0e500110, NULL, NULL, FPU_ALL, do_fp_ctrl},
490 {"ldf", 0x0c100100, "sdep", NULL, FPU_ALL, do_fp_ldst},
491 {"stf", 0x0c000100, "sdep", NULL, FPU_ALL, do_fp_ldst},
492 {"lfm", 0x0c100200, NULL, lfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
493 {"sfm", 0x0c000200, NULL, sfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
494 {"mvf", 0x0e008100, "sde", round_flags, FPU_ALL, do_fp_monadic},
495 {"mnf", 0x0e108100, "sde", round_flags, FPU_ALL, do_fp_monadic},
496 {"abs", 0x0e208100, "sde", round_flags, FPU_ALL, do_fp_monadic},
497 {"rnd", 0x0e308100, "sde", round_flags, FPU_ALL, do_fp_monadic},
498 {"sqt", 0x0e408100, "sde", round_flags, FPU_ALL, do_fp_monadic},
499 {"log", 0x0e508100, "sde", round_flags, FPU_ALL, do_fp_monadic},
500 {"lgn", 0x0e608100, "sde", round_flags, FPU_ALL, do_fp_monadic},
501 {"exp", 0x0e708100, "sde", round_flags, FPU_ALL, do_fp_monadic},
502 {"sin", 0x0e808100, "sde", round_flags, FPU_ALL, do_fp_monadic},
503 {"cos", 0x0e908100, "sde", round_flags, FPU_ALL, do_fp_monadic},
504 {"tan", 0x0ea08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
505 {"asn", 0x0eb08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
506 {"acs", 0x0ec08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
507 {"atn", 0x0ed08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
508 {"urd", 0x0ee08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
509 {"nrm", 0x0ef08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
510 {"adf", 0x0e000100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
511 {"suf", 0x0e200100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
512 {"rsf", 0x0e300100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
513 {"muf", 0x0e100100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
514 {"dvf", 0x0e400100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
515 {"rdf", 0x0e500100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
516 {"pow", 0x0e600100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
517 {"rpw", 0x0e700100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
518 {"rmf", 0x0e800100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
519 {"fml", 0x0e900100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
520 {"fdv", 0x0ea00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
521 {"frd", 0x0eb00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
522 {"pol", 0x0ec00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
523 {"cmf", 0x0e90f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
524 {"cnf", 0x0eb0f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
525/* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
526 be an optional suffix, but part of the instruction. To be compatible,
527 we accept either. */
528 {"cmfe", 0x0ed0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
529 {"cnfe", 0x0ef0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
530 {"flt", 0x0e000110, "sde", round_flags, FPU_ALL, do_fp_from_reg},
590c50d8 531 {"fix", 0x0e100110, NULL, fix_flags, FPU_ALL, do_fp_to_reg},
338a7060
DE
532
533/* Generic copressor instructions */
c479fc62
JSC
534 {"cdp", 0x0e000000, NULL, NULL, ARM_2UP, do_cdp},
535 {"ldc", 0x0c100000, NULL, cplong_flag, ARM_2UP, do_lstc},
536 {"stc", 0x0c000000, NULL, cplong_flag, ARM_2UP, do_lstc},
537 {"mcr", 0x0e000010, NULL, NULL, ARM_2UP, do_co_reg},
538 {"mrc", 0x0e100010, NULL, NULL, ARM_2UP, do_co_reg},
338a7060
DE
539};
540
541/* defines for various bits that we will want to toggle */
542
543#define INST_IMMEDIATE 0x02000000
544#define OFFSET_REG 0x02000000
c479fc62 545#define HWOFFSET_IMM 0x00400000
338a7060
DE
546#define SHIFT_BY_REG 0x00000010
547#define PRE_INDEX 0x01000000
548#define INDEX_UP 0x00800000
549#define WRITE_BACK 0x00200000
550#define MULTI_SET_PSR 0x00400000
551
552#define LITERAL_MASK 0xf000f000
553#define COND_MASK 0xf0000000
554#define OPCODE_MASK 0xfe1fffff
555#define DATA_OP_SHIFT 21
556
557/* Codes to distinguish the arithmetic instructions */
558
559#define OPCODE_AND 0
560#define OPCODE_EOR 1
561#define OPCODE_SUB 2
562#define OPCODE_RSB 3
563#define OPCODE_ADD 4
564#define OPCODE_ADC 5
565#define OPCODE_SBC 6
566#define OPCODE_RSC 7
567#define OPCODE_TST 8
568#define OPCODE_TEQ 9
569#define OPCODE_CMP 10
570#define OPCODE_CMN 11
571#define OPCODE_ORR 12
572#define OPCODE_MOV 13
573#define OPCODE_BIC 14
574#define OPCODE_MVN 15
575
590c50d8
ILT
576static void do_t_arit PARAMS ((char *operands));
577static void do_t_add PARAMS ((char *operands));
578static void do_t_asr PARAMS ((char *operands));
579static void do_t_branch PARAMS ((char *operands));
580static void do_t_bx PARAMS ((char *operands));
581static void do_t_compare PARAMS ((char *operands));
582static void do_t_ldmstm PARAMS ((char *operands));
583static void do_t_ldr PARAMS ((char *operands));
584static void do_t_ldrb PARAMS ((char *operands));
585static void do_t_ldrh PARAMS ((char *operands));
586static void do_t_lds PARAMS ((char *operands));
587static void do_t_lsl PARAMS ((char *operands));
588static void do_t_lsr PARAMS ((char *operands));
589static void do_t_mov PARAMS ((char *operands));
590static void do_t_push_pop PARAMS ((char *operands));
591static void do_t_str PARAMS ((char *operands));
592static void do_t_strb PARAMS ((char *operands));
593static void do_t_strh PARAMS ((char *operands));
594static void do_t_sub PARAMS ((char *operands));
595static void do_t_swi PARAMS ((char *operands));
596static void do_t_adr PARAMS ((char *operands));
597
598#define T_OPCODE_MUL 0x4340
599#define T_OPCODE_TST 0x4200
600#define T_OPCODE_CMN 0x42c0
601#define T_OPCODE_NEG 0x4240
602#define T_OPCODE_MVN 0x43c0
603
604#define T_OPCODE_ADD_R3 0x1800
605#define T_OPCODE_SUB_R3 0x1a00
606#define T_OPCODE_ADD_HI 0x4400
607#define T_OPCODE_ADD_ST 0xb000
608#define T_OPCODE_SUB_ST 0xb080
609#define T_OPCODE_ADD_SP 0xa800
610#define T_OPCODE_ADD_PC 0xa000
611#define T_OPCODE_ADD_I8 0x3000
612#define T_OPCODE_SUB_I8 0x3800
613#define T_OPCODE_ADD_I3 0x1c00
614#define T_OPCODE_SUB_I3 0x1e00
615
616#define T_OPCODE_ASR_R 0x4100
617#define T_OPCODE_LSL_R 0x4080
618#define T_OPCODE_LSR_R 0x40c0
619#define T_OPCODE_ASR_I 0x1000
620#define T_OPCODE_LSL_I 0x0000
621#define T_OPCODE_LSR_I 0x0800
622
623#define T_OPCODE_MOV_I8 0x2000
624#define T_OPCODE_CMP_I8 0x2800
625#define T_OPCODE_CMP_LR 0x4280
626#define T_OPCODE_MOV_HR 0x4600
627#define T_OPCODE_CMP_HR 0x4500
628
629#define T_OPCODE_LDR_PC 0x4800
630#define T_OPCODE_LDR_SP 0x9800
631#define T_OPCODE_STR_SP 0x9000
632#define T_OPCODE_LDR_IW 0x6800
633#define T_OPCODE_STR_IW 0x6000
634#define T_OPCODE_LDR_IH 0x8800
635#define T_OPCODE_STR_IH 0x8000
636#define T_OPCODE_LDR_IB 0x7800
637#define T_OPCODE_STR_IB 0x7000
638#define T_OPCODE_LDR_RW 0x5800
639#define T_OPCODE_STR_RW 0x5000
640#define T_OPCODE_LDR_RH 0x5a00
641#define T_OPCODE_STR_RH 0x5200
642#define T_OPCODE_LDR_RB 0x5c00
643#define T_OPCODE_STR_RB 0x5400
644
645#define T_OPCODE_PUSH 0xb400
646#define T_OPCODE_POP 0xbc00
647
648#define T_OPCODE_BRANCH 0xe7fe
649
650static int thumb_reg PARAMS ((char **str, int hi_lo));
651
652#define THUMB_SIZE 2 /* Size of thumb instruction */
653#define THUMB_REG_LO 0x1
654#define THUMB_REG_HI 0x2
655#define THUMB_REG_ANY 0x3
656
657#define THUMB_H1 0x0080
658#define THUMB_H2 0x0040
659
660#define THUMB_ASR 0
661#define THUMB_LSL 1
662#define THUMB_LSR 2
663
664#define THUMB_MOVE 0
665#define THUMB_COMPARE 1
666
667#define THUMB_LOAD 0
668#define THUMB_STORE 1
669
670#define THUMB_PP_PC_LR 0x0100
671
672/* These three are used for immediate shifts, do not alter */
673#define THUMB_WORD 2
674#define THUMB_HALFWORD 1
675#define THUMB_BYTE 0
676
677struct thumb_opcode
678{
679 CONST char *template; /* Basic string to match */
680 unsigned long value; /* Basic instruction code */
681 int size;
682 void (*parms)(); /* Function to call to parse args */
683};
684
685static CONST struct thumb_opcode tinsns[] =
686{
687 {"adc", 0x4140, 2, do_t_arit},
688 {"add", 0x0000, 2, do_t_add},
689 {"and", 0x4000, 2, do_t_arit},
690 {"asr", 0x0000, 2, do_t_asr},
691 {"b", T_OPCODE_BRANCH, 2, do_t_branch},
692 {"beq", 0xd0fe, 2, do_t_branch},
693 {"bne", 0xd1fe, 2, do_t_branch},
694 {"bcs", 0xd2fe, 2, do_t_branch},
695 {"bhs", 0xd2fe, 2, do_t_branch},
696 {"bcc", 0xd3fe, 2, do_t_branch},
697 {"bul", 0xd3fe, 2, do_t_branch},
698 {"blo", 0xd3fe, 2, do_t_branch},
699 {"bmi", 0xd4fe, 2, do_t_branch},
700 {"bpl", 0xd5fe, 2, do_t_branch},
701 {"bvs", 0xd6fe, 2, do_t_branch},
702 {"bvc", 0xd7fe, 2, do_t_branch},
703 {"bhi", 0xd8fe, 2, do_t_branch},
704 {"bls", 0xd9fe, 2, do_t_branch},
705 {"bge", 0xdafe, 2, do_t_branch},
706 {"blt", 0xdbfe, 2, do_t_branch},
707 {"bgt", 0xdcfe, 2, do_t_branch},
708 {"ble", 0xddfe, 2, do_t_branch},
709 {"bic", 0x4380, 2, do_t_arit},
710 {"bl", 0xf7fffffe, 4, do_t_branch},
711 {"bx", 0x4700, 2, do_t_bx},
712 {"cmn", T_OPCODE_CMN, 2, do_t_arit},
713 {"cmp", 0x0000, 2, do_t_compare},
714 {"eor", 0x4040, 2, do_t_arit},
715 {"ldmia", 0xc800, 2, do_t_ldmstm},
716 {"ldr", 0x0000, 2, do_t_ldr},
717 {"ldrb", 0x0000, 2, do_t_ldrb},
718 {"ldrh", 0x0000, 2, do_t_ldrh},
719 {"ldrsb", 0x5600, 2, do_t_lds},
720 {"ldrsh", 0x5e00, 2, do_t_lds},
721 {"ldsb", 0x5600, 2, do_t_lds},
722 {"ldsh", 0x5e00, 2, do_t_lds},
723 {"lsl", 0x0000, 2, do_t_lsl},
724 {"lsr", 0x0000, 2, do_t_lsr},
725 {"mov", 0x0000, 2, do_t_mov},
726 {"mul", T_OPCODE_MUL, 2, do_t_arit},
727 {"mvn", T_OPCODE_MVN, 2, do_t_arit},
728 {"neg", T_OPCODE_NEG, 2, do_t_arit},
729 {"orr", 0x4300, 2, do_t_arit},
730 {"pop", 0xbc00, 2, do_t_push_pop},
731 {"push", 0xb400, 2, do_t_push_pop},
732 {"ror", 0x41c0, 2, do_t_arit},
733 {"sbc", 0x4180, 2, do_t_arit},
734 {"stmia", 0xc000, 2, do_t_ldmstm},
735 {"str", 0x0000, 2, do_t_str},
736 {"strb", 0x0000, 2, do_t_strb},
737 {"strh", 0x0000, 2, do_t_strh},
738 {"swi", 0xdf00, 2, do_t_swi},
739 {"sub", 0x0000, 2, do_t_sub},
740 {"tst", T_OPCODE_TST, 2, do_t_arit},
741 /* Pseudo ops: */
742 {"adr", 0x0000, 2, do_t_adr},
743 {"nop", 0x0000, 2, do_nop},
744};
745
338a7060
DE
746struct reg_entry
747{
748 CONST char *name;
749 int number;
750};
751
752#define int_register(reg) ((reg) >= 0 && (reg) <= 15)
753#define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
754#define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
755
756#define REG_PC 15
590c50d8
ILT
757#define REG_LR 14
758#define REG_SP 13
338a7060
DE
759
760/* These are the standard names; Users can add aliases with .req */
761static CONST struct reg_entry reg_table[] =
762{
763 /* Processor Register Numbers */
590c50d8
ILT
764 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
765 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
766 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
767 {"r12", 12}, {"r13", REG_SP},{"r14", REG_LR},{"r15", REG_PC},
338a7060 768 /* APCS conventions */
590c50d8
ILT
769 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
770 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
771 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
772 {"fp", 11}, {"ip", 12}, {"sp", REG_SP},{"lr", REG_LR},{"pc", REG_PC},
338a7060
DE
773 /* FP Registers */
774 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
775 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
776 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
777 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
778 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
779 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
780 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
781 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
782 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
783 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
784 {NULL, 0}
785};
786
787static CONST char *bad_args = "Bad arguments to instruction";
788static CONST char *bad_pc = "r15 not allowed here";
789
790static struct hash_control *arm_ops_hsh = NULL;
590c50d8 791static struct hash_control *arm_tops_hsh = NULL;
338a7060
DE
792static struct hash_control *arm_cond_hsh = NULL;
793static struct hash_control *arm_shift_hsh = NULL;
794static struct hash_control *arm_reg_hsh = NULL;
795static struct hash_control *arm_psr_hsh = NULL;
796
797/* This table describes all the machine specific pseudo-ops the assembler
798 has to support. The fields are:
799 pseudo-op name without dot
800 function to call to execute this pseudo-op
801 Integer arg to pass to the function
802 */
803
804static void s_req PARAMS ((int));
805static void s_align PARAMS ((int));
806static void s_bss PARAMS ((int));
807static void s_even PARAMS ((int));
808static void s_ltorg PARAMS ((int));
590c50d8
ILT
809static void s_arm PARAMS ((int));
810static void s_thumb PARAMS ((int));
811static void s_code PARAMS ((int));
338a7060
DE
812
813static int my_get_expression PARAMS ((expressionS *, char **));
814
815CONST pseudo_typeS md_pseudo_table[] =
816{
817 {"req", s_req, 0}, /* Never called becasue '.req' does not start line */
818 {"bss", s_bss, 0},
819 {"align", s_align, 0},
590c50d8
ILT
820 {"arm", s_arm, 0},
821 {"thumb", s_thumb, 0},
822 {"code", s_code, 0},
338a7060
DE
823 {"even", s_even, 0},
824 {"ltorg", s_ltorg, 0},
825 {"pool", s_ltorg, 0},
826 {"word", cons, 4},
827 {"extend", float_cons, 'x'},
828 {"ldouble", float_cons, 'x'},
829 {"packed", float_cons, 'p'},
830 {0, 0, 0}
831};
832
833/* Stuff needed to resolve the label ambiguity
834 As:
835 ...
836 label: <insn>
837 may differ from:
838 ...
839 label:
840 <insn>
841*/
842
843symbolS *last_label_seen;
844
845/* Literal stuff */
846
847#define MAX_LITERAL_POOL_SIZE 1024
848
849typedef struct literalS
850{
851 struct expressionS exp;
852 struct arm_it *inst;
853} literalT;
854
855literalT literals[MAX_LITERAL_POOL_SIZE];
856int next_literal_pool_place = 0; /* Next free entry in the pool */
857int lit_pool_num = 1; /* Next literal pool number */
858symbolS *current_poolP = NULL;
859symbolS *symbol_make_empty ();
860
861static int
862add_to_lit_pool ()
863{
c479fc62
JSC
864 int lit_count = 0;
865
338a7060
DE
866 if (current_poolP == NULL)
867 current_poolP = symbol_make_empty();
868
c479fc62
JSC
869 /* Check if this literal value is already in the pool: */
870 while (lit_count < next_literal_pool_place)
338a7060 871 {
c479fc62
JSC
872 if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op
873 && inst.reloc.exp.X_op == O_constant
874 && literals[lit_count].exp.X_add_number == inst.reloc.exp.X_add_number
875 && literals[lit_count].exp.X_unsigned == inst.reloc.exp.X_unsigned)
876 break;
877 lit_count++;
878 }
879
880 if (lit_count == next_literal_pool_place) /* new entry */
881 {
882 if (next_literal_pool_place > MAX_LITERAL_POOL_SIZE)
883 {
884 inst.error = "Literal Pool Overflow\n";
885 return FAIL;
886 }
887
888 literals[next_literal_pool_place].exp = inst.reloc.exp;
889 lit_count = next_literal_pool_place++;
338a7060
DE
890 }
891
338a7060 892 inst.reloc.exp.X_op = O_symbol;
c479fc62 893 inst.reloc.exp.X_add_number = (lit_count)*4-8;
338a7060
DE
894 inst.reloc.exp.X_add_symbol = current_poolP;
895
896 return SUCCESS;
897}
898
899/* Can't use symbol_new here, so have to create a symbol and them at
590c50d8 900 a later date assign it a value. Thats what these functions do */
338a7060
DE
901static void
902symbol_locate (symbolP, name, segment, valu, frag)
903 symbolS *symbolP;
904 CONST char *name; /* It is copied, the caller can modify */
905 segT segment; /* Segment identifier (SEG_<something>) */
906 valueT valu; /* Symbol value */
907 fragS *frag; /* Associated fragment */
908{
909 unsigned int name_length;
910 char *preserved_copy_of_name;
911
912 name_length = strlen (name) + 1; /* +1 for \0 */
913 obstack_grow (&notes, name, name_length);
914 preserved_copy_of_name = obstack_finish (&notes);
915#ifdef STRIP_UNDERSCORE
916 if (preserved_copy_of_name[0] == '_')
917 preserved_copy_of_name++;
918#endif
919
920#ifdef tc_canonicalize_symbol_name
921 preserved_copy_of_name =
922 tc_canonicalize_symbol_name (preserved_copy_of_name);
923#endif
924
925 S_SET_NAME (symbolP, preserved_copy_of_name);
926
927 S_SET_SEGMENT (symbolP, segment);
928 S_SET_VALUE (symbolP, valu);
929 symbol_clear_list_pointers(symbolP);
930
931 symbolP->sy_frag = frag;
932
933 /*
934 * Link to end of symbol chain.
935 */
936 {
937 extern int symbol_table_frozen;
938 if (symbol_table_frozen)
939 abort ();
940 }
941
942 symbol_append (symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP);
943
944 obj_symbol_new_hook (symbolP);
945
946#ifdef tc_symbol_new_hook
947 tc_symbol_new_hook (symbolP);
948#endif
949
950#ifdef DEBUG_SYMS
951 verify_symbol_chain(symbol_rootP, symbol_lastP);
952#endif /* DEBUG_SYMS */
953}
954
955symbolS *
956symbol_make_empty ()
957{
958 symbolS *symbolP;
959
960 symbolP = (symbolS *) obstack_alloc (&notes, sizeof (symbolS));
961
962 /* symbol must be born in some fixed state. This seems as good as any. */
963 memset (symbolP, 0, sizeof (symbolS));
964
338a7060
DE
965 symbolP->bsym = bfd_make_empty_symbol (stdoutput);
966 assert (symbolP->bsym != 0);
967 symbolP->bsym->udata.p = (PTR) symbolP;
338a7060
DE
968
969 return symbolP;
970}
971
972/* Check that an immediate is valid, and if so, convert it to the right format
973 */
974
975/* OH, for a rotate instruction in C! */
976
977static int
978validate_immediate (val)
979 int val;
980{
981 unsigned int a = (unsigned int) val;
982 int i;
983
984 /* Do the easy (and most common ones) quickly */
985 for (i = 0; i <= 24; i += 2)
986 {
987 if ((a & (0xff << i)) == a)
988 return (int) (((32 - i) & 0x1e) << 7) | ((a >> i) & 0xff);
989 }
990
991 /* Now do the harder ones */
992 for (; i < 32; i += 2)
993 {
994 if ((a & ((0xff << i) | (0xff >> (32 - i)))) == a)
995 {
996 a = ((a >> i) & 0xff) | ((a << (32 - i)) & 0xff);
997 return (int) a | (((32 - i) >> 1) << 8);
998 }
999 }
1000 return FAIL;
1001}
1002
1003static int
c479fc62 1004validate_offset_imm (val, hwse)
338a7060 1005 int val;
c479fc62 1006 int hwse;
338a7060 1007{
c479fc62
JSC
1008 if ((hwse && (val < -255 || val > 255))
1009 || (val < -4095 || val > 4095))
1010 return FAIL;
338a7060
DE
1011 return val;
1012}
1013
1014
1015static void
1016s_req (a)
1017 int a;
1018{
1019 as_bad ("Invalid syntax for .req directive.");
1020}
1021
1022static void
1023s_bss (ignore)
1024 int ignore;
1025{
1026 /* We don't support putting frags in the BSS segment, we fake it by
1027 marking in_bss, then looking at s_skip for clues?.. */
1028 subseg_set (bss_section, 0);
1029 demand_empty_rest_of_line ();
1030}
1031
1032static void
1033s_even (ignore)
1034 int ignore;
1035{
1036 if (!need_pass_2) /* Never make frag if expect extra pass. */
590c50d8 1037 frag_align (1, 0, 0);
338a7060
DE
1038 record_alignment (now_seg, 1);
1039 demand_empty_rest_of_line ();
1040}
1041
1042static void
1043s_ltorg (internal)
1044 int internal;
1045{
1046 int lit_count = 0;
1047 char sym_name[20];
1048
1049 if (current_poolP == NULL)
1050 {
1051 /* Nothing to do */
1052 if (!internal)
1053 as_tsktsk ("Nothing to put in the pool\n");
1054 return;
1055 }
1056
1057 /* Align pool as you have word accesses */
1058 /* Only make a frag if we have to ... */
1059 if (!need_pass_2)
590c50d8 1060 frag_align (2, 0, 0);
338a7060
DE
1061
1062 record_alignment (now_seg, 2);
1063
1064 if (internal)
1065 as_tsktsk ("Inserting implicit pool at change of section");
1066
1067 sprintf (sym_name, "$$lit_\002%x", lit_pool_num++);
1068
1069 symbol_locate (current_poolP, sym_name, now_seg,
c479fc62 1070 (valueT) frag_now_fix (), frag_now);
338a7060
DE
1071 symbol_table_insert (current_poolP);
1072
1073 while (lit_count < next_literal_pool_place)
1074 /* First output the expression in the instruction to the pool */
1075 emit_expr (&(literals[lit_count++].exp), 4); /* .word */
1076
1077 next_literal_pool_place = 0;
1078 current_poolP = NULL;
1079}
1080
c479fc62 1081#if 0 /* not used */
338a7060
DE
1082static void
1083arm_align (power, fill)
1084 int power;
1085 int fill;
1086{
1087 /* Only make a frag if we HAVE to ... */
1088 if (power && !need_pass_2)
590c50d8 1089 frag_align (power, fill, 0);
338a7060
DE
1090
1091 record_alignment (now_seg, power);
1092}
c479fc62 1093#endif
338a7060
DE
1094
1095static void
1096s_align (unused) /* Same as s_align_ptwo but align 0 => align 2 */
1097 int unused;
1098{
1099 register int temp;
1100 register long temp_fill;
1101 long max_alignment = 15;
1102
1103 temp = get_absolute_expression ();
1104 if (temp > max_alignment)
1105 as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
1106 else if (temp < 0)
1107 {
1108 as_bad ("Alignment negative. 0 assumed.");
1109 temp = 0;
1110 }
1111
1112 if (*input_line_pointer == ',')
1113 {
1114 input_line_pointer++;
1115 temp_fill = get_absolute_expression ();
1116 }
1117 else
1118 temp_fill = 0;
1119
1120 if (!temp)
1121 temp = 2;
1122
1123 /* Only make a frag if we HAVE to. . . */
1124 if (temp && !need_pass_2)
590c50d8 1125 frag_align (temp, (int) temp_fill, 0);
338a7060
DE
1126 demand_empty_rest_of_line ();
1127
1128 record_alignment (now_seg, temp);
1129}
1130
590c50d8
ILT
1131static void
1132opcode_select (width)
1133 int width;
1134{
1135 switch (width)
1136 {
1137 case 16:
1138 if (! thumb_mode)
1139 {
1140 if (! (cpu_variant & ARM_THUMB))
1141 as_bad ("selected processor does not support THUMB opcodes");
1142 thumb_mode = 1;
1143 /* No need to force the alignment, since we will have been
1144 coming from ARM mode, which is word-aligned. */
1145 record_alignment (now_seg, 1);
1146 }
1147 break;
1148
1149 case 32:
1150 if (thumb_mode)
1151 {
1152 if ((cpu_variant & ARM_ANY) == ARM_THUMB)
1153 as_bad ("selected processor does not support ARM opcodes");
1154 thumb_mode = 0;
1155 if (!need_pass_2)
1156 frag_align (2, 0, 0);
1157 record_alignment (now_seg, 1);
1158 }
1159 break;
1160
1161 default:
1162 as_bad ("invalid instruction size selected (%d)", width);
1163 }
1164}
1165
1166static void
1167s_arm (ignore)
1168 int ignore;
1169{
1170 opcode_select (32);
1171 demand_empty_rest_of_line ();
1172}
1173
1174static void
1175s_thumb (ignore)
1176 int ignore;
1177{
1178 opcode_select (16);
1179 demand_empty_rest_of_line ();
1180}
1181
1182static void
1183s_code (unused)
1184 int unused;
1185{
1186 register int temp;
1187
1188 temp = get_absolute_expression ();
1189 switch (temp)
1190 {
1191 case 16:
1192 case 32:
1193 opcode_select(temp);
1194 break;
1195
1196 default:
1197 as_bad ("invalid operand to .code directive (%d)", temp);
1198 }
1199}
1200
338a7060
DE
1201static void
1202end_of_line (str)
1203 char *str;
1204{
1205 while (*str == ' ')
1206 str++;
1207
1208 if (*str != '\0')
1209 inst.error = "Garbage following instruction";
1210}
1211
1212static int
1213skip_past_comma (str)
1214 char **str;
1215{
1216 char *p = *str, c;
1217 int comma = 0;
1218
1219 while ((c = *p) == ' ' || c == ',')
1220 {
1221 p++;
1222 if (c == ',' && comma++)
1223 return FAIL;
1224 }
1225
1226 if (c == '\0')
1227 return FAIL;
1228
1229 *str = p;
1230 return comma ? SUCCESS : FAIL;
1231}
1232
1233/* A standard register must be given at this point. Shift is the place to
1234 put it in the instruction. */
1235
1236static int
1237reg_required_here (str, shift)
1238 char **str;
1239 int shift;
1240{
1241 int reg;
1242 char *start = *str;
1243
1244 if ((reg = arm_reg_parse (str)) != FAIL && int_register (reg))
1245 {
1246 inst.instruction |= reg << shift;
1247 return reg;
1248 }
1249
1250 /* In the few cases where we might be able to accept something else
1251 this error can be overridden */
1252 inst.error = "Register expected";
1253
1254 /* Restore the start point, we may have got a reg of the wrong class. */
1255 *str = start;
1256 return FAIL;
1257}
1258
1259static int
1260psr_required_here (str, shift)
1261 char **str;
1262 int shift;
1263{
1264 int psr;
1265 char *start = *str;
1266
1267 if ((psr = arm_psr_parse (str)) != FAIL && psr < 2)
1268 {
1269 if (psr == 1)
1270 inst.instruction |= 1 << shift; /* Should be bit 22 */
1271 return psr;
1272 }
1273
1274 /* In the few cases where we might be able to accept something else
1275 this error can be overridden */
1276 inst.error = "<psr> expected";
1277
1278 /* Restore the start point. */
1279 *str = start;
1280 return FAIL;
1281}
1282
1283static int
1284psrf_required_here (str, shift)
1285 char **str;
1286 int shift;
1287{
1288 int psrf;
1289 char *start = *str;
1290
1291 if ((psrf = arm_psr_parse (str)) != FAIL && psrf > 1)
1292 {
1293 if (psrf == 1 || psrf == 3)
1294 inst.instruction |= 1 << shift; /* Should be bit 22 */
1295 return psrf;
1296 }
1297
1298 /* In the few cases where we might be able to accept something else
1299 this error can be overridden */
1300 inst.error = "<psrf> expected";
1301
1302 /* Restore the start point. */
1303 *str = start;
1304 return FAIL;
1305}
1306
1307static int
1308co_proc_number (str)
1309 char **str;
1310{
1311 int processor, pchar;
1312
1313 while (**str == ' ')
1314 (*str)++;
1315
1316 /* The data sheet seems to imply that just a number on its own is valid
1317 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1318 accept either. */
1319 if (**str == 'p' || **str == 'P')
1320 (*str)++;
1321
1322 pchar = *(*str)++;
1323 if (pchar >= '0' && pchar <= '9')
1324 {
1325 processor = pchar - '0';
1326 if (**str >= '0' && **str <= '9')
1327 {
1328 processor = processor * 10 + *(*str)++ - '0';
1329 if (processor > 15)
1330 {
1331 inst.error = "Illegal co-processor number";
1332 return FAIL;
1333 }
1334 }
1335 }
1336 else
1337 {
1338 inst.error = "Bad or missing co-processor number";
1339 return FAIL;
1340 }
1341
1342 inst.instruction |= processor << 8;
1343 return SUCCESS;
1344}
1345
1346static int
1347cp_opc_expr (str, where, length)
1348 char **str;
1349 int where;
1350 int length;
1351{
1352 expressionS expr;
1353
1354 while (**str == ' ')
1355 (*str)++;
1356
1357 memset (&expr, '\0', sizeof (expr));
1358
1359 if (my_get_expression (&expr, str))
1360 return FAIL;
1361 if (expr.X_op != O_constant)
1362 {
1363 inst.error = "bad or missing expression";
1364 return FAIL;
1365 }
1366
1367 if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
1368 {
1369 inst.error = "immediate co-processor expression too large";
1370 return FAIL;
1371 }
1372
1373 inst.instruction |= expr.X_add_number << where;
1374 return SUCCESS;
1375}
1376
1377static int
1378cp_reg_required_here (str, where)
1379 char **str;
1380 int where;
1381{
1382 int reg;
1383 char *start = *str;
1384
1385 if ((reg = arm_reg_parse (str)) != FAIL && cp_register (reg))
1386 {
1387 reg &= 15;
1388 inst.instruction |= reg << where;
1389 return reg;
1390 }
1391
1392 /* In the few cases where we might be able to accept something else
1393 this error can be overridden */
1394 inst.error = "Co-processor register expected";
1395
1396 /* Restore the start point */
1397 *str = start;
1398 return FAIL;
1399}
1400
1401static int
1402fp_reg_required_here (str, where)
1403 char **str;
1404 int where;
1405{
1406 int reg;
1407 char *start = *str;
1408
1409 if ((reg = arm_reg_parse (str)) != FAIL && fp_register (reg))
1410 {
1411 reg &= 7;
1412 inst.instruction |= reg << where;
1413 return reg;
1414 }
1415
1416 /* In the few cases where we might be able to accept something else
1417 this error can be overridden */
1418 inst.error = "Floating point register expected";
1419
1420 /* Restore the start point */
1421 *str = start;
1422 return FAIL;
1423}
1424
1425static int
1426cp_address_offset (str)
1427 char **str;
1428{
1429 int offset;
1430
1431 while (**str == ' ')
1432 (*str)++;
1433
1434 if (**str != '#')
1435 {
1436 inst.error = "immediate expression expected";
1437 return FAIL;
1438 }
1439
1440 (*str)++;
1441 if (my_get_expression (&inst.reloc.exp, str))
1442 return FAIL;
1443 if (inst.reloc.exp.X_op == O_constant)
1444 {
1445 offset = inst.reloc.exp.X_add_number;
1446 if (offset & 3)
1447 {
1448 inst.error = "co-processor address must be word aligned";
1449 return FAIL;
1450 }
1451
1452 if (offset > 1023 || offset < -1023)
1453 {
1454 inst.error = "offset too large";
1455 return FAIL;
1456 }
1457
1458 if (offset >= 0)
1459 inst.instruction |= INDEX_UP;
1460 else
1461 offset = -offset;
1462
1463 inst.instruction |= offset >> 2;
1464 }
1465 else
1466 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1467
1468 return SUCCESS;
1469}
1470
1471static int
1472cp_address_required_here (str)
1473 char **str;
1474{
1475 char *p = *str;
1476 int pre_inc = 0;
1477 int write_back = 0;
1478
1479 if (*p == '[')
1480 {
1481 int reg;
1482
1483 p++;
1484 while (*p == ' ')
1485 p++;
1486
1487 if ((reg = reg_required_here (&p, 16)) == FAIL)
1488 {
1489 inst.error = "Register required";
1490 return FAIL;
1491 }
1492
1493 while (*p == ' ')
1494 p++;
1495
1496 if (*p == ']')
1497 {
1498 p++;
1499 if (skip_past_comma (&p) == SUCCESS)
1500 {
1501 /* [Rn], #expr */
1502 write_back = WRITE_BACK;
1503 if (reg == REG_PC)
1504 {
1505 inst.error = "pc may not be used in post-increment";
1506 return FAIL;
1507 }
1508
1509 if (cp_address_offset (&p) == FAIL)
1510 return FAIL;
1511 }
1512 else
1513 pre_inc = PRE_INDEX | INDEX_UP;
1514 }
1515 else
1516 {
1517 /* '['Rn, #expr']'[!] */
1518
1519 if (skip_past_comma (&p) == FAIL)
1520 {
1521 inst.error = "pre-indexed expression expected";
1522 return FAIL;
1523 }
1524
1525 pre_inc = PRE_INDEX;
1526 if (cp_address_offset (&p) == FAIL)
1527 return FAIL;
1528
1529 while (*p == ' ')
1530 p++;
1531
1532 if (*p++ != ']')
1533 {
1534 inst.error = "missing ]";
1535 return FAIL;
1536 }
1537
1538 while (*p == ' ')
1539 p++;
1540
1541 if (*p == '!')
1542 {
1543 if (reg == REG_PC)
1544 {
1545 inst.error = "pc may not be used with write-back";
1546 return FAIL;
1547 }
1548
1549 p++;
1550 write_back = WRITE_BACK;
1551 }
1552 }
1553 }
1554 else
1555 {
1556 if (my_get_expression (&inst.reloc.exp, &p))
1557 return FAIL;
1558
1559 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1560 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
1561 inst.reloc.pc_rel = 1;
1562 inst.instruction |= (REG_PC << 16);
c479fc62 1563 pre_inc = PRE_INDEX;
338a7060
DE
1564 }
1565
1566 inst.instruction |= write_back | pre_inc;
1567 *str = p;
1568 return SUCCESS;
1569}
1570
1571static void
1572do_nop (str, flags)
1573 char *str;
1574 unsigned long flags;
1575{
1576 /* Do nothing really */
1577 inst.instruction |= flags; /* This is pointless */
1578 end_of_line (str);
1579 return;
1580}
1581
1582static void
1583do_mrs (str, flags)
1584 char *str;
1585 unsigned long flags;
1586{
1587 /* Only one syntax */
1588 while (*str == ' ')
1589 str++;
1590
1591 if (reg_required_here (&str, 12) == FAIL)
1592 {
1593 inst.error = bad_args;
1594 return;
1595 }
1596
1597 if (skip_past_comma (&str) == FAIL
1598 || psr_required_here (&str, 22) == FAIL)
1599 {
1600 inst.error = "<psr> expected";
1601 return;
1602 }
1603
1604 inst.instruction |= flags;
1605 end_of_line (str);
1606 return;
1607}
1608
1609static void
1610do_msr (str, flags)
1611 char *str;
1612 unsigned long flags;
1613{
1614 int psr, psrf, reg;
1615 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression" */
1616
1617 while (*str == ' ')
1618 str++;
1619
1620 if ((psr = psr_required_here (&str, 22)) != FAIL)
1621 {
1622 inst.instruction |= PSR_ALL;
1623 /* Sytax should be "<psr>, Rm" */
1624 if (skip_past_comma (&str) == FAIL
1625 || (reg = reg_required_here (&str, 0)) == FAIL)
1626 {
1627 inst.error = bad_args;
1628 return;
1629 }
1630 }
1631 else if ((psrf = psrf_required_here (&str, 22)) != FAIL)
1632 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1633 {
1634 if (skip_past_comma (&str) == FAIL)
1635 {
1636 inst.error = bad_args;
1637 return;
1638 }
1639 if ((reg = reg_required_here (&str, 0)) != FAIL)
1640 ;
1641 /* Immediate expression */
1642 else if (*(str++) == '#')
1643 {
1644 inst.error = NULL;
1645 if (my_get_expression (&inst.reloc.exp, &str))
1646 {
1647 inst.error = "Register or shift expression expected";
1648 return;
1649 }
1650
1651 if (inst.reloc.exp.X_add_symbol)
1652 {
1653 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
1654 inst.reloc.pc_rel = 0;
1655 }
1656 else
1657 {
1658 int value = validate_immediate (inst.reloc.exp.X_add_number);
1659 if (value == FAIL)
1660 {
1661 inst.error = "Invalid constant";
1662 return;
1663 }
1664
1665 inst.instruction |= value;
1666 }
1667
1668 flags |= INST_IMMEDIATE;
1669 }
1670 else
1671 {
1672 inst.error = "Error: the other";
1673 return;
1674 }
1675 }
1676 else
1677 {
1678 inst.error = bad_args;
1679 return;
1680 }
1681
1682 inst.error = NULL;
1683 inst.instruction |= flags;
1684 end_of_line (str);
1685 return;
1686}
1687
1688/* Long Multiply Parser
1689 UMULL RdLo, RdHi, Rm, Rs
1690 SMULL RdLo, RdHi, Rm, Rs
1691 UMLAL RdLo, RdHi, Rm, Rs
1692 SMLAL RdLo, RdHi, Rm, Rs
1693*/
1694static void
1695do_mull (str, flags)
1696 char *str;
1697 unsigned long flags;
1698{
1699 int rdlo, rdhi, rm, rs;
1700
1701 /* only one format "rdlo, rdhi, rm, rs" */
1702 while (*str == ' ')
1703 str++;
1704
1705 if ((rdlo = reg_required_here (&str, 12)) == FAIL)
1706 {
1707 inst.error = bad_args;
1708 return;
1709 }
1710
1711 if (skip_past_comma (&str) == FAIL
1712 || (rdhi = reg_required_here (&str, 16)) == FAIL)
1713 {
1714 inst.error = bad_args;
1715 return;
1716 }
1717
1718 if (skip_past_comma (&str) == FAIL
1719 || (rm = reg_required_here (&str, 0)) == FAIL)
1720 {
1721 inst.error = bad_args;
1722 return;
1723 }
1724
1725 /* rdhi, rdlo and rm must all be different */
1726 if (rdlo == rdhi || rdlo == rm || rdhi == rm)
1727 as_tsktsk ("rdhi, rdlo and rm must all be different");
1728
1729 if (skip_past_comma (&str) == FAIL
1730 || (rs = reg_required_here (&str, 8)) == FAIL)
1731 {
1732 inst.error = bad_args;
1733 return;
1734 }
1735
1736 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
1737 {
1738 inst.error = bad_pc;
1739 return;
1740 }
1741
1742 inst.instruction |= flags;
1743 end_of_line (str);
1744 return;
1745}
1746
1747static void
1748do_mul (str, flags)
1749 char *str;
1750 unsigned long flags;
1751{
1752 int rd, rm;
1753
1754 /* only one format "rd, rm, rs" */
1755 while (*str == ' ')
1756 str++;
1757
1758 if ((rd = reg_required_here (&str, 16)) == FAIL)
1759 {
1760 inst.error = bad_args;
1761 return;
1762 }
1763
1764 if (rd == REG_PC)
1765 {
1766 inst.error = bad_pc;
1767 return;
1768 }
1769
1770 if (skip_past_comma (&str) == FAIL
1771 || (rm = reg_required_here (&str, 0)) == FAIL)
1772 {
1773 inst.error = bad_args;
1774 return;
1775 }
1776
1777 if (rm == REG_PC)
1778 {
1779 inst.error = bad_pc;
1780 return;
1781 }
1782
1783 if (rm == rd)
1784 as_tsktsk ("rd and rm should be different in mul");
1785
1786 if (skip_past_comma (&str) == FAIL
1787 || (rm = reg_required_here (&str, 8)) == FAIL)
1788 {
1789 inst.error = bad_args;
1790 return;
1791 }
1792
1793 if (rm == REG_PC)
1794 {
1795 inst.error = bad_pc;
1796 return;
1797 }
1798
1799 inst.instruction |= flags;
1800 end_of_line (str);
1801 return;
1802}
1803
1804static void
1805do_mla (str, flags)
1806 char *str;
1807 unsigned long flags;
1808{
1809 int rd, rm;
1810
1811 /* only one format "rd, rm, rs, rn" */
1812 while (*str == ' ')
1813 str++;
1814
1815 if ((rd = reg_required_here (&str, 16)) == FAIL)
1816 {
1817 inst.error = bad_args;
1818 return;
1819 }
1820
1821 if (rd == REG_PC)
1822 {
1823 inst.error = bad_pc;
1824 return;
1825 }
1826
1827 if (skip_past_comma (&str) == FAIL
1828 || (rm = reg_required_here (&str, 0)) == FAIL)
1829 {
1830 inst.error = bad_args;
1831 return;
1832 }
1833
1834 if (rm == REG_PC)
1835 {
1836 inst.error = bad_pc;
1837 return;
1838 }
1839
1840 if (rm == rd)
1841 as_tsktsk ("rd and rm should be different in mla");
1842
1843 if (skip_past_comma (&str) == FAIL
1844 || (rd = reg_required_here (&str, 8)) == FAIL
1845 || skip_past_comma (&str) == FAIL
1846 || (rm = reg_required_here (&str, 12)) == FAIL)
1847 {
1848 inst.error = bad_args;
1849 return;
1850 }
1851
1852 if (rd == REG_PC || rm == REG_PC)
1853 {
1854 inst.error = bad_pc;
1855 return;
1856 }
1857
1858 inst.instruction |= flags;
1859 end_of_line (str);
1860 return;
1861}
1862
1863/* Returns the index into fp_values of a floating point number, or -1 if
1864 not in the table. */
1865static int
1866my_get_float_expression (str)
1867 char **str;
1868{
1869 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1870 char *save_in;
1871 expressionS exp;
1872 int i, j;
1873
1874 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
1875 /* Look for a raw floating point number */
1876 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
1877 && (is_end_of_line [(int)(*save_in)] || *save_in == '\0'))
1878 {
1879 for (i = 0; i < NUM_FLOAT_VALS; i++)
1880 {
1881 for (j = 0; j < MAX_LITTLENUMS; j++)
1882 {
1883 if (words[j] != fp_values[i][j])
1884 break;
1885 }
1886
1887 if (j == MAX_LITTLENUMS)
1888 {
1889 *str = save_in;
1890 return i;
1891 }
1892 }
1893 }
1894
1895 /* Try and parse a more complex expression, this will probably fail
1896 unless the code uses a floating point prefix (eg "0f") */
1897 save_in = input_line_pointer;
1898 input_line_pointer = *str;
1899 if (expression (&exp) == absolute_section
1900 && exp.X_op == O_big
1901 && exp.X_add_number < 0)
1902 {
c479fc62
JSC
1903 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
1904 Ditto for 15. */
1905 if (gen_to_words (words, 5, (long)15) == 0)
338a7060
DE
1906 {
1907 for (i = 0; i < NUM_FLOAT_VALS; i++)
1908 {
1909 for (j = 0; j < MAX_LITTLENUMS; j++)
1910 {
1911 if (words[j] != fp_values[i][j])
1912 break;
1913 }
1914
1915 if (j == MAX_LITTLENUMS)
1916 {
1917 *str = input_line_pointer;
1918 input_line_pointer = save_in;
1919 return i;
1920 }
1921 }
1922 }
1923 }
1924
1925 *str = input_line_pointer;
1926 input_line_pointer = save_in;
1927 return -1;
1928}
1929
1930/* Return true if anything in the expression is a bignum */
1931static int
1932walk_no_bignums (sp)
1933 symbolS *sp;
1934{
1935 if (sp->sy_value.X_op == O_big)
1936 return 1;
1937
1938 if (sp->sy_value.X_add_symbol)
1939 {
1940 return (walk_no_bignums (sp->sy_value.X_add_symbol)
1941 || (sp->sy_value.X_op_symbol
1942 && walk_no_bignums (sp->sy_value.X_op_symbol)));
1943 }
1944
1945 return 0;
1946}
1947
1948static int
1949my_get_expression (ep, str)
1950 expressionS *ep;
1951 char **str;
1952{
1953 char *save_in;
1954 segT seg;
1955
1956 save_in = input_line_pointer;
1957 input_line_pointer = *str;
1958 seg = expression (ep);
c479fc62
JSC
1959
1960#ifdef OBJ_AOUT
338a7060
DE
1961 if (seg != absolute_section
1962 && seg != text_section
1963 && seg != data_section
1964 && seg != bss_section
1965 && seg != undefined_section)
1966 {
1967 inst.error = "bad_segment";
1968 *str = input_line_pointer;
1969 input_line_pointer = save_in;
1970 return 1;
1971 }
c479fc62 1972#endif
338a7060
DE
1973
1974 /* Get rid of any bignums now, so that we don't generate an error for which
1975 we can't establish a line number later on. Big numbers are never valid
c479fc62 1976 in instructions, which is where this routine is always called. */
338a7060
DE
1977 if (ep->X_op == O_big
1978 || (ep->X_add_symbol
1979 && (walk_no_bignums (ep->X_add_symbol)
1980 || (ep->X_op_symbol
1981 && walk_no_bignums (ep->X_op_symbol)))))
1982 {
1983 inst.error = "Invalid constant";
1984 *str = input_line_pointer;
1985 input_line_pointer = save_in;
1986 return 1;
1987 }
1988
1989 *str = input_line_pointer;
1990 input_line_pointer = save_in;
1991 return 0;
1992}
1993
1994/* unrestrict should be one if <shift> <register> is permitted for this
1995 instruction */
1996
1997static int
1998decode_shift (str, unrestrict)
1999 char **str;
2000 int unrestrict;
2001{
2002 struct asm_shift *shft;
2003 char *p;
2004 char c;
2005
2006 while (**str == ' ')
2007 (*str)++;
2008
2009 for (p = *str; isalpha (*p); p++)
2010 ;
2011
2012 if (p == *str)
2013 {
2014 inst.error = "Shift expression expected";
2015 return FAIL;
2016 }
2017
2018 c = *p;
2019 *p = '\0';
2020 shft = (struct asm_shift *) hash_find (arm_shift_hsh, *str);
2021 *p = c;
2022 if (shft)
2023 {
590c50d8
ILT
2024 if (!strcmp (*str, "rrx")
2025 || !strcmp (*str, "RRX"))
338a7060
DE
2026 {
2027 *str = p;
2028 inst.instruction |= shft->value;
2029 return SUCCESS;
2030 }
2031
2032 while (*p == ' ')
2033 p++;
2034
2035 if (unrestrict && reg_required_here (&p, 8) != FAIL)
2036 {
2037 inst.instruction |= shft->value | SHIFT_BY_REG;
2038 *str = p;
2039 return SUCCESS;
2040 }
2041 else if (*p == '#')
2042 {
2043 inst.error = NULL;
2044 p++;
2045 if (my_get_expression (&inst.reloc.exp, &p))
2046 return FAIL;
2047
2048 /* Validate some simple #expressions */
590c50d8 2049 if (inst.reloc.exp.X_op == O_constant)
338a7060 2050 {
590c50d8
ILT
2051 unsigned num = inst.reloc.exp.X_add_number;
2052
2053 /* Reject operations greater than 32, or lsl #32 */
2054 if (num > 32 || (num == 32 && shft->value == 0))
338a7060
DE
2055 {
2056 inst.error = "Invalid immediate shift";
2057 return FAIL;
2058 }
2059
2060 /* Shifts of zero should be converted to lsl (which is zero)*/
2061 if (num == 0)
2062 {
2063 *str = p;
2064 return SUCCESS;
2065 }
2066
2067 /* Shifts of 32 are encoded as 0, for those shifts that
2068 support it. */
2069 if (num == 32)
2070 num = 0;
2071
2072 inst.instruction |= (num << 7) | shft->value;
2073 *str = p;
2074 return SUCCESS;
2075 }
2076
2077 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
2078 inst.reloc.pc_rel = 0;
2079 inst.instruction |= shft->value;
2080 *str = p;
2081 return SUCCESS;
2082 }
2083 else
2084 {
2085 inst.error = unrestrict ? "shift requires register or #expression"
2086 : "shift requires #expression";
2087 *str = p;
2088 return FAIL;
2089 }
2090 }
2091
2092 inst.error = "Shift expression expected";
2093 return FAIL;
2094}
2095
2096/* Do those data_ops which can take a negative immediate constant */
2097/* by altering the instuction. A bit of a hack really */
2098/* MOV <-> MVN
2099 AND <-> BIC
2100 ADC <-> SBC
2101 by inverting the second operand, and
2102 ADD <-> SUB
2103 CMP <-> CMN
2104 by negating the second operand.
2105*/
2106static int
2107negate_data_op (instruction, value)
2108 unsigned long *instruction;
2109 unsigned long value;
2110{
2111 int op, new_inst;
2112 unsigned long negated, inverted;
2113
2114 negated = validate_immediate (-value);
2115 inverted = validate_immediate (~value);
2116
2117 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
2118 switch (op)
2119 {
2120 /* First negates */
2121 case OPCODE_SUB: /* ADD <-> SUB */
2122 new_inst = OPCODE_ADD;
2123 value = negated;
2124 break;
2125
2126 case OPCODE_ADD:
2127 new_inst = OPCODE_SUB;
2128 value = negated;
2129 break;
2130
2131 case OPCODE_CMP: /* CMP <-> CMN */
2132 new_inst = OPCODE_CMN;
2133 value = negated;
2134 break;
2135
2136 case OPCODE_CMN:
2137 new_inst = OPCODE_CMP;
2138 value = negated;
2139 break;
2140
2141 /* Now Inverted ops */
2142 case OPCODE_MOV: /* MOV <-> MVN */
2143 new_inst = OPCODE_MVN;
2144 value = inverted;
2145 break;
2146
2147 case OPCODE_MVN:
2148 new_inst = OPCODE_MOV;
2149 value = inverted;
2150 break;
2151
2152 case OPCODE_AND: /* AND <-> BIC */
2153 new_inst = OPCODE_BIC;
2154 value = inverted;
2155 break;
2156
2157 case OPCODE_BIC:
2158 new_inst = OPCODE_AND;
2159 value = inverted;
2160 break;
2161
2162 case OPCODE_ADC: /* ADC <-> SBC */
2163 new_inst = OPCODE_SBC;
2164 value = inverted;
2165 break;
2166
2167 case OPCODE_SBC:
2168 new_inst = OPCODE_ADC;
2169 value = inverted;
2170 break;
2171
2172 /* We cannot do anything */
2173 default:
2174 return FAIL;
2175 }
2176
2177 if (value == FAIL)
2178 return FAIL;
2179
2180 *instruction &= OPCODE_MASK;
2181 *instruction |= new_inst << DATA_OP_SHIFT;
2182 return value;
2183}
2184
2185static int
2186data_op2 (str)
2187 char **str;
2188{
2189 int value;
2190 expressionS expr;
2191
2192 while (**str == ' ')
2193 (*str)++;
2194
2195 if (reg_required_here (str, 0) != FAIL)
2196 {
2197 if (skip_past_comma (str) == SUCCESS)
2198 {
2199 /* Shift operation on register */
2200 return decode_shift (str, NO_SHIFT_RESTRICT);
2201 }
2202 return SUCCESS;
2203 }
2204 else
2205 {
2206 /* Immediate expression */
2207 if (*((*str)++) == '#')
2208 {
2209 inst.error = NULL;
2210 if (my_get_expression (&inst.reloc.exp, str))
2211 return FAIL;
2212
2213 if (inst.reloc.exp.X_add_symbol)
2214 {
2215 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2216 inst.reloc.pc_rel = 0;
2217 }
2218 else
2219 {
2220 if (skip_past_comma (str) == SUCCESS)
2221 {
2222 /* #x, y -- ie explicit rotation by Y */
2223 if (my_get_expression (&expr, str))
2224 return FAIL;
2225
2226 if (expr.X_op != O_constant)
2227 {
2228 inst.error = "Constant expression expected";
2229 return FAIL;
2230 }
2231
2232 /* Rotate must be a multiple of 2 */
2233 if (((unsigned) expr.X_add_number) > 30
2234 || (expr.X_add_number & 1) != 0
2235 || ((unsigned) inst.reloc.exp.X_add_number) > 255)
2236 {
2237 inst.error = "Invalid constant";
2238 return FAIL;
2239 }
2240 inst.instruction |= INST_IMMEDIATE;
2241 inst.instruction |= inst.reloc.exp.X_add_number;
2242 inst.instruction |= expr.X_add_number << 7;
2243 return SUCCESS;
2244 }
2245
2246 /* Implicit rotation, select a suitable one */
2247 value = validate_immediate (inst.reloc.exp.X_add_number);
2248
2249 if (value == FAIL)
2250 {
2251 /* Can't be done, perhaps the code reads something like
2252 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2253 if ((value = negate_data_op (&inst.instruction,
2254 inst.reloc.exp.X_add_number))
2255 == FAIL)
2256 {
2257 inst.error = "Invalid constant";
2258 return FAIL;
2259 }
2260 }
2261
2262 inst.instruction |= value;
2263 }
2264
2265 inst.instruction |= INST_IMMEDIATE;
2266 return SUCCESS;
2267 }
2268
2269 inst.error = "Register or shift expression expected";
2270 return FAIL;
2271 }
2272}
2273
2274static int
2275fp_op2 (str, flags)
2276 char **str;
2277 unsigned long flags;
2278{
2279 while (**str == ' ')
2280 (*str)++;
2281
2282 if (fp_reg_required_here (str, 0) != FAIL)
2283 return SUCCESS;
2284 else
2285 {
2286 /* Immediate expression */
2287 if (*((*str)++) == '#')
2288 {
2289 int i;
2290
2291 inst.error = NULL;
2292 while (**str == ' ')
2293 (*str)++;
2294
2295 /* First try and match exact strings, this is to guarantee that
2296 some formats will work even for cross assembly */
2297
2298 for (i = 0; fp_const[i]; i++)
2299 {
2300 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
2301 {
2302 char *start = *str;
2303
2304 *str += strlen (fp_const[i]);
2305 if (is_end_of_line[(int)**str] || **str == '\0')
2306 {
2307 inst.instruction |= i + 8;
2308 return SUCCESS;
2309 }
2310 *str = start;
2311 }
2312 }
2313
2314 /* Just because we didn't get a match doesn't mean that the
2315 constant isn't valid, just that it is in a format that we
2316 don't automatically recognize. Try parsing it with
2317 the standard expression routines. */
2318 if ((i = my_get_float_expression (str)) >= 0)
2319 {
2320 inst.instruction |= i + 8;
2321 return SUCCESS;
2322 }
2323
2324 inst.error = "Invalid floating point immediate expression";
2325 return FAIL;
2326 }
2327 inst.error = "Floating point register or immediate expression expected";
2328 return FAIL;
2329 }
2330}
2331
2332static void
2333do_arit (str, flags)
2334 char *str;
2335 unsigned long flags;
2336{
2337 while (*str == ' ')
2338 str++;
2339
2340 if (reg_required_here (&str, 12) == FAIL
2341 || skip_past_comma (&str) == FAIL
2342 || reg_required_here (&str, 16) == FAIL
2343 || skip_past_comma (&str) == FAIL
2344 || data_op2 (&str) == FAIL)
2345 {
2346 if (!inst.error)
2347 inst.error = bad_args;
2348 return;
2349 }
2350
2351 inst.instruction |= flags;
2352 end_of_line (str);
2353 return;
2354}
2355
2356static void
2357do_adr (str, flags)
2358 char *str;
2359 unsigned long flags;
2360{
590c50d8
ILT
2361 /* This is a pseudo-op of the form "adr rd, label" to be converted
2362 into a relative address of the form "add rd, pc, #label-.-8" */
338a7060
DE
2363
2364 while (*str == ' ')
2365 str++;
2366
2367 if (reg_required_here (&str, 12) == FAIL
2368 || skip_past_comma (&str) == FAIL
2369 || my_get_expression (&inst.reloc.exp, &str))
2370 {
2371 if (!inst.error)
2372 inst.error = bad_args;
2373 return;
2374 }
2375 /* Frag hacking will turn this into a sub instruction if the offset turns
2376 out to be negative. */
2377 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2378 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
2379 inst.reloc.pc_rel = 1;
2380 inst.instruction |= flags;
2381 end_of_line (str);
2382 return;
2383}
2384
2385static void
2386do_cmp (str, flags)
2387 char *str;
2388 unsigned long flags;
2389{
2390 while (*str == ' ')
2391 str++;
2392
2393 if (reg_required_here (&str, 16) == FAIL)
2394 {
2395 if (!inst.error)
2396 inst.error = bad_args;
2397 return;
2398 }
2399
2400 if (skip_past_comma (&str) == FAIL
2401 || data_op2 (&str) == FAIL)
2402 {
2403 if (!inst.error)
2404 inst.error = bad_args;
2405 return;
2406 }
2407
2408 inst.instruction |= flags;
2409 if ((flags & 0x0000f000) == 0)
590c50d8 2410 inst.instruction |= CONDS_BIT;
338a7060
DE
2411
2412 end_of_line (str);
2413 return;
2414}
2415
2416static void
2417do_mov (str, flags)
2418 char *str;
2419 unsigned long flags;
2420{
2421 while (*str == ' ')
2422 str++;
2423
2424 if (reg_required_here (&str, 12) == FAIL)
2425 {
2426 if (!inst.error)
2427 inst.error = bad_args;
2428 return;
2429 }
2430
2431 if (skip_past_comma (&str) == FAIL
2432 || data_op2 (&str) == FAIL)
2433 {
2434 if (!inst.error)
2435 inst.error = bad_args;
2436 return;
2437 }
2438
2439 inst.instruction |= flags;
2440 end_of_line (str);
2441 return;
2442}
2443
2444static int
c479fc62 2445ldst_extend (str, hwse)
338a7060 2446 char **str;
c479fc62 2447 int hwse;
338a7060
DE
2448{
2449 int add = INDEX_UP;
2450
2451 switch (**str)
2452 {
2453 case '#':
2454 (*str)++;
2455 if (my_get_expression (&inst.reloc.exp, str))
2456 return FAIL;
2457
2458 if (inst.reloc.exp.X_op == O_constant)
2459 {
2460 int value = inst.reloc.exp.X_add_number;
2461
c479fc62
JSC
2462 if ((hwse && (value < -255 || value > 255))
2463 || (value < -4095 || value > 4095))
338a7060
DE
2464 {
2465 inst.error = "address offset too large";
2466 return FAIL;
2467 }
2468
2469 if (value < 0)
2470 {
2471 value = -value;
2472 add = 0;
2473 }
2474
c479fc62
JSC
2475 /* Halfword and signextension instructions have the
2476 immediate value split across bits 11..8 and bits 3..0 */
2477 if (hwse)
2478 inst.instruction |= add | HWOFFSET_IMM | (value >> 4) << 8 | value & 0xF;
2479 else
2480 inst.instruction |= add | value;
338a7060
DE
2481 }
2482 else
2483 {
c479fc62
JSC
2484 if (hwse)
2485 {
2486 inst.instruction |= HWOFFSET_IMM;
2487 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2488 }
2489 else
2490 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
338a7060
DE
2491 inst.reloc.pc_rel = 0;
2492 }
2493 return SUCCESS;
2494
2495 case '-':
2496 add = 0; /* and fall through */
2497 case '+':
2498 (*str)++; /* and fall through */
2499 default:
2500 if (reg_required_here (str, 0) == FAIL)
2501 {
2502 inst.error = "Register expected";
2503 return FAIL;
2504 }
c479fc62
JSC
2505
2506 if (hwse)
2507 inst.instruction |= add;
2508 else
590c50d8
ILT
2509 {
2510 inst.instruction |= add | OFFSET_REG;
2511 if (skip_past_comma (str) == SUCCESS)
2512 return decode_shift (str, SHIFT_RESTRICT);
2513 }
c479fc62 2514
338a7060
DE
2515 return SUCCESS;
2516 }
2517}
2518
2519static void
2520do_ldst (str, flags)
2521 char *str;
2522 unsigned long flags;
2523{
c479fc62 2524 int halfword = 0;
338a7060
DE
2525 int pre_inc = 0;
2526 int conflict_reg;
2527 int value;
2528
c479fc62 2529 /* This is not ideal, but it is the simplest way of dealing with the
590c50d8 2530 ARM7T halfword instructions (since they use a different
c479fc62 2531 encoding, but the same mnemonic): */
590c50d8 2532 if (halfword = ((flags & 0x80000000) != 0))
c479fc62
JSC
2533 {
2534 /* This is actually a load/store of a halfword, or a
2535 signed-extension load */
590c50d8 2536 if ((cpu_variant & ARM_ARCH4) == 0)
c479fc62 2537 {
590c50d8
ILT
2538 inst.error
2539 = "Processor does not support halfwords or signed bytes\n";
2540 return;
c479fc62 2541 }
590c50d8
ILT
2542
2543 inst.instruction = (inst.instruction & COND_MASK)
2544 | (flags & ~COND_MASK);
2545
2546 flags = 0;
c479fc62
JSC
2547 }
2548
338a7060
DE
2549 while (*str == ' ')
2550 str++;
2551
2552 if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
2553 {
2554 if (!inst.error)
2555 inst.error = bad_args;
2556 return;
2557 }
2558
2559 if (skip_past_comma (&str) == FAIL)
2560 {
2561 inst.error = "Address expected";
2562 return;
2563 }
2564
2565 if (*str == '[')
2566 {
2567 int reg;
2568
2569 str++;
2570 while (*str == ' ')
2571 str++;
2572
2573 if ((reg = reg_required_here (&str, 16)) == FAIL)
2574 {
2575 inst.error = "Register required";
2576 return;
2577 }
2578
2579 conflict_reg = (((conflict_reg == reg)
590c50d8 2580 && (inst.instruction & LOAD_BIT))
338a7060
DE
2581 ? 1 : 0);
2582
2583 while (*str == ' ')
2584 str++;
2585
2586 if (*str == ']')
2587 {
2588 str++;
2589 if (skip_past_comma (&str) == SUCCESS)
2590 {
2591 /* [Rn],... (post inc) */
590c50d8 2592 if (ldst_extend (&str, halfword) == FAIL)
338a7060
DE
2593 return;
2594 if (conflict_reg)
2595 as_warn ("destination register same as write-back base\n");
2596 }
2597 else
2598 {
2599 /* [Rn] */
590c50d8 2600 if (halfword)
c479fc62
JSC
2601 inst.instruction |= HWOFFSET_IMM;
2602
2603 while (*str == ' ')
2604 str++;
2605
2606 if (*str == '!')
2607 {
2608 if (conflict_reg)
2609 as_warn ("destination register same as write-back base\n");
2610 str++;
2611 inst.instruction |= WRITE_BACK;
2612 }
2613
338a7060 2614 flags |= INDEX_UP;
c479fc62
JSC
2615 if (! (flags & TRANS_BIT))
2616 pre_inc = 1;
338a7060
DE
2617 }
2618 }
2619 else
2620 {
2621 /* [Rn,...] */
2622 if (skip_past_comma (&str) == FAIL)
2623 {
2624 inst.error = "pre-indexed expression expected";
2625 return;
2626 }
2627
2628 pre_inc = 1;
590c50d8 2629 if (ldst_extend (&str, halfword) == FAIL)
338a7060
DE
2630 return;
2631
2632 while (*str == ' ')
2633 str++;
2634
2635 if (*str++ != ']')
2636 {
2637 inst.error = "missing ]";
2638 return;
2639 }
2640
2641 while (*str == ' ')
2642 str++;
2643
2644 if (*str == '!')
2645 {
2646 if (conflict_reg)
590c50d8 2647 as_tsktsk ("destination register same as write-back base\n");
338a7060
DE
2648 str++;
2649 inst.instruction |= WRITE_BACK;
2650 }
2651 }
2652 }
2653 else if (*str == '=')
2654 {
2655 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2656 str++;
2657
2658 while (*str == ' ')
2659 str++;
2660
2661 if (my_get_expression (&inst.reloc.exp, &str))
2662 return;
2663
2664 if (inst.reloc.exp.X_op != O_constant
2665 && inst.reloc.exp.X_op != O_symbol)
2666 {
2667 inst.error = "Constant expression expected";
2668 return;
2669 }
2670
2671 if (inst.reloc.exp.X_op == O_constant
2672 && (value = validate_immediate(inst.reloc.exp.X_add_number)) != FAIL)
2673 {
2674 /* This can be done with a mov instruction */
2675 inst.instruction &= LITERAL_MASK;
2676 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
2677 inst.instruction |= (flags & COND_MASK) | (value & 0xfff);
2678 end_of_line(str);
2679 return;
2680 }
2681 else
2682 {
2683 /* Insert into literal pool */
2684 if (add_to_lit_pool () == FAIL)
2685 {
2686 if (!inst.error)
2687 inst.error = "literal pool insertion failed\n";
2688 return;
2689 }
2690
2691 /* Change the instruction exp to point to the pool */
590c50d8 2692 if (halfword)
c479fc62
JSC
2693 {
2694 inst.instruction |= HWOFFSET_IMM;
2695 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
2696 }
2697 else
2698 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
338a7060
DE
2699 inst.reloc.pc_rel = 1;
2700 inst.instruction |= (REG_PC << 16);
2701 pre_inc = 1;
2702 }
2703 }
2704 else
2705 {
2706 if (my_get_expression (&inst.reloc.exp, &str))
2707 return;
2708
590c50d8 2709 if (halfword)
c479fc62
JSC
2710 {
2711 inst.instruction |= HWOFFSET_IMM;
2712 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2713 }
2714 else
2715 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
338a7060
DE
2716 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
2717 inst.reloc.pc_rel = 1;
2718 inst.instruction |= (REG_PC << 16);
2719 pre_inc = 1;
2720 }
2721
2722 if (pre_inc && (flags & TRANS_BIT))
2723 inst.error = "Pre-increment instruction with translate";
2724
2725 inst.instruction |= flags | (pre_inc ? PRE_INDEX : 0);
2726 end_of_line (str);
2727 return;
2728}
2729
590c50d8
ILT
2730static long
2731reg_list (strp)
2732 char **strp;
338a7060 2733{
590c50d8
ILT
2734 char *str = *strp;
2735 long range = 0;
2736 int another_range;
338a7060 2737
590c50d8
ILT
2738 /* We come back here if we get ranges concatenated by '+' or '|' */
2739 do
338a7060 2740 {
590c50d8 2741 another_range = 0;
338a7060 2742
590c50d8
ILT
2743 if (*str == '{')
2744 {
2745 int in_range = 0;
2746 int cur_reg = -1;
2747
2748 str++;
2749 do
2750 {
2751 int reg;
2752
2753 while (*str == ' ')
2754 str++;
338a7060 2755
590c50d8
ILT
2756 if ((reg = arm_reg_parse (&str)) == FAIL || !int_register (reg))
2757 {
2758 inst.error = "Register expected";
2759 return FAIL;
2760 }
338a7060 2761
590c50d8
ILT
2762 if (in_range)
2763 {
2764 int i;
2765
2766 if (reg <= cur_reg)
2767 {
2768 inst.error = "Bad range in register list";
2769 return FAIL;
2770 }
338a7060 2771
590c50d8
ILT
2772 for (i = cur_reg + 1; i < reg; i++)
2773 {
2774 if (range & (1 << i))
2775 as_tsktsk
2776 ("Warning: Duplicated register (r%d) in register list",
2777 i);
2778 else
2779 range |= 1 << i;
2780 }
2781 in_range = 0;
2782 }
2783
2784 if (range & (1 << reg))
2785 as_tsktsk ("Warning: Duplicated register (r%d) in register list",
2786 reg);
2787 else if (reg <= cur_reg)
2788 as_tsktsk ("Warning: Register range not in ascending order");
2789
2790 range |= 1 << reg;
2791 cur_reg = reg;
2792 } while (skip_past_comma (&str) != FAIL
2793 || (in_range = 1, *str++ == '-'));
2794 str--;
338a7060
DE
2795 while (*str == ' ')
2796 str++;
2797
590c50d8 2798 if (*str++ != '}')
338a7060 2799 {
590c50d8
ILT
2800 inst.error = "Missing `}'";
2801 return FAIL;
338a7060 2802 }
590c50d8
ILT
2803 }
2804 else
2805 {
2806 expressionS expr;
2807
2808 if (my_get_expression (&expr, &str))
2809 return FAIL;
338a7060 2810
590c50d8 2811 if (expr.X_op == O_constant)
338a7060 2812 {
590c50d8
ILT
2813 if (expr.X_add_number
2814 != (expr.X_add_number & 0x0000ffff))
338a7060 2815 {
590c50d8
ILT
2816 inst.error = "invalid register mask";
2817 return FAIL;
338a7060
DE
2818 }
2819
590c50d8 2820 if ((range & expr.X_add_number) != 0)
338a7060 2821 {
590c50d8
ILT
2822 int regno = range & expr.X_add_number;
2823
2824 regno &= -regno;
2825 regno = (1 << regno) - 1;
2826 as_tsktsk
2827 ("Warning: Duplicated register (r%d) in register list",
2828 regno);
2829 }
2830
2831 range |= expr.X_add_number;
2832 }
2833 else
2834 {
2835 if (inst.reloc.type != 0)
2836 {
2837 inst.error = "expression too complex";
2838 return FAIL;
338a7060 2839 }
590c50d8
ILT
2840
2841 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
2842 inst.reloc.type = BFD_RELOC_ARM_MULTI;
2843 inst.reloc.pc_rel = 0;
338a7060 2844 }
590c50d8 2845 }
338a7060 2846
338a7060
DE
2847 while (*str == ' ')
2848 str++;
2849
590c50d8 2850 if (*str == '|' || *str == '+')
338a7060 2851 {
590c50d8
ILT
2852 str++;
2853 another_range = 1;
338a7060 2854 }
590c50d8 2855 } while (another_range);
338a7060 2856
590c50d8
ILT
2857 *strp = str;
2858 return range;
2859}
338a7060 2860
590c50d8
ILT
2861static void
2862do_ldmstm (str, flags)
2863 char *str;
2864 unsigned long flags;
2865{
2866 int base_reg;
2867 long range;
338a7060 2868
590c50d8
ILT
2869 while (*str == ' ')
2870 str++;
338a7060 2871
590c50d8
ILT
2872 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
2873 {
2874 if (!inst.error)
2875 inst.error = bad_args;
2876 return;
2877 }
338a7060 2878
590c50d8
ILT
2879 if (base_reg == REG_PC)
2880 {
2881 inst.error = "r15 not allowed as base register";
2882 return;
338a7060
DE
2883 }
2884
2885 while (*str == ' ')
2886 str++;
590c50d8 2887 if (*str == '!')
338a7060 2888 {
590c50d8 2889 flags |= WRITE_BACK;
338a7060 2890 str++;
590c50d8
ILT
2891 }
2892
2893 if (skip_past_comma (&str) == FAIL
2894 || (range = reg_list (&str)) == FAIL)
2895 {
2896 if (! inst.error)
2897 inst.error = bad_args;
2898 return;
338a7060
DE
2899 }
2900
2901 if (*str == '^')
2902 {
2903 str++;
2904 flags |= MULTI_SET_PSR;
2905 }
590c50d8
ILT
2906
2907 inst.instruction |= flags | range;
338a7060
DE
2908 end_of_line (str);
2909 return;
2910}
2911
2912static void
2913do_swi (str, flags)
2914 char *str;
2915 unsigned long flags;
2916{
2917 /* Allow optional leading '#'. */
2918 while (*str == ' ')
2919 str++;
2920 if (*str == '#')
2921 str++;
2922
2923 if (my_get_expression (&inst.reloc.exp, &str))
2924 return;
2925
2926 inst.reloc.type = BFD_RELOC_ARM_SWI;
2927 inst.reloc.pc_rel = 0;
2928 inst.instruction |= flags;
2929 end_of_line (str);
2930 return;
2931}
2932
2933static void
2934do_swap (str, flags)
2935 char *str;
2936 unsigned long flags;
2937{
2938 int reg;
2939
2940 while (*str == ' ')
2941 str++;
2942
2943 if ((reg = reg_required_here (&str, 12)) == FAIL)
2944 return;
2945
2946 if (reg == REG_PC)
2947 {
2948 inst.error = "r15 not allowed in swap";
2949 return;
2950 }
2951
2952 if (skip_past_comma (&str) == FAIL
2953 || (reg = reg_required_here (&str, 0)) == FAIL)
2954 {
2955 if (!inst.error)
2956 inst.error = bad_args;
2957 return;
2958 }
2959
2960 if (reg == REG_PC)
2961 {
2962 inst.error = "r15 not allowed in swap";
2963 return;
2964 }
2965
2966 if (skip_past_comma (&str) == FAIL
2967 || *str++ != '[')
2968 {
2969 inst.error = bad_args;
2970 return;
2971 }
2972
2973 while (*str == ' ')
2974 str++;
2975
2976 if ((reg = reg_required_here (&str, 16)) == FAIL)
2977 return;
2978
2979 if (reg == REG_PC)
2980 {
2981 inst.error = bad_pc;
2982 return;
2983 }
2984
2985 while (*str == ' ')
2986 str++;
2987
2988 if (*str++ != ']')
2989 {
2990 inst.error = "missing ]";
2991 return;
2992 }
2993
2994 inst.instruction |= flags;
2995 end_of_line (str);
2996 return;
2997}
2998
2999static void
3000do_branch (str, flags)
3001 char *str;
3002 unsigned long flags;
3003{
3004 if (my_get_expression (&inst.reloc.exp, &str))
3005 return;
3006 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
3007 inst.reloc.pc_rel = 1;
590c50d8
ILT
3008 end_of_line (str);
3009 return;
3010}
3011
3012static void
3013do_bx (str, flags)
3014 char *str;
3015 unsigned long flags;
3016{
3017 int reg;
3018
3019 while (*str == ' ')
3020 str++;
3021
3022 if ((reg = reg_required_here (&str, 0)) == FAIL)
3023 return;
3024
3025 if (reg == REG_PC)
3026 as_tsktsk ("Use of r15 in bx has undefined behaviour");
3027
338a7060
DE
3028 end_of_line (str);
3029 return;
3030}
3031
3032static void
3033do_cdp (str, flags)
3034 char *str;
3035 unsigned long flags;
3036{
3037 /* Co-processor data operation.
3038 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3039 while (*str == ' ')
3040 str++;
3041
3042 if (co_proc_number (&str) == FAIL)
3043 {
3044 if (!inst.error)
3045 inst.error = bad_args;
3046 return;
3047 }
3048
3049 if (skip_past_comma (&str) == FAIL
3050 || cp_opc_expr (&str, 20,4) == FAIL)
3051 {
3052 if (!inst.error)
3053 inst.error = bad_args;
3054 return;
3055 }
3056
3057 if (skip_past_comma (&str) == FAIL
3058 || cp_reg_required_here (&str, 12) == FAIL)
3059 {
3060 if (!inst.error)
3061 inst.error = bad_args;
3062 return;
3063 }
3064
3065 if (skip_past_comma (&str) == FAIL
3066 || cp_reg_required_here (&str, 16) == FAIL)
3067 {
3068 if (!inst.error)
3069 inst.error = bad_args;
3070 return;
3071 }
3072
3073 if (skip_past_comma (&str) == FAIL
3074 || cp_reg_required_here (&str, 0) == FAIL)
3075 {
3076 if (!inst.error)
3077 inst.error = bad_args;
3078 return;
3079 }
3080
3081 if (skip_past_comma (&str) == SUCCESS)
3082 {
3083 if (cp_opc_expr (&str, 5, 3) == FAIL)
3084 {
3085 if (!inst.error)
3086 inst.error = bad_args;
3087 return;
3088 }
3089 }
3090
3091 end_of_line (str);
3092 return;
3093}
3094
3095static void
3096do_lstc (str, flags)
3097 char *str;
3098 unsigned long flags;
3099{
3100 /* Co-processor register load/store.
3101 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3102
3103 while (*str == ' ')
3104 str++;
3105
3106 if (co_proc_number (&str) == FAIL)
3107 {
3108 if (!inst.error)
3109 inst.error = bad_args;
3110 return;
3111 }
3112
3113 if (skip_past_comma (&str) == FAIL
3114 || cp_reg_required_here (&str, 12) == FAIL)
3115 {
3116 if (!inst.error)
3117 inst.error = bad_args;
3118 return;
3119 }
3120
3121 if (skip_past_comma (&str) == FAIL
3122 || cp_address_required_here (&str) == FAIL)
3123 {
3124 if (! inst.error)
3125 inst.error = bad_args;
3126 return;
3127 }
3128
3129 inst.instruction |= flags;
3130 end_of_line (str);
3131 return;
3132}
3133
3134static void
3135do_co_reg (str, flags)
3136 char *str;
3137 unsigned long flags;
3138{
3139 /* Co-processor register transfer.
3140 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3141
3142 while (*str == ' ')
3143 str++;
3144
3145 if (co_proc_number (&str) == FAIL)
3146 {
3147 if (!inst.error)
3148 inst.error = bad_args;
3149 return;
3150 }
3151
3152 if (skip_past_comma (&str) == FAIL
3153 || cp_opc_expr (&str, 21, 3) == FAIL)
3154 {
3155 if (!inst.error)
3156 inst.error = bad_args;
3157 return;
3158 }
3159
3160 if (skip_past_comma (&str) == FAIL
3161 || reg_required_here (&str, 12) == FAIL)
3162 {
3163 if (!inst.error)
3164 inst.error = bad_args;
3165 return;
3166 }
3167
3168 if (skip_past_comma (&str) == FAIL
3169 || cp_reg_required_here (&str, 16) == FAIL)
3170 {
3171 if (!inst.error)
3172 inst.error = bad_args;
3173 return;
3174 }
3175
3176 if (skip_past_comma (&str) == FAIL
3177 || cp_reg_required_here (&str, 0) == FAIL)
3178 {
3179 if (!inst.error)
3180 inst.error = bad_args;
3181 return;
3182 }
3183
3184 if (skip_past_comma (&str) == SUCCESS)
3185 {
3186 if (cp_opc_expr (&str, 5, 3) == FAIL)
3187 {
3188 if (!inst.error)
3189 inst.error = bad_args;
3190 return;
3191 }
3192 }
3193
3194 end_of_line (str);
3195 return;
3196}
3197
3198static void
3199do_fp_ctrl (str, flags)
3200 char *str;
3201 unsigned long flags;
3202{
3203 /* FP control registers.
3204 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3205
3206 while (*str == ' ')
3207 str++;
3208
3209 if (reg_required_here (&str, 12) == FAIL)
3210 {
3211 if (!inst.error)
3212 inst.error = bad_args;
3213 return;
3214 }
3215
3216 end_of_line (str);
3217 return;
3218}
3219
3220static void
3221do_fp_ldst (str, flags)
3222 char *str;
3223 unsigned long flags;
3224{
3225 while (*str == ' ')
3226 str++;
3227
3228 switch (inst.suffix)
3229 {
3230 case SUFF_S:
3231 break;
3232 case SUFF_D:
3233 inst.instruction |= CP_T_X;
3234 break;
3235 case SUFF_E:
3236 inst.instruction |= CP_T_Y;
3237 break;
3238 case SUFF_P:
3239 inst.instruction |= CP_T_X | CP_T_Y;
3240 break;
3241 default:
3242 abort ();
3243 }
3244
3245 if (fp_reg_required_here (&str, 12) == FAIL)
3246 {
3247 if (!inst.error)
3248 inst.error = bad_args;
3249 return;
3250 }
3251
3252 if (skip_past_comma (&str) == FAIL
3253 || cp_address_required_here (&str) == FAIL)
3254 {
3255 if (!inst.error)
3256 inst.error = bad_args;
3257 return;
3258 }
3259
3260 end_of_line (str);
3261}
3262
3263static void
3264do_fp_ldmstm (str, flags)
3265 char *str;
3266 unsigned long flags;
3267{
3268 int num_regs;
3269
3270 while (*str == ' ')
3271 str++;
3272
3273 if (fp_reg_required_here (&str, 12) == FAIL)
3274 {
3275 if (! inst.error)
3276 inst.error = bad_args;
3277 return;
3278 }
3279
3280 /* Get Number of registers to transfer */
3281 if (skip_past_comma (&str) == FAIL
3282 || my_get_expression (&inst.reloc.exp, &str))
3283 {
3284 if (! inst.error)
3285 inst.error = "constant expression expected";
3286 return;
3287 }
3288
3289 if (inst.reloc.exp.X_op != O_constant)
3290 {
3291 inst.error = "Constant value required for number of registers";
3292 return;
3293 }
3294
3295 num_regs = inst.reloc.exp.X_add_number;
3296
3297 if (num_regs < 1 || num_regs > 4)
3298 {
3299 inst.error = "number of registers must be in the range [1:4]";
3300 return;
3301 }
3302
3303 switch (num_regs)
3304 {
3305 case 1:
3306 inst.instruction |= CP_T_X;
3307 break;
3308 case 2:
3309 inst.instruction |= CP_T_Y;
3310 break;
3311 case 3:
3312 inst.instruction |= CP_T_Y | CP_T_X;
3313 break;
3314 case 4:
3315 break;
3316 default:
3317 abort ();
3318 }
3319
3320 if (flags)
3321 {
3322 int reg;
3323 int write_back;
3324 int offset;
3325
3326 /* The instruction specified "ea" or "fd", so we can only accept
3327 [Rn]{!}. The instruction does not really support stacking or
3328 unstacking, so we have to emulate these by setting appropriate
3329 bits and offsets. */
3330 if (skip_past_comma (&str) == FAIL
3331 || *str != '[')
3332 {
3333 if (! inst.error)
3334 inst.error = bad_args;
3335 return;
3336 }
3337
3338 str++;
3339 while (*str == ' ')
3340 str++;
3341
3342 if ((reg = reg_required_here (&str, 16)) == FAIL)
3343 {
3344 inst.error = "Register required";
3345 return;
3346 }
3347
3348 while (*str == ' ')
3349 str++;
3350
3351 if (*str != ']')
3352 {
3353 inst.error = bad_args;
3354 return;
3355 }
3356
3357 str++;
3358 if (*str == '!')
3359 {
3360 write_back = 1;
3361 str++;
3362 if (reg == REG_PC)
3363 {
3364 inst.error = "R15 not allowed as base register with write-back";
3365 return;
3366 }
3367 }
3368 else
3369 write_back = 0;
3370
3371 if (flags & CP_T_Pre)
3372 {
3373 /* Pre-decrement */
3374 offset = 3 * num_regs;
3375 if (write_back)
3376 flags |= CP_T_WB;
3377 }
3378 else
3379 {
3380 /* Post-increment */
3381 if (write_back)
3382 {
3383 flags |= CP_T_WB;
3384 offset = 3 * num_regs;
3385 }
3386 else
3387 {
3388 /* No write-back, so convert this into a standard pre-increment
3389 instruction -- aesthetically more pleasing. */
3390 flags = CP_T_Pre | CP_T_UD;
3391 offset = 0;
3392 }
3393 }
3394
3395 inst.instruction |= flags | offset;
3396 }
3397 else if (skip_past_comma (&str) == FAIL
3398 || cp_address_required_here (&str) == FAIL)
3399 {
3400 if (! inst.error)
3401 inst.error = bad_args;
3402 return;
3403 }
3404
3405 end_of_line (str);
3406}
3407
3408static void
3409do_fp_dyadic (str, flags)
3410 char *str;
3411 unsigned long flags;
3412{
3413 while (*str == ' ')
3414 str++;
3415
3416 switch (inst.suffix)
3417 {
3418 case SUFF_S:
3419 break;
3420 case SUFF_D:
3421 inst.instruction |= 0x00000080;
3422 break;
3423 case SUFF_E:
3424 inst.instruction |= 0x00080000;
3425 break;
3426 default:
3427 abort ();
3428 }
3429
3430 if (fp_reg_required_here (&str, 12) == FAIL)
3431 {
3432 if (! inst.error)
3433 inst.error = bad_args;
3434 return;
3435 }
3436
3437 if (skip_past_comma (&str) == FAIL
3438 || fp_reg_required_here (&str, 16) == FAIL)
3439 {
3440 if (! inst.error)
3441 inst.error = bad_args;
3442 return;
3443 }
3444
3445 if (skip_past_comma (&str) == FAIL
3446 || fp_op2 (&str) == FAIL)
3447 {
3448 if (! inst.error)
3449 inst.error = bad_args;
3450 return;
3451 }
3452
3453 inst.instruction |= flags;
3454 end_of_line (str);
3455 return;
3456}
3457
3458static void
3459do_fp_monadic (str, flags)
3460 char *str;
3461 unsigned long flags;
3462{
3463 while (*str == ' ')
3464 str++;
3465
3466 switch (inst.suffix)
3467 {
3468 case SUFF_S:
3469 break;
3470 case SUFF_D:
3471 inst.instruction |= 0x00000080;
3472 break;
3473 case SUFF_E:
3474 inst.instruction |= 0x00080000;
3475 break;
3476 default:
3477 abort ();
3478 }
3479
3480 if (fp_reg_required_here (&str, 12) == FAIL)
3481 {
3482 if (! inst.error)
3483 inst.error = bad_args;
3484 return;
3485 }
3486
3487 if (skip_past_comma (&str) == FAIL
3488 || fp_op2 (&str) == FAIL)
3489 {
3490 if (! inst.error)
3491 inst.error = bad_args;
3492 return;
3493 }
3494
3495 inst.instruction |= flags;
3496 end_of_line (str);
3497 return;
3498}
3499
3500static void
3501do_fp_cmp (str, flags)
3502 char *str;
3503 unsigned long flags;
3504{
3505 while (*str == ' ')
3506 str++;
3507
3508 if (fp_reg_required_here (&str, 16) == FAIL)
3509 {
3510 if (! inst.error)
3511 inst.error = bad_args;
3512 return;
3513 }
3514
3515 if (skip_past_comma (&str) == FAIL
3516 || fp_op2 (&str) == FAIL)
3517 {
3518 if (! inst.error)
3519 inst.error = bad_args;
3520 return;
3521 }
3522
3523 inst.instruction |= flags;
3524 end_of_line (str);
3525 return;
3526}
3527
3528static void
3529do_fp_from_reg (str, flags)
3530 char *str;
3531 unsigned long flags;
3532{
3533 while (*str == ' ')
3534 str++;
3535
3536 switch (inst.suffix)
3537 {
3538 case SUFF_S:
3539 break;
3540 case SUFF_D:
3541 inst.instruction |= 0x00000080;
3542 break;
3543 case SUFF_E:
3544 inst.instruction |= 0x00080000;
3545 break;
3546 default:
3547 abort ();
3548 }
3549
3550 if (fp_reg_required_here (&str, 16) == FAIL)
3551 {
3552 if (! inst.error)
3553 inst.error = bad_args;
3554 return;
3555 }
3556
3557 if (skip_past_comma (&str) == FAIL
3558 || reg_required_here (&str, 12) == FAIL)
3559 {
3560 if (! inst.error)
3561 inst.error = bad_args;
3562 return;
3563 }
3564
3565 inst.instruction |= flags;
3566 end_of_line (str);
3567 return;
3568}
3569
3570static void
3571do_fp_to_reg (str, flags)
3572 char *str;
3573 unsigned long flags;
3574{
3575 while (*str == ' ')
3576 str++;
3577
3578 if (reg_required_here (&str, 12) == FAIL)
3579 {
3580 if (! inst.error)
3581 inst.error = bad_args;
3582 return;
3583 }
3584
3585 if (skip_past_comma (&str) == FAIL
3586 || fp_reg_required_here (&str, 0) == FAIL)
3587 {
3588 if (! inst.error)
3589 inst.error = bad_args;
3590 return;
3591 }
3592
3593 inst.instruction |= flags;
3594 end_of_line (str);
3595 return;
3596}
3597
590c50d8
ILT
3598/* Thumb specific routines */
3599
3600/* Parse and validate that a register is of the right form, this saves
3601 repeated checking of this information in many similar cases.
3602 Unlike the 32-bit case we do not insert the register into the opcode
3603 here, since the position is often unknown until the full instruction
3604 has been parsed. */
3605static int
3606thumb_reg (strp, hi_lo)
3607 char **strp;
3608 int hi_lo;
338a7060 3609{
590c50d8 3610 int reg;
338a7060 3611
590c50d8
ILT
3612 if ((reg = arm_reg_parse (strp)) == FAIL || ! int_register (reg))
3613 {
3614 inst.error = "Register expected";
3615 return FAIL;
3616 }
338a7060 3617
590c50d8
ILT
3618 switch (hi_lo)
3619 {
3620 case THUMB_REG_LO:
3621 if (reg > 7)
3622 {
3623 inst.error = "lo register required";
3624 return FAIL;
3625 }
3626 break;
338a7060 3627
590c50d8
ILT
3628 case THUMB_REG_HI:
3629 if (reg < 8)
3630 {
3631 inst.error = "hi register required";
3632 return FAIL;
3633 }
3634 break;
3635
3636 default:
3637 break;
3638 }
3639
3640 return reg;
3641}
3642
3643/* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3644 was SUB. */
3645static void
3646thumb_add_sub (str, subtract)
3647 char *str;
3648 int subtract;
3649{
3650 int Rd, Rs, Rn = FAIL;
3651
3652 while (*str == ' ')
3653 str++;
3654
3655 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
3656 || skip_past_comma (&str) == FAIL)
3657 {
3658 if (! inst.error)
3659 inst.error = bad_args;
3660 return;
3661 }
3662
3663 if (*str == '#')
3664 {
3665 Rs = Rd;
3666 str++;
3667 if (my_get_expression (&inst.reloc.exp, &str))
3668 return;
3669 }
3670 else
3671 {
3672 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
3673 return;
3674
3675 if (skip_past_comma (&str) == FAIL)
3676 {
3677 /* Two operand format, shuffle the registers and pretend there
3678 are 3 */
3679 Rn = Rs;
3680 Rs = Rd;
3681 }
3682 else if (*str == '#')
3683 {
3684 str++;
3685 if (my_get_expression (&inst.reloc.exp, &str))
3686 return;
3687 }
3688 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
3689 return;
3690 }
3691
3692 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3693 for the latter case, EXPR contains the immediate that was found. */
3694 if (Rn != FAIL)
3695 {
3696 /* All register format. */
3697 if (Rd > 7 || Rs > 7 || Rd > 7)
3698 {
3699 if (Rs != Rd)
3700 {
3701 inst.error = "dest and source1 must be the same register";
3702 return;
3703 }
3704
3705 /* Can't do this for SUB */
3706 if (subtract)
3707 {
3708 inst.error = "subtract valid only on lo regs";
3709 return;
3710 }
3711
3712 inst.instruction = (T_OPCODE_ADD_HI
3713 | (Rd > 7 ? THUMB_H1 : 0)
3714 | (Rn > 7 ? THUMB_H2 : 0));
3715 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
3716 }
3717 else
3718 {
3719 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
3720 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
3721 }
3722 }
3723 else
3724 {
3725 /* Immediate expression, now things start to get nasty. */
3726
3727 /* First deal with HI regs, only very restricted cases allowed:
3728 Adjusting SP, and using PC or SP to get an address. */
3729 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
3730 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
3731 {
3732 inst.error = "invalid Hi register with immediate";
3733 return;
3734 }
3735
3736 if (inst.reloc.exp.X_op != O_constant)
3737 {
3738 /* Value isn't known yet, all we can do is store all the fragments
3739 we know about in the instruction and let the reloc hacking
3740 work it all out. */
3741 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
3742 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
3743 }
3744 else
3745 {
3746 int offset = inst.reloc.exp.X_add_number;
3747
3748 if (subtract)
3749 offset = -offset;
3750
3751 if (offset < 0)
3752 {
3753 offset = -offset;
3754 subtract = 1;
3755
3756 /* Quick check, in case offset is MIN_INT */
3757 if (offset < 0)
3758 {
3759 inst.error = "immediate value out of range";
3760 return;
3761 }
3762 }
3763 else
3764 subtract = 0;
3765
3766 if (Rd == REG_SP)
3767 {
3768 if (offset & ~0x1fc)
3769 {
3770 inst.error = "invalid immediate value for stack adjust";
3771 return;
3772 }
3773 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
3774 inst.instruction |= offset >> 2;
3775 }
3776 else if (Rs == REG_PC || Rs == REG_SP)
3777 {
3778 if (subtract
3779 || (offset & ~0x3fc))
3780 {
3781 inst.error = "invalid immediate for address calculation";
3782 return;
3783 }
3784 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
3785 : T_OPCODE_ADD_SP);
3786 inst.instruction |= (Rd << 8) | (offset >> 2);
3787 }
3788 else if (Rs == Rd)
3789 {
3790 if (offset & ~0xff)
3791 {
3792 inst.error = "immediate value out of range";
3793 return;
3794 }
3795 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
3796 inst.instruction |= (Rd << 8) | offset;
3797 }
3798 else
3799 {
3800 if (offset & ~0x7)
3801 {
3802 inst.error = "immediate value out of range";
3803 return;
3804 }
3805 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
3806 inst.instruction |= Rd | (Rs << 3) | (offset << 6);
3807 }
3808 }
3809 }
3810 end_of_line (str);
3811}
3812
3813static void
3814thumb_shift (str, shift)
3815 char *str;
3816 int shift;
3817{
3818 int Rd, Rs, Rn = FAIL;
3819
3820 while (*str == ' ')
3821 str++;
3822
3823 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
3824 || skip_past_comma (&str) == FAIL)
3825 {
3826 if (! inst.error)
3827 inst.error = bad_args;
3828 return;
3829 }
3830
3831 if (*str == '#')
3832 {
3833 /* Two operand immediate format, set Rs to Rd. */
3834 Rs = Rd;
3835 str++;
3836 if (my_get_expression (&inst.reloc.exp, &str))
3837 return;
3838 }
3839 else
3840 {
3841 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
3842 return;
3843
3844 if (skip_past_comma (&str) == FAIL)
3845 {
3846 /* Two operand format, shuffle the registers and pretend there
3847 are 3 */
3848 Rn = Rs;
3849 Rs = Rd;
3850 }
3851 else if (*str == '#')
3852 {
3853 str++;
3854 if (my_get_expression (&inst.reloc.exp, &str))
3855 return;
3856 }
3857 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
3858 return;
3859 }
3860
3861 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3862 for the latter case, EXPR contains the immediate that was found. */
3863
3864 if (Rn != FAIL)
3865 {
3866 if (Rs != Rd)
3867 {
3868 inst.error = "source1 and dest must be same register";
3869 return;
3870 }
3871
3872 switch (shift)
3873 {
3874 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
3875 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
3876 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
3877 }
3878
3879 inst.instruction |= Rd | (Rn << 3);
3880 }
3881 else
3882 {
3883 switch (shift)
3884 {
3885 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
3886 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
3887 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
3888 }
3889
3890 if (inst.reloc.exp.X_op != O_constant)
3891 {
3892 /* Value isn't known yet, create a dummy reloc and let reloc
3893 hacking fix it up */
3894
3895 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
3896 }
3897 else
3898 {
3899 unsigned shift_value = inst.reloc.exp.X_add_number;
3900
3901 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
3902 {
3903 inst.error = "Invalid immediate for shift";
3904 return;
3905 }
3906
3907 /* Shifts of zero are handled by converting to LSL */
3908 if (shift_value == 0)
3909 inst.instruction = T_OPCODE_LSL_I;
3910
3911 /* Shifts of 32 are encoded as a shift of zero */
3912 if (shift_value == 32)
3913 shift_value = 0;
3914
3915 inst.instruction |= shift_value << 6;
3916 }
3917
3918 inst.instruction |= Rd | (Rs << 3);
3919 }
3920 end_of_line (str);
3921}
3922
3923static void
3924thumb_mov_compare (str, move)
3925 char *str;
3926 int move;
3927{
3928 int Rd, Rs = FAIL;
3929
3930 while (*str == ' ')
3931 str++;
3932
3933 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
3934 || skip_past_comma (&str) == FAIL)
3935 {
3936 if (! inst.error)
3937 inst.error = bad_args;
3938 return;
3939 }
3940
3941 if (*str == '#')
3942 {
3943 str++;
3944 if (my_get_expression (&inst.reloc.exp, &str))
3945 return;
3946 }
3947 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
3948 return;
3949
3950 if (Rs != FAIL)
3951 {
3952 if (Rs < 8 && Rd < 8)
3953 {
3954 if (move == THUMB_MOVE)
3955 /* A move of two lowregs is, by convention, encoded as
3956 ADD Rd, Rs, #0 */
3957 inst.instruction = T_OPCODE_ADD_I3;
3958 else
3959 inst.instruction = T_OPCODE_CMP_LR;
3960 inst.instruction |= Rd | (Rs << 3);
3961 }
3962 else
3963 {
3964 if (move == THUMB_MOVE)
3965 inst.instruction = T_OPCODE_MOV_HR;
3966 else
3967 inst.instruction = T_OPCODE_CMP_HR;
3968
3969 if (Rd > 7)
3970 inst.instruction |= THUMB_H1;
3971
3972 if (Rs > 7)
3973 inst.instruction |= THUMB_H2;
3974
3975 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
3976 }
3977 }
3978 else
3979 {
3980 if (Rd > 7)
3981 {
3982 inst.error = "only lo regs allowed with immediate";
3983 return;
3984 }
3985
3986 if (move == THUMB_MOVE)
3987 inst.instruction = T_OPCODE_MOV_I8;
3988 else
3989 inst.instruction = T_OPCODE_CMP_I8;
3990
3991 inst.instruction |= Rd << 8;
3992
3993 if (inst.reloc.exp.X_op != O_constant)
3994 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
3995 else
3996 {
3997 unsigned value = inst.reloc.exp.X_add_number;
3998
3999 if (value > 255)
4000 {
4001 inst.error = "invalid immediate";
4002 return;
4003 }
4004
4005 inst.instruction |= value;
4006 }
4007 }
4008
4009 end_of_line (str);
4010}
4011
4012static void
4013thumb_load_store (str, load_store, size)
4014 char *str;
4015 int load_store;
4016 int size;
4017{
4018 int Rd, Rb, Ro = FAIL;
4019
4020 while (*str == ' ')
4021 str++;
4022
4023 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4024 || skip_past_comma (&str) == FAIL)
4025 {
4026 if (! inst.error)
4027 inst.error = bad_args;
4028 return;
4029 }
4030
4031 if (*str == '[')
4032 {
4033 str++;
4034 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4035 return;
4036
4037 if (skip_past_comma (&str) != FAIL)
4038 {
4039 if (*str == '#')
4040 {
4041 str++;
4042 if (my_get_expression (&inst.reloc.exp, &str))
4043 return;
4044 }
4045 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4046 return;
4047 }
4048 else
4049 {
4050 inst.reloc.exp.X_op = O_constant;
4051 inst.reloc.exp.X_add_number = 0;
4052 }
4053
4054 if (*str != ']')
4055 {
4056 inst.error = "expected ']'";
4057 return;
4058 }
4059 str++;
4060 }
4061 else if (*str == '=')
4062 {
4063 abort ();
4064 }
4065 else
4066 {
4067 if (my_get_expression (&inst.reloc.exp, &str))
4068 return;
4069
4070 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
4071 inst.reloc.pc_rel = 1;
4072 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset */
4073 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4074 end_of_line (str);
4075 return;
4076 }
4077
4078 if (Rb == REG_PC || Rb == REG_SP)
4079 {
4080 if (size != THUMB_WORD)
4081 {
4082 inst.error = "byte or halfword not valid for base register";
4083 return;
4084 }
4085 else if (Rb == REG_PC && load_store != THUMB_LOAD)
4086 {
4087 inst.error = "R15 based store not allowed";
4088 return;
4089 }
4090 else if (Ro != FAIL)
4091 {
4092 inst.error = "Invalid base register for register offset";
4093 return;
4094 }
4095
4096 if (Rb == REG_PC)
4097 inst.instruction = T_OPCODE_LDR_PC;
4098 else if (load_store == THUMB_LOAD)
4099 inst.instruction = T_OPCODE_LDR_SP;
4100 else
4101 inst.instruction = T_OPCODE_STR_SP;
4102
4103 inst.instruction |= Rd << 8;
4104 if (inst.reloc.exp.X_op == O_constant)
4105 {
4106 unsigned offset = inst.reloc.exp.X_add_number;
4107
4108 if (offset & ~0x3fc)
4109 {
4110 inst.error = "invalid offset";
4111 return;
4112 }
4113
4114 inst.instruction |= offset >> 2;
4115 }
4116 else
4117 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4118 }
4119 else if (Rb > 7)
4120 {
4121 inst.error = "invalid base register in load/store";
4122 return;
4123 }
4124 else if (Ro == FAIL)
4125 {
4126 /* Immediate offset */
4127 if (size == THUMB_WORD)
4128 inst.instruction = (load_store == THUMB_LOAD
4129 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
4130 else if (size == THUMB_HALFWORD)
4131 inst.instruction = (load_store == THUMB_LOAD
4132 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
4133 else
4134 inst.instruction = (load_store == THUMB_LOAD
4135 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
4136
4137 inst.instruction |= Rd | (Rb << 3);
4138
4139 if (inst.reloc.exp.X_op == O_constant)
4140 {
4141 unsigned offset = inst.reloc.exp.X_add_number;
4142
4143 if (offset & ~(0x1f << size))
4144 {
4145 inst.error = "Invalid offset";
4146 return;
4147 }
4148 inst.instruction |= offset << 6;
4149 }
4150 else
4151 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4152 }
4153 else
4154 {
4155 /* Register offset */
4156 if (size == THUMB_WORD)
4157 inst.instruction = (load_store == THUMB_LOAD
4158 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
4159 else if (size == THUMB_HALFWORD)
4160 inst.instruction = (load_store == THUMB_LOAD
4161 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
4162 else
4163 inst.instruction = (load_store == THUMB_LOAD
4164 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
4165
4166 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4167 }
4168
4169 end_of_line (str);
4170}
4171
4172/* Handle the Format 4 instructions that do not have equivalents in other
4173 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4174 BIC and MVN. */
4175static void
4176do_t_arit (str)
4177 char *str;
4178{
4179 int Rd, Rs, Rn;
4180
4181 while (*str == ' ')
4182 str++;
4183
4184 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4185 return;
4186
4187 if (skip_past_comma (&str) == FAIL
4188 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4189 {
4190 if (! inst.error)
4191 inst.error = bad_args;
4192 return;
4193 }
4194
4195 if (skip_past_comma (&str) != FAIL)
4196 {
4197 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4198 (It isn't allowed for CMP either, but that isn't handled by this
4199 function.) */
4200 if (inst.instruction == T_OPCODE_TST
4201 || inst.instruction == T_OPCODE_CMN
4202 || inst.instruction == T_OPCODE_NEG
4203 || inst.instruction == T_OPCODE_MVN)
4204 {
4205 inst.error = bad_args;
4206 return;
4207 }
4208
4209 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4210 return;
4211
4212 if (Rs != Rd)
4213 {
4214 inst.error = "dest and source1 one must be the same register";
4215 return;
4216 }
4217 Rs = Rn;
4218 }
4219
4220 if (inst.instruction == T_OPCODE_MUL
4221 && Rs == Rd)
4222 as_tsktsk ("Rs and Rd must be different in MUL");
4223
4224 inst.instruction |= Rd | (Rs << 3);
4225 end_of_line (str);
4226}
4227
4228static void
4229do_t_add (str)
4230 char *str;
4231{
4232 thumb_add_sub (str, 0);
4233}
4234
4235static void
4236do_t_asr (str)
4237 char *str;
4238{
4239 thumb_shift (str, THUMB_ASR);
4240}
4241
4242static void
4243do_t_branch (str)
4244 char *str;
4245{
4246 if (my_get_expression (&inst.reloc.exp, &str))
4247 return;
4248 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
4249 inst.reloc.pc_rel = 1;
4250 end_of_line (str);
4251}
4252
4253static void
4254do_t_bx (str)
4255 char *str;
4256{
4257 int reg;
4258
4259 while (*str == ' ')
4260 str++;
4261
4262 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4263 return;
4264
4265 /* This sets THUMB_H2 from the top bit of reg. */
4266 inst.instruction |= reg << 3;
4267
4268 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4269 should cause the alignment to be checked once it is known. This is
4270 because BX PC only works if the instruction is word aligned. */
4271
4272 end_of_line (str);
4273}
4274
4275static void
4276do_t_compare (str)
4277 char *str;
4278{
4279 thumb_mov_compare (str, THUMB_COMPARE);
4280}
4281
4282static void
4283do_t_ldmstm (str)
4284 char *str;
4285{
4286 int Rb;
4287 long range;
4288
4289 while (*str == ' ')
4290 str++;
4291
4292 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4293 return;
4294
4295 if (*str != '!')
4296 as_warn ("Inserted missing '!': load/store multiple always writes back base register");
4297 else
4298 str++;
4299
4300 if (skip_past_comma (&str) == FAIL
4301 || (range = reg_list (&str)) == FAIL)
4302 {
4303 if (! inst.error)
4304 inst.error = bad_args;
4305 return;
4306 }
4307
4308 if (inst.reloc.type != BFD_RELOC_NONE)
4309 {
4310 /* This really doesn't seem worth it. */
4311 inst.reloc.type = BFD_RELOC_NONE;
4312 inst.error = "Expression too complex";
4313 return;
4314 }
4315
4316 if (range & ~0xff)
4317 {
4318 inst.error = "only lo-regs valid in load/store multiple";
4319 return;
4320 }
4321
4322 inst.instruction |= (Rb << 8) | range;
4323 end_of_line (str);
4324}
4325
4326static void
4327do_t_ldr (str)
4328 char *str;
4329{
4330 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
4331}
4332
4333static void
4334do_t_ldrb (str)
4335 char *str;
4336{
4337 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
4338}
4339
4340static void
4341do_t_ldrh (str)
4342 char *str;
4343{
4344 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
4345}
4346
4347static void
4348do_t_lds (str)
4349 char *str;
4350{
4351 int Rd, Rb, Ro;
4352
4353 while (*str == ' ')
4354 str++;
4355
4356 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4357 || skip_past_comma (&str) == FAIL
4358 || *str++ != '['
4359 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4360 || skip_past_comma (&str) == FAIL
4361 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4362 || *str++ != ']')
4363 {
4364 if (! inst.error)
4365 inst.error = "Syntax: ldrs[b] Rd, [Rb, Ro]";
4366 return;
4367 }
4368
4369 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4370 end_of_line (str);
4371}
4372
4373static void
4374do_t_lsl (str)
4375 char *str;
4376{
4377 thumb_shift (str, THUMB_LSL);
4378}
4379
4380static void
4381do_t_lsr (str)
4382 char *str;
4383{
4384 thumb_shift (str, THUMB_LSR);
4385}
4386
4387static void
4388do_t_mov (str)
4389 char *str;
4390{
4391 thumb_mov_compare (str, THUMB_MOVE);
4392}
4393
4394static void
4395do_t_push_pop (str)
4396 char *str;
4397{
4398 long range;
4399
4400 while (*str == ' ')
4401 str++;
4402
4403 if ((range = reg_list (&str)) == FAIL)
4404 {
4405 if (! inst.error)
4406 inst.error = bad_args;
4407 return;
4408 }
4409
4410 if (inst.reloc.type != BFD_RELOC_NONE)
4411 {
4412 /* This really doesn't seem worth it. */
4413 inst.reloc.type = BFD_RELOC_NONE;
4414 inst.error = "Expression too complex";
4415 return;
4416 }
4417
4418 if (range & ~0xff)
4419 {
4420 if ((inst.instruction == T_OPCODE_PUSH
4421 && (range & ~0xff) == 1 << REG_LR)
4422 || (inst.instruction == T_OPCODE_POP
4423 && (range & ~0xff) == 1 << REG_PC))
4424 {
4425 inst.instruction |= THUMB_PP_PC_LR;
4426 range &= 0xff;
4427 }
4428 else
4429 {
4430 inst.error = "invalid register list to push/pop instruction";
4431 return;
4432 }
4433 }
4434
4435 inst.instruction |= range;
4436 end_of_line (str);
4437}
4438
4439static void
4440do_t_str (str)
4441 char *str;
4442{
4443 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
4444}
4445
4446static void
4447do_t_strb (str)
4448 char *str;
4449{
4450 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
4451}
4452
4453static void
4454do_t_strh (str)
4455 char *str;
4456{
4457 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
4458}
4459
4460static void
4461do_t_sub (str)
4462 char *str;
4463{
4464 thumb_add_sub (str, 1);
4465}
4466
4467static void
4468do_t_swi (str)
4469 char *str;
4470{
4471 while (*str == ' ')
4472 str++;
4473
4474 if (my_get_expression (&inst.reloc.exp, &str))
4475 return;
4476
4477 inst.reloc.type = BFD_RELOC_ARM_SWI;
4478 end_of_line (str);
4479 return;
4480}
4481
4482static void
4483do_t_adr (str)
4484 char *str;
4485{
4486 /* This is a pseudo-op of the form "adr rd, label" to be converted
4487 into a relative address of the form "add rd, pc, #label-.-8" */
4488 while (*str == ' ')
4489 str++;
4490
4491 if (reg_required_here (&str, 8) == FAIL
4492 || skip_past_comma (&str) == FAIL
4493 || my_get_expression (&inst.reloc.exp, &str))
4494 {
4495 if (!inst.error)
4496 inst.error = bad_args;
4497 return;
4498 }
4499
4500 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
4501 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
4502 inst.reloc.pc_rel = 1;
4503 inst.instruction |= REG_PC; /* Rd is already placed into the instruction */
4504 end_of_line (str);
4505}
4506
4507static void
4508insert_reg (entry)
4509 int entry;
4510{
4511 int len = strlen (reg_table[entry].name) + 2;
4512 char *buf = (char *) xmalloc (len);
4513 char *buf2 = (char *) xmalloc (len);
4514 int i = 0;
4515
4516#ifdef REGISTER_PREFIX
4517 buf[i++] = REGISTER_PREFIX;
4518#endif
4519
4520 strcpy (buf + i, reg_table[entry].name);
4521
4522 for (i = 0; buf[i]; i++)
4523 buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i];
338a7060
DE
4524
4525 buf2[i] = '\0';
4526
4527 hash_insert (arm_reg_hsh, buf, (PTR) &reg_table[entry]);
4528 hash_insert (arm_reg_hsh, buf2, (PTR) &reg_table[entry]);
4529}
4530
4531static void
4532insert_reg_alias (str, regnum)
4533 char *str;
4534 int regnum;
4535{
4536 struct reg_entry *new =
4537 (struct reg_entry *)xmalloc (sizeof (struct reg_entry));
4538 char *name = xmalloc (strlen (str) + 1);
4539 strcpy (name, str);
4540
4541 new->name = name;
4542 new->number = regnum;
4543
4544 hash_insert (arm_reg_hsh, name, (PTR) new);
4545}
4546
4547static void
4548set_constant_flonums ()
4549{
4550 int i;
4551
4552 for (i = 0; i < NUM_FLOAT_VALS; i++)
4553 if (atof_ieee ((char *)fp_const[i], 'x', fp_values[i]) == NULL)
4554 abort ();
4555}
4556
4557void
4558md_begin ()
4559{
4560 int i;
4561
4562 if ((arm_ops_hsh = hash_new ()) == NULL
590c50d8 4563 || (arm_tops_hsh = hash_new ()) == NULL
338a7060
DE
4564 || (arm_cond_hsh = hash_new ()) == NULL
4565 || (arm_shift_hsh = hash_new ()) == NULL
4566 || (arm_reg_hsh = hash_new ()) == NULL
4567 || (arm_psr_hsh = hash_new ()) == NULL)
4568 as_fatal ("Virtual memory exhausted");
4569
4570 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
4571 hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i));
590c50d8
ILT
4572 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
4573 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
338a7060
DE
4574 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
4575 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
4576 for (i = 0; i < sizeof (shift) / sizeof (struct asm_shift); i++)
4577 hash_insert (arm_shift_hsh, shift[i].template, (PTR) (shift + i));
4578 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
4579 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
4580
4581 for (i = 0; reg_table[i].name; i++)
4582 insert_reg (i);
4583
4584 set_constant_flonums ();
46686c78
NC
4585
4586#ifdef OBJ_COFF
4587 /* Set the flags in the private structure */
4588 coff_arm_bfd_set_private_flags (stdoutput, uses_apcs_26 ? F_APCS26 : 0);
4589#endif
4590
4591 {
4592 unsigned mach;
4593
4594 /* Record the CPU type as well */
4595 switch (cpu_variant & ARM_CPU_MASK)
4596 {
4597 case ARM_2:
4598 mach = bfd_mach_arm_2;
4599 break;
4600
4601 case ARM_3: /* also ARM_250 */
4602 mach = bfd_mach_arm_2a;
4603 break;
4604
4605 default:
4606 case ARM_6 | ARM_3 | ARM_2: /* Actually no CPU type defined */
4607 case ARM_7: /* also ARM_6 */
4608 mach = bfd_mach_arm_3;
4609 break;
4610 }
4611
4612 /* Catch special cases */
4613 if (cpu_variant & ARM_THUMB)
4614 mach = bfd_mach_arm_4T;
4615 else if (cpu_variant & ARM_LONGMUL)
4616 mach = bfd_mach_arm_3M;
4617 else if (cpu_variant & ARM_ARCH4)
4618 mach = bfd_mach_arm_4;
4619
4620 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
4621 }
338a7060
DE
4622}
4623
338a7060
DE
4624/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4625 for use in the a.out file, and stores them in the array pointed to by buf.
4626 This knows about the endian-ness of the target machine and does
4627 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4628 2 (short) and 4 (long) Floating numbers are put out as a series of
4629 LITTLENUMS (shorts, here at least)
4630 */
4631void
4632md_number_to_chars (buf, val, n)
4633 char *buf;
4634 valueT val;
4635 int n;
4636{
4637 if (target_big_endian)
4638 number_to_chars_bigendian (buf, val, n);
4639 else
4640 number_to_chars_littleendian (buf, val, n);
4641}
4642
4643static valueT
4644md_chars_to_number (buf, n)
4645 char *buf;
4646 int n;
4647{
4648 valueT result = 0;
4649 unsigned char *where = (unsigned char *) buf;
4650
4651 if (target_big_endian)
4652 {
4653 while (n--)
4654 {
4655 result <<= 8;
4656 result |= (*where++ & 255);
4657 }
4658 }
4659 else
4660 {
4661 while (n--)
4662 {
4663 result <<= 8;
4664 result |= (where[n] & 255);
4665 }
4666 }
4667
4668 return result;
4669}
4670
c479fc62
JSC
4671/* Turn a string in input_line_pointer into a floating point constant
4672 of type TYPE, and store the appropriate bytes in *litP. The number
4673 of LITTLENUMS emitted is stored in *sizeP . An error message is
4674 returned, or NULL on OK.
4675
4676 Note that fp constants aren't represent in the normal way on the ARM.
4677 In big endian mode, things are as expected. However, in little endian
4678 mode fp constants are big-endian word-wise, and little-endian byte-wise
4679 within the words. For example, (double) 1.1 in big endian mode is
4680 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4681 the byte sequence 99 99 f1 3f 9a 99 99 99.
4682
4683 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
338a7060 4684
338a7060
DE
4685char *
4686md_atof (type, litP, sizeP)
4687 char type;
4688 char *litP;
4689 int *sizeP;
4690{
4691 int prec;
4692 LITTLENUM_TYPE words[MAX_LITTLENUMS];
338a7060 4693 char *t;
c479fc62 4694 int i;
338a7060
DE
4695
4696 switch (type)
4697 {
338a7060
DE
4698 case 'f':
4699 case 'F':
4700 case 's':
4701 case 'S':
4702 prec = 2;
4703 break;
4704
4705 case 'd':
4706 case 'D':
4707 case 'r':
4708 case 'R':
4709 prec = 4;
4710 break;
4711
4712 case 'x':
4713 case 'X':
4714 prec = 6;
4715 break;
4716
4717 case 'p':
4718 case 'P':
4719 prec = 6;
4720 break;
4721
4722 default:
4723 *sizeP = 0;
4724 return "Bad call to MD_ATOF()";
4725 }
c479fc62 4726
338a7060
DE
4727 t = atof_ieee (input_line_pointer, type, words);
4728 if (t)
4729 input_line_pointer = t;
c479fc62
JSC
4730 *sizeP = prec * 2;
4731
4732 if (target_big_endian)
338a7060 4733 {
c479fc62
JSC
4734 for (i = 0; i < prec; i++)
4735 {
4736 md_number_to_chars (litP, (valueT) words[i], 2);
4737 litP += 2;
4738 }
338a7060 4739 }
c479fc62
JSC
4740 else
4741 {
4742 /* For a 4 byte float the order of elements in `words' is 1 0. For an
4743 8 byte float the order is 1 0 3 2. */
4744 for (i = 0; i < prec; i += 2)
4745 {
4746 md_number_to_chars (litP, (valueT) words[i + 1], 2);
4747 md_number_to_chars (litP + 2, (valueT) words[i], 2);
4748 litP += 4;
4749 }
4750 }
4751
338a7060
DE
4752 return 0;
4753}
4754
4755/* We have already put the pipeline compensation in the instruction */
4756
4757long
4758md_pcrel_from (fixP)
4759 fixS *fixP;
4760{
4761 if (fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
4762 && fixP->fx_subsy == NULL)
4763 return 0; /* HACK */
4764
4765 return fixP->fx_where + fixP->fx_frag->fr_address;
4766}
4767
4768/* Round up a section size to the appropriate boundary. */
4769valueT
4770md_section_align (segment, size)
4771 segT segment;
4772 valueT size;
4773{
4774 /* Round all sects to multiple of 4 */
4775 return (size + 3) & ~3;
4776}
4777
4778/* We have no need to default values of symbols. */
4779
4780/* ARGSUSED */
4781symbolS *
4782md_undefined_symbol (name)
4783 char *name;
4784{
4785 return 0;
4786}
4787
4788/* arm_reg_parse () := if it looks like a register, return its token and
4789 advance the pointer. */
4790
4791static int
4792arm_reg_parse (ccp)
4793 register char **ccp;
4794{
4795 char *start = *ccp;
4796 char c;
4797 char *p;
4798 struct reg_entry *reg;
4799
4800#ifdef REGISTER_PREFIX
4801 if (*start != REGISTER_PREFIX)
4802 return FAIL;
4803 p = start + 1;
4804#else
4805 p = start;
4806#ifdef OPTIONAL_REGISTER_PREFIX
4807 if (*p == OPTIONAL_REGISTER_PREFIX)
4808 p++, start++;
4809#endif
4810#endif
4811 if (!isalpha (*p) || !is_name_beginner (*p))
4812 return FAIL;
4813
4814 c = *p++;
4815 while (isalpha (c) || isdigit (c) || c == '_')
4816 c = *p++;
4817
4818 *--p = 0;
4819 reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
4820 *p = c;
4821
4822 if (reg)
4823 {
4824 *ccp = p;
4825 return reg->number;
4826 }
4827
4828 return FAIL;
4829}
4830
4831static int
4832arm_psr_parse (ccp)
4833 register char **ccp;
4834{
4835 char *start = *ccp;
4836 char c, *p;
4837 CONST struct asm_psr *psr;
4838
4839 p = start;
4840 c = *p++;
4841 while (isalpha (c) || c == '_')
4842 c = *p++;
4843
4844 *--p = 0;
4845 psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
4846 *p = c;
4847
4848 if (psr)
4849 {
4850 *ccp = p;
4851 return psr->number;
4852 }
4853
4854 return FAIL;
4855}
4856
4857int
c479fc62 4858md_apply_fix3 (fixP, val, seg)
338a7060
DE
4859 fixS *fixP;
4860 valueT *val;
c479fc62 4861 segT seg;
338a7060
DE
4862{
4863 offsetT value = *val;
4864 offsetT newval, temp;
4865 int sign;
4866 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
590c50d8 4867 arm_fix_data *arm_data = (arm_fix_data *) fixP->tc_fix_data;
338a7060
DE
4868
4869 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
4870
338a7060
DE
4871 /* Note whether this will delete the relocation. */
4872 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
4873 fixP->fx_done = 1;
4874
c479fc62
JSC
4875 /* If this symbol is in a different section then we need to leave it for
4876 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
4877 so we have to undo it's effects here. */
4878 if (fixP->fx_pcrel)
4879 {
4880 if (S_IS_DEFINED (fixP->fx_addsy)
4881 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
4882 value += md_pcrel_from (fixP);
4883 }
4884
4885 fixP->fx_addnumber = value; /* Remember value for emit_reloc */
4886
338a7060
DE
4887 switch (fixP->fx_r_type)
4888 {
4889 case BFD_RELOC_ARM_IMMEDIATE:
4890 newval = validate_immediate (value);
590c50d8 4891 temp = md_chars_to_number (buf, INSN_SIZE);
338a7060
DE
4892
4893 /* If the instruction will fail, see if we can fix things up by
4894 changing the opcode. */
4895 if (newval == FAIL
4896 && (newval = negate_data_op (&temp, value)) == FAIL)
4897 {
4898 as_bad_where (fixP->fx_file, fixP->fx_line,
4899 "invalid constant after fixup\n");
4900 break;
4901 }
4902
4903 newval |= (temp & 0xfffff000);
590c50d8 4904 md_number_to_chars (buf, newval, INSN_SIZE);
338a7060
DE
4905 break;
4906
c479fc62 4907 case BFD_RELOC_ARM_OFFSET_IMM:
338a7060 4908 sign = value >= 0;
c479fc62
JSC
4909 if ((value = validate_offset_imm (value, 0)) == FAIL)
4910 {
4911 as_bad ("bad immediate value for offset (%d)", val);
4912 break;
4913 }
338a7060
DE
4914 if (value < 0)
4915 value = -value;
4916
590c50d8 4917 newval = md_chars_to_number (buf, INSN_SIZE);
338a7060 4918 newval &= 0xff7ff000;
590c50d8
ILT
4919 newval |= value | (sign ? INDEX_UP : 0);
4920 md_number_to_chars (buf, newval, INSN_SIZE);
c479fc62
JSC
4921 break;
4922
4923 case BFD_RELOC_ARM_OFFSET_IMM8:
4924 case BFD_RELOC_ARM_HWLITERAL:
4925 sign = value >= 0;
4926 if ((value = validate_offset_imm (value, 1)) == FAIL)
4927 {
4928 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
4929 as_bad_where (fixP->fx_file, fixP->fx_line,
4930 "invalid literal constant: pool needs to be closer\n");
4931 else
4932 as_bad ("bad immediate value for offset (%d)", value);
4933 break;
4934 }
4935
4936 if (value < 0)
4937 value = -value;
4938
590c50d8 4939 newval = md_chars_to_number (buf, INSN_SIZE);
c479fc62 4940 newval &= 0xff7ff0f0;
590c50d8
ILT
4941 newval |= ((value >> 4) << 8) | value & 0xf | (sign ? INDEX_UP : 0);
4942 md_number_to_chars (buf, newval, INSN_SIZE);
338a7060
DE
4943 break;
4944
4945 case BFD_RELOC_ARM_LITERAL:
4946 sign = value >= 0;
4947 if (value < 0)
4948 value = -value;
4949
c479fc62 4950 if ((value = validate_offset_imm (value, 0)) == FAIL)
338a7060
DE
4951 {
4952 as_bad_where (fixP->fx_file, fixP->fx_line,
4953 "invalid literal constant: pool needs to be closer\n");
4954 break;
4955 }
4956
590c50d8 4957 newval = md_chars_to_number (buf, INSN_SIZE);
338a7060 4958 newval &= 0xff7ff000;
590c50d8
ILT
4959 newval |= value | (sign ? INDEX_UP : 0);
4960 md_number_to_chars (buf, newval, INSN_SIZE);
338a7060
DE
4961 break;
4962
4963 case BFD_RELOC_ARM_SHIFT_IMM:
590c50d8 4964 newval = md_chars_to_number (buf, INSN_SIZE);
338a7060
DE
4965 if (((unsigned long) value) > 32
4966 || (value == 32
4967 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
4968 {
4969 as_bad_where (fixP->fx_file, fixP->fx_line,
4970 "shift expression is too large");
4971 break;
4972 }
4973
4974 if (value == 0)
4975 newval &= ~0x60; /* Shifts of zero must be done as lsl */
4976 else if (value == 32)
4977 value = 0;
4978 newval &= 0xfffff07f;
4979 newval |= (value & 0x1f) << 7;
590c50d8 4980 md_number_to_chars (buf, newval , INSN_SIZE);
338a7060
DE
4981 break;
4982
4983 case BFD_RELOC_ARM_SWI:
590c50d8
ILT
4984 if (arm_data->thumb_mode)
4985 {
4986 if (((unsigned long) value) > 0xff)
4987 as_bad_where (fixP->fx_file, fixP->fx_line,
4988 "Invalid swi expression");
4989 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
4990 newval |= value;
4991 md_number_to_chars (buf, newval, THUMB_SIZE);
4992 }
4993 else
4994 {
4995 if (((unsigned long) value) > 0x00ffffff)
4996 as_bad_where (fixP->fx_file, fixP->fx_line,
4997 "Invalid swi expression");
4998 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
4999 newval |= value;
5000 md_number_to_chars (buf, newval , INSN_SIZE);
5001 }
338a7060
DE
5002 break;
5003
5004 case BFD_RELOC_ARM_MULTI:
5005 if (((unsigned long) value) > 0xffff)
5006 as_bad_where (fixP->fx_file, fixP->fx_line,
5007 "Invalid expression in load/store multiple");
590c50d8
ILT
5008 newval = value | md_chars_to_number (buf, INSN_SIZE);
5009 md_number_to_chars (buf, newval, INSN_SIZE);
338a7060
DE
5010 break;
5011
5012 case BFD_RELOC_ARM_PCREL_BRANCH:
590c50d8
ILT
5013 if (arm_data->thumb_mode)
5014 {
5015 unsigned long newval2;
5016 newval = md_chars_to_number (buf, THUMB_SIZE);
5017 if (fixP->fx_size == 4)
5018 {
5019 unsigned long diff;
5020
5021 newval2 = md_chars_to_number (buf, THUMB_SIZE);
5022 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
5023 if (diff & 0x400000)
5024 diff |= ~0x3fffff;
5025 value += diff;
5026 if ((value & 0x400000) && ((value & ~0x3fffff) != ~0x3fffff))
5027 as_bad_where (fixP->fx_file, fixP->fx_line,
5028 "Branch with link out of range");
5029
5030 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
5031 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
5032 md_number_to_chars (buf, newval, THUMB_SIZE);
5033 md_number_to_chars (buf, newval2, THUMB_SIZE);
5034 }
5035 else
5036 {
5037 if (newval == T_OPCODE_BRANCH)
5038 {
5039 unsigned long diff = (newval & 0x7ff) << 1;
5040 if (diff & 0x800)
5041 diff |= ~0x7ff;
5042
5043 value += diff;
5044 if ((value & 0x800) && ((value & ~0x7ff) != ~0x7ff))
5045 as_bad_where (fixP->fx_file, fixP->fx_line,
5046 "Branch out of range");
5047 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
5048 }
5049 else
5050 {
5051 unsigned long diff = (newval & 0xff) << 1;
5052 if (diff & 0x100)
5053 diff |= ~0xff;
5054
5055 value += diff;
5056 if ((value & 0x100) && ((value & ~0xff) != ~0xff))
5057 as_bad_where (fixP->fx_file, fixP->fx_line,
5058 "Branch out of range");
5059 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
5060 }
5061 md_number_to_chars (buf, newval, THUMB_SIZE);
5062 }
5063 }
5064 else
5065 {
5066 value = (value >> 2) & 0x00ffffff;
5067 newval = md_chars_to_number (buf, INSN_SIZE);
5068 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
5069 newval = value | (newval & 0xff000000);
5070 md_number_to_chars (buf, newval, INSN_SIZE);
5071 }
338a7060
DE
5072 break;
5073
5074 case BFD_RELOC_8:
5075 if (fixP->fx_done || fixP->fx_pcrel)
5076 md_number_to_chars (buf, value, 1);
5077 break;
5078
5079 case BFD_RELOC_16:
5080 if (fixP->fx_done || fixP->fx_pcrel)
5081 md_number_to_chars (buf, value, 2);
5082 break;
5083
c479fc62 5084 case BFD_RELOC_RVA:
338a7060
DE
5085 case BFD_RELOC_32:
5086 if (fixP->fx_done || fixP->fx_pcrel)
5087 md_number_to_chars (buf, value, 4);
5088 break;
5089
5090 case BFD_RELOC_ARM_CP_OFF_IMM:
5091 sign = value >= 0;
5092 if (value < -1023 || value > 1023 || (value & 3))
5093 as_bad_where (fixP->fx_file, fixP->fx_line,
5094 "Illegal value for co-processor offset");
5095 if (value < 0)
5096 value = -value;
590c50d8
ILT
5097 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
5098 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
5099 md_number_to_chars (buf, newval , INSN_SIZE);
5100 break;
5101
5102 case BFD_RELOC_ARM_THUMB_OFFSET:
5103 newval = md_chars_to_number (buf, THUMB_SIZE);
5104 /* Exactly what ranges, and where the offset is inserted depends on
5105 the type of instruction, we can establish this from the top 4 bits */
5106 switch (newval >> 12)
5107 {
5108 case 4: /* PC load */
5109 /* PC loads are somewhat odd, bit 2 of the PC is forced to zero
5110 for these loads, so we may need to round up the offset if the
5111 instruction is not word aligned since the final address must
5112 be. */
5113
5114 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
5115 as_bad_where (fixP->fx_file, fixP->fx_line,
5116 "Invalid offset, target not word aligned");
5117
5118 if ((value + 2) & ~0x3fe)
5119 as_bad_where (fixP->fx_file, fixP->fx_line,
5120 "Invalid offset");
5121 /* Round up, since pc will be rounded down. */
5122 newval |= (value + 2) >> 2;
5123 break;
5124
5125 case 9: /* SP load/store */
5126 if (value & ~0x3fc)
5127 as_bad_where (fixP->fx_file, fixP->fx_line,
5128 "Invalid offset");
5129 newval |= value >> 2;
5130 break;
5131
5132 case 6: /* Word load/store */
5133 if (value & ~0x7c)
5134 as_bad_where (fixP->fx_file, fixP->fx_line,
5135 "Invalid offset");
5136 newval |= value << 4; /* 6 - 2 */
5137 break;
5138
5139 case 7: /* Byte load/store */
5140 if (value & ~0x1f)
5141 as_bad_where (fixP->fx_file, fixP->fx_line,
5142 "Invalid offset");
5143 newval |= value << 6;
5144 break;
5145
5146 case 8: /* Halfword load/store */
5147 if (value & ~0x3e)
5148 as_bad_where (fixP->fx_file, fixP->fx_line,
5149 "Invalid offset");
5150 newval |= value << 5; /* 6 - 1 */
5151 break;
5152
5153 default:
5154 abort ();
5155 }
5156 md_number_to_chars (buf, newval, THUMB_SIZE);
5157 break;
5158
5159 case BFD_RELOC_ARM_THUMB_ADD:
5160 /* This is a complicated relocation, since we use it for all of
5161 the following immediate relocations:
5162 3bit ADD/SUB
5163 8bit ADD/SUB
5164 9bit ADD/SUB SP word-aligned
5165 10bit ADD PC/SP word-aligned
5166
5167 The type of instruction being processed is encoded in the
5168 instruction field:
5169 0x8000 SUB
5170 0x00F0 Rd
5171 0x000F Rs
5172 */
5173 newval = md_chars_to_number (buf, THUMB_SIZE);
5174 {
5175 int rd = (newval >> 4) & 0xf;
5176 int rs = newval & 0xf;
5177 int subtract = newval & 0x8000;
5178
5179 if (rd == REG_SP)
5180 {
5181 if (value & ~0x1fc)
5182 as_bad_where (fixP->fx_file, fixP->fx_line,
5183 "Invalid immediate for stack address calculation");
5184 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
5185 newval |= value >> 2;
5186 }
5187 else if (rs == REG_PC || rs == REG_SP)
5188 {
5189 if (subtract ||
5190 value & ~0x3fc)
5191 as_bad_where (fixP->fx_file, fixP->fx_line,
5192 "Invalid immediate for address calculation (value = 0x%08X)", value);
5193 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
5194 newval |= value >> 2;
5195 }
5196 else if (rs == rd)
5197 {
5198 if (value & ~0xff)
5199 as_bad_where (fixP->fx_file, fixP->fx_line,
5200 "Invalid 8bit immediate");
5201 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
5202 newval |= (rd << 8) | value;
5203 }
5204 else
5205 {
5206 if (value & ~0x7)
5207 as_bad_where (fixP->fx_file, fixP->fx_line,
5208 "Invalid 3bit immediate");
5209 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
5210 newval |= rd | (rs << 3) | (value << 6);
5211 }
5212 }
5213 md_number_to_chars (buf, newval , THUMB_SIZE);
5214 break;
5215
5216 case BFD_RELOC_ARM_THUMB_IMM:
5217 newval = md_chars_to_number (buf, THUMB_SIZE);
5218 switch (newval >> 11)
5219 {
5220 case 0x04: /* 8bit immediate MOV */
5221 case 0x05: /* 8bit immediate CMP */
5222 if (value < 0 || value > 255)
5223 as_bad_where (fixP->fx_file, fixP->fx_line,
5224 "Invalid immediate: %d is too large", value);
5225 newval |= value;
5226 break;
5227
5228 default:
5229 abort ();
5230 }
5231 md_number_to_chars (buf, newval , THUMB_SIZE);
5232 break;
5233
5234 case BFD_RELOC_ARM_THUMB_SHIFT:
5235 /* 5bit shift value (0..31) */
5236 if (value < 0 || value > 31)
5237 as_bad_where (fixP->fx_file, fixP->fx_line,
5238 "Illegal Thumb shift value: %d", value);
5239 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
5240 newval |= value << 6;
5241 md_number_to_chars (buf, newval , THUMB_SIZE);
338a7060
DE
5242 break;
5243
5244 case BFD_RELOC_NONE:
5245 default:
5246 as_bad_where (fixP->fx_file, fixP->fx_line,
5247 "Bad relocation fixup type (%d)\n", fixP->fx_r_type);
5248 }
5249
5250 return 1;
5251}
5252
5253/* Translate internal representation of relocation info to BFD target
5254 format. */
5255arelent *
5256tc_gen_reloc (section, fixp)
5257 asection *section;
5258 fixS *fixp;
5259{
5260 arelent *reloc;
5261 bfd_reloc_code_real_type code;
5262
590c50d8 5263 reloc = (arelent *) xmalloc (sizeof (arelent));
338a7060
DE
5264
5265 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
5266 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5267
338a7060
DE
5268 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5269 if (fixp->fx_pcrel == 0)
5270 reloc->addend = fixp->fx_offset;
5271 else
5272 reloc->addend = fixp->fx_offset = reloc->address;
5273
5274 switch (fixp->fx_r_type)
5275 {
5276 case BFD_RELOC_8:
5277 if (fixp->fx_pcrel)
5278 {
5279 code = BFD_RELOC_8_PCREL;
5280 break;
5281 }
5282
5283 case BFD_RELOC_16:
5284 if (fixp->fx_pcrel)
5285 {
5286 code = BFD_RELOC_16_PCREL;
5287 break;
5288 }
5289
5290 case BFD_RELOC_32:
5291 if (fixp->fx_pcrel)
5292 {
5293 code = BFD_RELOC_32_PCREL;
5294 break;
5295 }
5296
5297 case BFD_RELOC_ARM_PCREL_BRANCH:
c479fc62 5298 case BFD_RELOC_RVA:
338a7060
DE
5299 code = fixp->fx_r_type;
5300 break;
5301
5302 case BFD_RELOC_ARM_LITERAL:
c479fc62 5303 case BFD_RELOC_ARM_HWLITERAL:
338a7060
DE
5304 /* If this is called then the a literal has been referenced across
5305 a section boundry - possibly due to an implicit dump */
5306 as_bad ("Literal referenced across section boundry (Implicit dump?)");
5307 return NULL;
5308
5309 case BFD_RELOC_ARM_IMMEDIATE:
5310 as_bad ("Internal_relocation (type %d) not fixed up (IMMEDIATE)"
5311 , fixp->fx_r_type);
5312 return NULL;
5313
5314 case BFD_RELOC_ARM_OFFSET_IMM:
5315 as_bad ("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"
5316 , fixp->fx_r_type);
5317 return NULL;
5318
c479fc62
JSC
5319 case BFD_RELOC_ARM_OFFSET_IMM8:
5320 as_bad ("Internal_relocation (type %d) not fixed up (OFFSET_IMM8)"
5321 , fixp->fx_r_type);
5322 return NULL;
5323
338a7060
DE
5324 case BFD_RELOC_ARM_SHIFT_IMM:
5325 as_bad ("Internal_relocation (type %d) not fixed up (SHIFT_IMM)"
5326 , fixp->fx_r_type);
5327 return NULL;
5328
5329 case BFD_RELOC_ARM_SWI:
5330 as_bad ("Internal_relocation (type %d) not fixed up (SWI)"
5331 , fixp->fx_r_type);
5332 return NULL;
5333
5334 case BFD_RELOC_ARM_MULTI:
5335 as_bad ("Internal_relocation (type %d) not fixed up (MULTI)"
5336 , fixp->fx_r_type);
5337 return NULL;
5338
5339 case BFD_RELOC_ARM_CP_OFF_IMM:
5340 as_bad ("Internal_relocation (type %d) not fixed up (CP_OFF_IMM)"
5341 , fixp->fx_r_type);
5342 return NULL;
5343
590c50d8
ILT
5344 case BFD_RELOC_ARM_THUMB_OFFSET:
5345 as_bad ("Internal_relocation (type %d) not fixed up (THUMB_OFFSET)"
5346 , fixp->fx_r_type);
5347 return NULL;
5348
338a7060
DE
5349 default:
5350 abort ();
5351 }
5352
5353 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
5354 assert (reloc->howto != 0);
5355
5356 return reloc;
5357}
5358
5359CONST int md_short_jump_size = 4;
5360CONST int md_long_jump_size = 4;
5361
5362/* These should never be called on the arm */
5363void
5364md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
5365 char *ptr;
5366 addressT from_addr, to_addr;
5367 fragS *frag;
5368 symbolS *to_symbol;
5369{
5370 as_fatal ("md_create_long_jump\n");
5371}
5372
5373void
5374md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
5375 char *ptr;
5376 addressT from_addr, to_addr;
5377 fragS *frag;
5378 symbolS *to_symbol;
5379{
5380 as_fatal ("md_create_short_jump\n");
5381}
5382
5383int
5384md_estimate_size_before_relax (fragP, segtype)
5385 fragS *fragP;
5386 segT segtype;
5387{
5388 as_fatal ("md_estimate_size_before_relax\n");
5389 return (1);
5390}
5391
5392void
5393output_inst (str)
5394 char *str;
5395{
5396 char *to = NULL;
5397
5398 if (inst.error)
5399 {
5400 as_bad ("%s -- statement `%s'\n", inst.error, str);
5401 return;
5402 }
5403
590c50d8
ILT
5404 to = frag_more (inst.size);
5405 if (thumb_mode && (inst.size > 2))
5406 {
5407 md_number_to_chars (to, inst.instruction >> 16, 2);
5408 to += 2;
5409 inst.size = 2;
5410 }
5411
5412 md_number_to_chars (to, inst.instruction, inst.size);
338a7060
DE
5413
5414 if (inst.reloc.type != BFD_RELOC_NONE)
5415 fix_new_arm (frag_now, to - frag_now->fr_literal,
590c50d8 5416 inst.size, &inst.reloc.exp, inst.reloc.pc_rel,
338a7060
DE
5417 inst.reloc.type);
5418
5419 return;
5420}
5421
5422void
5423md_assemble (str)
5424 char *str;
5425{
5426 char c;
338a7060
DE
5427 char *p, *q, *start;
5428
5429 /* Align the instruction */
5430 /* this may not be the right thing to do but ... */
5431 /* arm_align (2, 0); */
5432 listing_prev_line (); /* Defined in listing.h */
5433
5434 /* Align the previous label if needed */
5435 if (last_label_seen != NULL)
5436 {
5437 last_label_seen->sy_frag = frag_now;
c479fc62 5438 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
338a7060
DE
5439 S_SET_SEGMENT (last_label_seen, now_seg);
5440 }
5441
5442 memset (&inst, '\0', sizeof (inst));
5443 inst.reloc.type = BFD_RELOC_NONE;
5444
5445 if (*str == ' ')
5446 str++; /* Skip leading white space */
5447
5448 /* scan up to the end of the op-code, which must end in white space or
5449 end of string */
5450 for (start = p = str; *p != '\0'; p++)
5451 if (*p == ' ')
5452 break;
5453
5454 if (p == str)
5455 {
5456 as_bad ("No operator -- statement `%s'\n", str);
5457 return;
5458 }
5459
590c50d8 5460 if (thumb_mode)
338a7060 5461 {
590c50d8 5462 CONST struct thumb_opcode *opcode;
338a7060 5463
590c50d8
ILT
5464 c = *p;
5465 *p = '\0';
5466 opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
5467 *p = c;
5468 if (opcode)
5469 {
338a7060 5470 inst.instruction = opcode->value;
590c50d8
ILT
5471 inst.size = opcode->size;
5472 (*opcode->parms)(p);
5473 output_inst (start);
5474 return;
5475 }
5476 }
5477 else
5478 {
5479 CONST struct asm_opcode *opcode;
5480
5481 inst.size = INSN_SIZE;
5482 /* p now points to the end of the opcode, probably white space, but we
5483 have to break the opcode up in case it contains condionals and flags;
5484 keep trying with progressively smaller basic instructions until one
5485 matches, or we run out of opcode. */
5486 q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
5487 for (; q != str; q--)
5488 {
5489 c = *q;
5490 *q = '\0';
5491 opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
5492 *q = c;
5493 if (opcode && opcode->template)
338a7060 5494 {
590c50d8
ILT
5495 unsigned long flag_bits = 0;
5496 char *r;
5497
5498 /* Check that this instruction is supported for this CPU */
5499 if ((opcode->variants & cpu_variant) == 0)
5500 goto try_shorter;
5501
5502 inst.instruction = opcode->value;
5503 if (q == p) /* Just a simple opcode */
338a7060 5504 {
590c50d8
ILT
5505 if (opcode->comp_suffix != 0)
5506 as_bad ("Opcode `%s' must have suffix from <%s>\n", str,
5507 opcode->comp_suffix);
5508 else
5509 {
5510 inst.instruction |= COND_ALWAYS;
5511 (*opcode->parms)(q, 0);
5512 }
5513 output_inst (start);
5514 return;
338a7060 5515 }
338a7060 5516
590c50d8
ILT
5517 /* Now check for a conditional */
5518 r = q;
5519 if (p - r >= 2)
338a7060 5520 {
590c50d8
ILT
5521 CONST struct asm_cond *cond;
5522 char d = *(r + 2);
5523
5524 *(r + 2) = '\0';
5525 cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
5526 *(r + 2) = d;
5527 if (cond)
5528 {
5529 if (cond->value == 0xf0000000)
5530 as_tsktsk (
5531"Warning: Use of the 'nv' conditional is deprecated\n");
338a7060 5532
590c50d8
ILT
5533 inst.instruction |= cond->value;
5534 r += 2;
5535 }
5536 else
5537 inst.instruction |= COND_ALWAYS;
338a7060
DE
5538 }
5539 else
5540 inst.instruction |= COND_ALWAYS;
338a7060 5541
590c50d8
ILT
5542 /* if there is a compulsory suffix, it should come here, before
5543 any optional flags. */
5544 if (opcode->comp_suffix)
338a7060 5545 {
590c50d8 5546 CONST char *s = opcode->comp_suffix;
338a7060 5547
590c50d8
ILT
5548 while (*s)
5549 {
5550 inst.suffix++;
5551 if (*r == *s)
5552 break;
5553 s++;
5554 }
338a7060 5555
590c50d8
ILT
5556 if (*s == '\0')
5557 {
5558 as_bad ("Opcode `%s' must have suffix from <%s>\n", str,
5559 opcode->comp_suffix);
5560 return;
5561 }
338a7060 5562
590c50d8
ILT
5563 r++;
5564 }
5565
5566 /* The remainder, if any should now be flags for the instruction;
5567 Scan these checking each one found with the opcode. */
5568 if (r != p)
5569 {
5570 char d;
5571 CONST struct asm_flg *flag = opcode->flags;
338a7060 5572
590c50d8 5573 if (flag)
338a7060 5574 {
590c50d8
ILT
5575 int flagno;
5576
5577 d = *p;
5578 *p = '\0';
5579
5580 for (flagno = 0; flag[flagno].template; flagno++)
338a7060 5581 {
590c50d8
ILT
5582 if (! strcmp (r, flag[flagno].template))
5583 {
5584 flag_bits |= flag[flagno].set_bits;
5585 break;
5586 }
338a7060 5587 }
338a7060 5588
590c50d8
ILT
5589 *p = d;
5590 if (! flag[flagno].template)
5591 goto try_shorter;
5592 }
5593 else
338a7060
DE
5594 goto try_shorter;
5595 }
590c50d8
ILT
5596
5597 (*opcode->parms) (p, flag_bits);
5598 output_inst (start);
5599 return;
338a7060
DE
5600 }
5601
590c50d8
ILT
5602 try_shorter:
5603 ;
338a7060 5604 }
338a7060 5605 }
590c50d8 5606
338a7060
DE
5607 /* It wasn't an instruction, but it might be a register alias of the form
5608 alias .req reg
5609 */
5610 q = p;
5611 while (*q == ' ')
5612 q++;
5613
5614 c = *p;
5615 *p = '\0';
5616
5617 if (*q && !strncmp (q, ".req ", 4))
5618 {
5619 int reg;
5620 if ((reg = arm_reg_parse (&str)) == FAIL)
5621 {
5622 char *r;
5623
5624 q += 4;
5625 while (*q == ' ')
5626 q++;
5627
5628 for (r = q; *r != '\0'; r++)
5629 if (*r == ' ')
5630 break;
5631
5632 if (r != q)
5633 {
5634 int regnum;
5635 char d = *r;
5636
5637 *r = '\0';
5638 regnum = arm_reg_parse (&q);
5639 *r = d;
5640 if (regnum != FAIL)
5641 {
5642 insert_reg_alias (str, regnum);
5643 *p = c;
5644 return;
5645 }
5646 }
5647 }
5648 else
5649 {
5650 *p = c;
5651 return;
5652 }
5653 }
5654
5655 *p = c;
5656 as_bad ("bad instruction `%s'", start);
5657}
5658
5659/*
5660 * md_parse_option
5661 * Invocation line includes a switch not recognized by the base assembler.
5662 * See if it's a processor-specific option. These are:
5663 * Cpu variants, the arm part is optional:
5664 * -m[arm]1 Currently not supported.
5665 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
5666 * -m[arm]3 Arm 3 processor
c479fc62
JSC
5667 * -m[arm]6, Arm 6 processors
5668 * -m[arm]7[t][[d]m] Arm 7 processors
338a7060
DE
5669 * -mall All (except the ARM1)
5670 * FP variants:
5671 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
5672 * -mfpe-old (No float load/store multiples)
5673 * -mno-fpu Disable all floating point instructions
5674 * Run-time endian selection:
5675 * -EB big endian cpu
5676 * -EL little endian cpu
46686c78
NC
5677 * ARM Procedure Calling Standard:
5678 * -mapcs-32 32 bit APCS
5679 * -mapcs-26 26 bit APCS
338a7060
DE
5680 */
5681
5682CONST char *md_shortopts = "m:";
46686c78
NC
5683struct option md_longopts[] =
5684{
338a7060
DE
5685#ifdef ARM_BI_ENDIAN
5686#define OPTION_EB (OPTION_MD_BASE + 0)
5687 {"EB", no_argument, NULL, OPTION_EB},
5688#define OPTION_EL (OPTION_MD_BASE + 1)
5689 {"EL", no_argument, NULL, OPTION_EL},
5690#endif
5691 {NULL, no_argument, NULL, 0}
5692};
590c50d8 5693size_t md_longopts_size = sizeof (md_longopts);
338a7060
DE
5694
5695int
5696md_parse_option (c, arg)
5697 int c;
5698 char *arg;
5699{
5700 char *str = arg;
5701
5702 switch (c)
5703 {
5704#ifdef ARM_BI_ENDIAN
5705 case OPTION_EB:
5706 target_big_endian = 1;
5707 break;
5708 case OPTION_EL:
5709 target_big_endian = 0;
5710 break;
5711#endif
5712
5713 case 'm':
5714 switch (*str)
5715 {
5716 case 'f':
5717 if (! strcmp (str, "fpa10"))
5718 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
5719 else if (! strcmp (str, "fpa11"))
5720 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
5721 else if (! strcmp (str, "fpe-old"))
5722 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
5723 else
5724 goto bad;
5725 break;
5726
5727 case 'n':
5728 if (! strcmp (str, "no-fpu"))
5729 cpu_variant &= ~FPU_ALL;
5730 break;
5731
590c50d8
ILT
5732 case 't':
5733 /* Limit assembler to generating only Thumb instructions: */
5734 if (! strcmp (str, "thumb"))
5735 {
5736 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB;
5737 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
5738 thumb_mode = 1;
5739 }
5740 else
5741 goto bad;
5742 break;
5743
338a7060
DE
5744 default:
5745 if (! strcmp (str, "all"))
5746 {
5747 cpu_variant = ARM_ALL | FPU_ALL;
5748 return 1;
5749 }
46686c78
NC
5750 else if (! strcmp( str, "apcs-32" ))
5751 {
5752 uses_apcs_26 = false;
5753 return 1;
5754 }
5755 else if (! strcmp( str, "apcs-26" ))
5756 {
5757 uses_apcs_26 = true;
5758 return 1;
5759 }
5760
338a7060
DE
5761 /* Strip off optional "arm" */
5762 if (! strncmp (str, "arm", 3))
5763 str += 3;
5764
5765 switch (*str)
5766 {
5767 case '1':
5768 if (! strcmp (str, "1"))
5769 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
5770 else
5771 goto bad;
5772 break;
5773
5774 case '2':
5775 if (! strcmp (str, "2"))
5776 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
5777 else if (! strcmp (str, "250"))
5778 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
5779 else
5780 goto bad;
5781 break;
5782
5783 case '3':
5784 if (! strcmp (str, "3"))
5785 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
5786 else
5787 goto bad;
5788 break;
5789
5790 case '6':
5791 if (! strcmp (str, "6"))
5792 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
5793 else
5794 goto bad;
5795 break;
5796
5797 case '7':
c479fc62
JSC
5798 str++; /* eat the '7' */
5799 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
5800 for (; *str; str++)
5801 {
5802 switch (*str)
5803 {
5804 case 't':
590c50d8 5805 cpu_variant |= ARM_THUMB;
c479fc62
JSC
5806 break;
5807
5808 case 'm':
5809 cpu_variant |= ARM_LONGMUL;
5810 break;
5811
5812 case 'd': /* debug */
5813 case 'i': /* embedded ice */
5814 /* Included for completeness in ARM processor
5815 naming. */
5816 break;
5817
5818 default:
5819 goto bad;
5820 }
5821 }
338a7060
DE
5822 break;
5823
46686c78
NC
5824 case 'v':
5825 /* Select variant based on architecture rather than processor */
5826 switch (*++str)
5827 {
5828 case '2':
5829 switch (*++str)
5830 {
5831 case 'a': cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3; break;
5832 case 0: cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; break;
5833 default: as_bad( "Invalid architecture variant -m%s", arg ); break;
5834 }
5835 break;
5836
5837 case '3':
5838 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
5839
5840 switch (*++str)
5841 {
5842 case 'm': cpu_variant |= ARM_LONGMUL; break;
5843 case 0: break;
5844 default: as_bad( "Invalid architecture variant -m%s", arg ); break;
5845 }
5846 break;
5847
5848 case '4':
5849 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
5850
5851 switch (*++str)
5852 {
5853 case 't': cpu_variant |= ARM_THUMB; break;
5854 case 0: break;
5855 default: as_bad( "Invalid architecture variant -m%s", arg ); break;
5856 }
5857 break;
5858
5859 default:
5860 as_bad( "Invalid architecture variant -m%s", arg );
5861 break;
5862 }
5863 break;
5864
338a7060
DE
5865 default:
5866 bad:
46686c78 5867 as_bad ("Invalid processor variant -m%s", arg);
338a7060
DE
5868 return 0;
5869 }
5870 }
5871 break;
5872
5873 default:
5874 return 0;
5875 }
5876
5877 return 1;
5878}
5879
5880void
5881md_show_usage (fp)
5882 FILE *fp;
5883{
5884 fprintf (fp,
46686c78
NC
5885"-m[arm][1|2|250|3|6|7[t][d][m][i]] select processor variant\n\
5886-m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n\
5887-mthumb\t\t\tonly allow Thumb instructions\n\
338a7060
DE
5888-mall\t\t\tallow any instruction\n\
5889-mfpa10, -mfpa11\tselect floating point architecture\n\
5890-mfpe-old\t\tdon't allow floating-point multiple instructions\n\
46686c78
NC
5891-mno-fpu\t\tdon't allow any floating-point instructions.\n\
5892-mapcs-32, -mapcs-26\tspecify which ARM Procedure Calling Standard is in use\n");
338a7060
DE
5893#ifdef ARM_BI_ENDIAN
5894 fprintf (fp,
5895"-EB\t\t\tassemble code for a big endian cpu\n\
5896-EL\t\t\tassemble code for a little endian cpu\n");
5897#endif
5898}
5899
5900/* We need to be able to fix up arbitrary expressions in some statements.
5901 This is so that we can handle symbols that are an arbitrary distance from
5902 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
5903 which returns part of an address in a form which will be valid for
5904 a data instruction. We do this by pushing the expression into a symbol
5905 in the expr_section, and creating a fix for that. */
5906
5907static void
5908fix_new_arm (frag, where, size, exp, pc_rel, reloc)
5909 fragS *frag;
5910 int where;
5911 short int size;
5912 expressionS *exp;
5913 int pc_rel;
5914 int reloc;
5915{
5916 fixS *new_fix;
590c50d8 5917 arm_fix_data *arm_data;
338a7060
DE
5918
5919 switch (exp->X_op)
5920 {
5921 case O_constant:
5922 case O_symbol:
5923 case O_add:
5924 case O_subtract:
5925 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
5926 break;
5927
5928 default:
590c50d8
ILT
5929 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
5930 pc_rel, reloc);
338a7060
DE
5931 break;
5932 }
5933
590c50d8
ILT
5934 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
5935 arm_data = (arm_fix_data *) obstack_alloc (&notes, sizeof (arm_fix_data));
5936 new_fix->tc_fix_data = (PTR) arm_data;
5937 arm_data->thumb_mode = thumb_mode;
5938
338a7060
DE
5939 return;
5940}
5941
5942/* A good place to do this, although this was probably not intended
5943 * for this kind of use. We need to dump the literal pool before
5944 * references are made to a null symbol pointer. */
5945void
5946arm_after_pass_hook (ignore)
5947 asection *ignore;
5948{
5949 if (current_poolP != NULL)
5950 {
5951 subseg_set (text_section, 0); /* Put it at the end of text section */
5952 s_ltorg (0);
5953 listing_prev_line ();
5954 }
5955}
5956
5957void
5958arm_start_line_hook ()
5959{
5960 last_label_seen = NULL;
5961}
5962
5963void
5964arm_frob_label (sym)
5965 symbolS *sym;
5966{
5967 last_label_seen = sym;
5968}
590c50d8
ILT
5969
5970int
5971arm_data_in_code ()
5972{
5973 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
5974 {
5975 *input_line_pointer = '/';
5976 input_line_pointer += 5;
5977 *input_line_pointer = 0;
5978 return 1;
5979 }
5980 return 0;
5981}
5982
5983char *
5984arm_canonicalize_symbol_name (name)
5985 char *name;
5986{
5987 int len;
5988
5989 if (thumb_mode && (len = strlen (name)) > 5
5990 && ! strcmp (name + len - 5, "/data"))
5991 {
5992 *(name + len - 5) = 0;
5993 }
5994
5995 return name;
5996}
This page took 0.437181 seconds and 4 git commands to generate.