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