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