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