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