source: trunk/binutils/gas/config/tc-arc.c@ 2446

Last change on this file since 2446 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

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