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