Workaround for Itanium A/B step errata
[deliverable/binutils-gdb.git] / gas / config / tc-arc.c
CommitLineData
252b5132 1/* tc-arc.c -- Assembler for the ARC
1dab94dd
KH
2 Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000
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
310b5aa2
ILT
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
1dab94dd 21 02111-1307, USA. */
252b5132
RH
22
23#include <stdio.h>
24#include <ctype.h>
25#include "as.h"
26#include "subsegs.h"
27#include "opcode/arc.h"
28#include "elf/arc.h"
29
30extern int arc_get_mach PARAMS ((char *));
31
32static arc_insn arc_insert_operand PARAMS ((arc_insn,
33 const struct arc_operand *, int,
34 const struct arc_operand_value *,
35 offsetT, char *, unsigned int));
36static void arc_common PARAMS ((int));
37static void arc_cpu PARAMS ((int));
38/*static void arc_rename PARAMS ((int));*/
39static int get_arc_exp_reloc_type PARAMS ((int, int, expressionS *,
40 expressionS *));
41
42const pseudo_typeS md_pseudo_table[] =
43{
44 { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0) */
45 { "common", arc_common, 0 },
46/*{ "hword", cons, 2 }, - already exists */
47 { "word", cons, 4 },
48/*{ "xword", cons, 8 },*/
49 { "cpu", arc_cpu, 0 },
50/*{ "rename", arc_rename, 0 },*/
51 { NULL, 0, 0 },
52};
53
54/* This array holds the chars that always start a comment. If the
55 pre-processor is disabled, these aren't very useful */
56const char comment_chars[] = "#;";
57
58/* This array holds the chars that only start a comment at the beginning of
59 a line. If the line seems to have the form '# 123 filename'
60 .line and .file directives will appear in the pre-processed output */
61/* Note that input_file.c hand checks for '#' at the beginning of the
62 first line of the input file. This is because the compiler outputs
1dab94dd 63 #NO_APP at the beginning of its output. */
252b5132 64/* Also note that comments started like this one will always
1dab94dd 65 work if '/' isn't otherwise defined. */
252b5132
RH
66const char line_comment_chars[] = "#";
67
68const char line_separator_chars[] = "";
69
70/* Chars that can be used to separate mant from exp in floating point nums */
71const char EXP_CHARS[] = "eE";
72
73/* Chars that mean this number is a floating point constant */
74/* As in 0f12.456 */
75/* or 0d1.2345e12 */
76const char FLT_CHARS[] = "rRsSfFdD";
77
78/* Byte order. */
79extern int target_big_endian;
80const char *arc_target_format = DEFAULT_TARGET_FORMAT;
81static int byte_order = DEFAULT_BYTE_ORDER;
82
83/* One of bfd_mach_arc_xxx. */
84static int arc_mach_type = bfd_mach_arc_base;
85
86/* Non-zero if the cpu type has been explicitly specified. */
87static int mach_type_specified_p = 0;
88
89/* Non-zero if opcode tables have been initialized.
90 A .cpu command must appear before any instructions. */
91static int cpu_tables_init_p = 0;
92
93static struct hash_control *arc_suffix_hash = NULL;
94\f
95const char *md_shortopts = "";
96struct option md_longopts[] =
97{
98#define OPTION_EB (OPTION_MD_BASE + 0)
99 {"EB", no_argument, NULL, OPTION_EB},
100#define OPTION_EL (OPTION_MD_BASE + 1)
101 {"EL", no_argument, NULL, OPTION_EL},
102 { NULL, no_argument, NULL, 0 }
103};
104size_t md_longopts_size = sizeof (md_longopts);
105
106/*
107 * md_parse_option
108 *
109 * Invocation line includes a switch not recognized by the base assembler.
110 * See if it's a processor-specific option.
111 */
112
113int
114md_parse_option (c, arg)
115 int c;
4a314ec8 116 char *arg ATTRIBUTE_UNUSED;
252b5132
RH
117{
118 switch (c)
119 {
120 case OPTION_EB:
121 byte_order = BIG_ENDIAN;
122 arc_target_format = "elf32-bigarc";
123 break;
124 case OPTION_EL:
125 byte_order = LITTLE_ENDIAN;
126 arc_target_format = "elf32-littlearc";
127 break;
128 default:
129 return 0;
130 }
131 return 1;
132}
133
134void
135md_show_usage (stream)
136 FILE *stream;
137{
138 fprintf (stream, _("\
139ARC options:\n\
140-EB generate big endian output\n\
141-EL generate little endian output\n"));
142}
143
144/* This function is called once, at assembler startup time. It should
145 set up all the tables, etc. that the MD part of the assembler will need.
146 Opcode selection is defered until later because we might see a .cpu
147 command. */
148
149void
150md_begin ()
151{
152 /* The endianness can be chosen "at the factory". */
153 target_big_endian = byte_order == BIG_ENDIAN;
154
155 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
156 as_warn (_("could not set architecture and machine"));
157
158 /* Assume the base cpu. This call is necessary because we need to
159 initialize `arc_operand_map' which may be needed before we see the
160 first insn. */
161 arc_opcode_init_tables (arc_get_opcode_mach (bfd_mach_arc_base,
162 target_big_endian));
163}
164
165/* Initialize the various opcode and operand tables.
166 MACH is one of bfd_mach_arc_xxx. */
167
168static void
169init_opcode_tables (mach)
170 int mach;
171{
4a314ec8 172 int i;
252b5132
RH
173 char *last;
174
175 if ((arc_suffix_hash = hash_new ()) == NULL)
176 as_fatal (_("virtual memory exhausted"));
177
178 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
179 as_warn (_("could not set architecture and machine"));
180
181 /* This initializes a few things in arc-opc.c that we need.
182 This must be called before the various arc_xxx_supported fns. */
183 arc_opcode_init_tables (arc_get_opcode_mach (mach, target_big_endian));
184
185 /* Only put the first entry of each equivalently named suffix in the
186 table. */
187 last = "";
188 for (i = 0; i < arc_suffixes_count; i++)
189 {
190 if (! arc_opval_supported (&arc_suffixes[i]))
191 continue;
192 if (strcmp (arc_suffixes[i].name, last) != 0)
193 hash_insert (arc_suffix_hash, arc_suffixes[i].name, (PTR) (arc_suffixes + i));
194 last = arc_suffixes[i].name;
195 }
196
197 /* Since registers don't have a prefix, we put them in the symbol table so
198 they can't be used as symbols. This also simplifies argument parsing as
199 we can let gas parse registers for us. The recorded register number is
200 the index in `arc_reg_names'. */
201 for (i = 0; i < arc_reg_names_count; i++)
202 {
203 if (! arc_opval_supported (&arc_reg_names[i]))
204 continue;
205 /* Use symbol_create here instead of symbol_new so we don't try to
206 output registers into the object file's symbol table. */
207 symbol_table_insert (symbol_create (arc_reg_names[i].name, reg_section,
208 i, &zero_address_frag));
209 }
210
211 /* Tell `s_cpu' it's too late. */
212 cpu_tables_init_p = 1;
213}
214\f
215/* Insert an operand value into an instruction.
216 If REG is non-NULL, it is a register number and ignore VAL. */
217
218static arc_insn
219arc_insert_operand (insn, operand, mods, reg, val, file, line)
220 arc_insn insn;
221 const struct arc_operand *operand;
222 int mods;
223 const struct arc_operand_value *reg;
224 offsetT val;
225 char *file;
226 unsigned int line;
227{
228 if (operand->bits != 32)
229 {
230 long min, max;
231 offsetT test;
232
233 if ((operand->flags & ARC_OPERAND_SIGNED) != 0)
234 {
235 if ((operand->flags & ARC_OPERAND_SIGNOPT) != 0)
236 max = (1 << operand->bits) - 1;
237 else
238 max = (1 << (operand->bits - 1)) - 1;
239 min = - (1 << (operand->bits - 1));
240 }
241 else
242 {
243 max = (1 << operand->bits) - 1;
244 min = 0;
245 }
246
247 if ((operand->flags & ARC_OPERAND_NEGATIVE) != 0)
248 test = - val;
249 else
250 test = val;
251
252 if (test < (offsetT) min || test > (offsetT) max)
253 {
254 const char *err =
255 _("operand out of range (%s not between %ld and %ld)");
256 char buf[100];
257
258 sprint_value (buf, test);
259 if (file == (char *) NULL)
260 as_warn (err, buf, min, max);
261 else
262 as_warn_where (file, line, err, buf, min, max);
263 }
264 }
265
266 if (operand->insert)
267 {
268 const char *errmsg;
269
270 errmsg = NULL;
271 insn = (*operand->insert) (insn, operand, mods, reg, (long) val, &errmsg);
272 if (errmsg != (const char *) NULL)
273 as_warn (errmsg);
274 }
275 else
276 insn |= (((long) val & ((1 << operand->bits) - 1))
277 << operand->shift);
278
279 return insn;
280}
281
282/* We need to keep a list of fixups. We can't simply generate them as
283 we go, because that would require us to first create the frag, and
284 that would screw up references to ``.''. */
285
286struct arc_fixup
287{
288 /* index into `arc_operands' */
289 int opindex;
290 expressionS exp;
291};
292
293#define MAX_FIXUPS 5
294
295#define MAX_SUFFIXES 5
296
297/* This routine is called for each instruction to be assembled. */
298
299void
300md_assemble (str)
301 char *str;
302{
303 const struct arc_opcode *opcode;
304 char *start;
305 arc_insn insn;
306 static int init_tables_p = 0;
307
308 /* Opcode table initialization is deferred until here because we have to
309 wait for a possible .cpu command. */
310 if (!init_tables_p)
311 {
312 init_opcode_tables (arc_mach_type);
313 init_tables_p = 1;
314 }
315
316 /* Skip leading white space. */
317 while (isspace (*str))
318 str++;
319
320 /* The instructions are stored in lists hashed by the first letter (though
321 we needn't care how they're hashed). Get the first in the list. */
322
323 opcode = arc_opcode_lookup_asm (str);
324
325 /* Keep looking until we find a match. */
326
327 start = str;
328 for ( ; opcode != NULL; opcode = ARC_OPCODE_NEXT_ASM (opcode))
329 {
330 int past_opcode_p, fc, num_suffixes;
331 char *syn;
332 struct arc_fixup fixups[MAX_FIXUPS];
333 /* Used as a sanity check. If we need a limm reloc, make sure we ask
334 for an extra 4 bytes from frag_more. */
335 int limm_reloc_p;
336 const struct arc_operand_value *insn_suffixes[MAX_SUFFIXES];
337
338 /* Is this opcode supported by the selected cpu? */
339 if (! arc_opcode_supported (opcode))
340 continue;
341
342 /* Scan the syntax string. If it doesn't match, try the next one. */
343
344 arc_opcode_init_insert ();
345 insn = opcode->value;
346 fc = 0;
347 past_opcode_p = 0;
348 num_suffixes = 0;
349 limm_reloc_p = 0;
350
351 /* We don't check for (*str != '\0') here because we want to parse
352 any trailing fake arguments in the syntax string. */
353 for (str = start, syn = opcode->syntax; *syn != '\0'; )
354 {
355 int mods;
356 const struct arc_operand *operand;
357
358 /* Non operand chars must match exactly. */
359 if (*syn != '%' || *++syn == '%')
360 {
361 /* Handle '+' specially as we want to allow "ld r0,[sp-4]". */
362 /* ??? The syntax has changed to [sp,-4]. */
363 if (0 && *syn == '+' && *str == '-')
364 {
365 /* Skip over syn's +, but leave str's - alone.
366 That makes the case identical to "ld r0,[sp+-4]". */
367 ++syn;
368 }
369 else if (*str == *syn)
370 {
371 if (*syn == ' ')
372 past_opcode_p = 1;
373 ++syn;
374 ++str;
375 }
376 else
377 break;
378 continue;
379 }
380
381 /* We have an operand. Pick out any modifiers. */
382 mods = 0;
4a314ec8 383 while (ARC_MOD_P (arc_operands[arc_operand_map[(int) *syn]].flags))
252b5132 384 {
4a314ec8 385 mods |= arc_operands[arc_operand_map[(int) *syn]].flags & ARC_MOD_BITS;
252b5132
RH
386 ++syn;
387 }
4a314ec8 388 operand = arc_operands + arc_operand_map[(int) *syn];
252b5132
RH
389 if (operand->fmt == 0)
390 as_fatal (_("unknown syntax format character `%c'"), *syn);
391
392 if (operand->flags & ARC_OPERAND_FAKE)
393 {
394 const char *errmsg = NULL;
395 if (operand->insert)
396 {
397 insn = (*operand->insert) (insn, operand, mods, NULL, 0, &errmsg);
398 /* If we get an error, go on to try the next insn. */
399 if (errmsg)
400 break;
401 }
402 ++syn;
403 }
404 /* Are we finished with suffixes? */
405 else if (!past_opcode_p)
406 {
407 int found;
408 char c;
409 char *s,*t;
410 const struct arc_operand_value *suf,*suffix,*suffix_end;
411
412 if (!(operand->flags & ARC_OPERAND_SUFFIX))
413 abort ();
414
415 /* If we're at a space in the input string, we want to skip the
416 remaining suffixes. There may be some fake ones though, so
417 just go on to try the next one. */
418 if (*str == ' ')
419 {
420 ++syn;
421 continue;
422 }
423
424 s = str;
425 if (mods & ARC_MOD_DOT)
426 {
427 if (*s != '.')
428 break;
429 ++s;
430 }
431 else
432 {
433 /* This can happen in "b.nd foo" and we're currently looking
434 for "%q" (ie: a condition code suffix). */
435 if (*s == '.')
436 {
437 ++syn;
438 continue;
439 }
440 }
441
442 /* Pick the suffix out and look it up via the hash table. */
443 for (t = s; *t && isalpha (*t); ++t)
444 continue;
445 c = *t;
446 *t = '\0';
447 suf = hash_find (arc_suffix_hash, s);
448 *t = c;
449 if (!suf)
450 {
451 /* This can happen in "blle foo" and we're currently using
452 the template "b%q%.n %j". The "bl" insn occurs later in
453 the table so "lle" isn't an illegal suffix. */
454 break;
455 }
456
457 /* Is it the right type? Note that the same character is used
458 several times, so we have to examine all of them. This is
459 relatively efficient as equivalent entries are kept
460 together. If it's not the right type, don't increment `str'
461 so we try the next one in the series. */
462 found = 0;
463 suffix_end = arc_suffixes + arc_suffixes_count;
464 for (suffix = suf;
465 suffix < suffix_end && strcmp (suffix->name, suf->name) == 0;
466 ++suffix)
467 {
468 if (arc_operands[suffix->type].fmt == *syn)
469 {
470 /* Insert the suffix's value into the insn. */
471 if (operand->insert)
472 insn = (*operand->insert) (insn, operand,
473 mods, NULL, suffix->value,
474 NULL);
475 else
476 insn |= suffix->value << operand->shift;
477
478 str = t;
479 found = 1;
480 break;
481 }
482 }
483 ++syn;
484 if (!found)
485 ; /* Wrong type. Just go on to try next insn entry. */
486 else
487 {
488 if (num_suffixes == MAX_SUFFIXES)
489 as_bad (_("too many suffixes"));
490 else
491 insn_suffixes[num_suffixes++] = suffix;
492 }
493 }
494 else
495 /* This is either a register or an expression of some kind. */
496 {
252b5132
RH
497 char *hold;
498 const struct arc_operand_value *reg = NULL;
499 long value = 0;
500 expressionS exp;
501
502 if (operand->flags & ARC_OPERAND_SUFFIX)
503 abort ();
504
505 /* Is there anything left to parse?
506 We don't check for this at the top because we want to parse
507 any trailing fake arguments in the syntax string. */
508 if (*str == '\0')
509 break;
510#if 0
511 /* Is this a syntax character? Eg: is there a '[' present when
512 there shouldn't be? */
513 if (!isalnum (*str)
514 /* '.' as in ".LLC0" */
515 && *str != '.'
516 /* '_' as in "_print" */
517 && *str != '_'
518 /* '-' as in "[fp,-4]" */
519 && *str != '-'
520 /* '%' as in "%ia(_func)" */
521 && *str != '%')
522 break;
523#endif
524
525 /* Parse the operand. */
526 hold = input_line_pointer;
527 input_line_pointer = str;
528 expression (&exp);
529 str = input_line_pointer;
530 input_line_pointer = hold;
531
532 if (exp.X_op == O_illegal)
533 as_bad (_("illegal operand"));
534 else if (exp.X_op == O_absent)
535 as_bad (_("missing operand"));
536 else if (exp.X_op == O_constant)
537 {
538 value = exp.X_add_number;
539 }
540 else if (exp.X_op == O_register)
541 {
542 reg = arc_reg_names + exp.X_add_number;
543 }
544 else
545 {
546 /* We need to generate a fixup for this expression. */
547 if (fc >= MAX_FIXUPS)
548 as_fatal (_("too many fixups"));
549 fixups[fc].exp = exp;
550
551 /* If this is a register constant (IE: one whose
552 register value gets stored as 61-63) then this
553 must be a limm. We don't support shimm relocs. */
554 /* ??? This bit could use some cleaning up.
555 Referencing the format chars like this goes
556 against style. */
557#define IS_REG_OPERAND(o) ((o) == 'a' || (o) == 'b' || (o) == 'c')
558 if (IS_REG_OPERAND (*syn))
559 {
560 const char *junk;
561
562 fixups[fc].opindex = arc_operand_map['L'];
563 limm_reloc_p = 1;
564 /* Tell insert_reg we need a limm. This is
565 needed because the value at this point is
566 zero, a shimm. */
567 /* ??? We need a cleaner interface than this. */
568 (*arc_operands[arc_operand_map['Q']].insert)
569 (insn, operand, mods, reg, 0L, &junk);
570 }
571 else
4a314ec8 572 fixups[fc].opindex = arc_operand_map[(int) *syn];
252b5132
RH
573 ++fc;
574 value = 0;
575 }
576
577 /* Insert the register or expression into the instruction. */
578 if (operand->insert)
579 {
580 const char *errmsg = NULL;
581 insn = (*operand->insert) (insn, operand, mods,
582 reg, (long) value, &errmsg);
583#if 0
584 if (errmsg != (const char *) NULL)
585 as_warn (errmsg);
586#endif
587 /* FIXME: We want to try shimm insns for limm ones. But if
588 the constant won't fit, we must go on to try the next
589 possibility. Where do we issue warnings for constants
590 that are too big then? At present, we'll flag the insn
591 as unrecognizable! Maybe have the "bad instruction"
592 error message include our `errmsg'? */
593 if (errmsg != (const char *) NULL)
594 break;
595 }
596 else
597 insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
598
599 ++syn;
600 }
601 }
602
603 /* If we're at the end of the syntax string, we're done. */
604 /* FIXME: try to move this to a separate function. */
605 if (*syn == '\0')
606 {
607 int i;
608 char *f;
609 long limm, limm_p;
610
611 /* For the moment we assume a valid `str' can only contain blanks
612 now. IE: We needn't try again with a longer version of the
613 insn and it is assumed that longer versions of insns appear
614 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
615
616 while (isspace (*str))
617 ++str;
618
619 if (*str != '\0')
620 as_bad (_("junk at end of line: `%s'"), str);
621
622 /* Is there a limm value? */
623 limm_p = arc_opcode_limm_p (&limm);
624
625 /* Perform various error and warning tests. */
626
627 {
628 static int in_delay_slot_p = 0;
629 static int prev_insn_needs_cc_nop_p = 0;
630 /* delay slot type seen */
631 int delay_slot_type = ARC_DELAY_NONE;
632 /* conditional execution flag seen */
633 int conditional = 0;
634 /* 1 if condition codes are being set */
635 int cc_set_p = 0;
636 /* 1 if conditional branch, including `b' "branch always" */
637 int cond_branch_p = opcode->flags & ARC_OPCODE_COND_BRANCH;
252b5132
RH
638
639 for (i = 0; i < num_suffixes; ++i)
640 {
641 switch (arc_operands[insn_suffixes[i]->type].fmt)
642 {
643 case 'n' :
644 delay_slot_type = insn_suffixes[i]->value;
645 break;
646 case 'q' :
647 conditional = insn_suffixes[i]->value;
648 break;
649 case 'f' :
650 cc_set_p = 1;
651 break;
652 }
653 }
654
655 /* Putting an insn with a limm value in a delay slot is supposed to
656 be legal, but let's warn the user anyway. Ditto for 8 byte
657 jumps with delay slots. */
658 if (in_delay_slot_p && limm_p)
659 as_warn (_("8 byte instruction in delay slot"));
660 if (delay_slot_type != ARC_DELAY_NONE && limm_p)
661 as_warn (_("8 byte jump instruction with delay slot"));
662 in_delay_slot_p = (delay_slot_type != ARC_DELAY_NONE) && !limm_p;
663
664 /* Warn when a conditional branch immediately follows a set of
665 the condition codes. Note that this needn't be done if the
666 insn that sets the condition codes uses a limm. */
667 if (cond_branch_p && conditional != 0 /* 0 = "always" */
668 && prev_insn_needs_cc_nop_p)
669 as_warn (_("conditional branch follows set of flags"));
670 prev_insn_needs_cc_nop_p = cc_set_p && !limm_p;
671 }
672
673 /* Write out the instruction.
674 It is important to fetch enough space in one call to `frag_more'.
675 We use (f - frag_now->fr_literal) to compute where we are and we
676 don't want frag_now to change between calls. */
677 if (limm_p)
678 {
679 f = frag_more (8);
680 md_number_to_chars (f, insn, 4);
681 md_number_to_chars (f + 4, limm, 4);
682 }
683 else if (limm_reloc_p)
684 {
685 /* We need a limm reloc, but the tables think we don't. */
686 abort ();
687 }
688 else
689 {
690 f = frag_more (4);
691 md_number_to_chars (f, insn, 4);
692 }
693
694 /* Create any fixups. */
695 for (i = 0; i < fc; ++i)
696 {
697 int op_type, reloc_type;
698 expressionS exptmp;
699 const struct arc_operand *operand;
700
701 /* Create a fixup for this operand.
702 At this point we do not use a bfd_reloc_code_real_type for
703 operands residing in the insn, but instead just use the
704 operand index. This lets us easily handle fixups for any
705 operand type, although that is admittedly not a very exciting
706 feature. We pick a BFD reloc type in md_apply_fix.
707
708 Limm values (4 byte immediate "constants") must be treated
709 normally because they're not part of the actual insn word
710 and thus the insertion routines don't handle them. */
711
712 if (arc_operands[fixups[i].opindex].flags & ARC_OPERAND_LIMM)
713 {
714 op_type = fixups[i].opindex;
715 /* FIXME: can we add this data to the operand table? */
716 if (op_type == arc_operand_map['L'])
717 reloc_type = BFD_RELOC_32;
718 else if (op_type == arc_operand_map['J'])
719 reloc_type = BFD_RELOC_ARC_B26;
720 else
721 abort ();
722 reloc_type = get_arc_exp_reloc_type (1, reloc_type,
723 &fixups[i].exp,
724 &exptmp);
725 }
726 else
727 {
728 op_type = get_arc_exp_reloc_type (0, fixups[i].opindex,
729 &fixups[i].exp, &exptmp);
730 reloc_type = op_type + (int) BFD_RELOC_UNUSED;
731 }
732 operand = &arc_operands[op_type];
733 fix_new_exp (frag_now,
734 ((f - frag_now->fr_literal)
735 + (operand->flags & ARC_OPERAND_LIMM ? 4 : 0)), 4,
736 &exptmp,
737 (operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0,
738 (bfd_reloc_code_real_type) reloc_type);
739 }
740
741 /* All done. */
742 return;
743 }
744
745 /* Try the next entry. */
746 }
747
748 as_bad (_("bad instruction `%s'"), start);
749}
750\f
751/* ??? This was copied from tc-sparc.c, I think. Is it necessary? */
752
753static void
754arc_common (ignore)
4a314ec8 755 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
756{
757 char *name;
758 char c;
759 char *p;
4a314ec8
NC
760 int temp;
761 unsigned int size;
252b5132
RH
762 symbolS *symbolP;
763
764 name = input_line_pointer;
765 c = get_symbol_end ();
766 /* just after name is now '\0' */
767 p = input_line_pointer;
768 *p = c;
769 SKIP_WHITESPACE ();
770 if (*input_line_pointer != ',')
771 {
772 as_bad (_("expected comma after symbol-name"));
773 ignore_rest_of_line ();
774 return;
775 }
776 input_line_pointer++; /* skip ',' */
777 if ((temp = get_absolute_expression ()) < 0)
778 {
779 as_bad (_(".COMMon length (%d.) <0! Ignored."), temp);
780 ignore_rest_of_line ();
781 return;
782 }
783 size = temp;
784 *p = 0;
785 symbolP = symbol_find_or_make (name);
786 *p = c;
787 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
788 {
789 as_bad (_("ignoring attempt to re-define symbol"));
790 ignore_rest_of_line ();
791 return;
792 }
793 if (S_GET_VALUE (symbolP) != 0)
794 {
795 if (S_GET_VALUE (symbolP) != size)
796 {
797 as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %d."),
798 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
799 }
800 }
7dcc9865 801 assert (symbol_get_frag (symbolP) == &zero_address_frag);
252b5132
RH
802 if (*input_line_pointer != ',')
803 {
804 as_bad (_("expected comma after common length"));
805 ignore_rest_of_line ();
806 return;
807 }
808 input_line_pointer++;
809 SKIP_WHITESPACE ();
810 if (*input_line_pointer != '"')
811 {
812 temp = get_absolute_expression ();
813 if (temp < 0)
814 {
815 temp = 0;
816 as_warn (_("Common alignment negative; 0 assumed"));
817 }
4a314ec8 818 if (S_IS_LOCAL(symbolP))
252b5132
RH
819 {
820 segT old_sec;
821 int old_subsec;
822 char *p;
823 int align;
824
252b5132
RH
825 old_sec = now_seg;
826 old_subsec = now_subseg;
827 align = temp;
828 record_alignment (bss_section, align);
829 subseg_set (bss_section, 0);
830 if (align)
831 frag_align (align, 0, 0);
832 if (S_GET_SEGMENT (symbolP) == bss_section)
7dcc9865
ILT
833 symbol_get_frag (symbolP)->fr_symbol = 0;
834 symbol_set_frag (symbolP, frag_now);
252b5132
RH
835 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
836 (offsetT) size, (char *) 0);
837 *p = 0;
838 S_SET_SEGMENT (symbolP, bss_section);
839 S_CLEAR_EXTERNAL (symbolP);
840 subseg_set (old_sec, old_subsec);
841 }
842 else
843 {
844 allocate_common:
845 S_SET_VALUE (symbolP, (valueT) size);
846 S_SET_ALIGN (symbolP, temp);
847 S_SET_EXTERNAL (symbolP);
848 S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
849 }
850 }
851 else
852 {
853 input_line_pointer++;
854 /* ??? Some say data, some say bss. */
855 if (strncmp (input_line_pointer, ".bss\"", 5)
856 && strncmp (input_line_pointer, ".data\"", 6))
857 {
858 input_line_pointer--;
859 goto bad_common_segment;
860 }
861 while (*input_line_pointer++ != '"')
862 ;
863 goto allocate_common;
864 }
865 demand_empty_rest_of_line ();
866 return;
867
868 {
869 bad_common_segment:
870 p = input_line_pointer;
871 while (*p && *p != '\n')
872 p++;
873 c = *p;
874 *p = '\0';
875 as_bad (_("bad .common segment %s"), input_line_pointer + 1);
876 *p = c;
877 input_line_pointer = p;
878 ignore_rest_of_line ();
879 return;
880 }
881}
882
883/* Select the cpu we're assembling for. */
884
885static void
886arc_cpu (ignore)
4a314ec8 887 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
888{
889 int mach;
890 char c;
891 char *cpu;
892
893 /* If an instruction has already been seen, it's too late. */
894 if (cpu_tables_init_p)
895 {
896 as_bad (_(".cpu command must appear before any instructions"));
897 ignore_rest_of_line ();
898 return;
899 }
900
901 cpu = input_line_pointer;
902 c = get_symbol_end ();
903 mach = arc_get_mach (cpu);
904 *input_line_pointer = c;
905 if (mach == -1)
906 goto bad_cpu;
907
908 demand_empty_rest_of_line ();
909
910 /* The cpu may have been selected on the command line.
911 The choices must match. */
912 /* ??? This was a command line option early on. It's gone now, but
913 leave this in. */
914 if (mach_type_specified_p && mach != arc_mach_type)
915 as_bad (_(".cpu conflicts with previous value"));
916 else
917 {
918 arc_mach_type = mach;
919 mach_type_specified_p = 1;
920 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
921 as_warn (_("could not set architecture and machine"));
922 }
923 return;
924
925 bad_cpu:
926 as_bad (_("bad .cpu op"));
927 ignore_rest_of_line ();
928}
929
930#if 0
931/* The .rename pseudo-op. This is used by gcc to implement
932 -mmangle-cpu-libgcc. */
933
934static void
935arc_rename (ignore)
936 int ignore;
937{
938 char *name,*new;
939 char c;
940 symbolS *sym;
941 int len;
942
943 name = input_line_pointer;
944 c = get_symbol_end ();
945 sym = symbol_find_or_make (name);
946 *input_line_pointer = c;
947
948 if (*input_line_pointer != ',')
949 {
950 as_bad (_("missing rename string"));
951 ignore_rest_of_line ();
952 return;
953 }
954 ++input_line_pointer;
955 SKIP_WHITESPACE ();
956
957 name = input_line_pointer;
958 c = get_symbol_end ();
959 if (*name == '\0')
960 {
961 *input_line_pointer = c;
962 as_bad (_("invalid symbol to rename to"));
963 ignore_rest_of_line ();
964 return;
965 }
966 new = (char *) xmalloc (strlen (name) + 1);
967 strcpy (new, name);
968 *input_line_pointer = c;
7dcc9865 969 symbol_get_tc (sym)->real_name = new;
252b5132
RH
970
971 demand_empty_rest_of_line ();
972}
973#endif
974\f
975/* Turn a string in input_line_pointer into a floating point constant of type
976 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
977 emitted is stored in *sizeP.
978 An error message is returned, or NULL on OK. */
979
980/* Equal to MAX_PRECISION in atof-ieee.c */
981#define MAX_LITTLENUMS 6
982
983char *
984md_atof (type, litP, sizeP)
985 char type;
986 char *litP;
987 int *sizeP;
988{
989 int prec;
990 LITTLENUM_TYPE words[MAX_LITTLENUMS];
991 LITTLENUM_TYPE *wordP;
992 char *t;
993 char *atof_ieee ();
994
995 switch (type)
996 {
997 case 'f':
998 case 'F':
999 prec = 2;
1000 break;
1001
1002 case 'd':
1003 case 'D':
1004 prec = 4;
1005 break;
1006
1007 default:
1008 *sizeP = 0;
1009 return _("bad call to md_atof");
1010 }
1011
1012 t = atof_ieee (input_line_pointer, type, words);
1013 if (t)
1014 input_line_pointer = t;
1015 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1016 for (wordP = words; prec--;)
1017 {
1018 md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
1019 litP += sizeof (LITTLENUM_TYPE);
1020 }
1021
1022 return NULL;
1023}
1024
1025/* Write a value out to the object file, using the appropriate
1026 endianness. */
1027
1028void
1029md_number_to_chars (buf, val, n)
1030 char *buf;
1031 valueT val;
1032 int n;
1033{
1034 if (target_big_endian)
1035 number_to_chars_bigendian (buf, val, n);
1036 else
1037 number_to_chars_littleendian (buf, val, n);
1038}
1039
1dab94dd 1040/* Round up a section size to the appropriate boundary. */
252b5132
RH
1041
1042valueT
1043md_section_align (segment, size)
1044 segT segment;
1045 valueT size;
1046{
1047 int align = bfd_get_section_alignment (stdoutput, segment);
1048
1049 return ((size + (1 << align) - 1) & (-1 << align));
1050}
1051
1052/* We don't have any form of relaxing. */
1053
1054int
1055md_estimate_size_before_relax (fragp, seg)
4a314ec8
NC
1056 fragS *fragp ATTRIBUTE_UNUSED;
1057 asection *seg ATTRIBUTE_UNUSED;
252b5132
RH
1058{
1059 abort ();
1060}
1061
1062/* Convert a machine dependent frag. We never generate these. */
1063
1064void
1065md_convert_frag (abfd, sec, fragp)
4a314ec8
NC
1066 bfd *abfd ATTRIBUTE_UNUSED;
1067 asection *sec ATTRIBUTE_UNUSED;
1068 fragS *fragp ATTRIBUTE_UNUSED;
252b5132
RH
1069{
1070 abort ();
1071}
1072
1073/* Parse an operand that is machine-specific.
1074
1075 The ARC has a special %-op to adjust addresses so they're usable in
1076 branches. The "st" is short for the STatus register.
1077 ??? Later expand this to take a flags value too.
1078
1079 ??? We can't create new expression types so we map the %-op's onto the
1080 existing syntax. This means that the user could use the chosen syntax
1081 to achieve the same effect. Perhaps put a special cookie in X_add_number
1082 to mark the expression as special. */
1083
1dab94dd 1084void
252b5132
RH
1085md_operand (expressionP)
1086 expressionS *expressionP;
1087{
1088 char *p = input_line_pointer;
1089
1090 if (*p == '%' && strncmp (p, "%st(", 4) == 0)
1091 {
1092 input_line_pointer += 4;
1093 expression (expressionP);
1094 if (*input_line_pointer != ')')
1095 {
1096 as_bad (_("missing ')' in %-op"));
1097 return;
1098 }
1099 ++input_line_pointer;
1100 if (expressionP->X_op == O_symbol
1101 && expressionP->X_add_number == 0
1dab94dd 1102 /* I think this test is unnecessary but just as a sanity check... */
252b5132
RH
1103 && expressionP->X_op_symbol == NULL)
1104 {
1105 expressionS two;
1106
1107 expressionP->X_op = O_right_shift;
1108 two.X_op = O_constant;
1109 two.X_add_symbol = two.X_op_symbol = NULL;
1110 two.X_add_number = 2;
1111 expressionP->X_op_symbol = make_expr_symbol (&two);
1112 }
1113 /* allow %st(sym1-sym2) */
1114 else if (expressionP->X_op == O_subtract
1115 && expressionP->X_add_symbol != NULL
1116 && expressionP->X_op_symbol != NULL
1117 && expressionP->X_add_number == 0)
1118 {
1119 expressionS two;
1120
1121 expressionP->X_add_symbol = make_expr_symbol (expressionP);
1122 expressionP->X_op = O_right_shift;
1123 two.X_op = O_constant;
1124 two.X_add_symbol = two.X_op_symbol = NULL;
1125 two.X_add_number = 2;
1126 expressionP->X_op_symbol = make_expr_symbol (&two);
1127 }
1128 else
1129 {
1130 as_bad (_("expression too complex for %%st"));
1131 return;
1132 }
1133 }
1134}
1135
1136/* We have no need to default values of symbols.
1137 We could catch register names here, but that is handled by inserting
1138 them all in the symbol table to begin with. */
1139
1140symbolS *
1141md_undefined_symbol (name)
4a314ec8 1142 char *name ATTRIBUTE_UNUSED;
252b5132
RH
1143{
1144 return 0;
1145}
1146\f
1147/* Functions concerning expressions. */
1148
1149/* Parse a .byte, .word, etc. expression.
1150
1151 Values for the status register are specified with %st(label).
1152 `label' will be right shifted by 2. */
1153
1154void
1155arc_parse_cons_expression (exp, nbytes)
1156 expressionS *exp;
4a314ec8 1157 int nbytes ATTRIBUTE_UNUSED;
252b5132
RH
1158{
1159 expr (0, exp);
1160}
1161
1162/* Record a fixup for a cons expression. */
1163
1164void
1165arc_cons_fix_new (frag, where, nbytes, exp)
1166 fragS *frag;
1167 int where;
1168 int nbytes;
1169 expressionS *exp;
1170{
1171 if (nbytes == 4)
1172 {
1173 int reloc_type;
1174 expressionS exptmp;
1175
1176 /* This may be a special ARC reloc (eg: %st()). */
1177 reloc_type = get_arc_exp_reloc_type (1, BFD_RELOC_32, exp, &exptmp);
1178 fix_new_exp (frag, where, nbytes, &exptmp, 0, reloc_type);
1179 }
1180 else
1181 {
1182 fix_new_exp (frag, where, nbytes, exp, 0,
1183 nbytes == 2 ? BFD_RELOC_16
1184 : nbytes == 8 ? BFD_RELOC_64
1185 : BFD_RELOC_32);
1186 }
1187}
1188\f
1189/* Functions concerning relocs. */
1190
1191/* The location from which a PC relative jump should be calculated,
1192 given a PC relative reloc. */
1193
1dab94dd 1194long
252b5132
RH
1195md_pcrel_from (fixP)
1196 fixS *fixP;
1197{
1198 if (fixP->fx_addsy != (symbolS *) NULL
1199 && ! S_IS_DEFINED (fixP->fx_addsy))
1200 {
1201 /* The symbol is undefined. Let the linker figure it out. */
1202 return 0;
1203 }
1204
1205 /* Return the address of the delay slot. */
1206 return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
1207}
1208
1209/* Compute the reloc type of an expression.
1210 The possibly modified expression is stored in EXPNEW.
1211
1212 This is used to convert the expressions generated by the %-op's into
1213 the appropriate operand type. It is called for both data in instructions
1214 (operands) and data outside instructions (variables, debugging info, etc.).
1215
1216 Currently supported %-ops:
1217
1218 %st(symbol): represented as "symbol >> 2"
1219 "st" is short for STatus as in the status register (pc)
1220
1221 DEFAULT_TYPE is the type to use if no special processing is required.
1222
1223 DATA_P is non-zero for data or limm values, zero for insn operands.
1224 Remember that the opcode "insertion fns" cannot be used on data, they're
1225 only for inserting operands into insns. They also can't be used for limm
1226 values as the insertion routines don't handle limm values. When called for
1227 insns we return fudged reloc types (real_value - BFD_RELOC_UNUSED). When
1228 called for data or limm values we use real reloc types. */
1229
1230static int
1231get_arc_exp_reloc_type (data_p, default_type, exp, expnew)
1232 int data_p;
1233 int default_type;
1234 expressionS *exp;
1235 expressionS *expnew;
1236{
1237 /* If the expression is "symbol >> 2" we must change it to just "symbol",
1238 as fix_new_exp can't handle it. Similarily for (symbol - symbol) >> 2.
1239 That's ok though. What's really going on here is that we're using
1240 ">> 2" as a special syntax for specifying BFD_RELOC_ARC_B26. */
1241
1242 if (exp->X_op == O_right_shift
1243 && exp->X_op_symbol != NULL
a77f5182
ILT
1244 && symbol_constant_p (exp->X_op_symbol)
1245 && S_GET_VALUE (exp->X_op_symbol) == 2
252b5132
RH
1246 && exp->X_add_number == 0)
1247 {
1248 if (exp->X_add_symbol != NULL
a77f5182
ILT
1249 && (symbol_constant_p (exp->X_add_symbol)
1250 || symbol_equated_p (exp->X_add_symbol)))
252b5132
RH
1251 {
1252 *expnew = *exp;
1253 expnew->X_op = O_symbol;
1254 expnew->X_op_symbol = NULL;
1255 return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
1256 }
1257 else if (exp->X_add_symbol != NULL
a77f5182
ILT
1258 && (symbol_get_value_expression (exp->X_add_symbol)->X_op
1259 == O_subtract))
252b5132 1260 {
a77f5182 1261 *expnew = *symbol_get_value_expression (exp->X_add_symbol);
252b5132
RH
1262 return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
1263 }
1264 }
1265
1266 *expnew = *exp;
1267 return default_type;
1268}
1269
1270/* Apply a fixup to the object code. This is called for all the
1271 fixups we generated by the call to fix_new_exp, above. In the call
1272 above we used a reloc code which was the largest legal reloc code
1273 plus the operand index. Here we undo that to recover the operand
1274 index. At this point all symbol values should be fully resolved,
1275 and we attempt to completely resolve the reloc. If we can not do
1276 that, we determine the correct reloc code and put it back in the fixup. */
1277
1278int
1279md_apply_fix3 (fixP, valueP, seg)
1280 fixS *fixP;
1281 valueT *valueP;
1282 segT seg;
1283{
1284 /*char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;*/
1285 valueT value;
1286
1287 /* FIXME FIXME FIXME: The value we are passed in *valueP includes
1288 the symbol values. Since we are using BFD_ASSEMBLER, if we are
1289 doing this relocation the code in write.c is going to call
1290 bfd_perform_relocation, which is also going to use the symbol
1291 value. That means that if the reloc is fully resolved we want to
1292 use *valueP since bfd_perform_relocation is not being used.
1293 However, if the reloc is not fully resolved we do not want to use
1294 *valueP, and must use fx_offset instead. However, if the reloc
1295 is PC relative, we do want to use *valueP since it includes the
1296 result of md_pcrel_from. This is confusing. */
1297
1298 if (fixP->fx_addsy == (symbolS *) NULL)
1299 {
1300 value = *valueP;
1301 fixP->fx_done = 1;
1302 }
1303 else if (fixP->fx_pcrel)
1304 {
1305 value = *valueP;
1306 /* ELF relocations are against symbols.
1307 If this symbol is in a different section then we need to leave it for
1308 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
1309 so we have to undo it's effects here. */
1310 if (S_IS_DEFINED (fixP->fx_addsy)
1311 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
1312 value += md_pcrel_from (fixP);
1313 }
1314 else
1315 {
1316 value = fixP->fx_offset;
1317 if (fixP->fx_subsy != (symbolS *) NULL)
1318 {
1319 if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)
1320 value -= S_GET_VALUE (fixP->fx_subsy);
1321 else
1322 {
1323 /* We can't actually support subtracting a symbol. */
1324 as_bad_where (fixP->fx_file, fixP->fx_line,
1325 _("expression too complex"));
1326 }
1327 }
1328 }
1329
1330 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
1331 {
1332 int opindex;
1333 const struct arc_operand *operand;
1334 char *where;
1335 arc_insn insn;
1336
1337 opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
1338
1339 operand = &arc_operands[opindex];
1340
1341 /* Fetch the instruction, insert the fully resolved operand
1342 value, and stuff the instruction back again. */
1343 where = fixP->fx_frag->fr_literal + fixP->fx_where;
1344 if (target_big_endian)
1345 insn = bfd_getb32 ((unsigned char *) where);
1346 else
1347 insn = bfd_getl32 ((unsigned char *) where);
1348 insn = arc_insert_operand (insn, operand, -1, NULL, (offsetT) value,
1349 fixP->fx_file, fixP->fx_line);
1350 if (target_big_endian)
1351 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1352 else
1353 bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
1354
1355 if (fixP->fx_done)
1356 {
1357 /* Nothing else to do here. */
1358 return 1;
1359 }
1360
1361 /* Determine a BFD reloc value based on the operand information.
1362 We are only prepared to turn a few of the operands into relocs.
1363 !!! Note that we can't handle limm values here. Since we're using
1364 implicit addends the addend must be inserted into the instruction,
1365 however, the opcode insertion routines currently do nothing with
1366 limm values. */
1367 if (operand->fmt == 'B')
1368 {
1369 assert ((operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0
1370 && operand->bits == 20
1371 && operand->shift == 7);
1372 fixP->fx_r_type = BFD_RELOC_ARC_B22_PCREL;
1373 }
1374 else if (0 && operand->fmt == 'J')
1375 {
1376 assert ((operand->flags & ARC_OPERAND_ABSOLUTE_BRANCH) != 0
1377 && operand->bits == 24
1378 && operand->shift == 32);
1379 fixP->fx_r_type = BFD_RELOC_ARC_B26;
1380 }
1381 else if (0 && operand->fmt == 'L')
1382 {
1383 assert ((operand->flags & ARC_OPERAND_LIMM) != 0
1384 && operand->bits == 32
1385 && operand->shift == 32);
1386 fixP->fx_r_type = BFD_RELOC_32;
1387 }
1388 else
1389 {
1390 as_bad_where (fixP->fx_file, fixP->fx_line,
1391 _("unresolved expression that must be resolved"));
1392 fixP->fx_done = 1;
1393 return 1;
1394 }
1395 }
1396 else
1397 {
1398 switch (fixP->fx_r_type)
1399 {
1400 case BFD_RELOC_8:
1401 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1402 value, 1);
1403 break;
1404 case BFD_RELOC_16:
1405 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1406 value, 2);
1407 break;
1408 case BFD_RELOC_32:
1409 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1410 value, 4);
1411 break;
1412#if 0
1413 case BFD_RELOC_64:
1414 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1415 value, 8);
1416 break;
1417#endif
1418 case BFD_RELOC_ARC_B26:
1419 /* If !fixP->fx_done then `value' is an implicit addend.
1420 We must shift it right by 2 in this case as well because the
1421 linker performs the relocation and then adds this in (as opposed
1422 to adding this in and then shifting right by 2). */
1423 value >>= 2;
1424 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1425 value, 4);
1426 break;
1427 default:
1428 abort ();
1429 }
1430 }
1431
1432 fixP->fx_addnumber = value;
1433
1434 return 1;
1435}
1436
1437/* Translate internal representation of relocation info to BFD target
1438 format. */
1439
1440arelent *
1441tc_gen_reloc (section, fixP)
4a314ec8 1442 asection *section ATTRIBUTE_UNUSED;
252b5132
RH
1443 fixS *fixP;
1444{
1445 arelent *reloc;
1446
1447 reloc = (arelent *) xmalloc (sizeof (arelent));
1448
310b5aa2
ILT
1449 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1450 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
252b5132
RH
1451 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1452 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
1453 if (reloc->howto == (reloc_howto_type *) NULL)
1454 {
1455 as_bad_where (fixP->fx_file, fixP->fx_line,
1456 _("internal error: can't export reloc type %d (`%s')"),
1457 fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
1458 return NULL;
1459 }
1460
1461 assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
1462
1463 reloc->addend = fixP->fx_addnumber;
1464
1465 return reloc;
1466}
1467\f
1468/* Frobbers. */
1469
1470#if 0
1471/* Set the real name if the .rename pseudo-op was used.
1472 Return 1 if the symbol should not be included in the symbol table. */
1473
1474int
1475arc_frob_symbol (sym)
1476 symbolS *sym;
1477{
7dcc9865
ILT
1478 if (symbol_get_tc (sym)->real_name != (char *) NULL)
1479 S_SET_NAME (sym, symbol_get_tc (sym)->real_name);
252b5132
RH
1480
1481 return 0;
1482}
1483#endif
This page took 0.117157 seconds and 4 git commands to generate.