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