Add Dmitry Diky to maintainers list as msp430 maintainer
[deliverable/binutils-gdb.git] / gas / config / tc-arc.c
CommitLineData
252b5132 1/* tc-arc.c -- Assembler for the ARC
f17c130b 2 Copyright 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005
f7e42eb4 3 Free Software Foundation, Inc.
252b5132
RH
4 Contributed by Doug Evans (dje@cygnus.com).
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19203624
KH
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
252b5132
RH
22
23#include <stdio.h>
0d2bcfaf 24#include "libiberty.h"
252b5132 25#include "as.h"
a161fe53 26#include "struc-symbol.h"
3882b010 27#include "safe-ctype.h"
252b5132
RH
28#include "subsegs.h"
29#include "opcode/arc.h"
0d2bcfaf 30#include "../opcodes/arc-ext.h"
252b5132 31#include "elf/arc.h"
bcee8eb8 32#include "dwarf2dbg.h"
252b5132
RH
33
34extern int arc_get_mach PARAMS ((char *));
0d2bcfaf
NC
35extern int arc_operand_type PARAMS ((int));
36extern int arc_insn_not_jl PARAMS ((arc_insn));
37extern int arc_limm_fixup_adjust PARAMS ((arc_insn));
38extern int arc_get_noshortcut_flag PARAMS ((void));
39extern int arc_set_ext_seg PARAMS ((void));
19203624 40extern void arc_code_symbol PARAMS ((expressionS *));
252b5132
RH
41
42static arc_insn arc_insert_operand PARAMS ((arc_insn,
43 const struct arc_operand *, int,
44 const struct arc_operand_value *,
45 offsetT, char *, unsigned int));
46static void arc_common PARAMS ((int));
0d2bcfaf
NC
47static void arc_extinst PARAMS ((int));
48static void arc_extoper PARAMS ((int));
49static void arc_option PARAMS ((int));
89b57c9a 50static int get_arc_exp_reloc_type PARAMS ((int, int, expressionS *,
252b5132
RH
51 expressionS *));
52
89b57c9a
NC
53static void init_opcode_tables PARAMS ((int));
54
0d2bcfaf
NC
55const struct suffix_classes {
56 char *name;
57 int len;
58} suffixclass[] = {
59 { "SUFFIX_COND|SUFFIX_FLAG",23 },
60 { "SUFFIX_FLAG", 11 },
61 { "SUFFIX_COND", 11 },
62 { "SUFFIX_NONE", 11 }
63};
64
bfb32b52 65#define MAXSUFFIXCLASS (sizeof (suffixclass) / sizeof (struct suffix_classes))
0d2bcfaf
NC
66
67const struct syntax_classes {
68 char *name;
69 int len;
70 int class;
71} syntaxclass[] = {
72 { "SYNTAX_3OP|OP1_MUST_BE_IMM", 26, SYNTAX_3OP|OP1_MUST_BE_IMM|SYNTAX_VALID },
73 { "OP1_MUST_BE_IMM|SYNTAX_3OP", 26, OP1_MUST_BE_IMM|SYNTAX_3OP|SYNTAX_VALID },
74 { "SYNTAX_2OP|OP1_IMM_IMPLIED", 26, SYNTAX_2OP|OP1_IMM_IMPLIED|SYNTAX_VALID },
75 { "OP1_IMM_IMPLIED|SYNTAX_2OP", 26, OP1_IMM_IMPLIED|SYNTAX_2OP|SYNTAX_VALID },
76 { "SYNTAX_3OP", 10, SYNTAX_3OP|SYNTAX_VALID },
77 { "SYNTAX_2OP", 10, SYNTAX_2OP|SYNTAX_VALID }
78};
79
bfb32b52 80#define MAXSYNTAXCLASS (sizeof (syntaxclass) / sizeof (struct syntax_classes))
0d2bcfaf 81
19203624 82const pseudo_typeS md_pseudo_table[] = {
bcee8eb8 83 { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0). */
0d2bcfaf 84 { "comm", arc_common, 0 },
252b5132 85 { "common", arc_common, 0 },
0d2bcfaf
NC
86 { "lcomm", arc_common, 1 },
87 { "lcommon", arc_common, 1 },
88 { "2byte", cons, 2 },
89 { "half", cons, 2 },
90 { "short", cons, 2 },
91 { "3byte", cons, 3 },
92 { "4byte", cons, 4 },
252b5132 93 { "word", cons, 4 },
0d2bcfaf 94 { "option", arc_option, 0 },
bcee8eb8 95 { "cpu", arc_option, 0 },
0d2bcfaf
NC
96 { "block", s_space, 0 },
97 { "extcondcode", arc_extoper, 0 },
98 { "extcoreregister", arc_extoper, 1 },
99 { "extauxregister", arc_extoper, 2 },
100 { "extinstruction", arc_extinst, 0 },
252b5132
RH
101 { NULL, 0, 0 },
102};
103
104/* This array holds the chars that always start a comment. If the
bcee8eb8 105 pre-processor is disabled, these aren't very useful. */
252b5132
RH
106const char comment_chars[] = "#;";
107
108/* This array holds the chars that only start a comment at the beginning of
109 a line. If the line seems to have the form '# 123 filename'
110 .line and .file directives will appear in the pre-processed output */
111/* Note that input_file.c hand checks for '#' at the beginning of the
112 first line of the input file. This is because the compiler outputs
bfb32b52 113 #NO_APP at the beginning of its output. */
252b5132 114/* Also note that comments started like this one will always
bfb32b52 115 work if '/' isn't otherwise defined. */
252b5132
RH
116const char line_comment_chars[] = "#";
117
118const char line_separator_chars[] = "";
119
bcee8eb8 120/* Chars that can be used to separate mant from exp in floating point nums. */
252b5132
RH
121const char EXP_CHARS[] = "eE";
122
bcee8eb8
AM
123/* Chars that mean this number is a floating point constant
124 As in 0f12.456 or 0d1.2345e12. */
252b5132
RH
125const char FLT_CHARS[] = "rRsSfFdD";
126
127/* Byte order. */
128extern int target_big_endian;
129const char *arc_target_format = DEFAULT_TARGET_FORMAT;
130static int byte_order = DEFAULT_BYTE_ORDER;
131
0d2bcfaf
NC
132static segT arcext_section;
133
134/* One of bfd_mach_arc_n. */
bcee8eb8 135static int arc_mach_type = bfd_mach_arc_6;
252b5132
RH
136
137/* Non-zero if the cpu type has been explicitly specified. */
138static int mach_type_specified_p = 0;
139
140/* Non-zero if opcode tables have been initialized.
bcee8eb8 141 A .option command must appear before any instructions. */
252b5132
RH
142static int cpu_tables_init_p = 0;
143
144static struct hash_control *arc_suffix_hash = NULL;
145\f
146const char *md_shortopts = "";
19203624 147struct option md_longopts[] = {
252b5132 148#define OPTION_EB (OPTION_MD_BASE + 0)
bcee8eb8 149 { "EB", no_argument, NULL, OPTION_EB },
252b5132 150#define OPTION_EL (OPTION_MD_BASE + 1)
bcee8eb8 151 { "EL", no_argument, NULL, OPTION_EL },
0d2bcfaf 152#define OPTION_ARC5 (OPTION_MD_BASE + 2)
bcee8eb8
AM
153 { "marc5", no_argument, NULL, OPTION_ARC5 },
154 { "pre-v6", no_argument, NULL, OPTION_ARC5 },
0d2bcfaf 155#define OPTION_ARC6 (OPTION_MD_BASE + 3)
bcee8eb8 156 { "marc6", no_argument, NULL, OPTION_ARC6 },
0d2bcfaf 157#define OPTION_ARC7 (OPTION_MD_BASE + 4)
bcee8eb8 158 { "marc7", no_argument, NULL, OPTION_ARC7 },
0d2bcfaf 159#define OPTION_ARC8 (OPTION_MD_BASE + 5)
bcee8eb8 160 { "marc8", no_argument, NULL, OPTION_ARC8 },
0d2bcfaf 161#define OPTION_ARC (OPTION_MD_BASE + 6)
bcee8eb8 162 { "marc", no_argument, NULL, OPTION_ARC },
252b5132
RH
163 { NULL, no_argument, NULL, 0 }
164};
165size_t md_longopts_size = sizeof (md_longopts);
166
0d2bcfaf
NC
167#define IS_SYMBOL_OPERAND(o) \
168 ((o) == 'b' || (o) == 'c' || (o) == 's' || (o) == 'o' || (o) == 'O')
169
19203624 170struct arc_operand_value *get_ext_suffix (char *s);
0d2bcfaf 171
19203624
KH
172/* Invocation line includes a switch not recognized by the base assembler.
173 See if it's a processor-specific option. */
252b5132
RH
174
175int
176md_parse_option (c, arg)
177 int c;
4a314ec8 178 char *arg ATTRIBUTE_UNUSED;
252b5132
RH
179{
180 switch (c)
1e07b820 181 {
0d2bcfaf
NC
182 case OPTION_ARC5:
183 arc_mach_type = bfd_mach_arc_5;
184 break;
bcee8eb8 185 case OPTION_ARC:
0d2bcfaf
NC
186 case OPTION_ARC6:
187 arc_mach_type = bfd_mach_arc_6;
188 break;
189 case OPTION_ARC7:
190 arc_mach_type = bfd_mach_arc_7;
191 break;
192 case OPTION_ARC8:
193 arc_mach_type = bfd_mach_arc_8;
194 break;
252b5132
RH
195 case OPTION_EB:
196 byte_order = BIG_ENDIAN;
197 arc_target_format = "elf32-bigarc";
198 break;
199 case OPTION_EL:
200 byte_order = LITTLE_ENDIAN;
201 arc_target_format = "elf32-littlearc";
202 break;
203 default:
204 return 0;
1e07b820 205 }
252b5132
RH
206 return 1;
207}
208
209void
210md_show_usage (stream)
211 FILE *stream;
212{
0d2bcfaf
NC
213 fprintf (stream, "\
214ARC Options:\n\
215 -marc[5|6|7|8] select processor variant (default arc%d)\n\
216 -EB assemble code for a big endian cpu\n\
217 -EL assemble code for a little endian cpu\n", arc_mach_type + 5);
252b5132
RH
218}
219
220/* This function is called once, at assembler startup time. It should
221 set up all the tables, etc. that the MD part of the assembler will need.
bcee8eb8 222 Opcode selection is deferred until later because we might see a .option
252b5132
RH
223 command. */
224
225void
226md_begin ()
227{
228 /* The endianness can be chosen "at the factory". */
229 target_big_endian = byte_order == BIG_ENDIAN;
230
231 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
0d2bcfaf 232 as_warn ("could not set architecture and machine");
252b5132 233
bcee8eb8
AM
234 /* This call is necessary because we need to initialize `arc_operand_map'
235 which may be needed before we see the first insn. */
0d2bcfaf 236 arc_opcode_init_tables (arc_get_opcode_mach (arc_mach_type,
252b5132
RH
237 target_big_endian));
238}
239
240/* Initialize the various opcode and operand tables.
241 MACH is one of bfd_mach_arc_xxx. */
252b5132
RH
242static void
243init_opcode_tables (mach)
244 int mach;
245{
4a314ec8 246 int i;
252b5132
RH
247 char *last;
248
249 if ((arc_suffix_hash = hash_new ()) == NULL)
0d2bcfaf 250 as_fatal ("virtual memory exhausted");
252b5132
RH
251
252 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
0d2bcfaf 253 as_warn ("could not set architecture and machine");
252b5132
RH
254
255 /* This initializes a few things in arc-opc.c that we need.
256 This must be called before the various arc_xxx_supported fns. */
257 arc_opcode_init_tables (arc_get_opcode_mach (mach, target_big_endian));
258
259 /* Only put the first entry of each equivalently named suffix in the
260 table. */
261 last = "";
262 for (i = 0; i < arc_suffixes_count; i++)
263 {
252b5132
RH
264 if (strcmp (arc_suffixes[i].name, last) != 0)
265 hash_insert (arc_suffix_hash, arc_suffixes[i].name, (PTR) (arc_suffixes + i));
266 last = arc_suffixes[i].name;
267 }
268
269 /* Since registers don't have a prefix, we put them in the symbol table so
270 they can't be used as symbols. This also simplifies argument parsing as
271 we can let gas parse registers for us. The recorded register number is
0d2bcfaf
NC
272 the address of the register's entry in arc_reg_names.
273
274 If the register name is already in the table, then the existing
275 definition is assumed to be from an .ExtCoreRegister pseudo-op. */
276
252b5132
RH
277 for (i = 0; i < arc_reg_names_count; i++)
278 {
19203624 279 if (symbol_find (arc_reg_names[i].name))
252b5132
RH
280 continue;
281 /* Use symbol_create here instead of symbol_new so we don't try to
282 output registers into the object file's symbol table. */
bcee8eb8
AM
283 symbol_table_insert (symbol_create (arc_reg_names[i].name,
284 reg_section,
285 (int) &arc_reg_names[i],
286 &zero_address_frag));
252b5132
RH
287 }
288
0d2bcfaf 289 /* Tell `.option' it's too late. */
252b5132
RH
290 cpu_tables_init_p = 1;
291}
292\f
293/* Insert an operand value into an instruction.
294 If REG is non-NULL, it is a register number and ignore VAL. */
295
296static arc_insn
297arc_insert_operand (insn, operand, mods, reg, val, file, line)
298 arc_insn insn;
299 const struct arc_operand *operand;
300 int mods;
301 const struct arc_operand_value *reg;
302 offsetT val;
303 char *file;
304 unsigned int line;
305{
306 if (operand->bits != 32)
307 {
308 long min, max;
309 offsetT test;
310
311 if ((operand->flags & ARC_OPERAND_SIGNED) != 0)
312 {
313 if ((operand->flags & ARC_OPERAND_SIGNOPT) != 0)
314 max = (1 << operand->bits) - 1;
315 else
316 max = (1 << (operand->bits - 1)) - 1;
317 min = - (1 << (operand->bits - 1));
318 }
319 else
320 {
321 max = (1 << operand->bits) - 1;
322 min = 0;
323 }
324
325 if ((operand->flags & ARC_OPERAND_NEGATIVE) != 0)
326 test = - val;
327 else
328 test = val;
329
330 if (test < (offsetT) min || test > (offsetT) max)
e5976317 331 as_warn_value_out_of_range (_("operand"), test, (offsetT) min, (offsetT) max, file, line);
252b5132
RH
332 }
333
334 if (operand->insert)
335 {
336 const char *errmsg;
337
338 errmsg = NULL;
339 insn = (*operand->insert) (insn, operand, mods, reg, (long) val, &errmsg);
340 if (errmsg != (const char *) NULL)
341 as_warn (errmsg);
342 }
343 else
344 insn |= (((long) val & ((1 << operand->bits) - 1))
345 << operand->shift);
346
347 return insn;
348}
349
350/* We need to keep a list of fixups. We can't simply generate them as
351 we go, because that would require us to first create the frag, and
352 that would screw up references to ``.''. */
353
19203624 354struct arc_fixup {
bcee8eb8 355 /* index into `arc_operands' */
252b5132
RH
356 int opindex;
357 expressionS exp;
358};
359
360#define MAX_FIXUPS 5
361
362#define MAX_SUFFIXES 5
363
364/* This routine is called for each instruction to be assembled. */
365
366void
367md_assemble (str)
368 char *str;
369{
370 const struct arc_opcode *opcode;
0d2bcfaf
NC
371 const struct arc_opcode *std_opcode;
372 struct arc_opcode *ext_opcode;
252b5132 373 char *start;
0d2bcfaf 374 const char *last_errmsg = 0;
252b5132
RH
375 arc_insn insn;
376 static int init_tables_p = 0;
377
378 /* Opcode table initialization is deferred until here because we have to
bcee8eb8 379 wait for a possible .option command. */
252b5132
RH
380 if (!init_tables_p)
381 {
382 init_opcode_tables (arc_mach_type);
383 init_tables_p = 1;
384 }
385
386 /* Skip leading white space. */
3882b010 387 while (ISSPACE (*str))
252b5132
RH
388 str++;
389
390 /* The instructions are stored in lists hashed by the first letter (though
391 we needn't care how they're hashed). Get the first in the list. */
392
0d2bcfaf
NC
393 ext_opcode = arc_ext_opcodes;
394 std_opcode = arc_opcode_lookup_asm (str);
252b5132
RH
395
396 /* Keep looking until we find a match. */
397
398 start = str;
19203624 399 for (opcode = (ext_opcode ? ext_opcode : std_opcode);
0d2bcfaf
NC
400 opcode != NULL;
401 opcode = (ARC_OPCODE_NEXT_ASM (opcode)
1e07b820
KH
402 ? ARC_OPCODE_NEXT_ASM (opcode)
403 : (ext_opcode ? ext_opcode = NULL, std_opcode : NULL)))
252b5132
RH
404 {
405 int past_opcode_p, fc, num_suffixes;
0d2bcfaf 406 int fix_up_at = 0;
252b5132
RH
407 char *syn;
408 struct arc_fixup fixups[MAX_FIXUPS];
409 /* Used as a sanity check. If we need a limm reloc, make sure we ask
410 for an extra 4 bytes from frag_more. */
411 int limm_reloc_p;
0d2bcfaf 412 int ext_suffix_p;
252b5132
RH
413 const struct arc_operand_value *insn_suffixes[MAX_SUFFIXES];
414
415 /* Is this opcode supported by the selected cpu? */
416 if (! arc_opcode_supported (opcode))
417 continue;
418
419 /* Scan the syntax string. If it doesn't match, try the next one. */
420
421 arc_opcode_init_insert ();
422 insn = opcode->value;
423 fc = 0;
424 past_opcode_p = 0;
425 num_suffixes = 0;
426 limm_reloc_p = 0;
0d2bcfaf 427 ext_suffix_p = 0;
252b5132
RH
428
429 /* We don't check for (*str != '\0') here because we want to parse
430 any trailing fake arguments in the syntax string. */
19203624 431 for (str = start, syn = opcode->syntax; *syn != '\0';)
252b5132
RH
432 {
433 int mods;
434 const struct arc_operand *operand;
435
436 /* Non operand chars must match exactly. */
437 if (*syn != '%' || *++syn == '%')
438 {
2f12d57f 439 if (*str == *syn)
252b5132
RH
440 {
441 if (*syn == ' ')
442 past_opcode_p = 1;
443 ++syn;
444 ++str;
445 }
446 else
447 break;
448 continue;
449 }
450
451 /* We have an operand. Pick out any modifiers. */
452 mods = 0;
4a314ec8 453 while (ARC_MOD_P (arc_operands[arc_operand_map[(int) *syn]].flags))
252b5132 454 {
4a314ec8 455 mods |= arc_operands[arc_operand_map[(int) *syn]].flags & ARC_MOD_BITS;
252b5132
RH
456 ++syn;
457 }
4a314ec8 458 operand = arc_operands + arc_operand_map[(int) *syn];
252b5132 459 if (operand->fmt == 0)
0d2bcfaf 460 as_fatal ("unknown syntax format character `%c'", *syn);
252b5132
RH
461
462 if (operand->flags & ARC_OPERAND_FAKE)
463 {
464 const char *errmsg = NULL;
465 if (operand->insert)
466 {
467 insn = (*operand->insert) (insn, operand, mods, NULL, 0, &errmsg);
1e07b820
KH
468 if (errmsg != (const char *) NULL)
469 {
470 last_errmsg = errmsg;
471 if (operand->flags & ARC_OPERAND_ERROR)
472 {
473 as_bad (errmsg);
474 return;
475 }
476 else if (operand->flags & ARC_OPERAND_WARN)
477 as_warn (errmsg);
478 break;
479 }
19203624
KH
480 if (limm_reloc_p
481 && (operand->flags && operand->flags & ARC_OPERAND_LIMM)
482 && (operand->flags &
483 (ARC_OPERAND_ABSOLUTE_BRANCH | ARC_OPERAND_ADDRESS)))
1e07b820
KH
484 {
485 fixups[fix_up_at].opindex = arc_operand_map[operand->fmt];
486 }
252b5132
RH
487 }
488 ++syn;
489 }
490 /* Are we finished with suffixes? */
491 else if (!past_opcode_p)
492 {
493 int found;
494 char c;
19203624
KH
495 char *s, *t;
496 const struct arc_operand_value *suf, *suffix_end;
0d2bcfaf 497 const struct arc_operand_value *suffix = NULL;
252b5132
RH
498
499 if (!(operand->flags & ARC_OPERAND_SUFFIX))
500 abort ();
501
502 /* If we're at a space in the input string, we want to skip the
503 remaining suffixes. There may be some fake ones though, so
504 just go on to try the next one. */
505 if (*str == ' ')
506 {
507 ++syn;
508 continue;
509 }
510
511 s = str;
512 if (mods & ARC_MOD_DOT)
513 {
514 if (*s != '.')
515 break;
516 ++s;
517 }
518 else
519 {
520 /* This can happen in "b.nd foo" and we're currently looking
521 for "%q" (ie: a condition code suffix). */
522 if (*s == '.')
523 {
524 ++syn;
525 continue;
526 }
527 }
528
529 /* Pick the suffix out and look it up via the hash table. */
3882b010 530 for (t = s; *t && ISALNUM (*t); ++t)
252b5132
RH
531 continue;
532 c = *t;
533 *t = '\0';
19203624 534 if ((suf = get_ext_suffix (s)))
1e07b820
KH
535 ext_suffix_p = 1;
536 else
537 suf = hash_find (arc_suffix_hash, s);
252b5132
RH
538 if (!suf)
539 {
540 /* This can happen in "blle foo" and we're currently using
541 the template "b%q%.n %j". The "bl" insn occurs later in
542 the table so "lle" isn't an illegal suffix. */
1e07b820 543 *t = c;
252b5132
RH
544 break;
545 }
546
547 /* Is it the right type? Note that the same character is used
1e07b820 548 several times, so we have to examine all of them. This is
252b5132
RH
549 relatively efficient as equivalent entries are kept
550 together. If it's not the right type, don't increment `str'
551 so we try the next one in the series. */
552 found = 0;
1e07b820
KH
553 if (ext_suffix_p && arc_operands[suf->type].fmt == *syn)
554 {
555 /* Insert the suffix's value into the insn. */
556 *t = c;
557 if (operand->insert)
558 insn = (*operand->insert) (insn, operand,
559 mods, NULL, suf->value,
560 NULL);
561 else
562 insn |= suf->value << operand->shift;
b15c27d7 563 suffix = suf;
1e07b820
KH
564 str = t;
565 found = 1;
566 }
567 else
568 {
569 *t = c;
570 suffix_end = arc_suffixes + arc_suffixes_count;
571 for (suffix = suf;
572 suffix < suffix_end && strcmp (suffix->name, suf->name) == 0;
573 ++suffix)
574 {
575 if (arc_operands[suffix->type].fmt == *syn)
576 {
577 /* Insert the suffix's value into the insn. */
578 if (operand->insert)
579 insn = (*operand->insert) (insn, operand,
580 mods, NULL, suffix->value,
581 NULL);
582 else
583 insn |= suffix->value << operand->shift;
584
585 str = t;
586 found = 1;
587 break;
588 }
589 }
590 }
252b5132
RH
591 ++syn;
592 if (!found)
19203624
KH
593 /* Wrong type. Just go on to try next insn entry. */
594 ;
252b5132
RH
595 else
596 {
597 if (num_suffixes == MAX_SUFFIXES)
0d2bcfaf 598 as_bad ("too many suffixes");
252b5132
RH
599 else
600 insn_suffixes[num_suffixes++] = suffix;
601 }
602 }
603 else
604 /* This is either a register or an expression of some kind. */
605 {
252b5132
RH
606 char *hold;
607 const struct arc_operand_value *reg = NULL;
608 long value = 0;
609 expressionS exp;
610
611 if (operand->flags & ARC_OPERAND_SUFFIX)
612 abort ();
613
614 /* Is there anything left to parse?
615 We don't check for this at the top because we want to parse
616 any trailing fake arguments in the syntax string. */
2d0441d9 617 if (is_end_of_line[(unsigned char) *str])
252b5132 618 break;
252b5132
RH
619
620 /* Parse the operand. */
621 hold = input_line_pointer;
622 input_line_pointer = str;
623 expression (&exp);
624 str = input_line_pointer;
625 input_line_pointer = hold;
626
627 if (exp.X_op == O_illegal)
0d2bcfaf 628 as_bad ("illegal operand");
252b5132 629 else if (exp.X_op == O_absent)
0d2bcfaf 630 as_bad ("missing operand");
252b5132
RH
631 else if (exp.X_op == O_constant)
632 {
633 value = exp.X_add_number;
634 }
635 else if (exp.X_op == O_register)
636 {
0d2bcfaf 637 reg = (struct arc_operand_value *) exp.X_add_number;
252b5132 638 }
0d2bcfaf
NC
639#define IS_REG_DEST_OPERAND(o) ((o) == 'a')
640 else if (IS_REG_DEST_OPERAND (*syn))
19203624 641 as_bad ("symbol as destination register");
1e07b820 642 else
252b5132 643 {
19203624 644 if (!strncmp (str, "@h30", 4))
1e07b820 645 {
19203624 646 arc_code_symbol (&exp);
1e07b820
KH
647 str += 4;
648 }
252b5132
RH
649 /* We need to generate a fixup for this expression. */
650 if (fc >= MAX_FIXUPS)
0d2bcfaf 651 as_fatal ("too many fixups");
252b5132 652 fixups[fc].exp = exp;
1e07b820 653 /* We don't support shimm relocs. break here to force
19203624 654 the assembler to output a limm. */
0d2bcfaf 655#define IS_REG_SHIMM_OFFSET(o) ((o) == 'd')
19203624 656 if (IS_REG_SHIMM_OFFSET (*syn))
1e07b820 657 break;
252b5132
RH
658 /* If this is a register constant (IE: one whose
659 register value gets stored as 61-63) then this
bfb32b52 660 must be a limm. */
252b5132
RH
661 /* ??? This bit could use some cleaning up.
662 Referencing the format chars like this goes
663 against style. */
0d2bcfaf 664 if (IS_SYMBOL_OPERAND (*syn))
252b5132
RH
665 {
666 const char *junk;
252b5132 667 limm_reloc_p = 1;
19203624 668 /* Save this, we don't yet know what reloc to use. */
1e07b820 669 fix_up_at = fc;
252b5132
RH
670 /* Tell insert_reg we need a limm. This is
671 needed because the value at this point is
672 zero, a shimm. */
673 /* ??? We need a cleaner interface than this. */
674 (*arc_operands[arc_operand_map['Q']].insert)
675 (insn, operand, mods, reg, 0L, &junk);
676 }
677 else
4a314ec8 678 fixups[fc].opindex = arc_operand_map[(int) *syn];
252b5132
RH
679 ++fc;
680 value = 0;
681 }
682
683 /* Insert the register or expression into the instruction. */
684 if (operand->insert)
685 {
686 const char *errmsg = NULL;
687 insn = (*operand->insert) (insn, operand, mods,
688 reg, (long) value, &errmsg);
1e07b820
KH
689 if (errmsg != (const char *) NULL)
690 {
691 last_errmsg = errmsg;
692 if (operand->flags & ARC_OPERAND_ERROR)
693 {
694 as_bad (errmsg);
695 return;
696 }
697 else if (operand->flags & ARC_OPERAND_WARN)
698 as_warn (errmsg);
699 break;
700 }
252b5132
RH
701 }
702 else
703 insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
704
705 ++syn;
706 }
707 }
708
709 /* If we're at the end of the syntax string, we're done. */
710 /* FIXME: try to move this to a separate function. */
711 if (*syn == '\0')
712 {
713 int i;
714 char *f;
715 long limm, limm_p;
716
717 /* For the moment we assume a valid `str' can only contain blanks
718 now. IE: We needn't try again with a longer version of the
719 insn and it is assumed that longer versions of insns appear
720 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
721
3882b010 722 while (ISSPACE (*str))
252b5132
RH
723 ++str;
724
2d0441d9 725 if (!is_end_of_line[(unsigned char) *str])
0d2bcfaf 726 as_bad ("junk at end of line: `%s'", str);
252b5132
RH
727
728 /* Is there a limm value? */
729 limm_p = arc_opcode_limm_p (&limm);
730
731 /* Perform various error and warning tests. */
732
733 {
734 static int in_delay_slot_p = 0;
735 static int prev_insn_needs_cc_nop_p = 0;
736 /* delay slot type seen */
737 int delay_slot_type = ARC_DELAY_NONE;
738 /* conditional execution flag seen */
739 int conditional = 0;
740 /* 1 if condition codes are being set */
741 int cc_set_p = 0;
742 /* 1 if conditional branch, including `b' "branch always" */
743 int cond_branch_p = opcode->flags & ARC_OPCODE_COND_BRANCH;
252b5132
RH
744
745 for (i = 0; i < num_suffixes; ++i)
746 {
747 switch (arc_operands[insn_suffixes[i]->type].fmt)
748 {
19203624 749 case 'n':
252b5132
RH
750 delay_slot_type = insn_suffixes[i]->value;
751 break;
19203624 752 case 'q':
252b5132
RH
753 conditional = insn_suffixes[i]->value;
754 break;
19203624 755 case 'f':
252b5132
RH
756 cc_set_p = 1;
757 break;
758 }
759 }
760
761 /* Putting an insn with a limm value in a delay slot is supposed to
762 be legal, but let's warn the user anyway. Ditto for 8 byte
763 jumps with delay slots. */
764 if (in_delay_slot_p && limm_p)
1e07b820 765 as_warn ("8 byte instruction in delay slot");
0d2bcfaf 766 if (delay_slot_type != ARC_DELAY_NONE
19203624 767 && limm_p && arc_insn_not_jl (insn)) /* except for jl addr */
1e07b820 768 as_warn ("8 byte jump instruction with delay slot");
252b5132
RH
769 in_delay_slot_p = (delay_slot_type != ARC_DELAY_NONE) && !limm_p;
770
771 /* Warn when a conditional branch immediately follows a set of
772 the condition codes. Note that this needn't be done if the
773 insn that sets the condition codes uses a limm. */
774 if (cond_branch_p && conditional != 0 /* 0 = "always" */
0d2bcfaf 775 && prev_insn_needs_cc_nop_p && arc_mach_type == bfd_mach_arc_5)
1e07b820 776 as_warn ("conditional branch follows set of flags");
0d2bcfaf 777 prev_insn_needs_cc_nop_p =
1e07b820
KH
778 /* FIXME: ??? not required:
779 (delay_slot_type != ARC_DELAY_NONE) && */
780 cc_set_p && !limm_p;
252b5132
RH
781 }
782
783 /* Write out the instruction.
784 It is important to fetch enough space in one call to `frag_more'.
785 We use (f - frag_now->fr_literal) to compute where we are and we
786 don't want frag_now to change between calls. */
787 if (limm_p)
788 {
789 f = frag_more (8);
790 md_number_to_chars (f, insn, 4);
791 md_number_to_chars (f + 4, limm, 4);
9fcc94b6 792 dwarf2_emit_insn (8);
252b5132
RH
793 }
794 else if (limm_reloc_p)
795 {
796 /* We need a limm reloc, but the tables think we don't. */
797 abort ();
798 }
799 else
800 {
801 f = frag_more (4);
802 md_number_to_chars (f, insn, 4);
9fcc94b6 803 dwarf2_emit_insn (4);
252b5132
RH
804 }
805
806 /* Create any fixups. */
807 for (i = 0; i < fc; ++i)
808 {
809 int op_type, reloc_type;
810 expressionS exptmp;
811 const struct arc_operand *operand;
812
813 /* Create a fixup for this operand.
814 At this point we do not use a bfd_reloc_code_real_type for
815 operands residing in the insn, but instead just use the
816 operand index. This lets us easily handle fixups for any
817 operand type, although that is admittedly not a very exciting
94f592af 818 feature. We pick a BFD reloc type in md_apply_fix3.
252b5132
RH
819
820 Limm values (4 byte immediate "constants") must be treated
821 normally because they're not part of the actual insn word
822 and thus the insertion routines don't handle them. */
823
824 if (arc_operands[fixups[i].opindex].flags & ARC_OPERAND_LIMM)
825 {
19203624
KH
826 /* Modify the fixup addend as required by the cpu. */
827 fixups[i].exp.X_add_number += arc_limm_fixup_adjust (insn);
252b5132
RH
828 op_type = fixups[i].opindex;
829 /* FIXME: can we add this data to the operand table? */
0d2bcfaf 830 if (op_type == arc_operand_map['L']
1e07b820
KH
831 || op_type == arc_operand_map['s']
832 || op_type == arc_operand_map['o']
833 || op_type == arc_operand_map['O'])
252b5132
RH
834 reloc_type = BFD_RELOC_32;
835 else if (op_type == arc_operand_map['J'])
836 reloc_type = BFD_RELOC_ARC_B26;
837 else
838 abort ();
839 reloc_type = get_arc_exp_reloc_type (1, reloc_type,
840 &fixups[i].exp,
841 &exptmp);
842 }
843 else
844 {
845 op_type = get_arc_exp_reloc_type (0, fixups[i].opindex,
846 &fixups[i].exp, &exptmp);
847 reloc_type = op_type + (int) BFD_RELOC_UNUSED;
848 }
849 operand = &arc_operands[op_type];
850 fix_new_exp (frag_now,
851 ((f - frag_now->fr_literal)
852 + (operand->flags & ARC_OPERAND_LIMM ? 4 : 0)), 4,
853 &exptmp,
854 (operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0,
855 (bfd_reloc_code_real_type) reloc_type);
856 }
857
858 /* All done. */
859 return;
860 }
861
862 /* Try the next entry. */
863 }
864
19203624 865 if (NULL == last_errmsg)
0d2bcfaf
NC
866 as_bad ("bad instruction `%s'", start);
867 else
868 as_bad (last_errmsg);
252b5132
RH
869}
870\f
252b5132 871static void
0d2bcfaf
NC
872arc_extoper (opertype)
873 int opertype;
252b5132
RH
874{
875 char *name;
0d2bcfaf 876 char *mode;
252b5132
RH
877 char c;
878 char *p;
0d2bcfaf
NC
879 int imode = 0;
880 int number;
881 struct arc_ext_operand_value *ext_oper;
252b5132
RH
882 symbolS *symbolP;
883
0d2bcfaf
NC
884 segT old_sec;
885 int old_subsec;
886
252b5132
RH
887 name = input_line_pointer;
888 c = get_symbol_end ();
19203624 889 name = xstrdup (name);
0d2bcfaf
NC
890
891 p = name;
892 while (*p)
893 {
3882b010 894 *p = TOLOWER (*p);
1e07b820 895 p++;
0d2bcfaf
NC
896 }
897
bcee8eb8 898 /* just after name is now '\0' */
252b5132
RH
899 p = input_line_pointer;
900 *p = c;
901 SKIP_WHITESPACE ();
0d2bcfaf 902
252b5132
RH
903 if (*input_line_pointer != ',')
904 {
0d2bcfaf 905 as_bad ("expected comma after operand name");
252b5132 906 ignore_rest_of_line ();
19203624 907 free (name);
252b5132
RH
908 return;
909 }
0d2bcfaf 910
bcee8eb8 911 input_line_pointer++; /* skip ',' */
0d2bcfaf
NC
912 number = get_absolute_expression ();
913
19203624 914 if (number < 0)
0d2bcfaf 915 {
19203624
KH
916 as_bad ("negative operand number %d", number);
917 ignore_rest_of_line ();
918 free (name);
1e07b820 919 return;
0d2bcfaf
NC
920 }
921
922 if (opertype)
923 {
19203624 924 SKIP_WHITESPACE ();
0d2bcfaf
NC
925
926 if (*input_line_pointer != ',')
1e07b820
KH
927 {
928 as_bad ("expected comma after register-number");
929 ignore_rest_of_line ();
19203624 930 free (name);
1e07b820
KH
931 return;
932 }
bfb32b52 933
bcee8eb8 934 input_line_pointer++; /* skip ',' */
0d2bcfaf 935 mode = input_line_pointer;
bfb32b52 936
19203624 937 if (!strncmp (mode, "r|w", 3))
1e07b820
KH
938 {
939 imode = 0;
940 input_line_pointer += 3;
941 }
0d2bcfaf 942 else
1e07b820 943 {
19203624 944 if (!strncmp (mode, "r", 1))
1e07b820
KH
945 {
946 imode = ARC_REGISTER_READONLY;
947 input_line_pointer += 1;
948 }
949 else
950 {
19203624 951 if (strncmp (mode, "w", 1))
1e07b820
KH
952 {
953 as_bad ("invalid mode");
19203624
KH
954 ignore_rest_of_line ();
955 free (name);
1e07b820
KH
956 return;
957 }
958 else
959 {
960 imode = ARC_REGISTER_WRITEONLY;
961 input_line_pointer += 1;
962 }
963 }
964 }
19203624 965 SKIP_WHITESPACE ();
1e07b820
KH
966 if (1 == opertype)
967 {
968 if (*input_line_pointer != ',')
969 {
970 as_bad ("expected comma after register-mode");
971 ignore_rest_of_line ();
19203624 972 free (name);
1e07b820
KH
973 return;
974 }
975
bcee8eb8 976 input_line_pointer++; /* skip ',' */
1e07b820 977
19203624 978 if (!strncmp (input_line_pointer, "cannot_shortcut", 15))
1e07b820 979 {
19203624 980 imode |= arc_get_noshortcut_flag ();
1e07b820
KH
981 input_line_pointer += 15;
982 }
983 else
984 {
19203624 985 if (strncmp (input_line_pointer, "can_shortcut", 12))
1e07b820
KH
986 {
987 as_bad ("shortcut designator invalid");
19203624
KH
988 ignore_rest_of_line ();
989 free (name);
1e07b820
KH
990 return;
991 }
992 else
993 {
994 input_line_pointer += 12;
995 }
996 }
997 }
998 }
0d2bcfaf
NC
999
1000 if ((opertype == 1) && number > 60)
1e07b820 1001 {
19203624
KH
1002 as_bad ("core register value (%d) too large", number);
1003 ignore_rest_of_line ();
1004 free (name);
1e07b820
KH
1005 return;
1006 }
0d2bcfaf
NC
1007
1008 if ((opertype == 0) && number > 31)
1e07b820 1009 {
19203624
KH
1010 as_bad ("condition code value (%d) too large", number);
1011 ignore_rest_of_line ();
1012 free (name);
1e07b820
KH
1013 return;
1014 }
0d2bcfaf
NC
1015
1016 ext_oper = (struct arc_ext_operand_value *) \
19203624 1017 xmalloc (sizeof (struct arc_ext_operand_value));
0d2bcfaf 1018
19203624 1019 if (opertype)
0d2bcfaf 1020 {
19203624 1021 /* If the symbol already exists, point it at the new definition. */
0d2bcfaf 1022 if ((symbolP = symbol_find (name)))
1e07b820 1023 {
19203624
KH
1024 if (S_GET_SEGMENT (symbolP) == reg_section)
1025 S_SET_VALUE (symbolP, (int) &ext_oper->operand);
1e07b820
KH
1026 else
1027 {
19203624
KH
1028 as_bad ("attempt to override symbol: %s", name);
1029 ignore_rest_of_line ();
1030 free (name);
1031 free (ext_oper);
1e07b820
KH
1032 return;
1033 }
1034 }
0d2bcfaf 1035 else
1e07b820 1036 {
19203624 1037 /* If its not there, add it. */
1e07b820
KH
1038 symbol_table_insert (symbol_create (name, reg_section,
1039 (int) &ext_oper->operand, &zero_address_frag));
1040 }
0d2bcfaf
NC
1041 }
1042
1043 ext_oper->operand.name = name;
1044 ext_oper->operand.value = number;
19203624 1045 ext_oper->operand.type = arc_operand_type (opertype);
0d2bcfaf
NC
1046 ext_oper->operand.flags = imode;
1047
1048 ext_oper->next = arc_ext_operands;
1049 arc_ext_operands = ext_oper;
1050
19203624
KH
1051 /* OK, now that we know what this operand is, put a description in
1052 the arc extension section of the output file. */
0d2bcfaf
NC
1053
1054 old_sec = now_seg;
1055 old_subsec = now_subseg;
1056
19203624 1057 arc_set_ext_seg ();
0d2bcfaf
NC
1058
1059 switch (opertype)
1e07b820
KH
1060 {
1061 case 0:
19203624
KH
1062 p = frag_more (1);
1063 *p = 3 + strlen (name) + 1;
1064 p = frag_more (1);
1e07b820 1065 *p = EXT_COND_CODE;
19203624 1066 p = frag_more (1);
1e07b820 1067 *p = number;
19203624
KH
1068 p = frag_more (strlen (name) + 1);
1069 strcpy (p, name);
1e07b820
KH
1070 break;
1071 case 1:
19203624
KH
1072 p = frag_more (1);
1073 *p = 3 + strlen (name) + 1;
1074 p = frag_more (1);
1e07b820 1075 *p = EXT_CORE_REGISTER;
19203624 1076 p = frag_more (1);
1e07b820 1077 *p = number;
19203624
KH
1078 p = frag_more (strlen (name) + 1);
1079 strcpy (p, name);
1e07b820
KH
1080 break;
1081 case 2:
19203624
KH
1082 p = frag_more (1);
1083 *p = 6 + strlen (name) + 1;
1084 p = frag_more (1);
1e07b820 1085 *p = EXT_AUX_REGISTER;
19203624 1086 p = frag_more (1);
1e07b820 1087 *p = number >> 24 & 0xff;
19203624 1088 p = frag_more (1);
1e07b820 1089 *p = number >> 16 & 0xff;
19203624 1090 p = frag_more (1);
1e07b820 1091 *p = number >> 8 & 0xff;
19203624 1092 p = frag_more (1);
1e07b820 1093 *p = number & 0xff;
19203624
KH
1094 p = frag_more (strlen (name) + 1);
1095 strcpy (p, name);
1e07b820
KH
1096 break;
1097 default:
19203624
KH
1098 as_bad ("invalid opertype");
1099 ignore_rest_of_line ();
1100 free (name);
1e07b820
KH
1101 return;
1102 break;
1103 }
0d2bcfaf
NC
1104
1105 subseg_set (old_sec, old_subsec);
1106
19203624 1107 /* Enter all registers into the symbol table. */
0d2bcfaf 1108
19203624 1109 demand_empty_rest_of_line ();
0d2bcfaf
NC
1110}
1111
1112static void
1113arc_extinst (ignore)
19203624 1114 int ignore ATTRIBUTE_UNUSED;
0d2bcfaf 1115{
2132e3a3 1116 char syntax[129];
0d2bcfaf
NC
1117 char *name;
1118 char *p;
1119 char c;
1120 int suffixcode = -1;
19203624 1121 int opcode, subopcode;
0d2bcfaf
NC
1122 int i;
1123 int class = 0;
1124 int name_len;
1125 struct arc_opcode *ext_op;
1126
1127 segT old_sec;
1128 int old_subsec;
1129
1130 name = input_line_pointer;
1131 c = get_symbol_end ();
19203624 1132 name = xstrdup (name);
19203624
KH
1133 strcpy (syntax, name);
1134 name_len = strlen (name);
0d2bcfaf 1135
bcee8eb8 1136 /* just after name is now '\0' */
0d2bcfaf
NC
1137 p = input_line_pointer;
1138 *p = c;
1139
1140 SKIP_WHITESPACE ();
1141
1142 if (*input_line_pointer != ',')
252b5132 1143 {
0d2bcfaf 1144 as_bad ("expected comma after operand name");
252b5132
RH
1145 ignore_rest_of_line ();
1146 return;
1147 }
0d2bcfaf 1148
bcee8eb8 1149 input_line_pointer++; /* skip ',' */
0d2bcfaf
NC
1150 opcode = get_absolute_expression ();
1151
1152 SKIP_WHITESPACE ();
1153
1154 if (*input_line_pointer != ',')
252b5132 1155 {
0d2bcfaf 1156 as_bad ("expected comma after opcode");
252b5132
RH
1157 ignore_rest_of_line ();
1158 return;
1159 }
0d2bcfaf 1160
bcee8eb8 1161 input_line_pointer++; /* skip ',' */
0d2bcfaf
NC
1162 subopcode = get_absolute_expression ();
1163
19203624 1164 if (subopcode < 0)
252b5132 1165 {
19203624
KH
1166 as_bad ("negative subopcode %d", subopcode);
1167 ignore_rest_of_line ();
1e07b820 1168 return;
252b5132 1169 }
0d2bcfaf 1170
19203624 1171 if (subopcode)
0d2bcfaf 1172 {
19203624 1173 if (3 != opcode)
1e07b820
KH
1174 {
1175 as_bad ("subcode value found when opcode not equal 0x03");
19203624 1176 ignore_rest_of_line ();
1e07b820
KH
1177 return;
1178 }
1179 else
1180 {
1181 if (subopcode < 0x09 || subopcode == 0x3f)
1182 {
1183 as_bad ("invalid subopcode %d", subopcode);
19203624 1184 ignore_rest_of_line ();
1e07b820
KH
1185 return;
1186 }
1187 }
0d2bcfaf
NC
1188 }
1189
1190 SKIP_WHITESPACE ();
1191
252b5132
RH
1192 if (*input_line_pointer != ',')
1193 {
0d2bcfaf 1194 as_bad ("expected comma after subopcode");
252b5132
RH
1195 ignore_rest_of_line ();
1196 return;
1197 }
0d2bcfaf 1198
bcee8eb8 1199 input_line_pointer++; /* skip ',' */
0d2bcfaf 1200
19203624 1201 for (i = 0; i < (int) MAXSUFFIXCLASS; i++)
0d2bcfaf 1202 {
19203624 1203 if (!strncmp (suffixclass[i].name,input_line_pointer, suffixclass[i].len))
1e07b820
KH
1204 {
1205 suffixcode = i;
1206 input_line_pointer += suffixclass[i].len;
1207 break;
1208 }
0d2bcfaf
NC
1209 }
1210
19203624 1211 if (-1 == suffixcode)
0d2bcfaf
NC
1212 {
1213 as_bad ("invalid suffix class");
1214 ignore_rest_of_line ();
1215 return;
1216 }
1217
252b5132 1218 SKIP_WHITESPACE ();
0d2bcfaf
NC
1219
1220 if (*input_line_pointer != ',')
252b5132 1221 {
0d2bcfaf
NC
1222 as_bad ("expected comma after suffix class");
1223 ignore_rest_of_line ();
1224 return;
252b5132 1225 }
0d2bcfaf 1226
bcee8eb8 1227 input_line_pointer++; /* skip ',' */
0d2bcfaf 1228
19203624 1229 for (i = 0; i < (int) MAXSYNTAXCLASS; i++)
252b5132 1230 {
19203624 1231 if (!strncmp (syntaxclass[i].name,input_line_pointer, syntaxclass[i].len))
1e07b820
KH
1232 {
1233 class = syntaxclass[i].class;
1234 input_line_pointer += syntaxclass[i].len;
1235 break;
1236 }
252b5132 1237 }
252b5132 1238
19203624 1239 if (0 == (SYNTAX_VALID & class))
0d2bcfaf
NC
1240 {
1241 as_bad ("invalid syntax class");
1242 ignore_rest_of_line ();
1243 return;
1244 }
1245
19203624 1246 if ((0x3 == opcode) & (class & SYNTAX_3OP))
0d2bcfaf
NC
1247 {
1248 as_bad ("opcode 0x3 and SYNTAX_3OP invalid");
1249 ignore_rest_of_line ();
1250 return;
1251 }
1252
1253 switch (suffixcode)
1e07b820
KH
1254 {
1255 case 0:
19203624 1256 strcat (syntax, "%.q%.f ");
1e07b820
KH
1257 break;
1258 case 1:
19203624 1259 strcat (syntax, "%.f ");
1e07b820
KH
1260 break;
1261 case 2:
19203624 1262 strcat (syntax, "%.q ");
1e07b820
KH
1263 break;
1264 case 3:
19203624 1265 strcat (syntax, " ");
1e07b820
KH
1266 break;
1267 default:
19203624
KH
1268 as_bad ("unknown suffix class");
1269 ignore_rest_of_line ();
1e07b820
KH
1270 return;
1271 break;
1272 };
0d2bcfaf 1273
19203624
KH
1274 strcat (syntax, ((opcode == 0x3) ? "%a,%b" : ((class & SYNTAX_3OP) ? "%a,%b,%c" : "%b,%c")));
1275 if (suffixcode < 2)
1276 strcat (syntax, "%F");
1277 strcat (syntax, "%S%L");
0d2bcfaf 1278
19203624 1279 ext_op = (struct arc_opcode *) xmalloc (sizeof (struct arc_opcode));
19203624 1280 ext_op->syntax = xstrdup (syntax);
0d2bcfaf 1281
19203624
KH
1282 ext_op->mask = I (-1) | ((0x3 == opcode) ? C (-1) : 0);
1283 ext_op->value = I (opcode) | ((0x3 == opcode) ? C (subopcode) : 0);
0d2bcfaf
NC
1284 ext_op->flags = class;
1285 ext_op->next_asm = arc_ext_opcodes;
1286 ext_op->next_dis = arc_ext_opcodes;
1287 arc_ext_opcodes = ext_op;
1288
19203624
KH
1289 /* OK, now that we know what this inst is, put a description in the
1290 arc extension section of the output file. */
0d2bcfaf
NC
1291
1292 old_sec = now_seg;
1293 old_subsec = now_subseg;
1294
19203624 1295 arc_set_ext_seg ();
0d2bcfaf 1296
19203624
KH
1297 p = frag_more (1);
1298 *p = 5 + name_len + 1;
1299 p = frag_more (1);
0d2bcfaf 1300 *p = EXT_INSTRUCTION;
19203624 1301 p = frag_more (1);
0d2bcfaf 1302 *p = opcode;
19203624 1303 p = frag_more (1);
0d2bcfaf 1304 *p = subopcode;
19203624 1305 p = frag_more (1);
0d2bcfaf 1306 *p = (class & (OP1_MUST_BE_IMM | OP1_IMM_IMPLIED) ? IGNORE_FIRST_OPD : 0);
19203624
KH
1307 p = frag_more (name_len);
1308 strncpy (p, syntax, name_len);
1309 p = frag_more (1);
0d2bcfaf
NC
1310 *p = '\0';
1311
1312 subseg_set (old_sec, old_subsec);
1313
19203624 1314 demand_empty_rest_of_line ();
252b5132
RH
1315}
1316
0d2bcfaf 1317int
19203624 1318arc_set_ext_seg ()
0d2bcfaf
NC
1319{
1320 if (!arcext_section)
1321 {
1322 arcext_section = subseg_new (".arcextmap", 0);
1323 bfd_set_section_flags (stdoutput, arcext_section,
19203624 1324 SEC_READONLY | SEC_HAS_CONTENTS);
0d2bcfaf
NC
1325 }
1326 else
1327 subseg_set (arcext_section, 0);
1328 return 1;
1329}
252b5132
RH
1330
1331static void
0d2bcfaf
NC
1332arc_common (localScope)
1333 int localScope;
252b5132 1334{
0d2bcfaf 1335 char *name;
252b5132 1336 char c;
0d2bcfaf 1337 char *p;
19203624 1338 int align, size;
0d2bcfaf 1339 symbolS *symbolP;
252b5132 1340
0d2bcfaf
NC
1341 name = input_line_pointer;
1342 c = get_symbol_end ();
bcee8eb8 1343 /* just after name is now '\0' */
0d2bcfaf
NC
1344 p = input_line_pointer;
1345 *p = c;
1346 SKIP_WHITESPACE ();
1347
1348 if (*input_line_pointer != ',')
252b5132 1349 {
0d2bcfaf 1350 as_bad ("expected comma after symbol name");
252b5132
RH
1351 ignore_rest_of_line ();
1352 return;
1353 }
1354
bcee8eb8 1355 input_line_pointer++; /* skip ',' */
0d2bcfaf 1356 size = get_absolute_expression ();
252b5132 1357
0d2bcfaf
NC
1358 if (size < 0)
1359 {
1360 as_bad ("negative symbol length");
1361 ignore_rest_of_line ();
1362 return;
1363 }
252b5132 1364
0d2bcfaf
NC
1365 *p = 0;
1366 symbolP = symbol_find_or_make (name);
1367 *p = c;
1368
1369 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
1370 {
1371 as_bad ("ignoring attempt to re-define symbol");
1372 ignore_rest_of_line ();
1373 return;
1374 }
19203624
KH
1375 if (((int) S_GET_VALUE (symbolP) != 0) \
1376 && ((int) S_GET_VALUE (symbolP) != size))
0d2bcfaf
NC
1377 {
1378 as_warn ("length of symbol \"%s\" already %ld, ignoring %d",
1379 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
1380 }
1381 assert (symbolP->sy_frag == &zero_address_frag);
1382
0d2bcfaf
NC
1383 /* Now parse the alignment field. This field is optional for
1384 local and global symbols. Default alignment is zero. */
1385 if (*input_line_pointer == ',')
1386 {
1387 input_line_pointer++;
1388 align = get_absolute_expression ();
1389 if (align < 0)
1390 {
1391 align = 0;
1392 as_warn ("assuming symbol alignment of zero");
1393 }
1394 }
252b5132 1395 else
0d2bcfaf
NC
1396 align = 0;
1397
1398 if (localScope != 0)
252b5132 1399 {
0d2bcfaf
NC
1400 segT old_sec;
1401 int old_subsec;
1402 char *pfrag;
1403
1404 old_sec = now_seg;
1405 old_subsec = now_subseg;
1406 record_alignment (bss_section, align);
bcee8eb8 1407 subseg_set (bss_section, 0); /* ??? subseg_set (bss_section, 1); ??? */
0d2bcfaf
NC
1408
1409 if (align)
19203624
KH
1410 /* Do alignment. */
1411 frag_align (align, 0, 0);
0d2bcfaf 1412
19203624 1413 /* Detach from old frag. */
0d2bcfaf
NC
1414 if (S_GET_SEGMENT (symbolP) == bss_section)
1415 symbolP->sy_frag->fr_symbol = NULL;
1416
1417 symbolP->sy_frag = frag_now;
1418 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
19203624 1419 (offsetT) size, (char *) 0);
0d2bcfaf
NC
1420 *pfrag = 0;
1421
1422 S_SET_SIZE (symbolP, size);
1423 S_SET_SEGMENT (symbolP, bss_section);
1424 S_CLEAR_EXTERNAL (symbolP);
1425 symbolP->local = 1;
1426 subseg_set (old_sec, old_subsec);
1427 }
1428 else
1429 {
1430 S_SET_VALUE (symbolP, (valueT) size);
1431 S_SET_ALIGN (symbolP, align);
1432 S_SET_EXTERNAL (symbolP);
1433 S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
252b5132 1434 }
252b5132 1435
0d2bcfaf
NC
1436 symbolP->bsym->flags |= BSF_OBJECT;
1437
1438 demand_empty_rest_of_line ();
252b5132 1439}
0d2bcfaf 1440\f
0d2bcfaf 1441/* Select the cpu we're assembling for. */
252b5132
RH
1442
1443static void
0d2bcfaf 1444arc_option (ignore)
19203624 1445 int ignore ATTRIBUTE_UNUSED;
252b5132 1446{
0d2bcfaf 1447 int mach;
252b5132 1448 char c;
0d2bcfaf 1449 char *cpu;
252b5132 1450
0d2bcfaf 1451 cpu = input_line_pointer;
252b5132 1452 c = get_symbol_end ();
0d2bcfaf 1453 mach = arc_get_mach (cpu);
252b5132
RH
1454 *input_line_pointer = c;
1455
0d2bcfaf
NC
1456 /* If an instruction has already been seen, it's too late. */
1457 if (cpu_tables_init_p)
252b5132 1458 {
0d2bcfaf 1459 as_bad ("\".option\" directive must appear before any instructions");
252b5132
RH
1460 ignore_rest_of_line ();
1461 return;
1462 }
252b5132 1463
0d2bcfaf
NC
1464 if (mach == -1)
1465 goto bad_cpu;
1466
1467 if (mach_type_specified_p && mach != arc_mach_type)
252b5132 1468 {
0d2bcfaf 1469 as_bad ("\".option\" directive conflicts with initial definition");
252b5132
RH
1470 ignore_rest_of_line ();
1471 return;
1472 }
0d2bcfaf
NC
1473 else
1474 {
1475 /* The cpu may have been selected on the command line. */
1476 if (mach != arc_mach_type)
1477 as_warn ("\".option\" directive overrides command-line (default) value");
1478 arc_mach_type = mach;
1479 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
1480 as_fatal ("could not set architecture and machine");
1481 mach_type_specified_p = 1;
1482 }
252b5132 1483 demand_empty_rest_of_line ();
0d2bcfaf
NC
1484 return;
1485
1486 bad_cpu:
1487 as_bad ("invalid identifier for \".option\"");
1488 ignore_rest_of_line ();
252b5132 1489}
252b5132 1490\f
19203624
KH
1491/* Turn a string in input_line_pointer into a floating point constant
1492 of type TYPE, and store the appropriate bytes in *LITP. The number
1493 of LITTLENUMS emitted is stored in *SIZEP. An error message is
1494 returned, or NULL on OK. */
252b5132 1495
0d2bcfaf 1496/* Equal to MAX_PRECISION in atof-ieee.c */
252b5132
RH
1497#define MAX_LITTLENUMS 6
1498
1499char *
1500md_atof (type, litP, sizeP)
89b57c9a 1501 int type;
19203624
KH
1502 char *litP;
1503 int *sizeP;
252b5132
RH
1504{
1505 int prec;
1506 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1507 LITTLENUM_TYPE *wordP;
1508 char *t;
252b5132
RH
1509
1510 switch (type)
1511 {
1512 case 'f':
1513 case 'F':
1514 prec = 2;
1515 break;
1516
1517 case 'd':
1518 case 'D':
1519 prec = 4;
1520 break;
1521
1522 default:
1523 *sizeP = 0;
0d2bcfaf 1524 return "bad call to md_atof";
252b5132
RH
1525 }
1526
1527 t = atof_ieee (input_line_pointer, type, words);
1528 if (t)
1529 input_line_pointer = t;
1530 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1531 for (wordP = words; prec--;)
1532 {
1533 md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
1534 litP += sizeof (LITTLENUM_TYPE);
1535 }
1536
1537 return NULL;
1538}
1539
1540/* Write a value out to the object file, using the appropriate
1541 endianness. */
1542
1543void
1544md_number_to_chars (buf, val, n)
1545 char *buf;
1546 valueT val;
1547 int n;
1548{
1549 if (target_big_endian)
1550 number_to_chars_bigendian (buf, val, n);
1551 else
1552 number_to_chars_littleendian (buf, val, n);
1553}
1554
bfb32b52 1555/* Round up a section size to the appropriate boundary. */
252b5132
RH
1556
1557valueT
1558md_section_align (segment, size)
1559 segT segment;
1560 valueT size;
1561{
1562 int align = bfd_get_section_alignment (stdoutput, segment);
1563
1564 return ((size + (1 << align) - 1) & (-1 << align));
1565}
1566
1567/* We don't have any form of relaxing. */
1568
1569int
1570md_estimate_size_before_relax (fragp, seg)
4a314ec8
NC
1571 fragS *fragp ATTRIBUTE_UNUSED;
1572 asection *seg ATTRIBUTE_UNUSED;
252b5132 1573{
0d2bcfaf
NC
1574 as_fatal (_("md_estimate_size_before_relax\n"));
1575 return 1;
252b5132
RH
1576}
1577
1578/* Convert a machine dependent frag. We never generate these. */
1579
1580void
1581md_convert_frag (abfd, sec, fragp)
4a314ec8
NC
1582 bfd *abfd ATTRIBUTE_UNUSED;
1583 asection *sec ATTRIBUTE_UNUSED;
1584 fragS *fragp ATTRIBUTE_UNUSED;
252b5132 1585{
0d2bcfaf
NC
1586 as_fatal (_("md_convert_frag\n"));
1587}
1588
1589void
19203624 1590arc_code_symbol (expressionP)
0d2bcfaf
NC
1591 expressionS *expressionP;
1592{
d3ecfc59 1593 if (expressionP->X_op == O_symbol && expressionP->X_add_number == 0)
0d2bcfaf 1594 {
1e07b820
KH
1595 expressionS two;
1596 expressionP->X_op = O_right_shift;
bcee8eb8 1597 expressionP->X_add_symbol->sy_value.X_op = O_constant;
1e07b820
KH
1598 two.X_op = O_constant;
1599 two.X_add_symbol = two.X_op_symbol = NULL;
1600 two.X_add_number = 2;
1601 expressionP->X_op_symbol = make_expr_symbol (&two);
0d2bcfaf 1602 }
bcee8eb8 1603 /* Allow %st(sym1-sym2) */
19203624
KH
1604 else if (expressionP->X_op == O_subtract
1605 && expressionP->X_add_symbol != NULL
1606 && expressionP->X_op_symbol != NULL
1607 && expressionP->X_add_number == 0)
0d2bcfaf 1608 {
1e07b820
KH
1609 expressionS two;
1610 expressionP->X_add_symbol = make_expr_symbol (expressionP);
1611 expressionP->X_op = O_right_shift;
1612 two.X_op = O_constant;
1613 two.X_add_symbol = two.X_op_symbol = NULL;
1614 two.X_add_number = 2;
1615 expressionP->X_op_symbol = make_expr_symbol (&two);
0d2bcfaf
NC
1616 }
1617 else
1618 {
1e07b820
KH
1619 as_bad ("expression too complex code symbol");
1620 return;
0d2bcfaf 1621 }
252b5132
RH
1622}
1623
1624/* Parse an operand that is machine-specific.
1625
1626 The ARC has a special %-op to adjust addresses so they're usable in
1627 branches. The "st" is short for the STatus register.
1628 ??? Later expand this to take a flags value too.
1629
1630 ??? We can't create new expression types so we map the %-op's onto the
1631 existing syntax. This means that the user could use the chosen syntax
bfb32b52 1632 to achieve the same effect. */
252b5132 1633
bfb32b52 1634void
252b5132
RH
1635md_operand (expressionP)
1636 expressionS *expressionP;
1637{
1638 char *p = input_line_pointer;
1639
f17c130b
AM
1640 if (*p != '%')
1641 return;
1642
1643 if (strncmp (p, "%st(", 4) == 0)
1644 {
1645 input_line_pointer += 4;
1646 expression (expressionP);
1647 if (*input_line_pointer != ')')
1648 {
1649 as_bad ("missing ')' in %%-op");
1650 return;
1651 }
1652 ++input_line_pointer;
1653 arc_code_symbol (expressionP);
1654 }
1655 else
1656 {
1657 /* It could be a register. */
1658 int i, l;
1659 struct arc_ext_operand_value *ext_oper = arc_ext_operands;
1660 p++;
1661
1662 while (ext_oper)
1663 {
1664 l = strlen (ext_oper->operand.name);
1665 if (!strncmp (p, ext_oper->operand.name, l) && !ISALNUM (*(p + l)))
1666 {
1667 input_line_pointer += l + 1;
1668 expressionP->X_op = O_register;
1669 expressionP->X_add_number = (int) &ext_oper->operand;
1670 return;
1671 }
1672 ext_oper = ext_oper->next;
1673 }
1674 for (i = 0; i < arc_reg_names_count; i++)
1675 {
1676 l = strlen (arc_reg_names[i].name);
1677 if (!strncmp (p, arc_reg_names[i].name, l) && !ISALNUM (*(p + l)))
1678 {
1679 input_line_pointer += l + 1;
1680 expressionP->X_op = O_register;
1681 expressionP->X_add_number = (int) &arc_reg_names[i];
1682 break;
1683 }
1684 }
1685 }
252b5132
RH
1686}
1687
1688/* We have no need to default values of symbols.
1689 We could catch register names here, but that is handled by inserting
1690 them all in the symbol table to begin with. */
1691
1692symbolS *
1693md_undefined_symbol (name)
4a314ec8 1694 char *name ATTRIBUTE_UNUSED;
252b5132
RH
1695{
1696 return 0;
1697}
1698\f
1699/* Functions concerning expressions. */
1700
1701/* Parse a .byte, .word, etc. expression.
1702
1703 Values for the status register are specified with %st(label).
1704 `label' will be right shifted by 2. */
1705
1706void
1707arc_parse_cons_expression (exp, nbytes)
19203624
KH
1708 expressionS *exp;
1709 unsigned int nbytes ATTRIBUTE_UNUSED;
252b5132 1710{
0d2bcfaf
NC
1711 char *p = input_line_pointer;
1712 int code_symbol_fix = 0;
1713
19203624
KH
1714 for (; ! is_end_of_line[(unsigned char) *p]; p++)
1715 if (*p == '@' && !strncmp (p, "@h30", 4))
0d2bcfaf 1716 {
1e07b820 1717 code_symbol_fix = 1;
19203624 1718 strcpy (p, "; ");
0d2bcfaf 1719 }
1e07b820
KH
1720 expr (0, exp);
1721 if (code_symbol_fix)
1722 {
19203624 1723 arc_code_symbol (exp);
1e07b820
KH
1724 input_line_pointer = p;
1725 }
252b5132
RH
1726}
1727
1728/* Record a fixup for a cons expression. */
1729
1730void
1731arc_cons_fix_new (frag, where, nbytes, exp)
1732 fragS *frag;
1733 int where;
1734 int nbytes;
1735 expressionS *exp;
1736{
1737 if (nbytes == 4)
1738 {
1739 int reloc_type;
1740 expressionS exptmp;
1741
1742 /* This may be a special ARC reloc (eg: %st()). */
1743 reloc_type = get_arc_exp_reloc_type (1, BFD_RELOC_32, exp, &exptmp);
1744 fix_new_exp (frag, where, nbytes, &exptmp, 0, reloc_type);
1745 }
1746 else
1747 {
1748 fix_new_exp (frag, where, nbytes, exp, 0,
1749 nbytes == 2 ? BFD_RELOC_16
1750 : nbytes == 8 ? BFD_RELOC_64
1751 : BFD_RELOC_32);
1752 }
1753}
1754\f
1755/* Functions concerning relocs. */
1756
1757/* The location from which a PC relative jump should be calculated,
1758 given a PC relative reloc. */
1759
bfb32b52 1760long
252b5132
RH
1761md_pcrel_from (fixP)
1762 fixS *fixP;
1763{
252b5132
RH
1764 /* Return the address of the delay slot. */
1765 return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
1766}
1767
1768/* Compute the reloc type of an expression.
1769 The possibly modified expression is stored in EXPNEW.
1770
1771 This is used to convert the expressions generated by the %-op's into
1772 the appropriate operand type. It is called for both data in instructions
1773 (operands) and data outside instructions (variables, debugging info, etc.).
1774
1775 Currently supported %-ops:
1776
1777 %st(symbol): represented as "symbol >> 2"
1778 "st" is short for STatus as in the status register (pc)
1779
1780 DEFAULT_TYPE is the type to use if no special processing is required.
1781
1782 DATA_P is non-zero for data or limm values, zero for insn operands.
1783 Remember that the opcode "insertion fns" cannot be used on data, they're
1784 only for inserting operands into insns. They also can't be used for limm
1785 values as the insertion routines don't handle limm values. When called for
1786 insns we return fudged reloc types (real_value - BFD_RELOC_UNUSED). When
1787 called for data or limm values we use real reloc types. */
1788
1789static int
1790get_arc_exp_reloc_type (data_p, default_type, exp, expnew)
1791 int data_p;
1792 int default_type;
1793 expressionS *exp;
1794 expressionS *expnew;
1795{
1796 /* If the expression is "symbol >> 2" we must change it to just "symbol",
2d2255b5 1797 as fix_new_exp can't handle it. Similarly for (symbol - symbol) >> 2.
252b5132
RH
1798 That's ok though. What's really going on here is that we're using
1799 ">> 2" as a special syntax for specifying BFD_RELOC_ARC_B26. */
1800
1801 if (exp->X_op == O_right_shift
1802 && exp->X_op_symbol != NULL
0d2bcfaf
NC
1803 && exp->X_op_symbol->sy_value.X_op == O_constant
1804 && exp->X_op_symbol->sy_value.X_add_number == 2
252b5132
RH
1805 && exp->X_add_number == 0)
1806 {
1807 if (exp->X_add_symbol != NULL
0d2bcfaf
NC
1808 && (exp->X_add_symbol->sy_value.X_op == O_constant
1809 || exp->X_add_symbol->sy_value.X_op == O_symbol))
252b5132
RH
1810 {
1811 *expnew = *exp;
1812 expnew->X_op = O_symbol;
1813 expnew->X_op_symbol = NULL;
1814 return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
1815 }
1816 else if (exp->X_add_symbol != NULL
0d2bcfaf 1817 && exp->X_add_symbol->sy_value.X_op == O_subtract)
252b5132 1818 {
0d2bcfaf 1819 *expnew = exp->X_add_symbol->sy_value;
252b5132
RH
1820 return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
1821 }
1822 }
1823
1824 *expnew = *exp;
1825 return default_type;
1826}
1827
1828/* Apply a fixup to the object code. This is called for all the
1829 fixups we generated by the call to fix_new_exp, above. In the call
1830 above we used a reloc code which was the largest legal reloc code
1831 plus the operand index. Here we undo that to recover the operand
1832 index. At this point all symbol values should be fully resolved,
1833 and we attempt to completely resolve the reloc. If we can not do
1834 that, we determine the correct reloc code and put it back in the fixup. */
1835
94f592af
NC
1836void
1837md_apply_fix3 (fixP, valP, seg)
252b5132 1838 fixS *fixP;
94f592af 1839 valueT * valP;
252b5132
RH
1840 segT seg;
1841{
94f592af 1842 valueT value = * valP;
252b5132 1843
252b5132 1844 if (fixP->fx_addsy == (symbolS *) NULL)
94f592af
NC
1845 fixP->fx_done = 1;
1846
252b5132
RH
1847 else if (fixP->fx_pcrel)
1848 {
a161fe53
AM
1849 /* Hack around bfd_install_relocation brain damage. */
1850 if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
252b5132
RH
1851 value += md_pcrel_from (fixP);
1852 }
a161fe53
AM
1853
1854 /* We can't actually support subtracting a symbol. */
1855 if (fixP->fx_subsy != NULL)
1856 as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
252b5132
RH
1857
1858 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
1859 {
1860 int opindex;
1861 const struct arc_operand *operand;
1862 char *where;
1863 arc_insn insn;
1864
1865 opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
1866
1867 operand = &arc_operands[opindex];
1868
1869 /* Fetch the instruction, insert the fully resolved operand
1870 value, and stuff the instruction back again. */
1871 where = fixP->fx_frag->fr_literal + fixP->fx_where;
1872 if (target_big_endian)
1873 insn = bfd_getb32 ((unsigned char *) where);
1874 else
1875 insn = bfd_getl32 ((unsigned char *) where);
1876 insn = arc_insert_operand (insn, operand, -1, NULL, (offsetT) value,
1877 fixP->fx_file, fixP->fx_line);
1878 if (target_big_endian)
1879 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1880 else
1881 bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
1882
1883 if (fixP->fx_done)
1884 {
1885 /* Nothing else to do here. */
94f592af 1886 return;
252b5132
RH
1887 }
1888
1889 /* Determine a BFD reloc value based on the operand information.
1890 We are only prepared to turn a few of the operands into relocs.
1891 !!! Note that we can't handle limm values here. Since we're using
1892 implicit addends the addend must be inserted into the instruction,
1893 however, the opcode insertion routines currently do nothing with
1894 limm values. */
1895 if (operand->fmt == 'B')
1896 {
1897 assert ((operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0
1898 && operand->bits == 20
1899 && operand->shift == 7);
1900 fixP->fx_r_type = BFD_RELOC_ARC_B22_PCREL;
1901 }
0d2bcfaf 1902 else if (operand->fmt == 'J')
252b5132
RH
1903 {
1904 assert ((operand->flags & ARC_OPERAND_ABSOLUTE_BRANCH) != 0
1905 && operand->bits == 24
1906 && operand->shift == 32);
1907 fixP->fx_r_type = BFD_RELOC_ARC_B26;
1908 }
0d2bcfaf 1909 else if (operand->fmt == 'L')
252b5132
RH
1910 {
1911 assert ((operand->flags & ARC_OPERAND_LIMM) != 0
1912 && operand->bits == 32
1913 && operand->shift == 32);
1914 fixP->fx_r_type = BFD_RELOC_32;
1915 }
1916 else
1917 {
1918 as_bad_where (fixP->fx_file, fixP->fx_line,
0d2bcfaf 1919 "unresolved expression that must be resolved");
252b5132 1920 fixP->fx_done = 1;
94f592af 1921 return;
252b5132
RH
1922 }
1923 }
1924 else
1925 {
1926 switch (fixP->fx_r_type)
1927 {
1928 case BFD_RELOC_8:
1929 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1930 value, 1);
1931 break;
1932 case BFD_RELOC_16:
1933 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1934 value, 2);
1935 break;
1936 case BFD_RELOC_32:
1937 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1938 value, 4);
1939 break;
252b5132
RH
1940 case BFD_RELOC_ARC_B26:
1941 /* If !fixP->fx_done then `value' is an implicit addend.
1942 We must shift it right by 2 in this case as well because the
1943 linker performs the relocation and then adds this in (as opposed
1944 to adding this in and then shifting right by 2). */
1945 value >>= 2;
1946 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1947 value, 4);
1948 break;
1949 default:
1950 abort ();
1951 }
1952 }
252b5132
RH
1953}
1954
1955/* Translate internal representation of relocation info to BFD target
1956 format. */
1957
1958arelent *
1959tc_gen_reloc (section, fixP)
4a314ec8 1960 asection *section ATTRIBUTE_UNUSED;
252b5132
RH
1961 fixS *fixP;
1962{
1963 arelent *reloc;
1964
1965 reloc = (arelent *) xmalloc (sizeof (arelent));
65555e64 1966 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
252b5132 1967
65555e64 1968 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
252b5132
RH
1969 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1970 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
1971 if (reloc->howto == (reloc_howto_type *) NULL)
1972 {
1973 as_bad_where (fixP->fx_file, fixP->fx_line,
0d2bcfaf 1974 "internal error: can't export reloc type %d (`%s')",
19203624
KH
1975 fixP->fx_r_type,
1976 bfd_get_reloc_code_name (fixP->fx_r_type));
252b5132
RH
1977 return NULL;
1978 }
1979
1980 assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
1981
19203624 1982 /* Set addend to account for PC being advanced one insn before the
a161fe53 1983 target address is computed. */
252b5132 1984
19203624 1985 reloc->addend = (fixP->fx_pcrel ? -4 : 0);
252b5132 1986
0d2bcfaf 1987 return reloc;
252b5132 1988}
This page took 0.438032 seconds and 4 git commands to generate.