* config/tc-sh.c (md_convert_frag): Improve warning when branch is
[deliverable/binutils-gdb.git] / gas / config / tc-arm.c
CommitLineData
338a7060
DE
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)
5
6 Copyright (C) 1994, 1995 Free Software Foundation, Inc.
7
8 This file is part of GAS, the GNU Assembler.
9
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)
13 any later version.
14
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.
19
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. */
23
24#include <ctype.h>
25#include <string.h>
26#define NO_RELOC 0
27#include "as.h"
28
29/* need TARGET_CPU */
30#include "config.h"
31#include "subsegs.h"
32#include "obstack.h"
33#include "symbols.h"
34#include "listing.h"
35
36/* ??? This is currently unused. */
37#ifdef __STDC__
38#define internalError() \
39 as_fatal ("ARM Internal Error, line %d, %s", __LINE__, __FILE__)
40#else
41#define internalError() as_fatal ("ARM Internal Error")
42#endif
43
44/* Types of processor to assemble for. */
45#define ARM_1 0x00000001
46#define ARM_2 0x00000002
338a7060 47#define ARM_3 0x00000004
c479fc62 48#define ARM_250 0x00000004 /* ARM3 instruction set */
338a7060
DE
49#define ARM_6 0x00000008
50#define ARM_7 0x00000008
c479fc62
JSC
51
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 */
338a7060
DE
55
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
c479fc62 61#define ARM_6UP 0x00fffff8 /* Includes ARM7 */
338a7060
DE
62
63#define FPU_CORE 0x80000000
64#define FPU_FPA10 0x40000000
65#define FPU_FPA11 0x40000000
66#define FPU_NONE 0
67
68/* Some useful combinations */
69#define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
70#define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
71
72#ifndef CPU_DEFAULT
73#define CPU_DEFAULT ARM_ALL
74#endif
75
76#ifndef FPU_DEFAULT
77#define FPU_DEFAULT FPU_ALL
78#endif
79
80unsigned long cpu_variant = CPU_DEFAULT | FPU_DEFAULT;
81
82/* This array holds the chars that always start a comment. If the
83 pre-processor is disabled, these aren't very useful */
84CONST char comment_chars[] = "@";
85
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. */
93CONST char line_comment_chars[] = "#";
94
95CONST char line_separator_chars[] = "";
96
97/* Chars that can be used to separate mant from exp in floating point nums */
98CONST char EXP_CHARS[] = "eE";
99
100/* Chars that mean this number is a floating point constant */
101/* As in 0f12.456 */
102/* or 0d1.2345e12 */
103
104CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP";
105
106const int md_reloc_size = 8; /* Size of relocation record */
107
108struct arm_it
109{
110 CONST char *error;
111 unsigned long instruction;
112 int suffix;
113 struct
114 {
115 bfd_reloc_code_real_type type;
116 expressionS exp;
117 int pc_rel;
118 } reloc;
119};
120
121struct arm_it inst;
122
123struct asm_shift
124{
125 CONST char *template;
126 unsigned long value;
127};
128
129static CONST struct asm_shift shift[] =
130{
131 {"asl", 0},
132 {"lsl", 0},
133 {"lsr", 0x00000020},
134 {"asr", 0x00000040},
135 {"ror", 0x00000060},
136 {"rrx", 0x00000060},
137 {"ASL", 0},
138 {"LSL", 0},
139 {"LSR", 0x00000020},
140 {"ASR", 0x00000040},
141 {"ROR", 0x00000060},
142 {"RRX", 0x00000060}
143};
144
145#define NO_SHIFT_RESTRICT 1
146#define SHIFT_RESTRICT 0
147
148#define NUM_FLOAT_VALS 8
149
150CONST char *fp_const[] =
151{
152 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
153};
154
155/* Number of littlenums required to hold an extended precision number */
156#define MAX_LITTLENUMS 6
157
158LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
159
160#define FAIL (-1)
161#define SUCCESS (0)
162
163#define SUFF_S 1
164#define SUFF_D 2
165#define SUFF_E 3
166#define SUFF_P 4
167
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
173
174#define TRANS_BIT (0x00200000)
175
176struct asm_cond
177{
178 CONST char *template;
179 unsigned long value;
180};
181
182/* This is to save a hash look-up in the common case */
183#define COND_ALWAYS 0xe0000000
184
185static CONST struct asm_cond conds[] =
186{
187 {"eq", 0x00000000},
188 {"ne", 0x10000000},
189 {"cs", 0x20000000}, {"hs", 0x20000000},
190 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
191 {"mi", 0x40000000},
192 {"pl", 0x50000000},
193 {"vs", 0x60000000},
194 {"vc", 0x70000000},
195 {"hi", 0x80000000},
196 {"ls", 0x90000000},
197 {"ge", 0xa0000000},
198 {"lt", 0xb0000000},
199 {"gt", 0xc0000000},
200 {"le", 0xd0000000},
201 {"al", 0xe0000000},
202 {"nv", 0xf0000000}
203};
204
205
206struct asm_flg
207{
208 CONST char *template; /* Basic flag string */
209 unsigned long set_bits; /* Bits to set */
c479fc62 210 unsigned long variants; /* Which CPU variants this exists for */
338a7060
DE
211};
212
213static CONST struct asm_flg s_flag[] =
214{
c479fc62
JSC
215 {"s", 0x00100000, ARM_ANY},
216 {NULL, 0, 0}
338a7060
DE
217};
218
219static CONST struct asm_flg ldst_flags[] =
220{
c479fc62
JSC
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},
227 {NULL, 0, 0},
338a7060
DE
228};
229
230static CONST struct asm_flg byte_flag[] =
231{
c479fc62
JSC
232 {"b", 0x00400000, ARM_3UP},
233 {NULL, 0, 0}
338a7060
DE
234};
235
236static CONST struct asm_flg cmp_flags[] =
237{
c479fc62
JSC
238 {"s", 0x00100000, ARM_ANY},
239 {"p", 0x0010f000, ARM_ANY},
240 {NULL, 0, 0}
338a7060
DE
241};
242
243static CONST struct asm_flg ldm_flags[] =
244{
c479fc62
JSC
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},
253 {NULL, 0, 0}
338a7060
DE
254};
255
256static CONST struct asm_flg stm_flags[] =
257{
c479fc62
JSC
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},
266 {NULL, 0, 0}
338a7060
DE
267};
268
269static CONST struct asm_flg lfm_flags[] =
270{
c479fc62
JSC
271 {"fd", 0x00800000, FPU_MEMMULTI},
272 {"ea", 0x01000000, FPU_MEMMULTI},
273 {NULL, 0, 0}
338a7060
DE
274};
275
276static CONST struct asm_flg sfm_flags[] =
277{
c479fc62
JSC
278 {"fd", 0x01000000, FPU_MEMMULTI},
279 {"ea", 0x00800000, FPU_MEMMULTI},
280 {NULL, 0, 0}
338a7060
DE
281};
282
283static CONST struct asm_flg round_flags[] =
284{
c479fc62
JSC
285 {"p", 0x00000020, FPU_ALL},
286 {"m", 0x00000040, FPU_ALL},
287 {"z", 0x00000060, FPU_ALL},
288 {NULL, 0, 0}
338a7060
DE
289};
290
291static CONST struct asm_flg except_flag[] =
292{
c479fc62
JSC
293 {"e", 0x00400000, FPU_ALL},
294 {NULL, 0, 0}
338a7060
DE
295};
296
297static CONST struct asm_flg cplong_flag[] =
298{
c479fc62
JSC
299 {"l", 0x00400000, ARM_2UP},
300 {NULL, 0, 0}
338a7060
DE
301};
302
303struct asm_psr
304{
305 CONST char *template;
306 unsigned long number;
307};
308
309#define PSR_ALL 0x00010000
310
311static CONST struct asm_psr psrs[] =
312{
313 /* Valid <psr>'s */
314 {"cpsr", 0},
315 {"cpsr_all", 0},
316 {"spsr", 1},
317 {"spsr_all", 1},
318
319 /* Valid <psrf>'s */
320 {"cpsr_flg", 2},
321 {"spsr_flg", 3}
322};
323
324/* Functions called by parser */
325/* ARM instructions */
326static void do_arit PARAMS ((char *operands, unsigned long flags));
327static void do_cmp PARAMS ((char *operands, unsigned long flags));
328static void do_mov PARAMS ((char *operands, unsigned long flags));
329static void do_ldst PARAMS ((char *operands, unsigned long flags));
330static void do_ldmstm PARAMS ((char *operands, unsigned long flags));
331static void do_branch PARAMS ((char *operands, unsigned long flags));
332static void do_swi PARAMS ((char *operands, unsigned long flags));
333/* Pseudo Op codes */
334static void do_adr PARAMS ((char *operands, unsigned long flags));
335static void do_nop PARAMS ((char *operands, unsigned long flags));
336/* ARM 2 */
337static void do_mul PARAMS ((char *operands, unsigned long flags));
338static void do_mla PARAMS ((char *operands, unsigned long flags));
339/* ARM 3 */
340static void do_swap PARAMS ((char *operands, unsigned long flags));
341/* ARM 6 */
342static void do_msr PARAMS ((char *operands, unsigned long flags));
343static void do_mrs PARAMS ((char *operands, unsigned long flags));
c479fc62 344/* ARM 7M */
338a7060 345static void do_mull PARAMS ((char *operands, unsigned long flags));
c479fc62 346
338a7060
DE
347/* Coprocessor Instructions */
348static void do_cdp PARAMS ((char *operands, unsigned long flags));
349static void do_lstc PARAMS ((char *operands, unsigned long flags));
350static void do_co_reg PARAMS ((char *operands, unsigned long flags));
351static void do_fp_ctrl PARAMS ((char *operands, unsigned long flags));
352static void do_fp_ldst PARAMS ((char *operands, unsigned long flags));
353static void do_fp_ldmstm PARAMS ((char *operands, unsigned long flags));
354static void do_fp_dyadic PARAMS ((char *operands, unsigned long flags));
355static void do_fp_monadic PARAMS ((char *operands, unsigned long flags));
356static void do_fp_cmp PARAMS ((char *operands, unsigned long flags));
357static void do_fp_from_reg PARAMS ((char *operands, unsigned long flags));
358static void do_fp_to_reg PARAMS ((char *operands, unsigned long flags));
359
360static void fix_new_arm PARAMS ((fragS *frag, int where,
361 short int size, expressionS *exp,
362 int pc_rel, int reloc));
363static int arm_reg_parse PARAMS ((char **ccp));
364static int arm_psr_parse PARAMS ((char **ccp));
365
c479fc62
JSC
366/* ARM instructions take 4bytes in the object file, Thumb instructions
367 take 2. The assembler defaults to ARM code generation: */
368static int insn_size = 4;
338a7060
DE
369
370/* LONGEST_INST is the longest basic instruction name without conditions or
371 * flags.
372 * ARM7DM has 4 of length 5
373 */
374
375#define LONGEST_INST 5
376
377struct asm_opcode
378{
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 */
385};
386
387static CONST struct asm_opcode insns[] =
388{
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},
413
414/* Pseudo ops */
415 {"adr", 0x028f0000, NULL, NULL, ARM_ANY, do_adr},
416 {"nop", 0x01a00000, NULL, NULL, ARM_ANY, do_nop},
417
418/* ARM 2 multiplies */
419 {"mul", 0x00000090, NULL, s_flag, ARM_2UP, do_mul},
420 {"mla", 0x00200090, NULL, s_flag, ARM_2UP, do_mla},
421
422/* ARM 3 - swp instructions */
423 {"swp", 0x01000090, NULL, byte_flag, ARM_3UP, do_swap},
424
425/* ARM 6 Coprocessor instructions */
426 {"mrs", 0x010f0000, NULL, NULL, ARM_6UP, do_mrs},
427 {"msr", 0x0128f000, NULL, NULL, ARM_6UP, do_msr},
428
c479fc62 429/* ARM 7M long multiplies - need signed/unsigned flags! */
338a7060
DE
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},
434
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,
477 we accept either. */
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},
482
483/* Generic copressor instructions */
c479fc62
JSC
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},
338a7060
DE
489};
490
491/* defines for various bits that we will want to toggle */
492
493#define INST_IMMEDIATE 0x02000000
494#define OFFSET_REG 0x02000000
c479fc62 495#define HWOFFSET_IMM 0x00400000
338a7060
DE
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
501
502#define LITERAL_MASK 0xf000f000
503#define COND_MASK 0xf0000000
504#define OPCODE_MASK 0xfe1fffff
505#define DATA_OP_SHIFT 21
506
507/* Codes to distinguish the arithmetic instructions */
508
509#define OPCODE_AND 0
510#define OPCODE_EOR 1
511#define OPCODE_SUB 2
512#define OPCODE_RSB 3
513#define OPCODE_ADD 4
514#define OPCODE_ADC 5
515#define OPCODE_SBC 6
516#define OPCODE_RSC 7
517#define OPCODE_TST 8
518#define OPCODE_TEQ 9
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
525
526struct reg_entry
527{
528 CONST char *name;
529 int number;
530};
531
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)
535
536#define REG_PC 15
537
538/* These are the standard names; Users can add aliases with .req */
539static CONST struct reg_entry reg_table[] =
540{
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},
551 /* FP Registers */
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},
562 {NULL, 0}
563};
564
565static CONST char *bad_args = "Bad arguments to instruction";
566static CONST char *bad_pc = "r15 not allowed here";
567
568static struct hash_control *arm_ops_hsh = NULL;
569static struct hash_control *arm_cond_hsh = NULL;
570static struct hash_control *arm_shift_hsh = NULL;
571static struct hash_control *arm_reg_hsh = NULL;
572static struct hash_control *arm_psr_hsh = NULL;
573
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
579 */
580
581static void s_req PARAMS ((int));
582static void s_align PARAMS ((int));
583static void s_bss PARAMS ((int));
584static void s_even PARAMS ((int));
585static void s_ltorg PARAMS ((int));
586
587static int my_get_expression PARAMS ((expressionS *, char **));
588
589CONST pseudo_typeS md_pseudo_table[] =
590{
591 {"req", s_req, 0}, /* Never called becasue '.req' does not start line */
592 {"bss", s_bss, 0},
593 {"align", s_align, 0},
594 {"even", s_even, 0},
595 {"ltorg", s_ltorg, 0},
596 {"pool", s_ltorg, 0},
597 {"word", cons, 4},
598 {"extend", float_cons, 'x'},
599 {"ldouble", float_cons, 'x'},
600 {"packed", float_cons, 'p'},
601 {0, 0, 0}
602};
603
604/* Stuff needed to resolve the label ambiguity
605 As:
606 ...
607 label: <insn>
608 may differ from:
609 ...
610 label:
611 <insn>
612*/
613
614symbolS *last_label_seen;
615
616/* Literal stuff */
617
618#define MAX_LITERAL_POOL_SIZE 1024
619
620typedef struct literalS
621{
622 struct expressionS exp;
623 struct arm_it *inst;
624} literalT;
625
626literalT literals[MAX_LITERAL_POOL_SIZE];
627int next_literal_pool_place = 0; /* Next free entry in the pool */
628int lit_pool_num = 1; /* Next literal pool number */
629symbolS *current_poolP = NULL;
630symbolS *symbol_make_empty ();
631
632static int
633add_to_lit_pool ()
634{
c479fc62
JSC
635 int lit_count = 0;
636
338a7060
DE
637 if (current_poolP == NULL)
638 current_poolP = symbol_make_empty();
639
c479fc62
JSC
640 /* Check if this literal value is already in the pool: */
641 while (lit_count < next_literal_pool_place)
338a7060 642 {
c479fc62
JSC
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)
647 break;
648 lit_count++;
649 }
650
651 if (lit_count == next_literal_pool_place) /* new entry */
652 {
653 if (next_literal_pool_place > MAX_LITERAL_POOL_SIZE)
654 {
655 inst.error = "Literal Pool Overflow\n";
656 return FAIL;
657 }
658
659 literals[next_literal_pool_place].exp = inst.reloc.exp;
660 lit_count = next_literal_pool_place++;
338a7060
DE
661 }
662
338a7060 663 inst.reloc.exp.X_op = O_symbol;
c479fc62 664 inst.reloc.exp.X_add_number = (lit_count)*4-8;
338a7060
DE
665 inst.reloc.exp.X_add_symbol = current_poolP;
666
667 return SUCCESS;
668}
669
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 */
672static void
673symbol_locate (symbolP, name, segment, valu, frag)
674 symbolS *symbolP;
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 */
679{
680 unsigned int name_length;
681 char *preserved_copy_of_name;
682
683 name_length = strlen (name) + 1; /* +1 for \0 */
684 obstack_grow (&notes, name, name_length);
685 preserved_copy_of_name = obstack_finish (&notes);
686#ifdef STRIP_UNDERSCORE
687 if (preserved_copy_of_name[0] == '_')
688 preserved_copy_of_name++;
689#endif
690
691#ifdef tc_canonicalize_symbol_name
692 preserved_copy_of_name =
693 tc_canonicalize_symbol_name (preserved_copy_of_name);
694#endif
695
696 S_SET_NAME (symbolP, preserved_copy_of_name);
697
698 S_SET_SEGMENT (symbolP, segment);
699 S_SET_VALUE (symbolP, valu);
700 symbol_clear_list_pointers(symbolP);
701
702 symbolP->sy_frag = frag;
703
704 /*
705 * Link to end of symbol chain.
706 */
707 {
708 extern int symbol_table_frozen;
709 if (symbol_table_frozen)
710 abort ();
711 }
712
713 symbol_append (symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP);
714
715 obj_symbol_new_hook (symbolP);
716
717#ifdef tc_symbol_new_hook
718 tc_symbol_new_hook (symbolP);
719#endif
720
721#ifdef DEBUG_SYMS
722 verify_symbol_chain(symbol_rootP, symbol_lastP);
723#endif /* DEBUG_SYMS */
724}
725
726symbolS *
727symbol_make_empty ()
728{
729 symbolS *symbolP;
730
731 symbolP = (symbolS *) obstack_alloc (&notes, sizeof (symbolS));
732
733 /* symbol must be born in some fixed state. This seems as good as any. */
734 memset (symbolP, 0, sizeof (symbolS));
735
736#ifdef BFD_ASSEMBLER
737 symbolP->bsym = bfd_make_empty_symbol (stdoutput);
738 assert (symbolP->bsym != 0);
739 symbolP->bsym->udata.p = (PTR) symbolP;
740#endif
741
742 return symbolP;
743}
744
745/* Check that an immediate is valid, and if so, convert it to the right format
746 */
747
748/* OH, for a rotate instruction in C! */
749
750static int
751validate_immediate (val)
752 int val;
753{
754 unsigned int a = (unsigned int) val;
755 int i;
756
757 /* Do the easy (and most common ones) quickly */
758 for (i = 0; i <= 24; i += 2)
759 {
760 if ((a & (0xff << i)) == a)
761 return (int) (((32 - i) & 0x1e) << 7) | ((a >> i) & 0xff);
762 }
763
764 /* Now do the harder ones */
765 for (; i < 32; i += 2)
766 {
767 if ((a & ((0xff << i) | (0xff >> (32 - i)))) == a)
768 {
769 a = ((a >> i) & 0xff) | ((a << (32 - i)) & 0xff);
770 return (int) a | (((32 - i) >> 1) << 8);
771 }
772 }
773 return FAIL;
774}
775
776static int
c479fc62 777validate_offset_imm (val, hwse)
338a7060 778 int val;
c479fc62 779 int hwse;
338a7060 780{
c479fc62
JSC
781 if ((hwse && (val < -255 || val > 255))
782 || (val < -4095 || val > 4095))
783 return FAIL;
338a7060
DE
784 return val;
785}
786
787
788static void
789s_req (a)
790 int a;
791{
792 as_bad ("Invalid syntax for .req directive.");
793}
794
795static void
796s_bss (ignore)
797 int ignore;
798{
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 ();
803}
804
805static void
806s_even (ignore)
807 int ignore;
808{
809 if (!need_pass_2) /* Never make frag if expect extra pass. */
810 frag_align (1, 0);
811 record_alignment (now_seg, 1);
812 demand_empty_rest_of_line ();
813}
814
815static void
816s_ltorg (internal)
817 int internal;
818{
819 int lit_count = 0;
820 char sym_name[20];
821
822 if (current_poolP == NULL)
823 {
824 /* Nothing to do */
825 if (!internal)
826 as_tsktsk ("Nothing to put in the pool\n");
827 return;
828 }
829
830 /* Align pool as you have word accesses */
831 /* Only make a frag if we have to ... */
832 if (!need_pass_2)
833 frag_align (2, 0);
834
835 record_alignment (now_seg, 2);
836
837 if (internal)
838 as_tsktsk ("Inserting implicit pool at change of section");
839
840 sprintf (sym_name, "$$lit_\002%x", lit_pool_num++);
841
842 symbol_locate (current_poolP, sym_name, now_seg,
c479fc62 843 (valueT) frag_now_fix (), frag_now);
338a7060
DE
844 symbol_table_insert (current_poolP);
845
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 */
849
850 next_literal_pool_place = 0;
851 current_poolP = NULL;
852}
853
c479fc62 854#if 0 /* not used */
338a7060
DE
855static void
856arm_align (power, fill)
857 int power;
858 int fill;
859{
860 /* Only make a frag if we HAVE to ... */
861 if (power && !need_pass_2)
862 frag_align (power, fill);
863
864 record_alignment (now_seg, power);
865}
c479fc62 866#endif
338a7060
DE
867
868static void
869s_align (unused) /* Same as s_align_ptwo but align 0 => align 2 */
870 int unused;
871{
872 register int temp;
873 register long temp_fill;
874 long max_alignment = 15;
875
876 temp = get_absolute_expression ();
877 if (temp > max_alignment)
878 as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
879 else if (temp < 0)
880 {
881 as_bad ("Alignment negative. 0 assumed.");
882 temp = 0;
883 }
884
885 if (*input_line_pointer == ',')
886 {
887 input_line_pointer++;
888 temp_fill = get_absolute_expression ();
889 }
890 else
891 temp_fill = 0;
892
893 if (!temp)
894 temp = 2;
895
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 ();
900
901 record_alignment (now_seg, temp);
902}
903
904static void
905end_of_line (str)
906 char *str;
907{
908 while (*str == ' ')
909 str++;
910
911 if (*str != '\0')
912 inst.error = "Garbage following instruction";
913}
914
915static int
916skip_past_comma (str)
917 char **str;
918{
919 char *p = *str, c;
920 int comma = 0;
921
922 while ((c = *p) == ' ' || c == ',')
923 {
924 p++;
925 if (c == ',' && comma++)
926 return FAIL;
927 }
928
929 if (c == '\0')
930 return FAIL;
931
932 *str = p;
933 return comma ? SUCCESS : FAIL;
934}
935
936/* A standard register must be given at this point. Shift is the place to
937 put it in the instruction. */
938
939static int
940reg_required_here (str, shift)
941 char **str;
942 int shift;
943{
944 int reg;
945 char *start = *str;
946
947 if ((reg = arm_reg_parse (str)) != FAIL && int_register (reg))
948 {
949 inst.instruction |= reg << shift;
950 return reg;
951 }
952
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";
956
957 /* Restore the start point, we may have got a reg of the wrong class. */
958 *str = start;
959 return FAIL;
960}
961
962static int
963psr_required_here (str, shift)
964 char **str;
965 int shift;
966{
967 int psr;
968 char *start = *str;
969
970 if ((psr = arm_psr_parse (str)) != FAIL && psr < 2)
971 {
972 if (psr == 1)
973 inst.instruction |= 1 << shift; /* Should be bit 22 */
974 return psr;
975 }
976
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";
980
981 /* Restore the start point. */
982 *str = start;
983 return FAIL;
984}
985
986static int
987psrf_required_here (str, shift)
988 char **str;
989 int shift;
990{
991 int psrf;
992 char *start = *str;
993
994 if ((psrf = arm_psr_parse (str)) != FAIL && psrf > 1)
995 {
996 if (psrf == 1 || psrf == 3)
997 inst.instruction |= 1 << shift; /* Should be bit 22 */
998 return psrf;
999 }
1000
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";
1004
1005 /* Restore the start point. */
1006 *str = start;
1007 return FAIL;
1008}
1009
1010static int
1011co_proc_number (str)
1012 char **str;
1013{
1014 int processor, pchar;
1015
1016 while (**str == ' ')
1017 (*str)++;
1018
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
1021 accept either. */
1022 if (**str == 'p' || **str == 'P')
1023 (*str)++;
1024
1025 pchar = *(*str)++;
1026 if (pchar >= '0' && pchar <= '9')
1027 {
1028 processor = pchar - '0';
1029 if (**str >= '0' && **str <= '9')
1030 {
1031 processor = processor * 10 + *(*str)++ - '0';
1032 if (processor > 15)
1033 {
1034 inst.error = "Illegal co-processor number";
1035 return FAIL;
1036 }
1037 }
1038 }
1039 else
1040 {
1041 inst.error = "Bad or missing co-processor number";
1042 return FAIL;
1043 }
1044
1045 inst.instruction |= processor << 8;
1046 return SUCCESS;
1047}
1048
1049static int
1050cp_opc_expr (str, where, length)
1051 char **str;
1052 int where;
1053 int length;
1054{
1055 expressionS expr;
1056
1057 while (**str == ' ')
1058 (*str)++;
1059
1060 memset (&expr, '\0', sizeof (expr));
1061
1062 if (my_get_expression (&expr, str))
1063 return FAIL;
1064 if (expr.X_op != O_constant)
1065 {
1066 inst.error = "bad or missing expression";
1067 return FAIL;
1068 }
1069
1070 if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
1071 {
1072 inst.error = "immediate co-processor expression too large";
1073 return FAIL;
1074 }
1075
1076 inst.instruction |= expr.X_add_number << where;
1077 return SUCCESS;
1078}
1079
1080static int
1081cp_reg_required_here (str, where)
1082 char **str;
1083 int where;
1084{
1085 int reg;
1086 char *start = *str;
1087
1088 if ((reg = arm_reg_parse (str)) != FAIL && cp_register (reg))
1089 {
1090 reg &= 15;
1091 inst.instruction |= reg << where;
1092 return reg;
1093 }
1094
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";
1098
1099 /* Restore the start point */
1100 *str = start;
1101 return FAIL;
1102}
1103
1104static int
1105fp_reg_required_here (str, where)
1106 char **str;
1107 int where;
1108{
1109 int reg;
1110 char *start = *str;
1111
1112 if ((reg = arm_reg_parse (str)) != FAIL && fp_register (reg))
1113 {
1114 reg &= 7;
1115 inst.instruction |= reg << where;
1116 return reg;
1117 }
1118
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";
1122
1123 /* Restore the start point */
1124 *str = start;
1125 return FAIL;
1126}
1127
1128static int
1129cp_address_offset (str)
1130 char **str;
1131{
1132 int offset;
1133
1134 while (**str == ' ')
1135 (*str)++;
1136
1137 if (**str != '#')
1138 {
1139 inst.error = "immediate expression expected";
1140 return FAIL;
1141 }
1142
1143 (*str)++;
1144 if (my_get_expression (&inst.reloc.exp, str))
1145 return FAIL;
1146 if (inst.reloc.exp.X_op == O_constant)
1147 {
1148 offset = inst.reloc.exp.X_add_number;
1149 if (offset & 3)
1150 {
1151 inst.error = "co-processor address must be word aligned";
1152 return FAIL;
1153 }
1154
1155 if (offset > 1023 || offset < -1023)
1156 {
1157 inst.error = "offset too large";
1158 return FAIL;
1159 }
1160
1161 if (offset >= 0)
1162 inst.instruction |= INDEX_UP;
1163 else
1164 offset = -offset;
1165
1166 inst.instruction |= offset >> 2;
1167 }
1168 else
1169 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1170
1171 return SUCCESS;
1172}
1173
1174static int
1175cp_address_required_here (str)
1176 char **str;
1177{
1178 char *p = *str;
1179 int pre_inc = 0;
1180 int write_back = 0;
1181
1182 if (*p == '[')
1183 {
1184 int reg;
1185
1186 p++;
1187 while (*p == ' ')
1188 p++;
1189
1190 if ((reg = reg_required_here (&p, 16)) == FAIL)
1191 {
1192 inst.error = "Register required";
1193 return FAIL;
1194 }
1195
1196 while (*p == ' ')
1197 p++;
1198
1199 if (*p == ']')
1200 {
1201 p++;
1202 if (skip_past_comma (&p) == SUCCESS)
1203 {
1204 /* [Rn], #expr */
1205 write_back = WRITE_BACK;
1206 if (reg == REG_PC)
1207 {
1208 inst.error = "pc may not be used in post-increment";
1209 return FAIL;
1210 }
1211
1212 if (cp_address_offset (&p) == FAIL)
1213 return FAIL;
1214 }
1215 else
1216 pre_inc = PRE_INDEX | INDEX_UP;
1217 }
1218 else
1219 {
1220 /* '['Rn, #expr']'[!] */
1221
1222 if (skip_past_comma (&p) == FAIL)
1223 {
1224 inst.error = "pre-indexed expression expected";
1225 return FAIL;
1226 }
1227
1228 pre_inc = PRE_INDEX;
1229 if (cp_address_offset (&p) == FAIL)
1230 return FAIL;
1231
1232 while (*p == ' ')
1233 p++;
1234
1235 if (*p++ != ']')
1236 {
1237 inst.error = "missing ]";
1238 return FAIL;
1239 }
1240
1241 while (*p == ' ')
1242 p++;
1243
1244 if (*p == '!')
1245 {
1246 if (reg == REG_PC)
1247 {
1248 inst.error = "pc may not be used with write-back";
1249 return FAIL;
1250 }
1251
1252 p++;
1253 write_back = WRITE_BACK;
1254 }
1255 }
1256 }
1257 else
1258 {
1259 if (my_get_expression (&inst.reloc.exp, &p))
1260 return FAIL;
1261
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);
c479fc62 1266 pre_inc = PRE_INDEX;
338a7060
DE
1267 }
1268
1269 inst.instruction |= write_back | pre_inc;
1270 *str = p;
1271 return SUCCESS;
1272}
1273
1274static void
1275do_nop (str, flags)
1276 char *str;
1277 unsigned long flags;
1278{
1279 /* Do nothing really */
1280 inst.instruction |= flags; /* This is pointless */
1281 end_of_line (str);
1282 return;
1283}
1284
1285static void
1286do_mrs (str, flags)
1287 char *str;
1288 unsigned long flags;
1289{
1290 /* Only one syntax */
1291 while (*str == ' ')
1292 str++;
1293
1294 if (reg_required_here (&str, 12) == FAIL)
1295 {
1296 inst.error = bad_args;
1297 return;
1298 }
1299
1300 if (skip_past_comma (&str) == FAIL
1301 || psr_required_here (&str, 22) == FAIL)
1302 {
1303 inst.error = "<psr> expected";
1304 return;
1305 }
1306
1307 inst.instruction |= flags;
1308 end_of_line (str);
1309 return;
1310}
1311
1312static void
1313do_msr (str, flags)
1314 char *str;
1315 unsigned long flags;
1316{
1317 int psr, psrf, reg;
1318 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression" */
1319
1320 while (*str == ' ')
1321 str++;
1322
1323 if ((psr = psr_required_here (&str, 22)) != FAIL)
1324 {
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)
1329 {
1330 inst.error = bad_args;
1331 return;
1332 }
1333 }
1334 else if ((psrf = psrf_required_here (&str, 22)) != FAIL)
1335 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1336 {
1337 if (skip_past_comma (&str) == FAIL)
1338 {
1339 inst.error = bad_args;
1340 return;
1341 }
1342 if ((reg = reg_required_here (&str, 0)) != FAIL)
1343 ;
1344 /* Immediate expression */
1345 else if (*(str++) == '#')
1346 {
1347 inst.error = NULL;
1348 if (my_get_expression (&inst.reloc.exp, &str))
1349 {
1350 inst.error = "Register or shift expression expected";
1351 return;
1352 }
1353
1354 if (inst.reloc.exp.X_add_symbol)
1355 {
1356 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
1357 inst.reloc.pc_rel = 0;
1358 }
1359 else
1360 {
1361 int value = validate_immediate (inst.reloc.exp.X_add_number);
1362 if (value == FAIL)
1363 {
1364 inst.error = "Invalid constant";
1365 return;
1366 }
1367
1368 inst.instruction |= value;
1369 }
1370
1371 flags |= INST_IMMEDIATE;
1372 }
1373 else
1374 {
1375 inst.error = "Error: the other";
1376 return;
1377 }
1378 }
1379 else
1380 {
1381 inst.error = bad_args;
1382 return;
1383 }
1384
1385 inst.error = NULL;
1386 inst.instruction |= flags;
1387 end_of_line (str);
1388 return;
1389}
1390
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
1396*/
1397static void
1398do_mull (str, flags)
1399 char *str;
1400 unsigned long flags;
1401{
1402 int rdlo, rdhi, rm, rs;
1403
1404 /* only one format "rdlo, rdhi, rm, rs" */
1405 while (*str == ' ')
1406 str++;
1407
1408 if ((rdlo = reg_required_here (&str, 12)) == FAIL)
1409 {
1410 inst.error = bad_args;
1411 return;
1412 }
1413
1414 if (skip_past_comma (&str) == FAIL
1415 || (rdhi = reg_required_here (&str, 16)) == FAIL)
1416 {
1417 inst.error = bad_args;
1418 return;
1419 }
1420
1421 if (skip_past_comma (&str) == FAIL
1422 || (rm = reg_required_here (&str, 0)) == FAIL)
1423 {
1424 inst.error = bad_args;
1425 return;
1426 }
1427
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");
1431
1432 if (skip_past_comma (&str) == FAIL
1433 || (rs = reg_required_here (&str, 8)) == FAIL)
1434 {
1435 inst.error = bad_args;
1436 return;
1437 }
1438
1439 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
1440 {
1441 inst.error = bad_pc;
1442 return;
1443 }
1444
1445 inst.instruction |= flags;
1446 end_of_line (str);
1447 return;
1448}
1449
1450static void
1451do_mul (str, flags)
1452 char *str;
1453 unsigned long flags;
1454{
1455 int rd, rm;
1456
1457 /* only one format "rd, rm, rs" */
1458 while (*str == ' ')
1459 str++;
1460
1461 if ((rd = reg_required_here (&str, 16)) == FAIL)
1462 {
1463 inst.error = bad_args;
1464 return;
1465 }
1466
1467 if (rd == REG_PC)
1468 {
1469 inst.error = bad_pc;
1470 return;
1471 }
1472
1473 if (skip_past_comma (&str) == FAIL
1474 || (rm = reg_required_here (&str, 0)) == FAIL)
1475 {
1476 inst.error = bad_args;
1477 return;
1478 }
1479
1480 if (rm == REG_PC)
1481 {
1482 inst.error = bad_pc;
1483 return;
1484 }
1485
1486 if (rm == rd)
1487 as_tsktsk ("rd and rm should be different in mul");
1488
1489 if (skip_past_comma (&str) == FAIL
1490 || (rm = reg_required_here (&str, 8)) == FAIL)
1491 {
1492 inst.error = bad_args;
1493 return;
1494 }
1495
1496 if (rm == REG_PC)
1497 {
1498 inst.error = bad_pc;
1499 return;
1500 }
1501
1502 inst.instruction |= flags;
1503 end_of_line (str);
1504 return;
1505}
1506
1507static void
1508do_mla (str, flags)
1509 char *str;
1510 unsigned long flags;
1511{
1512 int rd, rm;
1513
1514 /* only one format "rd, rm, rs, rn" */
1515 while (*str == ' ')
1516 str++;
1517
1518 if ((rd = reg_required_here (&str, 16)) == FAIL)
1519 {
1520 inst.error = bad_args;
1521 return;
1522 }
1523
1524 if (rd == REG_PC)
1525 {
1526 inst.error = bad_pc;
1527 return;
1528 }
1529
1530 if (skip_past_comma (&str) == FAIL
1531 || (rm = reg_required_here (&str, 0)) == FAIL)
1532 {
1533 inst.error = bad_args;
1534 return;
1535 }
1536
1537 if (rm == REG_PC)
1538 {
1539 inst.error = bad_pc;
1540 return;
1541 }
1542
1543 if (rm == rd)
1544 as_tsktsk ("rd and rm should be different in mla");
1545
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)
1550 {
1551 inst.error = bad_args;
1552 return;
1553 }
1554
1555 if (rd == REG_PC || rm == REG_PC)
1556 {
1557 inst.error = bad_pc;
1558 return;
1559 }
1560
1561 inst.instruction |= flags;
1562 end_of_line (str);
1563 return;
1564}
1565
1566/* Returns the index into fp_values of a floating point number, or -1 if
1567 not in the table. */
1568static int
1569my_get_float_expression (str)
1570 char **str;
1571{
1572 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1573 char *save_in;
1574 expressionS exp;
1575 int i, j;
1576
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'))
1581 {
1582 for (i = 0; i < NUM_FLOAT_VALS; i++)
1583 {
1584 for (j = 0; j < MAX_LITTLENUMS; j++)
1585 {
1586 if (words[j] != fp_values[i][j])
1587 break;
1588 }
1589
1590 if (j == MAX_LITTLENUMS)
1591 {
1592 *str = save_in;
1593 return i;
1594 }
1595 }
1596 }
1597
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)
1605 {
c479fc62
JSC
1606 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
1607 Ditto for 15. */
1608 if (gen_to_words (words, 5, (long)15) == 0)
338a7060
DE
1609 {
1610 for (i = 0; i < NUM_FLOAT_VALS; i++)
1611 {
1612 for (j = 0; j < MAX_LITTLENUMS; j++)
1613 {
1614 if (words[j] != fp_values[i][j])
1615 break;
1616 }
1617
1618 if (j == MAX_LITTLENUMS)
1619 {
1620 *str = input_line_pointer;
1621 input_line_pointer = save_in;
1622 return i;
1623 }
1624 }
1625 }
1626 }
1627
1628 *str = input_line_pointer;
1629 input_line_pointer = save_in;
1630 return -1;
1631}
1632
1633/* Return true if anything in the expression is a bignum */
1634static int
1635walk_no_bignums (sp)
1636 symbolS *sp;
1637{
1638 if (sp->sy_value.X_op == O_big)
1639 return 1;
1640
1641 if (sp->sy_value.X_add_symbol)
1642 {
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)));
1646 }
1647
1648 return 0;
1649}
1650
1651static int
1652my_get_expression (ep, str)
1653 expressionS *ep;
1654 char **str;
1655{
1656 char *save_in;
1657 segT seg;
1658
1659 save_in = input_line_pointer;
1660 input_line_pointer = *str;
1661 seg = expression (ep);
c479fc62
JSC
1662
1663#ifdef OBJ_AOUT
338a7060
DE
1664 if (seg != absolute_section
1665 && seg != text_section
1666 && seg != data_section
1667 && seg != bss_section
1668 && seg != undefined_section)
1669 {
1670 inst.error = "bad_segment";
1671 *str = input_line_pointer;
1672 input_line_pointer = save_in;
1673 return 1;
1674 }
c479fc62 1675#endif
338a7060
DE
1676
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
c479fc62 1679 in instructions, which is where this routine is always called. */
338a7060
DE
1680 if (ep->X_op == O_big
1681 || (ep->X_add_symbol
1682 && (walk_no_bignums (ep->X_add_symbol)
1683 || (ep->X_op_symbol
1684 && walk_no_bignums (ep->X_op_symbol)))))
1685 {
1686 inst.error = "Invalid constant";
1687 *str = input_line_pointer;
1688 input_line_pointer = save_in;
1689 return 1;
1690 }
1691
1692 *str = input_line_pointer;
1693 input_line_pointer = save_in;
1694 return 0;
1695}
1696
1697/* unrestrict should be one if <shift> <register> is permitted for this
1698 instruction */
1699
1700static int
1701decode_shift (str, unrestrict)
1702 char **str;
1703 int unrestrict;
1704{
1705 struct asm_shift *shft;
1706 char *p;
1707 char c;
1708
1709 while (**str == ' ')
1710 (*str)++;
1711
1712 for (p = *str; isalpha (*p); p++)
1713 ;
1714
1715 if (p == *str)
1716 {
1717 inst.error = "Shift expression expected";
1718 return FAIL;
1719 }
1720
1721 c = *p;
1722 *p = '\0';
1723 shft = (struct asm_shift *) hash_find (arm_shift_hsh, *str);
1724 *p = c;
1725 if (shft)
1726 {
1727 if (!strcmp (*str, "rrx"))
1728 {
1729 *str = p;
1730 inst.instruction |= shft->value;
1731 return SUCCESS;
1732 }
1733
1734 while (*p == ' ')
1735 p++;
1736
1737 if (unrestrict && reg_required_here (&p, 8) != FAIL)
1738 {
1739 inst.instruction |= shft->value | SHIFT_BY_REG;
1740 *str = p;
1741 return SUCCESS;
1742 }
1743 else if (*p == '#')
1744 {
1745 inst.error = NULL;
1746 p++;
1747 if (my_get_expression (&inst.reloc.exp, &p))
1748 return FAIL;
1749
1750 /* Validate some simple #expressions */
1751 if (! inst.reloc.exp.X_add_symbol)
1752 {
1753 int num = inst.reloc.exp.X_add_number;
1754 if (num < 0 || num > 32
1755 || (num == 32
1756 && (shft->value == 0 || shft->value == 0x60)))
1757 {
1758 inst.error = "Invalid immediate shift";
1759 return FAIL;
1760 }
1761
1762 /* Shifts of zero should be converted to lsl (which is zero)*/
1763 if (num == 0)
1764 {
1765 *str = p;
1766 return SUCCESS;
1767 }
1768
1769 /* Shifts of 32 are encoded as 0, for those shifts that
1770 support it. */
1771 if (num == 32)
1772 num = 0;
1773
1774 inst.instruction |= (num << 7) | shft->value;
1775 *str = p;
1776 return SUCCESS;
1777 }
1778
1779 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
1780 inst.reloc.pc_rel = 0;
1781 inst.instruction |= shft->value;
1782 *str = p;
1783 return SUCCESS;
1784 }
1785 else
1786 {
1787 inst.error = unrestrict ? "shift requires register or #expression"
1788 : "shift requires #expression";
1789 *str = p;
1790 return FAIL;
1791 }
1792 }
1793
1794 inst.error = "Shift expression expected";
1795 return FAIL;
1796}
1797
1798/* Do those data_ops which can take a negative immediate constant */
1799/* by altering the instuction. A bit of a hack really */
1800/* MOV <-> MVN
1801 AND <-> BIC
1802 ADC <-> SBC
1803 by inverting the second operand, and
1804 ADD <-> SUB
1805 CMP <-> CMN
1806 by negating the second operand.
1807*/
1808static int
1809negate_data_op (instruction, value)
1810 unsigned long *instruction;
1811 unsigned long value;
1812{
1813 int op, new_inst;
1814 unsigned long negated, inverted;
1815
1816 negated = validate_immediate (-value);
1817 inverted = validate_immediate (~value);
1818
1819 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
1820 switch (op)
1821 {
1822 /* First negates */
1823 case OPCODE_SUB: /* ADD <-> SUB */
1824 new_inst = OPCODE_ADD;
1825 value = negated;
1826 break;
1827
1828 case OPCODE_ADD:
1829 new_inst = OPCODE_SUB;
1830 value = negated;
1831 break;
1832
1833 case OPCODE_CMP: /* CMP <-> CMN */
1834 new_inst = OPCODE_CMN;
1835 value = negated;
1836 break;
1837
1838 case OPCODE_CMN:
1839 new_inst = OPCODE_CMP;
1840 value = negated;
1841 break;
1842
1843 /* Now Inverted ops */
1844 case OPCODE_MOV: /* MOV <-> MVN */
1845 new_inst = OPCODE_MVN;
1846 value = inverted;
1847 break;
1848
1849 case OPCODE_MVN:
1850 new_inst = OPCODE_MOV;
1851 value = inverted;
1852 break;
1853
1854 case OPCODE_AND: /* AND <-> BIC */
1855 new_inst = OPCODE_BIC;
1856 value = inverted;
1857 break;
1858
1859 case OPCODE_BIC:
1860 new_inst = OPCODE_AND;
1861 value = inverted;
1862 break;
1863
1864 case OPCODE_ADC: /* ADC <-> SBC */
1865 new_inst = OPCODE_SBC;
1866 value = inverted;
1867 break;
1868
1869 case OPCODE_SBC:
1870 new_inst = OPCODE_ADC;
1871 value = inverted;
1872 break;
1873
1874 /* We cannot do anything */
1875 default:
1876 return FAIL;
1877 }
1878
1879 if (value == FAIL)
1880 return FAIL;
1881
1882 *instruction &= OPCODE_MASK;
1883 *instruction |= new_inst << DATA_OP_SHIFT;
1884 return value;
1885}
1886
1887static int
1888data_op2 (str)
1889 char **str;
1890{
1891 int value;
1892 expressionS expr;
1893
1894 while (**str == ' ')
1895 (*str)++;
1896
1897 if (reg_required_here (str, 0) != FAIL)
1898 {
1899 if (skip_past_comma (str) == SUCCESS)
1900 {
1901 /* Shift operation on register */
1902 return decode_shift (str, NO_SHIFT_RESTRICT);
1903 }
1904 return SUCCESS;
1905 }
1906 else
1907 {
1908 /* Immediate expression */
1909 if (*((*str)++) == '#')
1910 {
1911 inst.error = NULL;
1912 if (my_get_expression (&inst.reloc.exp, str))
1913 return FAIL;
1914
1915 if (inst.reloc.exp.X_add_symbol)
1916 {
1917 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
1918 inst.reloc.pc_rel = 0;
1919 }
1920 else
1921 {
1922 if (skip_past_comma (str) == SUCCESS)
1923 {
1924 /* #x, y -- ie explicit rotation by Y */
1925 if (my_get_expression (&expr, str))
1926 return FAIL;
1927
1928 if (expr.X_op != O_constant)
1929 {
1930 inst.error = "Constant expression expected";
1931 return FAIL;
1932 }
1933
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)
1938 {
1939 inst.error = "Invalid constant";
1940 return FAIL;
1941 }
1942 inst.instruction |= INST_IMMEDIATE;
1943 inst.instruction |= inst.reloc.exp.X_add_number;
1944 inst.instruction |= expr.X_add_number << 7;
1945 return SUCCESS;
1946 }
1947
1948 /* Implicit rotation, select a suitable one */
1949 value = validate_immediate (inst.reloc.exp.X_add_number);
1950
1951 if (value == FAIL)
1952 {
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))
1957 == FAIL)
1958 {
1959 inst.error = "Invalid constant";
1960 return FAIL;
1961 }
1962 }
1963
1964 inst.instruction |= value;
1965 }
1966
1967 inst.instruction |= INST_IMMEDIATE;
1968 return SUCCESS;
1969 }
1970
1971 inst.error = "Register or shift expression expected";
1972 return FAIL;
1973 }
1974}
1975
1976static int
1977fp_op2 (str, flags)
1978 char **str;
1979 unsigned long flags;
1980{
1981 while (**str == ' ')
1982 (*str)++;
1983
1984 if (fp_reg_required_here (str, 0) != FAIL)
1985 return SUCCESS;
1986 else
1987 {
1988 /* Immediate expression */
1989 if (*((*str)++) == '#')
1990 {
1991 int i;
1992
1993 inst.error = NULL;
1994 while (**str == ' ')
1995 (*str)++;
1996
1997 /* First try and match exact strings, this is to guarantee that
1998 some formats will work even for cross assembly */
1999
2000 for (i = 0; fp_const[i]; i++)
2001 {
2002 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
2003 {
2004 char *start = *str;
2005
2006 *str += strlen (fp_const[i]);
2007 if (is_end_of_line[(int)**str] || **str == '\0')
2008 {
2009 inst.instruction |= i + 8;
2010 return SUCCESS;
2011 }
2012 *str = start;
2013 }
2014 }
2015
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)
2021 {
2022 inst.instruction |= i + 8;
2023 return SUCCESS;
2024 }
2025
2026 inst.error = "Invalid floating point immediate expression";
2027 return FAIL;
2028 }
2029 inst.error = "Floating point register or immediate expression expected";
2030 return FAIL;
2031 }
2032}
2033
2034static void
2035do_arit (str, flags)
2036 char *str;
2037 unsigned long flags;
2038{
2039 while (*str == ' ')
2040 str++;
2041
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)
2047 {
2048 if (!inst.error)
2049 inst.error = bad_args;
2050 return;
2051 }
2052
2053 inst.instruction |= flags;
2054 end_of_line (str);
2055 return;
2056}
2057
2058static void
2059do_adr (str, flags)
2060 char *str;
2061 unsigned long flags;
2062{
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 */
2065
2066 while (*str == ' ')
2067 str++;
2068
2069 if (reg_required_here (&str, 12) == FAIL
2070 || skip_past_comma (&str) == FAIL
2071 || my_get_expression (&inst.reloc.exp, &str))
2072 {
2073 if (!inst.error)
2074 inst.error = bad_args;
2075 return;
2076 }
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;
2083 end_of_line (str);
2084 return;
2085}
2086
2087static void
2088do_cmp (str, flags)
2089 char *str;
2090 unsigned long flags;
2091{
2092 while (*str == ' ')
2093 str++;
2094
2095 if (reg_required_here (&str, 16) == FAIL)
2096 {
2097 if (!inst.error)
2098 inst.error = bad_args;
2099 return;
2100 }
2101
2102 if (skip_past_comma (&str) == FAIL
2103 || data_op2 (&str) == FAIL)
2104 {
2105 if (!inst.error)
2106 inst.error = bad_args;
2107 return;
2108 }
2109
2110 inst.instruction |= flags;
2111 if ((flags & 0x0000f000) == 0)
2112 inst.instruction |= 0x00100000;
2113
2114 end_of_line (str);
2115 return;
2116}
2117
2118static void
2119do_mov (str, flags)
2120 char *str;
2121 unsigned long flags;
2122{
2123 while (*str == ' ')
2124 str++;
2125
2126 if (reg_required_here (&str, 12) == FAIL)
2127 {
2128 if (!inst.error)
2129 inst.error = bad_args;
2130 return;
2131 }
2132
2133 if (skip_past_comma (&str) == FAIL
2134 || data_op2 (&str) == FAIL)
2135 {
2136 if (!inst.error)
2137 inst.error = bad_args;
2138 return;
2139 }
2140
2141 inst.instruction |= flags;
2142 end_of_line (str);
2143 return;
2144}
2145
2146static int
c479fc62 2147ldst_extend (str, hwse)
338a7060 2148 char **str;
c479fc62 2149 int hwse;
338a7060
DE
2150{
2151 int add = INDEX_UP;
2152
2153 switch (**str)
2154 {
2155 case '#':
2156 (*str)++;
2157 if (my_get_expression (&inst.reloc.exp, str))
2158 return FAIL;
2159
2160 if (inst.reloc.exp.X_op == O_constant)
2161 {
2162 int value = inst.reloc.exp.X_add_number;
2163
c479fc62
JSC
2164 if ((hwse && (value < -255 || value > 255))
2165 || (value < -4095 || value > 4095))
338a7060
DE
2166 {
2167 inst.error = "address offset too large";
2168 return FAIL;
2169 }
2170
2171 if (value < 0)
2172 {
2173 value = -value;
2174 add = 0;
2175 }
2176
c479fc62
JSC
2177 /* Halfword and signextension instructions have the
2178 immediate value split across bits 11..8 and bits 3..0 */
2179 if (hwse)
2180 inst.instruction |= add | HWOFFSET_IMM | (value >> 4) << 8 | value & 0xF;
2181 else
2182 inst.instruction |= add | value;
338a7060
DE
2183 }
2184 else
2185 {
c479fc62
JSC
2186 if (hwse)
2187 {
2188 inst.instruction |= HWOFFSET_IMM;
2189 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2190 }
2191 else
2192 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
338a7060
DE
2193 inst.reloc.pc_rel = 0;
2194 }
2195 return SUCCESS;
2196
2197 case '-':
2198 add = 0; /* and fall through */
2199 case '+':
2200 (*str)++; /* and fall through */
2201 default:
2202 if (reg_required_here (str, 0) == FAIL)
2203 {
2204 inst.error = "Register expected";
2205 return FAIL;
2206 }
c479fc62
JSC
2207
2208 if (hwse)
2209 inst.instruction |= add;
2210 else
2211 inst.instruction |= add | OFFSET_REG;
2212
2213 /* Shifts are not allowed in the halfword and signextension
2214 forms of single memory transfers: */
2215 if (!hwse && skip_past_comma (str) == SUCCESS)
338a7060
DE
2216 return decode_shift (str, SHIFT_RESTRICT);
2217 return SUCCESS;
2218 }
2219}
2220
2221static void
2222do_ldst (str, flags)
2223 char *str;
2224 unsigned long flags;
2225{
c479fc62
JSC
2226 int halfword = 0;
2227 int signextend = 0;
338a7060
DE
2228 int pre_inc = 0;
2229 int conflict_reg;
2230 int value;
2231
c479fc62
JSC
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)
2238 {
2239 /* This is actually a load/store of a halfword, or a
2240 signed-extension load */
2241 inst.instruction = (inst.instruction & COND_MASK)
2242 | 0x00000090
2243 | (inst.instruction & 0x00100000);
2244 if (signextend && !(inst.instruction & 0x00100000))
2245 {
2246 inst.error = "Sign-extension not applicable to store instructions";
2247 return;
2248 }
2249 }
2250
338a7060
DE
2251 while (*str == ' ')
2252 str++;
2253
2254 if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
2255 {
2256 if (!inst.error)
2257 inst.error = bad_args;
2258 return;
2259 }
2260
2261 if (skip_past_comma (&str) == FAIL)
2262 {
2263 inst.error = "Address expected";
2264 return;
2265 }
2266
2267 if (*str == '[')
2268 {
2269 int reg;
2270
2271 str++;
2272 while (*str == ' ')
2273 str++;
2274
2275 if ((reg = reg_required_here (&str, 16)) == FAIL)
2276 {
2277 inst.error = "Register required";
2278 return;
2279 }
2280
2281 conflict_reg = (((conflict_reg == reg)
2282 && (inst.instruction & 0x00100000))
2283 ? 1 : 0);
2284
2285 while (*str == ' ')
2286 str++;
2287
2288 if (*str == ']')
2289 {
2290 str++;
2291 if (skip_past_comma (&str) == SUCCESS)
2292 {
2293 /* [Rn],... (post inc) */
c479fc62 2294 if (ldst_extend (&str, halfword | signextend) == FAIL)
338a7060
DE
2295 return;
2296 if (conflict_reg)
2297 as_warn ("destination register same as write-back base\n");
2298 }
2299 else
2300 {
2301 /* [Rn] */
c479fc62
JSC
2302 if (halfword | signextend)
2303 inst.instruction |= HWOFFSET_IMM;
2304
2305 while (*str == ' ')
2306 str++;
2307
2308 if (*str == '!')
2309 {
2310 if (conflict_reg)
2311 as_warn ("destination register same as write-back base\n");
2312 str++;
2313 inst.instruction |= WRITE_BACK;
2314 }
2315
338a7060 2316 flags |= INDEX_UP;
c479fc62
JSC
2317 if (! (flags & TRANS_BIT))
2318 pre_inc = 1;
338a7060
DE
2319 }
2320 }
2321 else
2322 {
2323 /* [Rn,...] */
2324 if (skip_past_comma (&str) == FAIL)
2325 {
2326 inst.error = "pre-indexed expression expected";
2327 return;
2328 }
2329
2330 pre_inc = 1;
c479fc62 2331 if (ldst_extend (&str, halfword | signextend) == FAIL)
338a7060
DE
2332 return;
2333
2334 while (*str == ' ')
2335 str++;
2336
2337 if (*str++ != ']')
2338 {
2339 inst.error = "missing ]";
2340 return;
2341 }
2342
2343 while (*str == ' ')
2344 str++;
2345
2346 if (*str == '!')
2347 {
2348 if (conflict_reg)
2349 as_warn ("destination register same as write-back base\n");
2350 str++;
2351 inst.instruction |= WRITE_BACK;
2352 }
2353 }
2354 }
2355 else if (*str == '=')
2356 {
2357 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2358 str++;
2359
2360 while (*str == ' ')
2361 str++;
2362
2363 if (my_get_expression (&inst.reloc.exp, &str))
2364 return;
2365
2366 if (inst.reloc.exp.X_op != O_constant
2367 && inst.reloc.exp.X_op != O_symbol)
2368 {
2369 inst.error = "Constant expression expected";
2370 return;
2371 }
2372
2373 if (inst.reloc.exp.X_op == O_constant
2374 && (value = validate_immediate(inst.reloc.exp.X_add_number)) != FAIL)
2375 {
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);
2380 end_of_line(str);
2381 return;
2382 }
2383 else
2384 {
2385 /* Insert into literal pool */
2386 if (add_to_lit_pool () == FAIL)
2387 {
2388 if (!inst.error)
2389 inst.error = "literal pool insertion failed\n";
2390 return;
2391 }
2392
2393 /* Change the instruction exp to point to the pool */
c479fc62
JSC
2394 if (halfword || signextend)
2395 {
2396 inst.instruction |= HWOFFSET_IMM;
2397 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
2398 }
2399 else
2400 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
338a7060
DE
2401 inst.reloc.pc_rel = 1;
2402 inst.instruction |= (REG_PC << 16);
2403 pre_inc = 1;
2404 }
2405 }
2406 else
2407 {
2408 if (my_get_expression (&inst.reloc.exp, &str))
2409 return;
2410
c479fc62
JSC
2411 if (halfword || signextend)
2412 {
2413 inst.instruction |= HWOFFSET_IMM;
2414 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2415 }
2416 else
2417 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
338a7060
DE
2418 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
2419 inst.reloc.pc_rel = 1;
2420 inst.instruction |= (REG_PC << 16);
2421 pre_inc = 1;
2422 }
2423
2424 if (pre_inc && (flags & TRANS_BIT))
2425 inst.error = "Pre-increment instruction with translate";
2426
2427 inst.instruction |= flags | (pre_inc ? PRE_INDEX : 0);
2428 end_of_line (str);
2429 return;
2430}
2431
2432static void
2433do_ldmstm (str, flags)
2434 char *str;
2435 unsigned long flags;
2436{
2437 int base_reg;
2438
2439 while (*str == ' ')
2440 str++;
2441
2442 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
2443 {
2444 if (!inst.error)
2445 inst.error = bad_args;
2446 return;
2447 }
2448
2449 if (base_reg == REG_PC)
2450 {
2451 inst.error = "r15 not allowed as base register";
2452 return;
2453 }
2454
2455 while (*str == ' ')
2456 str++;
2457 if (*str == '!')
2458 {
2459 flags |= WRITE_BACK;
2460 str++;
2461 }
2462
2463 if (skip_past_comma (&str) == FAIL)
2464 {
2465 inst.error = bad_args;
2466 return;
2467 }
2468
2469 /* We come back here if we get ranges concatenated by '+' or '|' */
2470 another_range:
2471 if (*str == '{')
2472 {
2473 int in_range = 0;
2474 int cur_reg = -1;
2475
2476 str++;
2477 do
2478 {
2479 int reg;
2480
2481 while (*str == ' ')
2482 str++;
2483
2484 if ((reg = arm_reg_parse (&str)) == FAIL || !int_register (reg))
2485 {
2486 inst.error = "Register expected";
2487 return;
2488 }
2489
2490 if (in_range)
2491 {
2492 int i;
2493
2494 if (reg <= cur_reg)
2495 {
2496 inst.error = "Bad range in register list";
2497 return;
2498 }
2499
2500 for (i = cur_reg + 1; i < reg; i++)
2501 {
2502 if (flags & (1 << i))
2503 as_tsktsk
2504 ("Warning: Duplicated register (r%d) in register list",
2505 i);
2506 else
2507 flags |= 1 << i;
2508 }
2509 in_range = 0;
2510 }
2511
2512 if (flags & (1 << reg))
2513 as_tsktsk ("Warning: Duplicated register (r%d) in register list",
2514 reg);
2515 else if (reg <= cur_reg)
2516 as_tsktsk ("Warning: Register range not in ascending order");
2517
2518 flags |= 1 << reg;
2519 cur_reg = reg;
2520 } while (skip_past_comma (&str) != FAIL
2521 || (in_range = 1, *str++ == '-'));
2522 str--;
2523 while (*str == ' ')
2524 str++;
2525
2526 if (*str++ != '}')
2527 {
2528 inst.error = "Missing `}'";
2529 return;
2530 }
2531 }
2532 else
2533 {
2534 expressionS expr;
2535
2536 if (my_get_expression (&expr, &str))
2537 return;
2538
2539 if (expr.X_op == O_constant)
2540 {
2541 if (expr.X_add_number
2542 != (expr.X_add_number & 0x0000ffff))
2543 {
2544 inst.error = "invalid register mask";
2545 return;
2546 }
2547
2548 if ((flags & expr.X_add_number) != 0)
2549 {
2550 int regno = flags & expr.X_add_number;
2551
2552 regno &= -regno;
2553 regno = (1 << regno) - 1;
2554 as_tsktsk ("Warning: Duplicated register (r%d) in register list",
2555 regno);
2556 }
2557
2558 flags |= expr.X_add_number;
2559 }
2560 else
2561 {
2562 if (inst.reloc.type != 0)
2563 {
2564 inst.error = "expression too complex";
2565 return;
2566 }
2567
2568 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
2569 inst.reloc.type = BFD_RELOC_ARM_MULTI;
2570 inst.reloc.pc_rel = 0;
2571 }
2572 }
2573
2574 while (*str == ' ')
2575 str++;
2576
2577 if (*str == '|' || *str == '+')
2578 {
2579 str++;
2580 goto another_range;
2581 }
2582
2583 if (*str == '^')
2584 {
2585 str++;
2586 flags |= MULTI_SET_PSR;
2587 }
2588 inst.instruction |= flags;
2589 end_of_line (str);
2590 return;
2591}
2592
2593static void
2594do_swi (str, flags)
2595 char *str;
2596 unsigned long flags;
2597{
2598 /* Allow optional leading '#'. */
2599 while (*str == ' ')
2600 str++;
2601 if (*str == '#')
2602 str++;
2603
2604 if (my_get_expression (&inst.reloc.exp, &str))
2605 return;
2606
2607 inst.reloc.type = BFD_RELOC_ARM_SWI;
2608 inst.reloc.pc_rel = 0;
2609 inst.instruction |= flags;
2610 end_of_line (str);
2611 return;
2612}
2613
2614static void
2615do_swap (str, flags)
2616 char *str;
2617 unsigned long flags;
2618{
2619 int reg;
2620
2621 while (*str == ' ')
2622 str++;
2623
2624 if ((reg = reg_required_here (&str, 12)) == FAIL)
2625 return;
2626
2627 if (reg == REG_PC)
2628 {
2629 inst.error = "r15 not allowed in swap";
2630 return;
2631 }
2632
2633 if (skip_past_comma (&str) == FAIL
2634 || (reg = reg_required_here (&str, 0)) == FAIL)
2635 {
2636 if (!inst.error)
2637 inst.error = bad_args;
2638 return;
2639 }
2640
2641 if (reg == REG_PC)
2642 {
2643 inst.error = "r15 not allowed in swap";
2644 return;
2645 }
2646
2647 if (skip_past_comma (&str) == FAIL
2648 || *str++ != '[')
2649 {
2650 inst.error = bad_args;
2651 return;
2652 }
2653
2654 while (*str == ' ')
2655 str++;
2656
2657 if ((reg = reg_required_here (&str, 16)) == FAIL)
2658 return;
2659
2660 if (reg == REG_PC)
2661 {
2662 inst.error = bad_pc;
2663 return;
2664 }
2665
2666 while (*str == ' ')
2667 str++;
2668
2669 if (*str++ != ']')
2670 {
2671 inst.error = "missing ]";
2672 return;
2673 }
2674
2675 inst.instruction |= flags;
2676 end_of_line (str);
2677 return;
2678}
2679
2680static void
2681do_branch (str, flags)
2682 char *str;
2683 unsigned long flags;
2684{
2685 if (my_get_expression (&inst.reloc.exp, &str))
2686 return;
2687 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
2688 inst.reloc.pc_rel = 1;
2689 inst.instruction |= flags | 0x00fffffe; /* PC-rel adjust */
2690 end_of_line (str);
2691 return;
2692}
2693
2694static void
2695do_cdp (str, flags)
2696 char *str;
2697 unsigned long flags;
2698{
2699 /* Co-processor data operation.
2700 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
2701 while (*str == ' ')
2702 str++;
2703
2704 if (co_proc_number (&str) == FAIL)
2705 {
2706 if (!inst.error)
2707 inst.error = bad_args;
2708 return;
2709 }
2710
2711 if (skip_past_comma (&str) == FAIL
2712 || cp_opc_expr (&str, 20,4) == FAIL)
2713 {
2714 if (!inst.error)
2715 inst.error = bad_args;
2716 return;
2717 }
2718
2719 if (skip_past_comma (&str) == FAIL
2720 || cp_reg_required_here (&str, 12) == FAIL)
2721 {
2722 if (!inst.error)
2723 inst.error = bad_args;
2724 return;
2725 }
2726
2727 if (skip_past_comma (&str) == FAIL
2728 || cp_reg_required_here (&str, 16) == FAIL)
2729 {
2730 if (!inst.error)
2731 inst.error = bad_args;
2732 return;
2733 }
2734
2735 if (skip_past_comma (&str) == FAIL
2736 || cp_reg_required_here (&str, 0) == FAIL)
2737 {
2738 if (!inst.error)
2739 inst.error = bad_args;
2740 return;
2741 }
2742
2743 if (skip_past_comma (&str) == SUCCESS)
2744 {
2745 if (cp_opc_expr (&str, 5, 3) == FAIL)
2746 {
2747 if (!inst.error)
2748 inst.error = bad_args;
2749 return;
2750 }
2751 }
2752
2753 end_of_line (str);
2754 return;
2755}
2756
2757static void
2758do_lstc (str, flags)
2759 char *str;
2760 unsigned long flags;
2761{
2762 /* Co-processor register load/store.
2763 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
2764
2765 while (*str == ' ')
2766 str++;
2767
2768 if (co_proc_number (&str) == FAIL)
2769 {
2770 if (!inst.error)
2771 inst.error = bad_args;
2772 return;
2773 }
2774
2775 if (skip_past_comma (&str) == FAIL
2776 || cp_reg_required_here (&str, 12) == FAIL)
2777 {
2778 if (!inst.error)
2779 inst.error = bad_args;
2780 return;
2781 }
2782
2783 if (skip_past_comma (&str) == FAIL
2784 || cp_address_required_here (&str) == FAIL)
2785 {
2786 if (! inst.error)
2787 inst.error = bad_args;
2788 return;
2789 }
2790
2791 inst.instruction |= flags;
2792 end_of_line (str);
2793 return;
2794}
2795
2796static void
2797do_co_reg (str, flags)
2798 char *str;
2799 unsigned long flags;
2800{
2801 /* Co-processor register transfer.
2802 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
2803
2804 while (*str == ' ')
2805 str++;
2806
2807 if (co_proc_number (&str) == FAIL)
2808 {
2809 if (!inst.error)
2810 inst.error = bad_args;
2811 return;
2812 }
2813
2814 if (skip_past_comma (&str) == FAIL
2815 || cp_opc_expr (&str, 21, 3) == FAIL)
2816 {
2817 if (!inst.error)
2818 inst.error = bad_args;
2819 return;
2820 }
2821
2822 if (skip_past_comma (&str) == FAIL
2823 || reg_required_here (&str, 12) == FAIL)
2824 {
2825 if (!inst.error)
2826 inst.error = bad_args;
2827 return;
2828 }
2829
2830 if (skip_past_comma (&str) == FAIL
2831 || cp_reg_required_here (&str, 16) == FAIL)
2832 {
2833 if (!inst.error)
2834 inst.error = bad_args;
2835 return;
2836 }
2837
2838 if (skip_past_comma (&str) == FAIL
2839 || cp_reg_required_here (&str, 0) == FAIL)
2840 {
2841 if (!inst.error)
2842 inst.error = bad_args;
2843 return;
2844 }
2845
2846 if (skip_past_comma (&str) == SUCCESS)
2847 {
2848 if (cp_opc_expr (&str, 5, 3) == FAIL)
2849 {
2850 if (!inst.error)
2851 inst.error = bad_args;
2852 return;
2853 }
2854 }
2855
2856 end_of_line (str);
2857 return;
2858}
2859
2860static void
2861do_fp_ctrl (str, flags)
2862 char *str;
2863 unsigned long flags;
2864{
2865 /* FP control registers.
2866 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
2867
2868 while (*str == ' ')
2869 str++;
2870
2871 if (reg_required_here (&str, 12) == FAIL)
2872 {
2873 if (!inst.error)
2874 inst.error = bad_args;
2875 return;
2876 }
2877
2878 end_of_line (str);
2879 return;
2880}
2881
2882static void
2883do_fp_ldst (str, flags)
2884 char *str;
2885 unsigned long flags;
2886{
2887 while (*str == ' ')
2888 str++;
2889
2890 switch (inst.suffix)
2891 {
2892 case SUFF_S:
2893 break;
2894 case SUFF_D:
2895 inst.instruction |= CP_T_X;
2896 break;
2897 case SUFF_E:
2898 inst.instruction |= CP_T_Y;
2899 break;
2900 case SUFF_P:
2901 inst.instruction |= CP_T_X | CP_T_Y;
2902 break;
2903 default:
2904 abort ();
2905 }
2906
2907 if (fp_reg_required_here (&str, 12) == FAIL)
2908 {
2909 if (!inst.error)
2910 inst.error = bad_args;
2911 return;
2912 }
2913
2914 if (skip_past_comma (&str) == FAIL
2915 || cp_address_required_here (&str) == FAIL)
2916 {
2917 if (!inst.error)
2918 inst.error = bad_args;
2919 return;
2920 }
2921
2922 end_of_line (str);
2923}
2924
2925static void
2926do_fp_ldmstm (str, flags)
2927 char *str;
2928 unsigned long flags;
2929{
2930 int num_regs;
2931
2932 while (*str == ' ')
2933 str++;
2934
2935 if (fp_reg_required_here (&str, 12) == FAIL)
2936 {
2937 if (! inst.error)
2938 inst.error = bad_args;
2939 return;
2940 }
2941
2942 /* Get Number of registers to transfer */
2943 if (skip_past_comma (&str) == FAIL
2944 || my_get_expression (&inst.reloc.exp, &str))
2945 {
2946 if (! inst.error)
2947 inst.error = "constant expression expected";
2948 return;
2949 }
2950
2951 if (inst.reloc.exp.X_op != O_constant)
2952 {
2953 inst.error = "Constant value required for number of registers";
2954 return;
2955 }
2956
2957 num_regs = inst.reloc.exp.X_add_number;
2958
2959 if (num_regs < 1 || num_regs > 4)
2960 {
2961 inst.error = "number of registers must be in the range [1:4]";
2962 return;
2963 }
2964
2965 switch (num_regs)
2966 {
2967 case 1:
2968 inst.instruction |= CP_T_X;
2969 break;
2970 case 2:
2971 inst.instruction |= CP_T_Y;
2972 break;
2973 case 3:
2974 inst.instruction |= CP_T_Y | CP_T_X;
2975 break;
2976 case 4:
2977 break;
2978 default:
2979 abort ();
2980 }
2981
2982 if (flags)
2983 {
2984 int reg;
2985 int write_back;
2986 int offset;
2987
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
2993 || *str != '[')
2994 {
2995 if (! inst.error)
2996 inst.error = bad_args;
2997 return;
2998 }
2999
3000 str++;
3001 while (*str == ' ')
3002 str++;
3003
3004 if ((reg = reg_required_here (&str, 16)) == FAIL)
3005 {
3006 inst.error = "Register required";
3007 return;
3008 }
3009
3010 while (*str == ' ')
3011 str++;
3012
3013 if (*str != ']')
3014 {
3015 inst.error = bad_args;
3016 return;
3017 }
3018
3019 str++;
3020 if (*str == '!')
3021 {
3022 write_back = 1;
3023 str++;
3024 if (reg == REG_PC)
3025 {
3026 inst.error = "R15 not allowed as base register with write-back";
3027 return;
3028 }
3029 }
3030 else
3031 write_back = 0;
3032
3033 if (flags & CP_T_Pre)
3034 {
3035 /* Pre-decrement */
3036 offset = 3 * num_regs;
3037 if (write_back)
3038 flags |= CP_T_WB;
3039 }
3040 else
3041 {
3042 /* Post-increment */
3043 if (write_back)
3044 {
3045 flags |= CP_T_WB;
3046 offset = 3 * num_regs;
3047 }
3048 else
3049 {
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;
3053 offset = 0;
3054 }
3055 }
3056
3057 inst.instruction |= flags | offset;
3058 }
3059 else if (skip_past_comma (&str) == FAIL
3060 || cp_address_required_here (&str) == FAIL)
3061 {
3062 if (! inst.error)
3063 inst.error = bad_args;
3064 return;
3065 }
3066
3067 end_of_line (str);
3068}
3069
3070static void
3071do_fp_dyadic (str, flags)
3072 char *str;
3073 unsigned long flags;
3074{
3075 while (*str == ' ')
3076 str++;
3077
3078 switch (inst.suffix)
3079 {
3080 case SUFF_S:
3081 break;
3082 case SUFF_D:
3083 inst.instruction |= 0x00000080;
3084 break;
3085 case SUFF_E:
3086 inst.instruction |= 0x00080000;
3087 break;
3088 default:
3089 abort ();
3090 }
3091
3092 if (fp_reg_required_here (&str, 12) == FAIL)
3093 {
3094 if (! inst.error)
3095 inst.error = bad_args;
3096 return;
3097 }
3098
3099 if (skip_past_comma (&str) == FAIL
3100 || fp_reg_required_here (&str, 16) == FAIL)
3101 {
3102 if (! inst.error)
3103 inst.error = bad_args;
3104 return;
3105 }
3106
3107 if (skip_past_comma (&str) == FAIL
3108 || fp_op2 (&str) == FAIL)
3109 {
3110 if (! inst.error)
3111 inst.error = bad_args;
3112 return;
3113 }
3114
3115 inst.instruction |= flags;
3116 end_of_line (str);
3117 return;
3118}
3119
3120static void
3121do_fp_monadic (str, flags)
3122 char *str;
3123 unsigned long flags;
3124{
3125 while (*str == ' ')
3126 str++;
3127
3128 switch (inst.suffix)
3129 {
3130 case SUFF_S:
3131 break;
3132 case SUFF_D:
3133 inst.instruction |= 0x00000080;
3134 break;
3135 case SUFF_E:
3136 inst.instruction |= 0x00080000;
3137 break;
3138 default:
3139 abort ();
3140 }
3141
3142 if (fp_reg_required_here (&str, 12) == FAIL)
3143 {
3144 if (! inst.error)
3145 inst.error = bad_args;
3146 return;
3147 }
3148
3149 if (skip_past_comma (&str) == FAIL
3150 || fp_op2 (&str) == FAIL)
3151 {
3152 if (! inst.error)
3153 inst.error = bad_args;
3154 return;
3155 }
3156
3157 inst.instruction |= flags;
3158 end_of_line (str);
3159 return;
3160}
3161
3162static void
3163do_fp_cmp (str, flags)
3164 char *str;
3165 unsigned long flags;
3166{
3167 while (*str == ' ')
3168 str++;
3169
3170 if (fp_reg_required_here (&str, 16) == FAIL)
3171 {
3172 if (! inst.error)
3173 inst.error = bad_args;
3174 return;
3175 }
3176
3177 if (skip_past_comma (&str) == FAIL
3178 || fp_op2 (&str) == FAIL)
3179 {
3180 if (! inst.error)
3181 inst.error = bad_args;
3182 return;
3183 }
3184
3185 inst.instruction |= flags;
3186 end_of_line (str);
3187 return;
3188}
3189
3190static void
3191do_fp_from_reg (str, flags)
3192 char *str;
3193 unsigned long flags;
3194{
3195 while (*str == ' ')
3196 str++;
3197
3198 switch (inst.suffix)
3199 {
3200 case SUFF_S:
3201 break;
3202 case SUFF_D:
3203 inst.instruction |= 0x00000080;
3204 break;
3205 case SUFF_E:
3206 inst.instruction |= 0x00080000;
3207 break;
3208 default:
3209 abort ();
3210 }
3211
3212 if (fp_reg_required_here (&str, 16) == FAIL)
3213 {
3214 if (! inst.error)
3215 inst.error = bad_args;
3216 return;
3217 }
3218
3219 if (skip_past_comma (&str) == FAIL
3220 || reg_required_here (&str, 12) == FAIL)
3221 {
3222 if (! inst.error)
3223 inst.error = bad_args;
3224 return;
3225 }
3226
3227 inst.instruction |= flags;
3228 end_of_line (str);
3229 return;
3230}
3231
3232static void
3233do_fp_to_reg (str, flags)
3234 char *str;
3235 unsigned long flags;
3236{
3237 while (*str == ' ')
3238 str++;
3239
3240 if (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 || fp_reg_required_here (&str, 0) == FAIL)
3249 {
3250 if (! inst.error)
3251 inst.error = bad_args;
3252 return;
3253 }
3254
3255 inst.instruction |= flags;
3256 end_of_line (str);
3257 return;
3258}
3259
3260static void
3261insert_reg (entry)
3262 int entry;
3263{
3264 int len = strlen (reg_table[entry].name) + 2;
3265 char *buf = (char *) xmalloc (len);
3266 char *buf2 = (char *) xmalloc (len);
3267 int i = 0;
3268
3269#ifdef REGISTER_PREFIX
3270 buf[i++] = REGISTER_PREFIX;
3271#endif
3272
3273 strcpy (buf + i, reg_table[entry].name);
3274
3275 for (i = 0; buf[i]; i++)
3276 buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i];
3277
3278 buf2[i] = '\0';
3279
3280 hash_insert (arm_reg_hsh, buf, (PTR) &reg_table[entry]);
3281 hash_insert (arm_reg_hsh, buf2, (PTR) &reg_table[entry]);
3282}
3283
3284static void
3285insert_reg_alias (str, regnum)
3286 char *str;
3287 int regnum;
3288{
3289 struct reg_entry *new =
3290 (struct reg_entry *)xmalloc (sizeof (struct reg_entry));
3291 char *name = xmalloc (strlen (str) + 1);
3292 strcpy (name, str);
3293
3294 new->name = name;
3295 new->number = regnum;
3296
3297 hash_insert (arm_reg_hsh, name, (PTR) new);
3298}
3299
3300static void
3301set_constant_flonums ()
3302{
3303 int i;
3304
3305 for (i = 0; i < NUM_FLOAT_VALS; i++)
3306 if (atof_ieee ((char *)fp_const[i], 'x', fp_values[i]) == NULL)
3307 abort ();
3308}
3309
3310void
3311md_begin ()
3312{
3313 int i;
3314
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");
3321
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));
3330
3331 for (i = 0; reg_table[i].name; i++)
3332 insert_reg (i);
3333
3334 set_constant_flonums ();
3335}
3336
338a7060
DE
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)
3343 */
3344void
3345md_number_to_chars (buf, val, n)
3346 char *buf;
3347 valueT val;
3348 int n;
3349{
3350 if (target_big_endian)
3351 number_to_chars_bigendian (buf, val, n);
3352 else
3353 number_to_chars_littleendian (buf, val, n);
3354}
3355
3356static valueT
3357md_chars_to_number (buf, n)
3358 char *buf;
3359 int n;
3360{
3361 valueT result = 0;
3362 unsigned char *where = (unsigned char *) buf;
3363
3364 if (target_big_endian)
3365 {
3366 while (n--)
3367 {
3368 result <<= 8;
3369 result |= (*where++ & 255);
3370 }
3371 }
3372 else
3373 {
3374 while (n--)
3375 {
3376 result <<= 8;
3377 result |= (where[n] & 255);
3378 }
3379 }
3380
3381 return result;
3382}
3383
c479fc62
JSC
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.
3388
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.
3395
3396 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
338a7060 3397
338a7060
DE
3398char *
3399md_atof (type, litP, sizeP)
3400 char type;
3401 char *litP;
3402 int *sizeP;
3403{
3404 int prec;
3405 LITTLENUM_TYPE words[MAX_LITTLENUMS];
338a7060 3406 char *t;
c479fc62 3407 int i;
338a7060
DE
3408
3409 switch (type)
3410 {
338a7060
DE
3411 case 'f':
3412 case 'F':
3413 case 's':
3414 case 'S':
3415 prec = 2;
3416 break;
3417
3418 case 'd':
3419 case 'D':
3420 case 'r':
3421 case 'R':
3422 prec = 4;
3423 break;
3424
3425 case 'x':
3426 case 'X':
3427 prec = 6;
3428 break;
3429
3430 case 'p':
3431 case 'P':
3432 prec = 6;
3433 break;
3434
3435 default:
3436 *sizeP = 0;
3437 return "Bad call to MD_ATOF()";
3438 }
c479fc62 3439
338a7060
DE
3440 t = atof_ieee (input_line_pointer, type, words);
3441 if (t)
3442 input_line_pointer = t;
c479fc62
JSC
3443 *sizeP = prec * 2;
3444
3445 if (target_big_endian)
338a7060 3446 {
c479fc62
JSC
3447 for (i = 0; i < prec; i++)
3448 {
3449 md_number_to_chars (litP, (valueT) words[i], 2);
3450 litP += 2;
3451 }
338a7060 3452 }
c479fc62
JSC
3453 else
3454 {
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)
3458 {
3459 md_number_to_chars (litP, (valueT) words[i + 1], 2);
3460 md_number_to_chars (litP + 2, (valueT) words[i], 2);
3461 litP += 4;
3462 }
3463 }
3464
338a7060
DE
3465 return 0;
3466}
3467
3468/* We have already put the pipeline compensation in the instruction */
3469
3470long
3471md_pcrel_from (fixP)
3472 fixS *fixP;
3473{
3474 if (fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
3475 && fixP->fx_subsy == NULL)
3476 return 0; /* HACK */
3477
3478 return fixP->fx_where + fixP->fx_frag->fr_address;
3479}
3480
3481/* Round up a section size to the appropriate boundary. */
3482valueT
3483md_section_align (segment, size)
3484 segT segment;
3485 valueT size;
3486{
3487 /* Round all sects to multiple of 4 */
3488 return (size + 3) & ~3;
3489}
3490
3491/* We have no need to default values of symbols. */
3492
3493/* ARGSUSED */
3494symbolS *
3495md_undefined_symbol (name)
3496 char *name;
3497{
3498 return 0;
3499}
3500
3501/* arm_reg_parse () := if it looks like a register, return its token and
3502 advance the pointer. */
3503
3504static int
3505arm_reg_parse (ccp)
3506 register char **ccp;
3507{
3508 char *start = *ccp;
3509 char c;
3510 char *p;
3511 struct reg_entry *reg;
3512
3513#ifdef REGISTER_PREFIX
3514 if (*start != REGISTER_PREFIX)
3515 return FAIL;
3516 p = start + 1;
3517#else
3518 p = start;
3519#ifdef OPTIONAL_REGISTER_PREFIX
3520 if (*p == OPTIONAL_REGISTER_PREFIX)
3521 p++, start++;
3522#endif
3523#endif
3524 if (!isalpha (*p) || !is_name_beginner (*p))
3525 return FAIL;
3526
3527 c = *p++;
3528 while (isalpha (c) || isdigit (c) || c == '_')
3529 c = *p++;
3530
3531 *--p = 0;
3532 reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
3533 *p = c;
3534
3535 if (reg)
3536 {
3537 *ccp = p;
3538 return reg->number;
3539 }
3540
3541 return FAIL;
3542}
3543
3544static int
3545arm_psr_parse (ccp)
3546 register char **ccp;
3547{
3548 char *start = *ccp;
3549 char c, *p;
3550 CONST struct asm_psr *psr;
3551
3552 p = start;
3553 c = *p++;
3554 while (isalpha (c) || c == '_')
3555 c = *p++;
3556
3557 *--p = 0;
3558 psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
3559 *p = c;
3560
3561 if (psr)
3562 {
3563 *ccp = p;
3564 return psr->number;
3565 }
3566
3567 return FAIL;
3568}
3569
3570int
c479fc62 3571md_apply_fix3 (fixP, val, seg)
338a7060
DE
3572 fixS *fixP;
3573 valueT *val;
c479fc62 3574 segT seg;
338a7060
DE
3575{
3576 offsetT value = *val;
3577 offsetT newval, temp;
3578 int sign;
3579 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
3580
3581 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
3582
338a7060
DE
3583 /* Note whether this will delete the relocation. */
3584 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
3585 fixP->fx_done = 1;
3586
c479fc62
JSC
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. */
3590 if (fixP->fx_pcrel)
3591 {
3592 if (S_IS_DEFINED (fixP->fx_addsy)
3593 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
3594 value += md_pcrel_from (fixP);
3595 }
3596
3597 fixP->fx_addnumber = value; /* Remember value for emit_reloc */
3598
338a7060
DE
3599 switch (fixP->fx_r_type)
3600 {
3601 case BFD_RELOC_ARM_IMMEDIATE:
3602 newval = validate_immediate (value);
c479fc62 3603 temp = md_chars_to_number (buf, insn_size);
338a7060
DE
3604
3605 /* If the instruction will fail, see if we can fix things up by
3606 changing the opcode. */
3607 if (newval == FAIL
3608 && (newval = negate_data_op (&temp, value)) == FAIL)
3609 {
3610 as_bad_where (fixP->fx_file, fixP->fx_line,
3611 "invalid constant after fixup\n");
3612 break;
3613 }
3614
3615 newval |= (temp & 0xfffff000);
c479fc62 3616 md_number_to_chars (buf, newval, insn_size);
338a7060
DE
3617 break;
3618
c479fc62 3619 case BFD_RELOC_ARM_OFFSET_IMM:
338a7060 3620 sign = value >= 0;
c479fc62
JSC
3621 if ((value = validate_offset_imm (value, 0)) == FAIL)
3622 {
3623 as_bad ("bad immediate value for offset (%d)", val);
3624 break;
3625 }
338a7060
DE
3626 if (value < 0)
3627 value = -value;
3628
c479fc62 3629 newval = md_chars_to_number (buf, insn_size);
338a7060
DE
3630 newval &= 0xff7ff000;
3631 newval |= value | (sign ? 0x00800000 : 0);
c479fc62
JSC
3632 md_number_to_chars (buf, newval, insn_size);
3633 break;
3634
3635 case BFD_RELOC_ARM_OFFSET_IMM8:
3636 case BFD_RELOC_ARM_HWLITERAL:
3637 sign = value >= 0;
3638 if ((value = validate_offset_imm (value, 1)) == FAIL)
3639 {
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");
3643 else
3644 as_bad ("bad immediate value for offset (%d)", value);
3645 break;
3646 }
3647
3648 if (value < 0)
3649 value = -value;
3650
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);
338a7060
DE
3655 break;
3656
3657 case BFD_RELOC_ARM_LITERAL:
3658 sign = value >= 0;
3659 if (value < 0)
3660 value = -value;
3661
c479fc62 3662 if ((value = validate_offset_imm (value, 0)) == FAIL)
338a7060
DE
3663 {
3664 as_bad_where (fixP->fx_file, fixP->fx_line,
3665 "invalid literal constant: pool needs to be closer\n");
3666 break;
3667 }
3668
c479fc62 3669 newval = md_chars_to_number (buf, insn_size);
338a7060
DE
3670 newval &= 0xff7ff000;
3671 newval |= value | (sign ? 0x00800000 : 0);
c479fc62 3672 md_number_to_chars (buf, newval, insn_size);
338a7060
DE
3673 break;
3674
3675 case BFD_RELOC_ARM_SHIFT_IMM:
c479fc62 3676 newval = md_chars_to_number (buf, insn_size);
338a7060
DE
3677 if (((unsigned long) value) > 32
3678 || (value == 32
3679 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
3680 {
3681 as_bad_where (fixP->fx_file, fixP->fx_line,
3682 "shift expression is too large");
3683 break;
3684 }
3685
3686 if (value == 0)
3687 newval &= ~0x60; /* Shifts of zero must be done as lsl */
3688 else if (value == 32)
3689 value = 0;
3690 newval &= 0xfffff07f;
3691 newval |= (value & 0x1f) << 7;
c479fc62 3692 md_number_to_chars (buf, newval , insn_size);
338a7060
DE
3693 break;
3694
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");
c479fc62 3698 newval = md_chars_to_number (buf, insn_size) & 0xff000000;
338a7060 3699 newval |= value;
c479fc62 3700 md_number_to_chars (buf, newval , insn_size);
338a7060
DE
3701 break;
3702
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");
c479fc62
JSC
3707 newval = value | md_chars_to_number (buf, insn_size);
3708 md_number_to_chars (buf, newval, insn_size);
338a7060
DE
3709 break;
3710
3711 case BFD_RELOC_ARM_PCREL_BRANCH:
3712 value = (value >> 2) & 0x00ffffff;
c479fc62 3713 newval = md_chars_to_number (buf, insn_size);
338a7060
DE
3714 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
3715 newval = value | (newval & 0xff000000);
c479fc62 3716 md_number_to_chars (buf, newval, insn_size);
338a7060
DE
3717 break;
3718
3719 case BFD_RELOC_8:
3720 if (fixP->fx_done || fixP->fx_pcrel)
3721 md_number_to_chars (buf, value, 1);
3722 break;
3723
3724 case BFD_RELOC_16:
3725 if (fixP->fx_done || fixP->fx_pcrel)
3726 md_number_to_chars (buf, value, 2);
3727 break;
3728
c479fc62 3729 case BFD_RELOC_RVA:
338a7060
DE
3730 case BFD_RELOC_32:
3731 if (fixP->fx_done || fixP->fx_pcrel)
3732 md_number_to_chars (buf, value, 4);
3733 break;
3734
3735 case BFD_RELOC_ARM_CP_OFF_IMM:
3736 sign = value >= 0;
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");
3740 if (value < 0)
3741 value = -value;
c479fc62 3742 newval = md_chars_to_number (buf, insn_size) & 0xff7fff00;
338a7060 3743 newval |= (value >> 2) | (sign ? 0x00800000 : 0);
c479fc62 3744 md_number_to_chars (buf, newval , insn_size);
338a7060
DE
3745 break;
3746
3747 case BFD_RELOC_NONE:
3748 default:
3749 as_bad_where (fixP->fx_file, fixP->fx_line,
3750 "Bad relocation fixup type (%d)\n", fixP->fx_r_type);
3751 }
3752
3753 return 1;
3754}
3755
3756/* Translate internal representation of relocation info to BFD target
3757 format. */
3758arelent *
3759tc_gen_reloc (section, fixp)
3760 asection *section;
3761 fixS *fixp;
3762{
3763 arelent *reloc;
3764 bfd_reloc_code_real_type code;
3765
3766 reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
3767 assert (reloc != 0);
3768
3769 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
3770 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3771
338a7060
DE
3772 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
3773 if (fixp->fx_pcrel == 0)
3774 reloc->addend = fixp->fx_offset;
3775 else
3776 reloc->addend = fixp->fx_offset = reloc->address;
3777
3778 switch (fixp->fx_r_type)
3779 {
3780 case BFD_RELOC_8:
3781 if (fixp->fx_pcrel)
3782 {
3783 code = BFD_RELOC_8_PCREL;
3784 break;
3785 }
3786
3787 case BFD_RELOC_16:
3788 if (fixp->fx_pcrel)
3789 {
3790 code = BFD_RELOC_16_PCREL;
3791 break;
3792 }
3793
3794 case BFD_RELOC_32:
3795 if (fixp->fx_pcrel)
3796 {
3797 code = BFD_RELOC_32_PCREL;
3798 break;
3799 }
3800
3801 case BFD_RELOC_ARM_PCREL_BRANCH:
c479fc62 3802 case BFD_RELOC_RVA:
338a7060
DE
3803 code = fixp->fx_r_type;
3804 break;
3805
3806 case BFD_RELOC_ARM_LITERAL:
c479fc62 3807 case BFD_RELOC_ARM_HWLITERAL:
338a7060
DE
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?)");
3811 return NULL;
3812
3813 case BFD_RELOC_ARM_IMMEDIATE:
3814 as_bad ("Internal_relocation (type %d) not fixed up (IMMEDIATE)"
3815 , fixp->fx_r_type);
3816 return NULL;
3817
3818 case BFD_RELOC_ARM_OFFSET_IMM:
3819 as_bad ("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"
3820 , fixp->fx_r_type);
3821 return NULL;
3822
c479fc62
JSC
3823 case BFD_RELOC_ARM_OFFSET_IMM8:
3824 as_bad ("Internal_relocation (type %d) not fixed up (OFFSET_IMM8)"
3825 , fixp->fx_r_type);
3826 return NULL;
3827
338a7060
DE
3828 case BFD_RELOC_ARM_SHIFT_IMM:
3829 as_bad ("Internal_relocation (type %d) not fixed up (SHIFT_IMM)"
3830 , fixp->fx_r_type);
3831 return NULL;
3832
3833 case BFD_RELOC_ARM_SWI:
3834 as_bad ("Internal_relocation (type %d) not fixed up (SWI)"
3835 , fixp->fx_r_type);
3836 return NULL;
3837
3838 case BFD_RELOC_ARM_MULTI:
3839 as_bad ("Internal_relocation (type %d) not fixed up (MULTI)"
3840 , fixp->fx_r_type);
3841 return NULL;
3842
3843 case BFD_RELOC_ARM_CP_OFF_IMM:
3844 as_bad ("Internal_relocation (type %d) not fixed up (CP_OFF_IMM)"
3845 , fixp->fx_r_type);
3846 return NULL;
3847
3848 default:
3849 abort ();
3850 }
3851
3852 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
3853 assert (reloc->howto != 0);
3854
3855 return reloc;
3856}
3857
3858CONST int md_short_jump_size = 4;
3859CONST int md_long_jump_size = 4;
3860
3861/* These should never be called on the arm */
3862void
3863md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
3864 char *ptr;
3865 addressT from_addr, to_addr;
3866 fragS *frag;
3867 symbolS *to_symbol;
3868{
3869 as_fatal ("md_create_long_jump\n");
3870}
3871
3872void
3873md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
3874 char *ptr;
3875 addressT from_addr, to_addr;
3876 fragS *frag;
3877 symbolS *to_symbol;
3878{
3879 as_fatal ("md_create_short_jump\n");
3880}
3881
3882int
3883md_estimate_size_before_relax (fragP, segtype)
3884 fragS *fragP;
3885 segT segtype;
3886{
3887 as_fatal ("md_estimate_size_before_relax\n");
3888 return (1);
3889}
3890
3891void
3892output_inst (str)
3893 char *str;
3894{
3895 char *to = NULL;
3896
3897 if (inst.error)
3898 {
3899 as_bad ("%s -- statement `%s'\n", inst.error, str);
3900 return;
3901 }
3902
c479fc62
JSC
3903 to = frag_more (insn_size);
3904 md_number_to_chars (to, inst.instruction, insn_size);
338a7060
DE
3905
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,
3909 inst.reloc.type);
3910
3911 return;
3912}
3913
3914void
3915md_assemble (str)
3916 char *str;
3917{
3918 char c;
3919 CONST struct asm_opcode *opcode;
3920 char *p, *q, *start;
3921
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 */
3926
3927 /* Align the previous label if needed */
3928 if (last_label_seen != NULL)
3929 {
3930 last_label_seen->sy_frag = frag_now;
c479fc62 3931 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
338a7060
DE
3932 S_SET_SEGMENT (last_label_seen, now_seg);
3933 }
3934
3935 memset (&inst, '\0', sizeof (inst));
3936 inst.reloc.type = BFD_RELOC_NONE;
3937
3938 if (*str == ' ')
3939 str++; /* Skip leading white space */
3940
3941 /* scan up to the end of the op-code, which must end in white space or
3942 end of string */
3943 for (start = p = str; *p != '\0'; p++)
3944 if (*p == ' ')
3945 break;
3946
3947 if (p == str)
3948 {
3949 as_bad ("No operator -- statement `%s'\n", str);
3950 return;
3951 }
3952
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--)
3959 {
3960 c = *q;
3961 *q = '\0';
3962 opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
3963 *q = c;
3964 if (opcode && opcode->template)
3965 {
3966 unsigned long flag_bits = 0;
3967 char *r;
3968
3969 /* Check that this instruction is supported for this CPU */
3970 if ((opcode->variants & cpu_variant) == 0)
3971 goto try_shorter;
3972
3973 inst.instruction = opcode->value;
3974 if (q == p) /* Just a simple opcode */
3975 {
3976 if (opcode->comp_suffix != 0)
3977 as_bad ("Opcode `%s' must have suffix from <%s>\n", str,
3978 opcode->comp_suffix);
3979 else
3980 {
3981 inst.instruction |= COND_ALWAYS;
3982 (*opcode->parms)(q, 0);
3983 }
3984 output_inst (start);
3985 return;
3986 }
3987
3988 /* Now check for a conditional */
3989 r = q;
3990 if (p - r >= 2)
3991 {
3992 CONST struct asm_cond *cond;
3993 char d = *(r + 2);
3994
3995 *(r + 2) = '\0';
3996 cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
3997 *(r + 2) = d;
3998 if (cond)
3999 {
4000 if (cond->value == 0xf0000000)
4001 as_tsktsk
4002 ("Warning: Use of the 'nv' conditional is deprecated\n");
4003
4004 inst.instruction |= cond->value;
4005 r += 2;
4006 }
4007 else
4008 inst.instruction |= COND_ALWAYS;
4009 }
4010 else
4011 inst.instruction |= COND_ALWAYS;
4012
4013 /* if there is a compulsory suffix, it should come here, before
4014 any optional flags. */
4015 if (opcode->comp_suffix)
4016 {
4017 CONST char *s = opcode->comp_suffix;
4018
4019 while (*s)
4020 {
4021 inst.suffix++;
4022 if (*r == *s)
4023 break;
4024 s++;
4025 }
4026
4027 if (*s == '\0')
4028 {
4029 as_bad ("Opcode `%s' must have suffix from <%s>\n", str,
4030 opcode->comp_suffix);
4031 return;
4032 }
4033
4034 r++;
4035 }
4036
4037 /* The remainder, if any should now be flags for the instruction;
4038 Scan these checking each one found with the opcode. */
4039 if (r != p)
4040 {
4041 char d;
4042 CONST struct asm_flg *flag = opcode->flags;
4043
4044 if (flag)
4045 {
4046 int flagno;
4047
4048 d = *p;
4049 *p = '\0';
4050
4051 for (flagno = 0; flag[flagno].template; flagno++)
4052 {
c479fc62
JSC
4053 if ((flag[flagno].variants & cpu_variant) != 0
4054 && (! strcmp (r, flag[flagno].template)))
338a7060
DE
4055 {
4056 flag_bits |= flag[flagno].set_bits;
4057 break;
4058 }
4059 }
4060
4061 *p = d;
4062 if (! flag[flagno].template)
4063 goto try_shorter;
4064 }
4065 else
4066 goto try_shorter;
4067 }
4068
4069 (*opcode->parms) (p, flag_bits);
4070 output_inst (start);
4071 return;
4072 }
4073
4074 try_shorter:
4075 ;
4076 }
4077 /* It wasn't an instruction, but it might be a register alias of the form
4078 alias .req reg
4079 */
4080 q = p;
4081 while (*q == ' ')
4082 q++;
4083
4084 c = *p;
4085 *p = '\0';
4086
4087 if (*q && !strncmp (q, ".req ", 4))
4088 {
4089 int reg;
4090 if ((reg = arm_reg_parse (&str)) == FAIL)
4091 {
4092 char *r;
4093
4094 q += 4;
4095 while (*q == ' ')
4096 q++;
4097
4098 for (r = q; *r != '\0'; r++)
4099 if (*r == ' ')
4100 break;
4101
4102 if (r != q)
4103 {
4104 int regnum;
4105 char d = *r;
4106
4107 *r = '\0';
4108 regnum = arm_reg_parse (&q);
4109 *r = d;
4110 if (regnum != FAIL)
4111 {
4112 insert_reg_alias (str, regnum);
4113 *p = c;
4114 return;
4115 }
4116 }
4117 }
4118 else
4119 {
4120 *p = c;
4121 return;
4122 }
4123 }
4124
4125 *p = c;
4126 as_bad ("bad instruction `%s'", start);
4127}
4128
4129/*
4130 * md_parse_option
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
c479fc62
JSC
4137 * -m[arm]6, Arm 6 processors
4138 * -m[arm]7[t][[d]m] Arm 7 processors
338a7060
DE
4139 * -mall All (except the ARM1)
4140 * FP variants:
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
4147 */
4148
4149CONST char *md_shortopts = "m:";
4150struct 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},
4156#endif
4157 {NULL, no_argument, NULL, 0}
4158};
4159size_t md_longopts_size = sizeof(md_longopts);
4160
4161int
4162md_parse_option (c, arg)
4163 int c;
4164 char *arg;
4165{
4166 char *str = arg;
4167
4168 switch (c)
4169 {
4170#ifdef ARM_BI_ENDIAN
4171 case OPTION_EB:
4172 target_big_endian = 1;
4173 break;
4174 case OPTION_EL:
4175 target_big_endian = 0;
4176 break;
4177#endif
4178
4179 case 'm':
4180 switch (*str)
4181 {
4182 case 'f':
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;
4189 else
4190 goto bad;
4191 break;
4192
4193 case 'n':
4194 if (! strcmp (str, "no-fpu"))
4195 cpu_variant &= ~FPU_ALL;
4196 break;
4197
4198 default:
4199 if (! strcmp (str, "all"))
4200 {
4201 cpu_variant = ARM_ALL | FPU_ALL;
4202 return 1;
4203 }
4204
4205 /* Strip off optional "arm" */
4206 if (! strncmp (str, "arm", 3))
4207 str += 3;
4208
4209 switch (*str)
4210 {
4211 case '1':
4212 if (! strcmp (str, "1"))
4213 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
4214 else
4215 goto bad;
4216 break;
4217
4218 case '2':
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;
4223 else
4224 goto bad;
4225 break;
4226
4227 case '3':
4228 if (! strcmp (str, "3"))
4229 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
4230 else
4231 goto bad;
4232 break;
4233
4234 case '6':
4235 if (! strcmp (str, "6"))
4236 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
4237 else
4238 goto bad;
4239 break;
4240
4241 case '7':
c479fc62
JSC
4242 str++; /* eat the '7' */
4243 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
4244 for (; *str; str++)
4245 {
4246 switch (*str)
4247 {
4248 case 't':
4249 cpu_variant |= ARM_HALFWORD;
4250 break;
4251
4252 case 'm':
4253 cpu_variant |= ARM_LONGMUL;
4254 break;
4255
4256 case 'd': /* debug */
4257 case 'i': /* embedded ice */
4258 /* Included for completeness in ARM processor
4259 naming. */
4260 break;
4261
4262 default:
4263 goto bad;
4264 }
4265 }
338a7060
DE
4266 break;
4267
4268 default:
4269 bad:
4270 as_bad ("Invalid architecture -m%s", arg);
4271 return 0;
4272 }
4273 }
4274 break;
4275
4276 default:
4277 return 0;
4278 }
4279
4280 return 1;
4281}
4282
4283void
4284md_show_usage (fp)
4285 FILE *fp;
4286{
4287 fprintf (fp,
c479fc62 4288"-m[arm]1, -m[arm]2, -m[arm]250,\n-m[arm]3, -m[arm]6, -m[arm]7[t][[d]m]\n\
338a7060
DE
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
4295 fprintf (fp,
4296"-EB\t\t\tassemble code for a big endian cpu\n\
4297-EL\t\t\tassemble code for a little endian cpu\n");
4298#endif
4299}
4300
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. */
4307
4308static void
4309fix_new_arm (frag, where, size, exp, pc_rel, reloc)
4310 fragS *frag;
4311 int where;
4312 short int size;
4313 expressionS *exp;
4314 int pc_rel;
4315 int reloc;
4316{
4317 fixS *new_fix;
4318
4319 switch (exp->X_op)
4320 {
4321 case O_constant:
4322 case O_symbol:
4323 case O_add:
4324 case O_subtract:
4325 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
4326 break;
4327
4328 default:
4329 {
4330 const char *fake;
4331 symbolS *symbolP;
4332
4333 /* FIXME: This should be something which decode_local_label_name
4334 will handle. */
4335 fake = FAKE_LABEL_NAME;
4336
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
4340 S_SET_SEGMENT. */
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);
4344 }
4345 break;
4346 }
4347
4348 return;
4349}
4350
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. */
4354void
4355arm_after_pass_hook (ignore)
4356 asection *ignore;
4357{
4358 if (current_poolP != NULL)
4359 {
4360 subseg_set (text_section, 0); /* Put it at the end of text section */
4361 s_ltorg (0);
4362 listing_prev_line ();
4363 }
4364}
4365
4366void
4367arm_start_line_hook ()
4368{
4369 last_label_seen = NULL;
4370}
4371
4372void
4373arm_frob_label (sym)
4374 symbolS *sym;
4375{
4376 last_label_seen = sym;
4377}
This page took 0.224408 seconds and 4 git commands to generate.