Remove U suffix from constants for K&R compilers.
[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;
d92b1a8a 2664
252b5132 2665 end_of_line (str);
252b5132
RH
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 5372 && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
d92b1a8a 5373 || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
92a66162 5374 ))
252b5132
RH
5375 value = 0;
5376 else
5377 value += md_pcrel_from (fixP);
5378 }
5379 }
5380
ae5ad4ad 5381 fixP->fx_addnumber = value; /* Remember value for emit_reloc. */
252b5132
RH
5382
5383 switch (fixP->fx_r_type)
5384 {
5385 case BFD_RELOC_ARM_IMMEDIATE:
5386 newimm = validate_immediate (value);
5387 temp = md_chars_to_number (buf, INSN_SIZE);
5388
5389 /* If the instruction will fail, see if we can fix things up by
5390 changing the opcode. */
5391 if (newimm == (unsigned int) FAIL
5392 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
5393 {
5394 as_bad_where (fixP->fx_file, fixP->fx_line,
11450271 5395 _("invalid constant (%lx) after fixup"),
3d103319 5396 (unsigned long) value);
252b5132
RH
5397 break;
5398 }
5399
5400 newimm |= (temp & 0xfffff000);
5401 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5402 break;
5403
49a5575c
NC
5404 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
5405 {
5406 unsigned int highpart = 0;
5407 unsigned int newinsn = 0xe1a00000; /* nop */
5408 newimm = validate_immediate (value);
5409 temp = md_chars_to_number (buf, INSN_SIZE);
5410
5411 /* If the instruction will fail, see if we can fix things up by
5412 changing the opcode. */
5413 if (newimm == (unsigned int) FAIL
5414 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
5415 {
5416 /* No ? OK - try using two ADD instructions to generate the value. */
5417 newimm = validate_immediate_twopart (value, & highpart);
5418
5419 /* Yes - then make sure that the second instruction is also an add. */
5420 if (newimm != (unsigned int) FAIL)
5421 newinsn = temp;
5422 /* Still No ? Try using a negated value. */
5423 else if (validate_immediate_twopart (- value, & highpart) != (unsigned int) FAIL)
5424 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
5425 /* Otherwise - give up. */
5426 else
5427 {
5428 as_bad_where (fixP->fx_file, fixP->fx_line,
11450271 5429 _("Unable to compute ADRL instructions for PC offset of 0x%x"), value);
49a5575c
NC
5430 break;
5431 }
5432
5433 /* Replace the first operand in the 2nd instruction (which is the PC)
5434 with the destination register. We have already added in the PC in the
5435 first instruction and we do not want to do it again. */
5436 newinsn &= ~ 0xf0000;
5437 newinsn |= ((newinsn & 0x0f000) << 4);
5438 }
5439
5440 newimm |= (temp & 0xfffff000);
5441 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5442
5443 highpart |= (newinsn & 0xfffff000);
5444 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
5445 }
5446 break;
5447
5448 case BFD_RELOC_ARM_OFFSET_IMM:
252b5132 5449 sign = value >= 0;
276b1dc2
NC
5450
5451 if (value < 0)
5452 value = - value;
5453
5454 if (validate_offset_imm (value, 0) == FAIL)
252b5132 5455 {
50f4163f
NC
5456 as_bad_where (fixP->fx_file, fixP->fx_line,
5457 _("bad immediate value for offset (%ld)"), (long) value);
252b5132
RH
5458 break;
5459 }
252b5132
RH
5460
5461 newval = md_chars_to_number (buf, INSN_SIZE);
5462 newval &= 0xff7ff000;
5463 newval |= value | (sign ? INDEX_UP : 0);
5464 md_number_to_chars (buf, newval, INSN_SIZE);
5465 break;
5466
5467 case BFD_RELOC_ARM_OFFSET_IMM8:
5468 case BFD_RELOC_ARM_HWLITERAL:
5469 sign = value >= 0;
276b1dc2
NC
5470
5471 if (value < 0)
5472 value = - value;
5473
5474 if (validate_offset_imm (value, 1) == FAIL)
252b5132
RH
5475 {
5476 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
5477 as_bad_where (fixP->fx_file, fixP->fx_line,
11450271 5478 _("invalid literal constant: pool needs to be closer"));
252b5132 5479 else
50f4163f
NC
5480 as_bad (_("bad immediate value for half-word offset (%ld)"),
5481 (long) value);
252b5132
RH
5482 break;
5483 }
5484
252b5132
RH
5485 newval = md_chars_to_number (buf, INSN_SIZE);
5486 newval &= 0xff7ff0f0;
3d103319 5487 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
252b5132
RH
5488 md_number_to_chars (buf, newval, INSN_SIZE);
5489 break;
5490
5491 case BFD_RELOC_ARM_LITERAL:
5492 sign = value >= 0;
276b1dc2 5493
252b5132 5494 if (value < 0)
276b1dc2 5495 value = - value;
252b5132 5496
276b1dc2 5497 if (validate_offset_imm (value, 0) == FAIL)
252b5132
RH
5498 {
5499 as_bad_where (fixP->fx_file, fixP->fx_line,
11450271 5500 _("invalid literal constant: pool needs to be closer"));
252b5132
RH
5501 break;
5502 }
5503
5504 newval = md_chars_to_number (buf, INSN_SIZE);
5505 newval &= 0xff7ff000;
5506 newval |= value | (sign ? INDEX_UP : 0);
5507 md_number_to_chars (buf, newval, INSN_SIZE);
5508 break;
5509
5510 case BFD_RELOC_ARM_SHIFT_IMM:
5511 newval = md_chars_to_number (buf, INSN_SIZE);
5512 if (((unsigned long) value) > 32
5513 || (value == 32
5514 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
5515 {
5516 as_bad_where (fixP->fx_file, fixP->fx_line,
5517 _("shift expression is too large"));
5518 break;
5519 }
5520
5521 if (value == 0)
5522 newval &= ~0x60; /* Shifts of zero must be done as lsl */
5523 else if (value == 32)
5524 value = 0;
5525 newval &= 0xfffff07f;
5526 newval |= (value & 0x1f) << 7;
5527 md_number_to_chars (buf, newval , INSN_SIZE);
5528 break;
5529
5530 case BFD_RELOC_ARM_SWI:
5531 if (arm_data->thumb_mode)
5532 {
5533 if (((unsigned long) value) > 0xff)
5534 as_bad_where (fixP->fx_file, fixP->fx_line,
5535 _("Invalid swi expression"));
5536 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
5537 newval |= value;
5538 md_number_to_chars (buf, newval, THUMB_SIZE);
5539 }
5540 else
5541 {
5542 if (((unsigned long) value) > 0x00ffffff)
5543 as_bad_where (fixP->fx_file, fixP->fx_line,
5544 _("Invalid swi expression"));
5545 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
5546 newval |= value;
5547 md_number_to_chars (buf, newval , INSN_SIZE);
5548 }
5549 break;
5550
5551 case BFD_RELOC_ARM_MULTI:
5552 if (((unsigned long) value) > 0xffff)
5553 as_bad_where (fixP->fx_file, fixP->fx_line,
5554 _("Invalid expression in load/store multiple"));
5555 newval = value | md_chars_to_number (buf, INSN_SIZE);
5556 md_number_to_chars (buf, newval, INSN_SIZE);
5557 break;
5558
5559 case BFD_RELOC_ARM_PCREL_BRANCH:
5560 newval = md_chars_to_number (buf, INSN_SIZE);
661e4995 5561
67231402
NC
5562 /* Sign-extend a 24-bit number. */
5563#define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
5564
252b5132 5565#ifdef OBJ_ELF
252b5132 5566 if (! target_oabi)
67231402
NC
5567 value = fixP->fx_offset;
5568#endif
5569
5570 /* We are going to store value (shifted right by two) in the
5571 instruction, in a 24 bit, signed field. Thus we need to check
5572 that none of the top 8 bits of the shifted value (top 7 bits of
5573 the unshifted, unsigned value) are set, or that they are all set. */
fc633e5b
AM
5574 if ((value & ~ ((offsetT) 0x1ffffff)) != 0
5575 && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
67231402
NC
5576 {
5577#ifdef OBJ_ELF
5578 /* Normally we would be stuck at this point, since we cannot store
5579 the absolute address that is the destination of the branch in the
5580 24 bits of the branch instruction. If however, we happen to know
5581 that the destination of the branch is in the same section as the
5582 branch instruciton itself, then we can compute the relocation for
5583 ourselves and not have to bother the linker with it.
5584
5585 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
5586 because I have not worked out how to do this for OBJ_COFF or
5587 target_oabi. */
5588 if (! target_oabi
5589 && fixP->fx_addsy != NULL
5590 && S_IS_DEFINED (fixP->fx_addsy)
5591 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
5592 {
5593 /* Get pc relative value to go into the branch. */
5594 value = * val;
5595
5596 /* Permit a backward branch provided that enough bits are set.
5597 Allow a forwards branch, provided that enough bits are clear. */
fc633e5b
AM
5598 if ((value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
5599 || (value & ~ ((offsetT) 0x1ffffff)) == 0)
67231402
NC
5600 fixP->fx_done = 1;
5601 }
5602
5603 if (! fixP->fx_done)
252b5132 5604#endif
67231402
NC
5605 as_bad_where (fixP->fx_file, fixP->fx_line,
5606 _("gas can't handle same-section branch dest >= 0x04000000"));
5607 }
5608
5609 value >>= 2;
5610 value += SEXT24 (newval);
5611
fc633e5b
AM
5612 if ((value & ~ ((offsetT) 0xffffff)) != 0
5613 && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
67231402
NC
5614 as_bad_where (fixP->fx_file, fixP->fx_line,
5615 _("out of range branch"));
5616
5617 newval = (value & 0x00ffffff) | (newval & 0xff000000);
252b5132
RH
5618 md_number_to_chars (buf, newval, INSN_SIZE);
5619 break;
5620
d92b1a8a
NC
5621 case BFD_RELOC_ARM_PCREL_BLX:
5622 {
5623 offsetT hbit;
5624 newval = md_chars_to_number (buf, INSN_SIZE);
5625
5626#ifdef OBJ_ELF
5627 if (! target_oabi)
5628 value = fixP->fx_offset;
5629#endif
5630 hbit = (value >> 1) & 1;
5631 value = (value >> 2) & 0x00ffffff;
5632 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
5633 newval = value | (newval & 0xfe000000) | (hbit << 24);
5634 md_number_to_chars (buf, newval, INSN_SIZE);
5635 }
5636 break;
92a66162 5637
252b5132
RH
5638 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* conditional branch */
5639 newval = md_chars_to_number (buf, THUMB_SIZE);
5640 {
5641 addressT diff = (newval & 0xff) << 1;
5642 if (diff & 0x100)
5643 diff |= ~0xff;
5644
5645 value += diff;
5646 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
5647 as_bad_where (fixP->fx_file, fixP->fx_line,
5648 _("Branch out of range"));
5649 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
5650 }
5651 md_number_to_chars (buf, newval, THUMB_SIZE);
5652 break;
5653
5654 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* unconditional branch */
5655 newval = md_chars_to_number (buf, THUMB_SIZE);
5656 {
5657 addressT diff = (newval & 0x7ff) << 1;
5658 if (diff & 0x800)
5659 diff |= ~0x7ff;
5660
5661 value += diff;
5662 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
5663 as_bad_where (fixP->fx_file, fixP->fx_line,
5664 _("Branch out of range"));
5665 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
5666 }
5667 md_number_to_chars (buf, newval, THUMB_SIZE);
5668 break;
5669
d92b1a8a 5670 case BFD_RELOC_THUMB_PCREL_BLX:
252b5132
RH
5671 case BFD_RELOC_THUMB_PCREL_BRANCH23:
5672 {
5673 offsetT newval2;
5674 addressT diff;
5675
5676 newval = md_chars_to_number (buf, THUMB_SIZE);
5677 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
5678 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
5679 if (diff & 0x400000)
5680 diff |= ~0x3fffff;
ae5ad4ad
NC
5681#ifdef OBJ_ELF
5682 value = fixP->fx_offset;
5683#endif
252b5132
RH
5684 value += diff;
5685 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
5686 as_bad_where (fixP->fx_file, fixP->fx_line,
5687 _("Branch with link out of range"));
5688
5689 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
5690 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
5691 md_number_to_chars (buf, newval, THUMB_SIZE);
5692 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
5693 }
5694 break;
5695
5696 case BFD_RELOC_8:
5697 if (fixP->fx_done || fixP->fx_pcrel)
5698 md_number_to_chars (buf, value, 1);
5699#ifdef OBJ_ELF
5700 else if (!target_oabi)
5701 {
5702 value = fixP->fx_offset;
5703 md_number_to_chars (buf, value, 1);
5704 }
5705#endif
5706 break;
5707
5708 case BFD_RELOC_16:
5709 if (fixP->fx_done || fixP->fx_pcrel)
5710 md_number_to_chars (buf, value, 2);
5711#ifdef OBJ_ELF
5712 else if (!target_oabi)
5713 {
5714 value = fixP->fx_offset;
5715 md_number_to_chars (buf, value, 2);
5716 }
5717#endif
5718 break;
5719
5720#ifdef OBJ_ELF
5721 case BFD_RELOC_ARM_GOT32:
5722 case BFD_RELOC_ARM_GOTOFF:
5723 md_number_to_chars (buf, 0, 4);
5724 break;
5725#endif
5726
5727 case BFD_RELOC_RVA:
5728 case BFD_RELOC_32:
5729 if (fixP->fx_done || fixP->fx_pcrel)
5730 md_number_to_chars (buf, value, 4);
5731#ifdef OBJ_ELF
5732 else if (!target_oabi)
5733 {
5734 value = fixP->fx_offset;
5735 md_number_to_chars (buf, value, 4);
5736 }
5737#endif
5738 break;
5739
5740#ifdef OBJ_ELF
5741 case BFD_RELOC_ARM_PLT32:
5742 /* It appears the instruction is fully prepared at this point. */
5743 break;
5744#endif
5745
5746 case BFD_RELOC_ARM_GOTPC:
5747 md_number_to_chars (buf, value, 4);
5748 break;
5749
5750 case BFD_RELOC_ARM_CP_OFF_IMM:
5751 sign = value >= 0;
5752 if (value < -1023 || value > 1023 || (value & 3))
5753 as_bad_where (fixP->fx_file, fixP->fx_line,
5754 _("Illegal value for co-processor offset"));
5755 if (value < 0)
5756 value = -value;
5757 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
5758 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
5759 md_number_to_chars (buf, newval , INSN_SIZE);
5760 break;
5761
5762 case BFD_RELOC_ARM_THUMB_OFFSET:
5763 newval = md_chars_to_number (buf, THUMB_SIZE);
5764 /* Exactly what ranges, and where the offset is inserted depends on
5765 the type of instruction, we can establish this from the top 4 bits */
5766 switch (newval >> 12)
5767 {
5768 case 4: /* PC load */
5769 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5770 forced to zero for these loads, so we will need to round
5771 up the offset if the instruction address is not word
5772 aligned (since the final address produced must be, and
5773 we can only describe word-aligned immediate offsets). */
5774
5775 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
5776 as_bad_where (fixP->fx_file, fixP->fx_line,
5777 _("Invalid offset, target not word aligned (0x%08X)"),
5778 (unsigned int)(fixP->fx_frag->fr_address + fixP->fx_where + value));
5779
5780 if ((value + 2) & ~0x3fe)
5781 as_bad_where (fixP->fx_file, fixP->fx_line,
50f4163f 5782 _("Invalid offset, value too big (0x%08X)"), value);
252b5132
RH
5783
5784 /* Round up, since pc will be rounded down. */
5785 newval |= (value + 2) >> 2;
5786 break;
5787
5788 case 9: /* SP load/store */
5789 if (value & ~0x3fc)
5790 as_bad_where (fixP->fx_file, fixP->fx_line,
50f4163f 5791 _("Invalid offset, value too big (0x%08X)"), value);
252b5132
RH
5792 newval |= value >> 2;
5793 break;
5794
5795 case 6: /* Word load/store */
5796 if (value & ~0x7c)
5797 as_bad_where (fixP->fx_file, fixP->fx_line,
50f4163f 5798 _("Invalid offset, value too big (0x%08X)"), value);
252b5132
RH
5799 newval |= value << 4; /* 6 - 2 */
5800 break;
5801
5802 case 7: /* Byte load/store */
5803 if (value & ~0x1f)
5804 as_bad_where (fixP->fx_file, fixP->fx_line,
50f4163f 5805 _("Invalid offset, value too big (0x%08X)"), value);
252b5132
RH
5806 newval |= value << 6;
5807 break;
5808
5809 case 8: /* Halfword load/store */
5810 if (value & ~0x3e)
5811 as_bad_where (fixP->fx_file, fixP->fx_line,
50f4163f 5812 _("Invalid offset, value too big (0x%08X)"), value);
252b5132
RH
5813 newval |= value << 5; /* 6 - 1 */
5814 break;
5815
5816 default:
5817 as_bad_where (fixP->fx_file, fixP->fx_line,
3d103319
ILT
5818 "Unable to process relocation for thumb opcode: %lx",
5819 (unsigned long) newval);
252b5132
RH
5820 break;
5821 }
5822 md_number_to_chars (buf, newval, THUMB_SIZE);
5823 break;
5824
5825 case BFD_RELOC_ARM_THUMB_ADD:
5826 /* This is a complicated relocation, since we use it for all of
5827 the following immediate relocations:
5828 3bit ADD/SUB
5829 8bit ADD/SUB
5830 9bit ADD/SUB SP word-aligned
5831 10bit ADD PC/SP word-aligned
5832
5833 The type of instruction being processed is encoded in the
5834 instruction field:
5835 0x8000 SUB
5836 0x00F0 Rd
5837 0x000F Rs
5838 */
5839 newval = md_chars_to_number (buf, THUMB_SIZE);
5840 {
5841 int rd = (newval >> 4) & 0xf;
5842 int rs = newval & 0xf;
5843 int subtract = newval & 0x8000;
5844
5845 if (rd == REG_SP)
5846 {
5847 if (value & ~0x1fc)
5848 as_bad_where (fixP->fx_file, fixP->fx_line,
5849 _("Invalid immediate for stack address calculation"));
5850 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
5851 newval |= value >> 2;
5852 }
5853 else if (rs == REG_PC || rs == REG_SP)
5854 {
5855 if (subtract ||
5856 value & ~0x3fc)
5857 as_bad_where (fixP->fx_file, fixP->fx_line,
3d103319
ILT
5858 _("Invalid immediate for address calculation (value = 0x%08lX)"),
5859 (unsigned long) value);
252b5132
RH
5860 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
5861 newval |= rd << 8;
5862 newval |= value >> 2;
5863 }
5864 else if (rs == rd)
5865 {
5866 if (value & ~0xff)
5867 as_bad_where (fixP->fx_file, fixP->fx_line,
5868 _("Invalid 8bit immediate"));
5869 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
5870 newval |= (rd << 8) | value;
5871 }
5872 else
5873 {
5874 if (value & ~0x7)
5875 as_bad_where (fixP->fx_file, fixP->fx_line,
5876 _("Invalid 3bit immediate"));
5877 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
5878 newval |= rd | (rs << 3) | (value << 6);
5879 }
5880 }
5881 md_number_to_chars (buf, newval , THUMB_SIZE);
5882 break;
5883
5884 case BFD_RELOC_ARM_THUMB_IMM:
5885 newval = md_chars_to_number (buf, THUMB_SIZE);
5886 switch (newval >> 11)
5887 {
5888 case 0x04: /* 8bit immediate MOV */
5889 case 0x05: /* 8bit immediate CMP */
5890 if (value < 0 || value > 255)
5891 as_bad_where (fixP->fx_file, fixP->fx_line,
3d103319
ILT
5892 _("Invalid immediate: %ld is too large"),
5893 (long) value);
252b5132
RH
5894 newval |= value;
5895 break;
5896
5897 default:
5898 abort ();
5899 }
5900 md_number_to_chars (buf, newval , THUMB_SIZE);
5901 break;
5902
5903 case BFD_RELOC_ARM_THUMB_SHIFT:
5904 /* 5bit shift value (0..31) */
5905 if (value < 0 || value > 31)
5906 as_bad_where (fixP->fx_file, fixP->fx_line,
3d103319 5907 _("Illegal Thumb shift value: %ld"), (long) value);
252b5132
RH
5908 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
5909 newval |= value << 6;
5910 md_number_to_chars (buf, newval , THUMB_SIZE);
5911 break;
5912
5913 case BFD_RELOC_VTABLE_INHERIT:
5914 case BFD_RELOC_VTABLE_ENTRY:
5915 fixP->fx_done = 0;
5916 return 1;
5917
5918 case BFD_RELOC_NONE:
5919 default:
5920 as_bad_where (fixP->fx_file, fixP->fx_line,
11450271 5921 _("Bad relocation fixup type (%d)"), fixP->fx_r_type);
252b5132
RH
5922 }
5923
5924 return 1;
5925}
5926
5927/* Translate internal representation of relocation info to BFD target
5928 format. */
5929arelent *
5930tc_gen_reloc (section, fixp)
684b81fa 5931 asection * section ATTRIBUTE_UNUSED;
252b5132
RH
5932 fixS * fixp;
5933{
5934 arelent * reloc;
5935 bfd_reloc_code_real_type code;
5936
5937 reloc = (arelent *) xmalloc (sizeof (arelent));
5938
174419c1
ILT
5939 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
5940 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
252b5132
RH
5941 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5942
5943 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5944#ifndef OBJ_ELF
5945 if (fixp->fx_pcrel == 0)
5946 reloc->addend = fixp->fx_offset;
5947 else
5948 reloc->addend = fixp->fx_offset = reloc->address;
5949#else /* OBJ_ELF */
5950 reloc->addend = fixp->fx_offset;
5951#endif
5952
5953 switch (fixp->fx_r_type)
5954 {
5955 case BFD_RELOC_8:
5956 if (fixp->fx_pcrel)
5957 {
5958 code = BFD_RELOC_8_PCREL;
5959 break;
5960 }
5961
5962 case BFD_RELOC_16:
5963 if (fixp->fx_pcrel)
5964 {
5965 code = BFD_RELOC_16_PCREL;
5966 break;
5967 }
5968
5969 case BFD_RELOC_32:
5970 if (fixp->fx_pcrel)
5971 {
5972 code = BFD_RELOC_32_PCREL;
5973 break;
5974 }
5975
5976 case BFD_RELOC_ARM_PCREL_BRANCH:
d92b1a8a 5977 case BFD_RELOC_ARM_PCREL_BLX:
252b5132
RH
5978 case BFD_RELOC_RVA:
5979 case BFD_RELOC_THUMB_PCREL_BRANCH9:
5980 case BFD_RELOC_THUMB_PCREL_BRANCH12:
5981 case BFD_RELOC_THUMB_PCREL_BRANCH23:
d92b1a8a 5982 case BFD_RELOC_THUMB_PCREL_BLX:
252b5132
RH
5983 case BFD_RELOC_VTABLE_ENTRY:
5984 case BFD_RELOC_VTABLE_INHERIT:
5985 code = fixp->fx_r_type;
5986 break;
5987
5988 case BFD_RELOC_ARM_LITERAL:
5989 case BFD_RELOC_ARM_HWLITERAL:
5990 /* If this is called then the a literal has been referenced across
2f992c04 5991 a section boundary - possibly due to an implicit dump */
252b5132 5992 as_bad_where (fixp->fx_file, fixp->fx_line,
2f992c04 5993 _("Literal referenced across section boundary (Implicit dump?)"));
252b5132
RH
5994 return NULL;
5995
252b5132
RH
5996#ifdef OBJ_ELF
5997 case BFD_RELOC_ARM_GOT32:
5998 case BFD_RELOC_ARM_GOTOFF:
5999 case BFD_RELOC_ARM_PLT32:
6000 code = fixp->fx_r_type;
6001 break;
6002#endif
6003
6004 case BFD_RELOC_ARM_IMMEDIATE:
6005 as_bad_where (fixp->fx_file, fixp->fx_line,
6006 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
6007 fixp->fx_r_type);
6008 return NULL;
6009
49a5575c
NC
6010 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
6011 as_bad_where (fixp->fx_file, fixp->fx_line,
6012 _("ADRL used for a symbol not defined in the same file"),
6013 fixp->fx_r_type);
6014 return NULL;
6015
252b5132
RH
6016 case BFD_RELOC_ARM_OFFSET_IMM:
6017 as_bad_where (fixp->fx_file, fixp->fx_line,
6018 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
6019 fixp->fx_r_type);
6020 return NULL;
6021
6022 default:
6023 {
6024 char * type;
6025 switch (fixp->fx_r_type)
6026 {
6027 case BFD_RELOC_ARM_IMMEDIATE: type = "IMMEDIATE"; break;
6028 case BFD_RELOC_ARM_OFFSET_IMM: type = "OFFSET_IMM"; break;
6029 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
6030 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
6031 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
6032 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
6033 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
6034 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
6035 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
6036 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
6037 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
ae5ad4ad 6038 default: type = _("<unknown>"); break;
252b5132
RH
6039 }
6040 as_bad_where (fixp->fx_file, fixp->fx_line,
6041 _("Can not represent %s relocation in this object file format (%d)"),
6042 type, fixp->fx_pcrel);
6043 return NULL;
6044 }
6045 }
6046
6047#ifdef OBJ_ELF
6048 if (code == BFD_RELOC_32_PCREL
6049 && GOT_symbol
6050 && fixp->fx_addsy == GOT_symbol)
a8aed0fb
UD
6051 {
6052 code = BFD_RELOC_ARM_GOTPC;
6053 reloc->addend = fixp->fx_offset = reloc->address;
6054 }
252b5132
RH
6055#endif
6056
6057 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
6058
6059 if (reloc->howto == NULL)
6060 {
6061 as_bad_where (fixp->fx_file, fixp->fx_line,
6062 _("Can not represent %s relocation in this object file format"),
6063 bfd_get_reloc_code_name (code));
6064 return NULL;
6065 }
6066
c8d259f7
CM
6067 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
6068 vtable entry to be used in the relocation's section offset. */
6069 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
6070 reloc->address = fixp->fx_offset;
6071
252b5132
RH
6072 return reloc;
6073}
6074
6075int
6076md_estimate_size_before_relax (fragP, segtype)
684b81fa
NC
6077 fragS * fragP ATTRIBUTE_UNUSED;
6078 segT segtype ATTRIBUTE_UNUSED;
252b5132
RH
6079{
6080 as_fatal (_("md_estimate_size_before_relax\n"));
6081 return 1;
6082}
6083
6084static void
49a5575c 6085output_inst PARAMS ((void))
252b5132
RH
6086{
6087 char * to = NULL;
6088
6089 if (inst.error)
6090 {
6091 as_bad (inst.error);
6092 return;
6093 }
6094
6095 to = frag_more (inst.size);
ae5ad4ad 6096
252b5132
RH
6097 if (thumb_mode && (inst.size > THUMB_SIZE))
6098 {
6099 assert (inst.size == (2 * THUMB_SIZE));
6100 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
49a5575c
NC
6101 md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
6102 }
6103 else if (inst.size > INSN_SIZE)
6104 {
6105 assert (inst.size == (2 * INSN_SIZE));
6106 md_number_to_chars (to, inst.instruction, INSN_SIZE);
6107 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
252b5132
RH
6108 }
6109 else
6110 md_number_to_chars (to, inst.instruction, inst.size);
6111
6112 if (inst.reloc.type != BFD_RELOC_NONE)
6113 fix_new_arm (frag_now, to - frag_now->fr_literal,
6114 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
6115 inst.reloc.type);
6116
6117 return;
6118}
6119
6120void
6121md_assemble (str)
6122 char * str;
6123{
6124 char c;
6125 char * p;
6126 char * q;
6127 char * start;
6128
6129 /* Align the instruction.
6130 This may not be the right thing to do but ... */
6131 /* arm_align (2, 0); */
6132 listing_prev_line (); /* Defined in listing.h */
6133
6134 /* Align the previous label if needed. */
6135 if (last_label_seen != NULL)
6136 {
174419c1 6137 symbol_set_frag (last_label_seen, frag_now);
252b5132
RH
6138 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
6139 S_SET_SEGMENT (last_label_seen, now_seg);
6140 }
6141
6142 memset (&inst, '\0', sizeof (inst));
6143 inst.reloc.type = BFD_RELOC_NONE;
6144
ae5ad4ad 6145 skip_whitespace (str);
49a5575c 6146
252b5132
RH
6147 /* Scan up to the end of the op-code, which must end in white space or
6148 end of string. */
6149 for (start = p = str; *p != '\0'; p++)
6150 if (*p == ' ')
6151 break;
6152
6153 if (p == str)
6154 {
6155 as_bad (_("No operator -- statement `%s'\n"), str);
6156 return;
6157 }
6158
6159 if (thumb_mode)
6160 {
49a5575c 6161 CONST struct thumb_opcode * opcode;
252b5132
RH
6162
6163 c = *p;
6164 *p = '\0';
6165 opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
6166 *p = c;
49a5575c 6167
252b5132
RH
6168 if (opcode)
6169 {
92a66162 6170 /* Check that this instruction is supported for this CPU. */
a64bcdd8 6171 if (thumb_mode == 1 && (opcode->variants & cpu_variant) == 0)
92a66162
DL
6172 {
6173 as_bad (_("selected processor does not support this opcode"));
6174 return;
6175 }
6176
252b5132
RH
6177 inst.instruction = opcode->value;
6178 inst.size = opcode->size;
6179 (*opcode->parms)(p);
49a5575c 6180 output_inst ();
252b5132
RH
6181 return;
6182 }
6183 }
6184 else
6185 {
49a5575c 6186 CONST struct asm_opcode * opcode;
92a66162 6187 unsigned long cond_code;
252b5132
RH
6188
6189 inst.size = INSN_SIZE;
6190 /* p now points to the end of the opcode, probably white space, but we
6191 have to break the opcode up in case it contains condionals and flags;
6192 keep trying with progressively smaller basic instructions until one
ae5ad4ad 6193 matches, or we run out of opcode. */
252b5132 6194 q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
d92b1a8a 6195
252b5132
RH
6196 for (; q != str; q--)
6197 {
6198 c = *q;
6199 *q = '\0';
d92b1a8a 6200
252b5132
RH
6201 opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
6202 *q = c;
49a5575c 6203
252b5132
RH
6204 if (opcode && opcode->template)
6205 {
6206 unsigned long flag_bits = 0;
49a5575c 6207 char * r;
252b5132 6208
ae5ad4ad 6209 /* Check that this instruction is supported for this CPU. */
252b5132
RH
6210 if ((opcode->variants & cpu_variant) == 0)
6211 goto try_shorter;
6212
6213 inst.instruction = opcode->value;
ae5ad4ad 6214 if (q == p) /* Just a simple opcode. */
252b5132 6215 {
92a66162
DL
6216 if (opcode->comp_suffix)
6217 {
6218 if (*opcode->comp_suffix != '\0')
858f4ff6 6219 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
92a66162
DL
6220 str, opcode->comp_suffix);
6221 else
6222 /* Not a conditional instruction. */
6223 (*opcode->parms)(q, 0);
6224 }
252b5132
RH
6225 else
6226 {
92a66162 6227 /* A conditional instruction with default condition. */
252b5132
RH
6228 inst.instruction |= COND_ALWAYS;
6229 (*opcode->parms)(q, 0);
6230 }
49a5575c 6231 output_inst ();
252b5132
RH
6232 return;
6233 }
6234
92a66162 6235 /* Not just a simple opcode. Check if extra is a conditional. */
252b5132
RH
6236 r = q;
6237 if (p - r >= 2)
6238 {
6239 CONST struct asm_cond *cond;
6240 char d = *(r + 2);
6241
6242 *(r + 2) = '\0';
6243 cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
6244 *(r + 2) = d;
6245 if (cond)
6246 {
6247 if (cond->value == 0xf0000000)
6248 as_tsktsk (
6249_("Warning: Use of the 'nv' conditional is deprecated\n"));
6250
92a66162 6251 cond_code = cond->value;
252b5132
RH
6252 r += 2;
6253 }
6254 else
92a66162 6255 cond_code = COND_ALWAYS;
252b5132
RH
6256 }
6257 else
92a66162
DL
6258 cond_code = COND_ALWAYS;
6259
92a66162
DL
6260 /* Apply the conditional, or complain it's not allowed. */
6261 if (opcode->comp_suffix && *opcode->comp_suffix == '\0')
6262 {
6263 /* Instruction isn't conditional */
6264 if (cond_code != COND_ALWAYS)
6265 {
6266 as_bad (_("Opcode `%s' is unconditional\n"), str);
6267 return;
6268 }
6269 }
6270 else
6271 /* Instruction is conditional: set the condition into it. */
6272 inst.instruction |= cond_code;
6273
252b5132 6274
ae5ad4ad
NC
6275 /* If there is a compulsory suffix, it should come here, before
6276 any optional flags. */
92a66162 6277 if (opcode->comp_suffix && *opcode->comp_suffix != '\0')
252b5132
RH
6278 {
6279 CONST char *s = opcode->comp_suffix;
6280
6281 while (*s)
6282 {
6283 inst.suffix++;
6284 if (*r == *s)
6285 break;
6286 s++;
6287 }
6288
6289 if (*s == '\0')
6290 {
6291 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
6292 opcode->comp_suffix);
6293 return;
6294 }
6295
6296 r++;
6297 }
6298
6299 /* The remainder, if any should now be flags for the instruction;
6300 Scan these checking each one found with the opcode. */
6301 if (r != p)
6302 {
6303 char d;
6304 CONST struct asm_flg *flag = opcode->flags;
6305
6306 if (flag)
6307 {
6308 int flagno;
6309
6310 d = *p;
6311 *p = '\0';
6312
6313 for (flagno = 0; flag[flagno].template; flagno++)
6314 {
6315 if (streq (r, flag[flagno].template))
6316 {
6317 flag_bits |= flag[flagno].set_bits;
6318 break;
6319 }
6320 }
6321
6322 *p = d;
6323 if (! flag[flagno].template)
6324 goto try_shorter;
6325 }
6326 else
6327 goto try_shorter;
6328 }
6329
6330 (*opcode->parms) (p, flag_bits);
49a5575c 6331 output_inst ();
252b5132
RH
6332 return;
6333 }
6334
6335 try_shorter:
6336 ;
6337 }
6338 }
6339
6340 /* It wasn't an instruction, but it might be a register alias of the form
ae5ad4ad 6341 alias .req reg */
252b5132 6342 q = p;
ae5ad4ad 6343 skip_whitespace (q);
252b5132
RH
6344
6345 c = *p;
6346 *p = '\0';
6347
6348 if (*q && !strncmp (q, ".req ", 4))
6349 {
6350 int reg;
6351 char * copy_of_str = str;
6352 char * r;
6353
6354 q += 4;
ae5ad4ad 6355 skip_whitespace (q);
252b5132
RH
6356
6357 for (r = q; *r != '\0'; r++)
6358 if (*r == ' ')
6359 break;
6360
6361 if (r != q)
6362 {
6363 int regnum;
6364 char d = *r;
6365
6366 *r = '\0';
6367 regnum = arm_reg_parse (& q);
6368 *r = d;
6369
6370 reg = arm_reg_parse (& str);
6371
6372 if (reg == FAIL)
6373 {
6374 if (regnum != FAIL)
11450271 6375 insert_reg_alias (str, regnum);
252b5132 6376 else
92a66162 6377 as_warn (_("register '%s' does not exist\n"), q);
252b5132
RH
6378 }
6379 else if (regnum != FAIL)
6380 {
6381 if (reg != regnum)
ec9991dc
NC
6382 as_warn (_("ignoring redefinition of register alias '%s'"),
6383 copy_of_str );
252b5132 6384
ae5ad4ad 6385 /* Do not warn about redefinitions to the same alias. */
252b5132
RH
6386 }
6387 else
6388 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6389 copy_of_str, q);
6390 }
6391 else
6392 as_warn (_("ignoring incomplete .req pseuso op"));
6393
6394 *p = c;
6395 return;
6396 }
6397
6398 *p = c;
6399 as_bad (_("bad instruction `%s'"), start);
6400}
6401
6402/*
6403 * md_parse_option
6404 * Invocation line includes a switch not recognized by the base assembler.
6405 * See if it's a processor-specific option. These are:
6406 * Cpu variants, the arm part is optional:
6407 * -m[arm]1 Currently not supported.
6408 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6409 * -m[arm]3 Arm 3 processor
6410 * -m[arm]6[xx], Arm 6 processors
6411 * -m[arm]7[xx][t][[d]m] Arm 7 processors
49a5575c
NC
6412 * -m[arm]8[10] Arm 8 processors
6413 * -m[arm]9[20][tdmi] Arm 9 processors
c1d3c45e 6414 * -mstrongarm[110[0]] StrongARM processors
92a66162 6415 * -m[arm]v[2345] Arm architectures
252b5132
RH
6416 * -mall All (except the ARM1)
6417 * FP variants:
6418 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6419 * -mfpe-old (No float load/store multiples)
6420 * -mno-fpu Disable all floating point instructions
6421 * Run-time endian selection:
6422 * -EB big endian cpu
6423 * -EL little endian cpu
6424 * ARM Procedure Calling Standard:
6425 * -mapcs-32 32 bit APCS
6426 * -mapcs-26 26 bit APCS
6427 * -mapcs-float Pass floats in float regs
6428 * -mapcs-reentrant Position independent code
6429 * -mthumb-interwork Code supports Arm/Thumb interworking
6430 * -moabi Old ELF ABI
6431 */
6432
6433CONST char * md_shortopts = "m:k";
6434struct option md_longopts[] =
6435{
6436#ifdef ARM_BI_ENDIAN
6437#define OPTION_EB (OPTION_MD_BASE + 0)
6438 {"EB", no_argument, NULL, OPTION_EB},
6439#define OPTION_EL (OPTION_MD_BASE + 1)
6440 {"EL", no_argument, NULL, OPTION_EL},
6441#ifdef OBJ_ELF
6442#define OPTION_OABI (OPTION_MD_BASE +2)
6443 {"oabi", no_argument, NULL, OPTION_OABI},
6444#endif
6445#endif
6446 {NULL, no_argument, NULL, 0}
6447};
6448size_t md_longopts_size = sizeof (md_longopts);
6449
6450int
6451md_parse_option (c, arg)
6452 int c;
6453 char * arg;
6454{
6455 char * str = arg;
6456
6457 switch (c)
6458 {
6459#ifdef ARM_BI_ENDIAN
6460 case OPTION_EB:
6461 target_big_endian = 1;
6462 break;
6463 case OPTION_EL:
6464 target_big_endian = 0;
6465 break;
6466#endif
6467
6468 case 'm':
6469 switch (*str)
6470 {
6471 case 'f':
6472 if (streq (str, "fpa10"))
6473 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
6474 else if (streq (str, "fpa11"))
6475 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
6476 else if (streq (str, "fpe-old"))
6477 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
6478 else
6479 goto bad;
6480 break;
6481
6482 case 'n':
6483 if (streq (str, "no-fpu"))
6484 cpu_variant &= ~FPU_ALL;
6485 break;
6486
6487#ifdef OBJ_ELF
6488 case 'o':
6489 if (streq (str, "oabi"))
6490 target_oabi = true;
6491 break;
6492#endif
6493
6494 case 't':
6495 /* Limit assembler to generating only Thumb instructions: */
6496 if (streq (str, "thumb"))
6497 {
6498 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB;
6499 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
6500 thumb_mode = 1;
6501 }
6502 else if (streq (str, "thumb-interwork"))
6503 {
858f4ff6
NC
6504 if ((cpu_variant & ARM_THUMB) == 0)
6505 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4T;
252b5132
RH
6506#if defined OBJ_COFF || defined OBJ_ELF
6507 support_interwork = true;
6508#endif
6509 }
6510 else
6511 goto bad;
6512 break;
6513
6514 default:
6515 if (streq (str, "all"))
6516 {
6517 cpu_variant = ARM_ALL | FPU_ALL;
6518 return 1;
6519 }
6520#if defined OBJ_COFF || defined OBJ_ELF
6521 if (! strncmp (str, "apcs-", 5))
6522 {
6523 /* GCC passes on all command line options starting "-mapcs-..."
6524 to us, so we must parse them here. */
6525
6526 str += 5;
6527
6528 if (streq (str, "32"))
6529 {
6530 uses_apcs_26 = false;
6531 return 1;
6532 }
6533 else if (streq (str, "26"))
6534 {
6535 uses_apcs_26 = true;
6536 return 1;
6537 }
6538 else if (streq (str, "frame"))
6539 {
6540 /* Stack frames are being generated - does not affect
6541 linkage of code. */
6542 return 1;
6543 }
6544 else if (streq (str, "stack-check"))
6545 {
6546 /* Stack checking is being performed - does not affect
6547 linkage, but does require that the functions
6548 __rt_stkovf_split_small and __rt_stkovf_split_big be
6549 present in the final link. */
6550
6551 return 1;
6552 }
6553 else if (streq (str, "float"))
6554 {
6555 /* Floating point arguments are being passed in the floating
6556 point registers. This does affect linking, since this
6557 version of the APCS is incompatible with the version that
6558 passes floating points in the integer registers. */
6559
6560 uses_apcs_float = true;
6561 return 1;
6562 }
6563 else if (streq (str, "reentrant"))
6564 {
6565 /* Reentrant code has been generated. This does affect
6566 linking, since there is no point in linking reentrant/
6567 position independent code with absolute position code. */
6568 pic_code = true;
6569 return 1;
6570 }
6571
6572 as_bad (_("Unrecognised APCS switch -m%s"), arg);
6573 return 0;
6574 }
6575#endif
6576 /* Strip off optional "arm" */
6577 if (! strncmp (str, "arm", 3))
6578 str += 3;
6579
6580 switch (*str)
6581 {
6582 case '1':
6583 if (streq (str, "1"))
6584 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
6585 else
6586 goto bad;
6587 break;
6588
6589 case '2':
6590 if (streq (str, "2"))
6591 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
6592 else if (streq (str, "250"))
6593 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
6594 else
6595 goto bad;
6596 break;
6597
6598 case '3':
6599 if (streq (str, "3"))
6600 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
6601 else
6602 goto bad;
6603 break;
6604
6605 case '6':
6606 switch (strtol (str, NULL, 10))
6607 {
6608 case 6:
6609 case 60:
6610 case 600:
6611 case 610:
6612 case 620:
6613 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
6614 break;
6615 default:
6616 goto bad;
6617 }
6618 break;
6619
6620 case '7':
6621 switch (strtol (str, & str, 10)) /* Eat the processor name */
6622 {
6623 case 7:
6624 case 70:
6625 case 700:
6626 case 710:
b4d0b2b3 6627 case 720:
252b5132
RH
6628 case 7100:
6629 case 7500:
6630 break;
6631 default:
6632 goto bad;
6633 }
6634 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6635 for (; *str; str++)
6636 {
6637 switch (* str)
6638 {
6639 case 't':
49a5575c 6640 cpu_variant |= (ARM_THUMB | ARM_ARCH_V4);
252b5132
RH
6641 break;
6642
6643 case 'm':
6644 cpu_variant |= ARM_LONGMUL;
6645 break;
6646
6647 case 'f': /* fe => fp enabled cpu. */
6648 if (str[1] == 'e')
6649 ++ str;
6650 else
6651 goto bad;
6652
6653 case 'c': /* Left over from 710c processor name. */
6654 case 'd': /* Debug */
6655 case 'i': /* Embedded ICE */
6656 /* Included for completeness in ARM processor naming. */
6657 break;
6658
6659 default:
6660 goto bad;
6661 }
6662 }
6663 break;
6664
6665 case '8':
6666 if (streq (str, "8") || streq (str, "810"))
ec9991dc
NC
6667 cpu_variant = (cpu_variant & ~ARM_ANY)
6668 | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
252b5132
RH
6669 else
6670 goto bad;
6671 break;
6672
6673 case '9':
6674 if (streq (str, "9"))
ec9991dc
NC
6675 cpu_variant = (cpu_variant & ~ARM_ANY)
6676 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
c1d3c45e 6677 else if (streq (str, "920"))
ec9991dc
NC
6678 cpu_variant = (cpu_variant & ~ARM_ANY)
6679 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL;
c1d3c45e 6680 else if (streq (str, "920t"))
ec9991dc
NC
6681 cpu_variant = (cpu_variant & ~ARM_ANY)
6682 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
252b5132 6683 else if (streq (str, "9tdmi"))
ec9991dc
NC
6684 cpu_variant = (cpu_variant & ~ARM_ANY)
6685 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
252b5132
RH
6686 else
6687 goto bad;
6688 break;
92a66162 6689
252b5132
RH
6690
6691 case 's':
6692 if (streq (str, "strongarm")
6693 || streq (str, "strongarm110")
6694 || streq (str, "strongarm1100"))
ec9991dc
NC
6695 cpu_variant = (cpu_variant & ~ARM_ANY)
6696 | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
252b5132
RH
6697 else
6698 goto bad;
6699 break;
6700
6701 case 'v':
ec9991dc 6702 /* Select variant based on architecture rather than processor. */
252b5132
RH
6703 switch (*++str)
6704 {
6705 case '2':
6706 switch (*++str)
6707 {
ec9991dc
NC
6708 case 'a':
6709 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
6710 break;
6711 case 0:
6712 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
6713 break;
6714 default:
6715 as_bad (_("Invalid architecture variant -m%s"), arg);
6716 break;
252b5132
RH
6717 }
6718 break;
6719
6720 case '3':
6721 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6722
6723 switch (*++str)
6724 {
6725 case 'm': cpu_variant |= ARM_LONGMUL; break;
6726 case 0: break;
ec9991dc
NC
6727 default:
6728 as_bad (_("Invalid architecture variant -m%s"), arg);
6729 break;
252b5132
RH
6730 }
6731 break;
6732
6733 case '4':
49a5575c
NC
6734 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4;
6735
6736 switch (*++str)
6737 {
6738 case 't': cpu_variant |= ARM_THUMB; break;
6739 case 0: break;
ec9991dc
NC
6740 default:
6741 as_bad (_("Invalid architecture variant -m%s"), arg);
6742 break;
49a5575c
NC
6743 }
6744 break;
92a66162 6745
49a5575c
NC
6746 case '5':
6747 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V5;
252b5132
RH
6748 switch (*++str)
6749 {
6750 case 't': cpu_variant |= ARM_THUMB; break;
92a66162 6751 case 'e': cpu_variant |= ARM_EXT_V5E; break;
252b5132 6752 case 0: break;
ec9991dc
NC
6753 default:
6754 as_bad (_("Invalid architecture variant -m%s"), arg);
6755 break;
252b5132
RH
6756 }
6757 break;
6758
6759 default:
6760 as_bad (_("Invalid architecture variant -m%s"), arg);
6761 break;
6762 }
6763 break;
6764
6765 default:
6766 bad:
6767 as_bad (_("Invalid processor variant -m%s"), arg);
6768 return 0;
6769 }
6770 }
6771 break;
6772
325188ec 6773#if defined OBJ_ELF || defined OBJ_COFF
252b5132
RH
6774 case 'k':
6775 pic_code = 1;
6776 break;
325188ec 6777#endif
252b5132
RH
6778
6779 default:
6780 return 0;
6781 }
6782
6783 return 1;
6784}
6785
6786void
6787md_show_usage (fp)
6788 FILE * fp;
6789{
ec9991dc 6790 fprintf (fp, _("\
252b5132
RH
6791 ARM Specific Assembler Options:\n\
6792 -m[arm][<processor name>] select processor variant\n\
858f4ff6 6793 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
252b5132
RH
6794 -mthumb only allow Thumb instructions\n\
6795 -mthumb-interwork mark the assembled code as supporting interworking\n\
6796 -mall allow any instruction\n\
6797 -mfpa10, -mfpa11 select floating point architecture\n\
6798 -mfpe-old don't allow floating-point multiple instructions\n\
ec9991dc 6799 -mno-fpu don't allow any floating-point instructions.\n\
252b5132
RH
6800 -k generate PIC code.\n"));
6801#if defined OBJ_COFF || defined OBJ_ELF
ec9991dc
NC
6802 fprintf (fp, _("\
6803 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
6804 -mapcs-float floating point args are passed in FP regs\n\
252b5132
RH
6805 -mapcs-reentrant the code is position independent/reentrant\n"));
6806 #endif
6807#ifdef OBJ_ELF
ec9991dc 6808 fprintf (fp, _("\
252b5132
RH
6809 -moabi support the old ELF ABI\n"));
6810#endif
6811#ifdef ARM_BI_ENDIAN
ec9991dc 6812 fprintf (fp, _("\
252b5132
RH
6813 -EB assemble code for a big endian cpu\n\
6814 -EL assemble code for a little endian cpu\n"));
6815#endif
6816}
6817
6818/* We need to be able to fix up arbitrary expressions in some statements.
6819 This is so that we can handle symbols that are an arbitrary distance from
6820 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6821 which returns part of an address in a form which will be valid for
6822 a data instruction. We do this by pushing the expression into a symbol
6823 in the expr_section, and creating a fix for that. */
6824
6825static void
6826fix_new_arm (frag, where, size, exp, pc_rel, reloc)
6827 fragS * frag;
6828 int where;
6829 short int size;
6830 expressionS * exp;
6831 int pc_rel;
6832 int reloc;
6833{
6834 fixS * new_fix;
6835 arm_fix_data * arm_data;
6836
6837 switch (exp->X_op)
6838 {
6839 case O_constant:
6840 case O_symbol:
6841 case O_add:
6842 case O_subtract:
6843 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
6844 break;
6845
6846 default:
6847 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
6848 pc_rel, reloc);
6849 break;
6850 }
6851
6852 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6853 arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
6854 new_fix->tc_fix_data = (PTR) arm_data;
6855 arm_data->thumb_mode = thumb_mode;
6856
6857 return;
6858}
6859
6860
2f992c04 6861/* This fix_new is called by cons via TC_CONS_FIX_NEW. */
252b5132
RH
6862void
6863cons_fix_new_arm (frag, where, size, exp)
6864 fragS * frag;
6865 int where;
6866 int size;
6867 expressionS * exp;
6868{
6869 bfd_reloc_code_real_type type;
6870 int pcrel = 0;
6871
6872 /* Pick a reloc ...
6873 *
6874 * @@ Should look at CPU word size.
6875 */
6876 switch (size)
6877 {
6878 case 2:
6879 type = BFD_RELOC_16;
6880 break;
6881 case 4:
6882 default:
6883 type = BFD_RELOC_32;
6884 break;
6885 case 8:
6886 type = BFD_RELOC_64;
6887 break;
6888 }
6889
252b5132
RH
6890 fix_new_exp (frag, where, (int) size, exp, pcrel, type);
6891}
6892
6893/* A good place to do this, although this was probably not intended
ae5ad4ad
NC
6894 for this kind of use. We need to dump the literal pool before
6895 references are made to a null symbol pointer. */
252b5132
RH
6896void
6897arm_cleanup ()
6898{
ae5ad4ad
NC
6899 if (current_poolP == NULL)
6900 return;
6901
6902 subseg_set (text_section, 0); /* Put it at the end of text section. */
6903 s_ltorg (0);
6904 listing_prev_line ();
252b5132
RH
6905}
6906
6907void
6908arm_start_line_hook ()
6909{
6910 last_label_seen = NULL;
6911}
6912
6913void
6914arm_frob_label (sym)
6915 symbolS * sym;
6916{
6917 last_label_seen = sym;
6918
6919 ARM_SET_THUMB (sym, thumb_mode);
6920
6921#if defined OBJ_COFF || defined OBJ_ELF
6922 ARM_SET_INTERWORK (sym, support_interwork);
6923#endif
6924
6925 if (label_is_thumb_function_name)
6926 {
6927 /* When the address of a Thumb function is taken the bottom
6928 bit of that address should be set. This will allow
6929 interworking between Arm and Thumb functions to work
6930 correctly. */
6931
6932 THUMB_SET_FUNC (sym, 1);
6933
6934 label_is_thumb_function_name = false;
6935 }
6936}
6937
6938/* Adjust the symbol table. This marks Thumb symbols as distinct from
6939 ARM ones. */
6940
6941void
6942arm_adjust_symtab ()
6943{
6944#ifdef OBJ_COFF
6945 symbolS * sym;
6946
6947 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6948 {
6949 if (ARM_IS_THUMB (sym))
6950 {
6951 if (THUMB_IS_FUNC (sym))
6952 {
6953 /* Mark the symbol as a Thumb function. */
6954 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
6955 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
6956 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
6957
6958 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
6959 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
6960 else
6961 as_bad (_("%s: unexpected function type: %d"),
6962 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
6963 }
6964 else switch (S_GET_STORAGE_CLASS (sym))
6965 {
6966 case C_EXT:
6967 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
6968 break;
6969 case C_STAT:
6970 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
6971 break;
6972 case C_LABEL:
6973 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
6974 break;
6975 default: /* do nothing */
6976 break;
6977 }
6978 }
6979
6980 if (ARM_IS_INTERWORK (sym))
155f0fe7 6981 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
252b5132
RH
6982 }
6983#endif
6984#ifdef OBJ_ELF
6985 symbolS * sym;
252b5132
RH
6986 char bind;
6987
6988 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6989 {
6990 if (ARM_IS_THUMB (sym))
6991 {
056350c6
NC
6992 elf_symbol_type * elf_sym;
6993
2f0ca46a
NC
6994 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
6995 bind = ELF_ST_BIND (elf_sym);
6996
ec9991dc
NC
6997 /* If it's a .thumb_func, declare it as so,
6998 otherwise tag label as .code 16. */
252b5132 6999 if (THUMB_IS_FUNC (sym))
ec9991dc
NC
7000 elf_sym->internal_elf_sym.st_info =
7001 ELF_ST_INFO (bind, STT_ARM_TFUNC);
2f0ca46a 7002 else
ec9991dc
NC
7003 elf_sym->internal_elf_sym.st_info =
7004 ELF_ST_INFO (bind, STT_ARM_16BIT);
252b5132
RH
7005 }
7006 }
7007#endif
7008}
7009
7010int
7011arm_data_in_code ()
7012{
7013 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
7014 {
7015 *input_line_pointer = '/';
7016 input_line_pointer += 5;
7017 *input_line_pointer = 0;
7018 return 1;
7019 }
7020
7021 return 0;
7022}
7023
7024char *
7025arm_canonicalize_symbol_name (name)
7026 char * name;
7027{
7028 int len;
7029
7030 if (thumb_mode && (len = strlen (name)) > 5
7031 && streq (name + len - 5, "/data"))
ae5ad4ad 7032 *(name + len - 5) = 0;
252b5132
RH
7033
7034 return name;
7035}
7036
7037boolean
7038arm_validate_fix (fixP)
7039 fixS * fixP;
7040{
7041 /* If the destination of the branch is a defined symbol which does not have
7042 the THUMB_FUNC attribute, then we must be calling a function which has
7043 the (interfacearm) attribute. We look for the Thumb entry point to that
7044 function and change the branch to refer to that function instead. */
7045 if ( fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
7046 && fixP->fx_addsy != NULL
7047 && S_IS_DEFINED (fixP->fx_addsy)
7048 && ! THUMB_IS_FUNC (fixP->fx_addsy))
7049 {
7050 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
7051 return true;
7052 }
7053
7054 return false;
7055}
7056
7057#ifdef OBJ_ELF
7058/* Relocations against Thumb function names must be left unadjusted,
7059 so that the linker can use this information to correctly set the
7060 bottom bit of their addresses. The MIPS version of this function
7061 also prevents relocations that are mips-16 specific, but I do not
7062 know why it does this.
7063
7064 FIXME:
7065 There is one other problem that ought to be addressed here, but
7066 which currently is not: Taking the address of a label (rather
7067 than a function) and then later jumping to that address. Such
7068 addresses also ought to have their bottom bit set (assuming that
7069 they reside in Thumb code), but at the moment they will not. */
7070
7071boolean
7072arm_fix_adjustable (fixP)
7073 fixS * fixP;
7074{
252b5132
RH
7075 if (fixP->fx_addsy == NULL)
7076 return 1;
7077
7078 /* Prevent all adjustments to global symbols. */
7079 if (S_IS_EXTERN (fixP->fx_addsy))
7080 return 0;
7081
7082 if (S_IS_WEAK (fixP->fx_addsy))
7083 return 0;
7084
7085 if (THUMB_IS_FUNC (fixP->fx_addsy)
7086 && fixP->fx_subsy == NULL)
7087 return 0;
7088
7089 /* We need the symbol name for the VTABLE entries */
7090 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
7091 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
7092 return 0;
7093
7094 return 1;
7095}
7096
7097const char *
7098elf32_arm_target_format ()
7099{
7100 if (target_big_endian)
7101 if (target_oabi)
7102 return "elf32-bigarm-oabi";
7103 else
7104 return "elf32-bigarm";
7105 else
7106 if (target_oabi)
7107 return "elf32-littlearm-oabi";
7108 else
7109 return "elf32-littlearm";
7110}
7111
7112void
7113armelf_frob_symbol (symp, puntp)
7114 symbolS * symp;
7115 int * puntp;
7116{
7117 elf_frob_symbol (symp, puntp);
7118}
7119
7120int
7121arm_force_relocation (fixp)
7122 struct fix * fixp;
7123{
7124 if ( fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
7125 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
ae5ad4ad 7126 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
d92b1a8a
NC
7127 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
7128 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
ae5ad4ad 7129 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
252b5132
RH
7130 return 1;
7131
7132 return 0;
7133}
7134
7135static bfd_reloc_code_real_type
7136arm_parse_reloc ()
7137{
7138 char id[16];
7139 char * ip;
684b81fa 7140 unsigned int i;
252b5132
RH
7141 static struct
7142 {
7143 char * str;
7144 int len;
7145 bfd_reloc_code_real_type reloc;
7146 }
7147 reloc_map[] =
7148 {
7149#define MAP(str,reloc) { str, sizeof (str)-1, reloc }
7150 MAP ("(got)", BFD_RELOC_ARM_GOT32),
7151 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
7152 /* ScottB: Jan 30, 1998 */
7153 /* Added support for parsing "var(PLT)" branch instructions */
7154 /* generated by GCC for PLT relocs */
7155 MAP ("(plt)", BFD_RELOC_ARM_PLT32),
29c4c6b5 7156 { NULL, 0, BFD_RELOC_UNUSED }
252b5132
RH
7157#undef MAP
7158 };
7159
7160 for (i = 0, ip = input_line_pointer;
7161 i < sizeof (id) && (isalnum (*ip) || ispunct (*ip));
7162 i++, ip++)
7163 id[i] = tolower (*ip);
7164
7165 for (i = 0; reloc_map[i].str; i++)
7166 if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
7167 break;
7168
7169 input_line_pointer += reloc_map[i].len;
7170
7171 return reloc_map[i].reloc;
7172}
7173
7174static void
7175s_arm_elf_cons (nbytes)
7176 int nbytes;
7177{
7178 expressionS exp;
7179
7180#ifdef md_flush_pending_output
7181 md_flush_pending_output ();
7182#endif
7183
7184 if (is_it_end_of_statement ())
7185 {
7186 demand_empty_rest_of_line ();
7187 return;
7188 }
7189
7190#ifdef md_cons_align
7191 md_cons_align (nbytes);
7192#endif
7193
7194 do
7195 {
7196 bfd_reloc_code_real_type reloc;
7197
7198 expression (& exp);
7199
7200 if (exp.X_op == O_symbol
7201 && * input_line_pointer == '('
7202 && (reloc = arm_parse_reloc()) != BFD_RELOC_UNUSED)
7203 {
7204 reloc_howto_type * howto = bfd_reloc_type_lookup (stdoutput, reloc);
7205 int size = bfd_get_reloc_size (howto);
7206
7207 if (size > nbytes)
ec9991dc
NC
7208 as_bad ("%s relocations do not fit in %d bytes",
7209 howto->name, nbytes);
252b5132
RH
7210 else
7211 {
7212 register char * p = frag_more ((int) nbytes);
7213 int offset = nbytes - size;
7214
7215 fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
7216 & exp, 0, reloc);
7217 }
7218 }
7219 else
7220 emit_expr (& exp, (unsigned int) nbytes);
7221 }
7222 while (*input_line_pointer++ == ',');
7223
ec9991dc 7224 input_line_pointer--; /* Put terminator back into stream. */
252b5132
RH
7225 demand_empty_rest_of_line ();
7226}
7227
7228#endif /* OBJ_ELF */
This page took 0.380281 seconds and 4 git commands to generate.