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