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