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