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