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