1 /* tc-arm.c All the arm specific stuff in one convenient, huge,
2 slow to compile, easy to find file.
3 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
4 Modified by David Taylor (dtaylor@armltd.co.uk)
6 Copyright (C) 1994, 1995 Free Software Foundation, Inc.
8 This file is part of GAS, the GNU Assembler.
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to
22 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
36 /* ??? This is currently unused. */
38 #define internalError() \
39 as_fatal ("ARM Internal Error, line %d, %s", __LINE__, __FILE__)
41 #define internalError() as_fatal ("ARM Internal Error")
44 /* Types of processor to assemble for. */
45 #define ARM_1 0x00000001
46 #define ARM_2 0x00000002
47 #define ARM_3 0x00000004
48 #define ARM_250 0x00000004 /* ARM3 instruction set */
49 #define ARM_6 0x00000008
50 #define ARM_7 0x00000008
52 /* The following bitmasks control CPU extensions (ARM7 onwards): */
53 #define ARM_LONGMUL 0x00000010 /* allow long multiplies */
54 #define ARM_HALFWORD 0x00000020 /* allow ARM 16bit memory transfers */
56 /* Some useful combinations: */
57 #define ARM_ANY 0x00ffffff
58 #define ARM_2UP 0x00fffffe
59 #define ARM_ALL ARM_2UP /* Not arm1 only */
60 #define ARM_3UP 0x00fffffc
61 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
63 #define FPU_CORE 0x80000000
64 #define FPU_FPA10 0x40000000
65 #define FPU_FPA11 0x40000000
68 /* Some useful combinations */
69 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
70 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
73 #define CPU_DEFAULT ARM_ALL
77 #define FPU_DEFAULT FPU_ALL
80 unsigned long cpu_variant
= CPU_DEFAULT
| FPU_DEFAULT
;
82 /* This array holds the chars that always start a comment. If the
83 pre-processor is disabled, these aren't very useful */
84 CONST
char comment_chars
[] = "@";
86 /* This array holds the chars that only start a comment at the beginning of
87 a line. If the line seems to have the form '# 123 filename'
88 .line and .file directives will appear in the pre-processed output */
89 /* Note that input_file.c hand checks for '#' at the beginning of the
90 first line of the input file. This is because the compiler outputs
91 #NO_APP at the beginning of its output. */
92 /* Also note that comments like this one will always work. */
93 CONST
char line_comment_chars
[] = "#";
95 CONST
char line_separator_chars
[] = "";
97 /* Chars that can be used to separate mant from exp in floating point nums */
98 CONST
char EXP_CHARS
[] = "eE";
100 /* Chars that mean this number is a floating point constant */
104 CONST
char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
106 const int md_reloc_size
= 8; /* Size of relocation record */
111 unsigned long instruction
;
115 bfd_reloc_code_real_type type
;
125 CONST
char *template;
129 static CONST
struct asm_shift shift
[] =
145 #define NO_SHIFT_RESTRICT 1
146 #define SHIFT_RESTRICT 0
148 #define NUM_FLOAT_VALS 8
150 CONST
char *fp_const
[] =
152 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
155 /* Number of littlenums required to hold an extended precision number */
156 #define MAX_LITTLENUMS 6
158 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
168 #define CP_T_X 0x00008000
169 #define CP_T_Y 0x00400000
170 #define CP_T_Pre 0x01000000
171 #define CP_T_UD 0x00800000
172 #define CP_T_WB 0x00200000
174 #define TRANS_BIT (0x00200000)
178 CONST
char *template;
182 /* This is to save a hash look-up in the common case */
183 #define COND_ALWAYS 0xe0000000
185 static CONST
struct asm_cond conds
[] =
189 {"cs", 0x20000000}, {"hs", 0x20000000},
190 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
208 CONST
char *template; /* Basic flag string */
209 unsigned long set_bits
; /* Bits to set */
210 unsigned long variants
; /* Which CPU variants this exists for */
213 static CONST
struct asm_flg s_flag
[] =
215 {"s", 0x00100000, ARM_ANY
},
219 static CONST
struct asm_flg ldst_flags
[] =
221 {"b", 0x00400000, ARM_ANY
},
222 {"t", TRANS_BIT
, ARM_ANY
},
223 {"bt", 0x00400000 | TRANS_BIT
, ARM_ANY
},
224 {"h", 0x00000020, ARM_HALFWORD
},
225 {"sb", 0x00000040, ARM_HALFWORD
},
226 {"sh", 0x00000060, ARM_HALFWORD
},
230 static CONST
struct asm_flg byte_flag
[] =
232 {"b", 0x00400000, ARM_3UP
},
236 static CONST
struct asm_flg cmp_flags
[] =
238 {"s", 0x00100000, ARM_ANY
},
239 {"p", 0x0010f000, ARM_ANY
},
243 static CONST
struct asm_flg ldm_flags
[] =
245 {"ed", 0x01800000, ARM_ANY
},
246 {"fd", 0x00800000, ARM_ANY
},
247 {"ea", 0x01000000, ARM_ANY
},
248 {"fa", 0x08000000, ARM_ANY
},
249 {"ib", 0x01800000, ARM_ANY
},
250 {"ia", 0x00800000, ARM_ANY
},
251 {"db", 0x01000000, ARM_ANY
},
252 {"da", 0x08000000, ARM_ANY
},
256 static CONST
struct asm_flg stm_flags
[] =
258 {"ed", 0x08000000, ARM_ANY
},
259 {"fd", 0x01000000, ARM_ANY
},
260 {"ea", 0x00800000, ARM_ANY
},
261 {"fa", 0x01800000, ARM_ANY
},
262 {"ib", 0x01800000, ARM_ANY
},
263 {"ia", 0x00800000, ARM_ANY
},
264 {"db", 0x01000000, ARM_ANY
},
265 {"da", 0x08000000, ARM_ANY
},
269 static CONST
struct asm_flg lfm_flags
[] =
271 {"fd", 0x00800000, FPU_MEMMULTI
},
272 {"ea", 0x01000000, FPU_MEMMULTI
},
276 static CONST
struct asm_flg sfm_flags
[] =
278 {"fd", 0x01000000, FPU_MEMMULTI
},
279 {"ea", 0x00800000, FPU_MEMMULTI
},
283 static CONST
struct asm_flg round_flags
[] =
285 {"p", 0x00000020, FPU_ALL
},
286 {"m", 0x00000040, FPU_ALL
},
287 {"z", 0x00000060, FPU_ALL
},
291 static CONST
struct asm_flg except_flag
[] =
293 {"e", 0x00400000, FPU_ALL
},
297 static CONST
struct asm_flg cplong_flag
[] =
299 {"l", 0x00400000, ARM_2UP
},
305 CONST
char *template;
306 unsigned long number
;
309 #define PSR_ALL 0x00010000
311 static CONST
struct asm_psr psrs
[] =
324 /* Functions called by parser */
325 /* ARM instructions */
326 static void do_arit
PARAMS ((char *operands
, unsigned long flags
));
327 static void do_cmp
PARAMS ((char *operands
, unsigned long flags
));
328 static void do_mov
PARAMS ((char *operands
, unsigned long flags
));
329 static void do_ldst
PARAMS ((char *operands
, unsigned long flags
));
330 static void do_ldmstm
PARAMS ((char *operands
, unsigned long flags
));
331 static void do_branch
PARAMS ((char *operands
, unsigned long flags
));
332 static void do_swi
PARAMS ((char *operands
, unsigned long flags
));
333 /* Pseudo Op codes */
334 static void do_adr
PARAMS ((char *operands
, unsigned long flags
));
335 static void do_nop
PARAMS ((char *operands
, unsigned long flags
));
337 static void do_mul
PARAMS ((char *operands
, unsigned long flags
));
338 static void do_mla
PARAMS ((char *operands
, unsigned long flags
));
340 static void do_swap
PARAMS ((char *operands
, unsigned long flags
));
342 static void do_msr
PARAMS ((char *operands
, unsigned long flags
));
343 static void do_mrs
PARAMS ((char *operands
, unsigned long flags
));
345 static void do_mull
PARAMS ((char *operands
, unsigned long flags
));
347 /* Coprocessor Instructions */
348 static void do_cdp
PARAMS ((char *operands
, unsigned long flags
));
349 static void do_lstc
PARAMS ((char *operands
, unsigned long flags
));
350 static void do_co_reg
PARAMS ((char *operands
, unsigned long flags
));
351 static void do_fp_ctrl
PARAMS ((char *operands
, unsigned long flags
));
352 static void do_fp_ldst
PARAMS ((char *operands
, unsigned long flags
));
353 static void do_fp_ldmstm
PARAMS ((char *operands
, unsigned long flags
));
354 static void do_fp_dyadic
PARAMS ((char *operands
, unsigned long flags
));
355 static void do_fp_monadic
PARAMS ((char *operands
, unsigned long flags
));
356 static void do_fp_cmp
PARAMS ((char *operands
, unsigned long flags
));
357 static void do_fp_from_reg
PARAMS ((char *operands
, unsigned long flags
));
358 static void do_fp_to_reg
PARAMS ((char *operands
, unsigned long flags
));
360 static void fix_new_arm
PARAMS ((fragS
*frag
, int where
,
361 short int size
, expressionS
*exp
,
362 int pc_rel
, int reloc
));
363 static int arm_reg_parse
PARAMS ((char **ccp
));
364 static int arm_psr_parse
PARAMS ((char **ccp
));
366 /* ARM instructions take 4bytes in the object file, Thumb instructions
367 take 2. The assembler defaults to ARM code generation: */
368 static int insn_size
= 4;
370 /* LONGEST_INST is the longest basic instruction name without conditions or
372 * ARM7DM has 4 of length 5
375 #define LONGEST_INST 5
379 CONST
char *template; /* Basic string to match */
380 unsigned long value
; /* Basic instruction code */
381 CONST
char *comp_suffix
; /* Compulsory suffix that must follow conds */
382 CONST
struct asm_flg
*flags
; /* Bits to toggle if flag 'n' set */
383 unsigned long variants
; /* Which CPU variants this exists for */
384 void (*parms
)(); /* Function to call to parse args */
387 static CONST
struct asm_opcode insns
[] =
389 /* ARM Instructions */
390 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
391 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
392 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
393 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
394 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
395 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
396 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
397 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
398 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
399 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
400 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
401 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
402 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
403 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
404 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
405 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
406 {"str", 0x04000000, NULL
, ldst_flags
, ARM_ANY
, do_ldst
},
407 {"ldr", 0x04100000, NULL
, ldst_flags
, ARM_ANY
, do_ldst
},
408 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
409 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
410 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
411 {"bl", 0x0b000000, NULL
, NULL
, ARM_ANY
, do_branch
},
412 {"b", 0x0a000000, NULL
, NULL
, ARM_ANY
, do_branch
},
415 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
416 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
418 /* ARM 2 multiplies */
419 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
420 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
422 /* ARM 3 - swp instructions */
423 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
425 /* ARM 6 Coprocessor instructions */
426 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
427 {"msr", 0x0128f000, NULL
, NULL
, ARM_6UP
, do_msr
},
429 /* ARM 7M long multiplies - need signed/unsigned flags! */
430 {"smull", 0x00c00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
431 {"umull", 0x00800090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
432 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
433 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
435 /* Floating point instructions */
436 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
437 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
438 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
439 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
440 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
441 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
442 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
443 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
444 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
445 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
446 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
447 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
448 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
449 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
450 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
451 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
452 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
453 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
454 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
455 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
456 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
457 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
458 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
459 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
460 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
461 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
462 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
463 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
464 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
465 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
466 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
467 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
468 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
469 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
470 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
471 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
472 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
473 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
474 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
475 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
476 be an optional suffix, but part of the instruction. To be compatible,
478 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
479 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
480 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
481 {"fix", 0x0e100110, NULL
, round_flags
, FPU_ALL
, do_fp_to_reg
},
483 /* Generic copressor instructions */
484 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
485 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
486 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
487 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
488 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
491 /* defines for various bits that we will want to toggle */
493 #define INST_IMMEDIATE 0x02000000
494 #define OFFSET_REG 0x02000000
495 #define HWOFFSET_IMM 0x00400000
496 #define SHIFT_BY_REG 0x00000010
497 #define PRE_INDEX 0x01000000
498 #define INDEX_UP 0x00800000
499 #define WRITE_BACK 0x00200000
500 #define MULTI_SET_PSR 0x00400000
502 #define LITERAL_MASK 0xf000f000
503 #define COND_MASK 0xf0000000
504 #define OPCODE_MASK 0xfe1fffff
505 #define DATA_OP_SHIFT 21
507 /* Codes to distinguish the arithmetic instructions */
519 #define OPCODE_CMP 10
520 #define OPCODE_CMN 11
521 #define OPCODE_ORR 12
522 #define OPCODE_MOV 13
523 #define OPCODE_BIC 14
524 #define OPCODE_MVN 15
532 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
533 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
534 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
538 /* These are the standard names; Users can add aliases with .req */
539 static CONST
struct reg_entry reg_table
[] =
541 /* Processor Register Numbers */
542 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
543 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
544 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
545 {"r12", 12}, {"r13", 13}, {"r14", 14}, {"r15", REG_PC
},
546 /* APCS conventions */
547 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
548 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
549 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
550 {"fp", 11}, {"ip", 12}, {"sp", 13}, {"lr", 14}, {"pc", REG_PC
},
552 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
553 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
554 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
555 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
556 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
557 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
558 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
559 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
560 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
561 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
565 static CONST
char *bad_args
= "Bad arguments to instruction";
566 static CONST
char *bad_pc
= "r15 not allowed here";
568 static struct hash_control
*arm_ops_hsh
= NULL
;
569 static struct hash_control
*arm_cond_hsh
= NULL
;
570 static struct hash_control
*arm_shift_hsh
= NULL
;
571 static struct hash_control
*arm_reg_hsh
= NULL
;
572 static struct hash_control
*arm_psr_hsh
= NULL
;
574 /* This table describes all the machine specific pseudo-ops the assembler
575 has to support. The fields are:
576 pseudo-op name without dot
577 function to call to execute this pseudo-op
578 Integer arg to pass to the function
581 static void s_req
PARAMS ((int));
582 static void s_align
PARAMS ((int));
583 static void s_bss
PARAMS ((int));
584 static void s_even
PARAMS ((int));
585 static void s_ltorg
PARAMS ((int));
587 static int my_get_expression
PARAMS ((expressionS
*, char **));
589 CONST pseudo_typeS md_pseudo_table
[] =
591 {"req", s_req
, 0}, /* Never called becasue '.req' does not start line */
593 {"align", s_align
, 0},
595 {"ltorg", s_ltorg
, 0},
596 {"pool", s_ltorg
, 0},
598 {"extend", float_cons
, 'x'},
599 {"ldouble", float_cons
, 'x'},
600 {"packed", float_cons
, 'p'},
604 /* Stuff needed to resolve the label ambiguity
614 symbolS
*last_label_seen
;
618 #define MAX_LITERAL_POOL_SIZE 1024
620 typedef struct literalS
622 struct expressionS exp
;
626 literalT literals
[MAX_LITERAL_POOL_SIZE
];
627 int next_literal_pool_place
= 0; /* Next free entry in the pool */
628 int lit_pool_num
= 1; /* Next literal pool number */
629 symbolS
*current_poolP
= NULL
;
630 symbolS
*symbol_make_empty ();
637 if (current_poolP
== NULL
)
638 current_poolP
= symbol_make_empty();
640 /* Check if this literal value is already in the pool: */
641 while (lit_count
< next_literal_pool_place
)
643 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
644 && inst
.reloc
.exp
.X_op
== O_constant
645 && literals
[lit_count
].exp
.X_add_number
== inst
.reloc
.exp
.X_add_number
646 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
651 if (lit_count
== next_literal_pool_place
) /* new entry */
653 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
655 inst
.error
= "Literal Pool Overflow\n";
659 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
660 lit_count
= next_literal_pool_place
++;
663 inst
.reloc
.exp
.X_op
= O_symbol
;
664 inst
.reloc
.exp
.X_add_number
= (lit_count
)*4-8;
665 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
670 /* Can't use symbol_new here, so have to create a symbol and them at
671 a later datete assign iot a value. Thats what these functions do */
673 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
675 CONST
char *name
; /* It is copied, the caller can modify */
676 segT segment
; /* Segment identifier (SEG_<something>) */
677 valueT valu
; /* Symbol value */
678 fragS
*frag
; /* Associated fragment */
680 unsigned int name_length
;
681 char *preserved_copy_of_name
;
683 name_length
= strlen (name
) + 1; /* +1 for \0 */
684 obstack_grow (¬es
, name
, name_length
);
685 preserved_copy_of_name
= obstack_finish (¬es
);
686 #ifdef STRIP_UNDERSCORE
687 if (preserved_copy_of_name
[0] == '_')
688 preserved_copy_of_name
++;
691 #ifdef tc_canonicalize_symbol_name
692 preserved_copy_of_name
=
693 tc_canonicalize_symbol_name (preserved_copy_of_name
);
696 S_SET_NAME (symbolP
, preserved_copy_of_name
);
698 S_SET_SEGMENT (symbolP
, segment
);
699 S_SET_VALUE (symbolP
, valu
);
700 symbol_clear_list_pointers(symbolP
);
702 symbolP
->sy_frag
= frag
;
705 * Link to end of symbol chain.
708 extern int symbol_table_frozen
;
709 if (symbol_table_frozen
)
713 symbol_append (symbolP
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
715 obj_symbol_new_hook (symbolP
);
717 #ifdef tc_symbol_new_hook
718 tc_symbol_new_hook (symbolP
);
722 verify_symbol_chain(symbol_rootP
, symbol_lastP
);
723 #endif /* DEBUG_SYMS */
731 symbolP
= (symbolS
*) obstack_alloc (¬es
, sizeof (symbolS
));
733 /* symbol must be born in some fixed state. This seems as good as any. */
734 memset (symbolP
, 0, sizeof (symbolS
));
737 symbolP
->bsym
= bfd_make_empty_symbol (stdoutput
);
738 assert (symbolP
->bsym
!= 0);
739 symbolP
->bsym
->udata
.p
= (PTR
) symbolP
;
745 /* Check that an immediate is valid, and if so, convert it to the right format
748 /* OH, for a rotate instruction in C! */
751 validate_immediate (val
)
754 unsigned int a
= (unsigned int) val
;
757 /* Do the easy (and most common ones) quickly */
758 for (i
= 0; i
<= 24; i
+= 2)
760 if ((a
& (0xff << i
)) == a
)
761 return (int) (((32 - i
) & 0x1e) << 7) | ((a
>> i
) & 0xff);
764 /* Now do the harder ones */
765 for (; i
< 32; i
+= 2)
767 if ((a
& ((0xff << i
) | (0xff >> (32 - i
)))) == a
)
769 a
= ((a
>> i
) & 0xff) | ((a
<< (32 - i
)) & 0xff);
770 return (int) a
| (((32 - i
) >> 1) << 8);
777 validate_offset_imm (val
, hwse
)
781 if ((hwse
&& (val
< -255 || val
> 255))
782 || (val
< -4095 || val
> 4095))
792 as_bad ("Invalid syntax for .req directive.");
799 /* We don't support putting frags in the BSS segment, we fake it by
800 marking in_bss, then looking at s_skip for clues?.. */
801 subseg_set (bss_section
, 0);
802 demand_empty_rest_of_line ();
809 if (!need_pass_2
) /* Never make frag if expect extra pass. */
811 record_alignment (now_seg
, 1);
812 demand_empty_rest_of_line ();
822 if (current_poolP
== NULL
)
826 as_tsktsk ("Nothing to put in the pool\n");
830 /* Align pool as you have word accesses */
831 /* Only make a frag if we have to ... */
835 record_alignment (now_seg
, 2);
838 as_tsktsk ("Inserting implicit pool at change of section");
840 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
842 symbol_locate (current_poolP
, sym_name
, now_seg
,
843 (valueT
) frag_now_fix (), frag_now
);
844 symbol_table_insert (current_poolP
);
846 while (lit_count
< next_literal_pool_place
)
847 /* First output the expression in the instruction to the pool */
848 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
850 next_literal_pool_place
= 0;
851 current_poolP
= NULL
;
856 arm_align (power
, fill
)
860 /* Only make a frag if we HAVE to ... */
861 if (power
&& !need_pass_2
)
862 frag_align (power
, fill
);
864 record_alignment (now_seg
, power
);
869 s_align (unused
) /* Same as s_align_ptwo but align 0 => align 2 */
873 register long temp_fill
;
874 long max_alignment
= 15;
876 temp
= get_absolute_expression ();
877 if (temp
> max_alignment
)
878 as_bad ("Alignment too large: %d. assumed.", temp
= max_alignment
);
881 as_bad ("Alignment negative. 0 assumed.");
885 if (*input_line_pointer
== ',')
887 input_line_pointer
++;
888 temp_fill
= get_absolute_expression ();
896 /* Only make a frag if we HAVE to. . . */
897 if (temp
&& !need_pass_2
)
898 frag_align (temp
, (int) temp_fill
);
899 demand_empty_rest_of_line ();
901 record_alignment (now_seg
, temp
);
912 inst
.error
= "Garbage following instruction";
916 skip_past_comma (str
)
922 while ((c
= *p
) == ' ' || c
== ',')
925 if (c
== ',' && comma
++)
933 return comma
? SUCCESS
: FAIL
;
936 /* A standard register must be given at this point. Shift is the place to
937 put it in the instruction. */
940 reg_required_here (str
, shift
)
947 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
949 inst
.instruction
|= reg
<< shift
;
953 /* In the few cases where we might be able to accept something else
954 this error can be overridden */
955 inst
.error
= "Register expected";
957 /* Restore the start point, we may have got a reg of the wrong class. */
963 psr_required_here (str
, shift
)
970 if ((psr
= arm_psr_parse (str
)) != FAIL
&& psr
< 2)
973 inst
.instruction
|= 1 << shift
; /* Should be bit 22 */
977 /* In the few cases where we might be able to accept something else
978 this error can be overridden */
979 inst
.error
= "<psr> expected";
981 /* Restore the start point. */
987 psrf_required_here (str
, shift
)
994 if ((psrf
= arm_psr_parse (str
)) != FAIL
&& psrf
> 1)
996 if (psrf
== 1 || psrf
== 3)
997 inst
.instruction
|= 1 << shift
; /* Should be bit 22 */
1001 /* In the few cases where we might be able to accept something else
1002 this error can be overridden */
1003 inst
.error
= "<psrf> expected";
1005 /* Restore the start point. */
1011 co_proc_number (str
)
1014 int processor
, pchar
;
1016 while (**str
== ' ')
1019 /* The data sheet seems to imply that just a number on its own is valid
1020 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1022 if (**str
== 'p' || **str
== 'P')
1026 if (pchar
>= '0' && pchar
<= '9')
1028 processor
= pchar
- '0';
1029 if (**str
>= '0' && **str
<= '9')
1031 processor
= processor
* 10 + *(*str
)++ - '0';
1034 inst
.error
= "Illegal co-processor number";
1041 inst
.error
= "Bad or missing co-processor number";
1045 inst
.instruction
|= processor
<< 8;
1050 cp_opc_expr (str
, where
, length
)
1057 while (**str
== ' ')
1060 memset (&expr
, '\0', sizeof (expr
));
1062 if (my_get_expression (&expr
, str
))
1064 if (expr
.X_op
!= O_constant
)
1066 inst
.error
= "bad or missing expression";
1070 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1072 inst
.error
= "immediate co-processor expression too large";
1076 inst
.instruction
|= expr
.X_add_number
<< where
;
1081 cp_reg_required_here (str
, where
)
1088 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1091 inst
.instruction
|= reg
<< where
;
1095 /* In the few cases where we might be able to accept something else
1096 this error can be overridden */
1097 inst
.error
= "Co-processor register expected";
1099 /* Restore the start point */
1105 fp_reg_required_here (str
, where
)
1112 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1115 inst
.instruction
|= reg
<< where
;
1119 /* In the few cases where we might be able to accept something else
1120 this error can be overridden */
1121 inst
.error
= "Floating point register expected";
1123 /* Restore the start point */
1129 cp_address_offset (str
)
1134 while (**str
== ' ')
1139 inst
.error
= "immediate expression expected";
1144 if (my_get_expression (&inst
.reloc
.exp
, str
))
1146 if (inst
.reloc
.exp
.X_op
== O_constant
)
1148 offset
= inst
.reloc
.exp
.X_add_number
;
1151 inst
.error
= "co-processor address must be word aligned";
1155 if (offset
> 1023 || offset
< -1023)
1157 inst
.error
= "offset too large";
1162 inst
.instruction
|= INDEX_UP
;
1166 inst
.instruction
|= offset
>> 2;
1169 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1175 cp_address_required_here (str
)
1190 if ((reg
= reg_required_here (&p
, 16)) == FAIL
)
1192 inst
.error
= "Register required";
1202 if (skip_past_comma (&p
) == SUCCESS
)
1205 write_back
= WRITE_BACK
;
1208 inst
.error
= "pc may not be used in post-increment";
1212 if (cp_address_offset (&p
) == FAIL
)
1216 pre_inc
= PRE_INDEX
| INDEX_UP
;
1220 /* '['Rn, #expr']'[!] */
1222 if (skip_past_comma (&p
) == FAIL
)
1224 inst
.error
= "pre-indexed expression expected";
1228 pre_inc
= PRE_INDEX
;
1229 if (cp_address_offset (&p
) == FAIL
)
1237 inst
.error
= "missing ]";
1248 inst
.error
= "pc may not be used with write-back";
1253 write_back
= WRITE_BACK
;
1259 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1262 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1263 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
1264 inst
.reloc
.pc_rel
= 1;
1265 inst
.instruction
|= (REG_PC
<< 16);
1266 pre_inc
= PRE_INDEX
;
1269 inst
.instruction
|= write_back
| pre_inc
;
1277 unsigned long flags
;
1279 /* Do nothing really */
1280 inst
.instruction
|= flags
; /* This is pointless */
1288 unsigned long flags
;
1290 /* Only one syntax */
1294 if (reg_required_here (&str
, 12) == FAIL
)
1296 inst
.error
= bad_args
;
1300 if (skip_past_comma (&str
) == FAIL
1301 || psr_required_here (&str
, 22) == FAIL
)
1303 inst
.error
= "<psr> expected";
1307 inst
.instruction
|= flags
;
1315 unsigned long flags
;
1318 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression" */
1323 if ((psr
= psr_required_here (&str
, 22)) != FAIL
)
1325 inst
.instruction
|= PSR_ALL
;
1326 /* Sytax should be "<psr>, Rm" */
1327 if (skip_past_comma (&str
) == FAIL
1328 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
1330 inst
.error
= bad_args
;
1334 else if ((psrf
= psrf_required_here (&str
, 22)) != FAIL
)
1335 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1337 if (skip_past_comma (&str
) == FAIL
)
1339 inst
.error
= bad_args
;
1342 if ((reg
= reg_required_here (&str
, 0)) != FAIL
)
1344 /* Immediate expression */
1345 else if (*(str
++) == '#')
1348 if (my_get_expression (&inst
.reloc
.exp
, &str
))
1350 inst
.error
= "Register or shift expression expected";
1354 if (inst
.reloc
.exp
.X_add_symbol
)
1356 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
1357 inst
.reloc
.pc_rel
= 0;
1361 int value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
1364 inst
.error
= "Invalid constant";
1368 inst
.instruction
|= value
;
1371 flags
|= INST_IMMEDIATE
;
1375 inst
.error
= "Error: the other";
1381 inst
.error
= bad_args
;
1386 inst
.instruction
|= flags
;
1391 /* Long Multiply Parser
1392 UMULL RdLo, RdHi, Rm, Rs
1393 SMULL RdLo, RdHi, Rm, Rs
1394 UMLAL RdLo, RdHi, Rm, Rs
1395 SMLAL RdLo, RdHi, Rm, Rs
1398 do_mull (str
, flags
)
1400 unsigned long flags
;
1402 int rdlo
, rdhi
, rm
, rs
;
1404 /* only one format "rdlo, rdhi, rm, rs" */
1408 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
1410 inst
.error
= bad_args
;
1414 if (skip_past_comma (&str
) == FAIL
1415 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
1417 inst
.error
= bad_args
;
1421 if (skip_past_comma (&str
) == FAIL
1422 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1424 inst
.error
= bad_args
;
1428 /* rdhi, rdlo and rm must all be different */
1429 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
1430 as_tsktsk ("rdhi, rdlo and rm must all be different");
1432 if (skip_past_comma (&str
) == FAIL
1433 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
1435 inst
.error
= bad_args
;
1439 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
1441 inst
.error
= bad_pc
;
1445 inst
.instruction
|= flags
;
1453 unsigned long flags
;
1457 /* only one format "rd, rm, rs" */
1461 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
1463 inst
.error
= bad_args
;
1469 inst
.error
= bad_pc
;
1473 if (skip_past_comma (&str
) == FAIL
1474 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1476 inst
.error
= bad_args
;
1482 inst
.error
= bad_pc
;
1487 as_tsktsk ("rd and rm should be different in mul");
1489 if (skip_past_comma (&str
) == FAIL
1490 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
1492 inst
.error
= bad_args
;
1498 inst
.error
= bad_pc
;
1502 inst
.instruction
|= flags
;
1510 unsigned long flags
;
1514 /* only one format "rd, rm, rs, rn" */
1518 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
1520 inst
.error
= bad_args
;
1526 inst
.error
= bad_pc
;
1530 if (skip_past_comma (&str
) == FAIL
1531 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1533 inst
.error
= bad_args
;
1539 inst
.error
= bad_pc
;
1544 as_tsktsk ("rd and rm should be different in mla");
1546 if (skip_past_comma (&str
) == FAIL
1547 || (rd
= reg_required_here (&str
, 8)) == FAIL
1548 || skip_past_comma (&str
) == FAIL
1549 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
1551 inst
.error
= bad_args
;
1555 if (rd
== REG_PC
|| rm
== REG_PC
)
1557 inst
.error
= bad_pc
;
1561 inst
.instruction
|= flags
;
1566 /* Returns the index into fp_values of a floating point number, or -1 if
1567 not in the table. */
1569 my_get_float_expression (str
)
1572 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1577 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
1578 /* Look for a raw floating point number */
1579 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
1580 && (is_end_of_line
[(int)(*save_in
)] || *save_in
== '\0'))
1582 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
1584 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
1586 if (words
[j
] != fp_values
[i
][j
])
1590 if (j
== MAX_LITTLENUMS
)
1598 /* Try and parse a more complex expression, this will probably fail
1599 unless the code uses a floating point prefix (eg "0f") */
1600 save_in
= input_line_pointer
;
1601 input_line_pointer
= *str
;
1602 if (expression (&exp
) == absolute_section
1603 && exp
.X_op
== O_big
1604 && exp
.X_add_number
< 0)
1606 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
1608 if (gen_to_words (words
, 5, (long)15) == 0)
1610 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
1612 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
1614 if (words
[j
] != fp_values
[i
][j
])
1618 if (j
== MAX_LITTLENUMS
)
1620 *str
= input_line_pointer
;
1621 input_line_pointer
= save_in
;
1628 *str
= input_line_pointer
;
1629 input_line_pointer
= save_in
;
1633 /* Return true if anything in the expression is a bignum */
1635 walk_no_bignums (sp
)
1638 if (sp
->sy_value
.X_op
== O_big
)
1641 if (sp
->sy_value
.X_add_symbol
)
1643 return (walk_no_bignums (sp
->sy_value
.X_add_symbol
)
1644 || (sp
->sy_value
.X_op_symbol
1645 && walk_no_bignums (sp
->sy_value
.X_op_symbol
)));
1652 my_get_expression (ep
, str
)
1659 save_in
= input_line_pointer
;
1660 input_line_pointer
= *str
;
1661 seg
= expression (ep
);
1664 if (seg
!= absolute_section
1665 && seg
!= text_section
1666 && seg
!= data_section
1667 && seg
!= bss_section
1668 && seg
!= undefined_section
)
1670 inst
.error
= "bad_segment";
1671 *str
= input_line_pointer
;
1672 input_line_pointer
= save_in
;
1677 /* Get rid of any bignums now, so that we don't generate an error for which
1678 we can't establish a line number later on. Big numbers are never valid
1679 in instructions, which is where this routine is always called. */
1680 if (ep
->X_op
== O_big
1681 || (ep
->X_add_symbol
1682 && (walk_no_bignums (ep
->X_add_symbol
)
1684 && walk_no_bignums (ep
->X_op_symbol
)))))
1686 inst
.error
= "Invalid constant";
1687 *str
= input_line_pointer
;
1688 input_line_pointer
= save_in
;
1692 *str
= input_line_pointer
;
1693 input_line_pointer
= save_in
;
1697 /* unrestrict should be one if <shift> <register> is permitted for this
1701 decode_shift (str
, unrestrict
)
1705 struct asm_shift
*shft
;
1709 while (**str
== ' ')
1712 for (p
= *str
; isalpha (*p
); p
++)
1717 inst
.error
= "Shift expression expected";
1723 shft
= (struct asm_shift
*) hash_find (arm_shift_hsh
, *str
);
1727 if (!strcmp (*str
, "rrx"))
1730 inst
.instruction
|= shft
->value
;
1737 if (unrestrict
&& reg_required_here (&p
, 8) != FAIL
)
1739 inst
.instruction
|= shft
->value
| SHIFT_BY_REG
;
1747 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1750 /* Validate some simple #expressions */
1751 if (! inst
.reloc
.exp
.X_add_symbol
)
1753 int num
= inst
.reloc
.exp
.X_add_number
;
1754 if (num
< 0 || num
> 32
1756 && (shft
->value
== 0 || shft
->value
== 0x60)))
1758 inst
.error
= "Invalid immediate shift";
1762 /* Shifts of zero should be converted to lsl (which is zero)*/
1769 /* Shifts of 32 are encoded as 0, for those shifts that
1774 inst
.instruction
|= (num
<< 7) | shft
->value
;
1779 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
1780 inst
.reloc
.pc_rel
= 0;
1781 inst
.instruction
|= shft
->value
;
1787 inst
.error
= unrestrict
? "shift requires register or #expression"
1788 : "shift requires #expression";
1794 inst
.error
= "Shift expression expected";
1798 /* Do those data_ops which can take a negative immediate constant */
1799 /* by altering the instuction. A bit of a hack really */
1803 by inverting the second operand, and
1806 by negating the second operand.
1809 negate_data_op (instruction
, value
)
1810 unsigned long *instruction
;
1811 unsigned long value
;
1814 unsigned long negated
, inverted
;
1816 negated
= validate_immediate (-value
);
1817 inverted
= validate_immediate (~value
);
1819 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
1823 case OPCODE_SUB
: /* ADD <-> SUB */
1824 new_inst
= OPCODE_ADD
;
1829 new_inst
= OPCODE_SUB
;
1833 case OPCODE_CMP
: /* CMP <-> CMN */
1834 new_inst
= OPCODE_CMN
;
1839 new_inst
= OPCODE_CMP
;
1843 /* Now Inverted ops */
1844 case OPCODE_MOV
: /* MOV <-> MVN */
1845 new_inst
= OPCODE_MVN
;
1850 new_inst
= OPCODE_MOV
;
1854 case OPCODE_AND
: /* AND <-> BIC */
1855 new_inst
= OPCODE_BIC
;
1860 new_inst
= OPCODE_AND
;
1864 case OPCODE_ADC
: /* ADC <-> SBC */
1865 new_inst
= OPCODE_SBC
;
1870 new_inst
= OPCODE_ADC
;
1874 /* We cannot do anything */
1882 *instruction
&= OPCODE_MASK
;
1883 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
1894 while (**str
== ' ')
1897 if (reg_required_here (str
, 0) != FAIL
)
1899 if (skip_past_comma (str
) == SUCCESS
)
1901 /* Shift operation on register */
1902 return decode_shift (str
, NO_SHIFT_RESTRICT
);
1908 /* Immediate expression */
1909 if (*((*str
)++) == '#')
1912 if (my_get_expression (&inst
.reloc
.exp
, str
))
1915 if (inst
.reloc
.exp
.X_add_symbol
)
1917 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
1918 inst
.reloc
.pc_rel
= 0;
1922 if (skip_past_comma (str
) == SUCCESS
)
1924 /* #x, y -- ie explicit rotation by Y */
1925 if (my_get_expression (&expr
, str
))
1928 if (expr
.X_op
!= O_constant
)
1930 inst
.error
= "Constant expression expected";
1934 /* Rotate must be a multiple of 2 */
1935 if (((unsigned) expr
.X_add_number
) > 30
1936 || (expr
.X_add_number
& 1) != 0
1937 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
1939 inst
.error
= "Invalid constant";
1942 inst
.instruction
|= INST_IMMEDIATE
;
1943 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
1944 inst
.instruction
|= expr
.X_add_number
<< 7;
1948 /* Implicit rotation, select a suitable one */
1949 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
1953 /* Can't be done, perhaps the code reads something like
1954 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
1955 if ((value
= negate_data_op (&inst
.instruction
,
1956 inst
.reloc
.exp
.X_add_number
))
1959 inst
.error
= "Invalid constant";
1964 inst
.instruction
|= value
;
1967 inst
.instruction
|= INST_IMMEDIATE
;
1971 inst
.error
= "Register or shift expression expected";
1979 unsigned long flags
;
1981 while (**str
== ' ')
1984 if (fp_reg_required_here (str
, 0) != FAIL
)
1988 /* Immediate expression */
1989 if (*((*str
)++) == '#')
1994 while (**str
== ' ')
1997 /* First try and match exact strings, this is to guarantee that
1998 some formats will work even for cross assembly */
2000 for (i
= 0; fp_const
[i
]; i
++)
2002 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2006 *str
+= strlen (fp_const
[i
]);
2007 if (is_end_of_line
[(int)**str
] || **str
== '\0')
2009 inst
.instruction
|= i
+ 8;
2016 /* Just because we didn't get a match doesn't mean that the
2017 constant isn't valid, just that it is in a format that we
2018 don't automatically recognize. Try parsing it with
2019 the standard expression routines. */
2020 if ((i
= my_get_float_expression (str
)) >= 0)
2022 inst
.instruction
|= i
+ 8;
2026 inst
.error
= "Invalid floating point immediate expression";
2029 inst
.error
= "Floating point register or immediate expression expected";
2035 do_arit (str
, flags
)
2037 unsigned long flags
;
2042 if (reg_required_here (&str
, 12) == FAIL
2043 || skip_past_comma (&str
) == FAIL
2044 || reg_required_here (&str
, 16) == FAIL
2045 || skip_past_comma (&str
) == FAIL
2046 || data_op2 (&str
) == FAIL
)
2049 inst
.error
= bad_args
;
2053 inst
.instruction
|= flags
;
2061 unsigned long flags
;
2063 /* This is a pseudo-op of the form "adr rd, label" to be converted into
2064 a relative address of the form add rd, pc, #label-.-8 */
2069 if (reg_required_here (&str
, 12) == FAIL
2070 || skip_past_comma (&str
) == FAIL
2071 || my_get_expression (&inst
.reloc
.exp
, &str
))
2074 inst
.error
= bad_args
;
2077 /* Frag hacking will turn this into a sub instruction if the offset turns
2078 out to be negative. */
2079 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2080 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2081 inst
.reloc
.pc_rel
= 1;
2082 inst
.instruction
|= flags
;
2090 unsigned long flags
;
2095 if (reg_required_here (&str
, 16) == FAIL
)
2098 inst
.error
= bad_args
;
2102 if (skip_past_comma (&str
) == FAIL
2103 || data_op2 (&str
) == FAIL
)
2106 inst
.error
= bad_args
;
2110 inst
.instruction
|= flags
;
2111 if ((flags
& 0x0000f000) == 0)
2112 inst
.instruction
|= 0x00100000;
2121 unsigned long flags
;
2126 if (reg_required_here (&str
, 12) == FAIL
)
2129 inst
.error
= bad_args
;
2133 if (skip_past_comma (&str
) == FAIL
2134 || data_op2 (&str
) == FAIL
)
2137 inst
.error
= bad_args
;
2141 inst
.instruction
|= flags
;
2147 ldst_extend (str
, hwse
)
2157 if (my_get_expression (&inst
.reloc
.exp
, str
))
2160 if (inst
.reloc
.exp
.X_op
== O_constant
)
2162 int value
= inst
.reloc
.exp
.X_add_number
;
2164 if ((hwse
&& (value
< -255 || value
> 255))
2165 || (value
< -4095 || value
> 4095))
2167 inst
.error
= "address offset too large";
2177 /* Halfword and signextension instructions have the
2178 immediate value split across bits 11..8 and bits 3..0 */
2180 inst
.instruction
|= add
| HWOFFSET_IMM
| (value
>> 4) << 8 | value
& 0xF;
2182 inst
.instruction
|= add
| value
;
2188 inst
.instruction
|= HWOFFSET_IMM
;
2189 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2192 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2193 inst
.reloc
.pc_rel
= 0;
2198 add
= 0; /* and fall through */
2200 (*str
)++; /* and fall through */
2202 if (reg_required_here (str
, 0) == FAIL
)
2204 inst
.error
= "Register expected";
2209 inst
.instruction
|= add
;
2211 inst
.instruction
|= add
| OFFSET_REG
;
2213 /* Shifts are not allowed in the halfword and signextension
2214 forms of single memory transfers: */
2215 if (!hwse
&& skip_past_comma (str
) == SUCCESS
)
2216 return decode_shift (str
, SHIFT_RESTRICT
);
2222 do_ldst (str
, flags
)
2224 unsigned long flags
;
2232 /* This is not ideal, but it is the simplest way of dealing with the
2233 ARM7T extension instructions (since they use a different
2234 encoding, but the same mnemonic): */
2235 halfword
= flags
& 0x00000020;
2236 signextend
= flags
& 0x00000040;
2237 if (halfword
|| signextend
)
2239 /* This is actually a load/store of a halfword, or a
2240 signed-extension load */
2241 inst
.instruction
= (inst
.instruction
& COND_MASK
)
2243 | (inst
.instruction
& 0x00100000);
2244 if (signextend
&& !(inst
.instruction
& 0x00100000))
2246 inst
.error
= "Sign-extension not applicable to store instructions";
2254 if ((conflict_reg
= reg_required_here (&str
, 12)) == FAIL
)
2257 inst
.error
= bad_args
;
2261 if (skip_past_comma (&str
) == FAIL
)
2263 inst
.error
= "Address expected";
2275 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2277 inst
.error
= "Register required";
2281 conflict_reg
= (((conflict_reg
== reg
)
2282 && (inst
.instruction
& 0x00100000))
2291 if (skip_past_comma (&str
) == SUCCESS
)
2293 /* [Rn],... (post inc) */
2294 if (ldst_extend (&str
, halfword
| signextend
) == FAIL
)
2297 as_warn ("destination register same as write-back base\n");
2302 if (halfword
| signextend
)
2303 inst
.instruction
|= HWOFFSET_IMM
;
2311 as_warn ("destination register same as write-back base\n");
2313 inst
.instruction
|= WRITE_BACK
;
2317 if (! (flags
& TRANS_BIT
))
2324 if (skip_past_comma (&str
) == FAIL
)
2326 inst
.error
= "pre-indexed expression expected";
2331 if (ldst_extend (&str
, halfword
| signextend
) == FAIL
)
2339 inst
.error
= "missing ]";
2349 as_warn ("destination register same as write-back base\n");
2351 inst
.instruction
|= WRITE_BACK
;
2355 else if (*str
== '=')
2357 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2363 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2366 if (inst
.reloc
.exp
.X_op
!= O_constant
2367 && inst
.reloc
.exp
.X_op
!= O_symbol
)
2369 inst
.error
= "Constant expression expected";
2373 if (inst
.reloc
.exp
.X_op
== O_constant
2374 && (value
= validate_immediate(inst
.reloc
.exp
.X_add_number
)) != FAIL
)
2376 /* This can be done with a mov instruction */
2377 inst
.instruction
&= LITERAL_MASK
;
2378 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
2379 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
2385 /* Insert into literal pool */
2386 if (add_to_lit_pool () == FAIL
)
2389 inst
.error
= "literal pool insertion failed\n";
2393 /* Change the instruction exp to point to the pool */
2394 if (halfword
|| signextend
)
2396 inst
.instruction
|= HWOFFSET_IMM
;
2397 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
2400 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
2401 inst
.reloc
.pc_rel
= 1;
2402 inst
.instruction
|= (REG_PC
<< 16);
2408 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2411 if (halfword
|| signextend
)
2413 inst
.instruction
|= HWOFFSET_IMM
;
2414 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2417 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2418 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
2419 inst
.reloc
.pc_rel
= 1;
2420 inst
.instruction
|= (REG_PC
<< 16);
2424 if (pre_inc
&& (flags
& TRANS_BIT
))
2425 inst
.error
= "Pre-increment instruction with translate";
2427 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
2433 do_ldmstm (str
, flags
)
2435 unsigned long flags
;
2442 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
2445 inst
.error
= bad_args
;
2449 if (base_reg
== REG_PC
)
2451 inst
.error
= "r15 not allowed as base register";
2459 flags
|= WRITE_BACK
;
2463 if (skip_past_comma (&str
) == FAIL
)
2465 inst
.error
= bad_args
;
2469 /* We come back here if we get ranges concatenated by '+' or '|' */
2484 if ((reg
= arm_reg_parse (&str
)) == FAIL
|| !int_register (reg
))
2486 inst
.error
= "Register expected";
2496 inst
.error
= "Bad range in register list";
2500 for (i
= cur_reg
+ 1; i
< reg
; i
++)
2502 if (flags
& (1 << i
))
2504 ("Warning: Duplicated register (r%d) in register list",
2512 if (flags
& (1 << reg
))
2513 as_tsktsk ("Warning: Duplicated register (r%d) in register list",
2515 else if (reg
<= cur_reg
)
2516 as_tsktsk ("Warning: Register range not in ascending order");
2520 } while (skip_past_comma (&str
) != FAIL
2521 || (in_range
= 1, *str
++ == '-'));
2528 inst
.error
= "Missing `}'";
2536 if (my_get_expression (&expr
, &str
))
2539 if (expr
.X_op
== O_constant
)
2541 if (expr
.X_add_number
2542 != (expr
.X_add_number
& 0x0000ffff))
2544 inst
.error
= "invalid register mask";
2548 if ((flags
& expr
.X_add_number
) != 0)
2550 int regno
= flags
& expr
.X_add_number
;
2553 regno
= (1 << regno
) - 1;
2554 as_tsktsk ("Warning: Duplicated register (r%d) in register list",
2558 flags
|= expr
.X_add_number
;
2562 if (inst
.reloc
.type
!= 0)
2564 inst
.error
= "expression too complex";
2568 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
2569 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
2570 inst
.reloc
.pc_rel
= 0;
2577 if (*str
== '|' || *str
== '+')
2586 flags
|= MULTI_SET_PSR
;
2588 inst
.instruction
|= flags
;
2596 unsigned long flags
;
2598 /* Allow optional leading '#'. */
2604 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2607 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
2608 inst
.reloc
.pc_rel
= 0;
2609 inst
.instruction
|= flags
;
2615 do_swap (str
, flags
)
2617 unsigned long flags
;
2624 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
2629 inst
.error
= "r15 not allowed in swap";
2633 if (skip_past_comma (&str
) == FAIL
2634 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
2637 inst
.error
= bad_args
;
2643 inst
.error
= "r15 not allowed in swap";
2647 if (skip_past_comma (&str
) == FAIL
2650 inst
.error
= bad_args
;
2657 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2662 inst
.error
= bad_pc
;
2671 inst
.error
= "missing ]";
2675 inst
.instruction
|= flags
;
2681 do_branch (str
, flags
)
2683 unsigned long flags
;
2685 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2687 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
2688 inst
.reloc
.pc_rel
= 1;
2689 inst
.instruction
|= flags
| 0x00fffffe; /* PC-rel adjust */
2697 unsigned long flags
;
2699 /* Co-processor data operation.
2700 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
2704 if (co_proc_number (&str
) == FAIL
)
2707 inst
.error
= bad_args
;
2711 if (skip_past_comma (&str
) == FAIL
2712 || cp_opc_expr (&str
, 20,4) == FAIL
)
2715 inst
.error
= bad_args
;
2719 if (skip_past_comma (&str
) == FAIL
2720 || cp_reg_required_here (&str
, 12) == FAIL
)
2723 inst
.error
= bad_args
;
2727 if (skip_past_comma (&str
) == FAIL
2728 || cp_reg_required_here (&str
, 16) == FAIL
)
2731 inst
.error
= bad_args
;
2735 if (skip_past_comma (&str
) == FAIL
2736 || cp_reg_required_here (&str
, 0) == FAIL
)
2739 inst
.error
= bad_args
;
2743 if (skip_past_comma (&str
) == SUCCESS
)
2745 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
2748 inst
.error
= bad_args
;
2758 do_lstc (str
, flags
)
2760 unsigned long flags
;
2762 /* Co-processor register load/store.
2763 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
2768 if (co_proc_number (&str
) == FAIL
)
2771 inst
.error
= bad_args
;
2775 if (skip_past_comma (&str
) == FAIL
2776 || cp_reg_required_here (&str
, 12) == FAIL
)
2779 inst
.error
= bad_args
;
2783 if (skip_past_comma (&str
) == FAIL
2784 || cp_address_required_here (&str
) == FAIL
)
2787 inst
.error
= bad_args
;
2791 inst
.instruction
|= flags
;
2797 do_co_reg (str
, flags
)
2799 unsigned long flags
;
2801 /* Co-processor register transfer.
2802 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
2807 if (co_proc_number (&str
) == FAIL
)
2810 inst
.error
= bad_args
;
2814 if (skip_past_comma (&str
) == FAIL
2815 || cp_opc_expr (&str
, 21, 3) == FAIL
)
2818 inst
.error
= bad_args
;
2822 if (skip_past_comma (&str
) == FAIL
2823 || reg_required_here (&str
, 12) == FAIL
)
2826 inst
.error
= bad_args
;
2830 if (skip_past_comma (&str
) == FAIL
2831 || cp_reg_required_here (&str
, 16) == FAIL
)
2834 inst
.error
= bad_args
;
2838 if (skip_past_comma (&str
) == FAIL
2839 || cp_reg_required_here (&str
, 0) == FAIL
)
2842 inst
.error
= bad_args
;
2846 if (skip_past_comma (&str
) == SUCCESS
)
2848 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
2851 inst
.error
= bad_args
;
2861 do_fp_ctrl (str
, flags
)
2863 unsigned long flags
;
2865 /* FP control registers.
2866 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
2871 if (reg_required_here (&str
, 12) == FAIL
)
2874 inst
.error
= bad_args
;
2883 do_fp_ldst (str
, flags
)
2885 unsigned long flags
;
2890 switch (inst
.suffix
)
2895 inst
.instruction
|= CP_T_X
;
2898 inst
.instruction
|= CP_T_Y
;
2901 inst
.instruction
|= CP_T_X
| CP_T_Y
;
2907 if (fp_reg_required_here (&str
, 12) == FAIL
)
2910 inst
.error
= bad_args
;
2914 if (skip_past_comma (&str
) == FAIL
2915 || cp_address_required_here (&str
) == FAIL
)
2918 inst
.error
= bad_args
;
2926 do_fp_ldmstm (str
, flags
)
2928 unsigned long flags
;
2935 if (fp_reg_required_here (&str
, 12) == FAIL
)
2938 inst
.error
= bad_args
;
2942 /* Get Number of registers to transfer */
2943 if (skip_past_comma (&str
) == FAIL
2944 || my_get_expression (&inst
.reloc
.exp
, &str
))
2947 inst
.error
= "constant expression expected";
2951 if (inst
.reloc
.exp
.X_op
!= O_constant
)
2953 inst
.error
= "Constant value required for number of registers";
2957 num_regs
= inst
.reloc
.exp
.X_add_number
;
2959 if (num_regs
< 1 || num_regs
> 4)
2961 inst
.error
= "number of registers must be in the range [1:4]";
2968 inst
.instruction
|= CP_T_X
;
2971 inst
.instruction
|= CP_T_Y
;
2974 inst
.instruction
|= CP_T_Y
| CP_T_X
;
2988 /* The instruction specified "ea" or "fd", so we can only accept
2989 [Rn]{!}. The instruction does not really support stacking or
2990 unstacking, so we have to emulate these by setting appropriate
2991 bits and offsets. */
2992 if (skip_past_comma (&str
) == FAIL
2996 inst
.error
= bad_args
;
3004 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3006 inst
.error
= "Register required";
3015 inst
.error
= bad_args
;
3026 inst
.error
= "R15 not allowed as base register with write-back";
3033 if (flags
& CP_T_Pre
)
3036 offset
= 3 * num_regs
;
3042 /* Post-increment */
3046 offset
= 3 * num_regs
;
3050 /* No write-back, so convert this into a standard pre-increment
3051 instruction -- aesthetically more pleasing. */
3052 flags
= CP_T_Pre
| CP_T_UD
;
3057 inst
.instruction
|= flags
| offset
;
3059 else if (skip_past_comma (&str
) == FAIL
3060 || cp_address_required_here (&str
) == FAIL
)
3063 inst
.error
= bad_args
;
3071 do_fp_dyadic (str
, flags
)
3073 unsigned long flags
;
3078 switch (inst
.suffix
)
3083 inst
.instruction
|= 0x00000080;
3086 inst
.instruction
|= 0x00080000;
3092 if (fp_reg_required_here (&str
, 12) == FAIL
)
3095 inst
.error
= bad_args
;
3099 if (skip_past_comma (&str
) == FAIL
3100 || fp_reg_required_here (&str
, 16) == FAIL
)
3103 inst
.error
= bad_args
;
3107 if (skip_past_comma (&str
) == FAIL
3108 || fp_op2 (&str
) == FAIL
)
3111 inst
.error
= bad_args
;
3115 inst
.instruction
|= flags
;
3121 do_fp_monadic (str
, flags
)
3123 unsigned long flags
;
3128 switch (inst
.suffix
)
3133 inst
.instruction
|= 0x00000080;
3136 inst
.instruction
|= 0x00080000;
3142 if (fp_reg_required_here (&str
, 12) == FAIL
)
3145 inst
.error
= bad_args
;
3149 if (skip_past_comma (&str
) == FAIL
3150 || fp_op2 (&str
) == FAIL
)
3153 inst
.error
= bad_args
;
3157 inst
.instruction
|= flags
;
3163 do_fp_cmp (str
, flags
)
3165 unsigned long flags
;
3170 if (fp_reg_required_here (&str
, 16) == FAIL
)
3173 inst
.error
= bad_args
;
3177 if (skip_past_comma (&str
) == FAIL
3178 || fp_op2 (&str
) == FAIL
)
3181 inst
.error
= bad_args
;
3185 inst
.instruction
|= flags
;
3191 do_fp_from_reg (str
, flags
)
3193 unsigned long flags
;
3198 switch (inst
.suffix
)
3203 inst
.instruction
|= 0x00000080;
3206 inst
.instruction
|= 0x00080000;
3212 if (fp_reg_required_here (&str
, 16) == FAIL
)
3215 inst
.error
= bad_args
;
3219 if (skip_past_comma (&str
) == FAIL
3220 || reg_required_here (&str
, 12) == FAIL
)
3223 inst
.error
= bad_args
;
3227 inst
.instruction
|= flags
;
3233 do_fp_to_reg (str
, flags
)
3235 unsigned long flags
;
3240 if (reg_required_here (&str
, 12) == FAIL
)
3243 inst
.error
= bad_args
;
3247 if (skip_past_comma (&str
) == FAIL
3248 || fp_reg_required_here (&str
, 0) == FAIL
)
3251 inst
.error
= bad_args
;
3255 inst
.instruction
|= flags
;
3264 int len
= strlen (reg_table
[entry
].name
) + 2;
3265 char *buf
= (char *) xmalloc (len
);
3266 char *buf2
= (char *) xmalloc (len
);
3269 #ifdef REGISTER_PREFIX
3270 buf
[i
++] = REGISTER_PREFIX
;
3273 strcpy (buf
+ i
, reg_table
[entry
].name
);
3275 for (i
= 0; buf
[i
]; i
++)
3276 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
3280 hash_insert (arm_reg_hsh
, buf
, (PTR
) ®_table
[entry
]);
3281 hash_insert (arm_reg_hsh
, buf2
, (PTR
) ®_table
[entry
]);
3285 insert_reg_alias (str
, regnum
)
3289 struct reg_entry
*new =
3290 (struct reg_entry
*)xmalloc (sizeof (struct reg_entry
));
3291 char *name
= xmalloc (strlen (str
) + 1);
3295 new->number
= regnum
;
3297 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
3301 set_constant_flonums ()
3305 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
3306 if (atof_ieee ((char *)fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
3315 if ((arm_ops_hsh
= hash_new ()) == NULL
3316 || (arm_cond_hsh
= hash_new ()) == NULL
3317 || (arm_shift_hsh
= hash_new ()) == NULL
3318 || (arm_reg_hsh
= hash_new ()) == NULL
3319 || (arm_psr_hsh
= hash_new ()) == NULL
)
3320 as_fatal ("Virtual memory exhausted");
3322 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
3323 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
3324 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
3325 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
3326 for (i
= 0; i
< sizeof (shift
) / sizeof (struct asm_shift
); i
++)
3327 hash_insert (arm_shift_hsh
, shift
[i
].template, (PTR
) (shift
+ i
));
3328 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
3329 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
3331 for (i
= 0; reg_table
[i
].name
; i
++)
3334 set_constant_flonums ();
3337 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
3338 for use in the a.out file, and stores them in the array pointed to by buf.
3339 This knows about the endian-ness of the target machine and does
3340 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
3341 2 (short) and 4 (long) Floating numbers are put out as a series of
3342 LITTLENUMS (shorts, here at least)
3345 md_number_to_chars (buf
, val
, n
)
3350 if (target_big_endian
)
3351 number_to_chars_bigendian (buf
, val
, n
);
3353 number_to_chars_littleendian (buf
, val
, n
);
3357 md_chars_to_number (buf
, n
)
3362 unsigned char *where
= (unsigned char *) buf
;
3364 if (target_big_endian
)
3369 result
|= (*where
++ & 255);
3377 result
|= (where
[n
] & 255);
3384 /* Turn a string in input_line_pointer into a floating point constant
3385 of type TYPE, and store the appropriate bytes in *litP. The number
3386 of LITTLENUMS emitted is stored in *sizeP . An error message is
3387 returned, or NULL on OK.
3389 Note that fp constants aren't represent in the normal way on the ARM.
3390 In big endian mode, things are as expected. However, in little endian
3391 mode fp constants are big-endian word-wise, and little-endian byte-wise
3392 within the words. For example, (double) 1.1 in big endian mode is
3393 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
3394 the byte sequence 99 99 f1 3f 9a 99 99 99.
3396 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
3399 md_atof (type
, litP
, sizeP
)
3405 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
3437 return "Bad call to MD_ATOF()";
3440 t
= atof_ieee (input_line_pointer
, type
, words
);
3442 input_line_pointer
= t
;
3445 if (target_big_endian
)
3447 for (i
= 0; i
< prec
; i
++)
3449 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
3455 /* For a 4 byte float the order of elements in `words' is 1 0. For an
3456 8 byte float the order is 1 0 3 2. */
3457 for (i
= 0; i
< prec
; i
+= 2)
3459 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
3460 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
3468 /* We have already put the pipeline compensation in the instruction */
3471 md_pcrel_from (fixP
)
3474 if (fixP
->fx_addsy
&& S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
3475 && fixP
->fx_subsy
== NULL
)
3476 return 0; /* HACK */
3478 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
3481 /* Round up a section size to the appropriate boundary. */
3483 md_section_align (segment
, size
)
3487 /* Round all sects to multiple of 4 */
3488 return (size
+ 3) & ~3;
3491 /* We have no need to default values of symbols. */
3495 md_undefined_symbol (name
)
3501 /* arm_reg_parse () := if it looks like a register, return its token and
3502 advance the pointer. */
3506 register char **ccp
;
3511 struct reg_entry
*reg
;
3513 #ifdef REGISTER_PREFIX
3514 if (*start
!= REGISTER_PREFIX
)
3519 #ifdef OPTIONAL_REGISTER_PREFIX
3520 if (*p
== OPTIONAL_REGISTER_PREFIX
)
3524 if (!isalpha (*p
) || !is_name_beginner (*p
))
3528 while (isalpha (c
) || isdigit (c
) || c
== '_')
3532 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
3546 register char **ccp
;
3550 CONST
struct asm_psr
*psr
;
3554 while (isalpha (c
) || c
== '_')
3558 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
3571 md_apply_fix3 (fixP
, val
, seg
)
3576 offsetT value
= *val
;
3577 offsetT newval
, temp
;
3579 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
3581 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
3583 /* Note whether this will delete the relocation. */
3584 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
3587 /* If this symbol is in a different section then we need to leave it for
3588 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
3589 so we have to undo it's effects here. */
3592 if (S_IS_DEFINED (fixP
->fx_addsy
)
3593 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
3594 value
+= md_pcrel_from (fixP
);
3597 fixP
->fx_addnumber
= value
; /* Remember value for emit_reloc */
3599 switch (fixP
->fx_r_type
)
3601 case BFD_RELOC_ARM_IMMEDIATE
:
3602 newval
= validate_immediate (value
);
3603 temp
= md_chars_to_number (buf
, insn_size
);
3605 /* If the instruction will fail, see if we can fix things up by
3606 changing the opcode. */
3608 && (newval
= negate_data_op (&temp
, value
)) == FAIL
)
3610 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3611 "invalid constant after fixup\n");
3615 newval
|= (temp
& 0xfffff000);
3616 md_number_to_chars (buf
, newval
, insn_size
);
3619 case BFD_RELOC_ARM_OFFSET_IMM
:
3621 if ((value
= validate_offset_imm (value
, 0)) == FAIL
)
3623 as_bad ("bad immediate value for offset (%d)", val
);
3629 newval
= md_chars_to_number (buf
, insn_size
);
3630 newval
&= 0xff7ff000;
3631 newval
|= value
| (sign
? 0x00800000 : 0);
3632 md_number_to_chars (buf
, newval
, insn_size
);
3635 case BFD_RELOC_ARM_OFFSET_IMM8
:
3636 case BFD_RELOC_ARM_HWLITERAL
:
3638 if ((value
= validate_offset_imm (value
, 1)) == FAIL
)
3640 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
3641 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3642 "invalid literal constant: pool needs to be closer\n");
3644 as_bad ("bad immediate value for offset (%d)", value
);
3651 newval
= md_chars_to_number (buf
, insn_size
);
3652 newval
&= 0xff7ff0f0;
3653 newval
|= ((value
>> 4) << 8) | value
& 0xf | (sign
? 0x00800000 : 0);
3654 md_number_to_chars (buf
, newval
, insn_size
);
3657 case BFD_RELOC_ARM_LITERAL
:
3662 if ((value
= validate_offset_imm (value
, 0)) == FAIL
)
3664 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3665 "invalid literal constant: pool needs to be closer\n");
3669 newval
= md_chars_to_number (buf
, insn_size
);
3670 newval
&= 0xff7ff000;
3671 newval
|= value
| (sign
? 0x00800000 : 0);
3672 md_number_to_chars (buf
, newval
, insn_size
);
3675 case BFD_RELOC_ARM_SHIFT_IMM
:
3676 newval
= md_chars_to_number (buf
, insn_size
);
3677 if (((unsigned long) value
) > 32
3679 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
3681 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3682 "shift expression is too large");
3687 newval
&= ~0x60; /* Shifts of zero must be done as lsl */
3688 else if (value
== 32)
3690 newval
&= 0xfffff07f;
3691 newval
|= (value
& 0x1f) << 7;
3692 md_number_to_chars (buf
, newval
, insn_size
);
3695 case BFD_RELOC_ARM_SWI
:
3696 if (((unsigned long) value
) > 0x00ffffff)
3697 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "Invalid swi expression");
3698 newval
= md_chars_to_number (buf
, insn_size
) & 0xff000000;
3700 md_number_to_chars (buf
, newval
, insn_size
);
3703 case BFD_RELOC_ARM_MULTI
:
3704 if (((unsigned long) value
) > 0xffff)
3705 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3706 "Invalid expression in load/store multiple");
3707 newval
= value
| md_chars_to_number (buf
, insn_size
);
3708 md_number_to_chars (buf
, newval
, insn_size
);
3711 case BFD_RELOC_ARM_PCREL_BRANCH
:
3712 value
= (value
>> 2) & 0x00ffffff;
3713 newval
= md_chars_to_number (buf
, insn_size
);
3714 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
3715 newval
= value
| (newval
& 0xff000000);
3716 md_number_to_chars (buf
, newval
, insn_size
);
3720 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
3721 md_number_to_chars (buf
, value
, 1);
3725 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
3726 md_number_to_chars (buf
, value
, 2);
3731 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
3732 md_number_to_chars (buf
, value
, 4);
3735 case BFD_RELOC_ARM_CP_OFF_IMM
:
3737 if (value
< -1023 || value
> 1023 || (value
& 3))
3738 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3739 "Illegal value for co-processor offset");
3742 newval
= md_chars_to_number (buf
, insn_size
) & 0xff7fff00;
3743 newval
|= (value
>> 2) | (sign
? 0x00800000 : 0);
3744 md_number_to_chars (buf
, newval
, insn_size
);
3747 case BFD_RELOC_NONE
:
3749 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3750 "Bad relocation fixup type (%d)\n", fixP
->fx_r_type
);
3756 /* Translate internal representation of relocation info to BFD target
3759 tc_gen_reloc (section
, fixp
)
3764 bfd_reloc_code_real_type code
;
3766 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
3767 assert (reloc
!= 0);
3769 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
3770 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3772 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
3773 if (fixp
->fx_pcrel
== 0)
3774 reloc
->addend
= fixp
->fx_offset
;
3776 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
3778 switch (fixp
->fx_r_type
)
3783 code
= BFD_RELOC_8_PCREL
;
3790 code
= BFD_RELOC_16_PCREL
;
3797 code
= BFD_RELOC_32_PCREL
;
3801 case BFD_RELOC_ARM_PCREL_BRANCH
:
3803 code
= fixp
->fx_r_type
;
3806 case BFD_RELOC_ARM_LITERAL
:
3807 case BFD_RELOC_ARM_HWLITERAL
:
3808 /* If this is called then the a literal has been referenced across
3809 a section boundry - possibly due to an implicit dump */
3810 as_bad ("Literal referenced across section boundry (Implicit dump?)");
3813 case BFD_RELOC_ARM_IMMEDIATE
:
3814 as_bad ("Internal_relocation (type %d) not fixed up (IMMEDIATE)"
3818 case BFD_RELOC_ARM_OFFSET_IMM
:
3819 as_bad ("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"
3823 case BFD_RELOC_ARM_OFFSET_IMM8
:
3824 as_bad ("Internal_relocation (type %d) not fixed up (OFFSET_IMM8)"
3828 case BFD_RELOC_ARM_SHIFT_IMM
:
3829 as_bad ("Internal_relocation (type %d) not fixed up (SHIFT_IMM)"
3833 case BFD_RELOC_ARM_SWI
:
3834 as_bad ("Internal_relocation (type %d) not fixed up (SWI)"
3838 case BFD_RELOC_ARM_MULTI
:
3839 as_bad ("Internal_relocation (type %d) not fixed up (MULTI)"
3843 case BFD_RELOC_ARM_CP_OFF_IMM
:
3844 as_bad ("Internal_relocation (type %d) not fixed up (CP_OFF_IMM)"
3852 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
3853 assert (reloc
->howto
!= 0);
3858 CONST
int md_short_jump_size
= 4;
3859 CONST
int md_long_jump_size
= 4;
3861 /* These should never be called on the arm */
3863 md_create_long_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
3865 addressT from_addr
, to_addr
;
3869 as_fatal ("md_create_long_jump\n");
3873 md_create_short_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
3875 addressT from_addr
, to_addr
;
3879 as_fatal ("md_create_short_jump\n");
3883 md_estimate_size_before_relax (fragP
, segtype
)
3887 as_fatal ("md_estimate_size_before_relax\n");
3899 as_bad ("%s -- statement `%s'\n", inst
.error
, str
);
3903 to
= frag_more (insn_size
);
3904 md_number_to_chars (to
, inst
.instruction
, insn_size
);
3906 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
3907 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
3908 4, &inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
3919 CONST
struct asm_opcode
*opcode
;
3920 char *p
, *q
, *start
;
3922 /* Align the instruction */
3923 /* this may not be the right thing to do but ... */
3924 /* arm_align (2, 0); */
3925 listing_prev_line (); /* Defined in listing.h */
3927 /* Align the previous label if needed */
3928 if (last_label_seen
!= NULL
)
3930 last_label_seen
->sy_frag
= frag_now
;
3931 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
3932 S_SET_SEGMENT (last_label_seen
, now_seg
);
3935 memset (&inst
, '\0', sizeof (inst
));
3936 inst
.reloc
.type
= BFD_RELOC_NONE
;
3939 str
++; /* Skip leading white space */
3941 /* scan up to the end of the op-code, which must end in white space or
3943 for (start
= p
= str
; *p
!= '\0'; p
++)
3949 as_bad ("No operator -- statement `%s'\n", str
);
3953 /* p now points to the end of the opcode, probably white space, but we have
3954 to break the opcode up in case it contains condionals and flags;
3955 keep trying with progressively smaller basic instructions until one
3956 matches, or we run out of opcode. */
3957 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
3958 for (; q
!= str
; q
--)
3962 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
3964 if (opcode
&& opcode
->template)
3966 unsigned long flag_bits
= 0;
3969 /* Check that this instruction is supported for this CPU */
3970 if ((opcode
->variants
& cpu_variant
) == 0)
3973 inst
.instruction
= opcode
->value
;
3974 if (q
== p
) /* Just a simple opcode */
3976 if (opcode
->comp_suffix
!= 0)
3977 as_bad ("Opcode `%s' must have suffix from <%s>\n", str
,
3978 opcode
->comp_suffix
);
3981 inst
.instruction
|= COND_ALWAYS
;
3982 (*opcode
->parms
)(q
, 0);
3984 output_inst (start
);
3988 /* Now check for a conditional */
3992 CONST
struct asm_cond
*cond
;
3996 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
4000 if (cond
->value
== 0xf0000000)
4002 ("Warning: Use of the 'nv' conditional is deprecated\n");
4004 inst
.instruction
|= cond
->value
;
4008 inst
.instruction
|= COND_ALWAYS
;
4011 inst
.instruction
|= COND_ALWAYS
;
4013 /* if there is a compulsory suffix, it should come here, before
4014 any optional flags. */
4015 if (opcode
->comp_suffix
)
4017 CONST
char *s
= opcode
->comp_suffix
;
4029 as_bad ("Opcode `%s' must have suffix from <%s>\n", str
,
4030 opcode
->comp_suffix
);
4037 /* The remainder, if any should now be flags for the instruction;
4038 Scan these checking each one found with the opcode. */
4042 CONST
struct asm_flg
*flag
= opcode
->flags
;
4051 for (flagno
= 0; flag
[flagno
].template; flagno
++)
4053 if ((flag
[flagno
].variants
& cpu_variant
) != 0
4054 && (! strcmp (r
, flag
[flagno
].template)))
4056 flag_bits
|= flag
[flagno
].set_bits
;
4062 if (! flag
[flagno
].template)
4069 (*opcode
->parms
) (p
, flag_bits
);
4070 output_inst (start
);
4077 /* It wasn't an instruction, but it might be a register alias of the form
4087 if (*q
&& !strncmp (q
, ".req ", 4))
4090 if ((reg
= arm_reg_parse (&str
)) == FAIL
)
4098 for (r
= q
; *r
!= '\0'; r
++)
4108 regnum
= arm_reg_parse (&q
);
4112 insert_reg_alias (str
, regnum
);
4126 as_bad ("bad instruction `%s'", start
);
4131 * Invocation line includes a switch not recognized by the base assembler.
4132 * See if it's a processor-specific option. These are:
4133 * Cpu variants, the arm part is optional:
4134 * -m[arm]1 Currently not supported.
4135 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
4136 * -m[arm]3 Arm 3 processor
4137 * -m[arm]6, Arm 6 processors
4138 * -m[arm]7[t][[d]m] Arm 7 processors
4139 * -mall All (except the ARM1)
4141 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
4142 * -mfpe-old (No float load/store multiples)
4143 * -mno-fpu Disable all floating point instructions
4144 * Run-time endian selection:
4145 * -EB big endian cpu
4146 * -EL little endian cpu
4149 CONST
char *md_shortopts
= "m:";
4150 struct option md_longopts
[] = {
4151 #ifdef ARM_BI_ENDIAN
4152 #define OPTION_EB (OPTION_MD_BASE + 0)
4153 {"EB", no_argument
, NULL
, OPTION_EB
},
4154 #define OPTION_EL (OPTION_MD_BASE + 1)
4155 {"EL", no_argument
, NULL
, OPTION_EL
},
4157 {NULL
, no_argument
, NULL
, 0}
4159 size_t md_longopts_size
= sizeof(md_longopts
);
4162 md_parse_option (c
, arg
)
4170 #ifdef ARM_BI_ENDIAN
4172 target_big_endian
= 1;
4175 target_big_endian
= 0;
4183 if (! strcmp (str
, "fpa10"))
4184 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
4185 else if (! strcmp (str
, "fpa11"))
4186 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
4187 else if (! strcmp (str
, "fpe-old"))
4188 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
4194 if (! strcmp (str
, "no-fpu"))
4195 cpu_variant
&= ~FPU_ALL
;
4199 if (! strcmp (str
, "all"))
4201 cpu_variant
= ARM_ALL
| FPU_ALL
;
4205 /* Strip off optional "arm" */
4206 if (! strncmp (str
, "arm", 3))
4212 if (! strcmp (str
, "1"))
4213 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
4219 if (! strcmp (str
, "2"))
4220 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
4221 else if (! strcmp (str
, "250"))
4222 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
4228 if (! strcmp (str
, "3"))
4229 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
4235 if (! strcmp (str
, "6"))
4236 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
4242 str
++; /* eat the '7' */
4243 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
4249 cpu_variant
|= ARM_HALFWORD
;
4253 cpu_variant
|= ARM_LONGMUL
;
4256 case 'd': /* debug */
4257 case 'i': /* embedded ice */
4258 /* Included for completeness in ARM processor
4270 as_bad ("Invalid architecture -m%s", arg
);
4288 "-m[arm]1, -m[arm]2, -m[arm]250,\n-m[arm]3, -m[arm]6, -m[arm]7[t][[d]m]\n\
4289 \t\t\tselect processor architecture\n\
4290 -mall\t\t\tallow any instruction\n\
4291 -mfpa10, -mfpa11\tselect floating point architecture\n\
4292 -mfpe-old\t\tdon't allow floating-point multiple instructions\n\
4293 -mno-fpu\t\tdon't allow any floating-point instructions.\n");
4294 #ifdef ARM_BI_ENDIAN
4296 "-EB\t\t\tassemble code for a big endian cpu\n\
4297 -EL\t\t\tassemble code for a little endian cpu\n");
4301 /* We need to be able to fix up arbitrary expressions in some statements.
4302 This is so that we can handle symbols that are an arbitrary distance from
4303 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
4304 which returns part of an address in a form which will be valid for
4305 a data instruction. We do this by pushing the expression into a symbol
4306 in the expr_section, and creating a fix for that. */
4309 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
4325 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
4333 /* FIXME: This should be something which decode_local_label_name
4335 fake
= FAKE_LABEL_NAME
;
4337 /* Putting constant symbols in absolute_section rather than
4338 expr_section is convenient for the old a.out code, for which
4339 S_GET_SEGMENT does not always retrieve the value put in by
4341 symbolP
= symbol_new (fake
, expr_section
, 0, &zero_address_frag
);
4342 symbolP
->sy_value
= *exp
;
4343 new_fix
= fix_new (frag
, where
, size
, symbolP
, 0, pc_rel
, reloc
);
4351 /* A good place to do this, although this was probably not intended
4352 * for this kind of use. We need to dump the literal pool before
4353 * references are made to a null symbol pointer. */
4355 arm_after_pass_hook (ignore
)
4358 if (current_poolP
!= NULL
)
4360 subseg_set (text_section
, 0); /* Put it at the end of text section */
4362 listing_prev_line ();
4367 arm_start_line_hook ()
4369 last_label_seen
= NULL
;
4373 arm_frob_label (sym
)
4376 last_label_seen
= sym
;