Fix copyright notices
[deliverable/binutils-gdb.git] / gas / config / tc-arc.c
CommitLineData
252b5132 1/* tc-arc.c -- Assembler for the ARC
f7e42eb4
NC
2 Copyright 1994, 1995, 1997, 1999, 2000, 2001
3 Free Software Foundation, Inc.
252b5132
RH
4 Contributed by Doug Evans (dje@cygnus.com).
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19203624
KH
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
252b5132
RH
22
23#include <stdio.h>
24#include <ctype.h>
0d2bcfaf 25#include "libiberty.h"
252b5132
RH
26#include "as.h"
27#include "subsegs.h"
28#include "opcode/arc.h"
0d2bcfaf 29#include "../opcodes/arc-ext.h"
252b5132
RH
30#include "elf/arc.h"
31
32extern int arc_get_mach PARAMS ((char *));
0d2bcfaf
NC
33extern int arc_operand_type PARAMS ((int));
34extern int arc_insn_not_jl PARAMS ((arc_insn));
35extern int arc_limm_fixup_adjust PARAMS ((arc_insn));
36extern int arc_get_noshortcut_flag PARAMS ((void));
37extern int arc_set_ext_seg PARAMS ((void));
19203624 38extern void arc_code_symbol PARAMS ((expressionS *));
252b5132
RH
39
40static arc_insn arc_insert_operand PARAMS ((arc_insn,
41 const struct arc_operand *, int,
42 const struct arc_operand_value *,
43 offsetT, char *, unsigned int));
44static void arc_common PARAMS ((int));
0d2bcfaf
NC
45static void arc_extinst PARAMS ((int));
46static void arc_extoper PARAMS ((int));
47static void arc_option PARAMS ((int));
252b5132
RH
48static int get_arc_exp_reloc_type PARAMS ((int, int, expressionS *,
49 expressionS *));
50
0d2bcfaf
NC
51const struct suffix_classes {
52 char *name;
53 int len;
54} suffixclass[] = {
55 { "SUFFIX_COND|SUFFIX_FLAG",23 },
56 { "SUFFIX_FLAG", 11 },
57 { "SUFFIX_COND", 11 },
58 { "SUFFIX_NONE", 11 }
59};
60
bfb32b52 61#define MAXSUFFIXCLASS (sizeof (suffixclass) / sizeof (struct suffix_classes))
0d2bcfaf
NC
62
63const struct syntax_classes {
64 char *name;
65 int len;
66 int class;
67} syntaxclass[] = {
68 { "SYNTAX_3OP|OP1_MUST_BE_IMM", 26, SYNTAX_3OP|OP1_MUST_BE_IMM|SYNTAX_VALID },
69 { "OP1_MUST_BE_IMM|SYNTAX_3OP", 26, OP1_MUST_BE_IMM|SYNTAX_3OP|SYNTAX_VALID },
70 { "SYNTAX_2OP|OP1_IMM_IMPLIED", 26, SYNTAX_2OP|OP1_IMM_IMPLIED|SYNTAX_VALID },
71 { "OP1_IMM_IMPLIED|SYNTAX_2OP", 26, OP1_IMM_IMPLIED|SYNTAX_2OP|SYNTAX_VALID },
72 { "SYNTAX_3OP", 10, SYNTAX_3OP|SYNTAX_VALID },
73 { "SYNTAX_2OP", 10, SYNTAX_2OP|SYNTAX_VALID }
74};
75
bfb32b52 76#define MAXSYNTAXCLASS (sizeof (syntaxclass) / sizeof (struct syntax_classes))
0d2bcfaf 77
19203624 78const pseudo_typeS md_pseudo_table[] = {
0d2bcfaf
NC
79 { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0) */
80 { "comm", arc_common, 0 },
252b5132 81 { "common", arc_common, 0 },
0d2bcfaf
NC
82 { "lcomm", arc_common, 1 },
83 { "lcommon", arc_common, 1 },
84 { "2byte", cons, 2 },
85 { "half", cons, 2 },
86 { "short", cons, 2 },
87 { "3byte", cons, 3 },
88 { "4byte", cons, 4 },
252b5132 89 { "word", cons, 4 },
0d2bcfaf
NC
90 { "option", arc_option, 0 },
91 { "block", s_space, 0 },
92 { "extcondcode", arc_extoper, 0 },
93 { "extcoreregister", arc_extoper, 1 },
94 { "extauxregister", arc_extoper, 2 },
95 { "extinstruction", arc_extinst, 0 },
252b5132
RH
96 { NULL, 0, 0 },
97};
98
99/* This array holds the chars that always start a comment. If the
100 pre-processor is disabled, these aren't very useful */
101const char comment_chars[] = "#;";
102
103/* This array holds the chars that only start a comment at the beginning of
104 a line. If the line seems to have the form '# 123 filename'
105 .line and .file directives will appear in the pre-processed output */
106/* Note that input_file.c hand checks for '#' at the beginning of the
107 first line of the input file. This is because the compiler outputs
bfb32b52 108 #NO_APP at the beginning of its output. */
252b5132 109/* Also note that comments started like this one will always
bfb32b52 110 work if '/' isn't otherwise defined. */
252b5132
RH
111const char line_comment_chars[] = "#";
112
113const char line_separator_chars[] = "";
114
115/* Chars that can be used to separate mant from exp in floating point nums */
116const char EXP_CHARS[] = "eE";
117
118/* Chars that mean this number is a floating point constant */
119/* As in 0f12.456 */
120/* or 0d1.2345e12 */
121const char FLT_CHARS[] = "rRsSfFdD";
122
123/* Byte order. */
124extern int target_big_endian;
125const char *arc_target_format = DEFAULT_TARGET_FORMAT;
126static int byte_order = DEFAULT_BYTE_ORDER;
127
0d2bcfaf
NC
128static segT arcext_section;
129
130/* One of bfd_mach_arc_n. */
131static int arc_mach_type = bfd_mach_arc_5;
252b5132
RH
132
133/* Non-zero if the cpu type has been explicitly specified. */
134static int mach_type_specified_p = 0;
135
136/* Non-zero if opcode tables have been initialized.
137 A .cpu command must appear before any instructions. */
138static int cpu_tables_init_p = 0;
139
140static struct hash_control *arc_suffix_hash = NULL;
141\f
142const char *md_shortopts = "";
19203624 143struct option md_longopts[] = {
252b5132
RH
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
19203624 165struct arc_operand_value *get_ext_suffix (char *s);
0d2bcfaf 166
19203624
KH
167/* Invocation line includes a switch not recognized by the base assembler.
168 See if it's a processor-specific option. */
252b5132
RH
169
170int
171md_parse_option (c, arg)
172 int c;
4a314ec8 173 char *arg ATTRIBUTE_UNUSED;
252b5132
RH
174{
175 switch (c)
1e07b820 176 {
0d2bcfaf
NC
177 case OPTION_ARC:
178 case OPTION_ARC5:
179 arc_mach_type = bfd_mach_arc_5;
180 break;
181 case OPTION_ARC6:
182 arc_mach_type = bfd_mach_arc_6;
183 break;
184 case OPTION_ARC7:
185 arc_mach_type = bfd_mach_arc_7;
186 break;
187 case OPTION_ARC8:
188 arc_mach_type = bfd_mach_arc_8;
189 break;
252b5132
RH
190 case OPTION_EB:
191 byte_order = BIG_ENDIAN;
192 arc_target_format = "elf32-bigarc";
193 break;
194 case OPTION_EL:
195 byte_order = LITTLE_ENDIAN;
196 arc_target_format = "elf32-littlearc";
197 break;
198 default:
199 return 0;
1e07b820 200 }
252b5132
RH
201 return 1;
202}
203
204void
205md_show_usage (stream)
206 FILE *stream;
207{
0d2bcfaf
NC
208 fprintf (stream, "\
209ARC Options:\n\
210 -marc[5|6|7|8] select processor variant (default arc%d)\n\
211 -EB assemble code for a big endian cpu\n\
212 -EL assemble code for a little endian cpu\n", arc_mach_type + 5);
252b5132
RH
213}
214
215/* This function is called once, at assembler startup time. It should
216 set up all the tables, etc. that the MD part of the assembler will need.
217 Opcode selection is defered until later because we might see a .cpu
218 command. */
219
220void
221md_begin ()
222{
223 /* The endianness can be chosen "at the factory". */
224 target_big_endian = byte_order == BIG_ENDIAN;
225
226 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
0d2bcfaf 227 as_warn ("could not set architecture and machine");
252b5132 228
0d2bcfaf 229 /* This call is necessary because we need to
252b5132
RH
230 initialize `arc_operand_map' which may be needed before we see the
231 first insn. */
0d2bcfaf 232 arc_opcode_init_tables (arc_get_opcode_mach (arc_mach_type,
252b5132
RH
233 target_big_endian));
234}
235
236/* Initialize the various opcode and operand tables.
237 MACH is one of bfd_mach_arc_xxx. */
238
239static void
240init_opcode_tables (mach)
241 int mach;
242{
4a314ec8 243 int i;
252b5132
RH
244 char *last;
245
246 if ((arc_suffix_hash = hash_new ()) == NULL)
0d2bcfaf 247 as_fatal ("virtual memory exhausted");
252b5132
RH
248
249 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
0d2bcfaf 250 as_warn ("could not set architecture and machine");
252b5132
RH
251
252 /* This initializes a few things in arc-opc.c that we need.
253 This must be called before the various arc_xxx_supported fns. */
254 arc_opcode_init_tables (arc_get_opcode_mach (mach, target_big_endian));
255
256 /* Only put the first entry of each equivalently named suffix in the
257 table. */
258 last = "";
259 for (i = 0; i < arc_suffixes_count; i++)
260 {
252b5132
RH
261 if (strcmp (arc_suffixes[i].name, last) != 0)
262 hash_insert (arc_suffix_hash, arc_suffixes[i].name, (PTR) (arc_suffixes + i));
263 last = arc_suffixes[i].name;
264 }
265
266 /* Since registers don't have a prefix, we put them in the symbol table so
267 they can't be used as symbols. This also simplifies argument parsing as
268 we can let gas parse registers for us. The recorded register number is
0d2bcfaf
NC
269 the address of the register's entry in arc_reg_names.
270
271 If the register name is already in the table, then the existing
272 definition is assumed to be from an .ExtCoreRegister pseudo-op. */
273
252b5132
RH
274 for (i = 0; i < arc_reg_names_count; i++)
275 {
19203624 276 if (symbol_find (arc_reg_names[i].name))
252b5132
RH
277 continue;
278 /* Use symbol_create here instead of symbol_new so we don't try to
279 output registers into the object file's symbol table. */
280 symbol_table_insert (symbol_create (arc_reg_names[i].name, reg_section,
0d2bcfaf 281 (int) &arc_reg_names[i], &zero_address_frag));
252b5132
RH
282 }
283
0d2bcfaf 284 /* Tell `.option' it's too late. */
252b5132
RH
285 cpu_tables_init_p = 1;
286}
287\f
288/* Insert an operand value into an instruction.
289 If REG is non-NULL, it is a register number and ignore VAL. */
290
291static arc_insn
292arc_insert_operand (insn, operand, mods, reg, val, file, line)
293 arc_insn insn;
294 const struct arc_operand *operand;
295 int mods;
296 const struct arc_operand_value *reg;
297 offsetT val;
298 char *file;
299 unsigned int line;
300{
301 if (operand->bits != 32)
302 {
303 long min, max;
304 offsetT test;
305
306 if ((operand->flags & ARC_OPERAND_SIGNED) != 0)
307 {
308 if ((operand->flags & ARC_OPERAND_SIGNOPT) != 0)
309 max = (1 << operand->bits) - 1;
310 else
311 max = (1 << (operand->bits - 1)) - 1;
312 min = - (1 << (operand->bits - 1));
313 }
314 else
315 {
316 max = (1 << operand->bits) - 1;
317 min = 0;
318 }
319
320 if ((operand->flags & ARC_OPERAND_NEGATIVE) != 0)
321 test = - val;
322 else
323 test = val;
324
325 if (test < (offsetT) min || test > (offsetT) max)
326 {
327 const char *err =
0d2bcfaf 328 "operand out of range (%s not between %ld and %ld)";
252b5132
RH
329 char buf[100];
330
331 sprint_value (buf, test);
332 if (file == (char *) NULL)
333 as_warn (err, buf, min, max);
334 else
335 as_warn_where (file, line, err, buf, min, max);
336 }
337 }
338
339 if (operand->insert)
340 {
341 const char *errmsg;
342
343 errmsg = NULL;
344 insn = (*operand->insert) (insn, operand, mods, reg, (long) val, &errmsg);
345 if (errmsg != (const char *) NULL)
346 as_warn (errmsg);
347 }
348 else
349 insn |= (((long) val & ((1 << operand->bits) - 1))
350 << operand->shift);
351
352 return insn;
353}
354
355/* We need to keep a list of fixups. We can't simply generate them as
356 we go, because that would require us to first create the frag, and
357 that would screw up references to ``.''. */
358
19203624 359struct arc_fixup {
252b5132
RH
360 /* index into `arc_operands' */
361 int opindex;
362 expressionS exp;
363};
364
365#define MAX_FIXUPS 5
366
367#define MAX_SUFFIXES 5
368
369/* This routine is called for each instruction to be assembled. */
370
371void
372md_assemble (str)
373 char *str;
374{
375 const struct arc_opcode *opcode;
0d2bcfaf
NC
376 const struct arc_opcode *std_opcode;
377 struct arc_opcode *ext_opcode;
252b5132 378 char *start;
0d2bcfaf 379 const char *last_errmsg = 0;
252b5132
RH
380 arc_insn insn;
381 static int init_tables_p = 0;
382
383 /* Opcode table initialization is deferred until here because we have to
384 wait for a possible .cpu command. */
385 if (!init_tables_p)
386 {
387 init_opcode_tables (arc_mach_type);
388 init_tables_p = 1;
389 }
390
391 /* Skip leading white space. */
392 while (isspace (*str))
393 str++;
394
395 /* The instructions are stored in lists hashed by the first letter (though
396 we needn't care how they're hashed). Get the first in the list. */
397
0d2bcfaf
NC
398 ext_opcode = arc_ext_opcodes;
399 std_opcode = arc_opcode_lookup_asm (str);
252b5132
RH
400
401 /* Keep looking until we find a match. */
402
403 start = str;
19203624 404 for (opcode = (ext_opcode ? ext_opcode : std_opcode);
0d2bcfaf
NC
405 opcode != NULL;
406 opcode = (ARC_OPCODE_NEXT_ASM (opcode)
1e07b820
KH
407 ? ARC_OPCODE_NEXT_ASM (opcode)
408 : (ext_opcode ? ext_opcode = NULL, std_opcode : NULL)))
252b5132
RH
409 {
410 int past_opcode_p, fc, num_suffixes;
0d2bcfaf 411 int fix_up_at = 0;
252b5132
RH
412 char *syn;
413 struct arc_fixup fixups[MAX_FIXUPS];
414 /* Used as a sanity check. If we need a limm reloc, make sure we ask
415 for an extra 4 bytes from frag_more. */
416 int limm_reloc_p;
0d2bcfaf 417 int ext_suffix_p;
252b5132
RH
418 const struct arc_operand_value *insn_suffixes[MAX_SUFFIXES];
419
420 /* Is this opcode supported by the selected cpu? */
421 if (! arc_opcode_supported (opcode))
422 continue;
423
424 /* Scan the syntax string. If it doesn't match, try the next one. */
425
426 arc_opcode_init_insert ();
427 insn = opcode->value;
428 fc = 0;
429 past_opcode_p = 0;
430 num_suffixes = 0;
431 limm_reloc_p = 0;
0d2bcfaf 432 ext_suffix_p = 0;
252b5132
RH
433
434 /* We don't check for (*str != '\0') here because we want to parse
435 any trailing fake arguments in the syntax string. */
19203624 436 for (str = start, syn = opcode->syntax; *syn != '\0';)
252b5132
RH
437 {
438 int mods;
439 const struct arc_operand *operand;
440
441 /* Non operand chars must match exactly. */
442 if (*syn != '%' || *++syn == '%')
443 {
444 /* Handle '+' specially as we want to allow "ld r0,[sp-4]". */
445 /* ??? The syntax has changed to [sp,-4]. */
446 if (0 && *syn == '+' && *str == '-')
447 {
448 /* Skip over syn's +, but leave str's - alone.
449 That makes the case identical to "ld r0,[sp+-4]". */
450 ++syn;
451 }
452 else if (*str == *syn)
453 {
454 if (*syn == ' ')
455 past_opcode_p = 1;
456 ++syn;
457 ++str;
458 }
459 else
460 break;
461 continue;
462 }
463
464 /* We have an operand. Pick out any modifiers. */
465 mods = 0;
4a314ec8 466 while (ARC_MOD_P (arc_operands[arc_operand_map[(int) *syn]].flags))
252b5132 467 {
4a314ec8 468 mods |= arc_operands[arc_operand_map[(int) *syn]].flags & ARC_MOD_BITS;
252b5132
RH
469 ++syn;
470 }
4a314ec8 471 operand = arc_operands + arc_operand_map[(int) *syn];
252b5132 472 if (operand->fmt == 0)
0d2bcfaf 473 as_fatal ("unknown syntax format character `%c'", *syn);
252b5132
RH
474
475 if (operand->flags & ARC_OPERAND_FAKE)
476 {
477 const char *errmsg = NULL;
478 if (operand->insert)
479 {
480 insn = (*operand->insert) (insn, operand, mods, NULL, 0, &errmsg);
1e07b820
KH
481 if (errmsg != (const char *) NULL)
482 {
483 last_errmsg = errmsg;
484 if (operand->flags & ARC_OPERAND_ERROR)
485 {
486 as_bad (errmsg);
487 return;
488 }
489 else if (operand->flags & ARC_OPERAND_WARN)
490 as_warn (errmsg);
491 break;
492 }
19203624
KH
493 if (limm_reloc_p
494 && (operand->flags && operand->flags & ARC_OPERAND_LIMM)
495 && (operand->flags &
496 (ARC_OPERAND_ABSOLUTE_BRANCH | ARC_OPERAND_ADDRESS)))
1e07b820
KH
497 {
498 fixups[fix_up_at].opindex = arc_operand_map[operand->fmt];
499 }
252b5132
RH
500 }
501 ++syn;
502 }
503 /* Are we finished with suffixes? */
504 else if (!past_opcode_p)
505 {
506 int found;
507 char c;
19203624
KH
508 char *s, *t;
509 const struct arc_operand_value *suf, *suffix_end;
0d2bcfaf 510 const struct arc_operand_value *suffix = NULL;
252b5132
RH
511
512 if (!(operand->flags & ARC_OPERAND_SUFFIX))
513 abort ();
514
515 /* If we're at a space in the input string, we want to skip the
516 remaining suffixes. There may be some fake ones though, so
517 just go on to try the next one. */
518 if (*str == ' ')
519 {
520 ++syn;
521 continue;
522 }
523
524 s = str;
525 if (mods & ARC_MOD_DOT)
526 {
527 if (*s != '.')
528 break;
529 ++s;
530 }
531 else
532 {
533 /* This can happen in "b.nd foo" and we're currently looking
534 for "%q" (ie: a condition code suffix). */
535 if (*s == '.')
536 {
537 ++syn;
538 continue;
539 }
540 }
541
542 /* Pick the suffix out and look it up via the hash table. */
0d2bcfaf 543 for (t = s; *t && isalnum (*t); ++t)
252b5132
RH
544 continue;
545 c = *t;
546 *t = '\0';
19203624 547 if ((suf = get_ext_suffix (s)))
1e07b820
KH
548 ext_suffix_p = 1;
549 else
550 suf = hash_find (arc_suffix_hash, s);
252b5132
RH
551 if (!suf)
552 {
553 /* This can happen in "blle foo" and we're currently using
554 the template "b%q%.n %j". The "bl" insn occurs later in
555 the table so "lle" isn't an illegal suffix. */
1e07b820 556 *t = c;
252b5132
RH
557 break;
558 }
559
560 /* Is it the right type? Note that the same character is used
1e07b820 561 several times, so we have to examine all of them. This is
252b5132
RH
562 relatively efficient as equivalent entries are kept
563 together. If it's not the right type, don't increment `str'
564 so we try the next one in the series. */
565 found = 0;
1e07b820
KH
566 if (ext_suffix_p && arc_operands[suf->type].fmt == *syn)
567 {
568 /* Insert the suffix's value into the insn. */
569 *t = c;
570 if (operand->insert)
571 insn = (*operand->insert) (insn, operand,
572 mods, NULL, suf->value,
573 NULL);
574 else
575 insn |= suf->value << operand->shift;
576
577 str = t;
578 found = 1;
579 }
580 else
581 {
582 *t = c;
583 suffix_end = arc_suffixes + arc_suffixes_count;
584 for (suffix = suf;
585 suffix < suffix_end && strcmp (suffix->name, suf->name) == 0;
586 ++suffix)
587 {
588 if (arc_operands[suffix->type].fmt == *syn)
589 {
590 /* Insert the suffix's value into the insn. */
591 if (operand->insert)
592 insn = (*operand->insert) (insn, operand,
593 mods, NULL, suffix->value,
594 NULL);
595 else
596 insn |= suffix->value << operand->shift;
597
598 str = t;
599 found = 1;
600 break;
601 }
602 }
603 }
252b5132
RH
604 ++syn;
605 if (!found)
19203624
KH
606 /* Wrong type. Just go on to try next insn entry. */
607 ;
252b5132
RH
608 else
609 {
610 if (num_suffixes == MAX_SUFFIXES)
0d2bcfaf 611 as_bad ("too many suffixes");
252b5132
RH
612 else
613 insn_suffixes[num_suffixes++] = suffix;
614 }
615 }
616 else
617 /* This is either a register or an expression of some kind. */
618 {
252b5132
RH
619 char *hold;
620 const struct arc_operand_value *reg = NULL;
621 long value = 0;
622 expressionS exp;
623
624 if (operand->flags & ARC_OPERAND_SUFFIX)
625 abort ();
626
627 /* Is there anything left to parse?
628 We don't check for this at the top because we want to parse
629 any trailing fake arguments in the syntax string. */
630 if (*str == '\0')
631 break;
252b5132
RH
632
633 /* Parse the operand. */
634 hold = input_line_pointer;
635 input_line_pointer = str;
636 expression (&exp);
637 str = input_line_pointer;
638 input_line_pointer = hold;
639
640 if (exp.X_op == O_illegal)
0d2bcfaf 641 as_bad ("illegal operand");
252b5132 642 else if (exp.X_op == O_absent)
0d2bcfaf 643 as_bad ("missing operand");
252b5132
RH
644 else if (exp.X_op == O_constant)
645 {
646 value = exp.X_add_number;
647 }
648 else if (exp.X_op == O_register)
649 {
0d2bcfaf 650 reg = (struct arc_operand_value *) exp.X_add_number;
252b5132 651 }
0d2bcfaf
NC
652#define IS_REG_DEST_OPERAND(o) ((o) == 'a')
653 else if (IS_REG_DEST_OPERAND (*syn))
19203624 654 as_bad ("symbol as destination register");
1e07b820 655 else
252b5132 656 {
19203624 657 if (!strncmp (str, "@h30", 4))
1e07b820 658 {
19203624 659 arc_code_symbol (&exp);
1e07b820
KH
660 str += 4;
661 }
252b5132
RH
662 /* We need to generate a fixup for this expression. */
663 if (fc >= MAX_FIXUPS)
0d2bcfaf 664 as_fatal ("too many fixups");
252b5132 665 fixups[fc].exp = exp;
1e07b820 666 /* We don't support shimm relocs. break here to force
19203624 667 the assembler to output a limm. */
0d2bcfaf 668#define IS_REG_SHIMM_OFFSET(o) ((o) == 'd')
19203624 669 if (IS_REG_SHIMM_OFFSET (*syn))
1e07b820 670 break;
252b5132
RH
671 /* If this is a register constant (IE: one whose
672 register value gets stored as 61-63) then this
bfb32b52 673 must be a limm. */
252b5132
RH
674 /* ??? This bit could use some cleaning up.
675 Referencing the format chars like this goes
676 against style. */
0d2bcfaf 677 if (IS_SYMBOL_OPERAND (*syn))
252b5132
RH
678 {
679 const char *junk;
252b5132 680 limm_reloc_p = 1;
19203624 681 /* Save this, we don't yet know what reloc to use. */
1e07b820 682 fix_up_at = fc;
252b5132
RH
683 /* Tell insert_reg we need a limm. This is
684 needed because the value at this point is
685 zero, a shimm. */
686 /* ??? We need a cleaner interface than this. */
687 (*arc_operands[arc_operand_map['Q']].insert)
688 (insn, operand, mods, reg, 0L, &junk);
689 }
690 else
4a314ec8 691 fixups[fc].opindex = arc_operand_map[(int) *syn];
252b5132
RH
692 ++fc;
693 value = 0;
694 }
695
696 /* Insert the register or expression into the instruction. */
697 if (operand->insert)
698 {
699 const char *errmsg = NULL;
700 insn = (*operand->insert) (insn, operand, mods,
701 reg, (long) value, &errmsg);
1e07b820
KH
702 if (errmsg != (const char *) NULL)
703 {
704 last_errmsg = errmsg;
705 if (operand->flags & ARC_OPERAND_ERROR)
706 {
707 as_bad (errmsg);
708 return;
709 }
710 else if (operand->flags & ARC_OPERAND_WARN)
711 as_warn (errmsg);
712 break;
713 }
252b5132
RH
714 }
715 else
716 insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
717
718 ++syn;
719 }
720 }
721
722 /* If we're at the end of the syntax string, we're done. */
723 /* FIXME: try to move this to a separate function. */
724 if (*syn == '\0')
725 {
726 int i;
727 char *f;
728 long limm, limm_p;
729
730 /* For the moment we assume a valid `str' can only contain blanks
731 now. IE: We needn't try again with a longer version of the
732 insn and it is assumed that longer versions of insns appear
733 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
734
735 while (isspace (*str))
736 ++str;
737
738 if (*str != '\0')
0d2bcfaf 739 as_bad ("junk at end of line: `%s'", str);
252b5132
RH
740
741 /* Is there a limm value? */
742 limm_p = arc_opcode_limm_p (&limm);
743
744 /* Perform various error and warning tests. */
745
746 {
747 static int in_delay_slot_p = 0;
748 static int prev_insn_needs_cc_nop_p = 0;
749 /* delay slot type seen */
750 int delay_slot_type = ARC_DELAY_NONE;
751 /* conditional execution flag seen */
752 int conditional = 0;
753 /* 1 if condition codes are being set */
754 int cc_set_p = 0;
755 /* 1 if conditional branch, including `b' "branch always" */
756 int cond_branch_p = opcode->flags & ARC_OPCODE_COND_BRANCH;
252b5132
RH
757
758 for (i = 0; i < num_suffixes; ++i)
759 {
760 switch (arc_operands[insn_suffixes[i]->type].fmt)
761 {
19203624 762 case 'n':
252b5132
RH
763 delay_slot_type = insn_suffixes[i]->value;
764 break;
19203624 765 case 'q':
252b5132
RH
766 conditional = insn_suffixes[i]->value;
767 break;
19203624 768 case 'f':
252b5132
RH
769 cc_set_p = 1;
770 break;
771 }
772 }
773
774 /* Putting an insn with a limm value in a delay slot is supposed to
775 be legal, but let's warn the user anyway. Ditto for 8 byte
776 jumps with delay slots. */
777 if (in_delay_slot_p && limm_p)
1e07b820 778 as_warn ("8 byte instruction in delay slot");
0d2bcfaf 779 if (delay_slot_type != ARC_DELAY_NONE
19203624 780 && limm_p && arc_insn_not_jl (insn)) /* except for jl addr */
1e07b820 781 as_warn ("8 byte jump instruction with delay slot");
252b5132
RH
782 in_delay_slot_p = (delay_slot_type != ARC_DELAY_NONE) && !limm_p;
783
784 /* Warn when a conditional branch immediately follows a set of
785 the condition codes. Note that this needn't be done if the
786 insn that sets the condition codes uses a limm. */
787 if (cond_branch_p && conditional != 0 /* 0 = "always" */
0d2bcfaf 788 && prev_insn_needs_cc_nop_p && arc_mach_type == bfd_mach_arc_5)
1e07b820 789 as_warn ("conditional branch follows set of flags");
0d2bcfaf 790 prev_insn_needs_cc_nop_p =
1e07b820
KH
791 /* FIXME: ??? not required:
792 (delay_slot_type != ARC_DELAY_NONE) && */
793 cc_set_p && !limm_p;
252b5132
RH
794 }
795
796 /* Write out the instruction.
797 It is important to fetch enough space in one call to `frag_more'.
798 We use (f - frag_now->fr_literal) to compute where we are and we
799 don't want frag_now to change between calls. */
800 if (limm_p)
801 {
802 f = frag_more (8);
803 md_number_to_chars (f, insn, 4);
804 md_number_to_chars (f + 4, limm, 4);
805 }
806 else if (limm_reloc_p)
807 {
808 /* We need a limm reloc, but the tables think we don't. */
809 abort ();
810 }
811 else
812 {
813 f = frag_more (4);
814 md_number_to_chars (f, insn, 4);
815 }
816
817 /* Create any fixups. */
818 for (i = 0; i < fc; ++i)
819 {
820 int op_type, reloc_type;
821 expressionS exptmp;
822 const struct arc_operand *operand;
823
824 /* Create a fixup for this operand.
825 At this point we do not use a bfd_reloc_code_real_type for
826 operands residing in the insn, but instead just use the
827 operand index. This lets us easily handle fixups for any
828 operand type, although that is admittedly not a very exciting
829 feature. We pick a BFD reloc type in md_apply_fix.
830
831 Limm values (4 byte immediate "constants") must be treated
832 normally because they're not part of the actual insn word
833 and thus the insertion routines don't handle them. */
834
835 if (arc_operands[fixups[i].opindex].flags & ARC_OPERAND_LIMM)
836 {
19203624
KH
837 /* Modify the fixup addend as required by the cpu. */
838 fixups[i].exp.X_add_number += arc_limm_fixup_adjust (insn);
252b5132
RH
839 op_type = fixups[i].opindex;
840 /* FIXME: can we add this data to the operand table? */
0d2bcfaf 841 if (op_type == arc_operand_map['L']
1e07b820
KH
842 || op_type == arc_operand_map['s']
843 || op_type == arc_operand_map['o']
844 || op_type == arc_operand_map['O'])
252b5132
RH
845 reloc_type = BFD_RELOC_32;
846 else if (op_type == arc_operand_map['J'])
847 reloc_type = BFD_RELOC_ARC_B26;
848 else
849 abort ();
850 reloc_type = get_arc_exp_reloc_type (1, reloc_type,
851 &fixups[i].exp,
852 &exptmp);
853 }
854 else
855 {
856 op_type = get_arc_exp_reloc_type (0, fixups[i].opindex,
857 &fixups[i].exp, &exptmp);
858 reloc_type = op_type + (int) BFD_RELOC_UNUSED;
859 }
860 operand = &arc_operands[op_type];
861 fix_new_exp (frag_now,
862 ((f - frag_now->fr_literal)
863 + (operand->flags & ARC_OPERAND_LIMM ? 4 : 0)), 4,
864 &exptmp,
865 (operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0,
866 (bfd_reloc_code_real_type) reloc_type);
867 }
868
869 /* All done. */
870 return;
871 }
872
873 /* Try the next entry. */
874 }
875
19203624 876 if (NULL == last_errmsg)
0d2bcfaf
NC
877 as_bad ("bad instruction `%s'", start);
878 else
879 as_bad (last_errmsg);
252b5132
RH
880}
881\f
252b5132 882static void
0d2bcfaf
NC
883arc_extoper (opertype)
884 int opertype;
252b5132
RH
885{
886 char *name;
0d2bcfaf 887 char *mode;
252b5132
RH
888 char c;
889 char *p;
0d2bcfaf
NC
890 int imode = 0;
891 int number;
892 struct arc_ext_operand_value *ext_oper;
252b5132
RH
893 symbolS *symbolP;
894
0d2bcfaf
NC
895 segT old_sec;
896 int old_subsec;
897
252b5132
RH
898 name = input_line_pointer;
899 c = get_symbol_end ();
19203624 900 name = xstrdup (name);
0d2bcfaf
NC
901 if (NULL == name)
902 {
19203624 903 ignore_rest_of_line ();
1e07b820 904 return;
0d2bcfaf
NC
905 }
906
907 p = name;
908 while (*p)
909 {
19203624
KH
910 if (isupper (*p))
911 *p = tolower (*p);
1e07b820 912 p++;
0d2bcfaf
NC
913 }
914
252b5132
RH
915 /* just after name is now '\0' */
916 p = input_line_pointer;
917 *p = c;
918 SKIP_WHITESPACE ();
0d2bcfaf 919
252b5132
RH
920 if (*input_line_pointer != ',')
921 {
0d2bcfaf 922 as_bad ("expected comma after operand name");
252b5132 923 ignore_rest_of_line ();
19203624 924 free (name);
252b5132
RH
925 return;
926 }
0d2bcfaf 927
252b5132 928 input_line_pointer++; /* skip ',' */
0d2bcfaf
NC
929 number = get_absolute_expression ();
930
19203624 931 if (number < 0)
0d2bcfaf 932 {
19203624
KH
933 as_bad ("negative operand number %d", number);
934 ignore_rest_of_line ();
935 free (name);
1e07b820 936 return;
0d2bcfaf
NC
937 }
938
939 if (opertype)
940 {
19203624 941 SKIP_WHITESPACE ();
0d2bcfaf
NC
942
943 if (*input_line_pointer != ',')
1e07b820
KH
944 {
945 as_bad ("expected comma after register-number");
946 ignore_rest_of_line ();
19203624 947 free (name);
1e07b820
KH
948 return;
949 }
bfb32b52 950
0d2bcfaf
NC
951 input_line_pointer++; /* skip ',' */
952 mode = input_line_pointer;
bfb32b52 953
19203624 954 if (!strncmp (mode, "r|w", 3))
1e07b820
KH
955 {
956 imode = 0;
957 input_line_pointer += 3;
958 }
0d2bcfaf 959 else
1e07b820 960 {
19203624 961 if (!strncmp (mode, "r", 1))
1e07b820
KH
962 {
963 imode = ARC_REGISTER_READONLY;
964 input_line_pointer += 1;
965 }
966 else
967 {
19203624 968 if (strncmp (mode, "w", 1))
1e07b820
KH
969 {
970 as_bad ("invalid mode");
19203624
KH
971 ignore_rest_of_line ();
972 free (name);
1e07b820
KH
973 return;
974 }
975 else
976 {
977 imode = ARC_REGISTER_WRITEONLY;
978 input_line_pointer += 1;
979 }
980 }
981 }
19203624 982 SKIP_WHITESPACE ();
1e07b820
KH
983 if (1 == opertype)
984 {
985 if (*input_line_pointer != ',')
986 {
987 as_bad ("expected comma after register-mode");
988 ignore_rest_of_line ();
19203624 989 free (name);
1e07b820
KH
990 return;
991 }
992
993 input_line_pointer++; /* skip ',' */
994
19203624 995 if (!strncmp (input_line_pointer, "cannot_shortcut", 15))
1e07b820 996 {
19203624 997 imode |= arc_get_noshortcut_flag ();
1e07b820
KH
998 input_line_pointer += 15;
999 }
1000 else
1001 {
19203624 1002 if (strncmp (input_line_pointer, "can_shortcut", 12))
1e07b820
KH
1003 {
1004 as_bad ("shortcut designator invalid");
19203624
KH
1005 ignore_rest_of_line ();
1006 free (name);
1e07b820
KH
1007 return;
1008 }
1009 else
1010 {
1011 input_line_pointer += 12;
1012 }
1013 }
1014 }
1015 }
0d2bcfaf
NC
1016
1017 if ((opertype == 1) && number > 60)
1e07b820 1018 {
19203624
KH
1019 as_bad ("core register value (%d) too large", number);
1020 ignore_rest_of_line ();
1021 free (name);
1e07b820
KH
1022 return;
1023 }
0d2bcfaf
NC
1024
1025 if ((opertype == 0) && number > 31)
1e07b820 1026 {
19203624
KH
1027 as_bad ("condition code value (%d) too large", number);
1028 ignore_rest_of_line ();
1029 free (name);
1e07b820
KH
1030 return;
1031 }
0d2bcfaf
NC
1032
1033 ext_oper = (struct arc_ext_operand_value *) \
19203624 1034 xmalloc (sizeof (struct arc_ext_operand_value));
0d2bcfaf 1035
19203624 1036 if (opertype)
0d2bcfaf 1037 {
19203624 1038 /* If the symbol already exists, point it at the new definition. */
0d2bcfaf 1039 if ((symbolP = symbol_find (name)))
1e07b820 1040 {
19203624
KH
1041 if (S_GET_SEGMENT (symbolP) == reg_section)
1042 S_SET_VALUE (symbolP, (int) &ext_oper->operand);
1e07b820
KH
1043 else
1044 {
19203624
KH
1045 as_bad ("attempt to override symbol: %s", name);
1046 ignore_rest_of_line ();
1047 free (name);
1048 free (ext_oper);
1e07b820
KH
1049 return;
1050 }
1051 }
0d2bcfaf 1052 else
1e07b820 1053 {
19203624 1054 /* If its not there, add it. */
1e07b820
KH
1055 symbol_table_insert (symbol_create (name, reg_section,
1056 (int) &ext_oper->operand, &zero_address_frag));
1057 }
0d2bcfaf
NC
1058 }
1059
1060 ext_oper->operand.name = name;
1061 ext_oper->operand.value = number;
19203624 1062 ext_oper->operand.type = arc_operand_type (opertype);
0d2bcfaf
NC
1063 ext_oper->operand.flags = imode;
1064
1065 ext_oper->next = arc_ext_operands;
1066 arc_ext_operands = ext_oper;
1067
19203624
KH
1068 /* OK, now that we know what this operand is, put a description in
1069 the arc extension section of the output file. */
0d2bcfaf
NC
1070
1071 old_sec = now_seg;
1072 old_subsec = now_subseg;
1073
19203624 1074 arc_set_ext_seg ();
0d2bcfaf
NC
1075
1076 switch (opertype)
1e07b820
KH
1077 {
1078 case 0:
19203624
KH
1079 p = frag_more (1);
1080 *p = 3 + strlen (name) + 1;
1081 p = frag_more (1);
1e07b820 1082 *p = EXT_COND_CODE;
19203624 1083 p = frag_more (1);
1e07b820 1084 *p = number;
19203624
KH
1085 p = frag_more (strlen (name) + 1);
1086 strcpy (p, name);
1e07b820
KH
1087 break;
1088 case 1:
19203624
KH
1089 p = frag_more (1);
1090 *p = 3 + strlen (name) + 1;
1091 p = frag_more (1);
1e07b820 1092 *p = EXT_CORE_REGISTER;
19203624 1093 p = frag_more (1);
1e07b820 1094 *p = number;
19203624
KH
1095 p = frag_more (strlen (name) + 1);
1096 strcpy (p, name);
1e07b820
KH
1097 break;
1098 case 2:
19203624
KH
1099 p = frag_more (1);
1100 *p = 6 + strlen (name) + 1;
1101 p = frag_more (1);
1e07b820 1102 *p = EXT_AUX_REGISTER;
19203624 1103 p = frag_more (1);
1e07b820 1104 *p = number >> 24 & 0xff;
19203624 1105 p = frag_more (1);
1e07b820 1106 *p = number >> 16 & 0xff;
19203624 1107 p = frag_more (1);
1e07b820 1108 *p = number >> 8 & 0xff;
19203624 1109 p = frag_more (1);
1e07b820 1110 *p = number & 0xff;
19203624
KH
1111 p = frag_more (strlen (name) + 1);
1112 strcpy (p, name);
1e07b820
KH
1113 break;
1114 default:
19203624
KH
1115 as_bad ("invalid opertype");
1116 ignore_rest_of_line ();
1117 free (name);
1e07b820
KH
1118 return;
1119 break;
1120 }
0d2bcfaf
NC
1121
1122 subseg_set (old_sec, old_subsec);
1123
19203624 1124 /* Enter all registers into the symbol table. */
0d2bcfaf 1125
19203624 1126 demand_empty_rest_of_line ();
0d2bcfaf
NC
1127}
1128
1129static void
1130arc_extinst (ignore)
19203624 1131 int ignore ATTRIBUTE_UNUSED;
0d2bcfaf
NC
1132{
1133 unsigned char syntax[129];
1134 char *name;
1135 char *p;
1136 char c;
1137 int suffixcode = -1;
19203624 1138 int opcode, subopcode;
0d2bcfaf
NC
1139 int i;
1140 int class = 0;
1141 int name_len;
1142 struct arc_opcode *ext_op;
1143
1144 segT old_sec;
1145 int old_subsec;
1146
1147 name = input_line_pointer;
1148 c = get_symbol_end ();
19203624 1149 name = xstrdup (name);
0d2bcfaf
NC
1150 if (NULL == name)
1151 {
19203624 1152 ignore_rest_of_line ();
1e07b820 1153 return;
0d2bcfaf 1154 }
19203624
KH
1155 strcpy (syntax, name);
1156 name_len = strlen (name);
0d2bcfaf
NC
1157
1158 /* just after name is now '\0' */
1159 p = input_line_pointer;
1160 *p = c;
1161
1162 SKIP_WHITESPACE ();
1163
1164 if (*input_line_pointer != ',')
252b5132 1165 {
0d2bcfaf 1166 as_bad ("expected comma after operand name");
252b5132
RH
1167 ignore_rest_of_line ();
1168 return;
1169 }
0d2bcfaf
NC
1170
1171 input_line_pointer++; /* skip ',' */
1172 opcode = get_absolute_expression ();
1173
1174 SKIP_WHITESPACE ();
1175
1176 if (*input_line_pointer != ',')
252b5132 1177 {
0d2bcfaf 1178 as_bad ("expected comma after opcode");
252b5132
RH
1179 ignore_rest_of_line ();
1180 return;
1181 }
0d2bcfaf
NC
1182
1183 input_line_pointer++; /* skip ',' */
1184 subopcode = get_absolute_expression ();
1185
19203624 1186 if (subopcode < 0)
252b5132 1187 {
19203624
KH
1188 as_bad ("negative subopcode %d", subopcode);
1189 ignore_rest_of_line ();
1e07b820 1190 return;
252b5132 1191 }
0d2bcfaf 1192
19203624 1193 if (subopcode)
0d2bcfaf 1194 {
19203624 1195 if (3 != opcode)
1e07b820
KH
1196 {
1197 as_bad ("subcode value found when opcode not equal 0x03");
19203624 1198 ignore_rest_of_line ();
1e07b820
KH
1199 return;
1200 }
1201 else
1202 {
1203 if (subopcode < 0x09 || subopcode == 0x3f)
1204 {
1205 as_bad ("invalid subopcode %d", subopcode);
19203624 1206 ignore_rest_of_line ();
1e07b820
KH
1207 return;
1208 }
1209 }
0d2bcfaf
NC
1210 }
1211
1212 SKIP_WHITESPACE ();
1213
252b5132
RH
1214 if (*input_line_pointer != ',')
1215 {
0d2bcfaf 1216 as_bad ("expected comma after subopcode");
252b5132
RH
1217 ignore_rest_of_line ();
1218 return;
1219 }
0d2bcfaf
NC
1220
1221 input_line_pointer++; /* skip ',' */
1222
19203624 1223 for (i = 0; i < (int) MAXSUFFIXCLASS; i++)
0d2bcfaf 1224 {
19203624 1225 if (!strncmp (suffixclass[i].name,input_line_pointer, suffixclass[i].len))
1e07b820
KH
1226 {
1227 suffixcode = i;
1228 input_line_pointer += suffixclass[i].len;
1229 break;
1230 }
0d2bcfaf
NC
1231 }
1232
19203624 1233 if (-1 == suffixcode)
0d2bcfaf
NC
1234 {
1235 as_bad ("invalid suffix class");
1236 ignore_rest_of_line ();
1237 return;
1238 }
1239
252b5132 1240 SKIP_WHITESPACE ();
0d2bcfaf
NC
1241
1242 if (*input_line_pointer != ',')
252b5132 1243 {
0d2bcfaf
NC
1244 as_bad ("expected comma after suffix class");
1245 ignore_rest_of_line ();
1246 return;
252b5132 1247 }
0d2bcfaf
NC
1248
1249 input_line_pointer++; /* skip ',' */
1250
19203624 1251 for (i = 0; i < (int) MAXSYNTAXCLASS; i++)
252b5132 1252 {
19203624 1253 if (!strncmp (syntaxclass[i].name,input_line_pointer, syntaxclass[i].len))
1e07b820
KH
1254 {
1255 class = syntaxclass[i].class;
1256 input_line_pointer += syntaxclass[i].len;
1257 break;
1258 }
252b5132 1259 }
252b5132 1260
19203624 1261 if (0 == (SYNTAX_VALID & class))
0d2bcfaf
NC
1262 {
1263 as_bad ("invalid syntax class");
1264 ignore_rest_of_line ();
1265 return;
1266 }
1267
19203624 1268 if ((0x3 == opcode) & (class & SYNTAX_3OP))
0d2bcfaf
NC
1269 {
1270 as_bad ("opcode 0x3 and SYNTAX_3OP invalid");
1271 ignore_rest_of_line ();
1272 return;
1273 }
1274
1275 switch (suffixcode)
1e07b820
KH
1276 {
1277 case 0:
19203624 1278 strcat (syntax, "%.q%.f ");
1e07b820
KH
1279 break;
1280 case 1:
19203624 1281 strcat (syntax, "%.f ");
1e07b820
KH
1282 break;
1283 case 2:
19203624 1284 strcat (syntax, "%.q ");
1e07b820
KH
1285 break;
1286 case 3:
19203624 1287 strcat (syntax, " ");
1e07b820
KH
1288 break;
1289 default:
19203624
KH
1290 as_bad ("unknown suffix class");
1291 ignore_rest_of_line ();
1e07b820
KH
1292 return;
1293 break;
1294 };
0d2bcfaf 1295
19203624
KH
1296 strcat (syntax, ((opcode == 0x3) ? "%a,%b" : ((class & SYNTAX_3OP) ? "%a,%b,%c" : "%b,%c")));
1297 if (suffixcode < 2)
1298 strcat (syntax, "%F");
1299 strcat (syntax, "%S%L");
0d2bcfaf 1300
19203624
KH
1301 ext_op = (struct arc_opcode *) xmalloc (sizeof (struct arc_opcode));
1302 if (NULL == ext_op)
0d2bcfaf 1303 {
1e07b820
KH
1304 ignore_rest_of_line ();
1305 return;
0d2bcfaf
NC
1306 }
1307
19203624 1308 ext_op->syntax = xstrdup (syntax);
0d2bcfaf
NC
1309 if (NULL == ext_op->syntax)
1310 {
1e07b820
KH
1311 ignore_rest_of_line ();
1312 return;
0d2bcfaf
NC
1313 }
1314
19203624
KH
1315 ext_op->mask = I (-1) | ((0x3 == opcode) ? C (-1) : 0);
1316 ext_op->value = I (opcode) | ((0x3 == opcode) ? C (subopcode) : 0);
0d2bcfaf
NC
1317 ext_op->flags = class;
1318 ext_op->next_asm = arc_ext_opcodes;
1319 ext_op->next_dis = arc_ext_opcodes;
1320 arc_ext_opcodes = ext_op;
1321
19203624
KH
1322 /* OK, now that we know what this inst is, put a description in the
1323 arc extension section of the output file. */
0d2bcfaf
NC
1324
1325 old_sec = now_seg;
1326 old_subsec = now_subseg;
1327
19203624 1328 arc_set_ext_seg ();
0d2bcfaf 1329
19203624
KH
1330 p = frag_more (1);
1331 *p = 5 + name_len + 1;
1332 p = frag_more (1);
0d2bcfaf 1333 *p = EXT_INSTRUCTION;
19203624 1334 p = frag_more (1);
0d2bcfaf 1335 *p = opcode;
19203624 1336 p = frag_more (1);
0d2bcfaf 1337 *p = subopcode;
19203624 1338 p = frag_more (1);
0d2bcfaf 1339 *p = (class & (OP1_MUST_BE_IMM | OP1_IMM_IMPLIED) ? IGNORE_FIRST_OPD : 0);
19203624
KH
1340 p = frag_more (name_len);
1341 strncpy (p, syntax, name_len);
1342 p = frag_more (1);
0d2bcfaf
NC
1343 *p = '\0';
1344
1345 subseg_set (old_sec, old_subsec);
1346
19203624 1347 demand_empty_rest_of_line ();
252b5132
RH
1348}
1349
0d2bcfaf 1350int
19203624 1351arc_set_ext_seg ()
0d2bcfaf
NC
1352{
1353 if (!arcext_section)
1354 {
1355 arcext_section = subseg_new (".arcextmap", 0);
1356 bfd_set_section_flags (stdoutput, arcext_section,
19203624 1357 SEC_READONLY | SEC_HAS_CONTENTS);
0d2bcfaf
NC
1358 }
1359 else
1360 subseg_set (arcext_section, 0);
1361 return 1;
1362}
252b5132
RH
1363
1364static void
0d2bcfaf
NC
1365arc_common (localScope)
1366 int localScope;
252b5132 1367{
0d2bcfaf 1368 char *name;
252b5132 1369 char c;
0d2bcfaf 1370 char *p;
19203624 1371 int align, size;
0d2bcfaf 1372 symbolS *symbolP;
252b5132 1373
0d2bcfaf
NC
1374 name = input_line_pointer;
1375 c = get_symbol_end ();
1376 /* just after name is now '\0' */
1377 p = input_line_pointer;
1378 *p = c;
1379 SKIP_WHITESPACE ();
1380
1381 if (*input_line_pointer != ',')
252b5132 1382 {
0d2bcfaf 1383 as_bad ("expected comma after symbol name");
252b5132
RH
1384 ignore_rest_of_line ();
1385 return;
1386 }
1387
0d2bcfaf
NC
1388 input_line_pointer++; /* skip ',' */
1389 size = get_absolute_expression ();
252b5132 1390
0d2bcfaf
NC
1391 if (size < 0)
1392 {
1393 as_bad ("negative symbol length");
1394 ignore_rest_of_line ();
1395 return;
1396 }
252b5132 1397
0d2bcfaf
NC
1398 *p = 0;
1399 symbolP = symbol_find_or_make (name);
1400 *p = c;
1401
1402 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
1403 {
1404 as_bad ("ignoring attempt to re-define symbol");
1405 ignore_rest_of_line ();
1406 return;
1407 }
19203624
KH
1408 if (((int) S_GET_VALUE (symbolP) != 0) \
1409 && ((int) S_GET_VALUE (symbolP) != size))
0d2bcfaf
NC
1410 {
1411 as_warn ("length of symbol \"%s\" already %ld, ignoring %d",
1412 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
1413 }
1414 assert (symbolP->sy_frag == &zero_address_frag);
1415
0d2bcfaf
NC
1416 /* Now parse the alignment field. This field is optional for
1417 local and global symbols. Default alignment is zero. */
1418 if (*input_line_pointer == ',')
1419 {
1420 input_line_pointer++;
1421 align = get_absolute_expression ();
1422 if (align < 0)
1423 {
1424 align = 0;
1425 as_warn ("assuming symbol alignment of zero");
1426 }
1427 }
252b5132 1428 else
0d2bcfaf
NC
1429 align = 0;
1430
1431 if (localScope != 0)
252b5132 1432 {
0d2bcfaf
NC
1433 segT old_sec;
1434 int old_subsec;
1435 char *pfrag;
1436
1437 old_sec = now_seg;
1438 old_subsec = now_subseg;
1439 record_alignment (bss_section, align);
1440 subseg_set (bss_section, 0); /* ??? subseg_set (bss_section, 1); ??? */
1441
1442 if (align)
19203624
KH
1443 /* Do alignment. */
1444 frag_align (align, 0, 0);
0d2bcfaf 1445
19203624 1446 /* Detach from old frag. */
0d2bcfaf
NC
1447 if (S_GET_SEGMENT (symbolP) == bss_section)
1448 symbolP->sy_frag->fr_symbol = NULL;
1449
1450 symbolP->sy_frag = frag_now;
1451 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
19203624 1452 (offsetT) size, (char *) 0);
0d2bcfaf
NC
1453 *pfrag = 0;
1454
1455 S_SET_SIZE (symbolP, size);
1456 S_SET_SEGMENT (symbolP, bss_section);
1457 S_CLEAR_EXTERNAL (symbolP);
1458 symbolP->local = 1;
1459 subseg_set (old_sec, old_subsec);
1460 }
1461 else
1462 {
1463 S_SET_VALUE (symbolP, (valueT) size);
1464 S_SET_ALIGN (symbolP, align);
1465 S_SET_EXTERNAL (symbolP);
1466 S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
252b5132 1467 }
252b5132 1468
0d2bcfaf
NC
1469 symbolP->bsym->flags |= BSF_OBJECT;
1470
1471 demand_empty_rest_of_line ();
1472 return;
252b5132 1473}
0d2bcfaf 1474\f
0d2bcfaf 1475/* Select the cpu we're assembling for. */
252b5132
RH
1476
1477static void
0d2bcfaf 1478arc_option (ignore)
19203624 1479 int ignore ATTRIBUTE_UNUSED;
252b5132 1480{
0d2bcfaf 1481 int mach;
252b5132 1482 char c;
0d2bcfaf 1483 char *cpu;
252b5132 1484
0d2bcfaf 1485 cpu = input_line_pointer;
252b5132 1486 c = get_symbol_end ();
0d2bcfaf 1487 mach = arc_get_mach (cpu);
252b5132
RH
1488 *input_line_pointer = c;
1489
0d2bcfaf
NC
1490 /* If an instruction has already been seen, it's too late. */
1491 if (cpu_tables_init_p)
252b5132 1492 {
0d2bcfaf 1493 as_bad ("\".option\" directive must appear before any instructions");
252b5132
RH
1494 ignore_rest_of_line ();
1495 return;
1496 }
252b5132 1497
0d2bcfaf
NC
1498 if (mach == -1)
1499 goto bad_cpu;
1500
1501 if (mach_type_specified_p && mach != arc_mach_type)
252b5132 1502 {
0d2bcfaf 1503 as_bad ("\".option\" directive conflicts with initial definition");
252b5132
RH
1504 ignore_rest_of_line ();
1505 return;
1506 }
0d2bcfaf
NC
1507 else
1508 {
1509 /* The cpu may have been selected on the command line. */
1510 if (mach != arc_mach_type)
1511 as_warn ("\".option\" directive overrides command-line (default) value");
1512 arc_mach_type = mach;
1513 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
1514 as_fatal ("could not set architecture and machine");
1515 mach_type_specified_p = 1;
1516 }
252b5132 1517 demand_empty_rest_of_line ();
0d2bcfaf
NC
1518 return;
1519
1520 bad_cpu:
1521 as_bad ("invalid identifier for \".option\"");
1522 ignore_rest_of_line ();
252b5132 1523}
252b5132 1524\f
19203624
KH
1525/* Turn a string in input_line_pointer into a floating point constant
1526 of type TYPE, and store the appropriate bytes in *LITP. The number
1527 of LITTLENUMS emitted is stored in *SIZEP. An error message is
1528 returned, or NULL on OK. */
252b5132 1529
0d2bcfaf 1530/* Equal to MAX_PRECISION in atof-ieee.c */
252b5132
RH
1531#define MAX_LITTLENUMS 6
1532
1533char *
1534md_atof (type, litP, sizeP)
19203624
KH
1535 char type;
1536 char *litP;
1537 int *sizeP;
252b5132
RH
1538{
1539 int prec;
1540 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1541 LITTLENUM_TYPE *wordP;
1542 char *t;
1543 char *atof_ieee ();
1544
1545 switch (type)
1546 {
1547 case 'f':
1548 case 'F':
1549 prec = 2;
1550 break;
1551
1552 case 'd':
1553 case 'D':
1554 prec = 4;
1555 break;
1556
1557 default:
1558 *sizeP = 0;
0d2bcfaf 1559 return "bad call to md_atof";
252b5132
RH
1560 }
1561
1562 t = atof_ieee (input_line_pointer, type, words);
1563 if (t)
1564 input_line_pointer = t;
1565 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1566 for (wordP = words; prec--;)
1567 {
1568 md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
1569 litP += sizeof (LITTLENUM_TYPE);
1570 }
1571
1572 return NULL;
1573}
1574
1575/* Write a value out to the object file, using the appropriate
1576 endianness. */
1577
1578void
1579md_number_to_chars (buf, val, n)
1580 char *buf;
1581 valueT val;
1582 int n;
1583{
1584 if (target_big_endian)
1585 number_to_chars_bigendian (buf, val, n);
1586 else
1587 number_to_chars_littleendian (buf, val, n);
1588}
1589
bfb32b52 1590/* Round up a section size to the appropriate boundary. */
252b5132
RH
1591
1592valueT
1593md_section_align (segment, size)
1594 segT segment;
1595 valueT size;
1596{
1597 int align = bfd_get_section_alignment (stdoutput, segment);
1598
1599 return ((size + (1 << align) - 1) & (-1 << align));
1600}
1601
1602/* We don't have any form of relaxing. */
1603
1604int
1605md_estimate_size_before_relax (fragp, seg)
4a314ec8
NC
1606 fragS *fragp ATTRIBUTE_UNUSED;
1607 asection *seg ATTRIBUTE_UNUSED;
252b5132 1608{
0d2bcfaf
NC
1609 as_fatal (_("md_estimate_size_before_relax\n"));
1610 return 1;
252b5132
RH
1611}
1612
1613/* Convert a machine dependent frag. We never generate these. */
1614
1615void
1616md_convert_frag (abfd, sec, fragp)
4a314ec8
NC
1617 bfd *abfd ATTRIBUTE_UNUSED;
1618 asection *sec ATTRIBUTE_UNUSED;
1619 fragS *fragp ATTRIBUTE_UNUSED;
252b5132 1620{
0d2bcfaf
NC
1621 as_fatal (_("md_convert_frag\n"));
1622}
1623
1624void
19203624 1625arc_code_symbol (expressionP)
0d2bcfaf
NC
1626 expressionS *expressionP;
1627{
1628 if (expressionP->X_op == O_symbol && expressionP->X_add_number == 0
1e07b820
KH
1629 /* I think this test is unnecessary but just as a sanity check... */
1630 && expressionP->X_op_symbol == NULL)
0d2bcfaf 1631 {
1e07b820
KH
1632 expressionS two;
1633 expressionP->X_op = O_right_shift;
1634 two.X_op = O_constant;
1635 two.X_add_symbol = two.X_op_symbol = NULL;
1636 two.X_add_number = 2;
1637 expressionP->X_op_symbol = make_expr_symbol (&two);
0d2bcfaf 1638 }
19203624
KH
1639 /* Allow %st(sym1-sym2) */
1640 else if (expressionP->X_op == O_subtract
1641 && expressionP->X_add_symbol != NULL
1642 && expressionP->X_op_symbol != NULL
1643 && expressionP->X_add_number == 0)
0d2bcfaf 1644 {
1e07b820
KH
1645 expressionS two;
1646 expressionP->X_add_symbol = make_expr_symbol (expressionP);
1647 expressionP->X_op = O_right_shift;
1648 two.X_op = O_constant;
1649 two.X_add_symbol = two.X_op_symbol = NULL;
1650 two.X_add_number = 2;
1651 expressionP->X_op_symbol = make_expr_symbol (&two);
0d2bcfaf
NC
1652 }
1653 else
1654 {
1e07b820
KH
1655 as_bad ("expression too complex code symbol");
1656 return;
0d2bcfaf 1657 }
252b5132
RH
1658}
1659
1660/* Parse an operand that is machine-specific.
1661
1662 The ARC has a special %-op to adjust addresses so they're usable in
1663 branches. The "st" is short for the STatus register.
1664 ??? Later expand this to take a flags value too.
1665
1666 ??? We can't create new expression types so we map the %-op's onto the
1667 existing syntax. This means that the user could use the chosen syntax
bfb32b52 1668 to achieve the same effect. */
252b5132 1669
bfb32b52 1670void
252b5132
RH
1671md_operand (expressionP)
1672 expressionS *expressionP;
1673{
1674 char *p = input_line_pointer;
1675
0d2bcfaf 1676 if (*p == '%')
19203624 1677 if (strncmp (p, "%st(", 4) == 0)
0d2bcfaf 1678 {
1e07b820
KH
1679 input_line_pointer += 4;
1680 expression (expressionP);
1681 if (*input_line_pointer != ')')
1682 {
1683 as_bad ("missing ')' in %%-op");
1684 return;
1685 }
1686 ++input_line_pointer;
19203624 1687 arc_code_symbol (expressionP);
0d2bcfaf 1688 }
1e07b820 1689 else
19203624
KH
1690 { /* It could be a register. */
1691 int i, l;
1e07b820
KH
1692 struct arc_ext_operand_value *ext_oper = arc_ext_operands;
1693 p++;
0d2bcfaf 1694
1e07b820
KH
1695 while (ext_oper)
1696 {
19203624
KH
1697 l = strlen (ext_oper->operand.name);
1698 if (!strncmp (p, ext_oper->operand.name, l) && !isalnum(*(p + l)))
1e07b820
KH
1699 {
1700 input_line_pointer += l + 1;
1701 expressionP->X_op = O_register;
1702 expressionP->X_add_number = (int) &ext_oper->operand;
1703 return;
1704 }
1705 ext_oper = ext_oper->next;
1706 }
1707 for (i = 0; i < arc_reg_names_count; i++)
1708 {
19203624
KH
1709 l = strlen (arc_reg_names[i].name);
1710 if (!strncmp (p, arc_reg_names[i].name, l) && !isalnum (*(p + l)))
1e07b820
KH
1711 {
1712 input_line_pointer += l + 1;
1713 expressionP->X_op = O_register;
19203624 1714 expressionP->X_add_number = (int) &arc_reg_names[i];
1e07b820
KH
1715 break;
1716 }
1717 }
0d2bcfaf 1718 }
252b5132
RH
1719}
1720
1721/* We have no need to default values of symbols.
1722 We could catch register names here, but that is handled by inserting
1723 them all in the symbol table to begin with. */
1724
1725symbolS *
1726md_undefined_symbol (name)
4a314ec8 1727 char *name ATTRIBUTE_UNUSED;
252b5132
RH
1728{
1729 return 0;
1730}
1731\f
1732/* Functions concerning expressions. */
1733
1734/* Parse a .byte, .word, etc. expression.
1735
1736 Values for the status register are specified with %st(label).
1737 `label' will be right shifted by 2. */
1738
1739void
1740arc_parse_cons_expression (exp, nbytes)
19203624
KH
1741 expressionS *exp;
1742 unsigned int nbytes ATTRIBUTE_UNUSED;
252b5132 1743{
0d2bcfaf
NC
1744 char *p = input_line_pointer;
1745 int code_symbol_fix = 0;
1746
19203624
KH
1747 for (; ! is_end_of_line[(unsigned char) *p]; p++)
1748 if (*p == '@' && !strncmp (p, "@h30", 4))
0d2bcfaf 1749 {
1e07b820 1750 code_symbol_fix = 1;
19203624 1751 strcpy (p, "; ");
0d2bcfaf 1752 }
1e07b820
KH
1753 expr (0, exp);
1754 if (code_symbol_fix)
1755 {
19203624 1756 arc_code_symbol (exp);
1e07b820
KH
1757 input_line_pointer = p;
1758 }
252b5132
RH
1759}
1760
1761/* Record a fixup for a cons expression. */
1762
1763void
1764arc_cons_fix_new (frag, where, nbytes, exp)
1765 fragS *frag;
1766 int where;
1767 int nbytes;
1768 expressionS *exp;
1769{
1770 if (nbytes == 4)
1771 {
1772 int reloc_type;
1773 expressionS exptmp;
1774
1775 /* This may be a special ARC reloc (eg: %st()). */
1776 reloc_type = get_arc_exp_reloc_type (1, BFD_RELOC_32, exp, &exptmp);
1777 fix_new_exp (frag, where, nbytes, &exptmp, 0, reloc_type);
1778 }
1779 else
1780 {
1781 fix_new_exp (frag, where, nbytes, exp, 0,
1782 nbytes == 2 ? BFD_RELOC_16
1783 : nbytes == 8 ? BFD_RELOC_64
1784 : BFD_RELOC_32);
1785 }
1786}
1787\f
1788/* Functions concerning relocs. */
1789
1790/* The location from which a PC relative jump should be calculated,
1791 given a PC relative reloc. */
1792
bfb32b52 1793long
252b5132
RH
1794md_pcrel_from (fixP)
1795 fixS *fixP;
1796{
1797 if (fixP->fx_addsy != (symbolS *) NULL
1798 && ! S_IS_DEFINED (fixP->fx_addsy))
1799 {
1800 /* The symbol is undefined. Let the linker figure it out. */
1801 return 0;
1802 }
1803
1804 /* Return the address of the delay slot. */
1805 return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
1806}
1807
1808/* Compute the reloc type of an expression.
1809 The possibly modified expression is stored in EXPNEW.
1810
1811 This is used to convert the expressions generated by the %-op's into
1812 the appropriate operand type. It is called for both data in instructions
1813 (operands) and data outside instructions (variables, debugging info, etc.).
1814
1815 Currently supported %-ops:
1816
1817 %st(symbol): represented as "symbol >> 2"
1818 "st" is short for STatus as in the status register (pc)
1819
1820 DEFAULT_TYPE is the type to use if no special processing is required.
1821
1822 DATA_P is non-zero for data or limm values, zero for insn operands.
1823 Remember that the opcode "insertion fns" cannot be used on data, they're
1824 only for inserting operands into insns. They also can't be used for limm
1825 values as the insertion routines don't handle limm values. When called for
1826 insns we return fudged reloc types (real_value - BFD_RELOC_UNUSED). When
1827 called for data or limm values we use real reloc types. */
1828
1829static int
1830get_arc_exp_reloc_type (data_p, default_type, exp, expnew)
1831 int data_p;
1832 int default_type;
1833 expressionS *exp;
1834 expressionS *expnew;
1835{
1836 /* If the expression is "symbol >> 2" we must change it to just "symbol",
1837 as fix_new_exp can't handle it. Similarily for (symbol - symbol) >> 2.
1838 That's ok though. What's really going on here is that we're using
1839 ">> 2" as a special syntax for specifying BFD_RELOC_ARC_B26. */
1840
1841 if (exp->X_op == O_right_shift
1842 && exp->X_op_symbol != NULL
0d2bcfaf
NC
1843 && exp->X_op_symbol->sy_value.X_op == O_constant
1844 && exp->X_op_symbol->sy_value.X_add_number == 2
252b5132
RH
1845 && exp->X_add_number == 0)
1846 {
1847 if (exp->X_add_symbol != NULL
0d2bcfaf
NC
1848 && (exp->X_add_symbol->sy_value.X_op == O_constant
1849 || exp->X_add_symbol->sy_value.X_op == O_symbol))
252b5132
RH
1850 {
1851 *expnew = *exp;
1852 expnew->X_op = O_symbol;
1853 expnew->X_op_symbol = NULL;
1854 return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
1855 }
1856 else if (exp->X_add_symbol != NULL
0d2bcfaf 1857 && exp->X_add_symbol->sy_value.X_op == O_subtract)
252b5132 1858 {
0d2bcfaf 1859 *expnew = exp->X_add_symbol->sy_value;
252b5132
RH
1860 return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
1861 }
1862 }
1863
1864 *expnew = *exp;
1865 return default_type;
1866}
1867
1868/* Apply a fixup to the object code. This is called for all the
1869 fixups we generated by the call to fix_new_exp, above. In the call
1870 above we used a reloc code which was the largest legal reloc code
1871 plus the operand index. Here we undo that to recover the operand
1872 index. At this point all symbol values should be fully resolved,
1873 and we attempt to completely resolve the reloc. If we can not do
1874 that, we determine the correct reloc code and put it back in the fixup. */
1875
1876int
1877md_apply_fix3 (fixP, valueP, seg)
1878 fixS *fixP;
1879 valueT *valueP;
1880 segT seg;
1881{
19203624
KH
1882#if 0
1883 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1884#endif
252b5132
RH
1885 valueT value;
1886
1887 /* FIXME FIXME FIXME: The value we are passed in *valueP includes
1888 the symbol values. Since we are using BFD_ASSEMBLER, if we are
1889 doing this relocation the code in write.c is going to call
1890 bfd_perform_relocation, which is also going to use the symbol
1891 value. That means that if the reloc is fully resolved we want to
1892 use *valueP since bfd_perform_relocation is not being used.
1893 However, if the reloc is not fully resolved we do not want to use
1894 *valueP, and must use fx_offset instead. However, if the reloc
1895 is PC relative, we do want to use *valueP since it includes the
1896 result of md_pcrel_from. This is confusing. */
1897
1898 if (fixP->fx_addsy == (symbolS *) NULL)
1899 {
1900 value = *valueP;
1901 fixP->fx_done = 1;
1902 }
1903 else if (fixP->fx_pcrel)
1904 {
1905 value = *valueP;
1906 /* ELF relocations are against symbols.
1907 If this symbol is in a different section then we need to leave it for
1908 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
1909 so we have to undo it's effects here. */
1910 if (S_IS_DEFINED (fixP->fx_addsy)
1911 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
1912 value += md_pcrel_from (fixP);
1913 }
1914 else
1915 {
1916 value = fixP->fx_offset;
1917 if (fixP->fx_subsy != (symbolS *) NULL)
1918 {
1919 if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)
1920 value -= S_GET_VALUE (fixP->fx_subsy);
1921 else
1922 {
1923 /* We can't actually support subtracting a symbol. */
1924 as_bad_where (fixP->fx_file, fixP->fx_line,
0d2bcfaf 1925 "expression too complex");
252b5132
RH
1926 }
1927 }
1928 }
1929
1930 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
1931 {
1932 int opindex;
1933 const struct arc_operand *operand;
1934 char *where;
1935 arc_insn insn;
1936
1937 opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
1938
1939 operand = &arc_operands[opindex];
1940
1941 /* Fetch the instruction, insert the fully resolved operand
1942 value, and stuff the instruction back again. */
1943 where = fixP->fx_frag->fr_literal + fixP->fx_where;
1944 if (target_big_endian)
1945 insn = bfd_getb32 ((unsigned char *) where);
1946 else
1947 insn = bfd_getl32 ((unsigned char *) where);
1948 insn = arc_insert_operand (insn, operand, -1, NULL, (offsetT) value,
1949 fixP->fx_file, fixP->fx_line);
1950 if (target_big_endian)
1951 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1952 else
1953 bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
1954
1955 if (fixP->fx_done)
1956 {
1957 /* Nothing else to do here. */
1958 return 1;
1959 }
1960
1961 /* Determine a BFD reloc value based on the operand information.
1962 We are only prepared to turn a few of the operands into relocs.
1963 !!! Note that we can't handle limm values here. Since we're using
1964 implicit addends the addend must be inserted into the instruction,
1965 however, the opcode insertion routines currently do nothing with
1966 limm values. */
1967 if (operand->fmt == 'B')
1968 {
1969 assert ((operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0
1970 && operand->bits == 20
1971 && operand->shift == 7);
1972 fixP->fx_r_type = BFD_RELOC_ARC_B22_PCREL;
1973 }
0d2bcfaf 1974 else if (operand->fmt == 'J')
252b5132
RH
1975 {
1976 assert ((operand->flags & ARC_OPERAND_ABSOLUTE_BRANCH) != 0
1977 && operand->bits == 24
1978 && operand->shift == 32);
1979 fixP->fx_r_type = BFD_RELOC_ARC_B26;
1980 }
0d2bcfaf 1981 else if (operand->fmt == 'L')
252b5132
RH
1982 {
1983 assert ((operand->flags & ARC_OPERAND_LIMM) != 0
1984 && operand->bits == 32
1985 && operand->shift == 32);
1986 fixP->fx_r_type = BFD_RELOC_32;
1987 }
1988 else
1989 {
1990 as_bad_where (fixP->fx_file, fixP->fx_line,
0d2bcfaf 1991 "unresolved expression that must be resolved");
252b5132
RH
1992 fixP->fx_done = 1;
1993 return 1;
1994 }
1995 }
1996 else
1997 {
1998 switch (fixP->fx_r_type)
1999 {
2000 case BFD_RELOC_8:
2001 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
2002 value, 1);
2003 break;
2004 case BFD_RELOC_16:
2005 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
2006 value, 2);
2007 break;
2008 case BFD_RELOC_32:
2009 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
2010 value, 4);
2011 break;
2012#if 0
2013 case BFD_RELOC_64:
2014 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
2015 value, 8);
2016 break;
2017#endif
2018 case BFD_RELOC_ARC_B26:
2019 /* If !fixP->fx_done then `value' is an implicit addend.
2020 We must shift it right by 2 in this case as well because the
2021 linker performs the relocation and then adds this in (as opposed
2022 to adding this in and then shifting right by 2). */
2023 value >>= 2;
2024 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
2025 value, 4);
2026 break;
2027 default:
2028 abort ();
2029 }
2030 }
2031
2032 fixP->fx_addnumber = value;
2033
2034 return 1;
2035}
2036
2037/* Translate internal representation of relocation info to BFD target
2038 format. */
2039
2040arelent *
2041tc_gen_reloc (section, fixP)
4a314ec8 2042 asection *section ATTRIBUTE_UNUSED;
252b5132
RH
2043 fixS *fixP;
2044{
2045 arelent *reloc;
2046
2047 reloc = (arelent *) xmalloc (sizeof (arelent));
2048
0d2bcfaf 2049 reloc->sym_ptr_ptr = &fixP->fx_addsy->bsym;
252b5132
RH
2050 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
2051 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
2052 if (reloc->howto == (reloc_howto_type *) NULL)
2053 {
2054 as_bad_where (fixP->fx_file, fixP->fx_line,
0d2bcfaf 2055 "internal error: can't export reloc type %d (`%s')",
19203624
KH
2056 fixP->fx_r_type,
2057 bfd_get_reloc_code_name (fixP->fx_r_type));
252b5132
RH
2058 return NULL;
2059 }
2060
2061 assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
2062
19203624
KH
2063 /* Set addend to account for PC being advanced one insn before the
2064 target address is computed, drop fx_addnumber as it is handled
2065 elsewhere mlm */
252b5132 2066
19203624 2067 reloc->addend = (fixP->fx_pcrel ? -4 : 0);
252b5132 2068
0d2bcfaf 2069 return reloc;
252b5132 2070}
This page took 0.180321 seconds and 4 git commands to generate.