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