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