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