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