2005-02-17 Paul Brook <paul@codesourcery.com>
[deliverable/binutils-gdb.git] / gas / config / tc-arc.c
CommitLineData
252b5132 1/* tc-arc.c -- Assembler for the ARC
65555e64 2 Copyright 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003, 2004
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 {
439 /* Handle '+' specially as we want to allow "ld r0,[sp-4]". */
440 /* ??? The syntax has changed to [sp,-4]. */
441 if (0 && *syn == '+' && *str == '-')
442 {
443 /* Skip over syn's +, but leave str's - alone.
444 That makes the case identical to "ld r0,[sp+-4]". */
445 ++syn;
446 }
447 else if (*str == *syn)
448 {
449 if (*syn == ' ')
450 past_opcode_p = 1;
451 ++syn;
452 ++str;
453 }
454 else
455 break;
456 continue;
457 }
458
459 /* We have an operand. Pick out any modifiers. */
460 mods = 0;
4a314ec8 461 while (ARC_MOD_P (arc_operands[arc_operand_map[(int) *syn]].flags))
252b5132 462 {
4a314ec8 463 mods |= arc_operands[arc_operand_map[(int) *syn]].flags & ARC_MOD_BITS;
252b5132
RH
464 ++syn;
465 }
4a314ec8 466 operand = arc_operands + arc_operand_map[(int) *syn];
252b5132 467 if (operand->fmt == 0)
0d2bcfaf 468 as_fatal ("unknown syntax format character `%c'", *syn);
252b5132
RH
469
470 if (operand->flags & ARC_OPERAND_FAKE)
471 {
472 const char *errmsg = NULL;
473 if (operand->insert)
474 {
475 insn = (*operand->insert) (insn, operand, mods, NULL, 0, &errmsg);
1e07b820
KH
476 if (errmsg != (const char *) NULL)
477 {
478 last_errmsg = errmsg;
479 if (operand->flags & ARC_OPERAND_ERROR)
480 {
481 as_bad (errmsg);
482 return;
483 }
484 else if (operand->flags & ARC_OPERAND_WARN)
485 as_warn (errmsg);
486 break;
487 }
19203624
KH
488 if (limm_reloc_p
489 && (operand->flags && operand->flags & ARC_OPERAND_LIMM)
490 && (operand->flags &
491 (ARC_OPERAND_ABSOLUTE_BRANCH | ARC_OPERAND_ADDRESS)))
1e07b820
KH
492 {
493 fixups[fix_up_at].opindex = arc_operand_map[operand->fmt];
494 }
252b5132
RH
495 }
496 ++syn;
497 }
498 /* Are we finished with suffixes? */
499 else if (!past_opcode_p)
500 {
501 int found;
502 char c;
19203624
KH
503 char *s, *t;
504 const struct arc_operand_value *suf, *suffix_end;
0d2bcfaf 505 const struct arc_operand_value *suffix = NULL;
252b5132
RH
506
507 if (!(operand->flags & ARC_OPERAND_SUFFIX))
508 abort ();
509
510 /* If we're at a space in the input string, we want to skip the
511 remaining suffixes. There may be some fake ones though, so
512 just go on to try the next one. */
513 if (*str == ' ')
514 {
515 ++syn;
516 continue;
517 }
518
519 s = str;
520 if (mods & ARC_MOD_DOT)
521 {
522 if (*s != '.')
523 break;
524 ++s;
525 }
526 else
527 {
528 /* This can happen in "b.nd foo" and we're currently looking
529 for "%q" (ie: a condition code suffix). */
530 if (*s == '.')
531 {
532 ++syn;
533 continue;
534 }
535 }
536
537 /* Pick the suffix out and look it up via the hash table. */
3882b010 538 for (t = s; *t && ISALNUM (*t); ++t)
252b5132
RH
539 continue;
540 c = *t;
541 *t = '\0';
19203624 542 if ((suf = get_ext_suffix (s)))
1e07b820
KH
543 ext_suffix_p = 1;
544 else
545 suf = hash_find (arc_suffix_hash, s);
252b5132
RH
546 if (!suf)
547 {
548 /* This can happen in "blle foo" and we're currently using
549 the template "b%q%.n %j". The "bl" insn occurs later in
550 the table so "lle" isn't an illegal suffix. */
1e07b820 551 *t = c;
252b5132
RH
552 break;
553 }
554
555 /* Is it the right type? Note that the same character is used
1e07b820 556 several times, so we have to examine all of them. This is
252b5132
RH
557 relatively efficient as equivalent entries are kept
558 together. If it's not the right type, don't increment `str'
559 so we try the next one in the series. */
560 found = 0;
1e07b820
KH
561 if (ext_suffix_p && arc_operands[suf->type].fmt == *syn)
562 {
563 /* Insert the suffix's value into the insn. */
564 *t = c;
565 if (operand->insert)
566 insn = (*operand->insert) (insn, operand,
567 mods, NULL, suf->value,
568 NULL);
569 else
570 insn |= suf->value << operand->shift;
571
572 str = t;
573 found = 1;
574 }
575 else
576 {
577 *t = c;
578 suffix_end = arc_suffixes + arc_suffixes_count;
579 for (suffix = suf;
580 suffix < suffix_end && strcmp (suffix->name, suf->name) == 0;
581 ++suffix)
582 {
583 if (arc_operands[suffix->type].fmt == *syn)
584 {
585 /* Insert the suffix's value into the insn. */
586 if (operand->insert)
587 insn = (*operand->insert) (insn, operand,
588 mods, NULL, suffix->value,
589 NULL);
590 else
591 insn |= suffix->value << operand->shift;
592
593 str = t;
594 found = 1;
595 break;
596 }
597 }
598 }
252b5132
RH
599 ++syn;
600 if (!found)
19203624
KH
601 /* Wrong type. Just go on to try next insn entry. */
602 ;
252b5132
RH
603 else
604 {
605 if (num_suffixes == MAX_SUFFIXES)
0d2bcfaf 606 as_bad ("too many suffixes");
252b5132
RH
607 else
608 insn_suffixes[num_suffixes++] = suffix;
609 }
610 }
611 else
612 /* This is either a register or an expression of some kind. */
613 {
252b5132
RH
614 char *hold;
615 const struct arc_operand_value *reg = NULL;
616 long value = 0;
617 expressionS exp;
618
619 if (operand->flags & ARC_OPERAND_SUFFIX)
620 abort ();
621
622 /* Is there anything left to parse?
623 We don't check for this at the top because we want to parse
624 any trailing fake arguments in the syntax string. */
2d0441d9 625 if (is_end_of_line[(unsigned char) *str])
252b5132 626 break;
252b5132
RH
627
628 /* Parse the operand. */
629 hold = input_line_pointer;
630 input_line_pointer = str;
631 expression (&exp);
632 str = input_line_pointer;
633 input_line_pointer = hold;
634
635 if (exp.X_op == O_illegal)
0d2bcfaf 636 as_bad ("illegal operand");
252b5132 637 else if (exp.X_op == O_absent)
0d2bcfaf 638 as_bad ("missing operand");
252b5132
RH
639 else if (exp.X_op == O_constant)
640 {
641 value = exp.X_add_number;
642 }
643 else if (exp.X_op == O_register)
644 {
0d2bcfaf 645 reg = (struct arc_operand_value *) exp.X_add_number;
252b5132 646 }
0d2bcfaf
NC
647#define IS_REG_DEST_OPERAND(o) ((o) == 'a')
648 else if (IS_REG_DEST_OPERAND (*syn))
19203624 649 as_bad ("symbol as destination register");
1e07b820 650 else
252b5132 651 {
19203624 652 if (!strncmp (str, "@h30", 4))
1e07b820 653 {
19203624 654 arc_code_symbol (&exp);
1e07b820
KH
655 str += 4;
656 }
252b5132
RH
657 /* We need to generate a fixup for this expression. */
658 if (fc >= MAX_FIXUPS)
0d2bcfaf 659 as_fatal ("too many fixups");
252b5132 660 fixups[fc].exp = exp;
1e07b820 661 /* We don't support shimm relocs. break here to force
19203624 662 the assembler to output a limm. */
0d2bcfaf 663#define IS_REG_SHIMM_OFFSET(o) ((o) == 'd')
19203624 664 if (IS_REG_SHIMM_OFFSET (*syn))
1e07b820 665 break;
252b5132
RH
666 /* If this is a register constant (IE: one whose
667 register value gets stored as 61-63) then this
bfb32b52 668 must be a limm. */
252b5132
RH
669 /* ??? This bit could use some cleaning up.
670 Referencing the format chars like this goes
671 against style. */
0d2bcfaf 672 if (IS_SYMBOL_OPERAND (*syn))
252b5132
RH
673 {
674 const char *junk;
252b5132 675 limm_reloc_p = 1;
19203624 676 /* Save this, we don't yet know what reloc to use. */
1e07b820 677 fix_up_at = fc;
252b5132
RH
678 /* Tell insert_reg we need a limm. This is
679 needed because the value at this point is
680 zero, a shimm. */
681 /* ??? We need a cleaner interface than this. */
682 (*arc_operands[arc_operand_map['Q']].insert)
683 (insn, operand, mods, reg, 0L, &junk);
684 }
685 else
4a314ec8 686 fixups[fc].opindex = arc_operand_map[(int) *syn];
252b5132
RH
687 ++fc;
688 value = 0;
689 }
690
691 /* Insert the register or expression into the instruction. */
692 if (operand->insert)
693 {
694 const char *errmsg = NULL;
695 insn = (*operand->insert) (insn, operand, mods,
696 reg, (long) value, &errmsg);
1e07b820
KH
697 if (errmsg != (const char *) NULL)
698 {
699 last_errmsg = errmsg;
700 if (operand->flags & ARC_OPERAND_ERROR)
701 {
702 as_bad (errmsg);
703 return;
704 }
705 else if (operand->flags & ARC_OPERAND_WARN)
706 as_warn (errmsg);
707 break;
708 }
252b5132
RH
709 }
710 else
711 insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
712
713 ++syn;
714 }
715 }
716
717 /* If we're at the end of the syntax string, we're done. */
718 /* FIXME: try to move this to a separate function. */
719 if (*syn == '\0')
720 {
721 int i;
722 char *f;
723 long limm, limm_p;
724
725 /* For the moment we assume a valid `str' can only contain blanks
726 now. IE: We needn't try again with a longer version of the
727 insn and it is assumed that longer versions of insns appear
728 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
729
3882b010 730 while (ISSPACE (*str))
252b5132
RH
731 ++str;
732
2d0441d9 733 if (!is_end_of_line[(unsigned char) *str])
0d2bcfaf 734 as_bad ("junk at end of line: `%s'", str);
252b5132
RH
735
736 /* Is there a limm value? */
737 limm_p = arc_opcode_limm_p (&limm);
738
739 /* Perform various error and warning tests. */
740
741 {
742 static int in_delay_slot_p = 0;
743 static int prev_insn_needs_cc_nop_p = 0;
744 /* delay slot type seen */
745 int delay_slot_type = ARC_DELAY_NONE;
746 /* conditional execution flag seen */
747 int conditional = 0;
748 /* 1 if condition codes are being set */
749 int cc_set_p = 0;
750 /* 1 if conditional branch, including `b' "branch always" */
751 int cond_branch_p = opcode->flags & ARC_OPCODE_COND_BRANCH;
252b5132
RH
752
753 for (i = 0; i < num_suffixes; ++i)
754 {
755 switch (arc_operands[insn_suffixes[i]->type].fmt)
756 {
19203624 757 case 'n':
252b5132
RH
758 delay_slot_type = insn_suffixes[i]->value;
759 break;
19203624 760 case 'q':
252b5132
RH
761 conditional = insn_suffixes[i]->value;
762 break;
19203624 763 case 'f':
252b5132
RH
764 cc_set_p = 1;
765 break;
766 }
767 }
768
769 /* Putting an insn with a limm value in a delay slot is supposed to
770 be legal, but let's warn the user anyway. Ditto for 8 byte
771 jumps with delay slots. */
772 if (in_delay_slot_p && limm_p)
1e07b820 773 as_warn ("8 byte instruction in delay slot");
0d2bcfaf 774 if (delay_slot_type != ARC_DELAY_NONE
19203624 775 && limm_p && arc_insn_not_jl (insn)) /* except for jl addr */
1e07b820 776 as_warn ("8 byte jump instruction with delay slot");
252b5132
RH
777 in_delay_slot_p = (delay_slot_type != ARC_DELAY_NONE) && !limm_p;
778
779 /* Warn when a conditional branch immediately follows a set of
780 the condition codes. Note that this needn't be done if the
781 insn that sets the condition codes uses a limm. */
782 if (cond_branch_p && conditional != 0 /* 0 = "always" */
0d2bcfaf 783 && prev_insn_needs_cc_nop_p && arc_mach_type == bfd_mach_arc_5)
1e07b820 784 as_warn ("conditional branch follows set of flags");
0d2bcfaf 785 prev_insn_needs_cc_nop_p =
1e07b820
KH
786 /* FIXME: ??? not required:
787 (delay_slot_type != ARC_DELAY_NONE) && */
788 cc_set_p && !limm_p;
252b5132
RH
789 }
790
791 /* Write out the instruction.
792 It is important to fetch enough space in one call to `frag_more'.
793 We use (f - frag_now->fr_literal) to compute where we are and we
794 don't want frag_now to change between calls. */
795 if (limm_p)
796 {
797 f = frag_more (8);
798 md_number_to_chars (f, insn, 4);
799 md_number_to_chars (f + 4, limm, 4);
9fcc94b6 800 dwarf2_emit_insn (8);
252b5132
RH
801 }
802 else if (limm_reloc_p)
803 {
804 /* We need a limm reloc, but the tables think we don't. */
805 abort ();
806 }
807 else
808 {
809 f = frag_more (4);
810 md_number_to_chars (f, insn, 4);
9fcc94b6 811 dwarf2_emit_insn (4);
252b5132
RH
812 }
813
814 /* Create any fixups. */
815 for (i = 0; i < fc; ++i)
816 {
817 int op_type, reloc_type;
818 expressionS exptmp;
819 const struct arc_operand *operand;
820
821 /* Create a fixup for this operand.
822 At this point we do not use a bfd_reloc_code_real_type for
823 operands residing in the insn, but instead just use the
824 operand index. This lets us easily handle fixups for any
825 operand type, although that is admittedly not a very exciting
94f592af 826 feature. We pick a BFD reloc type in md_apply_fix3.
252b5132
RH
827
828 Limm values (4 byte immediate "constants") must be treated
829 normally because they're not part of the actual insn word
830 and thus the insertion routines don't handle them. */
831
832 if (arc_operands[fixups[i].opindex].flags & ARC_OPERAND_LIMM)
833 {
19203624
KH
834 /* Modify the fixup addend as required by the cpu. */
835 fixups[i].exp.X_add_number += arc_limm_fixup_adjust (insn);
252b5132
RH
836 op_type = fixups[i].opindex;
837 /* FIXME: can we add this data to the operand table? */
0d2bcfaf 838 if (op_type == arc_operand_map['L']
1e07b820
KH
839 || op_type == arc_operand_map['s']
840 || op_type == arc_operand_map['o']
841 || op_type == arc_operand_map['O'])
252b5132
RH
842 reloc_type = BFD_RELOC_32;
843 else if (op_type == arc_operand_map['J'])
844 reloc_type = BFD_RELOC_ARC_B26;
845 else
846 abort ();
847 reloc_type = get_arc_exp_reloc_type (1, reloc_type,
848 &fixups[i].exp,
849 &exptmp);
850 }
851 else
852 {
853 op_type = get_arc_exp_reloc_type (0, fixups[i].opindex,
854 &fixups[i].exp, &exptmp);
855 reloc_type = op_type + (int) BFD_RELOC_UNUSED;
856 }
857 operand = &arc_operands[op_type];
858 fix_new_exp (frag_now,
859 ((f - frag_now->fr_literal)
860 + (operand->flags & ARC_OPERAND_LIMM ? 4 : 0)), 4,
861 &exptmp,
862 (operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0,
863 (bfd_reloc_code_real_type) reloc_type);
864 }
865
866 /* All done. */
867 return;
868 }
869
870 /* Try the next entry. */
871 }
872
19203624 873 if (NULL == last_errmsg)
0d2bcfaf
NC
874 as_bad ("bad instruction `%s'", start);
875 else
876 as_bad (last_errmsg);
252b5132
RH
877}
878\f
252b5132 879static void
0d2bcfaf
NC
880arc_extoper (opertype)
881 int opertype;
252b5132
RH
882{
883 char *name;
0d2bcfaf 884 char *mode;
252b5132
RH
885 char c;
886 char *p;
0d2bcfaf
NC
887 int imode = 0;
888 int number;
889 struct arc_ext_operand_value *ext_oper;
252b5132
RH
890 symbolS *symbolP;
891
0d2bcfaf
NC
892 segT old_sec;
893 int old_subsec;
894
252b5132
RH
895 name = input_line_pointer;
896 c = get_symbol_end ();
19203624 897 name = xstrdup (name);
0d2bcfaf
NC
898
899 p = name;
900 while (*p)
901 {
3882b010 902 *p = TOLOWER (*p);
1e07b820 903 p++;
0d2bcfaf
NC
904 }
905
bcee8eb8 906 /* just after name is now '\0' */
252b5132
RH
907 p = input_line_pointer;
908 *p = c;
909 SKIP_WHITESPACE ();
0d2bcfaf 910
252b5132
RH
911 if (*input_line_pointer != ',')
912 {
0d2bcfaf 913 as_bad ("expected comma after operand name");
252b5132 914 ignore_rest_of_line ();
19203624 915 free (name);
252b5132
RH
916 return;
917 }
0d2bcfaf 918
bcee8eb8 919 input_line_pointer++; /* skip ',' */
0d2bcfaf
NC
920 number = get_absolute_expression ();
921
19203624 922 if (number < 0)
0d2bcfaf 923 {
19203624
KH
924 as_bad ("negative operand number %d", number);
925 ignore_rest_of_line ();
926 free (name);
1e07b820 927 return;
0d2bcfaf
NC
928 }
929
930 if (opertype)
931 {
19203624 932 SKIP_WHITESPACE ();
0d2bcfaf
NC
933
934 if (*input_line_pointer != ',')
1e07b820
KH
935 {
936 as_bad ("expected comma after register-number");
937 ignore_rest_of_line ();
19203624 938 free (name);
1e07b820
KH
939 return;
940 }
bfb32b52 941
bcee8eb8 942 input_line_pointer++; /* skip ',' */
0d2bcfaf 943 mode = input_line_pointer;
bfb32b52 944
19203624 945 if (!strncmp (mode, "r|w", 3))
1e07b820
KH
946 {
947 imode = 0;
948 input_line_pointer += 3;
949 }
0d2bcfaf 950 else
1e07b820 951 {
19203624 952 if (!strncmp (mode, "r", 1))
1e07b820
KH
953 {
954 imode = ARC_REGISTER_READONLY;
955 input_line_pointer += 1;
956 }
957 else
958 {
19203624 959 if (strncmp (mode, "w", 1))
1e07b820
KH
960 {
961 as_bad ("invalid mode");
19203624
KH
962 ignore_rest_of_line ();
963 free (name);
1e07b820
KH
964 return;
965 }
966 else
967 {
968 imode = ARC_REGISTER_WRITEONLY;
969 input_line_pointer += 1;
970 }
971 }
972 }
19203624 973 SKIP_WHITESPACE ();
1e07b820
KH
974 if (1 == opertype)
975 {
976 if (*input_line_pointer != ',')
977 {
978 as_bad ("expected comma after register-mode");
979 ignore_rest_of_line ();
19203624 980 free (name);
1e07b820
KH
981 return;
982 }
983
bcee8eb8 984 input_line_pointer++; /* skip ',' */
1e07b820 985
19203624 986 if (!strncmp (input_line_pointer, "cannot_shortcut", 15))
1e07b820 987 {
19203624 988 imode |= arc_get_noshortcut_flag ();
1e07b820
KH
989 input_line_pointer += 15;
990 }
991 else
992 {
19203624 993 if (strncmp (input_line_pointer, "can_shortcut", 12))
1e07b820
KH
994 {
995 as_bad ("shortcut designator invalid");
19203624
KH
996 ignore_rest_of_line ();
997 free (name);
1e07b820
KH
998 return;
999 }
1000 else
1001 {
1002 input_line_pointer += 12;
1003 }
1004 }
1005 }
1006 }
0d2bcfaf
NC
1007
1008 if ((opertype == 1) && number > 60)
1e07b820 1009 {
19203624
KH
1010 as_bad ("core register value (%d) too large", number);
1011 ignore_rest_of_line ();
1012 free (name);
1e07b820
KH
1013 return;
1014 }
0d2bcfaf
NC
1015
1016 if ((opertype == 0) && number > 31)
1e07b820 1017 {
19203624
KH
1018 as_bad ("condition code value (%d) too large", number);
1019 ignore_rest_of_line ();
1020 free (name);
1e07b820
KH
1021 return;
1022 }
0d2bcfaf
NC
1023
1024 ext_oper = (struct arc_ext_operand_value *) \
19203624 1025 xmalloc (sizeof (struct arc_ext_operand_value));
0d2bcfaf 1026
19203624 1027 if (opertype)
0d2bcfaf 1028 {
19203624 1029 /* If the symbol already exists, point it at the new definition. */
0d2bcfaf 1030 if ((symbolP = symbol_find (name)))
1e07b820 1031 {
19203624
KH
1032 if (S_GET_SEGMENT (symbolP) == reg_section)
1033 S_SET_VALUE (symbolP, (int) &ext_oper->operand);
1e07b820
KH
1034 else
1035 {
19203624
KH
1036 as_bad ("attempt to override symbol: %s", name);
1037 ignore_rest_of_line ();
1038 free (name);
1039 free (ext_oper);
1e07b820
KH
1040 return;
1041 }
1042 }
0d2bcfaf 1043 else
1e07b820 1044 {
19203624 1045 /* If its not there, add it. */
1e07b820
KH
1046 symbol_table_insert (symbol_create (name, reg_section,
1047 (int) &ext_oper->operand, &zero_address_frag));
1048 }
0d2bcfaf
NC
1049 }
1050
1051 ext_oper->operand.name = name;
1052 ext_oper->operand.value = number;
19203624 1053 ext_oper->operand.type = arc_operand_type (opertype);
0d2bcfaf
NC
1054 ext_oper->operand.flags = imode;
1055
1056 ext_oper->next = arc_ext_operands;
1057 arc_ext_operands = ext_oper;
1058
19203624
KH
1059 /* OK, now that we know what this operand is, put a description in
1060 the arc extension section of the output file. */
0d2bcfaf
NC
1061
1062 old_sec = now_seg;
1063 old_subsec = now_subseg;
1064
19203624 1065 arc_set_ext_seg ();
0d2bcfaf
NC
1066
1067 switch (opertype)
1e07b820
KH
1068 {
1069 case 0:
19203624
KH
1070 p = frag_more (1);
1071 *p = 3 + strlen (name) + 1;
1072 p = frag_more (1);
1e07b820 1073 *p = EXT_COND_CODE;
19203624 1074 p = frag_more (1);
1e07b820 1075 *p = number;
19203624
KH
1076 p = frag_more (strlen (name) + 1);
1077 strcpy (p, name);
1e07b820
KH
1078 break;
1079 case 1:
19203624
KH
1080 p = frag_more (1);
1081 *p = 3 + strlen (name) + 1;
1082 p = frag_more (1);
1e07b820 1083 *p = EXT_CORE_REGISTER;
19203624 1084 p = frag_more (1);
1e07b820 1085 *p = number;
19203624
KH
1086 p = frag_more (strlen (name) + 1);
1087 strcpy (p, name);
1e07b820
KH
1088 break;
1089 case 2:
19203624
KH
1090 p = frag_more (1);
1091 *p = 6 + strlen (name) + 1;
1092 p = frag_more (1);
1e07b820 1093 *p = EXT_AUX_REGISTER;
19203624 1094 p = frag_more (1);
1e07b820 1095 *p = number >> 24 & 0xff;
19203624 1096 p = frag_more (1);
1e07b820 1097 *p = number >> 16 & 0xff;
19203624 1098 p = frag_more (1);
1e07b820 1099 *p = number >> 8 & 0xff;
19203624 1100 p = frag_more (1);
1e07b820 1101 *p = number & 0xff;
19203624
KH
1102 p = frag_more (strlen (name) + 1);
1103 strcpy (p, name);
1e07b820
KH
1104 break;
1105 default:
19203624
KH
1106 as_bad ("invalid opertype");
1107 ignore_rest_of_line ();
1108 free (name);
1e07b820
KH
1109 return;
1110 break;
1111 }
0d2bcfaf
NC
1112
1113 subseg_set (old_sec, old_subsec);
1114
19203624 1115 /* Enter all registers into the symbol table. */
0d2bcfaf 1116
19203624 1117 demand_empty_rest_of_line ();
0d2bcfaf
NC
1118}
1119
1120static void
1121arc_extinst (ignore)
19203624 1122 int ignore ATTRIBUTE_UNUSED;
0d2bcfaf
NC
1123{
1124 unsigned char syntax[129];
1125 char *name;
1126 char *p;
1127 char c;
1128 int suffixcode = -1;
19203624 1129 int opcode, subopcode;
0d2bcfaf
NC
1130 int i;
1131 int class = 0;
1132 int name_len;
1133 struct arc_opcode *ext_op;
1134
1135 segT old_sec;
1136 int old_subsec;
1137
1138 name = input_line_pointer;
1139 c = get_symbol_end ();
19203624 1140 name = xstrdup (name);
19203624
KH
1141 strcpy (syntax, name);
1142 name_len = strlen (name);
0d2bcfaf 1143
bcee8eb8 1144 /* just after name is now '\0' */
0d2bcfaf
NC
1145 p = input_line_pointer;
1146 *p = c;
1147
1148 SKIP_WHITESPACE ();
1149
1150 if (*input_line_pointer != ',')
252b5132 1151 {
0d2bcfaf 1152 as_bad ("expected comma after operand name");
252b5132
RH
1153 ignore_rest_of_line ();
1154 return;
1155 }
0d2bcfaf 1156
bcee8eb8 1157 input_line_pointer++; /* skip ',' */
0d2bcfaf
NC
1158 opcode = get_absolute_expression ();
1159
1160 SKIP_WHITESPACE ();
1161
1162 if (*input_line_pointer != ',')
252b5132 1163 {
0d2bcfaf 1164 as_bad ("expected comma after opcode");
252b5132
RH
1165 ignore_rest_of_line ();
1166 return;
1167 }
0d2bcfaf 1168
bcee8eb8 1169 input_line_pointer++; /* skip ',' */
0d2bcfaf
NC
1170 subopcode = get_absolute_expression ();
1171
19203624 1172 if (subopcode < 0)
252b5132 1173 {
19203624
KH
1174 as_bad ("negative subopcode %d", subopcode);
1175 ignore_rest_of_line ();
1e07b820 1176 return;
252b5132 1177 }
0d2bcfaf 1178
19203624 1179 if (subopcode)
0d2bcfaf 1180 {
19203624 1181 if (3 != opcode)
1e07b820
KH
1182 {
1183 as_bad ("subcode value found when opcode not equal 0x03");
19203624 1184 ignore_rest_of_line ();
1e07b820
KH
1185 return;
1186 }
1187 else
1188 {
1189 if (subopcode < 0x09 || subopcode == 0x3f)
1190 {
1191 as_bad ("invalid subopcode %d", subopcode);
19203624 1192 ignore_rest_of_line ();
1e07b820
KH
1193 return;
1194 }
1195 }
0d2bcfaf
NC
1196 }
1197
1198 SKIP_WHITESPACE ();
1199
252b5132
RH
1200 if (*input_line_pointer != ',')
1201 {
0d2bcfaf 1202 as_bad ("expected comma after subopcode");
252b5132
RH
1203 ignore_rest_of_line ();
1204 return;
1205 }
0d2bcfaf 1206
bcee8eb8 1207 input_line_pointer++; /* skip ',' */
0d2bcfaf 1208
19203624 1209 for (i = 0; i < (int) MAXSUFFIXCLASS; i++)
0d2bcfaf 1210 {
19203624 1211 if (!strncmp (suffixclass[i].name,input_line_pointer, suffixclass[i].len))
1e07b820
KH
1212 {
1213 suffixcode = i;
1214 input_line_pointer += suffixclass[i].len;
1215 break;
1216 }
0d2bcfaf
NC
1217 }
1218
19203624 1219 if (-1 == suffixcode)
0d2bcfaf
NC
1220 {
1221 as_bad ("invalid suffix class");
1222 ignore_rest_of_line ();
1223 return;
1224 }
1225
252b5132 1226 SKIP_WHITESPACE ();
0d2bcfaf
NC
1227
1228 if (*input_line_pointer != ',')
252b5132 1229 {
0d2bcfaf
NC
1230 as_bad ("expected comma after suffix class");
1231 ignore_rest_of_line ();
1232 return;
252b5132 1233 }
0d2bcfaf 1234
bcee8eb8 1235 input_line_pointer++; /* skip ',' */
0d2bcfaf 1236
19203624 1237 for (i = 0; i < (int) MAXSYNTAXCLASS; i++)
252b5132 1238 {
19203624 1239 if (!strncmp (syntaxclass[i].name,input_line_pointer, syntaxclass[i].len))
1e07b820
KH
1240 {
1241 class = syntaxclass[i].class;
1242 input_line_pointer += syntaxclass[i].len;
1243 break;
1244 }
252b5132 1245 }
252b5132 1246
19203624 1247 if (0 == (SYNTAX_VALID & class))
0d2bcfaf
NC
1248 {
1249 as_bad ("invalid syntax class");
1250 ignore_rest_of_line ();
1251 return;
1252 }
1253
19203624 1254 if ((0x3 == opcode) & (class & SYNTAX_3OP))
0d2bcfaf
NC
1255 {
1256 as_bad ("opcode 0x3 and SYNTAX_3OP invalid");
1257 ignore_rest_of_line ();
1258 return;
1259 }
1260
1261 switch (suffixcode)
1e07b820
KH
1262 {
1263 case 0:
19203624 1264 strcat (syntax, "%.q%.f ");
1e07b820
KH
1265 break;
1266 case 1:
19203624 1267 strcat (syntax, "%.f ");
1e07b820
KH
1268 break;
1269 case 2:
19203624 1270 strcat (syntax, "%.q ");
1e07b820
KH
1271 break;
1272 case 3:
19203624 1273 strcat (syntax, " ");
1e07b820
KH
1274 break;
1275 default:
19203624
KH
1276 as_bad ("unknown suffix class");
1277 ignore_rest_of_line ();
1e07b820
KH
1278 return;
1279 break;
1280 };
0d2bcfaf 1281
19203624
KH
1282 strcat (syntax, ((opcode == 0x3) ? "%a,%b" : ((class & SYNTAX_3OP) ? "%a,%b,%c" : "%b,%c")));
1283 if (suffixcode < 2)
1284 strcat (syntax, "%F");
1285 strcat (syntax, "%S%L");
0d2bcfaf 1286
19203624 1287 ext_op = (struct arc_opcode *) xmalloc (sizeof (struct arc_opcode));
19203624 1288 ext_op->syntax = xstrdup (syntax);
0d2bcfaf 1289
19203624
KH
1290 ext_op->mask = I (-1) | ((0x3 == opcode) ? C (-1) : 0);
1291 ext_op->value = I (opcode) | ((0x3 == opcode) ? C (subopcode) : 0);
0d2bcfaf
NC
1292 ext_op->flags = class;
1293 ext_op->next_asm = arc_ext_opcodes;
1294 ext_op->next_dis = arc_ext_opcodes;
1295 arc_ext_opcodes = ext_op;
1296
19203624
KH
1297 /* OK, now that we know what this inst is, put a description in the
1298 arc extension section of the output file. */
0d2bcfaf
NC
1299
1300 old_sec = now_seg;
1301 old_subsec = now_subseg;
1302
19203624 1303 arc_set_ext_seg ();
0d2bcfaf 1304
19203624
KH
1305 p = frag_more (1);
1306 *p = 5 + name_len + 1;
1307 p = frag_more (1);
0d2bcfaf 1308 *p = EXT_INSTRUCTION;
19203624 1309 p = frag_more (1);
0d2bcfaf 1310 *p = opcode;
19203624 1311 p = frag_more (1);
0d2bcfaf 1312 *p = subopcode;
19203624 1313 p = frag_more (1);
0d2bcfaf 1314 *p = (class & (OP1_MUST_BE_IMM | OP1_IMM_IMPLIED) ? IGNORE_FIRST_OPD : 0);
19203624
KH
1315 p = frag_more (name_len);
1316 strncpy (p, syntax, name_len);
1317 p = frag_more (1);
0d2bcfaf
NC
1318 *p = '\0';
1319
1320 subseg_set (old_sec, old_subsec);
1321
19203624 1322 demand_empty_rest_of_line ();
252b5132
RH
1323}
1324
0d2bcfaf 1325int
19203624 1326arc_set_ext_seg ()
0d2bcfaf
NC
1327{
1328 if (!arcext_section)
1329 {
1330 arcext_section = subseg_new (".arcextmap", 0);
1331 bfd_set_section_flags (stdoutput, arcext_section,
19203624 1332 SEC_READONLY | SEC_HAS_CONTENTS);
0d2bcfaf
NC
1333 }
1334 else
1335 subseg_set (arcext_section, 0);
1336 return 1;
1337}
252b5132
RH
1338
1339static void
0d2bcfaf
NC
1340arc_common (localScope)
1341 int localScope;
252b5132 1342{
0d2bcfaf 1343 char *name;
252b5132 1344 char c;
0d2bcfaf 1345 char *p;
19203624 1346 int align, size;
0d2bcfaf 1347 symbolS *symbolP;
252b5132 1348
0d2bcfaf
NC
1349 name = input_line_pointer;
1350 c = get_symbol_end ();
bcee8eb8 1351 /* just after name is now '\0' */
0d2bcfaf
NC
1352 p = input_line_pointer;
1353 *p = c;
1354 SKIP_WHITESPACE ();
1355
1356 if (*input_line_pointer != ',')
252b5132 1357 {
0d2bcfaf 1358 as_bad ("expected comma after symbol name");
252b5132
RH
1359 ignore_rest_of_line ();
1360 return;
1361 }
1362
bcee8eb8 1363 input_line_pointer++; /* skip ',' */
0d2bcfaf 1364 size = get_absolute_expression ();
252b5132 1365
0d2bcfaf
NC
1366 if (size < 0)
1367 {
1368 as_bad ("negative symbol length");
1369 ignore_rest_of_line ();
1370 return;
1371 }
252b5132 1372
0d2bcfaf
NC
1373 *p = 0;
1374 symbolP = symbol_find_or_make (name);
1375 *p = c;
1376
1377 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
1378 {
1379 as_bad ("ignoring attempt to re-define symbol");
1380 ignore_rest_of_line ();
1381 return;
1382 }
19203624
KH
1383 if (((int) S_GET_VALUE (symbolP) != 0) \
1384 && ((int) S_GET_VALUE (symbolP) != size))
0d2bcfaf
NC
1385 {
1386 as_warn ("length of symbol \"%s\" already %ld, ignoring %d",
1387 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
1388 }
1389 assert (symbolP->sy_frag == &zero_address_frag);
1390
0d2bcfaf
NC
1391 /* Now parse the alignment field. This field is optional for
1392 local and global symbols. Default alignment is zero. */
1393 if (*input_line_pointer == ',')
1394 {
1395 input_line_pointer++;
1396 align = get_absolute_expression ();
1397 if (align < 0)
1398 {
1399 align = 0;
1400 as_warn ("assuming symbol alignment of zero");
1401 }
1402 }
252b5132 1403 else
0d2bcfaf
NC
1404 align = 0;
1405
1406 if (localScope != 0)
252b5132 1407 {
0d2bcfaf
NC
1408 segT old_sec;
1409 int old_subsec;
1410 char *pfrag;
1411
1412 old_sec = now_seg;
1413 old_subsec = now_subseg;
1414 record_alignment (bss_section, align);
bcee8eb8 1415 subseg_set (bss_section, 0); /* ??? subseg_set (bss_section, 1); ??? */
0d2bcfaf
NC
1416
1417 if (align)
19203624
KH
1418 /* Do alignment. */
1419 frag_align (align, 0, 0);
0d2bcfaf 1420
19203624 1421 /* Detach from old frag. */
0d2bcfaf
NC
1422 if (S_GET_SEGMENT (symbolP) == bss_section)
1423 symbolP->sy_frag->fr_symbol = NULL;
1424
1425 symbolP->sy_frag = frag_now;
1426 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
19203624 1427 (offsetT) size, (char *) 0);
0d2bcfaf
NC
1428 *pfrag = 0;
1429
1430 S_SET_SIZE (symbolP, size);
1431 S_SET_SEGMENT (symbolP, bss_section);
1432 S_CLEAR_EXTERNAL (symbolP);
1433 symbolP->local = 1;
1434 subseg_set (old_sec, old_subsec);
1435 }
1436 else
1437 {
1438 S_SET_VALUE (symbolP, (valueT) size);
1439 S_SET_ALIGN (symbolP, align);
1440 S_SET_EXTERNAL (symbolP);
1441 S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
252b5132 1442 }
252b5132 1443
0d2bcfaf
NC
1444 symbolP->bsym->flags |= BSF_OBJECT;
1445
1446 demand_empty_rest_of_line ();
252b5132 1447}
0d2bcfaf 1448\f
0d2bcfaf 1449/* Select the cpu we're assembling for. */
252b5132
RH
1450
1451static void
0d2bcfaf 1452arc_option (ignore)
19203624 1453 int ignore ATTRIBUTE_UNUSED;
252b5132 1454{
0d2bcfaf 1455 int mach;
252b5132 1456 char c;
0d2bcfaf 1457 char *cpu;
252b5132 1458
0d2bcfaf 1459 cpu = input_line_pointer;
252b5132 1460 c = get_symbol_end ();
0d2bcfaf 1461 mach = arc_get_mach (cpu);
252b5132
RH
1462 *input_line_pointer = c;
1463
0d2bcfaf
NC
1464 /* If an instruction has already been seen, it's too late. */
1465 if (cpu_tables_init_p)
252b5132 1466 {
0d2bcfaf 1467 as_bad ("\".option\" directive must appear before any instructions");
252b5132
RH
1468 ignore_rest_of_line ();
1469 return;
1470 }
252b5132 1471
0d2bcfaf
NC
1472 if (mach == -1)
1473 goto bad_cpu;
1474
1475 if (mach_type_specified_p && mach != arc_mach_type)
252b5132 1476 {
0d2bcfaf 1477 as_bad ("\".option\" directive conflicts with initial definition");
252b5132
RH
1478 ignore_rest_of_line ();
1479 return;
1480 }
0d2bcfaf
NC
1481 else
1482 {
1483 /* The cpu may have been selected on the command line. */
1484 if (mach != arc_mach_type)
1485 as_warn ("\".option\" directive overrides command-line (default) value");
1486 arc_mach_type = mach;
1487 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
1488 as_fatal ("could not set architecture and machine");
1489 mach_type_specified_p = 1;
1490 }
252b5132 1491 demand_empty_rest_of_line ();
0d2bcfaf
NC
1492 return;
1493
1494 bad_cpu:
1495 as_bad ("invalid identifier for \".option\"");
1496 ignore_rest_of_line ();
252b5132 1497}
252b5132 1498\f
19203624
KH
1499/* Turn a string in input_line_pointer into a floating point constant
1500 of type TYPE, and store the appropriate bytes in *LITP. The number
1501 of LITTLENUMS emitted is stored in *SIZEP. An error message is
1502 returned, or NULL on OK. */
252b5132 1503
0d2bcfaf 1504/* Equal to MAX_PRECISION in atof-ieee.c */
252b5132
RH
1505#define MAX_LITTLENUMS 6
1506
1507char *
1508md_atof (type, litP, sizeP)
89b57c9a 1509 int type;
19203624
KH
1510 char *litP;
1511 int *sizeP;
252b5132
RH
1512{
1513 int prec;
1514 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1515 LITTLENUM_TYPE *wordP;
1516 char *t;
252b5132
RH
1517
1518 switch (type)
1519 {
1520 case 'f':
1521 case 'F':
1522 prec = 2;
1523 break;
1524
1525 case 'd':
1526 case 'D':
1527 prec = 4;
1528 break;
1529
1530 default:
1531 *sizeP = 0;
0d2bcfaf 1532 return "bad call to md_atof";
252b5132
RH
1533 }
1534
1535 t = atof_ieee (input_line_pointer, type, words);
1536 if (t)
1537 input_line_pointer = t;
1538 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1539 for (wordP = words; prec--;)
1540 {
1541 md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
1542 litP += sizeof (LITTLENUM_TYPE);
1543 }
1544
1545 return NULL;
1546}
1547
1548/* Write a value out to the object file, using the appropriate
1549 endianness. */
1550
1551void
1552md_number_to_chars (buf, val, n)
1553 char *buf;
1554 valueT val;
1555 int n;
1556{
1557 if (target_big_endian)
1558 number_to_chars_bigendian (buf, val, n);
1559 else
1560 number_to_chars_littleendian (buf, val, n);
1561}
1562
bfb32b52 1563/* Round up a section size to the appropriate boundary. */
252b5132
RH
1564
1565valueT
1566md_section_align (segment, size)
1567 segT segment;
1568 valueT size;
1569{
1570 int align = bfd_get_section_alignment (stdoutput, segment);
1571
1572 return ((size + (1 << align) - 1) & (-1 << align));
1573}
1574
1575/* We don't have any form of relaxing. */
1576
1577int
1578md_estimate_size_before_relax (fragp, seg)
4a314ec8
NC
1579 fragS *fragp ATTRIBUTE_UNUSED;
1580 asection *seg ATTRIBUTE_UNUSED;
252b5132 1581{
0d2bcfaf
NC
1582 as_fatal (_("md_estimate_size_before_relax\n"));
1583 return 1;
252b5132
RH
1584}
1585
1586/* Convert a machine dependent frag. We never generate these. */
1587
1588void
1589md_convert_frag (abfd, sec, fragp)
4a314ec8
NC
1590 bfd *abfd ATTRIBUTE_UNUSED;
1591 asection *sec ATTRIBUTE_UNUSED;
1592 fragS *fragp ATTRIBUTE_UNUSED;
252b5132 1593{
0d2bcfaf
NC
1594 as_fatal (_("md_convert_frag\n"));
1595}
1596
1597void
19203624 1598arc_code_symbol (expressionP)
0d2bcfaf
NC
1599 expressionS *expressionP;
1600{
d3ecfc59 1601 if (expressionP->X_op == O_symbol && expressionP->X_add_number == 0)
0d2bcfaf 1602 {
1e07b820
KH
1603 expressionS two;
1604 expressionP->X_op = O_right_shift;
bcee8eb8 1605 expressionP->X_add_symbol->sy_value.X_op = O_constant;
1e07b820
KH
1606 two.X_op = O_constant;
1607 two.X_add_symbol = two.X_op_symbol = NULL;
1608 two.X_add_number = 2;
1609 expressionP->X_op_symbol = make_expr_symbol (&two);
0d2bcfaf 1610 }
bcee8eb8 1611 /* Allow %st(sym1-sym2) */
19203624
KH
1612 else if (expressionP->X_op == O_subtract
1613 && expressionP->X_add_symbol != NULL
1614 && expressionP->X_op_symbol != NULL
1615 && expressionP->X_add_number == 0)
0d2bcfaf 1616 {
1e07b820
KH
1617 expressionS two;
1618 expressionP->X_add_symbol = make_expr_symbol (expressionP);
1619 expressionP->X_op = O_right_shift;
1620 two.X_op = O_constant;
1621 two.X_add_symbol = two.X_op_symbol = NULL;
1622 two.X_add_number = 2;
1623 expressionP->X_op_symbol = make_expr_symbol (&two);
0d2bcfaf
NC
1624 }
1625 else
1626 {
1e07b820
KH
1627 as_bad ("expression too complex code symbol");
1628 return;
0d2bcfaf 1629 }
252b5132
RH
1630}
1631
1632/* Parse an operand that is machine-specific.
1633
1634 The ARC has a special %-op to adjust addresses so they're usable in
1635 branches. The "st" is short for the STatus register.
1636 ??? Later expand this to take a flags value too.
1637
1638 ??? We can't create new expression types so we map the %-op's onto the
1639 existing syntax. This means that the user could use the chosen syntax
bfb32b52 1640 to achieve the same effect. */
252b5132 1641
bfb32b52 1642void
252b5132
RH
1643md_operand (expressionP)
1644 expressionS *expressionP;
1645{
1646 char *p = input_line_pointer;
1647
0d2bcfaf 1648 if (*p == '%')
19203624 1649 if (strncmp (p, "%st(", 4) == 0)
0d2bcfaf 1650 {
1e07b820
KH
1651 input_line_pointer += 4;
1652 expression (expressionP);
1653 if (*input_line_pointer != ')')
1654 {
1655 as_bad ("missing ')' in %%-op");
1656 return;
1657 }
1658 ++input_line_pointer;
19203624 1659 arc_code_symbol (expressionP);
0d2bcfaf 1660 }
1e07b820 1661 else
bcee8eb8
AM
1662 {
1663 /* It could be a register. */
19203624 1664 int i, l;
1e07b820
KH
1665 struct arc_ext_operand_value *ext_oper = arc_ext_operands;
1666 p++;
0d2bcfaf 1667
1e07b820
KH
1668 while (ext_oper)
1669 {
19203624 1670 l = strlen (ext_oper->operand.name);
3882b010 1671 if (!strncmp (p, ext_oper->operand.name, l) && !ISALNUM (*(p + l)))
1e07b820
KH
1672 {
1673 input_line_pointer += l + 1;
1674 expressionP->X_op = O_register;
1675 expressionP->X_add_number = (int) &ext_oper->operand;
1676 return;
1677 }
1678 ext_oper = ext_oper->next;
1679 }
1680 for (i = 0; i < arc_reg_names_count; i++)
1681 {
19203624 1682 l = strlen (arc_reg_names[i].name);
3882b010 1683 if (!strncmp (p, arc_reg_names[i].name, l) && !ISALNUM (*(p + l)))
1e07b820
KH
1684 {
1685 input_line_pointer += l + 1;
1686 expressionP->X_op = O_register;
19203624 1687 expressionP->X_add_number = (int) &arc_reg_names[i];
1e07b820
KH
1688 break;
1689 }
1690 }
0d2bcfaf 1691 }
252b5132
RH
1692}
1693
1694/* We have no need to default values of symbols.
1695 We could catch register names here, but that is handled by inserting
1696 them all in the symbol table to begin with. */
1697
1698symbolS *
1699md_undefined_symbol (name)
4a314ec8 1700 char *name ATTRIBUTE_UNUSED;
252b5132
RH
1701{
1702 return 0;
1703}
1704\f
1705/* Functions concerning expressions. */
1706
1707/* Parse a .byte, .word, etc. expression.
1708
1709 Values for the status register are specified with %st(label).
1710 `label' will be right shifted by 2. */
1711
1712void
1713arc_parse_cons_expression (exp, nbytes)
19203624
KH
1714 expressionS *exp;
1715 unsigned int nbytes ATTRIBUTE_UNUSED;
252b5132 1716{
0d2bcfaf
NC
1717 char *p = input_line_pointer;
1718 int code_symbol_fix = 0;
1719
19203624
KH
1720 for (; ! is_end_of_line[(unsigned char) *p]; p++)
1721 if (*p == '@' && !strncmp (p, "@h30", 4))
0d2bcfaf 1722 {
1e07b820 1723 code_symbol_fix = 1;
19203624 1724 strcpy (p, "; ");
0d2bcfaf 1725 }
1e07b820
KH
1726 expr (0, exp);
1727 if (code_symbol_fix)
1728 {
19203624 1729 arc_code_symbol (exp);
1e07b820
KH
1730 input_line_pointer = p;
1731 }
252b5132
RH
1732}
1733
1734/* Record a fixup for a cons expression. */
1735
1736void
1737arc_cons_fix_new (frag, where, nbytes, exp)
1738 fragS *frag;
1739 int where;
1740 int nbytes;
1741 expressionS *exp;
1742{
1743 if (nbytes == 4)
1744 {
1745 int reloc_type;
1746 expressionS exptmp;
1747
1748 /* This may be a special ARC reloc (eg: %st()). */
1749 reloc_type = get_arc_exp_reloc_type (1, BFD_RELOC_32, exp, &exptmp);
1750 fix_new_exp (frag, where, nbytes, &exptmp, 0, reloc_type);
1751 }
1752 else
1753 {
1754 fix_new_exp (frag, where, nbytes, exp, 0,
1755 nbytes == 2 ? BFD_RELOC_16
1756 : nbytes == 8 ? BFD_RELOC_64
1757 : BFD_RELOC_32);
1758 }
1759}
1760\f
1761/* Functions concerning relocs. */
1762
1763/* The location from which a PC relative jump should be calculated,
1764 given a PC relative reloc. */
1765
bfb32b52 1766long
252b5132
RH
1767md_pcrel_from (fixP)
1768 fixS *fixP;
1769{
252b5132
RH
1770 /* Return the address of the delay slot. */
1771 return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
1772}
1773
1774/* Compute the reloc type of an expression.
1775 The possibly modified expression is stored in EXPNEW.
1776
1777 This is used to convert the expressions generated by the %-op's into
1778 the appropriate operand type. It is called for both data in instructions
1779 (operands) and data outside instructions (variables, debugging info, etc.).
1780
1781 Currently supported %-ops:
1782
1783 %st(symbol): represented as "symbol >> 2"
1784 "st" is short for STatus as in the status register (pc)
1785
1786 DEFAULT_TYPE is the type to use if no special processing is required.
1787
1788 DATA_P is non-zero for data or limm values, zero for insn operands.
1789 Remember that the opcode "insertion fns" cannot be used on data, they're
1790 only for inserting operands into insns. They also can't be used for limm
1791 values as the insertion routines don't handle limm values. When called for
1792 insns we return fudged reloc types (real_value - BFD_RELOC_UNUSED). When
1793 called for data or limm values we use real reloc types. */
1794
1795static int
1796get_arc_exp_reloc_type (data_p, default_type, exp, expnew)
1797 int data_p;
1798 int default_type;
1799 expressionS *exp;
1800 expressionS *expnew;
1801{
1802 /* If the expression is "symbol >> 2" we must change it to just "symbol",
2d2255b5 1803 as fix_new_exp can't handle it. Similarly for (symbol - symbol) >> 2.
252b5132
RH
1804 That's ok though. What's really going on here is that we're using
1805 ">> 2" as a special syntax for specifying BFD_RELOC_ARC_B26. */
1806
1807 if (exp->X_op == O_right_shift
1808 && exp->X_op_symbol != NULL
0d2bcfaf
NC
1809 && exp->X_op_symbol->sy_value.X_op == O_constant
1810 && exp->X_op_symbol->sy_value.X_add_number == 2
252b5132
RH
1811 && exp->X_add_number == 0)
1812 {
1813 if (exp->X_add_symbol != NULL
0d2bcfaf
NC
1814 && (exp->X_add_symbol->sy_value.X_op == O_constant
1815 || exp->X_add_symbol->sy_value.X_op == O_symbol))
252b5132
RH
1816 {
1817 *expnew = *exp;
1818 expnew->X_op = O_symbol;
1819 expnew->X_op_symbol = NULL;
1820 return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
1821 }
1822 else if (exp->X_add_symbol != NULL
0d2bcfaf 1823 && exp->X_add_symbol->sy_value.X_op == O_subtract)
252b5132 1824 {
0d2bcfaf 1825 *expnew = exp->X_add_symbol->sy_value;
252b5132
RH
1826 return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
1827 }
1828 }
1829
1830 *expnew = *exp;
1831 return default_type;
1832}
1833
1834/* Apply a fixup to the object code. This is called for all the
1835 fixups we generated by the call to fix_new_exp, above. In the call
1836 above we used a reloc code which was the largest legal reloc code
1837 plus the operand index. Here we undo that to recover the operand
1838 index. At this point all symbol values should be fully resolved,
1839 and we attempt to completely resolve the reloc. If we can not do
1840 that, we determine the correct reloc code and put it back in the fixup. */
1841
94f592af
NC
1842void
1843md_apply_fix3 (fixP, valP, seg)
252b5132 1844 fixS *fixP;
94f592af 1845 valueT * valP;
252b5132
RH
1846 segT seg;
1847{
94f592af 1848 valueT value = * valP;
252b5132 1849
252b5132 1850 if (fixP->fx_addsy == (symbolS *) NULL)
94f592af
NC
1851 fixP->fx_done = 1;
1852
252b5132
RH
1853 else if (fixP->fx_pcrel)
1854 {
a161fe53
AM
1855 /* Hack around bfd_install_relocation brain damage. */
1856 if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
252b5132
RH
1857 value += md_pcrel_from (fixP);
1858 }
a161fe53
AM
1859
1860 /* We can't actually support subtracting a symbol. */
1861 if (fixP->fx_subsy != NULL)
1862 as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
252b5132
RH
1863
1864 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
1865 {
1866 int opindex;
1867 const struct arc_operand *operand;
1868 char *where;
1869 arc_insn insn;
1870
1871 opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
1872
1873 operand = &arc_operands[opindex];
1874
1875 /* Fetch the instruction, insert the fully resolved operand
1876 value, and stuff the instruction back again. */
1877 where = fixP->fx_frag->fr_literal + fixP->fx_where;
1878 if (target_big_endian)
1879 insn = bfd_getb32 ((unsigned char *) where);
1880 else
1881 insn = bfd_getl32 ((unsigned char *) where);
1882 insn = arc_insert_operand (insn, operand, -1, NULL, (offsetT) value,
1883 fixP->fx_file, fixP->fx_line);
1884 if (target_big_endian)
1885 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1886 else
1887 bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
1888
1889 if (fixP->fx_done)
1890 {
1891 /* Nothing else to do here. */
94f592af 1892 return;
252b5132
RH
1893 }
1894
1895 /* Determine a BFD reloc value based on the operand information.
1896 We are only prepared to turn a few of the operands into relocs.
1897 !!! Note that we can't handle limm values here. Since we're using
1898 implicit addends the addend must be inserted into the instruction,
1899 however, the opcode insertion routines currently do nothing with
1900 limm values. */
1901 if (operand->fmt == 'B')
1902 {
1903 assert ((operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0
1904 && operand->bits == 20
1905 && operand->shift == 7);
1906 fixP->fx_r_type = BFD_RELOC_ARC_B22_PCREL;
1907 }
0d2bcfaf 1908 else if (operand->fmt == 'J')
252b5132
RH
1909 {
1910 assert ((operand->flags & ARC_OPERAND_ABSOLUTE_BRANCH) != 0
1911 && operand->bits == 24
1912 && operand->shift == 32);
1913 fixP->fx_r_type = BFD_RELOC_ARC_B26;
1914 }
0d2bcfaf 1915 else if (operand->fmt == 'L')
252b5132
RH
1916 {
1917 assert ((operand->flags & ARC_OPERAND_LIMM) != 0
1918 && operand->bits == 32
1919 && operand->shift == 32);
1920 fixP->fx_r_type = BFD_RELOC_32;
1921 }
1922 else
1923 {
1924 as_bad_where (fixP->fx_file, fixP->fx_line,
0d2bcfaf 1925 "unresolved expression that must be resolved");
252b5132 1926 fixP->fx_done = 1;
94f592af 1927 return;
252b5132
RH
1928 }
1929 }
1930 else
1931 {
1932 switch (fixP->fx_r_type)
1933 {
1934 case BFD_RELOC_8:
1935 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1936 value, 1);
1937 break;
1938 case BFD_RELOC_16:
1939 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1940 value, 2);
1941 break;
1942 case BFD_RELOC_32:
1943 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1944 value, 4);
1945 break;
252b5132
RH
1946 case BFD_RELOC_ARC_B26:
1947 /* If !fixP->fx_done then `value' is an implicit addend.
1948 We must shift it right by 2 in this case as well because the
1949 linker performs the relocation and then adds this in (as opposed
1950 to adding this in and then shifting right by 2). */
1951 value >>= 2;
1952 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1953 value, 4);
1954 break;
1955 default:
1956 abort ();
1957 }
1958 }
252b5132
RH
1959}
1960
1961/* Translate internal representation of relocation info to BFD target
1962 format. */
1963
1964arelent *
1965tc_gen_reloc (section, fixP)
4a314ec8 1966 asection *section ATTRIBUTE_UNUSED;
252b5132
RH
1967 fixS *fixP;
1968{
1969 arelent *reloc;
1970
1971 reloc = (arelent *) xmalloc (sizeof (arelent));
65555e64 1972 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
252b5132 1973
65555e64 1974 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
252b5132
RH
1975 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1976 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
1977 if (reloc->howto == (reloc_howto_type *) NULL)
1978 {
1979 as_bad_where (fixP->fx_file, fixP->fx_line,
0d2bcfaf 1980 "internal error: can't export reloc type %d (`%s')",
19203624
KH
1981 fixP->fx_r_type,
1982 bfd_get_reloc_code_name (fixP->fx_r_type));
252b5132
RH
1983 return NULL;
1984 }
1985
1986 assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
1987
19203624 1988 /* Set addend to account for PC being advanced one insn before the
a161fe53 1989 target address is computed. */
252b5132 1990
19203624 1991 reloc->addend = (fixP->fx_pcrel ? -4 : 0);
252b5132 1992
0d2bcfaf 1993 return reloc;
252b5132 1994}
This page took 0.348571 seconds and 4 git commands to generate.