Locale changes from Bruno Haible <haible@clisp.cons.org>.
[deliverable/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>
0d2bcfaf 24#include "libiberty.h"
252b5132 25#include "as.h"
3882b010 26#include "safe-ctype.h"
252b5132
RH
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. */
3882b010 396 while (ISSPACE (*str))
252b5132
RH
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. */
3882b010 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
3882b010 739 while (ISSPACE (*str))
252b5132
RH
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 {
3882b010 916 *p = TOLOWER (*p);
1e07b820 917 p++;
0d2bcfaf
NC
918 }
919
bcee8eb8 920 /* just after name is now '\0' */
252b5132
RH
921 p = input_line_pointer;
922 *p = c;
923 SKIP_WHITESPACE ();
0d2bcfaf 924
252b5132
RH
925 if (*input_line_pointer != ',')
926 {
0d2bcfaf 927 as_bad ("expected comma after operand name");
252b5132 928 ignore_rest_of_line ();
19203624 929 free (name);
252b5132
RH
930 return;
931 }
0d2bcfaf 932
bcee8eb8 933 input_line_pointer++; /* skip ',' */
0d2bcfaf
NC
934 number = get_absolute_expression ();
935
19203624 936 if (number < 0)
0d2bcfaf 937 {
19203624
KH
938 as_bad ("negative operand number %d", number);
939 ignore_rest_of_line ();
940 free (name);
1e07b820 941 return;
0d2bcfaf
NC
942 }
943
944 if (opertype)
945 {
19203624 946 SKIP_WHITESPACE ();
0d2bcfaf
NC
947
948 if (*input_line_pointer != ',')
1e07b820
KH
949 {
950 as_bad ("expected comma after register-number");
951 ignore_rest_of_line ();
19203624 952 free (name);
1e07b820
KH
953 return;
954 }
bfb32b52 955
bcee8eb8 956 input_line_pointer++; /* skip ',' */
0d2bcfaf 957 mode = input_line_pointer;
bfb32b52 958
19203624 959 if (!strncmp (mode, "r|w", 3))
1e07b820
KH
960 {
961 imode = 0;
962 input_line_pointer += 3;
963 }
0d2bcfaf 964 else
1e07b820 965 {
19203624 966 if (!strncmp (mode, "r", 1))
1e07b820
KH
967 {
968 imode = ARC_REGISTER_READONLY;
969 input_line_pointer += 1;
970 }
971 else
972 {
19203624 973 if (strncmp (mode, "w", 1))
1e07b820
KH
974 {
975 as_bad ("invalid mode");
19203624
KH
976 ignore_rest_of_line ();
977 free (name);
1e07b820
KH
978 return;
979 }
980 else
981 {
982 imode = ARC_REGISTER_WRITEONLY;
983 input_line_pointer += 1;
984 }
985 }
986 }
19203624 987 SKIP_WHITESPACE ();
1e07b820
KH
988 if (1 == opertype)
989 {
990 if (*input_line_pointer != ',')
991 {
992 as_bad ("expected comma after register-mode");
993 ignore_rest_of_line ();
19203624 994 free (name);
1e07b820
KH
995 return;
996 }
997
bcee8eb8 998 input_line_pointer++; /* skip ',' */
1e07b820 999
19203624 1000 if (!strncmp (input_line_pointer, "cannot_shortcut", 15))
1e07b820 1001 {
19203624 1002 imode |= arc_get_noshortcut_flag ();
1e07b820
KH
1003 input_line_pointer += 15;
1004 }
1005 else
1006 {
19203624 1007 if (strncmp (input_line_pointer, "can_shortcut", 12))
1e07b820
KH
1008 {
1009 as_bad ("shortcut designator invalid");
19203624
KH
1010 ignore_rest_of_line ();
1011 free (name);
1e07b820
KH
1012 return;
1013 }
1014 else
1015 {
1016 input_line_pointer += 12;
1017 }
1018 }
1019 }
1020 }
0d2bcfaf
NC
1021
1022 if ((opertype == 1) && number > 60)
1e07b820 1023 {
19203624
KH
1024 as_bad ("core register value (%d) too large", number);
1025 ignore_rest_of_line ();
1026 free (name);
1e07b820
KH
1027 return;
1028 }
0d2bcfaf
NC
1029
1030 if ((opertype == 0) && number > 31)
1e07b820 1031 {
19203624
KH
1032 as_bad ("condition code value (%d) too large", number);
1033 ignore_rest_of_line ();
1034 free (name);
1e07b820
KH
1035 return;
1036 }
0d2bcfaf
NC
1037
1038 ext_oper = (struct arc_ext_operand_value *) \
19203624 1039 xmalloc (sizeof (struct arc_ext_operand_value));
0d2bcfaf 1040
19203624 1041 if (opertype)
0d2bcfaf 1042 {
19203624 1043 /* If the symbol already exists, point it at the new definition. */
0d2bcfaf 1044 if ((symbolP = symbol_find (name)))
1e07b820 1045 {
19203624
KH
1046 if (S_GET_SEGMENT (symbolP) == reg_section)
1047 S_SET_VALUE (symbolP, (int) &ext_oper->operand);
1e07b820
KH
1048 else
1049 {
19203624
KH
1050 as_bad ("attempt to override symbol: %s", name);
1051 ignore_rest_of_line ();
1052 free (name);
1053 free (ext_oper);
1e07b820
KH
1054 return;
1055 }
1056 }
0d2bcfaf 1057 else
1e07b820 1058 {
19203624 1059 /* If its not there, add it. */
1e07b820
KH
1060 symbol_table_insert (symbol_create (name, reg_section,
1061 (int) &ext_oper->operand, &zero_address_frag));
1062 }
0d2bcfaf
NC
1063 }
1064
1065 ext_oper->operand.name = name;
1066 ext_oper->operand.value = number;
19203624 1067 ext_oper->operand.type = arc_operand_type (opertype);
0d2bcfaf
NC
1068 ext_oper->operand.flags = imode;
1069
1070 ext_oper->next = arc_ext_operands;
1071 arc_ext_operands = ext_oper;
1072
19203624
KH
1073 /* OK, now that we know what this operand is, put a description in
1074 the arc extension section of the output file. */
0d2bcfaf
NC
1075
1076 old_sec = now_seg;
1077 old_subsec = now_subseg;
1078
19203624 1079 arc_set_ext_seg ();
0d2bcfaf
NC
1080
1081 switch (opertype)
1e07b820
KH
1082 {
1083 case 0:
19203624
KH
1084 p = frag_more (1);
1085 *p = 3 + strlen (name) + 1;
1086 p = frag_more (1);
1e07b820 1087 *p = EXT_COND_CODE;
19203624 1088 p = frag_more (1);
1e07b820 1089 *p = number;
19203624
KH
1090 p = frag_more (strlen (name) + 1);
1091 strcpy (p, name);
1e07b820
KH
1092 break;
1093 case 1:
19203624
KH
1094 p = frag_more (1);
1095 *p = 3 + strlen (name) + 1;
1096 p = frag_more (1);
1e07b820 1097 *p = EXT_CORE_REGISTER;
19203624 1098 p = frag_more (1);
1e07b820 1099 *p = number;
19203624
KH
1100 p = frag_more (strlen (name) + 1);
1101 strcpy (p, name);
1e07b820
KH
1102 break;
1103 case 2:
19203624
KH
1104 p = frag_more (1);
1105 *p = 6 + strlen (name) + 1;
1106 p = frag_more (1);
1e07b820 1107 *p = EXT_AUX_REGISTER;
19203624 1108 p = frag_more (1);
1e07b820 1109 *p = number >> 24 & 0xff;
19203624 1110 p = frag_more (1);
1e07b820 1111 *p = number >> 16 & 0xff;
19203624 1112 p = frag_more (1);
1e07b820 1113 *p = number >> 8 & 0xff;
19203624 1114 p = frag_more (1);
1e07b820 1115 *p = number & 0xff;
19203624
KH
1116 p = frag_more (strlen (name) + 1);
1117 strcpy (p, name);
1e07b820
KH
1118 break;
1119 default:
19203624
KH
1120 as_bad ("invalid opertype");
1121 ignore_rest_of_line ();
1122 free (name);
1e07b820
KH
1123 return;
1124 break;
1125 }
0d2bcfaf
NC
1126
1127 subseg_set (old_sec, old_subsec);
1128
19203624 1129 /* Enter all registers into the symbol table. */
0d2bcfaf 1130
19203624 1131 demand_empty_rest_of_line ();
0d2bcfaf
NC
1132}
1133
1134static void
1135arc_extinst (ignore)
19203624 1136 int ignore ATTRIBUTE_UNUSED;
0d2bcfaf
NC
1137{
1138 unsigned char syntax[129];
1139 char *name;
1140 char *p;
1141 char c;
1142 int suffixcode = -1;
19203624 1143 int opcode, subopcode;
0d2bcfaf
NC
1144 int i;
1145 int class = 0;
1146 int name_len;
1147 struct arc_opcode *ext_op;
1148
1149 segT old_sec;
1150 int old_subsec;
1151
1152 name = input_line_pointer;
1153 c = get_symbol_end ();
19203624 1154 name = xstrdup (name);
0d2bcfaf
NC
1155 if (NULL == name)
1156 {
19203624 1157 ignore_rest_of_line ();
1e07b820 1158 return;
0d2bcfaf 1159 }
19203624
KH
1160 strcpy (syntax, name);
1161 name_len = strlen (name);
0d2bcfaf 1162
bcee8eb8 1163 /* just after name is now '\0' */
0d2bcfaf
NC
1164 p = input_line_pointer;
1165 *p = c;
1166
1167 SKIP_WHITESPACE ();
1168
1169 if (*input_line_pointer != ',')
252b5132 1170 {
0d2bcfaf 1171 as_bad ("expected comma after operand name");
252b5132
RH
1172 ignore_rest_of_line ();
1173 return;
1174 }
0d2bcfaf 1175
bcee8eb8 1176 input_line_pointer++; /* skip ',' */
0d2bcfaf
NC
1177 opcode = get_absolute_expression ();
1178
1179 SKIP_WHITESPACE ();
1180
1181 if (*input_line_pointer != ',')
252b5132 1182 {
0d2bcfaf 1183 as_bad ("expected comma after opcode");
252b5132
RH
1184 ignore_rest_of_line ();
1185 return;
1186 }
0d2bcfaf 1187
bcee8eb8 1188 input_line_pointer++; /* skip ',' */
0d2bcfaf
NC
1189 subopcode = get_absolute_expression ();
1190
19203624 1191 if (subopcode < 0)
252b5132 1192 {
19203624
KH
1193 as_bad ("negative subopcode %d", subopcode);
1194 ignore_rest_of_line ();
1e07b820 1195 return;
252b5132 1196 }
0d2bcfaf 1197
19203624 1198 if (subopcode)
0d2bcfaf 1199 {
19203624 1200 if (3 != opcode)
1e07b820
KH
1201 {
1202 as_bad ("subcode value found when opcode not equal 0x03");
19203624 1203 ignore_rest_of_line ();
1e07b820
KH
1204 return;
1205 }
1206 else
1207 {
1208 if (subopcode < 0x09 || subopcode == 0x3f)
1209 {
1210 as_bad ("invalid subopcode %d", subopcode);
19203624 1211 ignore_rest_of_line ();
1e07b820
KH
1212 return;
1213 }
1214 }
0d2bcfaf
NC
1215 }
1216
1217 SKIP_WHITESPACE ();
1218
252b5132
RH
1219 if (*input_line_pointer != ',')
1220 {
0d2bcfaf 1221 as_bad ("expected comma after subopcode");
252b5132
RH
1222 ignore_rest_of_line ();
1223 return;
1224 }
0d2bcfaf 1225
bcee8eb8 1226 input_line_pointer++; /* skip ',' */
0d2bcfaf 1227
19203624 1228 for (i = 0; i < (int) MAXSUFFIXCLASS; i++)
0d2bcfaf 1229 {
19203624 1230 if (!strncmp (suffixclass[i].name,input_line_pointer, suffixclass[i].len))
1e07b820
KH
1231 {
1232 suffixcode = i;
1233 input_line_pointer += suffixclass[i].len;
1234 break;
1235 }
0d2bcfaf
NC
1236 }
1237
19203624 1238 if (-1 == suffixcode)
0d2bcfaf
NC
1239 {
1240 as_bad ("invalid suffix class");
1241 ignore_rest_of_line ();
1242 return;
1243 }
1244
252b5132 1245 SKIP_WHITESPACE ();
0d2bcfaf
NC
1246
1247 if (*input_line_pointer != ',')
252b5132 1248 {
0d2bcfaf
NC
1249 as_bad ("expected comma after suffix class");
1250 ignore_rest_of_line ();
1251 return;
252b5132 1252 }
0d2bcfaf 1253
bcee8eb8 1254 input_line_pointer++; /* skip ',' */
0d2bcfaf 1255
19203624 1256 for (i = 0; i < (int) MAXSYNTAXCLASS; i++)
252b5132 1257 {
19203624 1258 if (!strncmp (syntaxclass[i].name,input_line_pointer, syntaxclass[i].len))
1e07b820
KH
1259 {
1260 class = syntaxclass[i].class;
1261 input_line_pointer += syntaxclass[i].len;
1262 break;
1263 }
252b5132 1264 }
252b5132 1265
19203624 1266 if (0 == (SYNTAX_VALID & class))
0d2bcfaf
NC
1267 {
1268 as_bad ("invalid syntax class");
1269 ignore_rest_of_line ();
1270 return;
1271 }
1272
19203624 1273 if ((0x3 == opcode) & (class & SYNTAX_3OP))
0d2bcfaf
NC
1274 {
1275 as_bad ("opcode 0x3 and SYNTAX_3OP invalid");
1276 ignore_rest_of_line ();
1277 return;
1278 }
1279
1280 switch (suffixcode)
1e07b820
KH
1281 {
1282 case 0:
19203624 1283 strcat (syntax, "%.q%.f ");
1e07b820
KH
1284 break;
1285 case 1:
19203624 1286 strcat (syntax, "%.f ");
1e07b820
KH
1287 break;
1288 case 2:
19203624 1289 strcat (syntax, "%.q ");
1e07b820
KH
1290 break;
1291 case 3:
19203624 1292 strcat (syntax, " ");
1e07b820
KH
1293 break;
1294 default:
19203624
KH
1295 as_bad ("unknown suffix class");
1296 ignore_rest_of_line ();
1e07b820
KH
1297 return;
1298 break;
1299 };
0d2bcfaf 1300
19203624
KH
1301 strcat (syntax, ((opcode == 0x3) ? "%a,%b" : ((class & SYNTAX_3OP) ? "%a,%b,%c" : "%b,%c")));
1302 if (suffixcode < 2)
1303 strcat (syntax, "%F");
1304 strcat (syntax, "%S%L");
0d2bcfaf 1305
19203624
KH
1306 ext_op = (struct arc_opcode *) xmalloc (sizeof (struct arc_opcode));
1307 if (NULL == ext_op)
0d2bcfaf 1308 {
1e07b820
KH
1309 ignore_rest_of_line ();
1310 return;
0d2bcfaf
NC
1311 }
1312
19203624 1313 ext_op->syntax = xstrdup (syntax);
0d2bcfaf
NC
1314 if (NULL == ext_op->syntax)
1315 {
1e07b820
KH
1316 ignore_rest_of_line ();
1317 return;
0d2bcfaf
NC
1318 }
1319
19203624
KH
1320 ext_op->mask = I (-1) | ((0x3 == opcode) ? C (-1) : 0);
1321 ext_op->value = I (opcode) | ((0x3 == opcode) ? C (subopcode) : 0);
0d2bcfaf
NC
1322 ext_op->flags = class;
1323 ext_op->next_asm = arc_ext_opcodes;
1324 ext_op->next_dis = arc_ext_opcodes;
1325 arc_ext_opcodes = ext_op;
1326
19203624
KH
1327 /* OK, now that we know what this inst is, put a description in the
1328 arc extension section of the output file. */
0d2bcfaf
NC
1329
1330 old_sec = now_seg;
1331 old_subsec = now_subseg;
1332
19203624 1333 arc_set_ext_seg ();
0d2bcfaf 1334
19203624
KH
1335 p = frag_more (1);
1336 *p = 5 + name_len + 1;
1337 p = frag_more (1);
0d2bcfaf 1338 *p = EXT_INSTRUCTION;
19203624 1339 p = frag_more (1);
0d2bcfaf 1340 *p = opcode;
19203624 1341 p = frag_more (1);
0d2bcfaf 1342 *p = subopcode;
19203624 1343 p = frag_more (1);
0d2bcfaf 1344 *p = (class & (OP1_MUST_BE_IMM | OP1_IMM_IMPLIED) ? IGNORE_FIRST_OPD : 0);
19203624
KH
1345 p = frag_more (name_len);
1346 strncpy (p, syntax, name_len);
1347 p = frag_more (1);
0d2bcfaf
NC
1348 *p = '\0';
1349
1350 subseg_set (old_sec, old_subsec);
1351
19203624 1352 demand_empty_rest_of_line ();
252b5132
RH
1353}
1354
0d2bcfaf 1355int
19203624 1356arc_set_ext_seg ()
0d2bcfaf
NC
1357{
1358 if (!arcext_section)
1359 {
1360 arcext_section = subseg_new (".arcextmap", 0);
1361 bfd_set_section_flags (stdoutput, arcext_section,
19203624 1362 SEC_READONLY | SEC_HAS_CONTENTS);
0d2bcfaf
NC
1363 }
1364 else
1365 subseg_set (arcext_section, 0);
1366 return 1;
1367}
252b5132
RH
1368
1369static void
0d2bcfaf
NC
1370arc_common (localScope)
1371 int localScope;
252b5132 1372{
0d2bcfaf 1373 char *name;
252b5132 1374 char c;
0d2bcfaf 1375 char *p;
19203624 1376 int align, size;
0d2bcfaf 1377 symbolS *symbolP;
252b5132 1378
0d2bcfaf
NC
1379 name = input_line_pointer;
1380 c = get_symbol_end ();
bcee8eb8 1381 /* just after name is now '\0' */
0d2bcfaf
NC
1382 p = input_line_pointer;
1383 *p = c;
1384 SKIP_WHITESPACE ();
1385
1386 if (*input_line_pointer != ',')
252b5132 1387 {
0d2bcfaf 1388 as_bad ("expected comma after symbol name");
252b5132
RH
1389 ignore_rest_of_line ();
1390 return;
1391 }
1392
bcee8eb8 1393 input_line_pointer++; /* skip ',' */
0d2bcfaf 1394 size = get_absolute_expression ();
252b5132 1395
0d2bcfaf
NC
1396 if (size < 0)
1397 {
1398 as_bad ("negative symbol length");
1399 ignore_rest_of_line ();
1400 return;
1401 }
252b5132 1402
0d2bcfaf
NC
1403 *p = 0;
1404 symbolP = symbol_find_or_make (name);
1405 *p = c;
1406
1407 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
1408 {
1409 as_bad ("ignoring attempt to re-define symbol");
1410 ignore_rest_of_line ();
1411 return;
1412 }
19203624
KH
1413 if (((int) S_GET_VALUE (symbolP) != 0) \
1414 && ((int) S_GET_VALUE (symbolP) != size))
0d2bcfaf
NC
1415 {
1416 as_warn ("length of symbol \"%s\" already %ld, ignoring %d",
1417 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
1418 }
1419 assert (symbolP->sy_frag == &zero_address_frag);
1420
0d2bcfaf
NC
1421 /* Now parse the alignment field. This field is optional for
1422 local and global symbols. Default alignment is zero. */
1423 if (*input_line_pointer == ',')
1424 {
1425 input_line_pointer++;
1426 align = get_absolute_expression ();
1427 if (align < 0)
1428 {
1429 align = 0;
1430 as_warn ("assuming symbol alignment of zero");
1431 }
1432 }
252b5132 1433 else
0d2bcfaf
NC
1434 align = 0;
1435
1436 if (localScope != 0)
252b5132 1437 {
0d2bcfaf
NC
1438 segT old_sec;
1439 int old_subsec;
1440 char *pfrag;
1441
1442 old_sec = now_seg;
1443 old_subsec = now_subseg;
1444 record_alignment (bss_section, align);
bcee8eb8 1445 subseg_set (bss_section, 0); /* ??? subseg_set (bss_section, 1); ??? */
0d2bcfaf
NC
1446
1447 if (align)
19203624
KH
1448 /* Do alignment. */
1449 frag_align (align, 0, 0);
0d2bcfaf 1450
19203624 1451 /* Detach from old frag. */
0d2bcfaf
NC
1452 if (S_GET_SEGMENT (symbolP) == bss_section)
1453 symbolP->sy_frag->fr_symbol = NULL;
1454
1455 symbolP->sy_frag = frag_now;
1456 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
19203624 1457 (offsetT) size, (char *) 0);
0d2bcfaf
NC
1458 *pfrag = 0;
1459
1460 S_SET_SIZE (symbolP, size);
1461 S_SET_SEGMENT (symbolP, bss_section);
1462 S_CLEAR_EXTERNAL (symbolP);
1463 symbolP->local = 1;
1464 subseg_set (old_sec, old_subsec);
1465 }
1466 else
1467 {
1468 S_SET_VALUE (symbolP, (valueT) size);
1469 S_SET_ALIGN (symbolP, align);
1470 S_SET_EXTERNAL (symbolP);
1471 S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
252b5132 1472 }
252b5132 1473
0d2bcfaf
NC
1474 symbolP->bsym->flags |= BSF_OBJECT;
1475
1476 demand_empty_rest_of_line ();
1477 return;
252b5132 1478}
0d2bcfaf 1479\f
0d2bcfaf 1480/* Select the cpu we're assembling for. */
252b5132
RH
1481
1482static void
0d2bcfaf 1483arc_option (ignore)
19203624 1484 int ignore ATTRIBUTE_UNUSED;
252b5132 1485{
0d2bcfaf 1486 int mach;
252b5132 1487 char c;
0d2bcfaf 1488 char *cpu;
252b5132 1489
0d2bcfaf 1490 cpu = input_line_pointer;
252b5132 1491 c = get_symbol_end ();
0d2bcfaf 1492 mach = arc_get_mach (cpu);
252b5132
RH
1493 *input_line_pointer = c;
1494
0d2bcfaf
NC
1495 /* If an instruction has already been seen, it's too late. */
1496 if (cpu_tables_init_p)
252b5132 1497 {
0d2bcfaf 1498 as_bad ("\".option\" directive must appear before any instructions");
252b5132
RH
1499 ignore_rest_of_line ();
1500 return;
1501 }
252b5132 1502
0d2bcfaf
NC
1503 if (mach == -1)
1504 goto bad_cpu;
1505
1506 if (mach_type_specified_p && mach != arc_mach_type)
252b5132 1507 {
0d2bcfaf 1508 as_bad ("\".option\" directive conflicts with initial definition");
252b5132
RH
1509 ignore_rest_of_line ();
1510 return;
1511 }
0d2bcfaf
NC
1512 else
1513 {
1514 /* The cpu may have been selected on the command line. */
1515 if (mach != arc_mach_type)
1516 as_warn ("\".option\" directive overrides command-line (default) value");
1517 arc_mach_type = mach;
1518 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
1519 as_fatal ("could not set architecture and machine");
1520 mach_type_specified_p = 1;
1521 }
252b5132 1522 demand_empty_rest_of_line ();
0d2bcfaf
NC
1523 return;
1524
1525 bad_cpu:
1526 as_bad ("invalid identifier for \".option\"");
1527 ignore_rest_of_line ();
252b5132 1528}
252b5132 1529\f
19203624
KH
1530/* Turn a string in input_line_pointer into a floating point constant
1531 of type TYPE, and store the appropriate bytes in *LITP. The number
1532 of LITTLENUMS emitted is stored in *SIZEP. An error message is
1533 returned, or NULL on OK. */
252b5132 1534
0d2bcfaf 1535/* Equal to MAX_PRECISION in atof-ieee.c */
252b5132
RH
1536#define MAX_LITTLENUMS 6
1537
1538char *
1539md_atof (type, litP, sizeP)
19203624
KH
1540 char type;
1541 char *litP;
1542 int *sizeP;
252b5132
RH
1543{
1544 int prec;
1545 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1546 LITTLENUM_TYPE *wordP;
1547 char *t;
1548 char *atof_ieee ();
1549
1550 switch (type)
1551 {
1552 case 'f':
1553 case 'F':
1554 prec = 2;
1555 break;
1556
1557 case 'd':
1558 case 'D':
1559 prec = 4;
1560 break;
1561
1562 default:
1563 *sizeP = 0;
0d2bcfaf 1564 return "bad call to md_atof";
252b5132
RH
1565 }
1566
1567 t = atof_ieee (input_line_pointer, type, words);
1568 if (t)
1569 input_line_pointer = t;
1570 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1571 for (wordP = words; prec--;)
1572 {
1573 md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
1574 litP += sizeof (LITTLENUM_TYPE);
1575 }
1576
1577 return NULL;
1578}
1579
1580/* Write a value out to the object file, using the appropriate
1581 endianness. */
1582
1583void
1584md_number_to_chars (buf, val, n)
1585 char *buf;
1586 valueT val;
1587 int n;
1588{
1589 if (target_big_endian)
1590 number_to_chars_bigendian (buf, val, n);
1591 else
1592 number_to_chars_littleendian (buf, val, n);
1593}
1594
bfb32b52 1595/* Round up a section size to the appropriate boundary. */
252b5132
RH
1596
1597valueT
1598md_section_align (segment, size)
1599 segT segment;
1600 valueT size;
1601{
1602 int align = bfd_get_section_alignment (stdoutput, segment);
1603
1604 return ((size + (1 << align) - 1) & (-1 << align));
1605}
1606
1607/* We don't have any form of relaxing. */
1608
1609int
1610md_estimate_size_before_relax (fragp, seg)
4a314ec8
NC
1611 fragS *fragp ATTRIBUTE_UNUSED;
1612 asection *seg ATTRIBUTE_UNUSED;
252b5132 1613{
0d2bcfaf
NC
1614 as_fatal (_("md_estimate_size_before_relax\n"));
1615 return 1;
252b5132
RH
1616}
1617
1618/* Convert a machine dependent frag. We never generate these. */
1619
1620void
1621md_convert_frag (abfd, sec, fragp)
4a314ec8
NC
1622 bfd *abfd ATTRIBUTE_UNUSED;
1623 asection *sec ATTRIBUTE_UNUSED;
1624 fragS *fragp ATTRIBUTE_UNUSED;
252b5132 1625{
0d2bcfaf
NC
1626 as_fatal (_("md_convert_frag\n"));
1627}
1628
1629void
19203624 1630arc_code_symbol (expressionP)
0d2bcfaf
NC
1631 expressionS *expressionP;
1632{
1633 if (expressionP->X_op == O_symbol && expressionP->X_add_number == 0
1e07b820
KH
1634 /* I think this test is unnecessary but just as a sanity check... */
1635 && expressionP->X_op_symbol == NULL)
0d2bcfaf 1636 {
1e07b820
KH
1637 expressionS two;
1638 expressionP->X_op = O_right_shift;
bcee8eb8 1639 expressionP->X_add_symbol->sy_value.X_op = O_constant;
1e07b820
KH
1640 two.X_op = O_constant;
1641 two.X_add_symbol = two.X_op_symbol = NULL;
1642 two.X_add_number = 2;
1643 expressionP->X_op_symbol = make_expr_symbol (&two);
0d2bcfaf 1644 }
bcee8eb8 1645 /* Allow %st(sym1-sym2) */
19203624
KH
1646 else if (expressionP->X_op == O_subtract
1647 && expressionP->X_add_symbol != NULL
1648 && expressionP->X_op_symbol != NULL
1649 && expressionP->X_add_number == 0)
0d2bcfaf 1650 {
1e07b820
KH
1651 expressionS two;
1652 expressionP->X_add_symbol = make_expr_symbol (expressionP);
1653 expressionP->X_op = O_right_shift;
1654 two.X_op = O_constant;
1655 two.X_add_symbol = two.X_op_symbol = NULL;
1656 two.X_add_number = 2;
1657 expressionP->X_op_symbol = make_expr_symbol (&two);
0d2bcfaf
NC
1658 }
1659 else
1660 {
1e07b820
KH
1661 as_bad ("expression too complex code symbol");
1662 return;
0d2bcfaf 1663 }
252b5132
RH
1664}
1665
1666/* Parse an operand that is machine-specific.
1667
1668 The ARC has a special %-op to adjust addresses so they're usable in
1669 branches. The "st" is short for the STatus register.
1670 ??? Later expand this to take a flags value too.
1671
1672 ??? We can't create new expression types so we map the %-op's onto the
1673 existing syntax. This means that the user could use the chosen syntax
bfb32b52 1674 to achieve the same effect. */
252b5132 1675
bfb32b52 1676void
252b5132
RH
1677md_operand (expressionP)
1678 expressionS *expressionP;
1679{
1680 char *p = input_line_pointer;
1681
0d2bcfaf 1682 if (*p == '%')
19203624 1683 if (strncmp (p, "%st(", 4) == 0)
0d2bcfaf 1684 {
1e07b820
KH
1685 input_line_pointer += 4;
1686 expression (expressionP);
1687 if (*input_line_pointer != ')')
1688 {
1689 as_bad ("missing ')' in %%-op");
1690 return;
1691 }
1692 ++input_line_pointer;
19203624 1693 arc_code_symbol (expressionP);
0d2bcfaf 1694 }
1e07b820 1695 else
bcee8eb8
AM
1696 {
1697 /* It could be a register. */
19203624 1698 int i, l;
1e07b820
KH
1699 struct arc_ext_operand_value *ext_oper = arc_ext_operands;
1700 p++;
0d2bcfaf 1701
1e07b820
KH
1702 while (ext_oper)
1703 {
19203624 1704 l = strlen (ext_oper->operand.name);
3882b010 1705 if (!strncmp (p, ext_oper->operand.name, l) && !ISALNUM (*(p + l)))
1e07b820
KH
1706 {
1707 input_line_pointer += l + 1;
1708 expressionP->X_op = O_register;
1709 expressionP->X_add_number = (int) &ext_oper->operand;
1710 return;
1711 }
1712 ext_oper = ext_oper->next;
1713 }
1714 for (i = 0; i < arc_reg_names_count; i++)
1715 {
19203624 1716 l = strlen (arc_reg_names[i].name);
3882b010 1717 if (!strncmp (p, arc_reg_names[i].name, l) && !ISALNUM (*(p + l)))
1e07b820
KH
1718 {
1719 input_line_pointer += l + 1;
1720 expressionP->X_op = O_register;
19203624 1721 expressionP->X_add_number = (int) &arc_reg_names[i];
1e07b820
KH
1722 break;
1723 }
1724 }
0d2bcfaf 1725 }
252b5132
RH
1726}
1727
1728/* We have no need to default values of symbols.
1729 We could catch register names here, but that is handled by inserting
1730 them all in the symbol table to begin with. */
1731
1732symbolS *
1733md_undefined_symbol (name)
4a314ec8 1734 char *name ATTRIBUTE_UNUSED;
252b5132
RH
1735{
1736 return 0;
1737}
1738\f
1739/* Functions concerning expressions. */
1740
1741/* Parse a .byte, .word, etc. expression.
1742
1743 Values for the status register are specified with %st(label).
1744 `label' will be right shifted by 2. */
1745
1746void
1747arc_parse_cons_expression (exp, nbytes)
19203624
KH
1748 expressionS *exp;
1749 unsigned int nbytes ATTRIBUTE_UNUSED;
252b5132 1750{
0d2bcfaf
NC
1751 char *p = input_line_pointer;
1752 int code_symbol_fix = 0;
1753
19203624
KH
1754 for (; ! is_end_of_line[(unsigned char) *p]; p++)
1755 if (*p == '@' && !strncmp (p, "@h30", 4))
0d2bcfaf 1756 {
1e07b820 1757 code_symbol_fix = 1;
19203624 1758 strcpy (p, "; ");
0d2bcfaf 1759 }
1e07b820
KH
1760 expr (0, exp);
1761 if (code_symbol_fix)
1762 {
19203624 1763 arc_code_symbol (exp);
1e07b820
KH
1764 input_line_pointer = p;
1765 }
252b5132
RH
1766}
1767
1768/* Record a fixup for a cons expression. */
1769
1770void
1771arc_cons_fix_new (frag, where, nbytes, exp)
1772 fragS *frag;
1773 int where;
1774 int nbytes;
1775 expressionS *exp;
1776{
1777 if (nbytes == 4)
1778 {
1779 int reloc_type;
1780 expressionS exptmp;
1781
1782 /* This may be a special ARC reloc (eg: %st()). */
1783 reloc_type = get_arc_exp_reloc_type (1, BFD_RELOC_32, exp, &exptmp);
1784 fix_new_exp (frag, where, nbytes, &exptmp, 0, reloc_type);
1785 }
1786 else
1787 {
1788 fix_new_exp (frag, where, nbytes, exp, 0,
1789 nbytes == 2 ? BFD_RELOC_16
1790 : nbytes == 8 ? BFD_RELOC_64
1791 : BFD_RELOC_32);
1792 }
1793}
1794\f
1795/* Functions concerning relocs. */
1796
1797/* The location from which a PC relative jump should be calculated,
1798 given a PC relative reloc. */
1799
bfb32b52 1800long
252b5132
RH
1801md_pcrel_from (fixP)
1802 fixS *fixP;
1803{
1804 if (fixP->fx_addsy != (symbolS *) NULL
1805 && ! S_IS_DEFINED (fixP->fx_addsy))
1806 {
1807 /* The symbol is undefined. Let the linker figure it out. */
1808 return 0;
1809 }
1810
1811 /* Return the address of the delay slot. */
1812 return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
1813}
1814
1815/* Compute the reloc type of an expression.
1816 The possibly modified expression is stored in EXPNEW.
1817
1818 This is used to convert the expressions generated by the %-op's into
1819 the appropriate operand type. It is called for both data in instructions
1820 (operands) and data outside instructions (variables, debugging info, etc.).
1821
1822 Currently supported %-ops:
1823
1824 %st(symbol): represented as "symbol >> 2"
1825 "st" is short for STatus as in the status register (pc)
1826
1827 DEFAULT_TYPE is the type to use if no special processing is required.
1828
1829 DATA_P is non-zero for data or limm values, zero for insn operands.
1830 Remember that the opcode "insertion fns" cannot be used on data, they're
1831 only for inserting operands into insns. They also can't be used for limm
1832 values as the insertion routines don't handle limm values. When called for
1833 insns we return fudged reloc types (real_value - BFD_RELOC_UNUSED). When
1834 called for data or limm values we use real reloc types. */
1835
1836static int
1837get_arc_exp_reloc_type (data_p, default_type, exp, expnew)
1838 int data_p;
1839 int default_type;
1840 expressionS *exp;
1841 expressionS *expnew;
1842{
1843 /* If the expression is "symbol >> 2" we must change it to just "symbol",
1844 as fix_new_exp can't handle it. Similarily for (symbol - symbol) >> 2.
1845 That's ok though. What's really going on here is that we're using
1846 ">> 2" as a special syntax for specifying BFD_RELOC_ARC_B26. */
1847
1848 if (exp->X_op == O_right_shift
1849 && exp->X_op_symbol != NULL
0d2bcfaf
NC
1850 && exp->X_op_symbol->sy_value.X_op == O_constant
1851 && exp->X_op_symbol->sy_value.X_add_number == 2
252b5132
RH
1852 && exp->X_add_number == 0)
1853 {
1854 if (exp->X_add_symbol != NULL
0d2bcfaf
NC
1855 && (exp->X_add_symbol->sy_value.X_op == O_constant
1856 || exp->X_add_symbol->sy_value.X_op == O_symbol))
252b5132
RH
1857 {
1858 *expnew = *exp;
1859 expnew->X_op = O_symbol;
1860 expnew->X_op_symbol = NULL;
1861 return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
1862 }
1863 else if (exp->X_add_symbol != NULL
0d2bcfaf 1864 && exp->X_add_symbol->sy_value.X_op == O_subtract)
252b5132 1865 {
0d2bcfaf 1866 *expnew = exp->X_add_symbol->sy_value;
252b5132
RH
1867 return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
1868 }
1869 }
1870
1871 *expnew = *exp;
1872 return default_type;
1873}
1874
1875/* Apply a fixup to the object code. This is called for all the
1876 fixups we generated by the call to fix_new_exp, above. In the call
1877 above we used a reloc code which was the largest legal reloc code
1878 plus the operand index. Here we undo that to recover the operand
1879 index. At this point all symbol values should be fully resolved,
1880 and we attempt to completely resolve the reloc. If we can not do
1881 that, we determine the correct reloc code and put it back in the fixup. */
1882
1883int
1884md_apply_fix3 (fixP, valueP, seg)
1885 fixS *fixP;
1886 valueT *valueP;
1887 segT seg;
1888{
19203624
KH
1889#if 0
1890 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1891#endif
252b5132
RH
1892 valueT value;
1893
1894 /* FIXME FIXME FIXME: The value we are passed in *valueP includes
1895 the symbol values. Since we are using BFD_ASSEMBLER, if we are
1896 doing this relocation the code in write.c is going to call
1897 bfd_perform_relocation, which is also going to use the symbol
1898 value. That means that if the reloc is fully resolved we want to
1899 use *valueP since bfd_perform_relocation is not being used.
1900 However, if the reloc is not fully resolved we do not want to use
1901 *valueP, and must use fx_offset instead. However, if the reloc
1902 is PC relative, we do want to use *valueP since it includes the
1903 result of md_pcrel_from. This is confusing. */
1904
1905 if (fixP->fx_addsy == (symbolS *) NULL)
1906 {
1907 value = *valueP;
1908 fixP->fx_done = 1;
1909 }
1910 else if (fixP->fx_pcrel)
1911 {
1912 value = *valueP;
1913 /* ELF relocations are against symbols.
1914 If this symbol is in a different section then we need to leave it for
1915 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
1916 so we have to undo it's effects here. */
1917 if (S_IS_DEFINED (fixP->fx_addsy)
1918 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
1919 value += md_pcrel_from (fixP);
1920 }
1921 else
1922 {
1923 value = fixP->fx_offset;
1924 if (fixP->fx_subsy != (symbolS *) NULL)
1925 {
1926 if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)
1927 value -= S_GET_VALUE (fixP->fx_subsy);
1928 else
1929 {
1930 /* We can't actually support subtracting a symbol. */
1931 as_bad_where (fixP->fx_file, fixP->fx_line,
0d2bcfaf 1932 "expression too complex");
252b5132
RH
1933 }
1934 }
1935 }
1936
1937 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
1938 {
1939 int opindex;
1940 const struct arc_operand *operand;
1941 char *where;
1942 arc_insn insn;
1943
1944 opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
1945
1946 operand = &arc_operands[opindex];
1947
1948 /* Fetch the instruction, insert the fully resolved operand
1949 value, and stuff the instruction back again. */
1950 where = fixP->fx_frag->fr_literal + fixP->fx_where;
1951 if (target_big_endian)
1952 insn = bfd_getb32 ((unsigned char *) where);
1953 else
1954 insn = bfd_getl32 ((unsigned char *) where);
1955 insn = arc_insert_operand (insn, operand, -1, NULL, (offsetT) value,
1956 fixP->fx_file, fixP->fx_line);
1957 if (target_big_endian)
1958 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1959 else
1960 bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
1961
1962 if (fixP->fx_done)
1963 {
1964 /* Nothing else to do here. */
1965 return 1;
1966 }
1967
1968 /* Determine a BFD reloc value based on the operand information.
1969 We are only prepared to turn a few of the operands into relocs.
1970 !!! Note that we can't handle limm values here. Since we're using
1971 implicit addends the addend must be inserted into the instruction,
1972 however, the opcode insertion routines currently do nothing with
1973 limm values. */
1974 if (operand->fmt == 'B')
1975 {
1976 assert ((operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0
1977 && operand->bits == 20
1978 && operand->shift == 7);
1979 fixP->fx_r_type = BFD_RELOC_ARC_B22_PCREL;
1980 }
0d2bcfaf 1981 else if (operand->fmt == 'J')
252b5132
RH
1982 {
1983 assert ((operand->flags & ARC_OPERAND_ABSOLUTE_BRANCH) != 0
1984 && operand->bits == 24
1985 && operand->shift == 32);
1986 fixP->fx_r_type = BFD_RELOC_ARC_B26;
1987 }
0d2bcfaf 1988 else if (operand->fmt == 'L')
252b5132
RH
1989 {
1990 assert ((operand->flags & ARC_OPERAND_LIMM) != 0
1991 && operand->bits == 32
1992 && operand->shift == 32);
1993 fixP->fx_r_type = BFD_RELOC_32;
1994 }
1995 else
1996 {
1997 as_bad_where (fixP->fx_file, fixP->fx_line,
0d2bcfaf 1998 "unresolved expression that must be resolved");
252b5132
RH
1999 fixP->fx_done = 1;
2000 return 1;
2001 }
2002 }
2003 else
2004 {
2005 switch (fixP->fx_r_type)
2006 {
2007 case BFD_RELOC_8:
2008 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
2009 value, 1);
2010 break;
2011 case BFD_RELOC_16:
2012 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
2013 value, 2);
2014 break;
2015 case BFD_RELOC_32:
2016 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
2017 value, 4);
2018 break;
2019#if 0
2020 case BFD_RELOC_64:
2021 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
2022 value, 8);
2023 break;
2024#endif
2025 case BFD_RELOC_ARC_B26:
2026 /* If !fixP->fx_done then `value' is an implicit addend.
2027 We must shift it right by 2 in this case as well because the
2028 linker performs the relocation and then adds this in (as opposed
2029 to adding this in and then shifting right by 2). */
2030 value >>= 2;
2031 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
2032 value, 4);
2033 break;
2034 default:
2035 abort ();
2036 }
2037 }
2038
2039 fixP->fx_addnumber = value;
2040
2041 return 1;
2042}
2043
2044/* Translate internal representation of relocation info to BFD target
2045 format. */
2046
2047arelent *
2048tc_gen_reloc (section, fixP)
4a314ec8 2049 asection *section ATTRIBUTE_UNUSED;
252b5132
RH
2050 fixS *fixP;
2051{
2052 arelent *reloc;
2053
2054 reloc = (arelent *) xmalloc (sizeof (arelent));
2055
0d2bcfaf 2056 reloc->sym_ptr_ptr = &fixP->fx_addsy->bsym;
252b5132
RH
2057 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
2058 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
2059 if (reloc->howto == (reloc_howto_type *) NULL)
2060 {
2061 as_bad_where (fixP->fx_file, fixP->fx_line,
0d2bcfaf 2062 "internal error: can't export reloc type %d (`%s')",
19203624
KH
2063 fixP->fx_r_type,
2064 bfd_get_reloc_code_name (fixP->fx_r_type));
252b5132
RH
2065 return NULL;
2066 }
2067
2068 assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
2069
19203624
KH
2070 /* Set addend to account for PC being advanced one insn before the
2071 target address is computed, drop fx_addnumber as it is handled
2072 elsewhere mlm */
252b5132 2073
19203624 2074 reloc->addend = (fixP->fx_pcrel ? -4 : 0);
252b5132 2075
0d2bcfaf 2076 return reloc;
252b5132 2077}
This page took 0.187213 seconds and 4 git commands to generate.