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