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