Fix 'the the' typo
[deliverable/binutils-gdb.git] / gas / config / tc-arc.c
CommitLineData
252b5132 1/* tc-arc.c -- Assembler for the ARC
9f1838ed 2 Copyright 1994, 1995, 1997, 1999, 2000, 2001, 2002
f7e42eb4 3 Free Software Foundation, Inc.
252b5132
RH
4 Contributed by Doug Evans (dje@cygnus.com).
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19203624
KH
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
252b5132
RH
22
23#include <stdio.h>
0d2bcfaf 24#include "libiberty.h"
252b5132 25#include "as.h"
a161fe53 26#include "struc-symbol.h"
3882b010 27#include "safe-ctype.h"
252b5132
RH
28#include "subsegs.h"
29#include "opcode/arc.h"
0d2bcfaf 30#include "../opcodes/arc-ext.h"
252b5132 31#include "elf/arc.h"
bcee8eb8 32#include "dwarf2dbg.h"
252b5132
RH
33
34extern int arc_get_mach PARAMS ((char *));
0d2bcfaf
NC
35extern int arc_operand_type PARAMS ((int));
36extern int arc_insn_not_jl PARAMS ((arc_insn));
37extern int arc_limm_fixup_adjust PARAMS ((arc_insn));
38extern int arc_get_noshortcut_flag PARAMS ((void));
39extern int arc_set_ext_seg PARAMS ((void));
19203624 40extern void arc_code_symbol PARAMS ((expressionS *));
252b5132
RH
41
42static arc_insn arc_insert_operand PARAMS ((arc_insn,
43 const struct arc_operand *, int,
44 const struct arc_operand_value *,
45 offsetT, char *, unsigned int));
46static void arc_common PARAMS ((int));
0d2bcfaf
NC
47static void arc_extinst PARAMS ((int));
48static void arc_extoper PARAMS ((int));
49static void arc_option PARAMS ((int));
89b57c9a 50static int get_arc_exp_reloc_type PARAMS ((int, int, expressionS *,
252b5132
RH
51 expressionS *));
52
89b57c9a
NC
53static void init_opcode_tables PARAMS ((int));
54
0d2bcfaf
NC
55const struct suffix_classes {
56 char *name;
57 int len;
58} suffixclass[] = {
59 { "SUFFIX_COND|SUFFIX_FLAG",23 },
60 { "SUFFIX_FLAG", 11 },
61 { "SUFFIX_COND", 11 },
62 { "SUFFIX_NONE", 11 }
63};
64
bfb32b52 65#define MAXSUFFIXCLASS (sizeof (suffixclass) / sizeof (struct suffix_classes))
0d2bcfaf
NC
66
67const struct syntax_classes {
68 char *name;
69 int len;
70 int class;
71} syntaxclass[] = {
72 { "SYNTAX_3OP|OP1_MUST_BE_IMM", 26, SYNTAX_3OP|OP1_MUST_BE_IMM|SYNTAX_VALID },
73 { "OP1_MUST_BE_IMM|SYNTAX_3OP", 26, OP1_MUST_BE_IMM|SYNTAX_3OP|SYNTAX_VALID },
74 { "SYNTAX_2OP|OP1_IMM_IMPLIED", 26, SYNTAX_2OP|OP1_IMM_IMPLIED|SYNTAX_VALID },
75 { "OP1_IMM_IMPLIED|SYNTAX_2OP", 26, OP1_IMM_IMPLIED|SYNTAX_2OP|SYNTAX_VALID },
76 { "SYNTAX_3OP", 10, SYNTAX_3OP|SYNTAX_VALID },
77 { "SYNTAX_2OP", 10, SYNTAX_2OP|SYNTAX_VALID }
78};
79
bfb32b52 80#define MAXSYNTAXCLASS (sizeof (syntaxclass) / sizeof (struct syntax_classes))
0d2bcfaf 81
19203624 82const pseudo_typeS md_pseudo_table[] = {
bcee8eb8 83 { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0). */
0d2bcfaf 84 { "comm", arc_common, 0 },
252b5132 85 { "common", arc_common, 0 },
0d2bcfaf
NC
86 { "lcomm", arc_common, 1 },
87 { "lcommon", arc_common, 1 },
88 { "2byte", cons, 2 },
89 { "half", cons, 2 },
90 { "short", cons, 2 },
91 { "3byte", cons, 3 },
92 { "4byte", cons, 4 },
252b5132 93 { "word", cons, 4 },
0d2bcfaf 94 { "option", arc_option, 0 },
bcee8eb8 95 { "cpu", arc_option, 0 },
0d2bcfaf
NC
96 { "block", s_space, 0 },
97 { "extcondcode", arc_extoper, 0 },
98 { "extcoreregister", arc_extoper, 1 },
99 { "extauxregister", arc_extoper, 2 },
100 { "extinstruction", arc_extinst, 0 },
252b5132
RH
101 { NULL, 0, 0 },
102};
103
104/* This array holds the chars that always start a comment. If the
bcee8eb8 105 pre-processor is disabled, these aren't very useful. */
252b5132
RH
106const char comment_chars[] = "#;";
107
108/* This array holds the chars that only start a comment at the beginning of
109 a line. If the line seems to have the form '# 123 filename'
110 .line and .file directives will appear in the pre-processed output */
111/* Note that input_file.c hand checks for '#' at the beginning of the
112 first line of the input file. This is because the compiler outputs
bfb32b52 113 #NO_APP at the beginning of its output. */
252b5132 114/* Also note that comments started like this one will always
bfb32b52 115 work if '/' isn't otherwise defined. */
252b5132
RH
116const char line_comment_chars[] = "#";
117
118const char line_separator_chars[] = "";
119
bcee8eb8 120/* Chars that can be used to separate mant from exp in floating point nums. */
252b5132
RH
121const char EXP_CHARS[] = "eE";
122
bcee8eb8
AM
123/* Chars that mean this number is a floating point constant
124 As in 0f12.456 or 0d1.2345e12. */
252b5132
RH
125const char FLT_CHARS[] = "rRsSfFdD";
126
127/* Byte order. */
128extern int target_big_endian;
129const char *arc_target_format = DEFAULT_TARGET_FORMAT;
130static int byte_order = DEFAULT_BYTE_ORDER;
131
0d2bcfaf
NC
132static segT arcext_section;
133
134/* One of bfd_mach_arc_n. */
bcee8eb8 135static int arc_mach_type = bfd_mach_arc_6;
252b5132
RH
136
137/* Non-zero if the cpu type has been explicitly specified. */
138static int mach_type_specified_p = 0;
139
140/* Non-zero if opcode tables have been initialized.
bcee8eb8 141 A .option command must appear before any instructions. */
252b5132
RH
142static int cpu_tables_init_p = 0;
143
144static struct hash_control *arc_suffix_hash = NULL;
145\f
146const char *md_shortopts = "";
19203624 147struct option md_longopts[] = {
252b5132 148#define OPTION_EB (OPTION_MD_BASE + 0)
bcee8eb8 149 { "EB", no_argument, NULL, OPTION_EB },
252b5132 150#define OPTION_EL (OPTION_MD_BASE + 1)
bcee8eb8 151 { "EL", no_argument, NULL, OPTION_EL },
0d2bcfaf 152#define OPTION_ARC5 (OPTION_MD_BASE + 2)
bcee8eb8
AM
153 { "marc5", no_argument, NULL, OPTION_ARC5 },
154 { "pre-v6", no_argument, NULL, OPTION_ARC5 },
0d2bcfaf 155#define OPTION_ARC6 (OPTION_MD_BASE + 3)
bcee8eb8 156 { "marc6", no_argument, NULL, OPTION_ARC6 },
0d2bcfaf 157#define OPTION_ARC7 (OPTION_MD_BASE + 4)
bcee8eb8 158 { "marc7", no_argument, NULL, OPTION_ARC7 },
0d2bcfaf 159#define OPTION_ARC8 (OPTION_MD_BASE + 5)
bcee8eb8 160 { "marc8", no_argument, NULL, OPTION_ARC8 },
0d2bcfaf 161#define OPTION_ARC (OPTION_MD_BASE + 6)
bcee8eb8 162 { "marc", no_argument, NULL, OPTION_ARC },
252b5132
RH
163 { NULL, no_argument, NULL, 0 }
164};
165size_t md_longopts_size = sizeof (md_longopts);
166
0d2bcfaf
NC
167#define IS_SYMBOL_OPERAND(o) \
168 ((o) == 'b' || (o) == 'c' || (o) == 's' || (o) == 'o' || (o) == 'O')
169
19203624 170struct arc_operand_value *get_ext_suffix (char *s);
0d2bcfaf 171
19203624
KH
172/* Invocation line includes a switch not recognized by the base assembler.
173 See if it's a processor-specific option. */
252b5132
RH
174
175int
176md_parse_option (c, arg)
177 int c;
4a314ec8 178 char *arg ATTRIBUTE_UNUSED;
252b5132
RH
179{
180 switch (c)
1e07b820 181 {
0d2bcfaf
NC
182 case OPTION_ARC5:
183 arc_mach_type = bfd_mach_arc_5;
184 break;
bcee8eb8 185 case OPTION_ARC:
0d2bcfaf
NC
186 case OPTION_ARC6:
187 arc_mach_type = bfd_mach_arc_6;
188 break;
189 case OPTION_ARC7:
190 arc_mach_type = bfd_mach_arc_7;
191 break;
192 case OPTION_ARC8:
193 arc_mach_type = bfd_mach_arc_8;
194 break;
252b5132
RH
195 case OPTION_EB:
196 byte_order = BIG_ENDIAN;
197 arc_target_format = "elf32-bigarc";
198 break;
199 case OPTION_EL:
200 byte_order = LITTLE_ENDIAN;
201 arc_target_format = "elf32-littlearc";
202 break;
203 default:
204 return 0;
1e07b820 205 }
252b5132
RH
206 return 1;
207}
208
209void
210md_show_usage (stream)
211 FILE *stream;
212{
0d2bcfaf
NC
213 fprintf (stream, "\
214ARC Options:\n\
215 -marc[5|6|7|8] select processor variant (default arc%d)\n\
216 -EB assemble code for a big endian cpu\n\
217 -EL assemble code for a little endian cpu\n", arc_mach_type + 5);
252b5132
RH
218}
219
220/* This function is called once, at assembler startup time. It should
221 set up all the tables, etc. that the MD part of the assembler will need.
bcee8eb8 222 Opcode selection is deferred until later because we might see a .option
252b5132
RH
223 command. */
224
225void
226md_begin ()
227{
228 /* The endianness can be chosen "at the factory". */
229 target_big_endian = byte_order == BIG_ENDIAN;
230
231 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
0d2bcfaf 232 as_warn ("could not set architecture and machine");
252b5132 233
bcee8eb8
AM
234 /* This call is necessary because we need to initialize `arc_operand_map'
235 which may be needed before we see the first insn. */
0d2bcfaf 236 arc_opcode_init_tables (arc_get_opcode_mach (arc_mach_type,
252b5132
RH
237 target_big_endian));
238}
239
240/* Initialize the various opcode and operand tables.
241 MACH is one of bfd_mach_arc_xxx. */
252b5132
RH
242static void
243init_opcode_tables (mach)
244 int mach;
245{
4a314ec8 246 int i;
252b5132
RH
247 char *last;
248
249 if ((arc_suffix_hash = hash_new ()) == NULL)
0d2bcfaf 250 as_fatal ("virtual memory exhausted");
252b5132
RH
251
252 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
0d2bcfaf 253 as_warn ("could not set architecture and machine");
252b5132
RH
254
255 /* This initializes a few things in arc-opc.c that we need.
256 This must be called before the various arc_xxx_supported fns. */
257 arc_opcode_init_tables (arc_get_opcode_mach (mach, target_big_endian));
258
259 /* Only put the first entry of each equivalently named suffix in the
260 table. */
261 last = "";
262 for (i = 0; i < arc_suffixes_count; i++)
263 {
252b5132
RH
264 if (strcmp (arc_suffixes[i].name, last) != 0)
265 hash_insert (arc_suffix_hash, arc_suffixes[i].name, (PTR) (arc_suffixes + i));
266 last = arc_suffixes[i].name;
267 }
268
269 /* Since registers don't have a prefix, we put them in the symbol table so
270 they can't be used as symbols. This also simplifies argument parsing as
271 we can let gas parse registers for us. The recorded register number is
0d2bcfaf
NC
272 the address of the register's entry in arc_reg_names.
273
274 If the register name is already in the table, then the existing
275 definition is assumed to be from an .ExtCoreRegister pseudo-op. */
276
252b5132
RH
277 for (i = 0; i < arc_reg_names_count; i++)
278 {
19203624 279 if (symbol_find (arc_reg_names[i].name))
252b5132
RH
280 continue;
281 /* Use symbol_create here instead of symbol_new so we don't try to
282 output registers into the object file's symbol table. */
bcee8eb8
AM
283 symbol_table_insert (symbol_create (arc_reg_names[i].name,
284 reg_section,
285 (int) &arc_reg_names[i],
286 &zero_address_frag));
252b5132
RH
287 }
288
0d2bcfaf 289 /* Tell `.option' it's too late. */
252b5132
RH
290 cpu_tables_init_p = 1;
291}
292\f
293/* Insert an operand value into an instruction.
294 If REG is non-NULL, it is a register number and ignore VAL. */
295
296static arc_insn
297arc_insert_operand (insn, operand, mods, reg, val, file, line)
298 arc_insn insn;
299 const struct arc_operand *operand;
300 int mods;
301 const struct arc_operand_value *reg;
302 offsetT val;
303 char *file;
304 unsigned int line;
305{
306 if (operand->bits != 32)
307 {
308 long min, max;
309 offsetT test;
310
311 if ((operand->flags & ARC_OPERAND_SIGNED) != 0)
312 {
313 if ((operand->flags & ARC_OPERAND_SIGNOPT) != 0)
314 max = (1 << operand->bits) - 1;
315 else
316 max = (1 << (operand->bits - 1)) - 1;
317 min = - (1 << (operand->bits - 1));
318 }
319 else
320 {
321 max = (1 << operand->bits) - 1;
322 min = 0;
323 }
324
325 if ((operand->flags & ARC_OPERAND_NEGATIVE) != 0)
326 test = - val;
327 else
328 test = val;
329
330 if (test < (offsetT) min || test > (offsetT) max)
331 {
332 const char *err =
0d2bcfaf 333 "operand out of range (%s not between %ld and %ld)";
252b5132
RH
334 char buf[100];
335
336 sprint_value (buf, test);
337 if (file == (char *) NULL)
338 as_warn (err, buf, min, max);
339 else
340 as_warn_where (file, line, err, buf, min, max);
341 }
342 }
343
344 if (operand->insert)
345 {
346 const char *errmsg;
347
348 errmsg = NULL;
349 insn = (*operand->insert) (insn, operand, mods, reg, (long) val, &errmsg);
350 if (errmsg != (const char *) NULL)
351 as_warn (errmsg);
352 }
353 else
354 insn |= (((long) val & ((1 << operand->bits) - 1))
355 << operand->shift);
356
357 return insn;
358}
359
360/* We need to keep a list of fixups. We can't simply generate them as
361 we go, because that would require us to first create the frag, and
362 that would screw up references to ``.''. */
363
19203624 364struct arc_fixup {
bcee8eb8 365 /* index into `arc_operands' */
252b5132
RH
366 int opindex;
367 expressionS exp;
368};
369
370#define MAX_FIXUPS 5
371
372#define MAX_SUFFIXES 5
373
374/* This routine is called for each instruction to be assembled. */
375
376void
377md_assemble (str)
378 char *str;
379{
380 const struct arc_opcode *opcode;
0d2bcfaf
NC
381 const struct arc_opcode *std_opcode;
382 struct arc_opcode *ext_opcode;
252b5132 383 char *start;
0d2bcfaf 384 const char *last_errmsg = 0;
252b5132
RH
385 arc_insn insn;
386 static int init_tables_p = 0;
387
388 /* Opcode table initialization is deferred until here because we have to
bcee8eb8 389 wait for a possible .option command. */
252b5132
RH
390 if (!init_tables_p)
391 {
392 init_opcode_tables (arc_mach_type);
393 init_tables_p = 1;
394 }
395
396 /* Skip leading white space. */
3882b010 397 while (ISSPACE (*str))
252b5132
RH
398 str++;
399
400 /* The instructions are stored in lists hashed by the first letter (though
401 we needn't care how they're hashed). Get the first in the list. */
402
0d2bcfaf
NC
403 ext_opcode = arc_ext_opcodes;
404 std_opcode = arc_opcode_lookup_asm (str);
252b5132
RH
405
406 /* Keep looking until we find a match. */
407
408 start = str;
19203624 409 for (opcode = (ext_opcode ? ext_opcode : std_opcode);
0d2bcfaf
NC
410 opcode != NULL;
411 opcode = (ARC_OPCODE_NEXT_ASM (opcode)
1e07b820
KH
412 ? ARC_OPCODE_NEXT_ASM (opcode)
413 : (ext_opcode ? ext_opcode = NULL, std_opcode : NULL)))
252b5132
RH
414 {
415 int past_opcode_p, fc, num_suffixes;
0d2bcfaf 416 int fix_up_at = 0;
252b5132
RH
417 char *syn;
418 struct arc_fixup fixups[MAX_FIXUPS];
419 /* Used as a sanity check. If we need a limm reloc, make sure we ask
420 for an extra 4 bytes from frag_more. */
421 int limm_reloc_p;
0d2bcfaf 422 int ext_suffix_p;
252b5132
RH
423 const struct arc_operand_value *insn_suffixes[MAX_SUFFIXES];
424
425 /* Is this opcode supported by the selected cpu? */
426 if (! arc_opcode_supported (opcode))
427 continue;
428
429 /* Scan the syntax string. If it doesn't match, try the next one. */
430
431 arc_opcode_init_insert ();
432 insn = opcode->value;
433 fc = 0;
434 past_opcode_p = 0;
435 num_suffixes = 0;
436 limm_reloc_p = 0;
0d2bcfaf 437 ext_suffix_p = 0;
252b5132
RH
438
439 /* We don't check for (*str != '\0') here because we want to parse
440 any trailing fake arguments in the syntax string. */
19203624 441 for (str = start, syn = opcode->syntax; *syn != '\0';)
252b5132
RH
442 {
443 int mods;
444 const struct arc_operand *operand;
445
446 /* Non operand chars must match exactly. */
447 if (*syn != '%' || *++syn == '%')
448 {
449 /* Handle '+' specially as we want to allow "ld r0,[sp-4]". */
450 /* ??? The syntax has changed to [sp,-4]. */
451 if (0 && *syn == '+' && *str == '-')
452 {
453 /* Skip over syn's +, but leave str's - alone.
454 That makes the case identical to "ld r0,[sp+-4]". */
455 ++syn;
456 }
457 else if (*str == *syn)
458 {
459 if (*syn == ' ')
460 past_opcode_p = 1;
461 ++syn;
462 ++str;
463 }
464 else
465 break;
466 continue;
467 }
468
469 /* We have an operand. Pick out any modifiers. */
470 mods = 0;
4a314ec8 471 while (ARC_MOD_P (arc_operands[arc_operand_map[(int) *syn]].flags))
252b5132 472 {
4a314ec8 473 mods |= arc_operands[arc_operand_map[(int) *syn]].flags & ARC_MOD_BITS;
252b5132
RH
474 ++syn;
475 }
4a314ec8 476 operand = arc_operands + arc_operand_map[(int) *syn];
252b5132 477 if (operand->fmt == 0)
0d2bcfaf 478 as_fatal ("unknown syntax format character `%c'", *syn);
252b5132
RH
479
480 if (operand->flags & ARC_OPERAND_FAKE)
481 {
482 const char *errmsg = NULL;
483 if (operand->insert)
484 {
485 insn = (*operand->insert) (insn, operand, mods, NULL, 0, &errmsg);
1e07b820
KH
486 if (errmsg != (const char *) NULL)
487 {
488 last_errmsg = errmsg;
489 if (operand->flags & ARC_OPERAND_ERROR)
490 {
491 as_bad (errmsg);
492 return;
493 }
494 else if (operand->flags & ARC_OPERAND_WARN)
495 as_warn (errmsg);
496 break;
497 }
19203624
KH
498 if (limm_reloc_p
499 && (operand->flags && operand->flags & ARC_OPERAND_LIMM)
500 && (operand->flags &
501 (ARC_OPERAND_ABSOLUTE_BRANCH | ARC_OPERAND_ADDRESS)))
1e07b820
KH
502 {
503 fixups[fix_up_at].opindex = arc_operand_map[operand->fmt];
504 }
252b5132
RH
505 }
506 ++syn;
507 }
508 /* Are we finished with suffixes? */
509 else if (!past_opcode_p)
510 {
511 int found;
512 char c;
19203624
KH
513 char *s, *t;
514 const struct arc_operand_value *suf, *suffix_end;
0d2bcfaf 515 const struct arc_operand_value *suffix = NULL;
252b5132
RH
516
517 if (!(operand->flags & ARC_OPERAND_SUFFIX))
518 abort ();
519
520 /* If we're at a space in the input string, we want to skip the
521 remaining suffixes. There may be some fake ones though, so
522 just go on to try the next one. */
523 if (*str == ' ')
524 {
525 ++syn;
526 continue;
527 }
528
529 s = str;
530 if (mods & ARC_MOD_DOT)
531 {
532 if (*s != '.')
533 break;
534 ++s;
535 }
536 else
537 {
538 /* This can happen in "b.nd foo" and we're currently looking
539 for "%q" (ie: a condition code suffix). */
540 if (*s == '.')
541 {
542 ++syn;
543 continue;
544 }
545 }
546
547 /* Pick the suffix out and look it up via the hash table. */
3882b010 548 for (t = s; *t && ISALNUM (*t); ++t)
252b5132
RH
549 continue;
550 c = *t;
551 *t = '\0';
19203624 552 if ((suf = get_ext_suffix (s)))
1e07b820
KH
553 ext_suffix_p = 1;
554 else
555 suf = hash_find (arc_suffix_hash, s);
252b5132
RH
556 if (!suf)
557 {
558 /* This can happen in "blle foo" and we're currently using
559 the template "b%q%.n %j". The "bl" insn occurs later in
560 the table so "lle" isn't an illegal suffix. */
1e07b820 561 *t = c;
252b5132
RH
562 break;
563 }
564
565 /* Is it the right type? Note that the same character is used
1e07b820 566 several times, so we have to examine all of them. This is
252b5132
RH
567 relatively efficient as equivalent entries are kept
568 together. If it's not the right type, don't increment `str'
569 so we try the next one in the series. */
570 found = 0;
1e07b820
KH
571 if (ext_suffix_p && arc_operands[suf->type].fmt == *syn)
572 {
573 /* Insert the suffix's value into the insn. */
574 *t = c;
575 if (operand->insert)
576 insn = (*operand->insert) (insn, operand,
577 mods, NULL, suf->value,
578 NULL);
579 else
580 insn |= suf->value << operand->shift;
581
582 str = t;
583 found = 1;
584 }
585 else
586 {
587 *t = c;
588 suffix_end = arc_suffixes + arc_suffixes_count;
589 for (suffix = suf;
590 suffix < suffix_end && strcmp (suffix->name, suf->name) == 0;
591 ++suffix)
592 {
593 if (arc_operands[suffix->type].fmt == *syn)
594 {
595 /* Insert the suffix's value into the insn. */
596 if (operand->insert)
597 insn = (*operand->insert) (insn, operand,
598 mods, NULL, suffix->value,
599 NULL);
600 else
601 insn |= suffix->value << operand->shift;
602
603 str = t;
604 found = 1;
605 break;
606 }
607 }
608 }
252b5132
RH
609 ++syn;
610 if (!found)
19203624
KH
611 /* Wrong type. Just go on to try next insn entry. */
612 ;
252b5132
RH
613 else
614 {
615 if (num_suffixes == MAX_SUFFIXES)
0d2bcfaf 616 as_bad ("too many suffixes");
252b5132
RH
617 else
618 insn_suffixes[num_suffixes++] = suffix;
619 }
620 }
621 else
622 /* This is either a register or an expression of some kind. */
623 {
252b5132
RH
624 char *hold;
625 const struct arc_operand_value *reg = NULL;
626 long value = 0;
627 expressionS exp;
628
629 if (operand->flags & ARC_OPERAND_SUFFIX)
630 abort ();
631
632 /* Is there anything left to parse?
633 We don't check for this at the top because we want to parse
634 any trailing fake arguments in the syntax string. */
2d0441d9 635 if (is_end_of_line[(unsigned char) *str])
252b5132 636 break;
252b5132
RH
637
638 /* Parse the operand. */
639 hold = input_line_pointer;
640 input_line_pointer = str;
641 expression (&exp);
642 str = input_line_pointer;
643 input_line_pointer = hold;
644
645 if (exp.X_op == O_illegal)
0d2bcfaf 646 as_bad ("illegal operand");
252b5132 647 else if (exp.X_op == O_absent)
0d2bcfaf 648 as_bad ("missing operand");
252b5132
RH
649 else if (exp.X_op == O_constant)
650 {
651 value = exp.X_add_number;
652 }
653 else if (exp.X_op == O_register)
654 {
0d2bcfaf 655 reg = (struct arc_operand_value *) exp.X_add_number;
252b5132 656 }
0d2bcfaf
NC
657#define IS_REG_DEST_OPERAND(o) ((o) == 'a')
658 else if (IS_REG_DEST_OPERAND (*syn))
19203624 659 as_bad ("symbol as destination register");
1e07b820 660 else
252b5132 661 {
19203624 662 if (!strncmp (str, "@h30", 4))
1e07b820 663 {
19203624 664 arc_code_symbol (&exp);
1e07b820
KH
665 str += 4;
666 }
252b5132
RH
667 /* We need to generate a fixup for this expression. */
668 if (fc >= MAX_FIXUPS)
0d2bcfaf 669 as_fatal ("too many fixups");
252b5132 670 fixups[fc].exp = exp;
1e07b820 671 /* We don't support shimm relocs. break here to force
19203624 672 the assembler to output a limm. */
0d2bcfaf 673#define IS_REG_SHIMM_OFFSET(o) ((o) == 'd')
19203624 674 if (IS_REG_SHIMM_OFFSET (*syn))
1e07b820 675 break;
252b5132
RH
676 /* If this is a register constant (IE: one whose
677 register value gets stored as 61-63) then this
bfb32b52 678 must be a limm. */
252b5132
RH
679 /* ??? This bit could use some cleaning up.
680 Referencing the format chars like this goes
681 against style. */
0d2bcfaf 682 if (IS_SYMBOL_OPERAND (*syn))
252b5132
RH
683 {
684 const char *junk;
252b5132 685 limm_reloc_p = 1;
19203624 686 /* Save this, we don't yet know what reloc to use. */
1e07b820 687 fix_up_at = fc;
252b5132
RH
688 /* Tell insert_reg we need a limm. This is
689 needed because the value at this point is
690 zero, a shimm. */
691 /* ??? We need a cleaner interface than this. */
692 (*arc_operands[arc_operand_map['Q']].insert)
693 (insn, operand, mods, reg, 0L, &junk);
694 }
695 else
4a314ec8 696 fixups[fc].opindex = arc_operand_map[(int) *syn];
252b5132
RH
697 ++fc;
698 value = 0;
699 }
700
701 /* Insert the register or expression into the instruction. */
702 if (operand->insert)
703 {
704 const char *errmsg = NULL;
705 insn = (*operand->insert) (insn, operand, mods,
706 reg, (long) value, &errmsg);
1e07b820
KH
707 if (errmsg != (const char *) NULL)
708 {
709 last_errmsg = errmsg;
710 if (operand->flags & ARC_OPERAND_ERROR)
711 {
712 as_bad (errmsg);
713 return;
714 }
715 else if (operand->flags & ARC_OPERAND_WARN)
716 as_warn (errmsg);
717 break;
718 }
252b5132
RH
719 }
720 else
721 insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
722
723 ++syn;
724 }
725 }
726
727 /* If we're at the end of the syntax string, we're done. */
728 /* FIXME: try to move this to a separate function. */
729 if (*syn == '\0')
730 {
731 int i;
732 char *f;
733 long limm, limm_p;
734
735 /* For the moment we assume a valid `str' can only contain blanks
736 now. IE: We needn't try again with a longer version of the
737 insn and it is assumed that longer versions of insns appear
738 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
739
3882b010 740 while (ISSPACE (*str))
252b5132
RH
741 ++str;
742
2d0441d9 743 if (!is_end_of_line[(unsigned char) *str])
0d2bcfaf 744 as_bad ("junk at end of line: `%s'", str);
252b5132
RH
745
746 /* Is there a limm value? */
747 limm_p = arc_opcode_limm_p (&limm);
748
749 /* Perform various error and warning tests. */
750
751 {
752 static int in_delay_slot_p = 0;
753 static int prev_insn_needs_cc_nop_p = 0;
754 /* delay slot type seen */
755 int delay_slot_type = ARC_DELAY_NONE;
756 /* conditional execution flag seen */
757 int conditional = 0;
758 /* 1 if condition codes are being set */
759 int cc_set_p = 0;
760 /* 1 if conditional branch, including `b' "branch always" */
761 int cond_branch_p = opcode->flags & ARC_OPCODE_COND_BRANCH;
252b5132
RH
762
763 for (i = 0; i < num_suffixes; ++i)
764 {
765 switch (arc_operands[insn_suffixes[i]->type].fmt)
766 {
19203624 767 case 'n':
252b5132
RH
768 delay_slot_type = insn_suffixes[i]->value;
769 break;
19203624 770 case 'q':
252b5132
RH
771 conditional = insn_suffixes[i]->value;
772 break;
19203624 773 case 'f':
252b5132
RH
774 cc_set_p = 1;
775 break;
776 }
777 }
778
779 /* Putting an insn with a limm value in a delay slot is supposed to
780 be legal, but let's warn the user anyway. Ditto for 8 byte
781 jumps with delay slots. */
782 if (in_delay_slot_p && limm_p)
1e07b820 783 as_warn ("8 byte instruction in delay slot");
0d2bcfaf 784 if (delay_slot_type != ARC_DELAY_NONE
19203624 785 && limm_p && arc_insn_not_jl (insn)) /* except for jl addr */
1e07b820 786 as_warn ("8 byte jump instruction with delay slot");
252b5132
RH
787 in_delay_slot_p = (delay_slot_type != ARC_DELAY_NONE) && !limm_p;
788
789 /* Warn when a conditional branch immediately follows a set of
790 the condition codes. Note that this needn't be done if the
791 insn that sets the condition codes uses a limm. */
792 if (cond_branch_p && conditional != 0 /* 0 = "always" */
0d2bcfaf 793 && prev_insn_needs_cc_nop_p && arc_mach_type == bfd_mach_arc_5)
1e07b820 794 as_warn ("conditional branch follows set of flags");
0d2bcfaf 795 prev_insn_needs_cc_nop_p =
1e07b820
KH
796 /* FIXME: ??? not required:
797 (delay_slot_type != ARC_DELAY_NONE) && */
798 cc_set_p && !limm_p;
252b5132
RH
799 }
800
801 /* Write out the instruction.
802 It is important to fetch enough space in one call to `frag_more'.
803 We use (f - frag_now->fr_literal) to compute where we are and we
804 don't want frag_now to change between calls. */
805 if (limm_p)
806 {
807 f = frag_more (8);
808 md_number_to_chars (f, insn, 4);
809 md_number_to_chars (f + 4, limm, 4);
9fcc94b6 810 dwarf2_emit_insn (8);
252b5132
RH
811 }
812 else if (limm_reloc_p)
813 {
814 /* We need a limm reloc, but the tables think we don't. */
815 abort ();
816 }
817 else
818 {
819 f = frag_more (4);
820 md_number_to_chars (f, insn, 4);
9fcc94b6 821 dwarf2_emit_insn (4);
252b5132
RH
822 }
823
824 /* Create any fixups. */
825 for (i = 0; i < fc; ++i)
826 {
827 int op_type, reloc_type;
828 expressionS exptmp;
829 const struct arc_operand *operand;
830
831 /* Create a fixup for this operand.
832 At this point we do not use a bfd_reloc_code_real_type for
833 operands residing in the insn, but instead just use the
834 operand index. This lets us easily handle fixups for any
835 operand type, although that is admittedly not a very exciting
94f592af 836 feature. We pick a BFD reloc type in md_apply_fix3.
252b5132
RH
837
838 Limm values (4 byte immediate "constants") must be treated
839 normally because they're not part of the actual insn word
840 and thus the insertion routines don't handle them. */
841
842 if (arc_operands[fixups[i].opindex].flags & ARC_OPERAND_LIMM)
843 {
19203624
KH
844 /* Modify the fixup addend as required by the cpu. */
845 fixups[i].exp.X_add_number += arc_limm_fixup_adjust (insn);
252b5132
RH
846 op_type = fixups[i].opindex;
847 /* FIXME: can we add this data to the operand table? */
0d2bcfaf 848 if (op_type == arc_operand_map['L']
1e07b820
KH
849 || op_type == arc_operand_map['s']
850 || op_type == arc_operand_map['o']
851 || op_type == arc_operand_map['O'])
252b5132
RH
852 reloc_type = BFD_RELOC_32;
853 else if (op_type == arc_operand_map['J'])
854 reloc_type = BFD_RELOC_ARC_B26;
855 else
856 abort ();
857 reloc_type = get_arc_exp_reloc_type (1, reloc_type,
858 &fixups[i].exp,
859 &exptmp);
860 }
861 else
862 {
863 op_type = get_arc_exp_reloc_type (0, fixups[i].opindex,
864 &fixups[i].exp, &exptmp);
865 reloc_type = op_type + (int) BFD_RELOC_UNUSED;
866 }
867 operand = &arc_operands[op_type];
868 fix_new_exp (frag_now,
869 ((f - frag_now->fr_literal)
870 + (operand->flags & ARC_OPERAND_LIMM ? 4 : 0)), 4,
871 &exptmp,
872 (operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0,
873 (bfd_reloc_code_real_type) reloc_type);
874 }
875
876 /* All done. */
877 return;
878 }
879
880 /* Try the next entry. */
881 }
882
19203624 883 if (NULL == last_errmsg)
0d2bcfaf
NC
884 as_bad ("bad instruction `%s'", start);
885 else
886 as_bad (last_errmsg);
252b5132
RH
887}
888\f
252b5132 889static void
0d2bcfaf
NC
890arc_extoper (opertype)
891 int opertype;
252b5132
RH
892{
893 char *name;
0d2bcfaf 894 char *mode;
252b5132
RH
895 char c;
896 char *p;
0d2bcfaf
NC
897 int imode = 0;
898 int number;
899 struct arc_ext_operand_value *ext_oper;
252b5132
RH
900 symbolS *symbolP;
901
0d2bcfaf
NC
902 segT old_sec;
903 int old_subsec;
904
252b5132
RH
905 name = input_line_pointer;
906 c = get_symbol_end ();
19203624 907 name = xstrdup (name);
0d2bcfaf
NC
908 if (NULL == name)
909 {
19203624 910 ignore_rest_of_line ();
1e07b820 911 return;
0d2bcfaf
NC
912 }
913
914 p = name;
915 while (*p)
916 {
3882b010 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)
89b57c9a 1541 int type;
19203624
KH
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;
89b57c9a 1549 char * atof_ieee PARAMS ((char *, int, LITTLENUM_TYPE *));
252b5132
RH
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{
d3ecfc59 1634 if (expressionP->X_op == O_symbol && expressionP->X_add_number == 0)
0d2bcfaf 1635 {
1e07b820
KH
1636 expressionS two;
1637 expressionP->X_op = O_right_shift;
bcee8eb8 1638 expressionP->X_add_symbol->sy_value.X_op = O_constant;
1e07b820
KH
1639 two.X_op = O_constant;
1640 two.X_add_symbol = two.X_op_symbol = NULL;
1641 two.X_add_number = 2;
1642 expressionP->X_op_symbol = make_expr_symbol (&two);
0d2bcfaf 1643 }
bcee8eb8 1644 /* Allow %st(sym1-sym2) */
19203624
KH
1645 else if (expressionP->X_op == O_subtract
1646 && expressionP->X_add_symbol != NULL
1647 && expressionP->X_op_symbol != NULL
1648 && expressionP->X_add_number == 0)
0d2bcfaf 1649 {
1e07b820
KH
1650 expressionS two;
1651 expressionP->X_add_symbol = make_expr_symbol (expressionP);
1652 expressionP->X_op = O_right_shift;
1653 two.X_op = O_constant;
1654 two.X_add_symbol = two.X_op_symbol = NULL;
1655 two.X_add_number = 2;
1656 expressionP->X_op_symbol = make_expr_symbol (&two);
0d2bcfaf
NC
1657 }
1658 else
1659 {
1e07b820
KH
1660 as_bad ("expression too complex code symbol");
1661 return;
0d2bcfaf 1662 }
252b5132
RH
1663}
1664
1665/* Parse an operand that is machine-specific.
1666
1667 The ARC has a special %-op to adjust addresses so they're usable in
1668 branches. The "st" is short for the STatus register.
1669 ??? Later expand this to take a flags value too.
1670
1671 ??? We can't create new expression types so we map the %-op's onto the
1672 existing syntax. This means that the user could use the chosen syntax
bfb32b52 1673 to achieve the same effect. */
252b5132 1674
bfb32b52 1675void
252b5132
RH
1676md_operand (expressionP)
1677 expressionS *expressionP;
1678{
1679 char *p = input_line_pointer;
1680
0d2bcfaf 1681 if (*p == '%')
19203624 1682 if (strncmp (p, "%st(", 4) == 0)
0d2bcfaf 1683 {
1e07b820
KH
1684 input_line_pointer += 4;
1685 expression (expressionP);
1686 if (*input_line_pointer != ')')
1687 {
1688 as_bad ("missing ')' in %%-op");
1689 return;
1690 }
1691 ++input_line_pointer;
19203624 1692 arc_code_symbol (expressionP);
0d2bcfaf 1693 }
1e07b820 1694 else
bcee8eb8
AM
1695 {
1696 /* It could be a register. */
19203624 1697 int i, l;
1e07b820
KH
1698 struct arc_ext_operand_value *ext_oper = arc_ext_operands;
1699 p++;
0d2bcfaf 1700
1e07b820
KH
1701 while (ext_oper)
1702 {
19203624 1703 l = strlen (ext_oper->operand.name);
3882b010 1704 if (!strncmp (p, ext_oper->operand.name, l) && !ISALNUM (*(p + l)))
1e07b820
KH
1705 {
1706 input_line_pointer += l + 1;
1707 expressionP->X_op = O_register;
1708 expressionP->X_add_number = (int) &ext_oper->operand;
1709 return;
1710 }
1711 ext_oper = ext_oper->next;
1712 }
1713 for (i = 0; i < arc_reg_names_count; i++)
1714 {
19203624 1715 l = strlen (arc_reg_names[i].name);
3882b010 1716 if (!strncmp (p, arc_reg_names[i].name, l) && !ISALNUM (*(p + l)))
1e07b820
KH
1717 {
1718 input_line_pointer += l + 1;
1719 expressionP->X_op = O_register;
19203624 1720 expressionP->X_add_number = (int) &arc_reg_names[i];
1e07b820
KH
1721 break;
1722 }
1723 }
0d2bcfaf 1724 }
252b5132
RH
1725}
1726
1727/* We have no need to default values of symbols.
1728 We could catch register names here, but that is handled by inserting
1729 them all in the symbol table to begin with. */
1730
1731symbolS *
1732md_undefined_symbol (name)
4a314ec8 1733 char *name ATTRIBUTE_UNUSED;
252b5132
RH
1734{
1735 return 0;
1736}
1737\f
1738/* Functions concerning expressions. */
1739
1740/* Parse a .byte, .word, etc. expression.
1741
1742 Values for the status register are specified with %st(label).
1743 `label' will be right shifted by 2. */
1744
1745void
1746arc_parse_cons_expression (exp, nbytes)
19203624
KH
1747 expressionS *exp;
1748 unsigned int nbytes ATTRIBUTE_UNUSED;
252b5132 1749{
0d2bcfaf
NC
1750 char *p = input_line_pointer;
1751 int code_symbol_fix = 0;
1752
19203624
KH
1753 for (; ! is_end_of_line[(unsigned char) *p]; p++)
1754 if (*p == '@' && !strncmp (p, "@h30", 4))
0d2bcfaf 1755 {
1e07b820 1756 code_symbol_fix = 1;
19203624 1757 strcpy (p, "; ");
0d2bcfaf 1758 }
1e07b820
KH
1759 expr (0, exp);
1760 if (code_symbol_fix)
1761 {
19203624 1762 arc_code_symbol (exp);
1e07b820
KH
1763 input_line_pointer = p;
1764 }
252b5132
RH
1765}
1766
1767/* Record a fixup for a cons expression. */
1768
1769void
1770arc_cons_fix_new (frag, where, nbytes, exp)
1771 fragS *frag;
1772 int where;
1773 int nbytes;
1774 expressionS *exp;
1775{
1776 if (nbytes == 4)
1777 {
1778 int reloc_type;
1779 expressionS exptmp;
1780
1781 /* This may be a special ARC reloc (eg: %st()). */
1782 reloc_type = get_arc_exp_reloc_type (1, BFD_RELOC_32, exp, &exptmp);
1783 fix_new_exp (frag, where, nbytes, &exptmp, 0, reloc_type);
1784 }
1785 else
1786 {
1787 fix_new_exp (frag, where, nbytes, exp, 0,
1788 nbytes == 2 ? BFD_RELOC_16
1789 : nbytes == 8 ? BFD_RELOC_64
1790 : BFD_RELOC_32);
1791 }
1792}
1793\f
1794/* Functions concerning relocs. */
1795
1796/* The location from which a PC relative jump should be calculated,
1797 given a PC relative reloc. */
1798
bfb32b52 1799long
252b5132
RH
1800md_pcrel_from (fixP)
1801 fixS *fixP;
1802{
252b5132
RH
1803 /* Return the address of the delay slot. */
1804 return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
1805}
1806
1807/* Compute the reloc type of an expression.
1808 The possibly modified expression is stored in EXPNEW.
1809
1810 This is used to convert the expressions generated by the %-op's into
1811 the appropriate operand type. It is called for both data in instructions
1812 (operands) and data outside instructions (variables, debugging info, etc.).
1813
1814 Currently supported %-ops:
1815
1816 %st(symbol): represented as "symbol >> 2"
1817 "st" is short for STatus as in the status register (pc)
1818
1819 DEFAULT_TYPE is the type to use if no special processing is required.
1820
1821 DATA_P is non-zero for data or limm values, zero for insn operands.
1822 Remember that the opcode "insertion fns" cannot be used on data, they're
1823 only for inserting operands into insns. They also can't be used for limm
1824 values as the insertion routines don't handle limm values. When called for
1825 insns we return fudged reloc types (real_value - BFD_RELOC_UNUSED). When
1826 called for data or limm values we use real reloc types. */
1827
1828static int
1829get_arc_exp_reloc_type (data_p, default_type, exp, expnew)
1830 int data_p;
1831 int default_type;
1832 expressionS *exp;
1833 expressionS *expnew;
1834{
1835 /* If the expression is "symbol >> 2" we must change it to just "symbol",
1836 as fix_new_exp can't handle it. Similarily for (symbol - symbol) >> 2.
1837 That's ok though. What's really going on here is that we're using
1838 ">> 2" as a special syntax for specifying BFD_RELOC_ARC_B26. */
1839
1840 if (exp->X_op == O_right_shift
1841 && exp->X_op_symbol != NULL
0d2bcfaf
NC
1842 && exp->X_op_symbol->sy_value.X_op == O_constant
1843 && exp->X_op_symbol->sy_value.X_add_number == 2
252b5132
RH
1844 && exp->X_add_number == 0)
1845 {
1846 if (exp->X_add_symbol != NULL
0d2bcfaf
NC
1847 && (exp->X_add_symbol->sy_value.X_op == O_constant
1848 || exp->X_add_symbol->sy_value.X_op == O_symbol))
252b5132
RH
1849 {
1850 *expnew = *exp;
1851 expnew->X_op = O_symbol;
1852 expnew->X_op_symbol = NULL;
1853 return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
1854 }
1855 else if (exp->X_add_symbol != NULL
0d2bcfaf 1856 && exp->X_add_symbol->sy_value.X_op == O_subtract)
252b5132 1857 {
0d2bcfaf 1858 *expnew = exp->X_add_symbol->sy_value;
252b5132
RH
1859 return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
1860 }
1861 }
1862
1863 *expnew = *exp;
1864 return default_type;
1865}
1866
1867/* Apply a fixup to the object code. This is called for all the
1868 fixups we generated by the call to fix_new_exp, above. In the call
1869 above we used a reloc code which was the largest legal reloc code
1870 plus the operand index. Here we undo that to recover the operand
1871 index. At this point all symbol values should be fully resolved,
1872 and we attempt to completely resolve the reloc. If we can not do
1873 that, we determine the correct reloc code and put it back in the fixup. */
1874
94f592af
NC
1875void
1876md_apply_fix3 (fixP, valP, seg)
252b5132 1877 fixS *fixP;
94f592af 1878 valueT * valP;
252b5132
RH
1879 segT seg;
1880{
19203624
KH
1881#if 0
1882 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1883#endif
94f592af 1884 valueT value = * valP;
252b5132 1885
252b5132 1886 if (fixP->fx_addsy == (symbolS *) NULL)
94f592af
NC
1887 fixP->fx_done = 1;
1888
252b5132
RH
1889 else if (fixP->fx_pcrel)
1890 {
a161fe53
AM
1891 /* Hack around bfd_install_relocation brain damage. */
1892 if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
252b5132
RH
1893 value += md_pcrel_from (fixP);
1894 }
a161fe53
AM
1895
1896 /* We can't actually support subtracting a symbol. */
1897 if (fixP->fx_subsy != NULL)
1898 as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
252b5132
RH
1899
1900 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
1901 {
1902 int opindex;
1903 const struct arc_operand *operand;
1904 char *where;
1905 arc_insn insn;
1906
1907 opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
1908
1909 operand = &arc_operands[opindex];
1910
1911 /* Fetch the instruction, insert the fully resolved operand
1912 value, and stuff the instruction back again. */
1913 where = fixP->fx_frag->fr_literal + fixP->fx_where;
1914 if (target_big_endian)
1915 insn = bfd_getb32 ((unsigned char *) where);
1916 else
1917 insn = bfd_getl32 ((unsigned char *) where);
1918 insn = arc_insert_operand (insn, operand, -1, NULL, (offsetT) value,
1919 fixP->fx_file, fixP->fx_line);
1920 if (target_big_endian)
1921 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1922 else
1923 bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
1924
1925 if (fixP->fx_done)
1926 {
1927 /* Nothing else to do here. */
94f592af 1928 return;
252b5132
RH
1929 }
1930
1931 /* Determine a BFD reloc value based on the operand information.
1932 We are only prepared to turn a few of the operands into relocs.
1933 !!! Note that we can't handle limm values here. Since we're using
1934 implicit addends the addend must be inserted into the instruction,
1935 however, the opcode insertion routines currently do nothing with
1936 limm values. */
1937 if (operand->fmt == 'B')
1938 {
1939 assert ((operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0
1940 && operand->bits == 20
1941 && operand->shift == 7);
1942 fixP->fx_r_type = BFD_RELOC_ARC_B22_PCREL;
1943 }
0d2bcfaf 1944 else if (operand->fmt == 'J')
252b5132
RH
1945 {
1946 assert ((operand->flags & ARC_OPERAND_ABSOLUTE_BRANCH) != 0
1947 && operand->bits == 24
1948 && operand->shift == 32);
1949 fixP->fx_r_type = BFD_RELOC_ARC_B26;
1950 }
0d2bcfaf 1951 else if (operand->fmt == 'L')
252b5132
RH
1952 {
1953 assert ((operand->flags & ARC_OPERAND_LIMM) != 0
1954 && operand->bits == 32
1955 && operand->shift == 32);
1956 fixP->fx_r_type = BFD_RELOC_32;
1957 }
1958 else
1959 {
1960 as_bad_where (fixP->fx_file, fixP->fx_line,
0d2bcfaf 1961 "unresolved expression that must be resolved");
252b5132 1962 fixP->fx_done = 1;
94f592af 1963 return;
252b5132
RH
1964 }
1965 }
1966 else
1967 {
1968 switch (fixP->fx_r_type)
1969 {
1970 case BFD_RELOC_8:
1971 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1972 value, 1);
1973 break;
1974 case BFD_RELOC_16:
1975 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1976 value, 2);
1977 break;
1978 case BFD_RELOC_32:
1979 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1980 value, 4);
1981 break;
1982#if 0
1983 case BFD_RELOC_64:
1984 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1985 value, 8);
1986 break;
1987#endif
1988 case BFD_RELOC_ARC_B26:
1989 /* If !fixP->fx_done then `value' is an implicit addend.
1990 We must shift it right by 2 in this case as well because the
1991 linker performs the relocation and then adds this in (as opposed
1992 to adding this in and then shifting right by 2). */
1993 value >>= 2;
1994 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1995 value, 4);
1996 break;
1997 default:
1998 abort ();
1999 }
2000 }
252b5132
RH
2001}
2002
2003/* Translate internal representation of relocation info to BFD target
2004 format. */
2005
2006arelent *
2007tc_gen_reloc (section, fixP)
4a314ec8 2008 asection *section ATTRIBUTE_UNUSED;
252b5132
RH
2009 fixS *fixP;
2010{
2011 arelent *reloc;
2012
2013 reloc = (arelent *) xmalloc (sizeof (arelent));
2014
0d2bcfaf 2015 reloc->sym_ptr_ptr = &fixP->fx_addsy->bsym;
252b5132
RH
2016 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
2017 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
2018 if (reloc->howto == (reloc_howto_type *) NULL)
2019 {
2020 as_bad_where (fixP->fx_file, fixP->fx_line,
0d2bcfaf 2021 "internal error: can't export reloc type %d (`%s')",
19203624
KH
2022 fixP->fx_r_type,
2023 bfd_get_reloc_code_name (fixP->fx_r_type));
252b5132
RH
2024 return NULL;
2025 }
2026
2027 assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
2028
19203624 2029 /* Set addend to account for PC being advanced one insn before the
a161fe53 2030 target address is computed. */
252b5132 2031
19203624 2032 reloc->addend = (fixP->fx_pcrel ? -4 : 0);
252b5132 2033
0d2bcfaf 2034 return reloc;
252b5132 2035}
This page took 0.276924 seconds and 4 git commands to generate.