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