]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/tc-fr30.c
sanitize fr30 port for now
[thirdparty/binutils-gdb.git] / gas / config / tc-fr30.c
1 /* tc-fr30.c -- Assembler for the Fujitsu FR30.
2 Copyright (C) 1998 Free Software Foundation.
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21
22 /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
23 This file is work in progress and was copied from m32r/tc-m32r.c in
24 order to all gas/configure to run with the target fr30-unknown-elf.
25 Other than changing all occurances for m32r to fr30, this file has not
26 been customized for fr30 in any way.
27 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
28
29 #include <stdio.h>
30 #include <ctype.h>
31 #include "as.h"
32 #include "subsegs.h"
33 #include "symcat.h"
34 #include "cgen-opc.h"
35 #include "cgen.h"
36
37 /* Linked list of symbols that are debugging symbols to be defined as the
38 beginning of the current instruction. */
39 typedef struct sym_link
40 {
41 struct sym_link *next;
42 symbolS *symbol;
43 } sym_linkS;
44
45 static sym_linkS *debug_sym_link = (sym_linkS *)0;
46
47 /* Structure to hold all of the different components describing
48 an individual instruction. */
49 typedef struct
50 {
51 const CGEN_INSN * insn;
52 const CGEN_INSN * orig_insn;
53 CGEN_FIELDS fields;
54 #if CGEN_INT_INSN_P
55 CGEN_INSN_INT buffer [1];
56 #define INSN_VALUE(buf) (*(buf))
57 #else
58 unsigned char buffer [CGEN_MAX_INSN_SIZE];
59 #define INSN_VALUE(buf) (buf)
60 #endif
61 char * addr;
62 fragS * frag;
63 int num_fixups;
64 fixS * fixups [GAS_CGEN_MAX_FIXUPS];
65 int indices [MAX_OPERAND_INSTANCES];
66 sym_linkS *debug_sym_link;
67 }
68 fr30_insn;
69
70 /* prev_insn.insn is non-null if last insn was a 16 bit insn on a 32 bit
71 boundary (i.e. was the first of two 16 bit insns). */
72 static fr30_insn prev_insn;
73
74 /* Non-zero if we've seen a relaxable insn since the last 32 bit
75 alignment request. */
76 static int seen_relaxable_p = 0;
77
78 /* Non-zero if -relax specified, in which case sufficient relocs are output
79 for the linker to do relaxing.
80 We do simple forms of relaxing internally, but they are always done.
81 This flag does not apply to them. */
82 static int fr30_relax;
83
84 #if 0 /* not supported yet */
85 /* If non-NULL, pointer to cpu description file to read.
86 This allows runtime additions to the assembler. */
87 static const char * fr30_cpu_desc;
88 #endif
89
90 /* Non-zero if warn when a high/shigh reloc has no matching low reloc.
91 Each high/shigh reloc must be paired with it's low cousin in order to
92 properly calculate the addend in a relocatable link (since there is a
93 potential carry from the low to the high/shigh).
94 This option is off by default though for user-written assembler code it
95 might make sense to make the default be on (i.e. have gcc pass a flag
96 to turn it off). This warning must not be on for GCC created code as
97 optimization may delete the low but not the high/shigh (at least we
98 shouldn't assume or require it to). */
99 static int warn_unmatched_high = 0;
100
101 /* stuff for .scomm symbols. */
102 static segT sbss_section;
103 static asection scom_section;
104 static asymbol scom_symbol;
105
106 const char comment_chars[] = ";";
107 const char line_comment_chars[] = "#";
108 const char line_separator_chars[] = "";
109 const char EXP_CHARS[] = "eE";
110 const char FLT_CHARS[] = "dD";
111
112 /* Relocations against symbols are done in two
113 parts, with a HI relocation and a LO relocation. Each relocation
114 has only 16 bits of space to store an addend. This means that in
115 order for the linker to handle carries correctly, it must be able
116 to locate both the HI and the LO relocation. This means that the
117 relocations must appear in order in the relocation table.
118
119 In order to implement this, we keep track of each unmatched HI
120 relocation. We then sort them so that they immediately precede the
121 corresponding LO relocation. */
122
123 struct fr30_hi_fixup
124 {
125 struct fr30_hi_fixup * next; /* Next HI fixup. */
126 fixS * fixp; /* This fixup. */
127 segT seg; /* The section this fixup is in. */
128
129 };
130
131 /* The list of unmatched HI relocs. */
132
133 static struct fr30_hi_fixup * fr30_hi_fixup_list;
134
135 \f
136 #define FR30_SHORTOPTS ""
137 const char * md_shortopts = FR30_SHORTOPTS;
138
139 struct option md_longopts[] =
140 {
141 /* Sigh. I guess all warnings must now have both variants. */
142 #define OPTION_WARN_UNMATCHED (OPTION_MD_BASE + 4)
143 {"warn-unmatched-high", OPTION_WARN_UNMATCHED},
144 {"Wuh", OPTION_WARN_UNMATCHED},
145 #define OPTION_NO_WARN_UNMATCHED (OPTION_MD_BASE + 5)
146 {"no-warn-unmatched-high", OPTION_WARN_UNMATCHED},
147 {"Wnuh", OPTION_WARN_UNMATCHED},
148
149 #if 0 /* not supported yet */
150 #define OPTION_RELAX (OPTION_MD_BASE + 6)
151 {"relax", no_argument, NULL, OPTION_RELAX},
152 #define OPTION_CPU_DESC (OPTION_MD_BASE + 7)
153 {"cpu-desc", required_argument, NULL, OPTION_CPU_DESC},
154 #endif
155
156 {NULL, no_argument, NULL, 0}
157 };
158 size_t md_longopts_size = sizeof (md_longopts);
159
160 int
161 md_parse_option (c, arg)
162 int c;
163 char * arg;
164 {
165 switch (c)
166 {
167 case OPTION_WARN_UNMATCHED:
168 warn_unmatched_high = 1;
169 break;
170
171 case OPTION_NO_WARN_UNMATCHED:
172 warn_unmatched_high = 0;
173 break;
174
175 #if 0 /* not supported yet */
176 case OPTION_RELAX:
177 fr30_relax = 1;
178 break;
179 case OPTION_CPU_DESC:
180 fr30_cpu_desc = arg;
181 break;
182 #endif
183
184 default:
185 return 0;
186 }
187 return 1;
188 }
189
190 void
191 md_show_usage (stream)
192 FILE * stream;
193 {
194 fprintf (stream, _(" FR30 specific command line options:\n"));
195
196 fprintf (stream, _("\
197 -warn-unmatched-high warn when an (s)high reloc has no matching low reloc\n"));
198 fprintf (stream, _("\
199 -no-warn-unmatched-high do not warn about missing low relocs\n"));
200 fprintf (stream, _("\
201 -Wuh synonym for -warn-unmatched-high\n"));
202 fprintf (stream, _("\
203 -Wnuh synonym for -no-warn-unmatched-high\n"));
204
205 #if 0
206 fprintf (stream, _("\
207 -relax create linker relaxable code\n"));
208 fprintf (stream, _("\
209 -cpu-desc provide runtime cpu description file\n"));
210 #endif
211 }
212
213 static void fill_insn PARAMS ((int));
214 static void fr30_scomm PARAMS ((int));
215 static void debug_sym PARAMS ((int));
216 static void expand_debug_syms PARAMS ((sym_linkS *, int));
217
218 /* Set by md_assemble for use by fr30_fill_insn. */
219 static subsegT prev_subseg;
220 static segT prev_seg;
221
222 /* The target specific pseudo-ops which we support. */
223 const pseudo_typeS md_pseudo_table[] =
224 {
225 { "word", cons, 4 },
226 { "fillinsn", fill_insn, 0 },
227 { "scomm", fr30_scomm, 0 },
228 { "debugsym", debug_sym, 0 },
229 { NULL, NULL, 0 }
230 };
231
232 /* FIXME: Should be machine generated. */
233 #define NOP_INSN 0x7000
234 #define PAR_NOP_INSN 0xf000 /* can only be used in 2nd slot */
235
236 /* When we align the .text section, insert the correct NOP pattern.
237 N is the power of 2 alignment. LEN is the length of pattern FILL.
238 MAX is the maximum number of characters to skip when doing the alignment,
239 or 0 if there is no maximum. */
240
241 int
242 fr30_do_align (n, fill, len, max)
243 int n;
244 const char * fill;
245 int len;
246 int max;
247 {
248 /* Only do this if the fill pattern wasn't specified. */
249 if (fill == NULL
250 && (now_seg->flags & SEC_CODE) != 0
251 /* Only do this special handling if aligning to at least a
252 4 byte boundary. */
253 && n > 1
254 /* Only do this special handling if we're allowed to emit at
255 least two bytes. */
256 && (max == 0 || max > 1))
257 {
258 static const unsigned char nop_pattern[] = { 0xf0, 0x00 };
259
260 #if 0
261 /* First align to a 2 byte boundary, in case there is an odd .byte. */
262 /* FIXME: How much memory will cause gas to use when assembling a big
263 program? Perhaps we can avoid the frag_align call? */
264 frag_align (1, 0, 0);
265 #endif
266 /* Next align to a 4 byte boundary (we know n >= 2) using a parallel
267 nop. */
268 frag_align_pattern (2, nop_pattern, sizeof nop_pattern, 0);
269 /* If doing larger alignments use a repeating sequence of appropriate
270 nops. */
271 if (n > 2)
272 {
273 static const unsigned char multi_nop_pattern[] =
274 { 0x70, 0x00, 0xf0, 0x00 };
275 frag_align_pattern (n, multi_nop_pattern, sizeof multi_nop_pattern,
276 max ? max - 2 : 0);
277 }
278
279 prev_insn.insn = NULL;
280 return 1;
281 }
282
283 return 0;
284 }
285
286 /* If the last instruction was the first of 2 16 bit insns,
287 output a nop to move the PC to a 32 bit boundary.
288
289 This is done via an alignment specification since branch relaxing
290 may make it unnecessary.
291
292 Internally, we need to output one of these each time a 32 bit insn is
293 seen after an insn that is relaxable. */
294
295 static void
296 fill_insn (ignore)
297 int ignore;
298 {
299 (void) fr30_do_align (2, NULL, 0, 0);
300 prev_insn.insn = NULL;
301 seen_relaxable_p = 0;
302 }
303
304 /* Record the symbol so that when we output the insn, we can create
305 a symbol that is at the start of the instruction. This is used
306 to emit the label for the start of a breakpoint without causing
307 the assembler to emit a NOP if the previous instruction was a
308 16 bit instruction. */
309
310 static void
311 debug_sym (ignore)
312 int ignore;
313 {
314 register char *name;
315 register char delim;
316 register char *end_name;
317 register symbolS *symbolP;
318 register sym_linkS *link;
319
320 name = input_line_pointer;
321 delim = get_symbol_end ();
322 end_name = input_line_pointer;
323
324 if ((symbolP = symbol_find (name)) == NULL
325 && (symbolP = md_undefined_symbol (name)) == NULL)
326 {
327 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
328 }
329
330 symbol_table_insert (symbolP);
331 if (S_IS_DEFINED (symbolP) && S_GET_SEGMENT (symbolP) != reg_section)
332 /* xgettext:c-format */
333 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
334
335 else
336 {
337 link = (sym_linkS *) xmalloc (sizeof (sym_linkS));
338 link->symbol = symbolP;
339 link->next = debug_sym_link;
340 debug_sym_link = link;
341 symbolP->local = 1;
342 }
343
344 *end_name = delim;
345 demand_empty_rest_of_line ();
346 }
347
348 /* Second pass to expanding the debug symbols, go through linked
349 list of symbols and reassign the address. */
350
351 static void
352 expand_debug_syms (syms, align)
353 sym_linkS *syms;
354 int align;
355 {
356 char *save_input_line = input_line_pointer;
357 sym_linkS *next_syms;
358
359 if (!syms)
360 return;
361
362 (void) fr30_do_align (align, NULL, 0, 0);
363 for (; syms != (sym_linkS *)0; syms = next_syms)
364 {
365 symbolS *symbolP = syms->symbol;
366 next_syms = syms->next;
367 input_line_pointer = ".\n";
368 pseudo_set (symbolP);
369 free ((char *)syms);
370 }
371
372 input_line_pointer = save_input_line;
373 }
374
375 /* Cover function to fill_insn called after a label and at end of assembly.
376 The result is always 1: we're called in a conditional to see if the
377 current line is a label. */
378
379 int
380 fr30_fill_insn (done)
381 int done;
382 {
383 if (prev_seg != NULL)
384 {
385 segT seg = now_seg;
386 subsegT subseg = now_subseg;
387
388 subseg_set (prev_seg, prev_subseg);
389
390 fill_insn (0);
391
392 subseg_set (seg, subseg);
393 }
394
395 if (done && debug_sym_link)
396 {
397 expand_debug_syms (debug_sym_link, 1);
398 debug_sym_link = (sym_linkS *)0;
399 }
400
401 return 1;
402 }
403 \f
404 void
405 md_begin ()
406 {
407 flagword applicable;
408 segT seg;
409 subsegT subseg;
410
411 /* Initialize the `cgen' interface. */
412
413 /* Set the machine number and endian. */
414 gas_cgen_opcode_desc = fr30_cgen_opcode_open (0 /* mach number */,
415 target_big_endian ?
416 CGEN_ENDIAN_BIG
417 : CGEN_ENDIAN_LITTLE);
418 fr30_cgen_init_asm (gas_cgen_opcode_desc);
419
420 /* This is a callback from cgen to gas to parse operands. */
421 cgen_set_parse_operand_fn (gas_cgen_opcode_desc, gas_cgen_parse_operand);
422
423 #if 0 /* not supported yet */
424 /* If a runtime cpu description file was provided, parse it. */
425 if (fr30_cpu_desc != NULL)
426 {
427 const char * errmsg;
428
429 errmsg = cgen_read_cpu_file (gas_cgen_opcode_desc, fr30_cpu_desc);
430 if (errmsg != NULL)
431 as_bad ("%s: %s", fr30_cpu_desc, errmsg);
432 }
433 #endif
434
435 /* Save the current subseg so we can restore it [it's the default one and
436 we don't want the initial section to be .sbss]. */
437 seg = now_seg;
438 subseg = now_subseg;
439
440 /* The sbss section is for local .scomm symbols. */
441 sbss_section = subseg_new (".sbss", 0);
442
443 /* This is copied from perform_an_assembly_pass. */
444 applicable = bfd_applicable_section_flags (stdoutput);
445 bfd_set_section_flags (stdoutput, sbss_section, applicable & SEC_ALLOC);
446
447 #if 0 /* What does this do? [see perform_an_assembly_pass] */
448 seg_info (bss_section)->bss = 1;
449 #endif
450
451 subseg_set (seg, subseg);
452
453 /* We must construct a fake section similar to bfd_com_section
454 but with the name .scommon. */
455 scom_section = bfd_com_section;
456 scom_section.name = ".scommon";
457 scom_section.output_section = & scom_section;
458 scom_section.symbol = & scom_symbol;
459 scom_section.symbol_ptr_ptr = & scom_section.symbol;
460 scom_symbol = * bfd_com_section.symbol;
461 scom_symbol.name = ".scommon";
462 scom_symbol.section = & scom_section;
463 }
464
465 void
466 md_assemble (str)
467 char * str;
468 {
469 #if 0
470 fr30_insn insn;
471 char * errmsg;
472 char * str2 = NULL;
473
474 /* Initialize GAS's cgen interface for a new instruction. */
475 gas_cgen_init_parse ();
476
477 insn.debug_sym_link = debug_sym_link;
478 debug_sym_link = (sym_linkS *)0;
479
480 insn.insn = fr30_cgen_assemble_insn
481 (gas_cgen_opcode_desc, str, & insn.fields, insn.buffer, & errmsg);
482
483 if (!insn.insn)
484 {
485 as_bad (errmsg);
486 return;
487 }
488
489 if (CGEN_INSN_BITSIZE (insn.insn) == 32)
490 {
491 /* 32 bit insns must live on 32 bit boundaries. */
492 if (prev_insn.insn || seen_relaxable_p)
493 {
494 /* ??? If calling fill_insn too many times turns us into a memory
495 pig, can we call a fn to assemble a nop instead of
496 !seen_relaxable_p? */
497 fill_insn (0);
498 }
499
500 expand_debug_syms (insn.debug_sym_link, 2);
501
502 /* Doesn't really matter what we pass for RELAX_P here. */
503 gas_cgen_finish_insn (insn.insn, insn.buffer,
504 CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
505 }
506 else
507 {
508 int on_32bit_boundary_p;
509
510 if (CGEN_INSN_BITSIZE (insn.insn) != 16)
511 abort();
512
513 insn.orig_insn = insn.insn;
514
515 /* Compute whether we're on a 32 bit boundary or not.
516 prev_insn.insn is NULL when we're on a 32 bit boundary. */
517 on_32bit_boundary_p = prev_insn.insn == NULL;
518
519 expand_debug_syms (insn.debug_sym_link, 1);
520
521 {
522 int i;
523 finished_insnS fi;
524
525 /* Ensure each pair of 16 bit insns is in the same frag. */
526 frag_grow (4);
527
528 gas_cgen_finish_insn (insn.orig_insn, insn.buffer,
529 CGEN_FIELDS_BITSIZE (& insn.fields),
530 1 /*relax_p*/, &fi);
531 insn.addr = fi.addr;
532 insn.frag = fi.frag;
533 insn.num_fixups = fi.num_fixups;
534 for (i = 0; i < fi.num_fixups; ++i)
535 insn.fixups[i] = fi.fixups[i];
536 }
537
538 /* Keep track of whether we've seen a pair of 16 bit insns.
539 prev_insn.insn is NULL when we're on a 32 bit boundary. */
540 if (on_32bit_boundary_p)
541 prev_insn = insn;
542 else
543 prev_insn.insn = NULL;
544
545 /* If the insn needs the following one to be on a 32 bit boundary
546 (e.g. subroutine calls), fill this insn's slot. */
547 if (on_32bit_boundary_p
548 && CGEN_INSN_ATTR (insn.orig_insn, CGEN_INSN_FILL_SLOT) != 0)
549 fill_insn (0);
550
551 /* If this is a relaxable insn (can be replaced with a larger version)
552 mark the fact so that we can emit an alignment directive for a
553 following 32 bit insn if we see one. */
554 if (CGEN_INSN_ATTR (insn.orig_insn, CGEN_INSN_RELAXABLE) != 0)
555 seen_relaxable_p = 1;
556 }
557
558 /* Set these so fr30_fill_insn can use them. */
559 prev_seg = now_seg;
560 prev_subseg = now_subseg;
561 #endif
562 }
563
564 /* The syntax in the manual says constants begin with '#'.
565 We just ignore it. */
566
567 void
568 md_operand (expressionP)
569 expressionS * expressionP;
570 {
571 if (* input_line_pointer == '#')
572 {
573 input_line_pointer ++;
574 expression (expressionP);
575 }
576 }
577
578 valueT
579 md_section_align (segment, size)
580 segT segment;
581 valueT size;
582 {
583 int align = bfd_get_section_alignment (stdoutput, segment);
584 return ((size + (1 << align) - 1) & (-1 << align));
585 }
586
587 symbolS *
588 md_undefined_symbol (name)
589 char * name;
590 {
591 return 0;
592 }
593 \f
594 /* .scomm pseudo-op handler.
595
596 This is a new pseudo-op to handle putting objects in .scommon.
597 By doing this the linker won't need to do any work and more importantly
598 it removes the implicit -G arg necessary to correctly link the object file.
599 */
600
601 static void
602 fr30_scomm (ignore)
603 int ignore;
604 {
605 register char * name;
606 register char c;
607 register char * p;
608 offsetT size;
609 register symbolS * symbolP;
610 offsetT align;
611 int align2;
612
613 name = input_line_pointer;
614 c = get_symbol_end ();
615
616 /* just after name is now '\0' */
617 p = input_line_pointer;
618 * p = c;
619 SKIP_WHITESPACE ();
620 if (* input_line_pointer != ',')
621 {
622 as_bad (_("Expected comma after symbol-name: rest of line ignored."));
623 ignore_rest_of_line ();
624 return;
625 }
626
627 input_line_pointer ++; /* skip ',' */
628 if ((size = get_absolute_expression ()) < 0)
629 {
630 /* xgettext:c-format */
631 as_warn (_(".SCOMMon length (%ld.) <0! Ignored."), (long) size);
632 ignore_rest_of_line ();
633 return;
634 }
635
636 /* The third argument to .scomm is the alignment. */
637 if (* input_line_pointer != ',')
638 align = 8;
639 else
640 {
641 ++ input_line_pointer;
642 align = get_absolute_expression ();
643 if (align <= 0)
644 {
645 as_warn (_("ignoring bad alignment"));
646 align = 8;
647 }
648 }
649 /* Convert to a power of 2 alignment. */
650 if (align)
651 {
652 for (align2 = 0; (align & 1) == 0; align >>= 1, ++ align2)
653 continue;
654 if (align != 1)
655 {
656 as_bad (_("Common alignment not a power of 2"));
657 ignore_rest_of_line ();
658 return;
659 }
660 }
661 else
662 align2 = 0;
663
664 * p = 0;
665 symbolP = symbol_find_or_make (name);
666 * p = c;
667
668 if (S_IS_DEFINED (symbolP))
669 {
670 /* xgettext:c-format */
671 as_bad (_("Ignoring attempt to re-define symbol `%s'."),
672 S_GET_NAME (symbolP));
673 ignore_rest_of_line ();
674 return;
675 }
676
677 if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
678 {
679 /* xgettext:c-format */
680 as_bad (_("Length of .scomm \"%s\" is already %ld. Not changed to %ld."),
681 S_GET_NAME (symbolP),
682 (long) S_GET_VALUE (symbolP),
683 (long) size);
684
685 ignore_rest_of_line ();
686 return;
687 }
688
689 if (symbolP->local)
690 {
691 segT old_sec = now_seg;
692 int old_subsec = now_subseg;
693 char * pfrag;
694
695 record_alignment (sbss_section, align2);
696 subseg_set (sbss_section, 0);
697
698 if (align2)
699 frag_align (align2, 0, 0);
700
701 if (S_GET_SEGMENT (symbolP) == sbss_section)
702 symbolP->sy_frag->fr_symbol = 0;
703
704 symbolP->sy_frag = frag_now;
705
706 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
707 (char *) 0);
708 * pfrag = 0;
709 S_SET_SIZE (symbolP, size);
710 S_SET_SEGMENT (symbolP, sbss_section);
711 S_CLEAR_EXTERNAL (symbolP);
712 subseg_set (old_sec, old_subsec);
713 }
714 else
715 {
716 S_SET_VALUE (symbolP, (valueT) size);
717 S_SET_ALIGN (symbolP, align2);
718 S_SET_EXTERNAL (symbolP);
719 S_SET_SEGMENT (symbolP, & scom_section);
720 }
721
722 demand_empty_rest_of_line ();
723 }
724 \f
725 /* Interface to relax_segment. */
726
727 /* FIXME: Build table by hand, get it working, then machine generate. */
728
729 const relax_typeS md_relax_table[] =
730 {
731 /* The fields are:
732 1) most positive reach of this state,
733 2) most negative reach of this state,
734 3) how many bytes this mode will add to the size of the current frag
735 4) which index into the table to try if we can't fit into this one. */
736
737 /* The first entry must be unused because an `rlx_more' value of zero ends
738 each list. */
739 {1, 1, 0, 0},
740
741 /* The displacement used by GAS is from the end of the 2 byte insn,
742 so we subtract 2 from the following. */
743 /* 16 bit insn, 8 bit disp -> 10 bit range.
744 This doesn't handle a branch in the right slot at the border:
745 the "& -4" isn't taken into account. It's not important enough to
746 complicate things over it, so we subtract an extra 2 (or + 2 in -ve
747 case). */
748 {511 - 2 - 2, -512 - 2 + 2, 0, 2 },
749 /* 32 bit insn, 24 bit disp -> 26 bit range. */
750 {0x2000000 - 1 - 2, -0x2000000 - 2, 2, 0 },
751 /* Same thing, but with leading nop for alignment. */
752 {0x2000000 - 1 - 2, -0x2000000 - 2, 4, 0 }
753 };
754
755 long
756 fr30_relax_frag (fragP, stretch)
757 fragS * fragP;
758 long stretch;
759 {
760 /* Address of branch insn. */
761 long address = fragP->fr_address + fragP->fr_fix - 2;
762 long growth = 0;
763
764 /* Keep 32 bit insns aligned on 32 bit boundaries. */
765 if (fragP->fr_subtype == 2)
766 {
767 if ((address & 3) != 0)
768 {
769 fragP->fr_subtype = 3;
770 growth = 2;
771 }
772 }
773 else if (fragP->fr_subtype == 3)
774 {
775 if ((address & 3) == 0)
776 {
777 fragP->fr_subtype = 2;
778 growth = -2;
779 }
780 }
781 else
782 {
783 growth = relax_frag (fragP, stretch);
784
785 /* Long jump on odd halfword boundary? */
786 if (fragP->fr_subtype == 2 && (address & 3) != 0)
787 {
788 fragP->fr_subtype = 3;
789 growth += 2;
790 }
791 }
792
793 return growth;
794 }
795
796 /* Return an initial guess of the length by which a fragment must grow to
797 hold a branch to reach its destination.
798 Also updates fr_type/fr_subtype as necessary.
799
800 Called just before doing relaxation.
801 Any symbol that is now undefined will not become defined.
802 The guess for fr_var is ACTUALLY the growth beyond fr_fix.
803 Whatever we do to grow fr_fix or fr_var contributes to our returned value.
804 Although it may not be explicit in the frag, pretend fr_var starts with a
805 0 value. */
806
807 int
808 md_estimate_size_before_relax (fragP, segment)
809 fragS * fragP;
810 segT segment;
811 {
812 int old_fr_fix = fragP->fr_fix;
813
814 /* The only thing we have to handle here are symbols outside of the
815 current segment. They may be undefined or in a different segment in
816 which case linker scripts may place them anywhere.
817 However, we can't finish the fragment here and emit the reloc as insn
818 alignment requirements may move the insn about. */
819
820 if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
821 {
822 /* The symbol is undefined in this segment.
823 Change the relaxation subtype to the max allowable and leave
824 all further handling to md_convert_frag. */
825 fragP->fr_subtype = 2;
826
827 #if 0 /* Can't use this, but leave in for illustration. */
828 /* Change 16 bit insn to 32 bit insn. */
829 fragP->fr_opcode[0] |= 0x80;
830
831 /* Increase known (fixed) size of fragment. */
832 fragP->fr_fix += 2;
833
834 /* Create a relocation for it. */
835 fix_new (fragP, old_fr_fix, 4,
836 fragP->fr_symbol,
837 fragP->fr_offset, 1 /* pcrel */,
838 /* FIXME: Can't use a real BFD reloc here.
839 gas_cgen_md_apply_fix3 can't handle it. */
840 BFD_RELOC_FR30_26_PCREL);
841
842 /* Mark this fragment as finished. */
843 frag_wane (fragP);
844 #else
845 {
846 const CGEN_INSN * insn;
847 int i;
848
849 /* Update the recorded insn.
850 Fortunately we don't have to look very far.
851 FIXME: Change this to record in the instruction the next higher
852 relaxable insn to use. */
853 for (i = 0, insn = fragP->fr_cgen.insn; i < 4; i++, insn++)
854 {
855 if ((strcmp (CGEN_INSN_MNEMONIC (insn),
856 CGEN_INSN_MNEMONIC (fragP->fr_cgen.insn))
857 == 0)
858 && CGEN_INSN_ATTR (insn, CGEN_INSN_RELAX))
859 break;
860 }
861 if (i == 4)
862 abort ();
863
864 fragP->fr_cgen.insn = insn;
865 return 2;
866 }
867 #endif
868 }
869
870 return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
871 }
872
873 /* *fragP has been relaxed to its final size, and now needs to have
874 the bytes inside it modified to conform to the new size.
875
876 Called after relaxation is finished.
877 fragP->fr_type == rs_machine_dependent.
878 fragP->fr_subtype is the subtype of what the address relaxed to. */
879
880 void
881 md_convert_frag (abfd, sec, fragP)
882 bfd * abfd;
883 segT sec;
884 fragS * fragP;
885 {
886 #if 0
887 char * opcode;
888 char * displacement;
889 int target_address;
890 int opcode_address;
891 int extension;
892 int addend;
893
894 opcode = fragP->fr_opcode;
895
896 /* Address opcode resides at in file space. */
897 opcode_address = fragP->fr_address + fragP->fr_fix - 2;
898
899 switch (fragP->fr_subtype)
900 {
901 case 1 :
902 extension = 0;
903 displacement = & opcode[1];
904 break;
905 case 2 :
906 opcode[0] |= 0x80;
907 extension = 2;
908 displacement = & opcode[1];
909 break;
910 case 3 :
911 opcode[2] = opcode[0] | 0x80;
912 md_number_to_chars (opcode, PAR_NOP_INSN, 2);
913 opcode_address += 2;
914 extension = 4;
915 displacement = & opcode[3];
916 break;
917 default :
918 abort ();
919 }
920
921 if (S_GET_SEGMENT (fragP->fr_symbol) != sec)
922 {
923 /* symbol must be resolved by linker */
924 if (fragP->fr_offset & 3)
925 as_warn (_("Addend to unresolved symbol not on word boundary."));
926 addend = fragP->fr_offset >> 2;
927 }
928 else
929 {
930 /* Address we want to reach in file space. */
931 target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
932 target_address += fragP->fr_symbol->sy_frag->fr_address;
933 addend = (target_address - (opcode_address & -4)) >> 2;
934 }
935
936 /* Create a relocation for symbols that must be resolved by the linker.
937 Otherwise output the completed insn. */
938
939 if (S_GET_SEGMENT (fragP->fr_symbol) != sec)
940 {
941 assert (fragP->fr_subtype != 1);
942 assert (fragP->fr_cgen.insn != 0);
943 gas_cgen_record_fixup (fragP,
944 /* Offset of branch insn in frag. */
945 fragP->fr_fix + extension - 4,
946 fragP->fr_cgen.insn,
947 4 /*length*/,
948 /* FIXME: quick hack */
949 #if 0
950 CGEN_OPERAND_ENTRY (fragP->fr_cgen.opindex),
951 #else
952 CGEN_OPERAND_ENTRY (FR30_OPERAND_DISP24),
953 #endif
954 fragP->fr_cgen.opinfo,
955 fragP->fr_symbol, fragP->fr_offset);
956 }
957
958 #define SIZE_FROM_RELAX_STATE(n) ((n) == 1 ? 1 : 3)
959
960 md_number_to_chars (displacement, (valueT) addend,
961 SIZE_FROM_RELAX_STATE (fragP->fr_subtype));
962
963 fragP->fr_fix += extension;
964 #endif
965 }
966 \f
967 /* Functions concerning relocs. */
968
969 /* The location from which a PC relative jump should be calculated,
970 given a PC relative reloc. */
971
972 long
973 md_pcrel_from_section (fixP, sec)
974 fixS * fixP;
975 segT sec;
976 {
977 if (fixP->fx_addsy != (symbolS *) NULL
978 && (! S_IS_DEFINED (fixP->fx_addsy)
979 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
980 {
981 /* The symbol is undefined (or is defined but not in this section).
982 Let the linker figure it out. */
983 return 0;
984 }
985
986 return (fixP->fx_frag->fr_address + fixP->fx_where) & -4L;
987 }
988
989 /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
990 Returns BFD_RELOC_NONE if no reloc type can be found.
991 *FIXP may be modified if desired. */
992
993 bfd_reloc_code_real_type
994 md_cgen_lookup_reloc (insn, operand, fixP)
995 const CGEN_INSN * insn;
996 const CGEN_OPERAND * operand;
997 fixS * fixP;
998 {
999 #if 0
1000 switch (CGEN_OPERAND_TYPE (operand))
1001 {
1002 case FR30_OPERAND_DISP8 : return BFD_RELOC_FR30_10_PCREL;
1003 case FR30_OPERAND_DISP16 : return BFD_RELOC_FR30_18_PCREL;
1004 case FR30_OPERAND_DISP24 : return BFD_RELOC_FR30_26_PCREL;
1005 case FR30_OPERAND_UIMM24 : return BFD_RELOC_FR30_24;
1006 case FR30_OPERAND_HI16 :
1007 case FR30_OPERAND_SLO16 :
1008 case FR30_OPERAND_ULO16 :
1009 /* If low/high/shigh/sda was used, it is recorded in `opinfo'. */
1010 if (fixP->tc_fix_data.opinfo != 0)
1011 return fixP->tc_fix_data.opinfo;
1012 break;
1013 default : /* avoid -Wall warning */
1014 break;
1015 }
1016 #endif
1017 return BFD_RELOC_NONE;
1018 }
1019
1020 /* Record a HI16 reloc for later matching with its LO16 cousin. */
1021
1022 static void
1023 fr30_record_hi16 (reloc_type, fixP, seg)
1024 int reloc_type;
1025 fixS * fixP;
1026 segT seg;
1027 {
1028 struct fr30_hi_fixup * hi_fixup;
1029
1030 assert (reloc_type == BFD_RELOC_FR30_HI16_SLO
1031 || reloc_type == BFD_RELOC_FR30_HI16_ULO);
1032
1033 hi_fixup = ((struct fr30_hi_fixup *)
1034 xmalloc (sizeof (struct fr30_hi_fixup)));
1035 hi_fixup->fixp = fixP;
1036 hi_fixup->seg = now_seg;
1037 hi_fixup->next = fr30_hi_fixup_list;
1038
1039 fr30_hi_fixup_list = hi_fixup;
1040 }
1041
1042 /* Called while parsing an instruction to create a fixup.
1043 We need to check for HI16 relocs and queue them up for later sorting. */
1044
1045 fixS *
1046 fr30_cgen_record_fixup_exp (frag, where, insn, length, operand, opinfo, exp)
1047 fragS * frag;
1048 int where;
1049 const CGEN_INSN * insn;
1050 int length;
1051 const CGEN_OPERAND * operand;
1052 int opinfo;
1053 expressionS * exp;
1054 {
1055 #if 0
1056 fixS * fixP = gas_cgen_record_fixup_exp (frag, where, insn, length,
1057 operand, opinfo, exp);
1058
1059 switch (CGEN_OPERAND_TYPE (operand))
1060 {
1061 case FR30_OPERAND_HI16 :
1062 /* If low/high/shigh/sda was used, it is recorded in `opinfo'. */
1063 if (fixP->tc_fix_data.opinfo == BFD_RELOC_FR30_HI16_SLO
1064 || fixP->tc_fix_data.opinfo == BFD_RELOC_FR30_HI16_ULO)
1065 fr30_record_hi16 (fixP->tc_fix_data.opinfo, fixP, now_seg);
1066 break;
1067 default : /* avoid -Wall warning */
1068 break;
1069 }
1070
1071 return fixP;
1072 #else
1073 return 0;
1074 #endif
1075 }
1076
1077 /* Return BFD reloc type from opinfo field in a fixS.
1078 It's tricky using fx_r_type in fr30_frob_file because the values
1079 are BFD_RELOC_UNUSED + operand number. */
1080 #define FX_OPINFO_R_TYPE(f) ((f)->tc_fix_data.opinfo)
1081
1082 /* Sort any unmatched HI16 relocs so that they immediately precede
1083 the corresponding LO16 reloc. This is called before md_apply_fix and
1084 tc_gen_reloc. */
1085
1086 void
1087 fr30_frob_file ()
1088 {
1089 struct fr30_hi_fixup * l;
1090
1091 for (l = fr30_hi_fixup_list; l != NULL; l = l->next)
1092 {
1093 segment_info_type * seginfo;
1094 int pass;
1095
1096 assert (FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_FR30_HI16_SLO
1097 || FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_FR30_HI16_ULO);
1098
1099 /* Check quickly whether the next fixup happens to be a matching low. */
1100 if (l->fixp->fx_next != NULL
1101 && FX_OPINFO_R_TYPE (l->fixp->fx_next) == BFD_RELOC_FR30_LO16
1102 && l->fixp->fx_addsy == l->fixp->fx_next->fx_addsy
1103 && l->fixp->fx_offset == l->fixp->fx_next->fx_offset)
1104 continue;
1105
1106 /* Look through the fixups for this segment for a matching `low'.
1107 When we find one, move the high/shigh just in front of it. We do
1108 this in two passes. In the first pass, we try to find a
1109 unique `low'. In the second pass, we permit multiple high's
1110 relocs for a single `low'. */
1111 seginfo = seg_info (l->seg);
1112 for (pass = 0; pass < 2; pass++)
1113 {
1114 fixS * f;
1115 fixS * prev;
1116
1117 prev = NULL;
1118 for (f = seginfo->fix_root; f != NULL; f = f->fx_next)
1119 {
1120 /* Check whether this is a `low' fixup which matches l->fixp. */
1121 if (FX_OPINFO_R_TYPE (f) == BFD_RELOC_FR30_LO16
1122 && f->fx_addsy == l->fixp->fx_addsy
1123 && f->fx_offset == l->fixp->fx_offset
1124 && (pass == 1
1125 || prev == NULL
1126 || (FX_OPINFO_R_TYPE (prev) != BFD_RELOC_FR30_HI16_SLO
1127 && FX_OPINFO_R_TYPE (prev) != BFD_RELOC_FR30_HI16_ULO)
1128 || prev->fx_addsy != f->fx_addsy
1129 || prev->fx_offset != f->fx_offset))
1130 {
1131 fixS ** pf;
1132
1133 /* Move l->fixp before f. */
1134 for (pf = &seginfo->fix_root;
1135 * pf != l->fixp;
1136 pf = & (* pf)->fx_next)
1137 assert (* pf != NULL);
1138
1139 * pf = l->fixp->fx_next;
1140
1141 l->fixp->fx_next = f;
1142 if (prev == NULL)
1143 seginfo->fix_root = l->fixp;
1144 else
1145 prev->fx_next = l->fixp;
1146
1147 break;
1148 }
1149
1150 prev = f;
1151 }
1152
1153 if (f != NULL)
1154 break;
1155
1156 if (pass == 1
1157 && warn_unmatched_high)
1158 as_warn_where (l->fixp->fx_file, l->fixp->fx_line,
1159 _("Unmatched high/shigh reloc"));
1160 }
1161 }
1162 }
1163
1164 /* See whether we need to force a relocation into the output file.
1165 This is used to force out switch and PC relative relocations when
1166 relaxing. */
1167
1168 int
1169 fr30_force_relocation (fix)
1170 fixS * fix;
1171 {
1172 if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
1173 || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1174 return 1;
1175
1176 if (! fr30_relax)
1177 return 0;
1178
1179 return (fix->fx_pcrel
1180 || 0 /* ??? */);
1181 }
1182 \f
1183 /* Write a value out to the object file, using the appropriate endianness. */
1184
1185 void
1186 md_number_to_chars (buf, val, n)
1187 char * buf;
1188 valueT val;
1189 int n;
1190 {
1191 if (target_big_endian)
1192 number_to_chars_bigendian (buf, val, n);
1193 else
1194 number_to_chars_littleendian (buf, val, n);
1195 }
1196
1197 /* Turn a string in input_line_pointer into a floating point constant of type
1198 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1199 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
1200 */
1201
1202 /* Equal to MAX_PRECISION in atof-ieee.c */
1203 #define MAX_LITTLENUMS 6
1204
1205 char *
1206 md_atof (type, litP, sizeP)
1207 char type;
1208 char *litP;
1209 int *sizeP;
1210 {
1211 int i;
1212 int prec;
1213 LITTLENUM_TYPE words [MAX_LITTLENUMS];
1214 char * t;
1215 char * atof_ieee ();
1216
1217 switch (type)
1218 {
1219 case 'f':
1220 case 'F':
1221 case 's':
1222 case 'S':
1223 prec = 2;
1224 break;
1225
1226 case 'd':
1227 case 'D':
1228 case 'r':
1229 case 'R':
1230 prec = 4;
1231 break;
1232
1233 /* FIXME: Some targets allow other format chars for bigger sizes here. */
1234
1235 default:
1236 * sizeP = 0;
1237 return _("Bad call to md_atof()");
1238 }
1239
1240 t = atof_ieee (input_line_pointer, type, words);
1241 if (t)
1242 input_line_pointer = t;
1243 * sizeP = prec * sizeof (LITTLENUM_TYPE);
1244
1245 if (target_big_endian)
1246 {
1247 for (i = 0; i < prec; i++)
1248 {
1249 md_number_to_chars (litP, (valueT) words[i],
1250 sizeof (LITTLENUM_TYPE));
1251 litP += sizeof (LITTLENUM_TYPE);
1252 }
1253 }
1254 else
1255 {
1256 for (i = prec - 1; i >= 0; i--)
1257 {
1258 md_number_to_chars (litP, (valueT) words[i],
1259 sizeof (LITTLENUM_TYPE));
1260 litP += sizeof (LITTLENUM_TYPE);
1261 }
1262 }
1263
1264 return 0;
1265 }
1266
1267 void
1268 fr30_elf_section_change_hook ()
1269 {
1270 /* If we have reached the end of a section and we have just emitted a
1271 16 bit insn, then emit a nop to make sure that the section ends on
1272 a 32 bit boundary. */
1273
1274 if (prev_insn.insn || seen_relaxable_p)
1275 (void) fr30_fill_insn (0);
1276 }
1277
1278 boolean
1279 fr30_fix_adjustable (fixP)
1280 fixS *fixP;
1281 {
1282
1283 if (fixP->fx_addsy == NULL)
1284 return 1;
1285
1286 /* Prevent all adjustments to global symbols. */
1287 if (S_IS_EXTERN (fixP->fx_addsy))
1288 return 0;
1289 if (S_IS_WEAK (fixP->fx_addsy))
1290 return 0;
1291
1292 /* We need the symbol name for the VTABLE entries */
1293 if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
1294 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1295 return 0;
1296
1297 return 1;
1298 }