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