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