1 /* tc-arc.c -- Assembler for the ARC
2 Copyright (C) 1994, 1995 Free Software Foundation, Inc.
3 Contributed by Doug Evans (dje@cygnus.com).
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
25 #include "opcode/arc.h"
28 extern int target_big_endian
;
29 extern int arc_get_mach
PARAMS ((char *));
31 static arc_insn arc_insert_operand
PARAMS ((arc_insn insn
,
32 const struct arc_operand
*operand
,
34 const struct arc_operand_value
*reg
,
36 char *file
, unsigned int line
));
38 static void arc_common
PARAMS ((int));
39 static void arc_cpu
PARAMS ((int));
40 /*static void arc_rename PARAMS ((int));*/
42 static int find_mach
PARAMS ((char *));
44 const pseudo_typeS md_pseudo_table
[] =
46 { "align", s_align_bytes
, 0 }, /* Defaulting is invalid (0) */
47 { "common", arc_common
, 0 },
48 /*{ "hword", cons, 2 }, - already exists */
51 { "cpu", arc_cpu
, 0 },
52 /*{ "rename", arc_rename, 0 },*/
56 const int md_short_jump_size
= 4;
57 const int md_long_jump_size
= 4;
58 const int md_reloc_size
= 12; /* Size of relocation record */
60 /* This array holds the chars that always start a comment. If the
61 pre-processor is disabled, these aren't very useful */
62 const char comment_chars
[] = "#;";
64 /* This array holds the chars that only start a comment at the beginning of
65 a line. If the line seems to have the form '# 123 filename'
66 .line and .file directives will appear in the pre-processed output */
67 /* Note that input_file.c hand checks for '#' at the beginning of the
68 first line of the input file. This is because the compiler outputs
69 #NO_APP at the beginning of its output. */
70 /* Also note that comments started like this one will always
71 work if '/' isn't otherwise defined. */
72 const char line_comment_chars
[] = "#";
74 const char line_separator_chars
[] = "";
76 /* Chars that can be used to separate mant from exp in floating point nums */
77 const char EXP_CHARS
[] = "eE";
79 /* Chars that mean this number is a floating point constant */
82 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
84 /* One of bfd_mach_arc_xxx. */
85 static int arc_mach_type
= bfd_mach_arc_base
;
87 /* Non-zero if the cpu type was specified on the command line. */
88 static int mach_type_specified
= 0;
90 /* Non-zero if opcode tables have been initialized.
91 A .cpu command must appear before any instructions. */
92 static int cpu_tables_init_p
= 0;
94 static const char *arc_condition_codes
[] =
96 "al", "eq", "ne", "p", "n", "c", "nc", "v",
97 "nv", "gt", "ge", "lt", "le", "hi", "ls", "pnz"
100 static struct hash_control
*arc_ops_hash
= NULL
;
101 static struct hash_control
*arc_suffix_hash
= NULL
;
102 static struct hash_control
*arc_reg_hash
= NULL
;
104 const char *md_shortopts
= "m:";
105 struct option md_longopts
[] =
107 { NULL
, no_argument
, NULL
, 0 }
109 size_t md_longopts_size
= sizeof (md_longopts
);
114 * Invocation line includes a switch not recognized by the base assembler.
115 * See if it's a processor-specific option.
119 md_parse_option (c
, arg
)
126 if (strncmp (arg
, "cpu=", 4) == 0)
128 int mach
= arc_get_mach (arg
+ 4);
132 arc_mach_type
= mach
;
133 mach_type_specified
= 1;
137 as_bad ("invalid architecture -m%s", arg
);
148 md_show_usage (stream
)
153 -mcpu={base,host,graphics,audio} select cpu type\n");
156 /* This function is called once, at assembler startup time. It should
157 set up all the tables, etc. that the MD part of the assembler will need.
158 Opcode selection is defered until later because we might see a .cpu
164 /* The endianness can be chosen "at the factory". One day we may have
166 target_big_endian
= 0;
168 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, arc_mach_type
))
169 as_warn ("could not set architecture and machine");
172 /* Initialize the various opcode and operand tables.
173 MACH is one of bfd_mach_arc_xxx. */
176 init_opcode_tables (mach
)
179 register unsigned int i
;
181 /* Indexed by bfd_mach_arc_xxx. */
182 static int cpu_type_map
[] =
190 if ((arc_ops_hash
= hash_new ()) == NULL
191 || (arc_suffix_hash
= hash_new ()) == NULL
192 || (arc_reg_hash
= hash_new ()) == NULL
)
193 as_fatal ("Virtual memory exhausted");
195 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, mach
))
196 as_warn ("could not set architecture and machine");
198 /* This initializes a few things in arc-opc.c that we need.
199 This must be called before the various arc_xxx_supported fns. */
200 arc_opcode_init_tables (cpu_type_map
[mach
]);
203 for (i
= 0; i
< arc_opcodes_count
; i
++)
204 hash_insert (arc_ops_hash
, arc_opcodes
[i
].name
, (PTR
) (arc_opcodes
+ i
));
207 /* Only put the first entry of each equivalently named suffix in the
210 for (i
= 0; i
< arc_suffixes_count
; i
++)
212 if (! arc_opval_supported (&arc_suffixes
[i
]))
214 if (strcmp (arc_suffixes
[i
].name
, last
) != 0)
215 hash_insert (arc_suffix_hash
, arc_suffixes
[i
].name
, (PTR
) (arc_suffixes
+ i
));
216 last
= arc_suffixes
[i
].name
;
219 /* ??? This is the simple version. See tc-arm.c for something snazzier. */
220 for (i
= 0; i
< arc_reg_names_count
; i
++)
222 if (! arc_opval_supported (&arc_reg_names
[i
]))
224 hash_insert (arc_reg_hash
, arc_reg_names
[i
].name
, (PTR
) (arc_reg_names
+ i
));
227 /* Tell `s_cpu' it's too late. */
228 cpu_tables_init_p
= 1;
231 /* Insert an operand value into an instruction.
232 If REG is non-NULL, it is a register number and ignore VAL. */
235 arc_insert_operand (insn
, operand
, mods
, reg
, val
, file
, line
)
237 const struct arc_operand
*operand
;
239 const struct arc_operand_value
*reg
;
244 if (operand
->bits
!= 32)
249 if ((operand
->flags
& ARC_OPERAND_SIGNED
) != 0)
251 if ((operand
->flags
& ARC_OPERAND_SIGNOPT
) != 0)
252 max
= (1 << operand
->bits
) - 1;
254 max
= (1 << (operand
->bits
- 1)) - 1;
255 min
= - (1 << (operand
->bits
- 1));
259 max
= (1 << operand
->bits
) - 1;
263 if ((operand
->flags
& ARC_OPERAND_NEGATIVE
) != 0)
268 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)
271 "operand out of range (%s not between %ld and %ld)";
274 sprint_value (buf
, test
);
275 if (file
== (char *) NULL
)
276 as_warn (err
, buf
, min
, max
);
278 as_warn_where (file
, line
, err
, buf
, min
, max
);
287 insn
= (*operand
->insert
) (insn
, operand
, mods
, reg
, (long) val
, &errmsg
);
288 if (errmsg
!= (const char *) NULL
)
292 insn
|= (((long) val
& ((1 << operand
->bits
) - 1))
298 /* We need to keep a list of fixups. We can't simply generate them as
299 we go, because that would require us to first create the frag, and
300 that would screw up references to ``.''. */
305 /* index into `arc_operands' */
309 #define MAX_INSN_FIXUPS 5
311 /* This routine is called for each instruction to be assembled. */
317 const struct arc_opcode
*opcode
,*opcode_end
;
320 bfd_reloc_code_real_type reloc
;
321 static int init_tables_p
= 0;
323 /* Opcode table initialization is deferred until here because we have to
324 wait for a possible .cpu command. */
327 init_opcode_tables (arc_mach_type
);
331 /* Skip leading white space. */
332 while (isspace (*str
))
335 /* The instructions are sorted by the first letter. Scan the opcode table
336 until we find the right one. */
337 opcode_end
= arc_opcodes
+ arc_opcodes_count
;
338 for (opcode
= arc_opcodes
; opcode
< opcode_end
; opcode
++)
339 if (*opcode
->syntax
== *str
)
341 if (opcode
== opcode_end
)
343 as_bad ("bad instruction `%s'", str
);
347 /* Keep looking until we find a match. If we haven't found a match, and the
348 first character no longer matches, we needn't look any further. */
351 for ( ; opcode
< opcode_end
&& *opcode
->syntax
== *start
; ++opcode
)
355 struct arc_fixup fixups
[MAX_INSN_FIXUPS
];
358 /* Is this opcode supported by the selected cpu? */
359 if (! arc_opcode_supported (opcode
))
362 /* Scan the syntax string. If it doesn't match, try the next one. */
364 arc_opcode_init_insert ();
365 insn
= opcode
->value
;
366 reloc
= BFD_RELOC_NONE
;
370 /* Used as a sanity check. If we need a limm reloc, make sure we ask
371 for an extra 4 bytes from frag_more. */
374 /* We don't check for (*str != '\0') here because we want to parse
375 any trailing fake arguments in the syntax string. */
376 for (str
= start
, syn
= opcode
->syntax
; *syn
!= '\0'; )
379 const struct arc_operand
*operand
;
381 /* Non operand chars must match exactly. */
382 if (*syn
!= '%' || *++syn
== '%')
384 /* Handle '+' specially as we want to allow "ld r0,[sp-4]". */
385 if (*syn
== '+' && *str
== '-')
387 /* Skip over syn's +, but leave str's - alone.
388 That makes the case identical to "ld r0,[sp+-4]". */
391 else if (*str
!= *syn
)
403 /* We have an operand. Pick out any modifiers. */
405 while (ARC_MOD_P (arc_operands
[arc_operand_map
[*syn
]].flags
))
407 mods
|= arc_operands
[arc_operand_map
[*syn
]].flags
& ARC_MOD_BITS
;
410 operand
= arc_operands
+ arc_operand_map
[*syn
];
411 if (operand
->fmt
== 0)
412 as_fatal ("unknown syntax format character `%c'", *syn
);
414 if (operand
->flags
& ARC_OPERAND_FAKE
)
416 const char *errmsg
= NULL
;
419 insn
= (*operand
->insert
) (insn
, operand
, mods
, NULL
, 0, &errmsg
);
420 /* If we get an error, go on to try the next insn. */
426 /* Are we finished with suffixes? */
427 else if (!past_opcode_p
)
432 const struct arc_operand_value
*suf
,*suffix
,*suffix_end
;
434 if (!(operand
->flags
& ARC_OPERAND_SUFFIX
))
437 /* If we're at a space in the input string, we want to skip the
438 remaining suffixes. There may be some fake ones though, so
439 just go on to try the next one. */
447 if (mods
& ARC_MOD_DOT
)
455 /* This can happen in "b.nd foo" and we're currently looking
456 for "%q" (ie: a condition code suffix). */
464 /* Pick the suffix out and look it up via the hash table. */
465 for (t
= s
; *t
&& isalpha (*t
); ++t
)
469 suf
= hash_find (arc_suffix_hash
, s
);
473 /* This can happen in "blle foo" and we're currently using
474 the template "b%q%.n %j". The "bl" insn occurs later in
475 the table so "lle" isn't an illegal suffix. */
479 /* Is it the right type? Note that the same character is used
480 several times, so we have to examine all of them. This is
481 relatively efficient as equivalent entries are kept
482 together. If it's not the right type, don't increment `str'
483 so we try the next one in the series. */
485 suffix_end
= arc_suffixes
+ arc_suffixes_count
;
487 suffix
< suffix_end
&& strcmp (suffix
->name
, suf
->name
) == 0;
490 if (arc_operands
[suffix
->type
].fmt
== *syn
)
492 /* Insert the suffix's value into the insn. */
494 insn
= (*operand
->insert
) (insn
, operand
,
495 mods
, NULL
, suffix
->value
,
498 insn
|= suffix
->value
<< operand
->shift
;
507 /* There's nothing to do except, go on to try the next one.
508 ??? This test can be deleted when we're done. */
512 /* This is either a register or an expression of some kind. */
516 const struct arc_operand_value
*reg
;
520 if (operand
->flags
& ARC_OPERAND_SUFFIX
)
523 /* Is there anything left to parse?
524 We don't check for this at the top because we want to parse
525 any trailing fake arguments in the syntax string. */
529 /* Is this a syntax character? Eg: is there a '[' present when
530 there shouldn't be? */
532 /* '.' as in ".LLC0" */
534 /* '_' as in "_print" */
536 /* '-' as in "[fp-4]" */
540 /* Is it a register? */
543 while (*str
&& (isalnum (*str
) || *str
== '_'))
547 reg
= hash_find (arc_reg_hash
, hold
);
551 /* Restore `str', it wasn't a register. */
554 /* Gather the operand. */
555 hold
= input_line_pointer
;
556 input_line_pointer
= str
;
558 str
= input_line_pointer
;
559 input_line_pointer
= hold
;
561 if (ex
.X_op
== O_illegal
)
562 as_bad ("illegal operand");
563 else if (ex
.X_op
== O_absent
)
564 as_bad ("missing operand");
565 else if (ex
.X_op
== O_constant
)
567 value
= ex
.X_add_number
;
571 /* We need to generate a fixup for this expression.
572 If this is a register constant (IE: one whose register
573 value gets stored as 61-63) then this must be a limm.
574 We don't support shimm relocs. */
575 if (fc
>= MAX_INSN_FIXUPS
)
576 as_fatal ("too many fixups");
579 /* ??? This bit could use some cleaning up. Referencing
580 the format chars like this goes against style. */
581 #define IS_REG_OPERAND(o) ((o) == 'a' || (o) == 'b' || (o) == 'c')
582 if (IS_REG_OPERAND (*syn
))
585 fixups
[fc
].opindex
= arc_operand_map
['L'];
587 /* Tell insert_reg we need a limm. This is needed
588 because the value at this point is zero, a shimm.
590 (*arc_operands
[arc_operand_map
['Q']].insert
)
591 (insn
, operand
, mods
, reg
, 0L, &junk
);
594 fixups
[fc
].opindex
= arc_operand_map
[*syn
];
600 /* Insert the register or expression into the instruction. */
603 const char *errmsg
= NULL
;
604 insn
= (*operand
->insert
) (insn
, operand
, mods
,
605 reg
, (long) value
, &errmsg
);
607 if (errmsg
!= (const char *) NULL
)
610 /* FIXME: We want to try shimm insns for limm ones. But if
611 the constant won't fit, we must go on to try the next
612 possibility. Where do we issue warnings for constants
613 that are too big then? At present, we'll flag the insn
614 as unrecognizable! Maybe have the "bad instruction"
615 error message include our `errmsg'? */
616 if (errmsg
!= (const char *) NULL
)
620 insn
|= (value
& ((1 << operand
->bits
) - 1)) << operand
->shift
;
632 /* We've found a matching insn.
633 ??? For the moment we assume a valid `str' can only contain blanks
634 now. IE: We needn't try again with a longer version of the
637 while (isspace (*str
))
641 as_bad ("junk at end of line: `%s'", str
);
643 /* Write out the instruction.
644 It is important to fetch enough space in one call to `frag_more'.
645 We use (f - frag_now->fr_literal) to compute where we are and we
646 don't want frag_now to change between calls. */
647 if (arc_opcode_limm_p (&limm
))
650 md_number_to_chars (f
, insn
, 4);
651 md_number_to_chars (f
+ 4, limm
, 4);
653 else if (limm_reloc_p
)
655 /* We need a limm reloc, but the tables think we don't. */
661 md_number_to_chars (f
, insn
, 4);
664 /* Create any fixups. At this point we do not use a
665 bfd_reloc_code_real_type, but instead just use the operand index.
666 This lets us easily handle fixups for any operand type, although
667 that is admittedly not a very exciting feature. We pick a BFD
668 reloc type in md_apply_fix. */
669 for (i
= 0; i
< fc
; i
++)
671 const struct arc_operand
*operand
;
673 operand
= &arc_operands
[fixups
[i
].opindex
];
674 fix_new_exp (frag_now
,
675 ((f
- frag_now
->fr_literal
)
676 + (operand
->fmt
== 'L' ? 4 : 0)), 4,
678 (operand
->flags
& ARC_OPERAND_RELATIVE
) != 0,
679 ((bfd_reloc_code_real_type
)
680 (fixups
[i
].opindex
+ (int) BFD_RELOC_UNUSED
)));
687 /* Try the next entry. */
690 as_bad ("bad instruction `%s'", start
);
703 name
= input_line_pointer
;
704 c
= get_symbol_end ();
705 /* just after name is now '\0' */
706 p
= input_line_pointer
;
709 if (*input_line_pointer
!= ',')
711 as_bad ("expected comma after symbol-name");
712 ignore_rest_of_line ();
715 input_line_pointer
++; /* skip ',' */
716 if ((temp
= get_absolute_expression ()) < 0)
718 as_bad (".COMMon length (%d.) <0! Ignored.", temp
);
719 ignore_rest_of_line ();
724 symbolP
= symbol_find_or_make (name
);
726 if (S_IS_DEFINED (symbolP
))
728 as_bad ("ignoring attempt to re-define symbol");
729 ignore_rest_of_line ();
732 if (S_GET_VALUE (symbolP
) != 0)
734 if (S_GET_VALUE (symbolP
) != size
)
736 as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
737 S_GET_NAME (symbolP
), (long) S_GET_VALUE (symbolP
), size
);
743 S_SET_VALUE (symbolP
, (valueT
) size
);
744 S_SET_EXTERNAL (symbolP
);
747 assert (symbolP
->sy_frag
== &zero_address_frag
);
748 if (*input_line_pointer
!= ',')
750 as_bad ("expected comma after common length");
751 ignore_rest_of_line ();
754 input_line_pointer
++;
756 if (*input_line_pointer
!= '"')
758 temp
= get_absolute_expression ();
760 if (temp
> max_alignment
)
762 temp
= max_alignment
;
763 as_warn ("Common alignment too large: %d. assumed", temp
);
769 as_warn ("Common alignment negative; 0 assumed");
781 old_subsec
= now_subseg
;
783 record_alignment (bss_section
, align
);
784 subseg_set (bss_section
, 0);
786 frag_align (align
, 0);
787 if (S_GET_SEGMENT (symbolP
) == bss_section
)
788 symbolP
->sy_frag
->fr_symbol
= 0;
789 symbolP
->sy_frag
= frag_now
;
790 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, size
,
793 S_SET_SEGMENT (symbolP
, bss_section
);
794 S_CLEAR_EXTERNAL (symbolP
);
795 subseg_set (old_sec
, old_subsec
);
801 S_SET_VALUE (symbolP
, (valueT
) size
);
803 S_SET_ALIGN (symbolP
, temp
);
805 S_SET_EXTERNAL (symbolP
);
806 /* should be common, but this is how gas does it for now */
807 S_SET_SEGMENT (symbolP
, bfd_und_section_ptr
);
812 input_line_pointer
++;
813 /* @@ Some use the dot, some don't. Can we get some consistency?? */
814 if (*input_line_pointer
== '.')
815 input_line_pointer
++;
816 /* @@ Some say data, some say bss. */
817 if (strncmp (input_line_pointer
, "bss\"", 4)
818 && strncmp (input_line_pointer
, "data\"", 5))
820 while (*--input_line_pointer
!= '"')
822 input_line_pointer
--;
823 goto bad_common_segment
;
825 while (*input_line_pointer
++ != '"')
827 goto allocate_common
;
829 demand_empty_rest_of_line ();
834 p
= input_line_pointer
;
835 while (*p
&& *p
!= '\n')
839 as_bad ("bad .common segment %s", input_line_pointer
+ 1);
841 input_line_pointer
= p
;
842 ignore_rest_of_line ();
847 /* Select the cpu we're assembling for. */
856 static int seen_p
= 0;
858 /* Allow only one .cpu. */
861 as_bad ("only one .cpu command allowed");
862 ignore_rest_of_line ();
867 /* If an instruction has already been seen, it's too late. */
868 if (cpu_tables_init_p
)
870 as_bad (".cpu command must appear before any instructions");
871 ignore_rest_of_line ();
875 cpu
= input_line_pointer
;
876 c
= get_symbol_end ();
877 mach
= arc_get_mach (cpu
);
878 *input_line_pointer
= c
;
882 /* Kind of overkill but what the heck. */
883 demand_empty_rest_of_line ();
885 /* The cpu may have been selected on the command line.
886 The choices must match. */
887 if (mach_type_specified
&& mach
!= arc_mach_type
)
888 as_bad (".cpu conflicts with -mcpu flag");
891 arc_mach_type
= mach
;
892 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, mach
))
893 as_warn ("could not set architecture and machine");
898 as_bad ("bad .cpu op");
899 ignore_rest_of_line ();
903 /* The .rename pseudo-op. This is used by gcc to implement
904 -mmangle-cpu-libgcc. */
915 name
= input_line_pointer
;
916 c
= get_symbol_end ();
917 sym
= symbol_find_or_make (name
);
918 *input_line_pointer
= c
;
920 if (*input_line_pointer
!= ',')
922 as_bad ("missing rename string");
923 ignore_rest_of_line ();
926 ++input_line_pointer
;
929 name
= input_line_pointer
;
930 c
= get_symbol_end ();
933 *input_line_pointer
= c
;
934 as_bad ("invalid symbol to rename to");
935 ignore_rest_of_line ();
938 new = (char *) xmalloc (strlen (name
) + 1);
940 *input_line_pointer
= c
;
941 sym
->sy_tc
.real_name
= new;
943 demand_empty_rest_of_line ();
947 /* Turn a string in input_line_pointer into a floating point constant of type
948 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
949 emitted is stored in *sizeP.
950 An error message is returned, or NULL on OK. */
952 /* Equal to MAX_PRECISION in atof-ieee.c */
953 #define MAX_LITTLENUMS 6
956 md_atof (type
, litP
, sizeP
)
962 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
963 LITTLENUM_TYPE
*wordP
;
981 return "bad call to md_atof";
984 t
= atof_ieee (input_line_pointer
, type
, words
);
986 input_line_pointer
= t
;
987 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
988 for (wordP
= words
; prec
--;)
990 md_number_to_chars (litP
, (valueT
) (*wordP
++), sizeof (LITTLENUM_TYPE
));
991 litP
+= sizeof (LITTLENUM_TYPE
);
997 /* Write a value out to the object file, using the appropriate
1001 md_number_to_chars (buf
, val
, n
)
1006 /* The ARC isn't bi-endian. Yet. */
1007 if (target_big_endian
)
1008 number_to_chars_bigendian (buf
, val
, n
);
1010 number_to_chars_littleendian (buf
, val
, n
);
1013 /* Round up a section size to the appropriate boundary. */
1016 md_section_align (segment
, size
)
1020 int align
= bfd_get_section_alignment (stdoutput
, segment
);
1022 return ((size
+ (1 << align
) - 1) & (-1 << align
));
1025 /* We don't have any form of relaxing. */
1028 md_estimate_size_before_relax (fragp
, seg
)
1035 const relax_typeS md_relax_table
[] =
1040 /* Convert a machine dependent frag. We never generate these. */
1043 md_convert_frag (abfd
, sec
, fragp
)
1051 /* Parse an operand that is machine-specific.
1052 We just return without modifying the expression if we have nothing to do. */
1056 md_operand (expressionP
)
1057 expressionS
*expressionP
;
1061 /* We have no need to default values of symbols. */
1065 md_undefined_symbol (name
)
1069 } /* md_undefined_symbol() */
1071 /* Functions concerning relocs. */
1073 /* The location from which a PC relative jump should be calculated,
1074 given a PC relative reloc. */
1077 md_pcrel_from (fixP
)
1080 if (fixP
->fx_addsy
!= (symbolS
*) NULL
1081 && ! S_IS_DEFINED (fixP
->fx_addsy
))
1082 /* Return offset from PC to delay slot. Offsets are from there. */
1085 /* Return the address of the delay slot. */
1086 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ fixP
->fx_size
;
1089 /* Apply a fixup to the object code. This is called for all the
1090 fixups we generated by the call to fix_new_exp, above. In the call
1091 above we used a reloc code which was the largest legal reloc code
1092 plus the operand index. Here we undo that to recover the operand
1093 index. At this point all symbol values should be fully resolved,
1094 and we attempt to completely resolve the reloc. If we can not do
1095 that, we determine the correct reloc code and put it back in the
1099 md_apply_fix (fixP
, valueP
)
1103 /*char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;*/
1106 /* FIXME FIXME FIXME: The value we are passed in *valueP includes
1107 the symbol values. Since we are using BFD_ASSEMBLER, if we are
1108 doing this relocation the code in write.c is going to call
1109 bfd_perform_relocation, which is also going to use the symbol
1110 value. That means that if the reloc is fully resolved we want to
1111 use *valueP since bfd_perform_relocation is not being used.
1112 However, if the reloc is not fully resolved we do not want to use
1113 *valueP, and must use fx_offset instead. However, if the reloc
1114 is PC relative, we do want to use *valueP since it includes the
1115 result of md_pcrel_from. This is confusing. */
1117 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
1122 else if (fixP
->fx_pcrel
)
1126 value
= fixP
->fx_offset
;
1127 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
1129 if (S_GET_SEGMENT (fixP
->fx_subsy
) == absolute_section
)
1130 value
-= S_GET_VALUE (fixP
->fx_subsy
);
1133 /* We can't actually support subtracting a symbol. */
1134 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1135 "expression too complex");
1140 if ((int) fixP
->fx_r_type
>= (int) BFD_RELOC_UNUSED
)
1143 const struct arc_operand
*operand
;
1147 opindex
= (int) fixP
->fx_r_type
- (int) BFD_RELOC_UNUSED
;
1149 operand
= &arc_operands
[opindex
];
1151 /* Fetch the instruction, insert the fully resolved operand
1152 value, and stuff the instruction back again. */
1153 where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1154 if (target_big_endian
)
1155 insn
= bfd_getb32 ((unsigned char *) where
);
1157 insn
= bfd_getl32 ((unsigned char *) where
);
1158 insn
= arc_insert_operand (insn
, operand
, -1, NULL
, (offsetT
) value
,
1159 fixP
->fx_file
, fixP
->fx_line
);
1160 if (target_big_endian
)
1161 bfd_putb32 ((bfd_vma
) insn
, (unsigned char *) where
);
1163 bfd_putl32 ((bfd_vma
) insn
, (unsigned char *) where
);
1167 /* Nothing else to do here. */
1171 /* Determine a BFD reloc value based on the operand information.
1172 We are only prepared to turn a few of the operands into relocs.
1173 FIXME: Selecting the reloc type is a bit haphazard; perhaps
1174 there should be a new field in the operand table. */
1175 if ((operand
->flags
& ARC_OPERAND_RELATIVE
) != 0
1176 && operand
->bits
== 20
1177 && operand
->shift
== 7)
1178 fixP
->fx_r_type
= BFD_RELOC_ARC_B22_PCREL
;
1179 else if ((operand
->flags
& ARC_OPERAND_ABSOLUTE
) != 0
1180 && operand
->bits
== 32
1181 && operand
->shift
== 32)
1182 fixP
->fx_r_type
= BFD_RELOC_32
;
1185 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1186 "unresolved expression that must be resolved");
1193 switch (fixP
->fx_r_type
)
1196 md_number_to_chars (fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
,
1200 md_number_to_chars (fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
,
1204 md_number_to_chars (fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
,
1213 fixP
->fx_addnumber
= value
;
1215 fixP
->fx_addnumber
= 0;
1221 /* Translate internal representation of relocation info to BFD target
1225 tc_gen_reloc (section
, fixP
)
1231 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
1233 reloc
->sym_ptr_ptr
= &fixP
->fx_addsy
->bsym
;
1234 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1235 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
1236 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
1238 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1239 "internal error: can't export reloc type %d (`%s')",
1240 fixP
->fx_r_type
, bfd_get_reloc_code_name (fixP
->fx_r_type
));
1243 reloc
->addend
= fixP
->fx_addnumber
;
1245 assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1253 /* Set the real name if the .rename pseudo-op was used.
1254 Return 1 if the symbol should not be included in the symbol table. */
1257 arc_frob_symbol (sym
)
1260 if (sym
->sy_tc
.real_name
!= (char *) NULL
)
1261 S_SET_NAME (sym
, sym
->sy_tc
.real_name
);