* Tidy.
[deliverable/binutils-gdb.git] / gas / config / tc-arc.c
CommitLineData
252b5132 1/* tc-arc.c -- Assembler for the ARC
0d2bcfaf 2 Copyright (C) 1994, 1995, 1997, 2000 Free Software Foundation, Inc.
252b5132
RH
3 Contributed by Doug Evans (dje@cygnus.com).
4
5 This file is part of GAS, the GNU Assembler.
6
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)
10 any later version.
11
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.
16
17 You should have received a copy of the GNU General Public License
0d2bcfaf
NC
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
252b5132
RH
20
21#include <stdio.h>
22#include <ctype.h>
0d2bcfaf 23#include "libiberty.h"
252b5132
RH
24#include "as.h"
25#include "subsegs.h"
26#include "opcode/arc.h"
0d2bcfaf 27#include "../opcodes/arc-ext.h"
252b5132
RH
28#include "elf/arc.h"
29
30extern int arc_get_mach PARAMS ((char *));
0d2bcfaf
NC
31extern int arc_operand_type PARAMS ((int));
32extern int arc_insn_not_jl PARAMS ((arc_insn));
33extern int arc_limm_fixup_adjust PARAMS ((arc_insn));
34extern int arc_get_noshortcut_flag PARAMS ((void));
35extern int arc_set_ext_seg PARAMS ((void));
36extern void arc_code_symbol PARAMS((expressionS *));
252b5132
RH
37
38static arc_insn arc_insert_operand PARAMS ((arc_insn,
39 const struct arc_operand *, int,
40 const struct arc_operand_value *,
41 offsetT, char *, unsigned int));
42static void arc_common PARAMS ((int));
0d2bcfaf
NC
43static void arc_extinst PARAMS ((int));
44static void arc_extoper PARAMS ((int));
45static void arc_option PARAMS ((int));
252b5132
RH
46static int get_arc_exp_reloc_type PARAMS ((int, int, expressionS *,
47 expressionS *));
48
0d2bcfaf
NC
49const struct suffix_classes {
50 char *name;
51 int len;
52} suffixclass[] = {
53 { "SUFFIX_COND|SUFFIX_FLAG",23 },
54 { "SUFFIX_FLAG", 11 },
55 { "SUFFIX_COND", 11 },
56 { "SUFFIX_NONE", 11 }
57};
58
bfb32b52 59#define MAXSUFFIXCLASS (sizeof (suffixclass) / sizeof (struct suffix_classes))
0d2bcfaf
NC
60
61const struct syntax_classes {
62 char *name;
63 int len;
64 int class;
65} syntaxclass[] = {
66 { "SYNTAX_3OP|OP1_MUST_BE_IMM", 26, SYNTAX_3OP|OP1_MUST_BE_IMM|SYNTAX_VALID },
67 { "OP1_MUST_BE_IMM|SYNTAX_3OP", 26, OP1_MUST_BE_IMM|SYNTAX_3OP|SYNTAX_VALID },
68 { "SYNTAX_2OP|OP1_IMM_IMPLIED", 26, SYNTAX_2OP|OP1_IMM_IMPLIED|SYNTAX_VALID },
69 { "OP1_IMM_IMPLIED|SYNTAX_2OP", 26, OP1_IMM_IMPLIED|SYNTAX_2OP|SYNTAX_VALID },
70 { "SYNTAX_3OP", 10, SYNTAX_3OP|SYNTAX_VALID },
71 { "SYNTAX_2OP", 10, SYNTAX_2OP|SYNTAX_VALID }
72};
73
bfb32b52 74#define MAXSYNTAXCLASS (sizeof (syntaxclass) / sizeof (struct syntax_classes))
0d2bcfaf 75
252b5132
RH
76const pseudo_typeS md_pseudo_table[] =
77{
0d2bcfaf
NC
78 { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0) */
79 { "comm", arc_common, 0 },
252b5132 80 { "common", arc_common, 0 },
0d2bcfaf
NC
81 { "lcomm", arc_common, 1 },
82 { "lcommon", arc_common, 1 },
83 { "2byte", cons, 2 },
84 { "half", cons, 2 },
85 { "short", cons, 2 },
86 { "3byte", cons, 3 },
87 { "4byte", cons, 4 },
252b5132 88 { "word", cons, 4 },
0d2bcfaf
NC
89 { "option", arc_option, 0 },
90 { "block", s_space, 0 },
91 { "extcondcode", arc_extoper, 0 },
92 { "extcoreregister", arc_extoper, 1 },
93 { "extauxregister", arc_extoper, 2 },
94 { "extinstruction", arc_extinst, 0 },
252b5132
RH
95 { NULL, 0, 0 },
96};
97
98/* This array holds the chars that always start a comment. If the
99 pre-processor is disabled, these aren't very useful */
100const char comment_chars[] = "#;";
101
102/* This array holds the chars that only start a comment at the beginning of
103 a line. If the line seems to have the form '# 123 filename'
104 .line and .file directives will appear in the pre-processed output */
105/* Note that input_file.c hand checks for '#' at the beginning of the
106 first line of the input file. This is because the compiler outputs
bfb32b52 107 #NO_APP at the beginning of its output. */
252b5132 108/* Also note that comments started like this one will always
bfb32b52 109 work if '/' isn't otherwise defined. */
252b5132
RH
110const char line_comment_chars[] = "#";
111
112const char line_separator_chars[] = "";
113
114/* Chars that can be used to separate mant from exp in floating point nums */
115const char EXP_CHARS[] = "eE";
116
117/* Chars that mean this number is a floating point constant */
118/* As in 0f12.456 */
119/* or 0d1.2345e12 */
120const char FLT_CHARS[] = "rRsSfFdD";
121
122/* Byte order. */
123extern int target_big_endian;
124const char *arc_target_format = DEFAULT_TARGET_FORMAT;
125static int byte_order = DEFAULT_BYTE_ORDER;
126
0d2bcfaf
NC
127static segT arcext_section;
128
129/* One of bfd_mach_arc_n. */
130static int arc_mach_type = bfd_mach_arc_5;
252b5132
RH
131
132/* Non-zero if the cpu type has been explicitly specified. */
133static int mach_type_specified_p = 0;
134
135/* Non-zero if opcode tables have been initialized.
136 A .cpu command must appear before any instructions. */
137static int cpu_tables_init_p = 0;
138
139static struct hash_control *arc_suffix_hash = NULL;
140\f
141const char *md_shortopts = "";
142struct option md_longopts[] =
143{
144#define OPTION_EB (OPTION_MD_BASE + 0)
145 {"EB", no_argument, NULL, OPTION_EB},
146#define OPTION_EL (OPTION_MD_BASE + 1)
147 {"EL", no_argument, NULL, OPTION_EL},
0d2bcfaf
NC
148#define OPTION_ARC5 (OPTION_MD_BASE + 2)
149 {"marc5", no_argument, NULL, OPTION_ARC5},
150#define OPTION_ARC6 (OPTION_MD_BASE + 3)
151 {"marc6", no_argument, NULL, OPTION_ARC6},
152#define OPTION_ARC7 (OPTION_MD_BASE + 4)
153 {"marc7", no_argument, NULL, OPTION_ARC7},
154#define OPTION_ARC8 (OPTION_MD_BASE + 5)
155 {"marc8", no_argument, NULL, OPTION_ARC8},
156#define OPTION_ARC (OPTION_MD_BASE + 6)
157 {"marc", no_argument, NULL, OPTION_ARC},
252b5132
RH
158 { NULL, no_argument, NULL, 0 }
159};
160size_t md_longopts_size = sizeof (md_longopts);
161
0d2bcfaf
NC
162#define IS_SYMBOL_OPERAND(o) \
163 ((o) == 'b' || (o) == 'c' || (o) == 's' || (o) == 'o' || (o) == 'O')
164
165struct arc_operand_value *get_ext_suffix(char *s);
166
252b5132
RH
167/*
168 * md_parse_option
169 *
170 * Invocation line includes a switch not recognized by the base assembler.
171 * See if it's a processor-specific option.
172 */
173
174int
175md_parse_option (c, arg)
176 int c;
4a314ec8 177 char *arg ATTRIBUTE_UNUSED;
252b5132
RH
178{
179 switch (c)
1e07b820 180 {
0d2bcfaf
NC
181 case OPTION_ARC:
182 case OPTION_ARC5:
183 arc_mach_type = bfd_mach_arc_5;
184 break;
185 case OPTION_ARC6:
186 arc_mach_type = bfd_mach_arc_6;
187 break;
188 case OPTION_ARC7:
189 arc_mach_type = bfd_mach_arc_7;
190 break;
191 case OPTION_ARC8:
192 arc_mach_type = bfd_mach_arc_8;
193 break;
252b5132
RH
194 case OPTION_EB:
195 byte_order = BIG_ENDIAN;
196 arc_target_format = "elf32-bigarc";
197 break;
198 case OPTION_EL:
199 byte_order = LITTLE_ENDIAN;
200 arc_target_format = "elf32-littlearc";
201 break;
202 default:
203 return 0;
1e07b820 204 }
252b5132
RH
205 return 1;
206}
207
208void
209md_show_usage (stream)
210 FILE *stream;
211{
0d2bcfaf
NC
212 fprintf (stream, "\
213ARC Options:\n\
214 -marc[5|6|7|8] select processor variant (default arc%d)\n\
215 -EB assemble code for a big endian cpu\n\
216 -EL assemble code for a little endian cpu\n", arc_mach_type + 5);
252b5132
RH
217}
218
219/* This function is called once, at assembler startup time. It should
220 set up all the tables, etc. that the MD part of the assembler will need.
221 Opcode selection is defered until later because we might see a .cpu
222 command. */
223
224void
225md_begin ()
226{
227 /* The endianness can be chosen "at the factory". */
228 target_big_endian = byte_order == BIG_ENDIAN;
229
230 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
0d2bcfaf 231 as_warn ("could not set architecture and machine");
252b5132 232
0d2bcfaf 233 /* This call is necessary because we need to
252b5132
RH
234 initialize `arc_operand_map' which may be needed before we see the
235 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. */
242
243static void
244init_opcode_tables (mach)
245 int mach;
246{
4a314ec8 247 int i;
252b5132
RH
248 char *last;
249
250 if ((arc_suffix_hash = hash_new ()) == NULL)
0d2bcfaf 251 as_fatal ("virtual memory exhausted");
252b5132
RH
252
253 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
0d2bcfaf 254 as_warn ("could not set architecture and machine");
252b5132
RH
255
256 /* This initializes a few things in arc-opc.c that we need.
257 This must be called before the various arc_xxx_supported fns. */
258 arc_opcode_init_tables (arc_get_opcode_mach (mach, target_big_endian));
259
260 /* Only put the first entry of each equivalently named suffix in the
261 table. */
262 last = "";
263 for (i = 0; i < arc_suffixes_count; i++)
264 {
252b5132
RH
265 if (strcmp (arc_suffixes[i].name, last) != 0)
266 hash_insert (arc_suffix_hash, arc_suffixes[i].name, (PTR) (arc_suffixes + i));
267 last = arc_suffixes[i].name;
268 }
269
270 /* Since registers don't have a prefix, we put them in the symbol table so
271 they can't be used as symbols. This also simplifies argument parsing as
272 we can let gas parse registers for us. The recorded register number is
0d2bcfaf
NC
273 the address of the register's entry in arc_reg_names.
274
275 If the register name is already in the table, then the existing
276 definition is assumed to be from an .ExtCoreRegister pseudo-op. */
277
252b5132
RH
278 for (i = 0; i < arc_reg_names_count; i++)
279 {
0d2bcfaf 280 if (symbol_find(arc_reg_names[i].name))
252b5132
RH
281 continue;
282 /* Use symbol_create here instead of symbol_new so we don't try to
283 output registers into the object file's symbol table. */
284 symbol_table_insert (symbol_create (arc_reg_names[i].name, reg_section,
0d2bcfaf 285 (int) &arc_reg_names[i], &zero_address_frag));
252b5132
RH
286 }
287
0d2bcfaf 288 /* Tell `.option' it's too late. */
252b5132
RH
289 cpu_tables_init_p = 1;
290}
291\f
292/* Insert an operand value into an instruction.
293 If REG is non-NULL, it is a register number and ignore VAL. */
294
295static arc_insn
296arc_insert_operand (insn, operand, mods, reg, val, file, line)
297 arc_insn insn;
298 const struct arc_operand *operand;
299 int mods;
300 const struct arc_operand_value *reg;
301 offsetT val;
302 char *file;
303 unsigned int line;
304{
305 if (operand->bits != 32)
306 {
307 long min, max;
308 offsetT test;
309
310 if ((operand->flags & ARC_OPERAND_SIGNED) != 0)
311 {
312 if ((operand->flags & ARC_OPERAND_SIGNOPT) != 0)
313 max = (1 << operand->bits) - 1;
314 else
315 max = (1 << (operand->bits - 1)) - 1;
316 min = - (1 << (operand->bits - 1));
317 }
318 else
319 {
320 max = (1 << operand->bits) - 1;
321 min = 0;
322 }
323
324 if ((operand->flags & ARC_OPERAND_NEGATIVE) != 0)
325 test = - val;
326 else
327 test = val;
328
329 if (test < (offsetT) min || test > (offsetT) max)
330 {
331 const char *err =
0d2bcfaf 332 "operand out of range (%s not between %ld and %ld)";
252b5132
RH
333 char buf[100];
334
335 sprint_value (buf, test);
336 if (file == (char *) NULL)
337 as_warn (err, buf, min, max);
338 else
339 as_warn_where (file, line, err, buf, min, max);
340 }
341 }
342
343 if (operand->insert)
344 {
345 const char *errmsg;
346
347 errmsg = NULL;
348 insn = (*operand->insert) (insn, operand, mods, reg, (long) val, &errmsg);
349 if (errmsg != (const char *) NULL)
350 as_warn (errmsg);
351 }
352 else
353 insn |= (((long) val & ((1 << operand->bits) - 1))
354 << operand->shift);
355
356 return insn;
357}
358
359/* We need to keep a list of fixups. We can't simply generate them as
360 we go, because that would require us to first create the frag, and
361 that would screw up references to ``.''. */
362
363struct arc_fixup
364{
365 /* index into `arc_operands' */
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
389 wait for a possible .cpu command. */
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. */
397 while (isspace (*str))
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;
0d2bcfaf
NC
409 for (opcode = (ext_opcode ? ext_opcode : std_opcode) ;
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. */
441 for (str = start, syn = opcode->syntax; *syn != '\0'; )
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 }
0d2bcfaf 498 if(limm_reloc_p
1e07b820
KH
499 && (operand->flags && operand->flags & ARC_OPERAND_LIMM)
500 && (operand->flags &
501 (ARC_OPERAND_ABSOLUTE_BRANCH | ARC_OPERAND_ADDRESS)))
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;
513 char *s,*t;
0d2bcfaf
NC
514 const struct arc_operand_value *suf,*suffix_end;
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. */
0d2bcfaf 548 for (t = s; *t && isalnum (*t); ++t)
252b5132
RH
549 continue;
550 c = *t;
551 *t = '\0';
1e07b820
KH
552 if ((suf = get_ext_suffix(s)))
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)
611 ; /* Wrong type. Just go on to try next insn entry. */
612 else
613 {
614 if (num_suffixes == MAX_SUFFIXES)
0d2bcfaf 615 as_bad ("too many suffixes");
252b5132
RH
616 else
617 insn_suffixes[num_suffixes++] = suffix;
618 }
619 }
620 else
621 /* This is either a register or an expression of some kind. */
622 {
252b5132
RH
623 char *hold;
624 const struct arc_operand_value *reg = NULL;
625 long value = 0;
626 expressionS exp;
627
628 if (operand->flags & ARC_OPERAND_SUFFIX)
629 abort ();
630
631 /* Is there anything left to parse?
632 We don't check for this at the top because we want to parse
633 any trailing fake arguments in the syntax string. */
634 if (*str == '\0')
635 break;
252b5132
RH
636
637 /* Parse the operand. */
638 hold = input_line_pointer;
639 input_line_pointer = str;
640 expression (&exp);
641 str = input_line_pointer;
642 input_line_pointer = hold;
643
644 if (exp.X_op == O_illegal)
0d2bcfaf 645 as_bad ("illegal operand");
252b5132 646 else if (exp.X_op == O_absent)
0d2bcfaf 647 as_bad ("missing operand");
252b5132
RH
648 else if (exp.X_op == O_constant)
649 {
650 value = exp.X_add_number;
651 }
652 else if (exp.X_op == O_register)
653 {
0d2bcfaf 654 reg = (struct arc_operand_value *) exp.X_add_number;
252b5132 655 }
0d2bcfaf
NC
656#define IS_REG_DEST_OPERAND(o) ((o) == 'a')
657 else if (IS_REG_DEST_OPERAND (*syn))
1e07b820
KH
658 as_bad("symbol as destination register");
659 else
252b5132 660 {
1e07b820
KH
661 if(!strncmp(str,"@h30",4))
662 {
663 arc_code_symbol(&exp);
664 str += 4;
665 }
252b5132
RH
666 /* We need to generate a fixup for this expression. */
667 if (fc >= MAX_FIXUPS)
0d2bcfaf 668 as_fatal ("too many fixups");
252b5132 669 fixups[fc].exp = exp;
1e07b820
KH
670 /* We don't support shimm relocs. break here to force
671 the assembler to output a limm */
0d2bcfaf 672#define IS_REG_SHIMM_OFFSET(o) ((o) == 'd')
1e07b820
KH
673 if(IS_REG_SHIMM_OFFSET(*syn))
674 break;
252b5132
RH
675 /* If this is a register constant (IE: one whose
676 register value gets stored as 61-63) then this
bfb32b52 677 must be a limm. */
252b5132
RH
678 /* ??? This bit could use some cleaning up.
679 Referencing the format chars like this goes
680 against style. */
0d2bcfaf 681 if (IS_SYMBOL_OPERAND (*syn))
252b5132
RH
682 {
683 const char *junk;
252b5132 684 limm_reloc_p = 1;
1e07b820
KH
685 /* save this, we don't yet know what reloc to use */
686 fix_up_at = fc;
252b5132
RH
687 /* Tell insert_reg we need a limm. This is
688 needed because the value at this point is
689 zero, a shimm. */
690 /* ??? We need a cleaner interface than this. */
691 (*arc_operands[arc_operand_map['Q']].insert)
692 (insn, operand, mods, reg, 0L, &junk);
693 }
694 else
4a314ec8 695 fixups[fc].opindex = arc_operand_map[(int) *syn];
252b5132
RH
696 ++fc;
697 value = 0;
698 }
699
700 /* Insert the register or expression into the instruction. */
701 if (operand->insert)
702 {
703 const char *errmsg = NULL;
704 insn = (*operand->insert) (insn, operand, mods,
705 reg, (long) value, &errmsg);
1e07b820
KH
706 if (errmsg != (const char *) NULL)
707 {
708 last_errmsg = errmsg;
709 if (operand->flags & ARC_OPERAND_ERROR)
710 {
711 as_bad (errmsg);
712 return;
713 }
714 else if (operand->flags & ARC_OPERAND_WARN)
715 as_warn (errmsg);
716 break;
717 }
252b5132
RH
718 }
719 else
720 insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
721
722 ++syn;
723 }
724 }
725
726 /* If we're at the end of the syntax string, we're done. */
727 /* FIXME: try to move this to a separate function. */
728 if (*syn == '\0')
729 {
730 int i;
731 char *f;
732 long limm, limm_p;
733
734 /* For the moment we assume a valid `str' can only contain blanks
735 now. IE: We needn't try again with a longer version of the
736 insn and it is assumed that longer versions of insns appear
737 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
738
739 while (isspace (*str))
740 ++str;
741
742 if (*str != '\0')
0d2bcfaf 743 as_bad ("junk at end of line: `%s'", str);
252b5132
RH
744
745 /* Is there a limm value? */
746 limm_p = arc_opcode_limm_p (&limm);
747
748 /* Perform various error and warning tests. */
749
750 {
751 static int in_delay_slot_p = 0;
752 static int prev_insn_needs_cc_nop_p = 0;
753 /* delay slot type seen */
754 int delay_slot_type = ARC_DELAY_NONE;
755 /* conditional execution flag seen */
756 int conditional = 0;
757 /* 1 if condition codes are being set */
758 int cc_set_p = 0;
759 /* 1 if conditional branch, including `b' "branch always" */
760 int cond_branch_p = opcode->flags & ARC_OPCODE_COND_BRANCH;
252b5132
RH
761
762 for (i = 0; i < num_suffixes; ++i)
763 {
764 switch (arc_operands[insn_suffixes[i]->type].fmt)
765 {
766 case 'n' :
767 delay_slot_type = insn_suffixes[i]->value;
768 break;
769 case 'q' :
770 conditional = insn_suffixes[i]->value;
771 break;
772 case 'f' :
773 cc_set_p = 1;
774 break;
775 }
776 }
777
778 /* Putting an insn with a limm value in a delay slot is supposed to
779 be legal, but let's warn the user anyway. Ditto for 8 byte
780 jumps with delay slots. */
781 if (in_delay_slot_p && limm_p)
1e07b820 782 as_warn ("8 byte instruction in delay slot");
0d2bcfaf
NC
783 if (delay_slot_type != ARC_DELAY_NONE
784 && limm_p && arc_insn_not_jl(insn)) /* except for jl addr */
1e07b820 785 as_warn ("8 byte jump instruction with delay slot");
252b5132
RH
786 in_delay_slot_p = (delay_slot_type != ARC_DELAY_NONE) && !limm_p;
787
788 /* Warn when a conditional branch immediately follows a set of
789 the condition codes. Note that this needn't be done if the
790 insn that sets the condition codes uses a limm. */
791 if (cond_branch_p && conditional != 0 /* 0 = "always" */
0d2bcfaf 792 && prev_insn_needs_cc_nop_p && arc_mach_type == bfd_mach_arc_5)
1e07b820 793 as_warn ("conditional branch follows set of flags");
0d2bcfaf 794 prev_insn_needs_cc_nop_p =
1e07b820
KH
795 /* FIXME: ??? not required:
796 (delay_slot_type != ARC_DELAY_NONE) && */
797 cc_set_p && !limm_p;
252b5132
RH
798 }
799
800 /* Write out the instruction.
801 It is important to fetch enough space in one call to `frag_more'.
802 We use (f - frag_now->fr_literal) to compute where we are and we
803 don't want frag_now to change between calls. */
804 if (limm_p)
805 {
806 f = frag_more (8);
807 md_number_to_chars (f, insn, 4);
808 md_number_to_chars (f + 4, limm, 4);
809 }
810 else if (limm_reloc_p)
811 {
812 /* We need a limm reloc, but the tables think we don't. */
813 abort ();
814 }
815 else
816 {
817 f = frag_more (4);
818 md_number_to_chars (f, insn, 4);
819 }
820
821 /* Create any fixups. */
822 for (i = 0; i < fc; ++i)
823 {
824 int op_type, reloc_type;
825 expressionS exptmp;
826 const struct arc_operand *operand;
827
828 /* Create a fixup for this operand.
829 At this point we do not use a bfd_reloc_code_real_type for
830 operands residing in the insn, but instead just use the
831 operand index. This lets us easily handle fixups for any
832 operand type, although that is admittedly not a very exciting
833 feature. We pick a BFD reloc type in md_apply_fix.
834
835 Limm values (4 byte immediate "constants") must be treated
836 normally because they're not part of the actual insn word
837 and thus the insertion routines don't handle them. */
838
839 if (arc_operands[fixups[i].opindex].flags & ARC_OPERAND_LIMM)
840 {
1e07b820
KH
841 /* modify the fixup addend as required by the cpu */
842 fixups[i].exp.X_add_number += arc_limm_fixup_adjust(insn);
252b5132
RH
843 op_type = fixups[i].opindex;
844 /* FIXME: can we add this data to the operand table? */
0d2bcfaf 845 if (op_type == arc_operand_map['L']
1e07b820
KH
846 || op_type == arc_operand_map['s']
847 || op_type == arc_operand_map['o']
848 || op_type == arc_operand_map['O'])
252b5132
RH
849 reloc_type = BFD_RELOC_32;
850 else if (op_type == arc_operand_map['J'])
851 reloc_type = BFD_RELOC_ARC_B26;
852 else
853 abort ();
854 reloc_type = get_arc_exp_reloc_type (1, reloc_type,
855 &fixups[i].exp,
856 &exptmp);
857 }
858 else
859 {
860 op_type = get_arc_exp_reloc_type (0, fixups[i].opindex,
861 &fixups[i].exp, &exptmp);
862 reloc_type = op_type + (int) BFD_RELOC_UNUSED;
863 }
864 operand = &arc_operands[op_type];
865 fix_new_exp (frag_now,
866 ((f - frag_now->fr_literal)
867 + (operand->flags & ARC_OPERAND_LIMM ? 4 : 0)), 4,
868 &exptmp,
869 (operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0,
870 (bfd_reloc_code_real_type) reloc_type);
871 }
872
873 /* All done. */
874 return;
875 }
876
877 /* Try the next entry. */
878 }
879
0d2bcfaf
NC
880 if(NULL == last_errmsg)
881 as_bad ("bad instruction `%s'", start);
882 else
883 as_bad (last_errmsg);
252b5132 884}
0d2bcfaf 885
252b5132 886\f
252b5132
RH
887
888static void
0d2bcfaf
NC
889arc_extoper (opertype)
890 int opertype;
252b5132
RH
891{
892 char *name;
0d2bcfaf 893 char *mode;
252b5132
RH
894 char c;
895 char *p;
0d2bcfaf
NC
896 int imode = 0;
897 int number;
898 struct arc_ext_operand_value *ext_oper;
252b5132
RH
899 symbolS *symbolP;
900
0d2bcfaf
NC
901 segT old_sec;
902 int old_subsec;
903
252b5132
RH
904 name = input_line_pointer;
905 c = get_symbol_end ();
0d2bcfaf
NC
906 name = xstrdup(name);
907 if (NULL == name)
908 {
1e07b820
KH
909 ignore_rest_of_line();
910 return;
0d2bcfaf
NC
911 }
912
913 p = name;
914 while (*p)
915 {
1e07b820
KH
916 if (isupper(*p))
917 *p = tolower(*p);
918 p++;
0d2bcfaf
NC
919 }
920
252b5132
RH
921 /* just after name is now '\0' */
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 ();
0d2bcfaf 930 free(name);
252b5132
RH
931 return;
932 }
0d2bcfaf 933
252b5132 934 input_line_pointer++; /* skip ',' */
0d2bcfaf
NC
935 number = get_absolute_expression ();
936
937 if(number < 0)
938 {
1e07b820
KH
939 as_bad ("negative operand number %d",number);
940 ignore_rest_of_line();
941 free(name);
942 return;
0d2bcfaf
NC
943 }
944
945 if (opertype)
946 {
947 SKIP_WHITESPACE();
948
949 if (*input_line_pointer != ',')
1e07b820
KH
950 {
951 as_bad ("expected comma after register-number");
952 ignore_rest_of_line ();
953 free(name);
954 return;
955 }
bfb32b52 956
0d2bcfaf
NC
957 input_line_pointer++; /* skip ',' */
958 mode = input_line_pointer;
bfb32b52 959
0d2bcfaf 960 if (!strncmp(mode, "r|w",3))
1e07b820
KH
961 {
962 imode = 0;
963 input_line_pointer += 3;
964 }
0d2bcfaf 965 else
1e07b820
KH
966 {
967 if (!strncmp(mode,"r",1))
968 {
969 imode = ARC_REGISTER_READONLY;
970 input_line_pointer += 1;
971 }
972 else
973 {
974 if (strncmp(mode,"w",1))
975 {
976 as_bad ("invalid mode");
977 ignore_rest_of_line();
978 free(name);
979 return;
980 }
981 else
982 {
983 imode = ARC_REGISTER_WRITEONLY;
984 input_line_pointer += 1;
985 }
986 }
987 }
988 SKIP_WHITESPACE();
989 if (1 == opertype)
990 {
991 if (*input_line_pointer != ',')
992 {
993 as_bad ("expected comma after register-mode");
994 ignore_rest_of_line ();
995 free(name);
996 return;
997 }
998
999 input_line_pointer++; /* skip ',' */
1000
1001 if(!strncmp(input_line_pointer,"cannot_shortcut",15))
1002 {
1003 imode |= arc_get_noshortcut_flag();
1004 input_line_pointer += 15;
1005 }
1006 else
1007 {
1008 if(strncmp(input_line_pointer,"can_shortcut",12))
1009 {
1010 as_bad ("shortcut designator invalid");
1011 ignore_rest_of_line();
1012 free(name);
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
KH
1024 {
1025 as_bad("core register value (%d) too large", number);
1026 ignore_rest_of_line();
1027 free(name);
1028 return;
1029 }
0d2bcfaf
NC
1030
1031 if ((opertype == 0) && number > 31)
1e07b820
KH
1032 {
1033 as_bad("condition code value (%d) too large", number);
1034 ignore_rest_of_line();
1035 free(name);
1036 return;
1037 }
0d2bcfaf
NC
1038
1039 ext_oper = (struct arc_ext_operand_value *) \
1e07b820 1040 xmalloc(sizeof (struct arc_ext_operand_value));
0d2bcfaf
NC
1041
1042 if(opertype)
1043 {
bfb32b52 1044 /* if the symbol already exists, point it at the new definition */
0d2bcfaf 1045 if ((symbolP = symbol_find (name)))
1e07b820
KH
1046 {
1047 if (S_GET_SEGMENT(symbolP) == reg_section)
1048 S_SET_VALUE(symbolP,(int)&ext_oper->operand);
1049 else
1050 {
1051 as_bad("attempt to override symbol: %s",name);
1052 ignore_rest_of_line();
1053 free(name);
1054 free(ext_oper);
1055 return;
1056 }
1057 }
0d2bcfaf 1058 else
1e07b820
KH
1059 {
1060 /* If its not there, add it */
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;
1068 ext_oper->operand.type = arc_operand_type(opertype);
1069 ext_oper->operand.flags = imode;
1070
1071 ext_oper->next = arc_ext_operands;
1072 arc_ext_operands = ext_oper;
1073
1e07b820
KH
1074 /* ok, now that we know what this operand is, put a description
1075 in the arc extension section of the output file */
0d2bcfaf
NC
1076
1077 old_sec = now_seg;
1078 old_subsec = now_subseg;
1079
1080 arc_set_ext_seg();
1081
1082 switch (opertype)
1e07b820
KH
1083 {
1084 case 0:
1085 p = frag_more(1);
1086 *p = 3 + strlen(name) + 1;
1087 p = frag_more(1);
1088 *p = EXT_COND_CODE;
1089 p = frag_more(1);
1090 *p = number;
1091 p = frag_more(strlen(name) + 1);
1092 strcpy(p,name);
1093 break;
1094 case 1:
1095 p = frag_more(1);
1096 *p = 3 + strlen(name) + 1;
1097 p = frag_more(1);
1098 *p = EXT_CORE_REGISTER;
1099 p = frag_more(1);
1100 *p = number;
1101 p = frag_more(strlen(name) + 1);
1102 strcpy(p,name);
1103 break;
1104 case 2:
1105 p = frag_more(1);
1106 *p = 6 + strlen(name) + 1;
1107 p = frag_more(1);
1108 *p = EXT_AUX_REGISTER;
1109 p = frag_more(1);
1110 *p = number >> 24 & 0xff;
1111 p = frag_more(1);
1112 *p = number >> 16 & 0xff;
1113 p = frag_more(1);
1114 *p = number >> 8 & 0xff;
1115 p = frag_more(1);
1116 *p = number & 0xff;
1117 p = frag_more(strlen(name) + 1);
1118 strcpy(p,name);
1119 break;
1120 default:
1121 as_bad("invalid opertype");
1122 ignore_rest_of_line();
1123 free(name);
1124 return;
1125 break;
1126 }
0d2bcfaf
NC
1127
1128 subseg_set (old_sec, old_subsec);
1129
1e07b820 1130 /* enter all registers into the symbol table */
0d2bcfaf
NC
1131
1132 demand_empty_rest_of_line();
1133}
1134
1135static void
1136arc_extinst (ignore)
1137 int ignore ATTRIBUTE_UNUSED;
1138{
1139 unsigned char syntax[129];
1140 char *name;
1141 char *p;
1142 char c;
1143 int suffixcode = -1;
1144 int opcode,subopcode;
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 ();
1155 name = xstrdup(name);
1156 if (NULL == name)
1157 {
1e07b820
KH
1158 ignore_rest_of_line();
1159 return;
0d2bcfaf
NC
1160 }
1161 strcpy(syntax,name);
1162 name_len = strlen(name);
1163
1164 /* just after name is now '\0' */
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
NC
1176
1177 input_line_pointer++; /* skip ',' */
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
NC
1188
1189 input_line_pointer++; /* skip ',' */
1190 subopcode = get_absolute_expression ();
1191
1192 if(subopcode < 0)
252b5132 1193 {
1e07b820
KH
1194 as_bad ("negative subopcode %d",subopcode);
1195 ignore_rest_of_line();
1196 return;
252b5132 1197 }
0d2bcfaf
NC
1198
1199 if(subopcode)
1200 {
1e07b820
KH
1201 if(3 != opcode)
1202 {
1203 as_bad ("subcode value found when opcode not equal 0x03");
1204 ignore_rest_of_line();
1205 return;
1206 }
1207 else
1208 {
1209 if (subopcode < 0x09 || subopcode == 0x3f)
1210 {
1211 as_bad ("invalid subopcode %d", subopcode);
1212 ignore_rest_of_line();
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
NC
1226
1227 input_line_pointer++; /* skip ',' */
1228
1229 for(i = 0; i < (int) MAXSUFFIXCLASS; i++)
1230 {
1e07b820
KH
1231 if(!strncmp(suffixclass[i].name,input_line_pointer, suffixclass[i].len))
1232 {
1233 suffixcode = i;
1234 input_line_pointer += suffixclass[i].len;
1235 break;
1236 }
0d2bcfaf
NC
1237 }
1238
1239 if(-1 == suffixcode)
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
NC
1254
1255 input_line_pointer++; /* skip ',' */
1256
1257 for(i = 0; i < (int) MAXSYNTAXCLASS; i++)
252b5132 1258 {
1e07b820
KH
1259 if(!strncmp(syntaxclass[i].name,input_line_pointer, syntaxclass[i].len))
1260 {
1261 class = syntaxclass[i].class;
1262 input_line_pointer += syntaxclass[i].len;
1263 break;
1264 }
252b5132 1265 }
252b5132 1266
0d2bcfaf
NC
1267 if(0 == (SYNTAX_VALID & class))
1268 {
1269 as_bad ("invalid syntax class");
1270 ignore_rest_of_line ();
1271 return;
1272 }
1273
1274 if ((0x3 == opcode) & (class & SYNTAX_3OP))
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:
1284 strcat(syntax,"%.q%.f ");
1285 break;
1286 case 1:
1287 strcat(syntax,"%.f ");
1288 break;
1289 case 2:
1290 strcat(syntax,"%.q ");
1291 break;
1292 case 3:
1293 strcat(syntax," ");
1294 break;
1295 default:
1296 as_bad("unknown suffix class");
1297 ignore_rest_of_line();
1298 return;
1299 break;
1300 };
0d2bcfaf
NC
1301
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");
1306
bfb32b52 1307 ext_op = (struct arc_opcode *) xmalloc(sizeof (struct arc_opcode));
0d2bcfaf
NC
1308 if(NULL == ext_op)
1309 {
1e07b820
KH
1310 ignore_rest_of_line ();
1311 return;
0d2bcfaf
NC
1312 }
1313
1314 ext_op->syntax = xstrdup(syntax);
1315 if (NULL == ext_op->syntax)
1316 {
1e07b820
KH
1317 ignore_rest_of_line ();
1318 return;
0d2bcfaf
NC
1319 }
1320
1321 ext_op->mask = I(-1) | ((0x3 == opcode) ? C(-1) : 0 );
1322 ext_op->value = I(opcode) | ((0x3 == opcode) ? C(subopcode) : 0 );
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
1e07b820
KH
1328 /* ok, now that we know what this inst is, put a description in
1329 the arc extension section of the output file */
0d2bcfaf
NC
1330
1331 old_sec = now_seg;
1332 old_subsec = now_subseg;
1333
1334 arc_set_ext_seg();
1335
1336 p = frag_more(1);
1337 *p = 5 + name_len +1;
1338 p = frag_more(1);
1339 *p = EXT_INSTRUCTION;
1340 p = frag_more(1);
1341 *p = opcode;
1342 p = frag_more(1);
1343 *p = subopcode;
1344 p = frag_more(1);
1345 *p = (class & (OP1_MUST_BE_IMM | OP1_IMM_IMPLIED) ? IGNORE_FIRST_OPD : 0);
1346 p = frag_more(name_len);
1347 strncpy(p,syntax,name_len);
1348 p = frag_more(1);
1349 *p = '\0';
1350
1351 subseg_set (old_sec, old_subsec);
1352
1353 demand_empty_rest_of_line();
252b5132
RH
1354}
1355
0d2bcfaf
NC
1356int
1357arc_set_ext_seg()
1358{
1359 if (!arcext_section)
1360 {
1361 arcext_section = subseg_new (".arcextmap", 0);
1362 bfd_set_section_flags (stdoutput, arcext_section,
1363 SEC_READONLY | SEC_HAS_CONTENTS);
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
NC
1376 char *p;
1377 int align, size;
1378 symbolS *symbolP;
252b5132 1379
0d2bcfaf
NC
1380 name = input_line_pointer;
1381 c = get_symbol_end ();
1382 /* just after name is now '\0' */
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
0d2bcfaf
NC
1394 input_line_pointer++; /* skip ',' */
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 }
1414 if ( ((int) S_GET_VALUE (symbolP) != 0) \
1415 && ((int) S_GET_VALUE (symbolP) != size) )
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);
1446 subseg_set (bss_section, 0); /* ??? subseg_set (bss_section, 1); ??? */
1447
1448 if (align)
1449 frag_align (align, 0, 0); /* do alignment */
1450
1451 /* detach from old frag */
1452 if (S_GET_SEGMENT (symbolP) == bss_section)
1453 symbolP->sy_frag->fr_symbol = NULL;
1454
1455 symbolP->sy_frag = frag_now;
1456 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
1457 (offsetT) size, (char *) 0);
1458 *pfrag = 0;
1459
1460 S_SET_SIZE (symbolP, size);
1461 S_SET_SEGMENT (symbolP, bss_section);
1462 S_CLEAR_EXTERNAL (symbolP);
1463 symbolP->local = 1;
1464 subseg_set (old_sec, old_subsec);
1465 }
1466 else
1467 {
1468 S_SET_VALUE (symbolP, (valueT) size);
1469 S_SET_ALIGN (symbolP, align);
1470 S_SET_EXTERNAL (symbolP);
1471 S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
252b5132 1472 }
252b5132 1473
0d2bcfaf
NC
1474 symbolP->bsym->flags |= BSF_OBJECT;
1475
1476 demand_empty_rest_of_line ();
1477 return;
252b5132
RH
1478}
1479
0d2bcfaf
NC
1480\f
1481
1482/* Select the cpu we're assembling for. */
252b5132
RH
1483
1484static void
0d2bcfaf
NC
1485arc_option (ignore)
1486 int ignore ATTRIBUTE_UNUSED;
252b5132 1487{
0d2bcfaf 1488 int mach;
252b5132 1489 char c;
0d2bcfaf 1490 char *cpu;
252b5132 1491
0d2bcfaf 1492 cpu = input_line_pointer;
252b5132 1493 c = get_symbol_end ();
0d2bcfaf 1494 mach = arc_get_mach (cpu);
252b5132
RH
1495 *input_line_pointer = c;
1496
0d2bcfaf
NC
1497 /* If an instruction has already been seen, it's too late. */
1498 if (cpu_tables_init_p)
252b5132 1499 {
0d2bcfaf 1500 as_bad ("\".option\" directive must appear before any instructions");
252b5132
RH
1501 ignore_rest_of_line ();
1502 return;
1503 }
252b5132 1504
0d2bcfaf
NC
1505 if (mach == -1)
1506 goto bad_cpu;
1507
1508 if (mach_type_specified_p && mach != arc_mach_type)
252b5132 1509 {
0d2bcfaf 1510 as_bad ("\".option\" directive conflicts with initial definition");
252b5132
RH
1511 ignore_rest_of_line ();
1512 return;
1513 }
0d2bcfaf
NC
1514 else
1515 {
1516 /* The cpu may have been selected on the command line. */
1517 if (mach != arc_mach_type)
1518 as_warn ("\".option\" directive overrides command-line (default) value");
1519 arc_mach_type = mach;
1520 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
1521 as_fatal ("could not set architecture and machine");
1522 mach_type_specified_p = 1;
1523 }
252b5132 1524 demand_empty_rest_of_line ();
0d2bcfaf
NC
1525 return;
1526
1527 bad_cpu:
1528 as_bad ("invalid identifier for \".option\"");
1529 ignore_rest_of_line ();
252b5132 1530}
0d2bcfaf 1531
252b5132
RH
1532\f
1533/* Turn a string in input_line_pointer into a floating point constant of type
1534 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1535 emitted is stored in *sizeP.
1536 An error message is returned, or NULL on OK. */
1537
0d2bcfaf 1538/* Equal to MAX_PRECISION in atof-ieee.c */
252b5132
RH
1539#define MAX_LITTLENUMS 6
1540
1541char *
1542md_atof (type, litP, sizeP)
0d2bcfaf
NC
1543 char type;
1544 char *litP;
1545 int *sizeP;
252b5132
RH
1546{
1547 int prec;
1548 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1549 LITTLENUM_TYPE *wordP;
1550 char *t;
1551 char *atof_ieee ();
1552
1553 switch (type)
1554 {
1555 case 'f':
1556 case 'F':
1557 prec = 2;
1558 break;
1559
1560 case 'd':
1561 case 'D':
1562 prec = 4;
1563 break;
1564
1565 default:
1566 *sizeP = 0;
0d2bcfaf 1567 return "bad call to md_atof";
252b5132
RH
1568 }
1569
1570 t = atof_ieee (input_line_pointer, type, words);
1571 if (t)
1572 input_line_pointer = t;
1573 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1574 for (wordP = words; prec--;)
1575 {
1576 md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
1577 litP += sizeof (LITTLENUM_TYPE);
1578 }
1579
1580 return NULL;
1581}
1582
1583/* Write a value out to the object file, using the appropriate
1584 endianness. */
1585
1586void
1587md_number_to_chars (buf, val, n)
1588 char *buf;
1589 valueT val;
1590 int n;
1591{
1592 if (target_big_endian)
1593 number_to_chars_bigendian (buf, val, n);
1594 else
1595 number_to_chars_littleendian (buf, val, n);
1596}
1597
bfb32b52 1598/* Round up a section size to the appropriate boundary. */
252b5132
RH
1599
1600valueT
1601md_section_align (segment, size)
1602 segT segment;
1603 valueT size;
1604{
1605 int align = bfd_get_section_alignment (stdoutput, segment);
1606
1607 return ((size + (1 << align) - 1) & (-1 << align));
1608}
1609
1610/* We don't have any form of relaxing. */
1611
1612int
1613md_estimate_size_before_relax (fragp, seg)
4a314ec8
NC
1614 fragS *fragp ATTRIBUTE_UNUSED;
1615 asection *seg ATTRIBUTE_UNUSED;
252b5132 1616{
0d2bcfaf
NC
1617 as_fatal (_("md_estimate_size_before_relax\n"));
1618 return 1;
252b5132
RH
1619}
1620
1621/* Convert a machine dependent frag. We never generate these. */
1622
1623void
1624md_convert_frag (abfd, sec, fragp)
4a314ec8
NC
1625 bfd *abfd ATTRIBUTE_UNUSED;
1626 asection *sec ATTRIBUTE_UNUSED;
1627 fragS *fragp ATTRIBUTE_UNUSED;
252b5132 1628{
0d2bcfaf
NC
1629 as_fatal (_("md_convert_frag\n"));
1630}
1631
1632void
1633arc_code_symbol(expressionP)
1634 expressionS *expressionP;
1635{
1636 if (expressionP->X_op == O_symbol && expressionP->X_add_number == 0
1e07b820
KH
1637 /* I think this test is unnecessary but just as a sanity check... */
1638 && expressionP->X_op_symbol == NULL)
0d2bcfaf 1639 {
1e07b820
KH
1640 expressionS two;
1641 expressionP->X_op = O_right_shift;
1642 two.X_op = O_constant;
1643 two.X_add_symbol = two.X_op_symbol = NULL;
1644 two.X_add_number = 2;
1645 expressionP->X_op_symbol = make_expr_symbol (&two);
0d2bcfaf 1646 }
1e07b820 1647 /* allow %st(sym1-sym2) */
0d2bcfaf 1648 else if (expressionP->X_op == O_subtract && expressionP->X_add_symbol != NULL
1e07b820 1649 && expressionP->X_op_symbol != NULL && expressionP->X_add_number == 0)
0d2bcfaf 1650 {
1e07b820
KH
1651 expressionS two;
1652 expressionP->X_add_symbol = make_expr_symbol (expressionP);
1653 expressionP->X_op = O_right_shift;
1654 two.X_op = O_constant;
1655 two.X_add_symbol = two.X_op_symbol = NULL;
1656 two.X_add_number = 2;
1657 expressionP->X_op_symbol = make_expr_symbol (&two);
0d2bcfaf
NC
1658 }
1659 else
1660 {
1e07b820
KH
1661 as_bad ("expression too complex code symbol");
1662 return;
0d2bcfaf 1663 }
252b5132
RH
1664}
1665
1666/* Parse an operand that is machine-specific.
1667
1668 The ARC has a special %-op to adjust addresses so they're usable in
1669 branches. The "st" is short for the STatus register.
1670 ??? Later expand this to take a flags value too.
1671
1672 ??? We can't create new expression types so we map the %-op's onto the
1673 existing syntax. This means that the user could use the chosen syntax
bfb32b52 1674 to achieve the same effect. */
252b5132 1675
bfb32b52 1676void
252b5132
RH
1677md_operand (expressionP)
1678 expressionS *expressionP;
1679{
1680 char *p = input_line_pointer;
1681
0d2bcfaf
NC
1682 if (*p == '%')
1683 if(strncmp (p, "%st(", 4) == 0)
1684 {
1e07b820
KH
1685 input_line_pointer += 4;
1686 expression (expressionP);
1687 if (*input_line_pointer != ')')
1688 {
1689 as_bad ("missing ')' in %%-op");
1690 return;
1691 }
1692 ++input_line_pointer;
1693 arc_code_symbol(expressionP);
0d2bcfaf 1694 }
1e07b820
KH
1695 else
1696 { /* it could be a register */
1697 int i,l;
1698 struct arc_ext_operand_value *ext_oper = arc_ext_operands;
1699 p++;
0d2bcfaf 1700
1e07b820
KH
1701 while (ext_oper)
1702 {
1703 l = strlen(ext_oper->operand.name);
1704 if(!strncmp(p,ext_oper->operand.name,l) && !isalnum(*(p + l)))
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 {
1715 l = strlen(arc_reg_names[i].name);
1716 if(!strncmp(p,arc_reg_names[i].name,l) && !isalnum(*(p + l)))
1717 {
1718 input_line_pointer += l + 1;
1719 expressionP->X_op = O_register;
1720 expressionP->X_add_number = (int) &arc_reg_names[i];
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)
0d2bcfaf
NC
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
1753 for (;! is_end_of_line[(unsigned char) *p]; p++)
1e07b820 1754 if (*p == '@' && !strncmp(p,"@h30",4))
0d2bcfaf 1755 {
1e07b820
KH
1756 code_symbol_fix = 1;
1757 strcpy(p,"; ");
0d2bcfaf 1758 }
1e07b820
KH
1759 expr (0, exp);
1760 if (code_symbol_fix)
1761 {
1762 arc_code_symbol(exp);
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{
1803 if (fixP->fx_addsy != (symbolS *) NULL
1804 && ! S_IS_DEFINED (fixP->fx_addsy))
1805 {
1806 /* The symbol is undefined. Let the linker figure it out. */
1807 return 0;
1808 }
1809
1810 /* Return the address of the delay slot. */
1811 return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
1812}
1813
1814/* Compute the reloc type of an expression.
1815 The possibly modified expression is stored in EXPNEW.
1816
1817 This is used to convert the expressions generated by the %-op's into
1818 the appropriate operand type. It is called for both data in instructions
1819 (operands) and data outside instructions (variables, debugging info, etc.).
1820
1821 Currently supported %-ops:
1822
1823 %st(symbol): represented as "symbol >> 2"
1824 "st" is short for STatus as in the status register (pc)
1825
1826 DEFAULT_TYPE is the type to use if no special processing is required.
1827
1828 DATA_P is non-zero for data or limm values, zero for insn operands.
1829 Remember that the opcode "insertion fns" cannot be used on data, they're
1830 only for inserting operands into insns. They also can't be used for limm
1831 values as the insertion routines don't handle limm values. When called for
1832 insns we return fudged reloc types (real_value - BFD_RELOC_UNUSED). When
1833 called for data or limm values we use real reloc types. */
1834
1835static int
1836get_arc_exp_reloc_type (data_p, default_type, exp, expnew)
1837 int data_p;
1838 int default_type;
1839 expressionS *exp;
1840 expressionS *expnew;
1841{
1842 /* If the expression is "symbol >> 2" we must change it to just "symbol",
1843 as fix_new_exp can't handle it. Similarily for (symbol - symbol) >> 2.
1844 That's ok though. What's really going on here is that we're using
1845 ">> 2" as a special syntax for specifying BFD_RELOC_ARC_B26. */
1846
1847 if (exp->X_op == O_right_shift
1848 && exp->X_op_symbol != NULL
0d2bcfaf
NC
1849 && exp->X_op_symbol->sy_value.X_op == O_constant
1850 && exp->X_op_symbol->sy_value.X_add_number == 2
252b5132
RH
1851 && exp->X_add_number == 0)
1852 {
1853 if (exp->X_add_symbol != NULL
0d2bcfaf
NC
1854 && (exp->X_add_symbol->sy_value.X_op == O_constant
1855 || exp->X_add_symbol->sy_value.X_op == O_symbol))
252b5132
RH
1856 {
1857 *expnew = *exp;
1858 expnew->X_op = O_symbol;
1859 expnew->X_op_symbol = NULL;
1860 return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
1861 }
1862 else if (exp->X_add_symbol != NULL
0d2bcfaf 1863 && exp->X_add_symbol->sy_value.X_op == O_subtract)
252b5132 1864 {
0d2bcfaf 1865 *expnew = exp->X_add_symbol->sy_value;
252b5132
RH
1866 return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
1867 }
1868 }
1869
1870 *expnew = *exp;
1871 return default_type;
1872}
1873
1874/* Apply a fixup to the object code. This is called for all the
1875 fixups we generated by the call to fix_new_exp, above. In the call
1876 above we used a reloc code which was the largest legal reloc code
1877 plus the operand index. Here we undo that to recover the operand
1878 index. At this point all symbol values should be fully resolved,
1879 and we attempt to completely resolve the reloc. If we can not do
1880 that, we determine the correct reloc code and put it back in the fixup. */
1881
1882int
1883md_apply_fix3 (fixP, valueP, seg)
1884 fixS *fixP;
1885 valueT *valueP;
1886 segT seg;
1887{
1888 /*char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;*/
1889 valueT value;
1890
1891 /* FIXME FIXME FIXME: The value we are passed in *valueP includes
1892 the symbol values. Since we are using BFD_ASSEMBLER, if we are
1893 doing this relocation the code in write.c is going to call
1894 bfd_perform_relocation, which is also going to use the symbol
1895 value. That means that if the reloc is fully resolved we want to
1896 use *valueP since bfd_perform_relocation is not being used.
1897 However, if the reloc is not fully resolved we do not want to use
1898 *valueP, and must use fx_offset instead. However, if the reloc
1899 is PC relative, we do want to use *valueP since it includes the
1900 result of md_pcrel_from. This is confusing. */
1901
1902 if (fixP->fx_addsy == (symbolS *) NULL)
1903 {
1904 value = *valueP;
1905 fixP->fx_done = 1;
1906 }
1907 else if (fixP->fx_pcrel)
1908 {
1909 value = *valueP;
1910 /* ELF relocations are against symbols.
1911 If this symbol is in a different section then we need to leave it for
1912 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
1913 so we have to undo it's effects here. */
1914 if (S_IS_DEFINED (fixP->fx_addsy)
1915 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
1916 value += md_pcrel_from (fixP);
1917 }
1918 else
1919 {
1920 value = fixP->fx_offset;
1921 if (fixP->fx_subsy != (symbolS *) NULL)
1922 {
1923 if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)
1924 value -= S_GET_VALUE (fixP->fx_subsy);
1925 else
1926 {
1927 /* We can't actually support subtracting a symbol. */
1928 as_bad_where (fixP->fx_file, fixP->fx_line,
0d2bcfaf 1929 "expression too complex");
252b5132
RH
1930 }
1931 }
1932 }
1933
1934 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
1935 {
1936 int opindex;
1937 const struct arc_operand *operand;
1938 char *where;
1939 arc_insn insn;
1940
1941 opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
1942
1943 operand = &arc_operands[opindex];
1944
1945 /* Fetch the instruction, insert the fully resolved operand
1946 value, and stuff the instruction back again. */
1947 where = fixP->fx_frag->fr_literal + fixP->fx_where;
1948 if (target_big_endian)
1949 insn = bfd_getb32 ((unsigned char *) where);
1950 else
1951 insn = bfd_getl32 ((unsigned char *) where);
1952 insn = arc_insert_operand (insn, operand, -1, NULL, (offsetT) value,
1953 fixP->fx_file, fixP->fx_line);
1954 if (target_big_endian)
1955 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1956 else
1957 bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
1958
1959 if (fixP->fx_done)
1960 {
1961 /* Nothing else to do here. */
1962 return 1;
1963 }
1964
1965 /* Determine a BFD reloc value based on the operand information.
1966 We are only prepared to turn a few of the operands into relocs.
1967 !!! Note that we can't handle limm values here. Since we're using
1968 implicit addends the addend must be inserted into the instruction,
1969 however, the opcode insertion routines currently do nothing with
1970 limm values. */
1971 if (operand->fmt == 'B')
1972 {
1973 assert ((operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0
1974 && operand->bits == 20
1975 && operand->shift == 7);
1976 fixP->fx_r_type = BFD_RELOC_ARC_B22_PCREL;
1977 }
0d2bcfaf 1978 else if (operand->fmt == 'J')
252b5132
RH
1979 {
1980 assert ((operand->flags & ARC_OPERAND_ABSOLUTE_BRANCH) != 0
1981 && operand->bits == 24
1982 && operand->shift == 32);
1983 fixP->fx_r_type = BFD_RELOC_ARC_B26;
1984 }
0d2bcfaf 1985 else if (operand->fmt == 'L')
252b5132
RH
1986 {
1987 assert ((operand->flags & ARC_OPERAND_LIMM) != 0
1988 && operand->bits == 32
1989 && operand->shift == 32);
1990 fixP->fx_r_type = BFD_RELOC_32;
1991 }
1992 else
1993 {
1994 as_bad_where (fixP->fx_file, fixP->fx_line,
0d2bcfaf 1995 "unresolved expression that must be resolved");
252b5132
RH
1996 fixP->fx_done = 1;
1997 return 1;
1998 }
1999 }
2000 else
2001 {
2002 switch (fixP->fx_r_type)
2003 {
2004 case BFD_RELOC_8:
2005 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
2006 value, 1);
2007 break;
2008 case BFD_RELOC_16:
2009 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
2010 value, 2);
2011 break;
2012 case BFD_RELOC_32:
2013 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
2014 value, 4);
2015 break;
2016#if 0
2017 case BFD_RELOC_64:
2018 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
2019 value, 8);
2020 break;
2021#endif
2022 case BFD_RELOC_ARC_B26:
2023 /* If !fixP->fx_done then `value' is an implicit addend.
2024 We must shift it right by 2 in this case as well because the
2025 linker performs the relocation and then adds this in (as opposed
2026 to adding this in and then shifting right by 2). */
2027 value >>= 2;
2028 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
2029 value, 4);
2030 break;
2031 default:
2032 abort ();
2033 }
2034 }
2035
2036 fixP->fx_addnumber = value;
2037
2038 return 1;
2039}
2040
2041/* Translate internal representation of relocation info to BFD target
2042 format. */
2043
2044arelent *
2045tc_gen_reloc (section, fixP)
4a314ec8 2046 asection *section ATTRIBUTE_UNUSED;
252b5132
RH
2047 fixS *fixP;
2048{
2049 arelent *reloc;
2050
2051 reloc = (arelent *) xmalloc (sizeof (arelent));
2052
0d2bcfaf 2053 reloc->sym_ptr_ptr = &fixP->fx_addsy->bsym;
252b5132
RH
2054 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
2055 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
2056 if (reloc->howto == (reloc_howto_type *) NULL)
2057 {
2058 as_bad_where (fixP->fx_file, fixP->fx_line,
0d2bcfaf 2059 "internal error: can't export reloc type %d (`%s')",
252b5132
RH
2060 fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
2061 return NULL;
2062 }
2063
2064 assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
2065
0d2bcfaf
NC
2066/* set addend to account for PC being advanced one insn before the target
2067 address is computed, drop fx_addnumber as it is handled elsewhere mlm */
252b5132 2068
0d2bcfaf 2069 reloc->addend = ( fixP->fx_pcrel ? -4 : 0 );
252b5132 2070
0d2bcfaf 2071 return reloc;
252b5132 2072}
This page took 0.164241 seconds and 4 git commands to generate.