tweak last patch
[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 (!strcmp (*str, "rrx")
2105 || !strcmp (*str, "RRX"))
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 static void
4394 do_t_branch23 (str)
4395 char *str;
4396 {
4397 if (my_get_expression (&inst.reloc.exp, &str))
4398 return;
4399 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
4400 inst.reloc.pc_rel = 1;
4401 end_of_line (str);
4402 }
4403
4404 static void
4405 do_t_bx (str)
4406 char *str;
4407 {
4408 int reg;
4409
4410 while (*str == ' ')
4411 str++;
4412
4413 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4414 return;
4415
4416 /* This sets THUMB_H2 from the top bit of reg. */
4417 inst.instruction |= reg << 3;
4418
4419 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4420 should cause the alignment to be checked once it is known. This is
4421 because BX PC only works if the instruction is word aligned. */
4422
4423 end_of_line (str);
4424 }
4425
4426 static void
4427 do_t_compare (str)
4428 char *str;
4429 {
4430 thumb_mov_compare (str, THUMB_COMPARE);
4431 }
4432
4433 static void
4434 do_t_ldmstm (str)
4435 char *str;
4436 {
4437 int Rb;
4438 long range;
4439
4440 while (*str == ' ')
4441 str++;
4442
4443 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4444 return;
4445
4446 if (*str != '!')
4447 as_warn ("Inserted missing '!': load/store multiple always writes back base register");
4448 else
4449 str++;
4450
4451 if (skip_past_comma (&str) == FAIL
4452 || (range = reg_list (&str)) == FAIL)
4453 {
4454 if (! inst.error)
4455 inst.error = bad_args;
4456 return;
4457 }
4458
4459 if (inst.reloc.type != BFD_RELOC_NONE)
4460 {
4461 /* This really doesn't seem worth it. */
4462 inst.reloc.type = BFD_RELOC_NONE;
4463 inst.error = "Expression too complex";
4464 return;
4465 }
4466
4467 if (range & ~0xff)
4468 {
4469 inst.error = "only lo-regs valid in load/store multiple";
4470 return;
4471 }
4472
4473 inst.instruction |= (Rb << 8) | range;
4474 end_of_line (str);
4475 }
4476
4477 static void
4478 do_t_ldr (str)
4479 char *str;
4480 {
4481 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
4482 }
4483
4484 static void
4485 do_t_ldrb (str)
4486 char *str;
4487 {
4488 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
4489 }
4490
4491 static void
4492 do_t_ldrh (str)
4493 char *str;
4494 {
4495 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
4496 }
4497
4498 static void
4499 do_t_lds (str)
4500 char *str;
4501 {
4502 int Rd, Rb, Ro;
4503
4504 while (*str == ' ')
4505 str++;
4506
4507 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4508 || skip_past_comma (&str) == FAIL
4509 || *str++ != '['
4510 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4511 || skip_past_comma (&str) == FAIL
4512 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4513 || *str++ != ']')
4514 {
4515 if (! inst.error)
4516 inst.error = "Syntax: ldrs[b] Rd, [Rb, Ro]";
4517 return;
4518 }
4519
4520 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4521 end_of_line (str);
4522 }
4523
4524 static void
4525 do_t_lsl (str)
4526 char *str;
4527 {
4528 thumb_shift (str, THUMB_LSL);
4529 }
4530
4531 static void
4532 do_t_lsr (str)
4533 char *str;
4534 {
4535 thumb_shift (str, THUMB_LSR);
4536 }
4537
4538 static void
4539 do_t_mov (str)
4540 char *str;
4541 {
4542 thumb_mov_compare (str, THUMB_MOVE);
4543 }
4544
4545 static void
4546 do_t_push_pop (str)
4547 char *str;
4548 {
4549 long range;
4550
4551 while (*str == ' ')
4552 str++;
4553
4554 if ((range = reg_list (&str)) == FAIL)
4555 {
4556 if (! inst.error)
4557 inst.error = bad_args;
4558 return;
4559 }
4560
4561 if (inst.reloc.type != BFD_RELOC_NONE)
4562 {
4563 /* This really doesn't seem worth it. */
4564 inst.reloc.type = BFD_RELOC_NONE;
4565 inst.error = "Expression too complex";
4566 return;
4567 }
4568
4569 if (range & ~0xff)
4570 {
4571 if ((inst.instruction == T_OPCODE_PUSH
4572 && (range & ~0xff) == 1 << REG_LR)
4573 || (inst.instruction == T_OPCODE_POP
4574 && (range & ~0xff) == 1 << REG_PC))
4575 {
4576 inst.instruction |= THUMB_PP_PC_LR;
4577 range &= 0xff;
4578 }
4579 else
4580 {
4581 inst.error = "invalid register list to push/pop instruction";
4582 return;
4583 }
4584 }
4585
4586 inst.instruction |= range;
4587 end_of_line (str);
4588 }
4589
4590 static void
4591 do_t_str (str)
4592 char *str;
4593 {
4594 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
4595 }
4596
4597 static void
4598 do_t_strb (str)
4599 char *str;
4600 {
4601 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
4602 }
4603
4604 static void
4605 do_t_strh (str)
4606 char *str;
4607 {
4608 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
4609 }
4610
4611 static void
4612 do_t_sub (str)
4613 char *str;
4614 {
4615 thumb_add_sub (str, 1);
4616 }
4617
4618 static void
4619 do_t_swi (str)
4620 char *str;
4621 {
4622 while (*str == ' ')
4623 str++;
4624
4625 if (my_get_expression (&inst.reloc.exp, &str))
4626 return;
4627
4628 inst.reloc.type = BFD_RELOC_ARM_SWI;
4629 end_of_line (str);
4630 return;
4631 }
4632
4633 static void
4634 do_t_adr (str)
4635 char *str;
4636 {
4637 /* This is a pseudo-op of the form "adr rd, label" to be converted
4638 into a relative address of the form "add rd, pc, #label-.-4" */
4639 while (*str == ' ')
4640 str++;
4641
4642 if (reg_required_here (&str, 4) == FAIL /* Store Rd in temporary location inside instruction. */
4643 || skip_past_comma (&str) == FAIL
4644 || my_get_expression (&inst.reloc.exp, &str))
4645 {
4646 if (!inst.error)
4647 inst.error = bad_args;
4648 return;
4649 }
4650
4651 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
4652 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust */
4653 inst.reloc.pc_rel = 1;
4654 inst.instruction |= REG_PC; /* Rd is already placed into the instruction */
4655 end_of_line (str);
4656 }
4657
4658 static void
4659 insert_reg (entry)
4660 int entry;
4661 {
4662 int len = strlen (reg_table[entry].name) + 2;
4663 char *buf = (char *) xmalloc (len);
4664 char *buf2 = (char *) xmalloc (len);
4665 int i = 0;
4666
4667 #ifdef REGISTER_PREFIX
4668 buf[i++] = REGISTER_PREFIX;
4669 #endif
4670
4671 strcpy (buf + i, reg_table[entry].name);
4672
4673 for (i = 0; buf[i]; i++)
4674 buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i];
4675
4676 buf2[i] = '\0';
4677
4678 hash_insert (arm_reg_hsh, buf, (PTR) &reg_table[entry]);
4679 hash_insert (arm_reg_hsh, buf2, (PTR) &reg_table[entry]);
4680 }
4681
4682 static void
4683 insert_reg_alias (str, regnum)
4684 char *str;
4685 int regnum;
4686 {
4687 struct reg_entry *new =
4688 (struct reg_entry *)xmalloc (sizeof (struct reg_entry));
4689 char *name = xmalloc (strlen (str) + 1);
4690 strcpy (name, str);
4691
4692 new->name = name;
4693 new->number = regnum;
4694
4695 hash_insert (arm_reg_hsh, name, (PTR) new);
4696 }
4697
4698 static void
4699 set_constant_flonums ()
4700 {
4701 int i;
4702
4703 for (i = 0; i < NUM_FLOAT_VALS; i++)
4704 if (atof_ieee ((char *)fp_const[i], 'x', fp_values[i]) == NULL)
4705 abort ();
4706 }
4707
4708 void
4709 md_begin ()
4710 {
4711 int i;
4712
4713 if ((arm_ops_hsh = hash_new ()) == NULL
4714 || (arm_tops_hsh = hash_new ()) == NULL
4715 || (arm_cond_hsh = hash_new ()) == NULL
4716 || (arm_shift_hsh = hash_new ()) == NULL
4717 || (arm_reg_hsh = hash_new ()) == NULL
4718 || (arm_psr_hsh = hash_new ()) == NULL)
4719 as_fatal ("Virtual memory exhausted");
4720
4721 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
4722 hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i));
4723 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
4724 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
4725 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
4726 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
4727 for (i = 0; i < sizeof (shift) / sizeof (struct asm_shift); i++)
4728 hash_insert (arm_shift_hsh, shift[i].template, (PTR) (shift + i));
4729 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
4730 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
4731
4732 for (i = 0; reg_table[i].name; i++)
4733 insert_reg (i);
4734
4735 set_constant_flonums ();
4736
4737 #ifdef OBJ_COFF
4738 {
4739 unsigned int flags = 0;
4740
4741 /* Set the flags in the private structure */
4742 if (uses_apcs_26) flags |= F_APCS26;
4743 if (support_interwork) flags |= F_INTERWORK;
4744 if (uses_apcs_float) flags |= F_APCS_FLOAT;
4745 if (pic_code) flags |= F_PIC;
4746
4747 bfd_set_private_flags (stdoutput, flags);
4748 }
4749 #endif
4750
4751 {
4752 unsigned mach;
4753
4754 /* Record the CPU type as well */
4755 switch (cpu_variant & ARM_CPU_MASK)
4756 {
4757 case ARM_2:
4758 mach = bfd_mach_arm_2;
4759 break;
4760
4761 case ARM_3: /* also ARM_250 */
4762 mach = bfd_mach_arm_2a;
4763 break;
4764
4765 default:
4766 case ARM_6 | ARM_3 | ARM_2: /* Actually no CPU type defined */
4767 mach = bfd_mach_arm_4;
4768 break;
4769
4770 case ARM_7: /* also ARM_6 */
4771 mach = bfd_mach_arm_3;
4772 break;
4773 }
4774
4775 /* Catch special cases */
4776 if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
4777 {
4778 if (cpu_variant & ARM_THUMB)
4779 mach = bfd_mach_arm_4T;
4780 else if ((cpu_variant & ARM_ARCHv4) == ARM_ARCHv4)
4781 mach = bfd_mach_arm_4;
4782 else if (cpu_variant & ARM_LONGMUL)
4783 mach = bfd_mach_arm_3M;
4784 }
4785
4786 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
4787 }
4788 }
4789
4790 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4791 for use in the a.out file, and stores them in the array pointed to by buf.
4792 This knows about the endian-ness of the target machine and does
4793 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4794 2 (short) and 4 (long) Floating numbers are put out as a series of
4795 LITTLENUMS (shorts, here at least)
4796 */
4797 void
4798 md_number_to_chars (buf, val, n)
4799 char *buf;
4800 valueT val;
4801 int n;
4802 {
4803 if (target_big_endian)
4804 number_to_chars_bigendian (buf, val, n);
4805 else
4806 number_to_chars_littleendian (buf, val, n);
4807 }
4808
4809 static valueT
4810 md_chars_to_number (buf, n)
4811 char *buf;
4812 int n;
4813 {
4814 valueT result = 0;
4815 unsigned char *where = (unsigned char *) buf;
4816
4817 if (target_big_endian)
4818 {
4819 while (n--)
4820 {
4821 result <<= 8;
4822 result |= (*where++ & 255);
4823 }
4824 }
4825 else
4826 {
4827 while (n--)
4828 {
4829 result <<= 8;
4830 result |= (where[n] & 255);
4831 }
4832 }
4833
4834 return result;
4835 }
4836
4837 /* Turn a string in input_line_pointer into a floating point constant
4838 of type TYPE, and store the appropriate bytes in *litP. The number
4839 of LITTLENUMS emitted is stored in *sizeP . An error message is
4840 returned, or NULL on OK.
4841
4842 Note that fp constants aren't represent in the normal way on the ARM.
4843 In big endian mode, things are as expected. However, in little endian
4844 mode fp constants are big-endian word-wise, and little-endian byte-wise
4845 within the words. For example, (double) 1.1 in big endian mode is
4846 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4847 the byte sequence 99 99 f1 3f 9a 99 99 99.
4848
4849 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
4850
4851 char *
4852 md_atof (type, litP, sizeP)
4853 char type;
4854 char *litP;
4855 int *sizeP;
4856 {
4857 int prec;
4858 LITTLENUM_TYPE words[MAX_LITTLENUMS];
4859 char *t;
4860 int i;
4861
4862 switch (type)
4863 {
4864 case 'f':
4865 case 'F':
4866 case 's':
4867 case 'S':
4868 prec = 2;
4869 break;
4870
4871 case 'd':
4872 case 'D':
4873 case 'r':
4874 case 'R':
4875 prec = 4;
4876 break;
4877
4878 case 'x':
4879 case 'X':
4880 prec = 6;
4881 break;
4882
4883 case 'p':
4884 case 'P':
4885 prec = 6;
4886 break;
4887
4888 default:
4889 *sizeP = 0;
4890 return "Bad call to MD_ATOF()";
4891 }
4892
4893 t = atof_ieee (input_line_pointer, type, words);
4894 if (t)
4895 input_line_pointer = t;
4896 *sizeP = prec * 2;
4897
4898 if (target_big_endian)
4899 {
4900 for (i = 0; i < prec; i++)
4901 {
4902 md_number_to_chars (litP, (valueT) words[i], 2);
4903 litP += 2;
4904 }
4905 }
4906 else
4907 {
4908 /* For a 4 byte float the order of elements in `words' is 1 0. For an
4909 8 byte float the order is 1 0 3 2. */
4910 for (i = 0; i < prec; i += 2)
4911 {
4912 md_number_to_chars (litP, (valueT) words[i + 1], 2);
4913 md_number_to_chars (litP + 2, (valueT) words[i], 2);
4914 litP += 4;
4915 }
4916 }
4917
4918 return 0;
4919 }
4920
4921 /* We have already put the pipeline compensation in the instruction */
4922
4923 long
4924 md_pcrel_from (fixP)
4925 fixS *fixP;
4926 {
4927 if (fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
4928 && fixP->fx_subsy == NULL)
4929 return 0; /* HACK */
4930
4931 if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
4932 {
4933 /* PC relative addressing on the Thumb is slightly odd
4934 as the bottom two bits of the PC are forced to zero
4935 for the calculation */
4936 return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
4937 }
4938
4939 return fixP->fx_where + fixP->fx_frag->fr_address;
4940 }
4941
4942 /* Round up a section size to the appropriate boundary. */
4943 valueT
4944 md_section_align (segment, size)
4945 segT segment;
4946 valueT size;
4947 {
4948 /* Round all sects to multiple of 4 */
4949 return (size + 3) & ~3;
4950 }
4951
4952 /* We have no need to default values of symbols. */
4953
4954 /* ARGSUSED */
4955 symbolS *
4956 md_undefined_symbol (name)
4957 char *name;
4958 {
4959 return 0;
4960 }
4961
4962 /* arm_reg_parse () := if it looks like a register, return its token and
4963 advance the pointer. */
4964
4965 static int
4966 arm_reg_parse (ccp)
4967 register char **ccp;
4968 {
4969 char *start = *ccp;
4970 char c;
4971 char *p;
4972 struct reg_entry *reg;
4973
4974 #ifdef REGISTER_PREFIX
4975 if (*start != REGISTER_PREFIX)
4976 return FAIL;
4977 p = start + 1;
4978 #else
4979 p = start;
4980 #ifdef OPTIONAL_REGISTER_PREFIX
4981 if (*p == OPTIONAL_REGISTER_PREFIX)
4982 p++, start++;
4983 #endif
4984 #endif
4985 if (!isalpha (*p) || !is_name_beginner (*p))
4986 return FAIL;
4987
4988 c = *p++;
4989 while (isalpha (c) || isdigit (c) || c == '_')
4990 c = *p++;
4991
4992 *--p = 0;
4993 reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
4994 *p = c;
4995
4996 if (reg)
4997 {
4998 *ccp = p;
4999 return reg->number;
5000 }
5001
5002 return FAIL;
5003 }
5004
5005 static int
5006 arm_psr_parse (ccp)
5007 register char **ccp;
5008 {
5009 char *start = *ccp;
5010 char c, *p;
5011 CONST struct asm_psr *psr;
5012
5013 p = start;
5014 c = *p++;
5015 while (isalpha (c) || c == '_')
5016 c = *p++;
5017
5018 *--p = 0;
5019 psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
5020 *p = c;
5021
5022 if (psr)
5023 {
5024 *ccp = p;
5025 return psr->number;
5026 }
5027
5028 return FAIL;
5029 }
5030
5031 int
5032 md_apply_fix3 (fixP, val, seg)
5033 fixS *fixP;
5034 valueT *val;
5035 segT seg;
5036 {
5037 offsetT value = *val;
5038 offsetT newval;
5039 unsigned int newimm;
5040 unsigned long temp;
5041 int sign;
5042 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
5043 arm_fix_data *arm_data = (arm_fix_data *) fixP->tc_fix_data;
5044
5045 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
5046
5047 /* Note whether this will delete the relocation. */
5048 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5049 if ((fixP->fx_addsy == 0 || fixP->fx_addsy->sy_value.X_op == O_constant)
5050 && !fixP->fx_pcrel)
5051 #else
5052 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
5053 #endif
5054 fixP->fx_done = 1;
5055
5056 /* If this symbol is in a different section then we need to leave it for
5057 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5058 so we have to undo it's effects here. */
5059 if (fixP->fx_pcrel)
5060 {
5061 if (S_IS_DEFINED (fixP->fx_addsy)
5062 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
5063 {
5064 if (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH)
5065 value = 0;
5066 else
5067 value += md_pcrel_from (fixP);
5068 }
5069 }
5070
5071 fixP->fx_addnumber = value; /* Remember value for emit_reloc */
5072
5073 switch (fixP->fx_r_type)
5074 {
5075 case BFD_RELOC_ARM_IMMEDIATE:
5076 newimm = (offsetT) validate_immediate (value);
5077 temp = md_chars_to_number (buf, INSN_SIZE);
5078
5079 /* If the instruction will fail, see if we can fix things up by
5080 changing the opcode. */
5081 if (newimm == (unsigned int) FAIL
5082 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
5083 {
5084 as_bad_where (fixP->fx_file, fixP->fx_line,
5085 "invalid constant after fixup\n");
5086 break;
5087 }
5088
5089 newimm |= (temp & 0xfffff000);
5090 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5091 break;
5092
5093 case BFD_RELOC_ARM_OFFSET_IMM:
5094 sign = value >= 0;
5095 if ((value = validate_offset_imm (value, 0)) == FAIL)
5096 {
5097 as_bad ("bad immediate value for offset (%d)", val);
5098 break;
5099 }
5100 if (value < 0)
5101 value = -value;
5102
5103 newval = md_chars_to_number (buf, INSN_SIZE);
5104 newval &= 0xff7ff000;
5105 newval |= value | (sign ? INDEX_UP : 0);
5106 md_number_to_chars (buf, newval, INSN_SIZE);
5107 break;
5108
5109 case BFD_RELOC_ARM_OFFSET_IMM8:
5110 case BFD_RELOC_ARM_HWLITERAL:
5111 sign = value >= 0;
5112 if ((value = validate_offset_imm (value, 1)) == FAIL)
5113 {
5114 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
5115 as_bad_where (fixP->fx_file, fixP->fx_line,
5116 "invalid literal constant: pool needs to be closer\n");
5117 else
5118 as_bad ("bad immediate value for offset (%d)", value);
5119 break;
5120 }
5121
5122 if (value < 0)
5123 value = -value;
5124
5125 newval = md_chars_to_number (buf, INSN_SIZE);
5126 newval &= 0xff7ff0f0;
5127 newval |= ((value >> 4) << 8) | value & 0xf | (sign ? INDEX_UP : 0);
5128 md_number_to_chars (buf, newval, INSN_SIZE);
5129 break;
5130
5131 case BFD_RELOC_ARM_LITERAL:
5132 sign = value >= 0;
5133 if (value < 0)
5134 value = -value;
5135
5136 if ((value = validate_offset_imm (value, 0)) == FAIL)
5137 {
5138 as_bad_where (fixP->fx_file, fixP->fx_line,
5139 "invalid literal constant: pool needs to be closer\n");
5140 break;
5141 }
5142
5143 newval = md_chars_to_number (buf, INSN_SIZE);
5144 newval &= 0xff7ff000;
5145 newval |= value | (sign ? INDEX_UP : 0);
5146 md_number_to_chars (buf, newval, INSN_SIZE);
5147 break;
5148
5149 case BFD_RELOC_ARM_SHIFT_IMM:
5150 newval = md_chars_to_number (buf, INSN_SIZE);
5151 if (((unsigned long) value) > 32
5152 || (value == 32
5153 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
5154 {
5155 as_bad_where (fixP->fx_file, fixP->fx_line,
5156 "shift expression is too large");
5157 break;
5158 }
5159
5160 if (value == 0)
5161 newval &= ~0x60; /* Shifts of zero must be done as lsl */
5162 else if (value == 32)
5163 value = 0;
5164 newval &= 0xfffff07f;
5165 newval |= (value & 0x1f) << 7;
5166 md_number_to_chars (buf, newval , INSN_SIZE);
5167 break;
5168
5169 case BFD_RELOC_ARM_SWI:
5170 if (arm_data->thumb_mode)
5171 {
5172 if (((unsigned long) value) > 0xff)
5173 as_bad_where (fixP->fx_file, fixP->fx_line,
5174 "Invalid swi expression");
5175 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
5176 newval |= value;
5177 md_number_to_chars (buf, newval, THUMB_SIZE);
5178 }
5179 else
5180 {
5181 if (((unsigned long) value) > 0x00ffffff)
5182 as_bad_where (fixP->fx_file, fixP->fx_line,
5183 "Invalid swi expression");
5184 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
5185 newval |= value;
5186 md_number_to_chars (buf, newval , INSN_SIZE);
5187 }
5188 break;
5189
5190 case BFD_RELOC_ARM_MULTI:
5191 if (((unsigned long) value) > 0xffff)
5192 as_bad_where (fixP->fx_file, fixP->fx_line,
5193 "Invalid expression in load/store multiple");
5194 newval = value | md_chars_to_number (buf, INSN_SIZE);
5195 md_number_to_chars (buf, newval, INSN_SIZE);
5196 break;
5197
5198 case BFD_RELOC_ARM_PCREL_BRANCH:
5199 value = (value >> 2) & 0x00ffffff;
5200 newval = md_chars_to_number (buf, INSN_SIZE);
5201 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
5202 newval = value | (newval & 0xff000000);
5203 md_number_to_chars (buf, newval, INSN_SIZE);
5204 break;
5205
5206 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* conditional branch */
5207 newval = md_chars_to_number (buf, THUMB_SIZE);
5208 {
5209 addressT diff = (newval & 0xff) << 1;
5210 if (diff & 0x100)
5211 diff |= ~0xff;
5212
5213 value += diff;
5214 if ((value & 0x100) && ((value & ~0xff) != ~0xff))
5215 as_bad_where (fixP->fx_file, fixP->fx_line,
5216 "Branch out of range");
5217 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
5218 }
5219 md_number_to_chars (buf, newval, THUMB_SIZE);
5220 break;
5221
5222 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* unconditional branch */
5223 newval = md_chars_to_number (buf, THUMB_SIZE);
5224 {
5225 addressT diff = (newval & 0x7ff) << 1;
5226 if (diff & 0x800)
5227 diff |= ~0x7ff;
5228
5229 value += diff;
5230 if ((value & 0x800) && ((value & ~0x7ff) != ~0x7ff))
5231 as_bad_where (fixP->fx_file, fixP->fx_line,
5232 "Branch out of range");
5233 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
5234 }
5235 md_number_to_chars (buf, newval, THUMB_SIZE);
5236 break;
5237
5238 case BFD_RELOC_THUMB_PCREL_BRANCH23:
5239 newval = md_chars_to_number (buf, THUMB_SIZE);
5240 {
5241 offsetT newval2;
5242 addressT diff;
5243
5244 newval2 = md_chars_to_number (buf + 2, THUMB_SIZE);
5245 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
5246 if (diff & 0x400000)
5247 diff |= ~0x3fffff;
5248 value += diff;
5249 if ((value & 0x400000) && ((value & ~0x3fffff) != ~0x3fffff))
5250 as_bad_where (fixP->fx_file, fixP->fx_line,
5251 "Branch with link out of range");
5252
5253 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
5254 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
5255 md_number_to_chars (buf, newval, THUMB_SIZE);
5256 md_number_to_chars (buf + 2, newval2, THUMB_SIZE);
5257 }
5258 break;
5259
5260 case BFD_RELOC_8:
5261 if (fixP->fx_done || fixP->fx_pcrel)
5262 md_number_to_chars (buf, value, 1);
5263 break;
5264
5265 case BFD_RELOC_16:
5266 if (fixP->fx_done || fixP->fx_pcrel)
5267 md_number_to_chars (buf, value, 2);
5268 break;
5269
5270 case BFD_RELOC_RVA:
5271 case BFD_RELOC_32:
5272 if (fixP->fx_done || fixP->fx_pcrel)
5273 md_number_to_chars (buf, value, 4);
5274 break;
5275
5276 case BFD_RELOC_ARM_CP_OFF_IMM:
5277 sign = value >= 0;
5278 if (value < -1023 || value > 1023 || (value & 3))
5279 as_bad_where (fixP->fx_file, fixP->fx_line,
5280 "Illegal value for co-processor offset");
5281 if (value < 0)
5282 value = -value;
5283 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
5284 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
5285 md_number_to_chars (buf, newval , INSN_SIZE);
5286 break;
5287
5288 case BFD_RELOC_ARM_THUMB_OFFSET:
5289 newval = md_chars_to_number (buf, THUMB_SIZE);
5290 /* Exactly what ranges, and where the offset is inserted depends on
5291 the type of instruction, we can establish this from the top 4 bits */
5292 switch (newval >> 12)
5293 {
5294 case 4: /* PC load */
5295 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5296 forced to zero for these loads, so we will need to round
5297 up the offset if the instruction address is not word
5298 aligned (since the final address produced must be, and
5299 we can only describe word-aligned immediate offsets). */
5300
5301 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
5302 as_bad_where (fixP->fx_file, fixP->fx_line,
5303 "Invalid offset, target not word aligned (0x%08X)",
5304 (unsigned int)(fixP->fx_frag->fr_address + fixP->fx_where + value));
5305
5306 if ((value + 2) & ~0x3fe)
5307 as_bad_where (fixP->fx_file, fixP->fx_line,
5308 "Invalid offset");
5309
5310 /* Round up, since pc will be rounded down. */
5311 newval |= (value + 2) >> 2;
5312 break;
5313
5314 case 9: /* SP load/store */
5315 if (value & ~0x3fc)
5316 as_bad_where (fixP->fx_file, fixP->fx_line,
5317 "Invalid offset");
5318 newval |= value >> 2;
5319 break;
5320
5321 case 6: /* Word load/store */
5322 if (value & ~0x7c)
5323 as_bad_where (fixP->fx_file, fixP->fx_line,
5324 "Invalid offset");
5325 newval |= value << 4; /* 6 - 2 */
5326 break;
5327
5328 case 7: /* Byte load/store */
5329 if (value & ~0x1f)
5330 as_bad_where (fixP->fx_file, fixP->fx_line,
5331 "Invalid offset");
5332 newval |= value << 6;
5333 break;
5334
5335 case 8: /* Halfword load/store */
5336 if (value & ~0x3e)
5337 as_bad_where (fixP->fx_file, fixP->fx_line,
5338 "Invalid offset");
5339 newval |= value << 5; /* 6 - 1 */
5340 break;
5341
5342 default:
5343 as_bad_where (fixP->fx_file, fixP->fx_line,
5344 "Unable to process relocation for thumb opcode: %x", newval);
5345 break;
5346 }
5347 md_number_to_chars (buf, newval, THUMB_SIZE);
5348 break;
5349
5350 case BFD_RELOC_ARM_THUMB_ADD:
5351 /* This is a complicated relocation, since we use it for all of
5352 the following immediate relocations:
5353 3bit ADD/SUB
5354 8bit ADD/SUB
5355 9bit ADD/SUB SP word-aligned
5356 10bit ADD PC/SP word-aligned
5357
5358 The type of instruction being processed is encoded in the
5359 instruction field:
5360 0x8000 SUB
5361 0x00F0 Rd
5362 0x000F Rs
5363 */
5364 newval = md_chars_to_number (buf, THUMB_SIZE);
5365 {
5366 int rd = (newval >> 4) & 0xf;
5367 int rs = newval & 0xf;
5368 int subtract = newval & 0x8000;
5369
5370 if (rd == REG_SP)
5371 {
5372 if (value & ~0x1fc)
5373 as_bad_where (fixP->fx_file, fixP->fx_line,
5374 "Invalid immediate for stack address calculation");
5375 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
5376 newval |= value >> 2;
5377 }
5378 else if (rs == REG_PC || rs == REG_SP)
5379 {
5380 if (subtract ||
5381 value & ~0x3fc)
5382 as_bad_where (fixP->fx_file, fixP->fx_line,
5383 "Invalid immediate for address calculation (value = 0x%08X)", value);
5384 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
5385 newval |= rd << 8;
5386 newval |= value >> 2;
5387 }
5388 else if (rs == rd)
5389 {
5390 if (value & ~0xff)
5391 as_bad_where (fixP->fx_file, fixP->fx_line,
5392 "Invalid 8bit immediate");
5393 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
5394 newval |= (rd << 8) | value;
5395 }
5396 else
5397 {
5398 if (value & ~0x7)
5399 as_bad_where (fixP->fx_file, fixP->fx_line,
5400 "Invalid 3bit immediate");
5401 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
5402 newval |= rd | (rs << 3) | (value << 6);
5403 }
5404 }
5405 md_number_to_chars (buf, newval , THUMB_SIZE);
5406 break;
5407
5408 case BFD_RELOC_ARM_THUMB_IMM:
5409 newval = md_chars_to_number (buf, THUMB_SIZE);
5410 switch (newval >> 11)
5411 {
5412 case 0x04: /* 8bit immediate MOV */
5413 case 0x05: /* 8bit immediate CMP */
5414 if (value < 0 || value > 255)
5415 as_bad_where (fixP->fx_file, fixP->fx_line,
5416 "Invalid immediate: %d is too large", value);
5417 newval |= value;
5418 break;
5419
5420 default:
5421 abort ();
5422 }
5423 md_number_to_chars (buf, newval , THUMB_SIZE);
5424 break;
5425
5426 case BFD_RELOC_ARM_THUMB_SHIFT:
5427 /* 5bit shift value (0..31) */
5428 if (value < 0 || value > 31)
5429 as_bad_where (fixP->fx_file, fixP->fx_line,
5430 "Illegal Thumb shift value: %d", value);
5431 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
5432 newval |= value << 6;
5433 md_number_to_chars (buf, newval , THUMB_SIZE);
5434 break;
5435
5436 case BFD_RELOC_NONE:
5437 default:
5438 as_bad_where (fixP->fx_file, fixP->fx_line,
5439 "Bad relocation fixup type (%d)\n", fixP->fx_r_type);
5440 }
5441
5442 return 1;
5443 }
5444
5445 /* Translate internal representation of relocation info to BFD target
5446 format. */
5447 arelent *
5448 tc_gen_reloc (section, fixp)
5449 asection *section;
5450 fixS *fixp;
5451 {
5452 arelent *reloc;
5453 bfd_reloc_code_real_type code;
5454
5455 reloc = (arelent *) xmalloc (sizeof (arelent));
5456
5457 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
5458 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5459
5460 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5461 if (fixp->fx_pcrel == 0)
5462 reloc->addend = fixp->fx_offset;
5463 else
5464 reloc->addend = fixp->fx_offset = reloc->address;
5465
5466 switch (fixp->fx_r_type)
5467 {
5468 case BFD_RELOC_8:
5469 if (fixp->fx_pcrel)
5470 {
5471 code = BFD_RELOC_8_PCREL;
5472 break;
5473 }
5474
5475 case BFD_RELOC_16:
5476 if (fixp->fx_pcrel)
5477 {
5478 code = BFD_RELOC_16_PCREL;
5479 break;
5480 }
5481
5482 case BFD_RELOC_32:
5483 if (fixp->fx_pcrel)
5484 {
5485 code = BFD_RELOC_32_PCREL;
5486 break;
5487 }
5488
5489 case BFD_RELOC_ARM_PCREL_BRANCH:
5490 case BFD_RELOC_RVA:
5491 case BFD_RELOC_THUMB_PCREL_BRANCH9:
5492 case BFD_RELOC_THUMB_PCREL_BRANCH12:
5493 case BFD_RELOC_THUMB_PCREL_BRANCH23:
5494 code = fixp->fx_r_type;
5495 break;
5496
5497 case BFD_RELOC_ARM_LITERAL:
5498 case BFD_RELOC_ARM_HWLITERAL:
5499 /* If this is called then the a literal has been referenced across
5500 a section boundry - possibly due to an implicit dump */
5501 as_bad_where (fixp->fx_file, fixp->fx_line,
5502 "Literal referenced across section boundry (Implicit dump?)");
5503 return NULL;
5504
5505 default:
5506 {
5507 char * type;
5508 switch (fixp->fx_r_type)
5509 {
5510 case BFD_RELOC_ARM_IMMEDIATE: type = "IMMEDIATE"; break;
5511 case BFD_RELOC_ARM_OFFSET_IMM: type = "OFFSET_IMM"; break;
5512 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
5513 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
5514 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
5515 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
5516 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
5517 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
5518 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
5519 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
5520 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
5521 default: type = "<unknown>"; break;
5522 }
5523 as_bad_where (fixp->fx_file, fixp->fx_line,
5524 "Can not represent %s relocation in this object file format (%d)",
5525 type, fixp->fx_pcrel);
5526 return NULL;
5527 }
5528 }
5529
5530 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
5531
5532 if (reloc->howto == NULL)
5533 {
5534 as_bad_where (fixp->fx_file, fixp->fx_line,
5535 "Can not represent %s relocation in this object file format",
5536 bfd_get_reloc_code_name (code));
5537 return NULL;
5538 }
5539
5540 return reloc;
5541 }
5542
5543 CONST int md_short_jump_size = 4;
5544 CONST int md_long_jump_size = 4;
5545
5546 /* These should never be called on the arm */
5547 void
5548 md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
5549 char *ptr;
5550 addressT from_addr, to_addr;
5551 fragS *frag;
5552 symbolS *to_symbol;
5553 {
5554 as_fatal ("md_create_long_jump\n");
5555 }
5556
5557 void
5558 md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
5559 char *ptr;
5560 addressT from_addr, to_addr;
5561 fragS *frag;
5562 symbolS *to_symbol;
5563 {
5564 as_fatal ("md_create_short_jump\n");
5565 }
5566
5567 int
5568 md_estimate_size_before_relax (fragP, segtype)
5569 fragS *fragP;
5570 segT segtype;
5571 {
5572 as_fatal ("md_estimate_size_before_relax\n");
5573 return (1);
5574 }
5575
5576 static void
5577 output_inst (str)
5578 char *str;
5579 {
5580 char *to = NULL;
5581
5582 if (inst.error)
5583 {
5584 as_bad (inst.error);
5585 return;
5586 }
5587
5588 to = frag_more (inst.size);
5589 if (thumb_mode && (inst.size > THUMB_SIZE))
5590 {
5591 assert (inst.size == (2 * THUMB_SIZE));
5592 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
5593 md_number_to_chars (to + 2, inst.instruction, THUMB_SIZE);
5594 }
5595 else
5596 md_number_to_chars (to, inst.instruction, inst.size);
5597
5598 if (inst.reloc.type != BFD_RELOC_NONE)
5599 fix_new_arm (frag_now, to - frag_now->fr_literal,
5600 inst.size, &inst.reloc.exp, inst.reloc.pc_rel,
5601 inst.reloc.type);
5602
5603 return;
5604 }
5605
5606 void
5607 md_assemble (str)
5608 char *str;
5609 {
5610 char c;
5611 char *p, *q, *start;
5612
5613 /* Align the instruction */
5614 /* this may not be the right thing to do but ... */
5615 /* arm_align (2, 0); */
5616 listing_prev_line (); /* Defined in listing.h */
5617
5618 /* Align the previous label if needed */
5619 if (last_label_seen != NULL)
5620 {
5621 last_label_seen->sy_frag = frag_now;
5622 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
5623 S_SET_SEGMENT (last_label_seen, now_seg);
5624 }
5625
5626 memset (&inst, '\0', sizeof (inst));
5627 inst.reloc.type = BFD_RELOC_NONE;
5628
5629 if (*str == ' ')
5630 str++; /* Skip leading white space */
5631
5632 /* scan up to the end of the op-code, which must end in white space or
5633 end of string */
5634 for (start = p = str; *p != '\0'; p++)
5635 if (*p == ' ')
5636 break;
5637
5638 if (p == str)
5639 {
5640 as_bad ("No operator -- statement `%s'\n", str);
5641 return;
5642 }
5643
5644 if (thumb_mode)
5645 {
5646 CONST struct thumb_opcode *opcode;
5647
5648 c = *p;
5649 *p = '\0';
5650 opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
5651 *p = c;
5652 if (opcode)
5653 {
5654 inst.instruction = opcode->value;
5655 inst.size = opcode->size;
5656 (*opcode->parms)(p);
5657 output_inst (start);
5658 return;
5659 }
5660 }
5661 else
5662 {
5663 CONST struct asm_opcode *opcode;
5664
5665 inst.size = INSN_SIZE;
5666 /* p now points to the end of the opcode, probably white space, but we
5667 have to break the opcode up in case it contains condionals and flags;
5668 keep trying with progressively smaller basic instructions until one
5669 matches, or we run out of opcode. */
5670 q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
5671 for (; q != str; q--)
5672 {
5673 c = *q;
5674 *q = '\0';
5675 opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
5676 *q = c;
5677 if (opcode && opcode->template)
5678 {
5679 unsigned long flag_bits = 0;
5680 char *r;
5681
5682 /* Check that this instruction is supported for this CPU */
5683 if ((opcode->variants & cpu_variant) == 0)
5684 goto try_shorter;
5685
5686 inst.instruction = opcode->value;
5687 if (q == p) /* Just a simple opcode */
5688 {
5689 if (opcode->comp_suffix != 0)
5690 as_bad ("Opcode `%s' must have suffix from <%s>\n", str,
5691 opcode->comp_suffix);
5692 else
5693 {
5694 inst.instruction |= COND_ALWAYS;
5695 (*opcode->parms)(q, 0);
5696 }
5697 output_inst (start);
5698 return;
5699 }
5700
5701 /* Now check for a conditional */
5702 r = q;
5703 if (p - r >= 2)
5704 {
5705 CONST struct asm_cond *cond;
5706 char d = *(r + 2);
5707
5708 *(r + 2) = '\0';
5709 cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
5710 *(r + 2) = d;
5711 if (cond)
5712 {
5713 if (cond->value == 0xf0000000)
5714 as_tsktsk (
5715 "Warning: Use of the 'nv' conditional is deprecated\n");
5716
5717 inst.instruction |= cond->value;
5718 r += 2;
5719 }
5720 else
5721 inst.instruction |= COND_ALWAYS;
5722 }
5723 else
5724 inst.instruction |= COND_ALWAYS;
5725
5726 /* if there is a compulsory suffix, it should come here, before
5727 any optional flags. */
5728 if (opcode->comp_suffix)
5729 {
5730 CONST char *s = opcode->comp_suffix;
5731
5732 while (*s)
5733 {
5734 inst.suffix++;
5735 if (*r == *s)
5736 break;
5737 s++;
5738 }
5739
5740 if (*s == '\0')
5741 {
5742 as_bad ("Opcode `%s' must have suffix from <%s>\n", str,
5743 opcode->comp_suffix);
5744 return;
5745 }
5746
5747 r++;
5748 }
5749
5750 /* The remainder, if any should now be flags for the instruction;
5751 Scan these checking each one found with the opcode. */
5752 if (r != p)
5753 {
5754 char d;
5755 CONST struct asm_flg *flag = opcode->flags;
5756
5757 if (flag)
5758 {
5759 int flagno;
5760
5761 d = *p;
5762 *p = '\0';
5763
5764 for (flagno = 0; flag[flagno].template; flagno++)
5765 {
5766 if (! strcmp (r, flag[flagno].template))
5767 {
5768 flag_bits |= flag[flagno].set_bits;
5769 break;
5770 }
5771 }
5772
5773 *p = d;
5774 if (! flag[flagno].template)
5775 goto try_shorter;
5776 }
5777 else
5778 goto try_shorter;
5779 }
5780
5781 (*opcode->parms) (p, flag_bits);
5782 output_inst (start);
5783 return;
5784 }
5785
5786 try_shorter:
5787 ;
5788 }
5789 }
5790
5791 /* It wasn't an instruction, but it might be a register alias of the form
5792 alias .req reg
5793 */
5794 q = p;
5795 while (*q == ' ')
5796 q++;
5797
5798 c = *p;
5799 *p = '\0';
5800
5801 if (*q && !strncmp (q, ".req ", 4))
5802 {
5803 int reg;
5804 char * copy_of_str = str;
5805 char * r;
5806
5807 q += 4;
5808 while (*q == ' ')
5809 q++;
5810
5811 for (r = q; *r != '\0'; r++)
5812 if (*r == ' ')
5813 break;
5814
5815 if (r != q)
5816 {
5817 int regnum;
5818 char d = *r;
5819
5820 *r = '\0';
5821 regnum = arm_reg_parse (& q);
5822 *r = d;
5823
5824 reg = arm_reg_parse (& str);
5825
5826 if (reg == FAIL)
5827 {
5828 if (regnum != FAIL)
5829 {
5830 insert_reg_alias (str, regnum);
5831 }
5832 else
5833 {
5834 as_warn ("register '%s' does not exist\n", q);
5835 }
5836 }
5837 else if (regnum != FAIL)
5838 {
5839 if (reg != regnum)
5840 as_warn ("ignoring redefinition of register alias '%s'", copy_of_str );
5841
5842 /* Do not warn abpout redefinitions to the same alias. */
5843 }
5844 else
5845 as_warn ("ignoring redefinition of register alias '%s' to non-existant register '%s'",
5846 copy_of_str, q);
5847 }
5848 else
5849 as_warn ("ignoring incomplete .req pseuso op");
5850
5851 *p = c;
5852 return;
5853 }
5854
5855 *p = c;
5856 as_bad ("bad instruction `%s'", start);
5857 }
5858
5859 /*
5860 * md_parse_option
5861 * Invocation line includes a switch not recognized by the base assembler.
5862 * See if it's a processor-specific option. These are:
5863 * Cpu variants, the arm part is optional:
5864 * -m[arm]1 Currently not supported.
5865 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
5866 * -m[arm]3 Arm 3 processor
5867 * -m[arm]6, Arm 6 processors
5868 * -m[arm]7[t][[d]m] Arm 7 processors
5869 * -mall All (except the ARM1)
5870 * FP variants:
5871 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
5872 * -mfpe-old (No float load/store multiples)
5873 * -mno-fpu Disable all floating point instructions
5874 * Run-time endian selection:
5875 * -EB big endian cpu
5876 * -EL little endian cpu
5877 * ARM Procedure Calling Standard:
5878 * -mapcs-32 32 bit APCS
5879 * -mapcs-26 26 bit APCS
5880 * -mapcs-float Pass floats in float regs
5881 * -mapcs-reentrant Position independent code
5882 * -mthumb-interwork Code supports Arm/Thumb interworking
5883 */
5884
5885 CONST char *md_shortopts = "m:";
5886 struct option md_longopts[] =
5887 {
5888 #ifdef ARM_BI_ENDIAN
5889 #define OPTION_EB (OPTION_MD_BASE + 0)
5890 {"EB", no_argument, NULL, OPTION_EB},
5891 #define OPTION_EL (OPTION_MD_BASE + 1)
5892 {"EL", no_argument, NULL, OPTION_EL},
5893 #endif
5894 {NULL, no_argument, NULL, 0}
5895 };
5896 size_t md_longopts_size = sizeof (md_longopts);
5897
5898 int
5899 md_parse_option (c, arg)
5900 int c;
5901 char *arg;
5902 {
5903 char *str = arg;
5904
5905 switch (c)
5906 {
5907 #ifdef ARM_BI_ENDIAN
5908 case OPTION_EB:
5909 target_big_endian = 1;
5910 break;
5911 case OPTION_EL:
5912 target_big_endian = 0;
5913 break;
5914 #endif
5915
5916 case 'm':
5917 switch (*str)
5918 {
5919 case 'f':
5920 if (! strcmp (str, "fpa10"))
5921 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
5922 else if (! strcmp (str, "fpa11"))
5923 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
5924 else if (! strcmp (str, "fpe-old"))
5925 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
5926 else
5927 goto bad;
5928 break;
5929
5930 case 'n':
5931 if (! strcmp (str, "no-fpu"))
5932 cpu_variant &= ~FPU_ALL;
5933 break;
5934
5935 case 't':
5936 /* Limit assembler to generating only Thumb instructions: */
5937 if (! strcmp (str, "thumb"))
5938 {
5939 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB;
5940 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
5941 thumb_mode = 1;
5942 }
5943 else if (! strcmp (str, "thumb-interwork"))
5944 {
5945 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB | ARM_ARCHv4;
5946 #ifdef OBJ_COFF
5947 support_interwork = true;
5948 #endif
5949 }
5950 else
5951 goto bad;
5952 break;
5953
5954 default:
5955 if (! strcmp (str, "all"))
5956 {
5957 cpu_variant = ARM_ALL | FPU_ALL;
5958 return 1;
5959 }
5960 #ifdef OBJ_COFF
5961 if (! strncmp (str, "apcs-", 5))
5962 {
5963 /* GCC passes on all command line options starting "-mapcs-..."
5964 to us, so we must parse them here. */
5965
5966 str += 5;
5967
5968 if (! strcmp (str, "32"))
5969 {
5970 uses_apcs_26 = false;
5971 return 1;
5972 }
5973 else if (! strcmp (str, "26"))
5974 {
5975 uses_apcs_26 = true;
5976 return 1;
5977 }
5978 else if (! strcmp (str, "frame"))
5979 {
5980 /* Stack frames are being generated - does not affect
5981 linkage of code. */
5982 return 1;
5983 }
5984 else if (! strcmp (str, "stack-check"))
5985 {
5986 /* Stack checking is being performed - does not affect
5987 linkage, but does require that the functions
5988 __rt_stkovf_split_small and __rt_stkovf_split_big be
5989 present in the final link. */
5990
5991 return 1;
5992 }
5993 else if (! strcmp (str, "float"))
5994 {
5995 /* Floating point arguments are being passed in the floating
5996 point registers. This does affect linking, since this
5997 version of the APCS is incompatible with the version that
5998 passes floating points in the integer registers. */
5999
6000 uses_apcs_float = true;
6001 return 1;
6002 }
6003 else if (! strcmp (str, "reentrant"))
6004 {
6005 /* Reentrant code has been generated. This does affect
6006 linking, since there is no point in linking reentrant/
6007 position independent code with absolute position code. */
6008 pic_code = true;
6009 return 1;
6010 }
6011
6012 as_bad ("Unrecognised APCS switch -m%s", arg);
6013 return 0;
6014 }
6015 #endif
6016 /* Strip off optional "arm" */
6017 if (! strncmp (str, "arm", 3))
6018 str += 3;
6019
6020 switch (*str)
6021 {
6022 case '1':
6023 if (! strcmp (str, "1"))
6024 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
6025 else
6026 goto bad;
6027 break;
6028
6029 case '2':
6030 if (! strcmp (str, "2"))
6031 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
6032 else if (! strcmp (str, "250"))
6033 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
6034 else
6035 goto bad;
6036 break;
6037
6038 case '3':
6039 if (! strcmp (str, "3"))
6040 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
6041 else
6042 goto bad;
6043 break;
6044
6045 case 's':
6046 if (! strcmp (str, "strongarm") || ! strcmp (str, "strongarm110"))
6047 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7 | ARM_ARCHv4 | ARM_LONGMUL;
6048 else
6049 goto bad;
6050 break;
6051
6052 case '8':
6053 if (! strcmp (str, "8"))
6054 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7 | ARM_ARCHv4 | ARM_LONGMUL;
6055 else
6056 goto bad;
6057 break;
6058
6059 case '6':
6060 if (! strcmp (str, "6"))
6061 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
6062 else
6063 goto bad;
6064 break;
6065
6066 case '7':
6067 str++; /* eat the '7' */
6068 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6069 for (; *str; str++)
6070 {
6071 switch (* str)
6072 {
6073 case 't':
6074 cpu_variant |= (ARM_THUMB | ARM_ARCHv4);
6075 break;
6076
6077 case 'm':
6078 cpu_variant |= ARM_LONGMUL;
6079 break;
6080
6081 case 'f': /* fe => fp enabled cpu. */
6082 if (str[1] == 'e')
6083 ++ str;
6084 else
6085 goto bad;
6086
6087 case 'c': /* Unknown */
6088 case 'd': /* debug */
6089 case 'i': /* embedded ice */
6090 /* Included for completeness in ARM processor naming. */
6091 break;
6092
6093 default:
6094 goto bad;
6095 }
6096 }
6097 break;
6098
6099 case 'v':
6100 /* Select variant based on architecture rather than processor */
6101 switch (*++str)
6102 {
6103 case '2':
6104 switch (*++str)
6105 {
6106 case 'a': cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3; break;
6107 case 0: cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; break;
6108 default: as_bad ("Invalid architecture variant -m%s", arg); break;
6109 }
6110 break;
6111
6112 case '3':
6113 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6114
6115 switch (*++str)
6116 {
6117 case 'm': cpu_variant |= ARM_LONGMUL; break;
6118 case 0: break;
6119 default: as_bad ("Invalid architecture variant -m%s", arg); break;
6120 }
6121 break;
6122
6123 case '4':
6124 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCHv4;
6125
6126 switch (*++str)
6127 {
6128 case 't': cpu_variant |= ARM_THUMB; break;
6129 case 0: break;
6130 default: as_bad ("Invalid architecture variant -m%s", arg); break;
6131 }
6132 break;
6133
6134 default:
6135 as_bad ("Invalid architecture variant -m%s", arg);
6136 break;
6137 }
6138 break;
6139
6140 default:
6141 bad:
6142 as_bad ("Invalid processor variant -m%s", arg);
6143 return 0;
6144 }
6145 }
6146 break;
6147
6148 default:
6149 return 0;
6150 }
6151
6152 return 1;
6153 }
6154
6155 void
6156 md_show_usage (fp)
6157 FILE *fp;
6158 {
6159 fprintf (fp,
6160 "-m[arm][<processor name>] select processor variant\n\
6161 -m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n\
6162 -mthumb\t\t\tonly allow Thumb instructions\n\
6163 -mthumb-interwork\tmark the assembled code as supporting interworking\n\
6164 -mall\t\t\tallow any instruction\n\
6165 -mfpa10, -mfpa11\tselect floating point architecture\n\
6166 -mfpe-old\t\tdon't allow floating-point multiple instructions\n\
6167 -mno-fpu\t\tdon't allow any floating-point instructions.\n");
6168 #ifdef OBJ_COFF
6169 fprintf (fp,
6170 "-mapcs-32, -mapcs-26\tspecify which ARM Procedure Calling Standard is in use\n");
6171 fprintf (fp,
6172 "-mapcs-float\t\tfloating point args are passed in floating point regs\n");
6173 fprintf (fp,
6174 "-mapcs-reentrant\tposition independent/reentrant code has been generated\n");
6175 #endif
6176 #ifdef ARM_BI_ENDIAN
6177 fprintf (fp,
6178 "-EB\t\t\tassemble code for a big endian cpu\n\
6179 -EL\t\t\tassemble code for a little endian cpu\n");
6180 #endif
6181 }
6182
6183 /* We need to be able to fix up arbitrary expressions in some statements.
6184 This is so that we can handle symbols that are an arbitrary distance from
6185 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6186 which returns part of an address in a form which will be valid for
6187 a data instruction. We do this by pushing the expression into a symbol
6188 in the expr_section, and creating a fix for that. */
6189
6190 static void
6191 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
6192 fragS *frag;
6193 int where;
6194 short int size;
6195 expressionS *exp;
6196 int pc_rel;
6197 int reloc;
6198 {
6199 fixS *new_fix;
6200 arm_fix_data *arm_data;
6201
6202 switch (exp->X_op)
6203 {
6204 case O_constant:
6205 case O_symbol:
6206 case O_add:
6207 case O_subtract:
6208 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
6209 break;
6210
6211 default:
6212 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
6213 pc_rel, reloc);
6214 break;
6215 }
6216
6217 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6218 arm_data = (arm_fix_data *) obstack_alloc (&notes, sizeof (arm_fix_data));
6219 new_fix->tc_fix_data = (PTR) arm_data;
6220 arm_data->thumb_mode = thumb_mode;
6221
6222 return;
6223 }
6224
6225 /* A good place to do this, although this was probably not intended
6226 * for this kind of use. We need to dump the literal pool before
6227 * references are made to a null symbol pointer. */
6228 void
6229 arm_after_pass_hook ()
6230 {
6231 if (current_poolP != NULL)
6232 {
6233 subseg_set (text_section, 0); /* Put it at the end of text section */
6234 s_ltorg (0);
6235 listing_prev_line ();
6236 }
6237 }
6238
6239 void
6240 arm_start_line_hook ()
6241 {
6242 last_label_seen = NULL;
6243 }
6244
6245 void
6246 arm_frob_label (sym)
6247 symbolS *sym;
6248 {
6249 last_label_seen = sym;
6250 ARM_SET_THUMB (sym, thumb_mode);
6251 #ifdef OBJ_COFF
6252 ARM_SET_INTERWORK (sym, support_interwork);
6253 #endif
6254
6255 if (label_is_thumb_function_name)
6256 {
6257 /* When the address of a Thumb function is taken the bottom
6258 bit of that address should be set. This will allow
6259 interworking between Arm and Thumb functions to work
6260 correctly. */
6261
6262 THUMB_SET_FUNC (sym, 1);
6263
6264 label_is_thumb_function_name = false;
6265 }
6266 }
6267
6268 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6269 ARM ones. */
6270
6271 void
6272 arm_adjust_symtab ()
6273 {
6274 #ifdef OBJ_COFF
6275 symbolS *sym;
6276
6277 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6278 {
6279 if (ARM_IS_THUMB (sym))
6280 {
6281 if (THUMB_IS_FUNC (sym))
6282 {
6283 /* Mark the symbol as a Thumb function. */
6284 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
6285 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
6286 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
6287 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
6288 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
6289 else
6290 as_bad ("%s: unexpected function type: %d", S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
6291 }
6292 else switch (S_GET_STORAGE_CLASS (sym))
6293 {
6294 case C_EXT:
6295 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
6296 break;
6297 case C_STAT:
6298 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
6299 break;
6300 case C_LABEL:
6301 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
6302 break;
6303 default: /* do nothing */
6304 break;
6305 }
6306 }
6307
6308 if (ARM_IS_INTERWORK (sym))
6309 {
6310 coffsymbol(sym->bsym)->native->u.syment.n_flags = 0xFF;
6311 }
6312 }
6313 #endif
6314 }
6315
6316 int
6317 arm_data_in_code ()
6318 {
6319 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
6320 {
6321 *input_line_pointer = '/';
6322 input_line_pointer += 5;
6323 *input_line_pointer = 0;
6324 return 1;
6325 }
6326 return 0;
6327 }
6328
6329 char *
6330 arm_canonicalize_symbol_name (name)
6331 char *name;
6332 {
6333 int len;
6334
6335 if (thumb_mode && (len = strlen (name)) > 5
6336 && ! strcmp (name + len - 5, "/data"))
6337 {
6338 *(name + len - 5) = 0;
6339 }
6340
6341 return name;
6342 }
This page took 0.20072 seconds and 5 git commands to generate.