]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/tc-arc.c
* config/tc-arc.c (arc_condition_codes): Deleted.
[thirdparty/binutils-gdb.git] / gas / config / tc-arc.c
1 /* tc-arc.c -- Assembler for the ARC
2 Copyright (C) 1994, 1995 Free Software Foundation, Inc.
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
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 #include <stdio.h>
22 #include <ctype.h>
23 #include "as.h"
24 #include "subsegs.h"
25 #include "opcode/arc.h"
26 #include "elf/arc.h"
27
28 extern int arc_get_mach PARAMS ((char *));
29
30 static arc_insn arc_insert_operand PARAMS ((arc_insn,
31 const struct arc_operand *, int,
32 const struct arc_operand_value *,
33 offsetT, char *, unsigned int));
34 static void arc_common PARAMS ((int));
35 static void arc_cpu PARAMS ((int));
36 /*static void arc_rename PARAMS ((int));*/
37 static int get_arc_exp_reloc_type PARAMS ((int, int, expressionS *,
38 expressionS *));
39
40 const pseudo_typeS md_pseudo_table[] =
41 {
42 { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0) */
43 { "common", arc_common, 0 },
44 /*{ "hword", cons, 2 }, - already exists */
45 { "word", cons, 4 },
46 /*{ "xword", cons, 8 },*/
47 { "cpu", arc_cpu, 0 },
48 /*{ "rename", arc_rename, 0 },*/
49 { NULL, 0, 0 },
50 };
51
52 const int md_short_jump_size = 4;
53 const int md_long_jump_size = 4;
54
55 /* This array holds the chars that always start a comment. If the
56 pre-processor is disabled, these aren't very useful */
57 const char comment_chars[] = "#;";
58
59 /* This array holds the chars that only start a comment at the beginning of
60 a line. If the line seems to have the form '# 123 filename'
61 .line and .file directives will appear in the pre-processed output */
62 /* Note that input_file.c hand checks for '#' at the beginning of the
63 first line of the input file. This is because the compiler outputs
64 #NO_APP at the beginning of its output. */
65 /* Also note that comments started like this one will always
66 work if '/' isn't otherwise defined. */
67 const char line_comment_chars[] = "#";
68
69 const char line_separator_chars[] = "";
70
71 /* Chars that can be used to separate mant from exp in floating point nums */
72 const char EXP_CHARS[] = "eE";
73
74 /* Chars that mean this number is a floating point constant */
75 /* As in 0f12.456 */
76 /* or 0d1.2345e12 */
77 const char FLT_CHARS[] = "rRsSfFdD";
78
79 /* Byte order. */
80 extern int target_big_endian;
81 const char *arc_target_format = DEFAULT_TARGET_FORMAT;
82 static int byte_order;
83
84 /* One of bfd_mach_arc_xxx. */
85 static int arc_mach_type = bfd_mach_arc_base;
86
87 /* Non-zero if the cpu type has been explicitly specified. */
88 static int mach_type_specified_p = 0;
89
90 /* Non-zero if opcode tables have been initialized.
91 A .cpu command must appear before any instructions. */
92 static int cpu_tables_init_p = 0;
93
94 static struct hash_control *arc_suffix_hash = NULL;
95 \f
96 const char *md_shortopts = "";
97 struct option md_longopts[] =
98 {
99 #define OPTION_EB (OPTION_MD_BASE + 0)
100 {"EB", no_argument, NULL, OPTION_EB},
101 #define OPTION_EL (OPTION_MD_BASE + 1)
102 {"EL", no_argument, NULL, OPTION_EL},
103 { NULL, no_argument, NULL, 0 }
104 };
105 size_t md_longopts_size = sizeof (md_longopts);
106
107 /*
108 * md_parse_option
109 *
110 * Invocation line includes a switch not recognized by the base assembler.
111 * See if it's a processor-specific option.
112 */
113
114 int
115 md_parse_option (c, arg)
116 int c;
117 char *arg;
118 {
119 switch (c)
120 {
121 case OPTION_EB:
122 byte_order = BIG_ENDIAN;
123 arc_target_format = "elf32-bigarc";
124 break;
125 case OPTION_EL:
126 byte_order = LITTLE_ENDIAN;
127 arc_target_format = "elf32-littlearc";
128 break;
129 default:
130 return 0;
131 }
132 return 1;
133 }
134
135 void
136 md_show_usage (stream)
137 FILE *stream;
138 {
139 fprintf (stream, "\
140 ARC options:\n\
141 -EB generate big endian output\n\
142 -EL generate little endian output\n");
143 }
144
145 /* This function is called once, at assembler startup time. It should
146 set up all the tables, etc. that the MD part of the assembler will need.
147 Opcode selection is defered until later because we might see a .cpu
148 command. */
149
150 void
151 md_begin ()
152 {
153 /* The endianness can be chosen "at the factory". */
154 target_big_endian = byte_order == BIG_ENDIAN;
155
156 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
157 as_warn ("could not set architecture and machine");
158
159 /* Assume the base cpu. This call is necessary because we need to
160 initialize `arc_operand_map' which may be needed before we see the
161 first insn. */
162 arc_opcode_init_tables (arc_get_opcode_mach (bfd_mach_arc_base,
163 target_big_endian));
164 }
165
166 /* Initialize the various opcode and operand tables.
167 MACH is one of bfd_mach_arc_xxx. */
168
169 static void
170 init_opcode_tables (mach)
171 int mach;
172 {
173 register unsigned int i;
174 char *last;
175
176 if ((arc_suffix_hash = hash_new ()) == NULL)
177 as_fatal ("virtual memory exhausted");
178
179 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
180 as_warn ("could not set architecture and machine");
181
182 /* This initializes a few things in arc-opc.c that we need.
183 This must be called before the various arc_xxx_supported fns. */
184 arc_opcode_init_tables (arc_get_opcode_mach (mach, target_big_endian));
185
186 /* Only put the first entry of each equivalently named suffix in the
187 table. */
188 last = "";
189 for (i = 0; i < arc_suffixes_count; i++)
190 {
191 if (! arc_opval_supported (&arc_suffixes[i]))
192 continue;
193 if (strcmp (arc_suffixes[i].name, last) != 0)
194 hash_insert (arc_suffix_hash, arc_suffixes[i].name, (PTR) (arc_suffixes + i));
195 last = arc_suffixes[i].name;
196 }
197
198 /* Since registers don't have a prefix, we put them in the symbol table so
199 they can't be used as symbols. This also simplifies argument parsing as
200 we can let gas parse registers for us. The recorded register number is
201 the index in `arc_reg_names'. */
202 for (i = 0; i < arc_reg_names_count; i++)
203 {
204 if (! arc_opval_supported (&arc_reg_names[i]))
205 continue;
206 /* Use symbol_create here instead of symbol_new so we don't try to
207 output registers into the object file's symbol table. */
208 symbol_table_insert (symbol_create (arc_reg_names[i].name, reg_section,
209 i, &zero_address_frag));
210 }
211
212 /* Tell `s_cpu' it's too late. */
213 cpu_tables_init_p = 1;
214 }
215 \f
216 /* Insert an operand value into an instruction.
217 If REG is non-NULL, it is a register number and ignore VAL. */
218
219 static arc_insn
220 arc_insert_operand (insn, operand, mods, reg, val, file, line)
221 arc_insn insn;
222 const struct arc_operand *operand;
223 int mods;
224 const struct arc_operand_value *reg;
225 offsetT val;
226 char *file;
227 unsigned int line;
228 {
229 if (operand->bits != 32)
230 {
231 long min, max;
232 offsetT test;
233
234 if ((operand->flags & ARC_OPERAND_SIGNED) != 0)
235 {
236 if ((operand->flags & ARC_OPERAND_SIGNOPT) != 0)
237 max = (1 << operand->bits) - 1;
238 else
239 max = (1 << (operand->bits - 1)) - 1;
240 min = - (1 << (operand->bits - 1));
241 }
242 else
243 {
244 max = (1 << operand->bits) - 1;
245 min = 0;
246 }
247
248 if ((operand->flags & ARC_OPERAND_NEGATIVE) != 0)
249 test = - val;
250 else
251 test = val;
252
253 if (test < (offsetT) min || test > (offsetT) max)
254 {
255 const char *err =
256 "operand out of range (%s not between %ld and %ld)";
257 char buf[100];
258
259 sprint_value (buf, test);
260 if (file == (char *) NULL)
261 as_warn (err, buf, min, max);
262 else
263 as_warn_where (file, line, err, buf, min, max);
264 }
265 }
266
267 if (operand->insert)
268 {
269 const char *errmsg;
270
271 errmsg = NULL;
272 insn = (*operand->insert) (insn, operand, mods, reg, (long) val, &errmsg);
273 if (errmsg != (const char *) NULL)
274 as_warn (errmsg);
275 }
276 else
277 insn |= (((long) val & ((1 << operand->bits) - 1))
278 << operand->shift);
279
280 return insn;
281 }
282
283 /* We need to keep a list of fixups. We can't simply generate them as
284 we go, because that would require us to first create the frag, and
285 that would screw up references to ``.''. */
286
287 struct arc_fixup
288 {
289 /* index into `arc_operands' */
290 int opindex;
291 expressionS exp;
292 };
293
294 #define MAX_INSN_FIXUPS 5
295
296 /* This routine is called for each instruction to be assembled. */
297
298 void
299 md_assemble (str)
300 char *str;
301 {
302 const struct arc_opcode *opcode,*opcode_end;
303 char *start;
304 arc_insn insn;
305 static int init_tables_p = 0;
306
307 /* Opcode table initialization is deferred until here because we have to
308 wait for a possible .cpu command. */
309 if (!init_tables_p)
310 {
311 init_opcode_tables (arc_mach_type);
312 init_tables_p = 1;
313 }
314
315 /* Skip leading white space. */
316 while (isspace (*str))
317 str++;
318
319 /* The instructions are sorted by the first letter. Scan the opcode table
320 until we find the right one. */
321 opcode_end = arc_opcodes + arc_opcodes_count;
322 for (opcode = arc_opcodes; opcode < opcode_end; opcode++)
323 if (*opcode->syntax == *str)
324 break;
325 if (opcode == opcode_end)
326 {
327 as_bad ("bad instruction `%s'", str);
328 return;
329 }
330
331 /* Keep looking until we find a match. If we haven't found a match, and the
332 first character no longer matches, we needn't look any further. */
333
334 start = str;
335 for ( ; opcode < opcode_end && *opcode->syntax == *start; ++opcode)
336 {
337 int past_opcode_p;
338 char *syn;
339 struct arc_fixup fixups[MAX_INSN_FIXUPS];
340 int fc,limm_reloc_p;
341
342 /* Is this opcode supported by the selected cpu? */
343 if (! arc_opcode_supported (opcode))
344 continue;
345
346 /* Scan the syntax string. If it doesn't match, try the next one. */
347
348 arc_opcode_init_insert ();
349 insn = opcode->value;
350 fc = 0;
351 past_opcode_p = 0;
352
353 /* Used as a sanity check. If we need a limm reloc, make sure we ask
354 for an extra 4 bytes from frag_more. */
355 limm_reloc_p = 0;
356
357 /* We don't check for (*str != '\0') here because we want to parse
358 any trailing fake arguments in the syntax string. */
359 for (str = start, syn = opcode->syntax; *syn != '\0'; )
360 {
361 int mods;
362 const struct arc_operand *operand;
363
364 /* Non operand chars must match exactly. */
365 if (*syn != '%' || *++syn == '%')
366 {
367 /* Handle '+' specially as we want to allow "ld r0,[sp-4]". */
368 /* ??? The syntax has changed to [sp,-4]. */
369 if (0 && *syn == '+' && *str == '-')
370 {
371 /* Skip over syn's +, but leave str's - alone.
372 That makes the case identical to "ld r0,[sp+-4]". */
373 ++syn;
374 }
375 else if (*str == *syn)
376 {
377 if (*syn == ' ')
378 past_opcode_p = 1;
379 ++syn;
380 ++str;
381 }
382 else
383 break;
384 continue;
385 }
386
387 /* We have an operand. Pick out any modifiers. */
388 mods = 0;
389 while (ARC_MOD_P (arc_operands[arc_operand_map[*syn]].flags))
390 {
391 mods |= arc_operands[arc_operand_map[*syn]].flags & ARC_MOD_BITS;
392 ++syn;
393 }
394 operand = arc_operands + arc_operand_map[*syn];
395 if (operand->fmt == 0)
396 as_fatal ("unknown syntax format character `%c'", *syn);
397
398 if (operand->flags & ARC_OPERAND_FAKE)
399 {
400 const char *errmsg = NULL;
401 if (operand->insert)
402 {
403 insn = (*operand->insert) (insn, operand, mods, NULL, 0, &errmsg);
404 /* If we get an error, go on to try the next insn. */
405 if (errmsg)
406 break;
407 }
408 ++syn;
409 }
410 /* Are we finished with suffixes? */
411 else if (!past_opcode_p)
412 {
413 int found;
414 char c;
415 char *s,*t;
416 const struct arc_operand_value *suf,*suffix,*suffix_end;
417
418 if (!(operand->flags & ARC_OPERAND_SUFFIX))
419 abort ();
420
421 /* If we're at a space in the input string, we want to skip the
422 remaining suffixes. There may be some fake ones though, so
423 just go on to try the next one. */
424 if (*str == ' ')
425 {
426 ++syn;
427 continue;
428 }
429
430 s = str;
431 if (mods & ARC_MOD_DOT)
432 {
433 if (*s != '.')
434 break;
435 ++s;
436 }
437 else
438 {
439 /* This can happen in "b.nd foo" and we're currently looking
440 for "%q" (ie: a condition code suffix). */
441 if (*s == '.')
442 {
443 ++syn;
444 continue;
445 }
446 }
447
448 /* Pick the suffix out and look it up via the hash table. */
449 for (t = s; *t && isalpha (*t); ++t)
450 continue;
451 c = *t;
452 *t = '\0';
453 suf = hash_find (arc_suffix_hash, s);
454 *t = c;
455 if (!suf)
456 {
457 /* This can happen in "blle foo" and we're currently using
458 the template "b%q%.n %j". The "bl" insn occurs later in
459 the table so "lle" isn't an illegal suffix. */
460 break;
461 }
462
463 /* Is it the right type? Note that the same character is used
464 several times, so we have to examine all of them. This is
465 relatively efficient as equivalent entries are kept
466 together. If it's not the right type, don't increment `str'
467 so we try the next one in the series. */
468 found = 0;
469 suffix_end = arc_suffixes + arc_suffixes_count;
470 for (suffix = suf;
471 suffix < suffix_end && strcmp (suffix->name, suf->name) == 0;
472 suffix++)
473 {
474 if (arc_operands[suffix->type].fmt == *syn)
475 {
476 /* Insert the suffix's value into the insn. */
477 if (operand->insert)
478 insn = (*operand->insert) (insn, operand,
479 mods, NULL, suffix->value,
480 NULL);
481 else
482 insn |= suffix->value << operand->shift;
483
484 str = t;
485 found = 1;
486 break;
487 }
488 }
489 ++syn;
490 if (!found)
491 /* There's nothing to do except go on to try the next one.
492 ??? This test can be deleted when we're done. */
493 ;
494 }
495 else
496 /* This is either a register or an expression of some kind. */
497 {
498 char c;
499 char *hold;
500 const struct arc_operand_value *reg = NULL;
501 long value = 0;
502 expressionS exp;
503
504 if (operand->flags & ARC_OPERAND_SUFFIX)
505 abort ();
506
507 /* Is there anything left to parse?
508 We don't check for this at the top because we want to parse
509 any trailing fake arguments in the syntax string. */
510 if (*str == '\0')
511 break;
512 #if 0
513 /* Is this a syntax character? Eg: is there a '[' present when
514 there shouldn't be? */
515 if (!isalnum (*str)
516 /* '.' as in ".LLC0" */
517 && *str != '.'
518 /* '_' as in "_print" */
519 && *str != '_'
520 /* '-' as in "[fp,-4]" */
521 && *str != '-'
522 /* '%' as in "%ia(_func)" */
523 && *str != '%')
524 break;
525 #endif
526
527 /* Parse the operand. */
528 hold = input_line_pointer;
529 input_line_pointer = str;
530 expression (&exp);
531 str = input_line_pointer;
532 input_line_pointer = hold;
533
534 if (exp.X_op == O_illegal)
535 as_bad ("illegal operand");
536 else if (exp.X_op == O_absent)
537 as_bad ("missing operand");
538 else if (exp.X_op == O_constant)
539 {
540 value = exp.X_add_number;
541 }
542 else if (exp.X_op == O_register)
543 {
544 reg = arc_reg_names + exp.X_add_number;
545 }
546 else
547 {
548 /* We need to generate a fixup for this expression. */
549 if (fc >= MAX_INSN_FIXUPS)
550 as_fatal ("too many fixups");
551 fixups[fc].exp = exp;
552
553 /* If this is a register constant (IE: one whose
554 register value gets stored as 61-63) then this
555 must be a limm. We don't support shimm relocs. */
556 /* ??? This bit could use some cleaning up.
557 Referencing the format chars like this goes
558 against style. */
559 #define IS_REG_OPERAND(o) ((o) == 'a' || (o) == 'b' || (o) == 'c')
560 if (IS_REG_OPERAND (*syn))
561 {
562 const char *junk;
563
564 fixups[fc].opindex = arc_operand_map['L'];
565 limm_reloc_p = 1;
566 /* Tell insert_reg we need a limm. This is
567 needed because the value at this point is
568 zero, a shimm. */
569 /* ??? We need a cleaner interface than this. */
570 (*arc_operands[arc_operand_map['Q']].insert)
571 (insn, operand, mods, reg, 0L, &junk);
572 }
573 else
574 fixups[fc].opindex = arc_operand_map[*syn];
575 ++fc;
576 value = 0;
577 }
578
579 /* Insert the register or expression into the instruction. */
580 if (operand->insert)
581 {
582 const char *errmsg = NULL;
583 insn = (*operand->insert) (insn, operand, mods,
584 reg, (long) value, &errmsg);
585 #if 0
586 if (errmsg != (const char *) NULL)
587 as_warn (errmsg);
588 #endif
589 /* FIXME: We want to try shimm insns for limm ones. But if
590 the constant won't fit, we must go on to try the next
591 possibility. Where do we issue warnings for constants
592 that are too big then? At present, we'll flag the insn
593 as unrecognizable! Maybe have the "bad instruction"
594 error message include our `errmsg'? */
595 if (errmsg != (const char *) NULL)
596 break;
597 }
598 else
599 insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
600
601 ++syn;
602 }
603 }
604
605 /* If we're at the end of the syntax string, we're done. */
606 if (*syn == '\0')
607 {
608 int i;
609 char *f;
610 long limm;
611
612 /* ??? For the moment we assume a valid `str' can only contain blanks
613 now. IE: We needn't try again with a longer version of the
614 insn. */
615
616 while (isspace (*str))
617 ++str;
618
619 if (*str != '\0')
620 as_bad ("junk at end of line: `%s'", str);
621
622 /* Write out the instruction.
623 It is important to fetch enough space in one call to `frag_more'.
624 We use (f - frag_now->fr_literal) to compute where we are and we
625 don't want frag_now to change between calls. */
626 if (arc_opcode_limm_p (&limm))
627 {
628 f = frag_more (8);
629 md_number_to_chars (f, insn, 4);
630 md_number_to_chars (f + 4, limm, 4);
631 }
632 else if (limm_reloc_p)
633 {
634 /* We need a limm reloc, but the tables think we don't. */
635 abort ();
636 }
637 else
638 {
639 f = frag_more (4);
640 md_number_to_chars (f, insn, 4);
641 }
642
643 /* Create any fixups. */
644 for (i = 0; i < fc; ++i)
645 {
646 int op_type, reloc_type;
647 expressionS exptmp;
648 const struct arc_operand *operand;
649
650 /* Create a fixup for this operand.
651 At this point we do not use a bfd_reloc_code_real_type for
652 operands residing in the insn, but instead just use the
653 operand index. This lets us easily handle fixups for any
654 operand type, although that is admittedly not a very exciting
655 feature. We pick a BFD reloc type in md_apply_fix.
656
657 Limm values (4 byte immediate "constants") must be treated
658 normally because they're not part of the actual insn word
659 and thus the insertion routines don't handle them. */
660
661 if (arc_operands[fixups[i].opindex].flags & ARC_OPERAND_LIMM)
662 {
663 op_type = fixups[i].opindex;
664 /* FIXME: can we add this data to the operand table? */
665 if (op_type == arc_operand_map['L'])
666 reloc_type = BFD_RELOC_32;
667 else if (op_type == arc_operand_map['J'])
668 reloc_type = BFD_RELOC_ARC_B26;
669 else
670 abort ();
671 reloc_type = get_arc_exp_reloc_type (1, reloc_type,
672 &fixups[i].exp,
673 &exptmp);
674 }
675 else
676 {
677 op_type = get_arc_exp_reloc_type (0, fixups[i].opindex,
678 &fixups[i].exp, &exptmp);
679 reloc_type = op_type + (int) BFD_RELOC_UNUSED;
680 }
681 operand = &arc_operands[op_type];
682 fix_new_exp (frag_now,
683 ((f - frag_now->fr_literal)
684 + (operand->flags & ARC_OPERAND_LIMM ? 4 : 0)), 4,
685 &exptmp,
686 (operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0,
687 (bfd_reloc_code_real_type) reloc_type);
688 }
689
690 /* All done. */
691 return;
692 }
693
694 /* Try the next entry. */
695 }
696
697 as_bad ("bad instruction `%s'", start);
698 }
699 \f
700 /* ??? This was copied from tc-sparc.c, I think. Is it necessary? */
701
702 static void
703 arc_common (ignore)
704 int ignore;
705 {
706 char *name;
707 char c;
708 char *p;
709 int temp, size;
710 symbolS *symbolP;
711
712 name = input_line_pointer;
713 c = get_symbol_end ();
714 /* just after name is now '\0' */
715 p = input_line_pointer;
716 *p = c;
717 SKIP_WHITESPACE ();
718 if (*input_line_pointer != ',')
719 {
720 as_bad ("expected comma after symbol-name");
721 ignore_rest_of_line ();
722 return;
723 }
724 input_line_pointer++; /* skip ',' */
725 if ((temp = get_absolute_expression ()) < 0)
726 {
727 as_bad (".COMMon length (%d.) <0! Ignored.", temp);
728 ignore_rest_of_line ();
729 return;
730 }
731 size = temp;
732 *p = 0;
733 symbolP = symbol_find_or_make (name);
734 *p = c;
735 if (S_IS_DEFINED (symbolP))
736 {
737 as_bad ("ignoring attempt to re-define symbol");
738 ignore_rest_of_line ();
739 return;
740 }
741 if (S_GET_VALUE (symbolP) != 0)
742 {
743 if (S_GET_VALUE (symbolP) != size)
744 {
745 as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
746 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
747 }
748 }
749 assert (symbolP->sy_frag == &zero_address_frag);
750 if (*input_line_pointer != ',')
751 {
752 as_bad ("expected comma after common length");
753 ignore_rest_of_line ();
754 return;
755 }
756 input_line_pointer++;
757 SKIP_WHITESPACE ();
758 if (*input_line_pointer != '"')
759 {
760 temp = get_absolute_expression ();
761 if (temp < 0)
762 {
763 temp = 0;
764 as_warn ("Common alignment negative; 0 assumed");
765 }
766 if (symbolP->local)
767 {
768 segT old_sec;
769 int old_subsec;
770 char *p;
771 int align;
772
773 allocate_bss:
774 old_sec = now_seg;
775 old_subsec = now_subseg;
776 align = temp;
777 record_alignment (bss_section, align);
778 subseg_set (bss_section, 0);
779 if (align)
780 frag_align (align, 0);
781 if (S_GET_SEGMENT (symbolP) == bss_section)
782 symbolP->sy_frag->fr_symbol = 0;
783 symbolP->sy_frag = frag_now;
784 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
785 (char *) 0);
786 *p = 0;
787 S_SET_SEGMENT (symbolP, bss_section);
788 S_CLEAR_EXTERNAL (symbolP);
789 subseg_set (old_sec, old_subsec);
790 }
791 else
792 {
793 allocate_common:
794 S_SET_VALUE (symbolP, (valueT) size);
795 S_SET_ALIGN (symbolP, temp);
796 S_SET_EXTERNAL (symbolP);
797 /* should be common, but this is how gas does it for now */
798 S_SET_SEGMENT (symbolP, bfd_und_section_ptr);
799 }
800 }
801 else
802 {
803 input_line_pointer++;
804 /* ??? Some say data, some say bss. */
805 if (strncmp (input_line_pointer, ".bss\"", 5)
806 && strncmp (input_line_pointer, ".data\"", 6))
807 {
808 input_line_pointer--;
809 goto bad_common_segment;
810 }
811 while (*input_line_pointer++ != '"')
812 ;
813 goto allocate_common;
814 }
815 demand_empty_rest_of_line ();
816 return;
817
818 {
819 bad_common_segment:
820 p = input_line_pointer;
821 while (*p && *p != '\n')
822 p++;
823 c = *p;
824 *p = '\0';
825 as_bad ("bad .common segment %s", input_line_pointer + 1);
826 *p = c;
827 input_line_pointer = p;
828 ignore_rest_of_line ();
829 return;
830 }
831 }
832
833 /* Select the cpu we're assembling for. */
834
835 static void
836 arc_cpu (ignore)
837 int ignore;
838 {
839 int mach;
840 char c;
841 char *cpu;
842
843 /* If an instruction has already been seen, it's too late. */
844 if (cpu_tables_init_p)
845 {
846 as_bad (".cpu command must appear before any instructions");
847 ignore_rest_of_line ();
848 return;
849 }
850
851 cpu = input_line_pointer;
852 c = get_symbol_end ();
853 mach = arc_get_mach (cpu);
854 *input_line_pointer = c;
855 if (mach == -1)
856 goto bad_cpu;
857
858 demand_empty_rest_of_line ();
859
860 /* The cpu may have been selected on the command line.
861 The choices must match. */
862 /* ??? This was a command line option early on. It's gone now, but
863 leave this in. */
864 if (mach_type_specified_p && mach != arc_mach_type)
865 as_bad (".cpu conflicts with previous value");
866 else
867 {
868 arc_mach_type = mach;
869 mach_type_specified_p = 1;
870 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
871 as_warn ("could not set architecture and machine");
872 }
873 return;
874
875 bad_cpu:
876 as_bad ("bad .cpu op");
877 ignore_rest_of_line ();
878 }
879
880 #if 0
881 /* The .rename pseudo-op. This is used by gcc to implement
882 -mmangle-cpu-libgcc. */
883
884 static void
885 arc_rename (ignore)
886 int ignore;
887 {
888 char *name,*new;
889 char c;
890 symbolS *sym;
891 int len;
892
893 name = input_line_pointer;
894 c = get_symbol_end ();
895 sym = symbol_find_or_make (name);
896 *input_line_pointer = c;
897
898 if (*input_line_pointer != ',')
899 {
900 as_bad ("missing rename string");
901 ignore_rest_of_line ();
902 return;
903 }
904 ++input_line_pointer;
905 SKIP_WHITESPACE ();
906
907 name = input_line_pointer;
908 c = get_symbol_end ();
909 if (*name == '\0')
910 {
911 *input_line_pointer = c;
912 as_bad ("invalid symbol to rename to");
913 ignore_rest_of_line ();
914 return;
915 }
916 new = (char *) xmalloc (strlen (name) + 1);
917 strcpy (new, name);
918 *input_line_pointer = c;
919 sym->sy_tc.real_name = new;
920
921 demand_empty_rest_of_line ();
922 }
923 #endif
924 \f
925 /* Turn a string in input_line_pointer into a floating point constant of type
926 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
927 emitted is stored in *sizeP.
928 An error message is returned, or NULL on OK. */
929
930 /* Equal to MAX_PRECISION in atof-ieee.c */
931 #define MAX_LITTLENUMS 6
932
933 char *
934 md_atof (type, litP, sizeP)
935 char type;
936 char *litP;
937 int *sizeP;
938 {
939 int prec;
940 LITTLENUM_TYPE words[MAX_LITTLENUMS];
941 LITTLENUM_TYPE *wordP;
942 char *t;
943 char *atof_ieee ();
944
945 switch (type)
946 {
947 case 'f':
948 case 'F':
949 prec = 2;
950 break;
951
952 case 'd':
953 case 'D':
954 prec = 4;
955 break;
956
957 default:
958 *sizeP = 0;
959 return "bad call to md_atof";
960 }
961
962 t = atof_ieee (input_line_pointer, type, words);
963 if (t)
964 input_line_pointer = t;
965 *sizeP = prec * sizeof (LITTLENUM_TYPE);
966 for (wordP = words; prec--;)
967 {
968 md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
969 litP += sizeof (LITTLENUM_TYPE);
970 }
971
972 return NULL;
973 }
974
975 /* Write a value out to the object file, using the appropriate
976 endianness. */
977
978 void
979 md_number_to_chars (buf, val, n)
980 char *buf;
981 valueT val;
982 int n;
983 {
984 if (target_big_endian)
985 number_to_chars_bigendian (buf, val, n);
986 else
987 number_to_chars_littleendian (buf, val, n);
988 }
989
990 /* Round up a section size to the appropriate boundary. */
991
992 valueT
993 md_section_align (segment, size)
994 segT segment;
995 valueT size;
996 {
997 int align = bfd_get_section_alignment (stdoutput, segment);
998
999 return ((size + (1 << align) - 1) & (-1 << align));
1000 }
1001
1002 /* We don't have any form of relaxing. */
1003
1004 int
1005 md_estimate_size_before_relax (fragp, seg)
1006 fragS *fragp;
1007 asection *seg;
1008 {
1009 abort ();
1010 }
1011
1012 const relax_typeS md_relax_table[] =
1013 {
1014 { 0 }
1015 };
1016
1017 /* Convert a machine dependent frag. We never generate these. */
1018
1019 void
1020 md_convert_frag (abfd, sec, fragp)
1021 bfd *abfd;
1022 asection *sec;
1023 fragS *fragp;
1024 {
1025 abort ();
1026 }
1027
1028 /* Parse an operand that is machine-specific.
1029
1030 The ARC has a special %-op to adjust addresses so they're usable in
1031 branches. The "st" is short for the STatus register.
1032 ??? Later expand this to take a flags value too.
1033
1034 ??? We can't create new expression types so we map the %-op's onto the
1035 existing syntax. This means that the user could use the chosen syntax
1036 to achieve the same effect. Perhaps put a special cookie in X_add_number
1037 to mark the expression as special. */
1038
1039 void
1040 md_operand (expressionP)
1041 expressionS *expressionP;
1042 {
1043 char *p = input_line_pointer;
1044
1045 if (*p == '%' && strncmp (p, "%st(", 4) == 0)
1046 {
1047 expressionS two;
1048
1049 input_line_pointer += 4;
1050 expression (expressionP);
1051 if (*input_line_pointer != ')')
1052 {
1053 as_bad ("missing ')' in %-op");
1054 return;
1055 }
1056 ++input_line_pointer;
1057 if (expressionP->X_op != O_symbol
1058 || expressionP->X_add_number != 0)
1059 {
1060 as_bad ("expression too complex for %st");
1061 return;
1062 }
1063 expressionP->X_op = O_right_shift;
1064 two.X_op = O_constant;
1065 two.X_add_symbol = two.X_op_symbol = NULL;
1066 two.X_add_number = 2;
1067 expressionP->X_op_symbol = make_expr_symbol (&two);
1068 }
1069 }
1070
1071 /* We have no need to default values of symbols.
1072 We could catch register names here, but that is handled by inserting
1073 them all in the symbol table to begin with. */
1074
1075 symbolS *
1076 md_undefined_symbol (name)
1077 char *name;
1078 {
1079 return 0;
1080 }
1081 \f
1082 /* Functions concerning expressions. */
1083
1084 /* Parse a .byte, .word, etc. expression.
1085
1086 Values for the status register are specified with %st(label).
1087 `label' will be right shifted by 2. */
1088
1089 void
1090 arc_parse_cons_expression (exp, nbytes)
1091 expressionS *exp;
1092 int nbytes;
1093 {
1094 expr (0, exp);
1095 }
1096
1097 /* Record a fixup for a cons expression. */
1098
1099 void
1100 arc_cons_fix_new (frag, where, nbytes, exp)
1101 fragS *frag;
1102 int where;
1103 int nbytes;
1104 expressionS *exp;
1105 {
1106 if (nbytes == 4)
1107 {
1108 int reloc_type;
1109 expressionS exptmp;
1110
1111 /* This may be a special ARC reloc (eg: %st()). */
1112 reloc_type = get_arc_exp_reloc_type (1, BFD_RELOC_32, exp, &exptmp);
1113 fix_new_exp (frag, where, nbytes, &exptmp, 0, reloc_type);
1114 }
1115 else
1116 {
1117 fix_new_exp (frag, where, nbytes, exp, 0,
1118 nbytes == 2 ? BFD_RELOC_16
1119 : nbytes == 8 ? BFD_RELOC_64
1120 : BFD_RELOC_32);
1121 }
1122 }
1123 \f
1124 /* Functions concerning relocs. */
1125
1126 /* The location from which a PC relative jump should be calculated,
1127 given a PC relative reloc. */
1128
1129 long
1130 md_pcrel_from (fixP)
1131 fixS *fixP;
1132 {
1133 if (fixP->fx_addsy != (symbolS *) NULL
1134 && ! S_IS_DEFINED (fixP->fx_addsy))
1135 /* Return offset from PC to delay slot. Offsets are from there. */
1136 return 4;
1137
1138 /* Return the address of the delay slot. */
1139 return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
1140 }
1141
1142 /* Compute the reloc type of an expression.
1143 The possibly modified expression is stored in EXPNEW.
1144
1145 This is used to convert the expressions generated by the %-op's into
1146 the appropriate operand type. It is called for both data in instructions
1147 (operands) and data outside instructions (variables, debugging info, etc.).
1148
1149 Currently supported %-ops:
1150
1151 %st(symbol): represented as "symbol >> 2"
1152 "st" is short for STatus as in the status register (pc)
1153
1154 DEFAULT_TYPE is the type to use if no special processing is required.
1155
1156 DATA_P is non-zero for data or limm values, zero for insn operands.
1157 Remember that the opcode "insertion fns" cannot be used on data, they're
1158 only for inserting operands into insns. They also can't be used for limm
1159 values as the insertion routines don't handle limm values. When called for
1160 insns we return fudged reloc types (real_value - BFD_RELOC_UNUSED). When
1161 called for data or limm values we use real reloc types. */
1162
1163 static int
1164 get_arc_exp_reloc_type (data_p, default_type, exp, expnew)
1165 int data_p;
1166 int default_type;
1167 expressionS *exp;
1168 expressionS *expnew;
1169 {
1170 /* If the expression is "symbol >> 2" we must change it to just "symbol",
1171 as fix_new_exp can't handle it. That's ok though. What's really going
1172 on here is that we're using ">> 2" as a special syntax for specifying
1173 BFD_RELOC_ARC_B26. */
1174
1175 if (exp->X_op == O_right_shift)
1176 {
1177 if (exp->X_add_symbol != NULL
1178 && (exp->X_add_symbol->sy_value.X_op == O_constant
1179 || exp->X_add_symbol->sy_value.X_op == O_symbol)
1180 && exp->X_op_symbol != NULL
1181 && exp->X_op_symbol->sy_value.X_op == O_constant
1182 && exp->X_op_symbol->sy_value.X_add_number == 2
1183 && exp->X_add_number == 0)
1184 {
1185 *expnew = *exp;
1186 expnew->X_op = O_symbol;
1187 expnew->X_op_symbol = NULL;
1188 return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
1189 }
1190 }
1191
1192 *expnew = *exp;
1193 return default_type;
1194 }
1195
1196 /* Apply a fixup to the object code. This is called for all the
1197 fixups we generated by the call to fix_new_exp, above. In the call
1198 above we used a reloc code which was the largest legal reloc code
1199 plus the operand index. Here we undo that to recover the operand
1200 index. At this point all symbol values should be fully resolved,
1201 and we attempt to completely resolve the reloc. If we can not do
1202 that, we determine the correct reloc code and put it back in the fixup. */
1203
1204 int
1205 md_apply_fix (fixP, valueP)
1206 fixS *fixP;
1207 valueT *valueP;
1208 {
1209 /*char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;*/
1210 valueT value;
1211
1212 /* FIXME FIXME FIXME: The value we are passed in *valueP includes
1213 the symbol values. Since we are using BFD_ASSEMBLER, if we are
1214 doing this relocation the code in write.c is going to call
1215 bfd_perform_relocation, which is also going to use the symbol
1216 value. That means that if the reloc is fully resolved we want to
1217 use *valueP since bfd_perform_relocation is not being used.
1218 However, if the reloc is not fully resolved we do not want to use
1219 *valueP, and must use fx_offset instead. However, if the reloc
1220 is PC relative, we do want to use *valueP since it includes the
1221 result of md_pcrel_from. This is confusing. */
1222
1223 if (fixP->fx_addsy == (symbolS *) NULL)
1224 {
1225 value = *valueP;
1226 fixP->fx_done = 1;
1227 }
1228 else if (fixP->fx_pcrel)
1229 value = *valueP;
1230 else
1231 {
1232 value = fixP->fx_offset;
1233 if (fixP->fx_subsy != (symbolS *) NULL)
1234 {
1235 if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)
1236 value -= S_GET_VALUE (fixP->fx_subsy);
1237 else
1238 {
1239 /* We can't actually support subtracting a symbol. */
1240 as_bad_where (fixP->fx_file, fixP->fx_line,
1241 "expression too complex");
1242 }
1243 }
1244 }
1245
1246 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
1247 {
1248 int opindex;
1249 const struct arc_operand *operand;
1250 char *where;
1251 arc_insn insn;
1252
1253 opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
1254
1255 operand = &arc_operands[opindex];
1256
1257 /* Fetch the instruction, insert the fully resolved operand
1258 value, and stuff the instruction back again. */
1259 where = fixP->fx_frag->fr_literal + fixP->fx_where;
1260 if (target_big_endian)
1261 insn = bfd_getb32 ((unsigned char *) where);
1262 else
1263 insn = bfd_getl32 ((unsigned char *) where);
1264 insn = arc_insert_operand (insn, operand, -1, NULL, (offsetT) value,
1265 fixP->fx_file, fixP->fx_line);
1266 if (target_big_endian)
1267 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1268 else
1269 bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
1270
1271 if (fixP->fx_done)
1272 {
1273 /* Nothing else to do here. */
1274 return 1;
1275 }
1276
1277 /* Determine a BFD reloc value based on the operand information.
1278 We are only prepared to turn a few of the operands into relocs.
1279 !!! Note that we can't handle limm values here. Since we're using
1280 implicit addends the addend must be inserted into the instruction,
1281 however, the opcode insertion routines currently do nothing with
1282 limm values. */
1283 if (operand->fmt == 'B')
1284 {
1285 assert ((operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0
1286 && operand->bits == 20
1287 && operand->shift == 7);
1288 fixP->fx_r_type = BFD_RELOC_ARC_B22_PCREL;
1289 }
1290 else if (0 && operand->fmt == 'J')
1291 {
1292 assert ((operand->flags & ARC_OPERAND_ABSOLUTE_BRANCH) != 0
1293 && operand->bits == 24
1294 && operand->shift == 32);
1295 fixP->fx_r_type = BFD_RELOC_ARC_B26;
1296 }
1297 else if (0 && operand->fmt == 'L')
1298 {
1299 assert ((operand->flags & ARC_OPERAND_LIMM) != 0
1300 && operand->bits == 32
1301 && operand->shift == 32);
1302 fixP->fx_r_type = BFD_RELOC_32;
1303 }
1304 else
1305 {
1306 as_bad_where (fixP->fx_file, fixP->fx_line,
1307 "unresolved expression that must be resolved");
1308 fixP->fx_done = 1;
1309 return 1;
1310 }
1311 }
1312 else
1313 {
1314 switch (fixP->fx_r_type)
1315 {
1316 case BFD_RELOC_8:
1317 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1318 value, 1);
1319 break;
1320 case BFD_RELOC_16:
1321 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1322 value, 2);
1323 break;
1324 case BFD_RELOC_32:
1325 case BFD_RELOC_ARC_B26:
1326 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1327 value, 4);
1328 break;
1329 #if 0
1330 case BFD_RELOC_64:
1331 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1332 value, 8);
1333 break;
1334 #endif
1335 default:
1336 abort ();
1337 }
1338 }
1339
1340 fixP->fx_addnumber = value;
1341
1342 return 1;
1343 }
1344
1345 /* Translate internal representation of relocation info to BFD target
1346 format. */
1347
1348 arelent *
1349 tc_gen_reloc (section, fixP)
1350 asection *section;
1351 fixS *fixP;
1352 {
1353 arelent *reloc;
1354
1355 reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
1356
1357 reloc->sym_ptr_ptr = &fixP->fx_addsy->bsym;
1358 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1359 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
1360 if (reloc->howto == (reloc_howto_type *) NULL)
1361 {
1362 as_bad_where (fixP->fx_file, fixP->fx_line,
1363 "internal error: can't export reloc type %d (`%s')",
1364 fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
1365 return NULL;
1366 }
1367 reloc->addend = fixP->fx_addnumber;
1368
1369 assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
1370
1371 return reloc;
1372 }
1373 \f
1374 /* Frobbers. */
1375
1376 #if 0
1377 /* Set the real name if the .rename pseudo-op was used.
1378 Return 1 if the symbol should not be included in the symbol table. */
1379
1380 int
1381 arc_frob_symbol (sym)
1382 symbolS *sym;
1383 {
1384 if (sym->sy_tc.real_name != (char *) NULL)
1385 S_SET_NAME (sym, sym->sy_tc.real_name);
1386
1387 return 0;
1388 }
1389 #endif