* config/tc-rx.c (md_convert_frag): If we can't compute the target
[external/binutils.git] / gas / config / tc-rx.c
1 /* tc-rx.c -- Assembler for the Renesas RX
2    Copyright 2008, 2009, 2010
3    Free Software Foundation, Inc.
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 3, 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 the Free
19    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20    02110-1301, USA.  */
21
22 #include "as.h"
23 #include "struc-symbol.h"
24 #include "obstack.h"
25 #include "safe-ctype.h"
26 #include "dwarf2dbg.h"
27 #include "libbfd.h"
28 #include "elf/common.h"
29 #include "elf/rx.h"
30 #include "rx-defs.h"
31 #include "filenames.h"
32 #include "listing.h"
33 #include "sb.h"
34 #include "macro.h"
35
36 #define RX_OPCODE_BIG_ENDIAN 0
37
38 const char comment_chars[]        = ";";
39 /* Note that input_file.c hand checks for '#' at the beginning of the
40    first line of the input file.  This is because the compiler outputs
41    #NO_APP at the beginning of its output.  */
42 const char line_comment_chars[]   = "#";
43 const char line_separator_chars[] = "!";
44
45 const char EXP_CHARS[]            = "eE";
46 const char FLT_CHARS[]            = "dD";
47 \f
48 /* ELF flags to set in the output file header.  */
49 static int elf_flags = 0;
50
51 bfd_boolean rx_use_conventional_section_names = FALSE;
52 static bfd_boolean rx_use_small_data_limit = FALSE;
53
54 enum options
55 {
56   OPTION_BIG = OPTION_MD_BASE,
57   OPTION_LITTLE,
58   OPTION_32BIT_DOUBLES,
59   OPTION_64BIT_DOUBLES,
60   OPTION_CONVENTIONAL_SECTION_NAMES,
61   OPTION_RENESAS_SECTION_NAMES,
62   OPTION_SMALL_DATA_LIMIT,
63   OPTION_RELAX
64 };
65
66 #define RX_SHORTOPTS ""
67 const char * md_shortopts = RX_SHORTOPTS;
68
69 /* Assembler options.  */
70 struct option md_longopts[] =
71 {
72   {"mbig-endian-data", no_argument, NULL, OPTION_BIG},
73   {"mlittle-endian-data", no_argument, NULL, OPTION_LITTLE},
74   /* The next two switches are here because the
75      generic parts of the linker testsuite uses them.  */
76   {"EB", no_argument, NULL, OPTION_BIG},
77   {"EL", no_argument, NULL, OPTION_LITTLE},
78   {"m32bit-doubles", no_argument, NULL, OPTION_32BIT_DOUBLES},
79   {"m64bit-doubles", no_argument, NULL, OPTION_64BIT_DOUBLES},
80   /* This option is here mainly for the binutils testsuites,
81      as many of their tests assume conventional section naming.  */
82   {"muse-conventional-section-names", no_argument, NULL, OPTION_CONVENTIONAL_SECTION_NAMES},
83   {"muse-renesas-section-names", no_argument, NULL, OPTION_RENESAS_SECTION_NAMES},
84   {"msmall-data-limit", no_argument, NULL, OPTION_SMALL_DATA_LIMIT},
85   {"relax", no_argument, NULL, OPTION_RELAX},
86   {NULL, no_argument, NULL, 0}
87 };
88 size_t md_longopts_size = sizeof (md_longopts);
89
90 int
91 md_parse_option (int c ATTRIBUTE_UNUSED, char * arg ATTRIBUTE_UNUSED)
92 {
93   switch (c)
94     {
95     case OPTION_BIG:
96       target_big_endian = 1;
97       return 1;
98
99     case OPTION_LITTLE:
100       target_big_endian = 0;
101       return 1;
102
103     case OPTION_32BIT_DOUBLES:
104       elf_flags &= ~ E_FLAG_RX_64BIT_DOUBLES;
105       return 1;
106
107     case OPTION_64BIT_DOUBLES:
108       elf_flags |= E_FLAG_RX_64BIT_DOUBLES;
109       return 1;
110
111     case OPTION_CONVENTIONAL_SECTION_NAMES:
112       rx_use_conventional_section_names = TRUE;
113       return 1;
114
115     case OPTION_RENESAS_SECTION_NAMES:
116       rx_use_conventional_section_names = FALSE;
117       return 1;
118
119     case OPTION_SMALL_DATA_LIMIT:
120       rx_use_small_data_limit = TRUE;
121       return 1;
122
123     case OPTION_RELAX:
124       linkrelax = 1;
125       return 1;
126     }
127   return 0;
128 }
129
130 void
131 md_show_usage (FILE * stream)
132 {
133   fprintf (stream, _(" RX specific command line options:\n"));
134   fprintf (stream, _("  --mbig-endian-data\n"));
135   fprintf (stream, _("  --mlittle-endian-data [default]\n"));
136   fprintf (stream, _("  --m32bit-doubles [default]\n"));
137   fprintf (stream, _("  --m64bit-doubles\n"));
138   fprintf (stream, _("  --muse-conventional-section-names\n"));
139   fprintf (stream, _("  --muse-renesas-section-names [default]\n"));
140   fprintf (stream, _("  --msmall-data-limit\n"));
141 }
142
143 static void
144 s_bss (int ignore ATTRIBUTE_UNUSED)
145 {
146   int temp;
147
148   temp = get_absolute_expression ();
149   subseg_set (bss_section, (subsegT) temp);
150   demand_empty_rest_of_line ();
151 }
152
153 static void
154 rx_float_cons (int ignore ATTRIBUTE_UNUSED)
155 {
156   if (elf_flags & E_FLAG_RX_64BIT_DOUBLES)
157     return float_cons ('d');
158   return float_cons ('f');
159 }
160
161 static char *
162 rx_strcasestr (const char *string, const char *sub)
163 {
164   int subl;
165   int strl;
166
167   if (!sub || !sub[0])
168     return (char *)string;
169
170   subl = strlen (sub);
171   strl = strlen (string);
172
173   while (strl >= subl)
174     {
175       /* strncasecmp is in libiberty.  */
176       if (strncasecmp (string, sub, subl) == 0)
177         return (char *)string;
178
179       string ++;
180       strl --;
181     }
182   return NULL;
183 }
184
185 static void
186 rx_include (int ignore)
187 {
188   FILE * try;
189   char * path;
190   char * filename;
191   char * current_filename;
192   char * eof;
193   char * p;
194   char * d;
195   char * f;
196   char   end_char;
197   size_t len;
198
199   /* The RX version of the .INCLUDE pseudo-op does not
200      have to have the filename inside double quotes.  */
201   SKIP_WHITESPACE ();
202   if (*input_line_pointer == '"')
203     {
204       /* Treat as the normal GAS .include pseudo-op.  */
205       s_include (ignore);
206       return;
207     }
208
209   /* Get the filename.  Spaces are allowed, NUL characters are not.  */
210   filename = input_line_pointer;
211   eof = find_end_of_line (filename, FALSE);
212   input_line_pointer = eof;
213
214   while (eof >= filename && (* eof == ' ' || * eof == '\n'))
215     -- eof;
216   end_char = *(++ eof);
217   * eof = 0;
218   if (eof == filename)
219     {
220       as_bad (_("no filename following .INCLUDE pseudo-op"));
221       * eof = end_char;
222       return;
223     }
224
225   as_where (& current_filename, NULL);
226   f = (char *) xmalloc (strlen (current_filename) + strlen (filename) + 1);
227
228   /* Check the filename.  If [@]..FILE[@] is found then replace
229      this with the current assembler source filename, stripped
230      of any directory prefixes or extensions.  */
231   if ((p = rx_strcasestr (filename, "..file")) != NULL)
232     {
233       char * c;
234
235       len = 6; /* strlen ("..file"); */
236
237       if (p > filename && p[-1] == '@')
238         -- p, ++len;
239
240       if (p[len] == '@')
241         len ++;
242
243       for (d = c = current_filename; *c; c++)
244         if (IS_DIR_SEPARATOR (* c))
245           d = c + 1;
246       for (c = d; *c; c++)
247         if (*c == '.')
248           break;
249
250       sprintf (f, "%.*s%.*s%.*s", (int) (p - filename), filename,
251                (int) (c - d), d,
252                (int) (strlen (filename) - ((p + len) - filename)),
253                p + len);
254     }
255   else
256     strcpy (f, filename);
257
258   /* RX .INCLUDE semantics say that 'filename' is located by:
259
260      1. If filename is absolute, just try that.  Otherwise...
261
262      2. If the current source file includes a directory component
263         then prepend that to the filename and try.  Otherwise...
264
265      3. Try any directories specified by the -I command line
266         option(s).
267
268      4 .Try a directory specifed by the INC100 environment variable.  */
269
270   if (IS_ABSOLUTE_PATH (f))
271     try = fopen (path = f, FOPEN_RT);
272   else
273     {
274       char * env = getenv ("INC100");
275
276       try = NULL;
277
278       len = strlen (current_filename);
279       if ((size_t) include_dir_maxlen > len)
280         len = include_dir_maxlen;
281       if (env && strlen (env) > len)
282         len = strlen (env);
283
284       path = (char *) xmalloc (strlen (f) + len + 5);
285
286       if (current_filename != NULL)
287         {
288           for (d = NULL, p = current_filename; *p; p++)
289             if (IS_DIR_SEPARATOR (* p))
290               d = p;
291
292           if (d != NULL)
293             {
294               sprintf (path, "%.*s/%s", (int) (d - current_filename), current_filename,
295                        f);
296               try = fopen (path, FOPEN_RT);
297             }
298         }
299
300       if (try == NULL)
301         {
302           int i;
303
304           for (i = 0; i < include_dir_count; i++)
305             {
306               sprintf (path, "%s/%s", include_dirs[i], f);
307               if ((try = fopen (path, FOPEN_RT)) != NULL)
308                 break;
309             }
310         }
311
312       if (try == NULL && env != NULL)
313         {
314           sprintf (path, "%s/%s", env, f);
315           try = fopen (path, FOPEN_RT);
316         }
317
318       free (f);
319     }
320
321   if (try == NULL)
322     {
323       as_bad (_("unable to locate include file: %s"), filename);
324       free (path);
325     }
326   else
327     {
328       fclose (try);
329       register_dependency (path);
330       input_scrub_insert_file (path);
331     }
332
333   * eof = end_char;
334 }
335
336 static void
337 parse_rx_section (char * name)
338 {
339   asection * sec;
340   int   type;
341   int   attr = SHF_ALLOC | SHF_EXECINSTR;
342   int   align = 2;
343   char  end_char;
344
345   do
346     {
347       char * p;
348
349       SKIP_WHITESPACE ();
350       for (p = input_line_pointer; *p && strchr ("\n\t, =", *p) == NULL; p++)
351         ;
352       end_char = *p;
353       *p = 0;
354
355       if (strcasecmp (input_line_pointer, "ALIGN") == 0)
356         {
357           *p = end_char;
358
359           if (end_char == ' ')
360             while (ISSPACE (*p))
361               p++;
362
363           if (*p == '=')
364             {
365               ++ p;
366               while (ISSPACE (*p))
367                 p++;
368               switch (*p)
369                 {
370                 case '2': align = 2; break;
371                 case '4': align = 4; break;
372                 case '8': align = 8; break;
373                 default:
374                   as_bad (_("unrecognised alignment value in .SECTION directive: %s"), p);
375                   ignore_rest_of_line ();
376                   return;
377                 }
378               ++ p;
379             }
380
381           end_char = *p;
382         }
383       else if (strcasecmp (input_line_pointer, "CODE") == 0)
384         attr = SHF_ALLOC | SHF_EXECINSTR;
385       else if (strcasecmp (input_line_pointer, "DATA") == 0)
386         attr = SHF_ALLOC | SHF_WRITE;
387       else if (strcasecmp (input_line_pointer, "ROMDATA") == 0)
388         attr = SHF_ALLOC;
389       else
390         {
391           as_bad (_("unknown parameter following .SECTION directive: %s"),
392                   input_line_pointer);
393
394           *p = end_char;
395           input_line_pointer = p + 1;
396           ignore_rest_of_line ();
397           return;
398         }
399
400       *p = end_char;
401       input_line_pointer = p + 1;
402     }
403   while (end_char != '\n' && end_char != 0);
404
405   if ((sec = bfd_get_section_by_name (stdoutput, name)) == NULL)
406     {
407       if (strcmp (name, "B") && strcmp (name, "B_1") && strcmp (name, "B_2"))
408         type = SHT_NULL;
409       else
410         type = SHT_NOBITS;
411
412       obj_elf_change_section (name, type, attr, 0, NULL, FALSE, FALSE);
413     }
414   else /* Try not to redefine a section, especially B_1.  */
415     {
416       int flags = sec->flags;
417
418       type = elf_section_type (sec);
419
420       attr = ((flags & SEC_READONLY) ? 0 : SHF_WRITE)
421         | ((flags & SEC_ALLOC) ? SHF_ALLOC : 0)
422         | ((flags & SEC_CODE) ? SHF_EXECINSTR : 0)
423         | ((flags & SEC_MERGE) ? SHF_MERGE : 0)
424         | ((flags & SEC_STRINGS) ? SHF_STRINGS : 0)
425         | ((flags & SEC_THREAD_LOCAL) ? SHF_TLS : 0);
426
427       obj_elf_change_section (name, type, attr, 0, NULL, FALSE, FALSE);
428     }
429
430   bfd_set_section_alignment (stdoutput, now_seg, align);
431 }
432
433 static void
434 rx_section (int ignore)
435 {
436   char * p;
437
438   /* The as100 assembler supports a different syntax for the .section
439      pseudo-op.  So check for it and handle it here if necessary. */
440   SKIP_WHITESPACE ();
441
442   /* Peek past the section name to see if arguments follow.  */
443   for (p = input_line_pointer; *p; p++)
444     if (*p == ',' || *p == '\n')
445       break;
446
447   if (*p == ',')
448     {
449       int len = p - input_line_pointer;
450
451       while (ISSPACE (*++p))
452         ;
453
454       if (*p != '"' && *p != '#')
455         {
456           char * name = (char *) xmalloc (len + 1);
457
458           strncpy (name, input_line_pointer, len);
459           name[len] = 0;
460
461           input_line_pointer = p;
462           parse_rx_section (name);
463           return;
464         }
465     }
466
467   obj_elf_section (ignore);
468 }
469
470 static void
471 rx_list (int ignore ATTRIBUTE_UNUSED)
472 {
473   SKIP_WHITESPACE ();
474
475   if (strncasecmp (input_line_pointer, "OFF", 3))
476     listing_list (0);
477   else if (strncasecmp (input_line_pointer, "ON", 2))
478     listing_list (1);
479   else
480     as_warn (_("expecting either ON or OFF after .list"));
481 }
482
483 /* Like the .rept pseudo op, but supports the
484    use of ..MACREP inside the repeated region.  */
485
486 static void
487 rx_rept (int ignore ATTRIBUTE_UNUSED)
488 {
489   int count = get_absolute_expression ();
490
491   do_repeat_with_expander (count, "MREPEAT", "ENDR", "..MACREP");
492 }
493
494 /* Like cons() accept that strings are allowed.  */
495
496 static void
497 rx_cons (int size)
498 {
499   SKIP_WHITESPACE ();
500
501   if (* input_line_pointer == '"')
502     stringer (8+0);
503   else
504     cons (size);
505 }
506
507 static void
508 rx_nop (int ignore ATTRIBUTE_UNUSED)
509 {
510   ignore_rest_of_line ();
511 }
512
513 static void
514 rx_unimp (int idx)
515 {
516   as_warn (_("The \".%s\" pseudo-op is not implemented\n"),
517            md_pseudo_table[idx].poc_name);
518   ignore_rest_of_line ();
519 }
520
521 /* The target specific pseudo-ops which we support.  */
522 const pseudo_typeS md_pseudo_table[] =
523 {
524   /* These are unimplemented.  They're listed first so that we can use
525      the poc_value as the index into this array, to get the name of
526      the pseudo.  So, keep these (1) first, and (2) in order, with (3)
527      the poc_value's in sequence.  */
528   { "btglb",    rx_unimp,       0 },
529   { "call",     rx_unimp,       1 },
530   { "einsf",    rx_unimp,       2 },
531   { "fb",       rx_unimp,       3 },
532   { "fbsym",    rx_unimp,       4 },
533   { "id",       rx_unimp,       5 },
534   { "initsct",  rx_unimp,       6 },
535   { "insf",     rx_unimp,       7 },
536   { "instr",    rx_unimp,       8 },
537   { "lbba",     rx_unimp,       9 },
538   { "len",      rx_unimp,       10 },
539   { "optj",     rx_unimp,       11 },
540   { "rvector",  rx_unimp,       12 },
541   { "sb",       rx_unimp,       13 },
542   { "sbbit",    rx_unimp,       14 },
543   { "sbsym",    rx_unimp,       15 },
544   { "sbsym16",  rx_unimp,       16 },
545
546   /* These are the do-nothing pseudos.  */
547   { "stk",      rx_nop,         0 },
548   /* The manual documents ".stk" but the compiler emits ".stack".  */
549   { "stack",    rx_nop,         0 },
550
551   /* Theae are Renesas as100 assembler pseudo-ops that we do support.  */
552   { "addr",     rx_cons,        3 },
553   { "align",    s_align_bytes,  2 },
554   { "byte",     rx_cons,        1 },
555   { "fixed",    float_cons,    'f' },
556   { "form",     listing_psize,  0 },
557   { "glb",      s_globl,        0 },
558   { "include",  rx_include,     0 },
559   { "list",     rx_list,        0 },
560   { "lword",    rx_cons,        4 },
561   { "mrepeat",  rx_rept,        0 },
562   { "section",  rx_section,     0 },
563
564   /* FIXME: The following pseudo-ops place their values (and associated
565      label if present) in the data section, regardless of whatever
566      section we are currently in.  At the moment this code does not
567      implement that part of the semantics.  */
568   { "blka",     s_space,        3 },
569   { "blkb",     s_space,        1 },
570   { "blkd",     s_space,        8 },
571   { "blkf",     s_space,        4 },
572   { "blkl",     s_space,        4 },
573   { "blkw",     s_space,        2 },
574
575   /* Our "standard" pseudos. */
576   { "double",   rx_float_cons,  0 },
577   { "bss",      s_bss,          0 },
578   { "3byte",    cons,           3 },
579   { "int",      cons,           4 },
580   { "word",     cons,           4 },
581
582   /* End of list marker.  */
583   { NULL,       NULL,           0 }
584 };
585
586 static asymbol * gp_symbol;
587
588 void
589 md_begin (void)
590 {
591   if (rx_use_small_data_limit)
592     /* Make the __gp symbol now rather
593        than after the symbol table is frozen.  We only do this
594        when supporting small data limits because otherwise we
595        pollute the symbol table.  */
596     gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
597 }
598
599 char * rx_lex_start;
600 char * rx_lex_end;
601
602 typedef struct rx_bytesT
603 {
604   char base[4];
605   int n_base;
606   char ops[8];
607   int n_ops;
608   struct
609   {
610     expressionS  exp;
611     char         offset;
612     char         nbits;
613     char         type; /* RXREL_*.  */
614     int          reloc;
615     fixS *       fixP;
616   } fixups[2];
617   int n_fixups;
618   struct
619   {
620     char type;
621     char field_pos;
622     char val_ofs;
623   } relax[2];
624   int n_relax;
625   int link_relax;
626   fixS *link_relax_fixP;
627   char times_grown;
628   char times_shrank;
629 } rx_bytesT;
630
631 static rx_bytesT rx_bytes;
632
633 void
634 rx_relax (int type, int pos)
635 {
636   rx_bytes.relax[rx_bytes.n_relax].type = type;
637   rx_bytes.relax[rx_bytes.n_relax].field_pos = pos;
638   rx_bytes.relax[rx_bytes.n_relax].val_ofs = rx_bytes.n_base + rx_bytes.n_ops;
639   rx_bytes.n_relax ++;
640 }
641
642 void
643 rx_linkrelax_dsp (int pos)
644 {
645   switch (pos)
646     {
647     case 4:
648       rx_bytes.link_relax |= RX_RELAXA_DSP4;
649       break;
650     case 6:
651       rx_bytes.link_relax |= RX_RELAXA_DSP6;
652       break;
653     case 14:
654       rx_bytes.link_relax |= RX_RELAXA_DSP14;
655       break;
656     }
657 }
658
659 void
660 rx_linkrelax_imm (int pos)
661 {
662   switch (pos)
663     {
664     case 6:
665       rx_bytes.link_relax |= RX_RELAXA_IMM6;
666       break;
667     case 12:
668       rx_bytes.link_relax |= RX_RELAXA_IMM12;
669       break;
670     }
671 }
672
673 void
674 rx_linkrelax_branch (void)
675 {
676   rx_bytes.link_relax |= RX_RELAXA_BRA;
677 }
678
679 static void
680 rx_fixup (expressionS exp, int offsetbits, int nbits, int type)
681 {
682   rx_bytes.fixups[rx_bytes.n_fixups].exp = exp;
683   rx_bytes.fixups[rx_bytes.n_fixups].offset = offsetbits;
684   rx_bytes.fixups[rx_bytes.n_fixups].nbits = nbits;
685   rx_bytes.fixups[rx_bytes.n_fixups].type = type;
686   rx_bytes.fixups[rx_bytes.n_fixups].reloc = exp.X_md;
687   rx_bytes.n_fixups ++;
688 }
689
690 #define rx_field_fixup(exp, offset, nbits, type)        \
691   rx_fixup (exp, offset, nbits, type)
692
693 #define rx_op_fixup(exp, offset, nbits, type)           \
694   rx_fixup (exp, offset + 8 * rx_bytes.n_base, nbits, type)
695
696 void
697 rx_base1 (int b1)
698 {
699   rx_bytes.base[0] = b1;
700   rx_bytes.n_base = 1;
701 }
702
703 void
704 rx_base2 (int b1, int b2)
705 {
706   rx_bytes.base[0] = b1;
707   rx_bytes.base[1] = b2;
708   rx_bytes.n_base = 2;
709 }
710
711 void
712 rx_base3 (int b1, int b2, int b3)
713 {
714   rx_bytes.base[0] = b1;
715   rx_bytes.base[1] = b2;
716   rx_bytes.base[2] = b3;
717   rx_bytes.n_base = 3;
718 }
719
720 void
721 rx_base4 (int b1, int b2, int b3, int b4)
722 {
723   rx_bytes.base[0] = b1;
724   rx_bytes.base[1] = b2;
725   rx_bytes.base[2] = b3;
726   rx_bytes.base[3] = b4;
727   rx_bytes.n_base = 4;
728 }
729
730 /* This gets complicated when the field spans bytes, because fields
731    are numbered from the MSB of the first byte as zero, and bits are
732    stored LSB towards the LSB of the byte.  Thus, a simple four-bit
733    insertion of 12 at position 4 of 0x00 yields: 0x0b.  A three-bit
734    insertion of b'MXL at position 7 is like this:
735
736      - - - -  - - - -   - - - -  - - - -
737                     M   X L               */
738
739 void
740 rx_field (int val, int pos, int sz)
741 {
742   int valm;
743   int bytep, bitp;
744
745   if (sz > 0)
746     {
747       if (val < 0 || val >= (1 << sz))
748         as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, sz);
749     }
750   else
751     {
752       sz = - sz;
753       if (val < -(1 << (sz - 1)) || val >= (1 << (sz - 1)))
754         as_bad (_("Value %d doesn't fit in signed %d-bit field"), val, sz);
755     }
756
757   /* This code points at 'M' in the above example.  */
758   bytep = pos / 8;
759   bitp = pos % 8;
760
761   while (bitp + sz > 8)
762     {
763       int ssz = 8 - bitp;
764       int svalm;
765
766       svalm = val >> (sz - ssz);
767       svalm = svalm & ((1 << ssz) - 1);
768       svalm = svalm << (8 - bitp - ssz);
769       gas_assert (bytep < rx_bytes.n_base);
770       rx_bytes.base[bytep] |= svalm;
771
772       bitp = 0;
773       sz -= ssz;
774       bytep ++;
775     }
776   valm = val & ((1 << sz) - 1);
777   valm = valm << (8 - bitp - sz);
778   gas_assert (bytep < rx_bytes.n_base);
779   rx_bytes.base[bytep] |= valm;
780 }
781
782 /* Special case of the above, for 3-bit displacements of 2..9.  */
783
784 void
785 rx_disp3 (expressionS exp, int pos)
786 {
787   rx_field_fixup (exp, pos, 3, RXREL_PCREL);
788 }
789
790 /* Special case of the above, for split 5-bit displacements.  Assumes
791    the displacement has been checked with rx_disp5op.  */
792 /* ---- -432 1--- 0--- */
793
794 void
795 rx_field5s (expressionS exp)
796 {
797   int val;
798
799   val = exp.X_add_number;
800   rx_bytes.base[0] |= val >> 2;
801   rx_bytes.base[1] |= (val << 6) & 0x80;
802   rx_bytes.base[1] |= (val << 3) & 0x08;
803 }
804
805 /* ---- ---- 4--- 3210 */
806
807 void
808 rx_field5s2 (expressionS exp)
809 {
810   int val;
811
812   val = exp.X_add_number;
813   rx_bytes.base[1] |= (val << 3) & 0x80;
814   rx_bytes.base[1] |= (val     ) & 0x0f;
815 }
816
817 #define OP(x) rx_bytes.ops[rx_bytes.n_ops++] = (x)
818
819 #define F_PRECISION 2
820
821 void
822 rx_op (expressionS exp, int nbytes, int type)
823 {
824   int v = 0;
825
826   if ((exp.X_op == O_constant || exp.X_op == O_big)
827       && type != RXREL_PCREL)
828     {
829       if (exp.X_op == O_big && exp.X_add_number <= 0)
830         {
831           LITTLENUM_TYPE w[2];
832           char * ip = rx_bytes.ops + rx_bytes.n_ops;
833
834           gen_to_words (w, F_PRECISION, 8);
835 #if RX_OPCODE_BIG_ENDIAN
836           ip[0] = w[0] >> 8;
837           ip[1] = w[0];
838           ip[2] = w[1] >> 8;
839           ip[3] = w[1];
840 #else
841           ip[3] = w[0] >> 8;
842           ip[2] = w[0];
843           ip[1] = w[1] >> 8;
844           ip[0] = w[1];
845 #endif
846           rx_bytes.n_ops += 4;
847         }
848       else
849         {
850           v = exp.X_add_number;
851           while (nbytes)
852             {
853 #if RX_OPCODE_BIG_ENDIAN
854               OP ((v >> (8 * (nbytes - 1))) & 0xff);
855 #else
856               OP (v & 0xff);
857               v >>= 8;
858 #endif
859               nbytes --;
860             }
861         }
862     }
863   else
864     {
865       rx_op_fixup (exp, rx_bytes.n_ops * 8, nbytes * 8, type);
866       memset (rx_bytes.ops + rx_bytes.n_ops, 0, nbytes);
867       rx_bytes.n_ops += nbytes;
868     }
869 }
870
871 int
872 rx_wrap (void)
873 {
874   return 0;
875 }
876
877 #define APPEND(B, N_B)                                 \
878   if (rx_bytes.N_B)                                    \
879     {                                                  \
880       memcpy (bytes + idx, rx_bytes.B, rx_bytes.N_B);  \
881       idx += rx_bytes.N_B;                             \
882     }
883
884 void
885 rx_frag_init (fragS * fragP)
886 {
887   if (rx_bytes.n_relax || rx_bytes.link_relax)
888     {
889       fragP->tc_frag_data = malloc (sizeof (rx_bytesT));
890       memcpy (fragP->tc_frag_data, & rx_bytes, sizeof (rx_bytesT));
891     }
892   else
893     fragP->tc_frag_data = 0;
894 }
895
896 /* Handle the as100's version of the .equ pseudo-op.  It has the syntax:
897    <symbol_name> .equ <expression>   */
898
899 static void
900 rx_equ (char * name, char * expression)
901 {
902   char   saved_name_end_char;
903   char * name_end;
904   char * saved_ilp;
905
906   while (ISSPACE (* name))
907     name ++;
908
909   for (name_end = name + 1; *name_end; name_end ++)
910     if (! ISALNUM (* name_end))
911       break;
912
913   saved_name_end_char = * name_end;
914   * name_end = 0;
915
916   saved_ilp = input_line_pointer;
917   input_line_pointer = expression;
918
919   equals (name, 1);
920
921   input_line_pointer = saved_ilp;
922   * name_end = saved_name_end_char;
923 }
924
925 /* Look for Renesas as100 pseudo-ops that occur after a symbol name
926    rather than at the start of a line.  (eg .EQU or .DEFINE).  If one
927    is found, process it and return TRUE otherwise return FALSE.  */
928
929 static bfd_boolean
930 scan_for_infix_rx_pseudo_ops (char * str)
931 {
932   char * p;
933   char * pseudo_op;
934   char * dot = strchr (str, '.');
935
936   if (dot == NULL || dot == str)
937     return FALSE;
938
939   /* A real pseudo-op must be preceeded by whitespace.  */
940   if (dot[-1] != ' ' && dot[-1] != '\t')
941     return FALSE;
942
943   pseudo_op = dot + 1;
944
945   if (!ISALNUM (* pseudo_op))
946     return FALSE;
947
948   for (p = pseudo_op + 1; ISALNUM (* p); p++)
949     ;
950
951   if (strncasecmp ("EQU", pseudo_op, p - pseudo_op) == 0)
952     rx_equ (str, p);
953   else if (strncasecmp ("DEFINE", pseudo_op, p - pseudo_op) == 0)
954     as_warn (_("The .DEFINE pseudo-op is not implemented"));
955   else if (strncasecmp ("MACRO", pseudo_op, p - pseudo_op) == 0)
956     as_warn (_("The .MACRO pseudo-op is not implemented"));
957   else if (strncasecmp ("BTEQU", pseudo_op, p - pseudo_op) == 0)
958     as_warn (_("The .BTEQU pseudo-op is not implemented."));
959   else
960     return FALSE;
961
962   return TRUE;
963 }
964
965 void
966 md_assemble (char * str)
967 {
968   char * bytes;
969   int idx = 0;
970   int i, rel;
971   fragS * frag_then = frag_now;
972   expressionS  *exp;
973
974   memset (& rx_bytes, 0, sizeof (rx_bytes));
975
976   rx_lex_init (str, str + strlen (str));
977   if (scan_for_infix_rx_pseudo_ops (str))
978     return;
979   rx_parse ();
980
981   /* This simplifies the relaxation code.  */
982   if (rx_bytes.n_relax || rx_bytes.link_relax)
983     {
984       /* We do it this way because we want the frag to have the
985          rx_bytes in it, which we initialize above.  */
986       bytes = frag_more (12);
987       frag_then = frag_now;
988       frag_variant (rs_machine_dependent,
989                     0 /* max_chars */,
990                     0 /* var */,
991                     0 /* subtype */,
992                     0 /* symbol */,
993                     0 /* offset */,
994                     0 /* opcode */);
995       frag_then->fr_opcode = bytes;
996       frag_then->fr_fix += rx_bytes.n_base + rx_bytes.n_ops;
997       frag_then->fr_subtype = rx_bytes.n_base + rx_bytes.n_ops;
998     }
999   else
1000     {
1001       bytes = frag_more (rx_bytes.n_base + rx_bytes.n_ops);
1002       frag_then = frag_now;
1003     }
1004
1005   APPEND (base, n_base);
1006   APPEND (ops, n_ops);
1007
1008   if (rx_bytes.link_relax && rx_bytes.n_fixups)
1009     {
1010       fixS * f;
1011
1012       f = fix_new (frag_then,
1013                    (char *) bytes - frag_then->fr_literal,
1014                    0,
1015                    abs_section_sym,
1016                    rx_bytes.link_relax | rx_bytes.n_fixups,
1017                    0,
1018                    BFD_RELOC_RX_RELAX);
1019       frag_then->tc_frag_data->link_relax_fixP = f;
1020     }
1021
1022   for (i = 0; i < rx_bytes.n_fixups; i ++)
1023     {
1024       /* index: [nbytes][type] */
1025       static int reloc_map[5][4] =
1026         {
1027           { 0,                  0,                0,                  BFD_RELOC_RX_DIR3U_PCREL },
1028           { BFD_RELOC_8,        BFD_RELOC_RX_8U,  BFD_RELOC_RX_NEG8,  BFD_RELOC_8_PCREL },
1029           { BFD_RELOC_RX_16_OP, BFD_RELOC_RX_16U, BFD_RELOC_RX_NEG16, BFD_RELOC_16_PCREL },
1030           { BFD_RELOC_RX_24_OP, BFD_RELOC_RX_24U, BFD_RELOC_RX_NEG24, BFD_RELOC_24_PCREL },
1031           { BFD_RELOC_RX_32_OP, BFD_RELOC_32,     BFD_RELOC_RX_NEG32, BFD_RELOC_32_PCREL },
1032         };
1033       fixS * f;
1034
1035       idx = rx_bytes.fixups[i].offset / 8;
1036       rel = reloc_map [rx_bytes.fixups[i].nbits / 8][(int) rx_bytes.fixups[i].type];
1037
1038       if (rx_bytes.fixups[i].reloc)
1039         rel = rx_bytes.fixups[i].reloc;
1040
1041       if (frag_then->tc_frag_data)
1042         exp = & frag_then->tc_frag_data->fixups[i].exp;
1043       else
1044         exp = & rx_bytes.fixups[i].exp;
1045
1046       f = fix_new_exp (frag_then,
1047                        (char *) bytes + idx - frag_then->fr_literal,
1048                        rx_bytes.fixups[i].nbits / 8,
1049                        exp,
1050                        rx_bytes.fixups[i].type == RXREL_PCREL ? 1 : 0,
1051                        rel);
1052       if (frag_then->tc_frag_data)
1053         frag_then->tc_frag_data->fixups[i].fixP = f;
1054     }
1055
1056   dwarf2_emit_insn (idx);
1057 }
1058
1059 void
1060 rx_md_end (void)
1061 {
1062 }
1063
1064 /* Write a value out to the object file, using the appropriate endianness.  */
1065
1066 void
1067 md_number_to_chars (char * buf, valueT val, int n)
1068 {
1069   if (target_big_endian)
1070     number_to_chars_bigendian (buf, val, n);
1071   else
1072     number_to_chars_littleendian (buf, val, n);
1073 }
1074
1075 static struct
1076 {
1077   char * fname;
1078   int    reloc;
1079 }
1080 reloc_functions[] =
1081 {
1082   { "gp", BFD_RELOC_GPREL16 },
1083   { 0, 0 }
1084 };
1085
1086 void
1087 md_operand (expressionS * exp ATTRIBUTE_UNUSED)
1088 {
1089   int reloc = 0;
1090   int i;
1091
1092   for (i = 0; reloc_functions[i].fname; i++)
1093     {
1094       int flen = strlen (reloc_functions[i].fname);
1095
1096       if (input_line_pointer[0] == '%'
1097           && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
1098           && input_line_pointer[flen + 1] == '(')
1099         {
1100           reloc = reloc_functions[i].reloc;
1101           input_line_pointer += flen + 2;
1102           break;
1103         }
1104     }
1105   if (reloc == 0)
1106     return;
1107
1108   expression (exp);
1109   if (* input_line_pointer == ')')
1110     input_line_pointer ++;
1111
1112   exp->X_md = reloc;
1113 }
1114
1115 valueT
1116 md_section_align (segT segment, valueT size)
1117 {
1118   int align = bfd_get_section_alignment (stdoutput, segment);
1119   return ((size + (1 << align) - 1) & (-1 << align));
1120 }
1121
1122                                 /* NOP - 1 cycle */
1123 static unsigned char nop_1[] = { 0x03};
1124                                 /* MOV.L R0,R0 - 1 cycle */
1125 static unsigned char nop_2[] = { 0xef, 0x00};
1126                                 /* MAX R0,R0 - 1 cycle */
1127 static unsigned char nop_3[] = { 0xfc, 0x13, 0x00 };
1128                                 /* MUL #1,R0 - 1 cycle */
1129 static unsigned char nop_4[] = { 0x76, 0x10, 0x01, 0x00 };
1130                                 /* MUL #1,R0 - 1 cycle */
1131 static unsigned char nop_5[] = { 0x77, 0x10, 0x01, 0x00, 0x00 };
1132                                 /* MUL #1,R0 - 1 cycle */
1133 static unsigned char nop_6[] = { 0x74, 0x10, 0x01, 0x00, 0x00, 0x00 };
1134                                 /* BRA.S .+7 - 1 cycle */
1135 static unsigned char nop_7[] = { 0x0F, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
1136
1137 static unsigned char *nops[] = { NULL, nop_1, nop_2, nop_3, nop_4, nop_5, nop_6, nop_7 };
1138 #define BIGGEST_NOP 7
1139
1140 /* When relaxing, we need to output a reloc for any .align directive
1141    so that we can retain this alignment as we adjust opcode sizes.  */
1142 void
1143 rx_handle_align (fragS * frag)
1144 {
1145   if ((frag->fr_type == rs_align
1146        || frag->fr_type == rs_align_code)
1147       && subseg_text_p (now_seg))
1148     {
1149       int count = (frag->fr_next->fr_address
1150                    - frag->fr_address   
1151                    - frag->fr_fix);
1152       unsigned char *base = (unsigned char *)frag->fr_literal + frag->fr_fix;
1153
1154       if (count > BIGGEST_NOP)
1155         {
1156           base[0] = 0x2e;
1157           base[1] = count;
1158           frag->fr_var = 2;
1159         }
1160       else if (count > 0)
1161         {
1162           memcpy (base, nops[count], count);
1163           frag->fr_var = count;
1164         }
1165     }
1166
1167   if (linkrelax
1168       && (frag->fr_type == rs_align
1169           || frag->fr_type == rs_align_code)
1170       && frag->fr_address + frag->fr_fix > 0
1171       && frag->fr_offset > 0
1172       && now_seg != bss_section)
1173     {
1174       fix_new (frag, frag->fr_fix, 0,
1175                &abs_symbol, RX_RELAXA_ALIGN + frag->fr_offset,
1176                0, BFD_RELOC_RX_RELAX);
1177       /* For the purposes of relaxation, this relocation is attached
1178          to the byte *after* the alignment - i.e. the byte that must
1179          remain aligned.  */
1180       fix_new (frag->fr_next, 0, 0,
1181                &abs_symbol, RX_RELAXA_ELIGN + frag->fr_offset,
1182                0, BFD_RELOC_RX_RELAX);
1183     }
1184 }
1185
1186 char *
1187 md_atof (int type, char * litP, int * sizeP)
1188 {
1189   return ieee_md_atof (type, litP, sizeP, target_big_endian);
1190 }
1191
1192 symbolS *
1193 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1194 {
1195   return NULL;
1196 }
1197
1198 /*----------------------------------------------------------------------*/
1199 /* To recap: we estimate everything based on md_estimate_size, then
1200    adjust based on rx_relax_frag.  When it all settles, we call
1201    md_convert frag to update the bytes.  The relaxation types and
1202    relocations are in fragP->tc_frag_data, which is a copy of that
1203    rx_bytes.
1204
1205    Our scheme is as follows: fr_fix has the size of the smallest
1206    opcode (like BRA.S).  We store the number of total bytes we need in
1207    fr_subtype.  When we're done relaxing, we use fr_subtype and the
1208    existing opcode bytes to figure out what actual opcode we need to
1209    put in there.  If the fixup isn't resolvable now, we use the
1210    maximal size.  */
1211
1212 #define TRACE_RELAX 0
1213 #define tprintf if (TRACE_RELAX) printf
1214
1215 typedef enum
1216 {
1217   OT_other,
1218   OT_bra,
1219   OT_beq,
1220   OT_bne,
1221   OT_bsr,
1222   OT_bcc
1223 } op_type_T;
1224
1225 /* We're looking for these types of relaxations:
1226
1227    BRA.S        00001dsp
1228    BRA.B        00101110 dspppppp
1229    BRA.W        00111000 dspppppp pppppppp
1230    BRA.A        00000100 dspppppp pppppppp pppppppp
1231
1232    BEQ.S        00010dsp
1233    BEQ.B        00100000 dspppppp
1234    BEQ.W        00111010 dspppppp pppppppp
1235
1236    BNE.S        00011dsp
1237    BNE.B        00100001 dspppppp
1238    BNE.W        00111011 dspppppp pppppppp
1239
1240    BSR.W        00111001 dspppppp pppppppp
1241    BSR.A        00000101 dspppppp pppppppp pppppppp
1242
1243    Bcc.B        0010cond dspppppp
1244
1245    Additionally, we can synthesize longer conditional branches using
1246    pairs of opcodes, one with an inverted conditional (flip LSB):
1247
1248    Bcc.W        0010ncnd 00000110 00111000 dspppppp pppppppp
1249    Bcc.A        0010ncnd 00000111 00000100 dspppppp pppppppp pppppppp
1250    BEQ.A        00011100 00000100 dspppppp pppppppp pppppppp
1251    BNE.A        00010100 00000100 dspppppp pppppppp pppppppp  */
1252
1253 /* Given the opcode bytes at OP, figure out which opcode it is and
1254    return the type of opcode.  We use this to re-encode the opcode as
1255    a different size later.  */
1256
1257 static op_type_T
1258 rx_opcode_type (char * op)
1259 {
1260   unsigned char b = (unsigned char) op[0];
1261
1262   switch (b & 0xf8)
1263     {
1264     case 0x08: return OT_bra;
1265     case 0x10: return OT_beq;
1266     case 0x18: return OT_bne;
1267     }
1268
1269   switch (b)
1270     {
1271     case 0x2e: return OT_bra;
1272     case 0x38: return OT_bra;
1273     case 0x04: return OT_bra;
1274
1275     case 0x20: return OT_beq;
1276     case 0x3a: return OT_beq;
1277
1278     case 0x21: return OT_bne;
1279     case 0x3b: return OT_bne;
1280
1281     case 0x39: return OT_bsr;
1282     case 0x05: return OT_bsr;
1283     }
1284
1285   if ((b & 0xf0) == 0x20)
1286     return OT_bcc;
1287
1288   return OT_other;
1289 }
1290
1291 /* Returns zero if *addrP has the target address.  Else returns nonzero
1292    if we cannot compute the target address yet.  */
1293
1294 static int
1295 rx_frag_fix_value (fragS *    fragP,
1296                    segT       segment,
1297                    int        which,
1298                    addressT * addrP,
1299                    int        need_diff,
1300                    addressT * sym_addr)
1301 {
1302   addressT addr = 0;
1303   rx_bytesT * b = fragP->tc_frag_data;
1304   expressionS * exp = & b->fixups[which].exp;
1305
1306   if (need_diff && exp->X_op != O_subtract)
1307     return 1;
1308
1309   if (exp->X_add_symbol)
1310     {
1311       if (S_FORCE_RELOC (exp->X_add_symbol, 1))
1312         return 1;
1313       if (S_GET_SEGMENT (exp->X_add_symbol) != segment)
1314         return 1;
1315       addr += S_GET_VALUE (exp->X_add_symbol);
1316     }
1317
1318   if (exp->X_op_symbol)
1319     {
1320       if (exp->X_op != O_subtract)
1321         return 1;
1322       if (S_FORCE_RELOC (exp->X_op_symbol, 1))
1323         return 1;
1324       if (S_GET_SEGMENT (exp->X_op_symbol) != segment)
1325         return 1;
1326       addr -= S_GET_VALUE (exp->X_op_symbol);
1327     }
1328   if (sym_addr)
1329     * sym_addr = addr;
1330   addr += exp->X_add_number;
1331   * addrP = addr;
1332   return 0;
1333 }
1334
1335 /* Estimate how big the opcode is after this relax pass.  The return
1336    value is the difference between fr_fix and the actual size.  We
1337    compute the total size in rx_relax_frag and store it in fr_subtype,
1338    sowe only need to subtract fx_fix and return it.  */
1339
1340 int
1341 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
1342 {
1343   int opfixsize;
1344   int delta;
1345
1346   tprintf ("\033[32m  est frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n",
1347            (unsigned long) (fragP->fr_address
1348                             + (fragP->fr_opcode - fragP->fr_literal)),
1349            (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
1350            fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype);
1351
1352   /* This is the size of the opcode that's accounted for in fr_fix.  */
1353   opfixsize = fragP->fr_fix - (fragP->fr_opcode - fragP->fr_literal);
1354   /* This is the size of the opcode that isn't.  */
1355   delta = (fragP->fr_subtype - opfixsize);
1356
1357   tprintf (" -> opfixsize %d delta %d\n", opfixsize, delta);
1358   return delta;
1359 }
1360
1361 /* Given the new addresses for this relax pass, figure out how big
1362    each opcode must be.  We store the total number of bytes needed in
1363    fr_subtype.  The return value is the difference between the size
1364    after the last pass and the size after this pass, so we use the old
1365    fr_subtype to calculate the difference.  */
1366
1367 int
1368 rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
1369 {
1370   addressT addr0, sym_addr;
1371   addressT mypc;
1372   int disp;
1373   int oldsize = fragP->fr_subtype;
1374   int newsize = oldsize;
1375   op_type_T optype;
1376    /* Index of relaxation we care about.  */
1377   int ri;
1378
1379   tprintf ("\033[36mrelax frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d str %ld\033[0m\n",
1380            (unsigned long) (fragP->fr_address
1381                             + (fragP->fr_opcode - fragP->fr_literal)),
1382            (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
1383            fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype, stretch);
1384
1385   optype = rx_opcode_type (fragP->fr_opcode);
1386
1387   /* In the one case where we have both a disp and imm relaxation, we want
1388      the imm relaxation here.  */
1389   ri = 0;
1390   if (fragP->tc_frag_data->n_relax > 1
1391       && fragP->tc_frag_data->relax[0].type == RX_RELAX_DISP)
1392     ri = 1;
1393
1394   /* Try to get the target address.  */
1395   if (rx_frag_fix_value (fragP, segment, ri, & addr0,
1396                          fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH,
1397                          & sym_addr))
1398     {
1399       /* If we don't, we must use the maximum size for the linker.
1400          Note that we don't use synthetically expanded conditionals
1401          for this.  */
1402       switch (fragP->tc_frag_data->relax[ri].type)
1403         {
1404         case RX_RELAX_BRANCH:
1405           switch (optype)
1406             {
1407             case OT_bra:
1408             case OT_bsr:
1409               newsize = 4;
1410               break;
1411             case OT_beq:
1412             case OT_bne:
1413               newsize = 3;
1414               break;
1415             case OT_bcc:
1416               newsize = 2;
1417               break;
1418             case OT_other:
1419               newsize = oldsize;
1420               break;
1421             }
1422           break;
1423
1424         case RX_RELAX_IMM:
1425           newsize = fragP->tc_frag_data->relax[ri].val_ofs + 4;
1426           break;
1427         }
1428       fragP->fr_subtype = newsize;
1429       tprintf (" -> new %d old %d delta %d (external)\n", newsize, oldsize, newsize-oldsize);
1430       return newsize - oldsize;
1431     }
1432
1433   mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1434   if (sym_addr > mypc)
1435     addr0 += stretch;
1436
1437   switch (fragP->tc_frag_data->relax[ri].type)
1438     {
1439     case  RX_RELAX_BRANCH:
1440       tprintf ("branch, addr %08lx pc %08lx disp %ld\n",
1441                (unsigned long) addr0, (unsigned long) mypc,
1442                (long) (addr0 - mypc));
1443       disp = (int) addr0 - (int) mypc;
1444
1445       switch (optype)
1446         {
1447         case OT_bcc:
1448           if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1449             /* bcc.b */
1450             newsize = 2;
1451           else if (disp >= -32768 && (disp - (oldsize-5)) <= 32767)
1452             /* bncc.b/bra.w */
1453             newsize = 5;
1454           else
1455             /* bncc.b/bra.a */
1456             newsize = 6;
1457           break;
1458
1459         case OT_beq:
1460         case OT_bne:
1461           if ((disp - (oldsize-1)) >= 3 && (disp - (oldsize-1)) <= 10 && !linkrelax)
1462             /* beq.s */
1463             newsize = 1;
1464           else if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1465             /* beq.b */
1466             newsize = 2;
1467           else if (disp >= -32768 && (disp - (oldsize-3)) <= 32767)
1468             /* beq.w */
1469             newsize = 3;
1470           else
1471             /* bne.s/bra.a */
1472             newsize = 5;
1473           break;
1474
1475         case OT_bra:
1476         case OT_bsr:
1477           if ((disp - (oldsize-1)) >= 3 && (disp - (oldsize-1)) <= 10 && !linkrelax)
1478             /* bra.s */
1479             newsize = 1;
1480           else if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1481             /* bra.b */
1482             newsize = 2;
1483           else if (disp >= -32768 && (disp - (oldsize-3)) <= 32767)
1484             /* bra.w */
1485             newsize = 3;
1486           else
1487             /* bra.a */
1488             newsize = 4;
1489           break;
1490
1491         case OT_other:
1492           break;
1493         }
1494       tprintf (" - newsize %d\n", newsize);
1495       break;
1496
1497     case RX_RELAX_IMM:
1498       tprintf ("other, addr %08lx pc %08lx LI %d OF %d\n",
1499                (unsigned long) addr0, (unsigned long) mypc,
1500                fragP->tc_frag_data->relax[ri].field_pos,
1501                fragP->tc_frag_data->relax[ri].val_ofs);
1502
1503       newsize = fragP->tc_frag_data->relax[ri].val_ofs;
1504
1505       if ((long) addr0 >= -128 && (long) addr0 <= 127)
1506         newsize += 1;
1507       else if ((long) addr0 >= -32768 && (long) addr0 <= 32767)
1508         newsize += 2;
1509       else if ((long) addr0 >= -8388608 && (long) addr0 <= 8388607)
1510         newsize += 3;
1511       else
1512         newsize += 4;
1513       break;
1514
1515     default:
1516       break;
1517     }
1518
1519   if (fragP->tc_frag_data->relax[ri].type == RX_RELAX_BRANCH)
1520     switch (optype)
1521       {
1522       case OT_bra:
1523       case OT_bcc:
1524       case OT_beq:
1525       case OT_bne:
1526         break;
1527       case OT_bsr:
1528         if (newsize < 3)
1529           newsize = 3;
1530         break;
1531       case OT_other:
1532         break;
1533       }
1534
1535   /* This prevents infinite loops in align-heavy sources.  */
1536   if (newsize < oldsize)
1537     {
1538       if (fragP->tc_frag_data->times_shrank > 10
1539          && fragP->tc_frag_data->times_grown > 10)
1540        newsize = oldsize;
1541       if (fragP->tc_frag_data->times_shrank < 20)
1542        fragP->tc_frag_data->times_shrank ++;
1543     }
1544   else if (newsize > oldsize)
1545     {
1546       if (fragP->tc_frag_data->times_grown < 20)
1547        fragP->tc_frag_data->times_grown ++;
1548     }
1549
1550   fragP->fr_subtype = newsize;
1551   tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
1552   return newsize - oldsize;
1553 }
1554
1555 /* This lets us test for the opcode type and the desired size in a
1556    switch statement.  */
1557 #define OPCODE(type,size) ((type) * 16 + (size))
1558
1559 /* Given the opcode stored in fr_opcode and the number of bytes we
1560    think we need, encode a new opcode.  We stored a pointer to the
1561    fixup for this opcode in the tc_frag_data structure.  If we can do
1562    the fixup here, we change the relocation type to "none" (we test
1563    for that in tc_gen_reloc) else we change it to the right type for
1564    the new (biggest) opcode.  */
1565
1566 void
1567 md_convert_frag (bfd *   abfd ATTRIBUTE_UNUSED,
1568                  segT    segment ATTRIBUTE_UNUSED,
1569                  fragS * fragP ATTRIBUTE_UNUSED)
1570 {
1571   rx_bytesT * rxb = fragP->tc_frag_data;
1572   addressT addr0, mypc;
1573   int disp;
1574   int reloc_type, reloc_adjust;
1575   char * op = fragP->fr_opcode;
1576   int keep_reloc = 0;
1577   int ri;
1578   int fi = (rxb->n_fixups > 1) ? 1 : 0;
1579   fixS * fix = rxb->fixups[fi].fixP;
1580
1581   tprintf ("\033[31mconvrt frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n",
1582            (unsigned long) (fragP->fr_address
1583                             + (fragP->fr_opcode - fragP->fr_literal)),
1584            (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
1585            fragP->fr_literal, fragP->fr_opcode, fragP->fr_type,
1586            fragP->fr_subtype);
1587
1588 #if TRACE_RELAX
1589   {
1590     int i;
1591
1592     printf ("lit %08x opc %08x", (int) fragP->fr_literal, (int) fragP->fr_opcode);
1593     for (i = 0; i < 10; i++)
1594       printf (" %02x", (unsigned char) (fragP->fr_opcode[i]));
1595     printf ("\n");
1596   }
1597 #endif
1598
1599   /* In the one case where we have both a disp and imm relaxation, we want
1600      the imm relaxation here.  */
1601   ri = 0;
1602   if (fragP->tc_frag_data->n_relax > 1
1603       && fragP->tc_frag_data->relax[0].type == RX_RELAX_DISP)
1604     ri = 1;
1605
1606   /* We used a new frag for this opcode, so the opcode address should
1607      be the frag address.  */
1608   mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1609
1610   /* Try to get the target address.  If we fail here, we just use the
1611      largest format.  */
1612   if (rx_frag_fix_value (fragP, segment, 0, & addr0,
1613                          fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH, 0))
1614     {
1615       /* We don't know the target address.  */
1616       keep_reloc = 1;
1617       addr0 = 0;
1618       disp = 0;
1619     }
1620   else
1621     {
1622       /* We know the target address, and it's in addr0.  */
1623       disp = (int) addr0 - (int) mypc;
1624     }
1625
1626   if (linkrelax)
1627     keep_reloc = 1;
1628
1629   reloc_type = BFD_RELOC_NONE;
1630   reloc_adjust = 0;
1631
1632   tprintf ("convert, op is %d, disp %d (%lx-%lx)\n",
1633            rx_opcode_type (fragP->fr_opcode), disp,
1634            (unsigned long) addr0, (unsigned long) mypc);
1635   switch (fragP->tc_frag_data->relax[ri].type)
1636     {
1637     case RX_RELAX_BRANCH:
1638       switch (OPCODE (rx_opcode_type (fragP->fr_opcode), fragP->fr_subtype))
1639         {
1640         case OPCODE (OT_bra, 1): /* BRA.S - no change.  */
1641           op[0] = 0x08 + (disp & 7);
1642           break;
1643         case OPCODE (OT_bra, 2): /* BRA.B - 8 bit.  */
1644           op[0] = 0x2e;
1645           op[1] = disp;
1646           reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1647           reloc_adjust = 1;
1648           break;
1649         case OPCODE (OT_bra, 3): /* BRA.W - 16 bit.  */
1650           op[0] = 0x38;
1651 #if RX_OPCODE_BIG_ENDIAN
1652           op[1] = (disp >> 8) & 0xff;
1653           op[2] = disp;
1654 #else
1655           op[2] = (disp >> 8) & 0xff;
1656           op[1] = disp;
1657 #endif
1658           reloc_adjust = 1;
1659           reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1660           break;
1661         case OPCODE (OT_bra, 4): /* BRA.A - 24 bit.  */
1662           op[0] = 0x04;
1663 #if RX_OPCODE_BIG_ENDIAN
1664           op[1] = (disp >> 16) & 0xff;
1665           op[2] = (disp >> 8) & 0xff;
1666           op[3] = disp;
1667 #else
1668           op[3] = (disp >> 16) & 0xff;
1669           op[2] = (disp >> 8) & 0xff;
1670           op[1] = disp;
1671 #endif
1672           reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1673           reloc_adjust = 1;
1674           break;
1675
1676         case OPCODE (OT_beq, 1): /* BEQ.S - no change.  */
1677           op[0] = 0x10 + (disp & 7);
1678           break;
1679         case OPCODE (OT_beq, 2): /* BEQ.B - 8 bit.  */
1680           op[0] = 0x20;
1681           op[1] = disp;
1682           reloc_adjust = 1;
1683           reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1684           break;
1685         case OPCODE (OT_beq, 3): /* BEQ.W - 16 bit.  */
1686           op[0] = 0x3a;
1687 #if RX_OPCODE_BIG_ENDIAN
1688           op[1] = (disp >> 8) & 0xff;
1689           op[2] = disp;
1690 #else
1691           op[2] = (disp >> 8) & 0xff;
1692           op[1] = disp;
1693 #endif
1694           reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1695           reloc_adjust = 1;
1696           break;
1697         case OPCODE (OT_beq, 5): /* BEQ.A - synthetic.  */
1698           op[0] = 0x1e; /* bne.s .+4.  */
1699           op[1] = 0x04; /* bra.a dsp:24.  */
1700           disp -= 1;
1701 #if RX_OPCODE_BIG_ENDIAN
1702           op[2] = (disp >> 16) & 0xff;
1703           op[3] = (disp >> 8) & 0xff;
1704           op[4] = disp;
1705 #else
1706           op[4] = (disp >> 16) & 0xff;
1707           op[3] = (disp >> 8) & 0xff;
1708           op[2] = disp;
1709 #endif
1710           reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1711           reloc_adjust = 2;
1712           break;
1713
1714         case OPCODE (OT_bne, 1): /* BNE.S - no change.  */
1715           op[0] = 0x18 + (disp & 7);
1716           break;
1717         case OPCODE (OT_bne, 2): /* BNE.B - 8 bit.  */
1718           op[0] = 0x21;
1719           op[1] = disp;
1720           reloc_adjust = 1;
1721           reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1722           break;
1723         case OPCODE (OT_bne, 3): /* BNE.W - 16 bit.  */
1724           op[0] = 0x3b;
1725 #if RX_OPCODE_BIG_ENDIAN
1726           op[1] = (disp >> 8) & 0xff;
1727           op[2] = disp;
1728 #else
1729           op[2] = (disp >> 8) & 0xff;
1730           op[1] = disp;
1731 #endif
1732           reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1733           reloc_adjust = 1;
1734           break;
1735         case OPCODE (OT_bne, 5): /* BNE.A - synthetic.  */
1736           op[0] = 0x15; /* beq.s .+4.  */
1737           op[1] = 0x04; /* bra.a dsp:24.  */
1738           disp -= 1;
1739 #if RX_OPCODE_BIG_ENDIAN
1740           op[2] = (disp >> 16) & 0xff;
1741           op[3] = (disp >> 8) & 0xff;
1742           op[4] = disp;
1743 #else
1744           op[4] = (disp >> 16) & 0xff;
1745           op[3] = (disp >> 8) & 0xff;
1746           op[2] = disp;
1747 #endif
1748           reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1749           reloc_adjust = 2;
1750           break;
1751
1752         case OPCODE (OT_bsr, 3): /* BSR.W - 16 bit.  */
1753           op[0] = 0x39;
1754 #if RX_OPCODE_BIG_ENDIAN
1755           op[1] = (disp >> 8) & 0xff;
1756           op[2] = disp;
1757 #else
1758           op[2] = (disp >> 8) & 0xff;
1759           op[1] = disp;
1760 #endif
1761           reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1762           reloc_adjust = 0;
1763           break;
1764         case OPCODE (OT_bsr, 4): /* BSR.A - 24 bit.  */
1765           op[0] = 0x05;
1766 #if RX_OPCODE_BIG_ENDIAN
1767           op[1] = (disp >> 16) & 0xff;
1768           op[2] = (disp >> 8) & 0xff;
1769           op[3] = disp;
1770 #else
1771           op[3] = (disp >> 16) & 0xff;
1772           op[2] = (disp >> 8) & 0xff;
1773           op[1] = disp;
1774 #endif
1775           reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1776           reloc_adjust = 0;
1777           break;
1778
1779         case OPCODE (OT_bcc, 2): /* Bcond.B - 8 bit.  */
1780           op[1] = disp;
1781           reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1782           break;
1783         case OPCODE (OT_bcc, 5): /* Bcond.W - synthetic.  */
1784           op[0] ^= 1; /* Invert condition.  */
1785           op[1] = 5;  /* Displacement.  */
1786           op[2] = 0x38;
1787           disp -= 2;
1788 #if RX_OPCODE_BIG_ENDIAN
1789           op[3] = (disp >> 8) & 0xff;
1790           op[4] = disp;
1791 #else
1792           op[4] = (disp >> 8) & 0xff;
1793           op[3] = disp;
1794 #endif
1795           reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1796           reloc_adjust = 2;
1797           break;
1798         case OPCODE (OT_bcc, 6): /* Bcond.S - synthetic.  */
1799           op[0] ^= 1; /* Invert condition.  */
1800           op[1] = 6;  /* Displacement.  */
1801           op[2] = 0x04;
1802           disp -= 2;
1803 #if RX_OPCODE_BIG_ENDIAN
1804           op[3] = (disp >> 16) & 0xff;
1805           op[4] = (disp >> 8) & 0xff;
1806           op[5] = disp;
1807 #else
1808           op[5] = (disp >> 16) & 0xff;
1809           op[4] = (disp >> 8) & 0xff;
1810           op[3] = disp;
1811 #endif
1812           reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1813           reloc_adjust = 2;
1814           break;
1815
1816         default:
1817           /* These are opcodes we'll relax in th linker, later.  */
1818           if (rxb->n_fixups)
1819             reloc_type = rxb->fixups[ri].fixP->fx_r_type;
1820           break;
1821         }
1822       break;
1823
1824     case RX_RELAX_IMM:
1825       {
1826         int nbytes = fragP->fr_subtype - fragP->tc_frag_data->relax[ri].val_ofs;
1827         int li;
1828         char * imm = op + fragP->tc_frag_data->relax[ri].val_ofs;
1829
1830         switch (nbytes)
1831           {
1832           case 1:
1833             li = 1;
1834             imm[0] = addr0;
1835             reloc_type = BFD_RELOC_8;
1836             break;
1837           case 2:
1838             li = 2;
1839 #if RX_OPCODE_BIG_ENDIAN
1840             imm[1] = addr0;
1841             imm[0] = addr0 >> 8;
1842 #else
1843             imm[0] = addr0;
1844             imm[1] = addr0 >> 8;
1845 #endif
1846             reloc_type = BFD_RELOC_RX_16_OP;
1847             break;
1848           case 3:
1849             li = 3;
1850 #if RX_OPCODE_BIG_ENDIAN
1851             imm[2] = addr0;
1852             imm[1] = addr0 >> 8;
1853             imm[0] = addr0 >> 16;
1854 #else
1855             imm[0] = addr0;
1856             imm[1] = addr0 >> 8;
1857             imm[2] = addr0 >> 16;
1858 #endif
1859             reloc_type = BFD_RELOC_RX_24_OP;
1860             break;
1861           case 4:
1862             li = 0;
1863 #if RX_OPCODE_BIG_ENDIAN
1864             imm[3] = addr0;
1865             imm[2] = addr0 >> 8;
1866             imm[1] = addr0 >> 16;
1867             imm[0] = addr0 >> 24;
1868 #else
1869             imm[0] = addr0;
1870             imm[1] = addr0 >> 8;
1871             imm[2] = addr0 >> 16;
1872             imm[3] = addr0 >> 24;
1873 #endif
1874             reloc_type = BFD_RELOC_RX_32_OP;
1875             break;
1876           default:
1877             as_bad (_("invalid immediate size"));
1878             li = -1;
1879           }
1880
1881         switch (fragP->tc_frag_data->relax[ri].field_pos)
1882           {
1883           case 6:
1884             op[0] &= 0xfc;
1885             op[0] |= li;
1886             break;
1887           case 12:
1888             op[1] &= 0xf3;
1889             op[1] |= li << 2;
1890             break;
1891           case 20:
1892             op[2] &= 0xf3;
1893             op[2] |= li << 2;
1894             break;
1895           default:
1896             as_bad (_("invalid immediate field position"));
1897           }
1898       }
1899       break;
1900
1901     default:
1902       if (rxb->n_fixups)
1903         {
1904           reloc_type = fix->fx_r_type;
1905           reloc_adjust = 0;
1906         }
1907       break;
1908     }
1909
1910   if (rxb->n_fixups)
1911     {
1912
1913       fix->fx_r_type = reloc_type;
1914       fix->fx_where += reloc_adjust;
1915       switch (reloc_type)
1916         {
1917         case BFD_RELOC_NONE:
1918           fix->fx_size = 0;
1919           break;
1920         case BFD_RELOC_8:
1921           fix->fx_size = 1;
1922           break;
1923         case BFD_RELOC_16_PCREL:
1924         case BFD_RELOC_RX_16_OP:
1925           fix->fx_size = 2;
1926           break;
1927         case BFD_RELOC_24_PCREL:
1928         case BFD_RELOC_RX_24_OP:
1929           fix->fx_size = 3;
1930           break;
1931         case BFD_RELOC_RX_32_OP:
1932           fix->fx_size = 4;
1933           break;
1934         }
1935     }
1936
1937   fragP->fr_fix = fragP->fr_subtype + (fragP->fr_opcode - fragP->fr_literal);
1938   tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP->fr_fix,
1939           fragP->fr_subtype, fragP->fr_opcode, fragP->fr_literal);
1940   fragP->fr_var = 0;
1941
1942   if (fragP->fr_next != NULL
1943           && ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
1944               != fragP->fr_fix))
1945     as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
1946             (long) fragP->fr_fix,
1947             (long) fragP->fr_address, (long) fragP->fr_next->fr_address);
1948 }
1949
1950 #undef OPCODE
1951 \f
1952 int
1953 rx_validate_fix_sub (struct fix * f)
1954 {
1955   /* We permit the subtraction of two symbols in a few cases.  */
1956   /* mov #sym1-sym2, R3 */
1957   if (f->fx_r_type == BFD_RELOC_RX_32_OP)
1958     return 1;
1959   /* .long sym1-sym2 */
1960   if (f->fx_r_type == BFD_RELOC_RX_DIFF
1961       && ! f->fx_pcrel
1962       && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
1963     return 1;
1964   return 0;
1965 }
1966
1967 long
1968 md_pcrel_from_section (fixS * fixP, segT sec)
1969 {
1970   long rv;
1971
1972   if (fixP->fx_addsy != NULL
1973       && (! S_IS_DEFINED (fixP->fx_addsy)
1974           || S_GET_SEGMENT (fixP->fx_addsy) != sec))
1975     /* The symbol is undefined (or is defined but not in this section).
1976        Let the linker figure it out.  */
1977     return 0;
1978
1979   rv = fixP->fx_frag->fr_address + fixP->fx_where;
1980   switch (fixP->fx_r_type)
1981     {
1982     case BFD_RELOC_RX_DIR3U_PCREL:
1983       return rv;
1984     default:
1985       return rv - 1;
1986     }
1987 }
1988
1989 void
1990 rx_cons_fix_new (fragS *        frag,
1991                  int            where,
1992                  int            size,
1993                  expressionS *  exp)
1994 {
1995   bfd_reloc_code_real_type type;
1996
1997   switch (size)
1998     {
1999     case 1:
2000       type = BFD_RELOC_8;
2001       break;
2002     case 2:
2003       type = BFD_RELOC_16;
2004       break;
2005     case 3:
2006       type = BFD_RELOC_24;
2007       break;
2008     case 4:
2009       type = BFD_RELOC_32;
2010       break;
2011     default:
2012       as_bad (_("unsupported constant size %d\n"), size);
2013       return;
2014     }
2015
2016   if (exp->X_op == O_subtract && exp->X_op_symbol)
2017     {
2018       if (size != 4 && size != 2 && size != 1)
2019         as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
2020       else
2021         type = BFD_RELOC_RX_DIFF;
2022     }
2023
2024   fix_new_exp (frag, where, (int) size, exp, 0, type);
2025 }
2026
2027 void
2028 md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
2029               valueT *     t ATTRIBUTE_UNUSED,
2030               segT         s ATTRIBUTE_UNUSED)
2031 {
2032   /* Instruction bytes are always little endian.  */
2033   char * op;
2034   unsigned long val;
2035
2036   if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
2037     return;
2038   if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
2039     return;
2040
2041 #define OP2(x) op[target_big_endian ? 1-x : x]
2042 #define OP3(x) op[target_big_endian ? 2-x : x]
2043 #define OP4(x) op[target_big_endian ? 3-x : x]
2044
2045   op = f->fx_frag->fr_literal + f->fx_where;
2046   val = (unsigned long) * t;
2047
2048   /* Opcode words are always the same endian.  Data words are either
2049      big or little endian.  */
2050
2051   switch (f->fx_r_type)
2052     {
2053     case BFD_RELOC_NONE:
2054       break;
2055
2056     case BFD_RELOC_RX_RELAX:
2057       f->fx_done = 1;
2058       break;
2059
2060     case BFD_RELOC_RX_DIR3U_PCREL:
2061       if (val < 3 || val > 10)
2062         as_bad_where (f->fx_file, f->fx_line,
2063                       _("jump not 3..10 bytes away (is %d)"), (int) val);
2064       op[0] &= 0xf8;
2065       op[0] |= val & 0x07;
2066       break;
2067
2068     case BFD_RELOC_8:
2069     case BFD_RELOC_8_PCREL:
2070     case BFD_RELOC_RX_8U:
2071       op[0] = val;
2072       break;
2073
2074     case BFD_RELOC_16:
2075       OP2(1) = val & 0xff;
2076       OP2(0) = (val >> 8) & 0xff;
2077       break;
2078
2079     case BFD_RELOC_16_PCREL:
2080     case BFD_RELOC_RX_16_OP:
2081     case BFD_RELOC_RX_16U:
2082 #if RX_OPCODE_BIG_ENDIAN
2083       op[1] = val & 0xff;
2084       op[0] = (val >> 8) & 0xff;
2085 #else
2086       op[0] = val & 0xff;
2087       op[1] = (val >> 8) & 0xff;
2088 #endif
2089       break;
2090
2091     case BFD_RELOC_24:
2092       OP3(0) = val & 0xff;
2093       OP3(1) = (val >> 8) & 0xff;
2094       OP3(2) = (val >> 16) & 0xff;
2095       break;
2096
2097     case BFD_RELOC_24_PCREL:
2098     case BFD_RELOC_RX_24_OP:
2099     case BFD_RELOC_RX_24U:
2100 #if RX_OPCODE_BIG_ENDIAN
2101       op[2] = val & 0xff;
2102       op[1] = (val >> 8) & 0xff;
2103       op[0] = (val >> 16) & 0xff;
2104 #else
2105       op[0] = val & 0xff;
2106       op[1] = (val >> 8) & 0xff;
2107       op[2] = (val >> 16) & 0xff;
2108 #endif
2109       break;
2110
2111     case BFD_RELOC_RX_DIFF:
2112       switch (f->fx_size)
2113         {
2114         case 1:
2115           op[0] = val & 0xff;
2116           break;
2117         case 2:
2118           OP2(0) = val & 0xff;
2119           OP2(1) = (val >> 8) & 0xff;
2120           break;
2121         case 4:
2122           OP4(0) = val & 0xff;
2123           OP4(1) = (val >> 8) & 0xff;
2124           OP4(2) = (val >> 16) & 0xff;
2125           OP4(3) = (val >> 24) & 0xff;
2126           break;
2127         }
2128       break;
2129
2130     case BFD_RELOC_32:
2131       OP4(0) = val & 0xff;
2132       OP4(1) = (val >> 8) & 0xff;
2133       OP4(2) = (val >> 16) & 0xff;
2134       OP4(3) = (val >> 24) & 0xff;
2135       break;
2136
2137     case BFD_RELOC_RX_32_OP:
2138 #if RX_OPCODE_BIG_ENDIAN
2139       op[3] = val & 0xff;
2140       op[2] = (val >> 8) & 0xff;
2141       op[1] = (val >> 16) & 0xff;
2142       op[0] = (val >> 24) & 0xff;
2143 #else
2144       op[0] = val & 0xff;
2145       op[1] = (val >> 8) & 0xff;
2146       op[2] = (val >> 16) & 0xff;
2147       op[3] = (val >> 24) & 0xff;
2148 #endif
2149       break;
2150
2151     case BFD_RELOC_RX_NEG8:
2152       op[0] = - val;
2153       break;
2154
2155     case BFD_RELOC_RX_NEG16:
2156       val = -val;
2157 #if RX_OPCODE_BIG_ENDIAN
2158       op[1] = val & 0xff;
2159       op[0] = (val >> 8) & 0xff;
2160 #else
2161       op[0] = val & 0xff;
2162       op[1] = (val >> 8) & 0xff;
2163 #endif
2164       break;
2165
2166     case BFD_RELOC_RX_NEG24:
2167       val = -val;
2168 #if RX_OPCODE_BIG_ENDIAN
2169       op[2] = val & 0xff;
2170       op[1] = (val >> 8) & 0xff;
2171       op[0] = (val >> 16) & 0xff;
2172 #else
2173       op[0] = val & 0xff;
2174       op[1] = (val >> 8) & 0xff;
2175       op[2] = (val >> 16) & 0xff;
2176 #endif
2177       break;
2178
2179     case BFD_RELOC_RX_NEG32:
2180       val = -val;
2181 #if RX_OPCODE_BIG_ENDIAN
2182       op[3] = val & 0xff;
2183       op[2] = (val >> 8) & 0xff;
2184       op[1] = (val >> 16) & 0xff;
2185       op[0] = (val >> 24) & 0xff;
2186 #else
2187       op[0] = val & 0xff;
2188       op[1] = (val >> 8) & 0xff;
2189       op[2] = (val >> 16) & 0xff;
2190       op[3] = (val >> 24) & 0xff;
2191 #endif
2192       break;
2193
2194     case BFD_RELOC_RX_GPRELL:
2195       val >>= 1;
2196     case BFD_RELOC_RX_GPRELW:
2197       val >>= 1;
2198     case BFD_RELOC_RX_GPRELB:
2199 #if RX_OPCODE_BIG_ENDIAN
2200       op[1] = val & 0xff;
2201       op[0] = (val >> 8) & 0xff;
2202 #else
2203       op[0] = val & 0xff;
2204       op[1] = (val >> 8) & 0xff;
2205 #endif
2206       break;
2207
2208     default:
2209       as_bad (_("Unknown reloc in md_apply_fix: %s"),
2210               bfd_get_reloc_code_name (f->fx_r_type));
2211       break;
2212     }
2213
2214   if (f->fx_addsy == NULL)
2215     f->fx_done = 1;
2216 }
2217
2218 arelent **
2219 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
2220 {
2221   static arelent * reloc[5];
2222   int is_opcode = 0;
2223
2224   if (fixp->fx_r_type == BFD_RELOC_NONE)
2225     {
2226       reloc[0] = NULL;
2227       return reloc;
2228     }
2229
2230   if (fixp->fx_subsy
2231       && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
2232     {
2233       fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
2234       fixp->fx_subsy = NULL;
2235     }
2236
2237   reloc[0]                = (arelent *) xmalloc (sizeof (arelent));
2238   reloc[0]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));
2239   * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2240   reloc[0]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
2241   reloc[0]->addend        = fixp->fx_offset;
2242
2243   if (fixp->fx_r_type == BFD_RELOC_RX_32_OP
2244       && fixp->fx_subsy)
2245     {
2246       fixp->fx_r_type = BFD_RELOC_RX_DIFF;
2247       is_opcode = 1;
2248     }
2249
2250   /* Certain BFD relocations cannot be translated directly into
2251      a single (non-Red Hat) RX relocation, but instead need
2252      multiple RX relocations - handle them here.  */
2253   switch (fixp->fx_r_type)
2254     {
2255     case BFD_RELOC_RX_DIFF:
2256       reloc[0]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2257
2258       reloc[1]                = (arelent *) xmalloc (sizeof (arelent));
2259       reloc[1]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));
2260       * reloc[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
2261       reloc[1]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
2262       reloc[1]->addend        = 0;
2263       reloc[1]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2264
2265       reloc[2]                = (arelent *) xmalloc (sizeof (arelent));
2266       reloc[2]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2267       reloc[2]->addend        = 0;
2268       reloc[2]->sym_ptr_ptr   = reloc[1]->sym_ptr_ptr;
2269       reloc[2]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
2270
2271       reloc[3]                = (arelent *) xmalloc (sizeof (arelent));
2272       switch (fixp->fx_size)
2273         {
2274         case 1:
2275           reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS8);
2276           break;
2277         case 2:
2278           if (!is_opcode && target_big_endian)
2279             reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16_REV);
2280           else
2281             reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16);
2282           break;
2283         case 4:
2284           if (!is_opcode && target_big_endian)
2285             reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32_REV);
2286           else
2287             reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32);
2288           break;
2289         }
2290       reloc[3]->addend      = 0;
2291       reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2292       reloc[3]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2293
2294       reloc[4] = NULL;
2295       break;
2296
2297     case BFD_RELOC_RX_GPRELL:
2298       reloc[0]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2299
2300       reloc[1]                = (arelent *) xmalloc (sizeof (arelent));
2301       reloc[1]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));
2302       if (gp_symbol == NULL)
2303         {
2304           if (symbol_table_frozen)
2305             {
2306               symbolS * gp;
2307
2308               gp = symbol_find ("__gp");
2309               if (gp == NULL)
2310                 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2311               else
2312                 gp_symbol = symbol_get_bfdsym (gp);
2313             }
2314           else
2315             gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2316         }
2317       * reloc[1]->sym_ptr_ptr = gp_symbol;
2318       reloc[1]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
2319       reloc[1]->addend        = 0;
2320       reloc[1]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2321
2322       reloc[2]              = (arelent *) xmalloc (sizeof (arelent));
2323       reloc[2]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2324       reloc[2]->addend      = 0;
2325       reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2326       reloc[2]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2327
2328       reloc[3]              = (arelent *) xmalloc (sizeof (arelent));
2329       reloc[3]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UL);
2330       reloc[3]->addend      = 0;
2331       reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2332       reloc[3]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2333
2334       reloc[4] = NULL;
2335       break;
2336
2337     case BFD_RELOC_RX_GPRELW:
2338       reloc[0]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2339
2340       reloc[1]                = (arelent *) xmalloc (sizeof (arelent));
2341       reloc[1]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));
2342       if (gp_symbol == NULL)
2343         {
2344           if (symbol_table_frozen)
2345             {
2346               symbolS * gp;
2347
2348               gp = symbol_find ("__gp");
2349               if (gp == NULL)
2350                 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2351               else
2352                 gp_symbol = symbol_get_bfdsym (gp);
2353             }
2354           else
2355             gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2356         }
2357       * reloc[1]->sym_ptr_ptr = gp_symbol;
2358       reloc[1]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
2359       reloc[1]->addend        = 0;
2360       reloc[1]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2361
2362       reloc[2]              = (arelent *) xmalloc (sizeof (arelent));
2363       reloc[2]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2364       reloc[2]->addend      = 0;
2365       reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2366       reloc[2]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2367
2368       reloc[3]              = (arelent *) xmalloc (sizeof (arelent));
2369       reloc[3]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UW);
2370       reloc[3]->addend      = 0;
2371       reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2372       reloc[3]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2373
2374       reloc[4] = NULL;
2375       break;
2376
2377     case BFD_RELOC_RX_GPRELB:
2378       reloc[0]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2379
2380       reloc[1]                = (arelent *) xmalloc (sizeof (arelent));
2381       reloc[1]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));
2382       if (gp_symbol == NULL)
2383         {
2384           if (symbol_table_frozen)
2385             {
2386               symbolS * gp;
2387
2388               gp = symbol_find ("__gp");
2389               if (gp == NULL)
2390                 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2391               else
2392                 gp_symbol = symbol_get_bfdsym (gp);
2393             }
2394           else
2395             gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2396         }
2397       * reloc[1]->sym_ptr_ptr = gp_symbol;
2398       reloc[1]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
2399       reloc[1]->addend        = 0;
2400       reloc[1]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2401
2402       reloc[2]              = (arelent *) xmalloc (sizeof (arelent));
2403       reloc[2]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2404       reloc[2]->addend      = 0;
2405       reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2406       reloc[2]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2407
2408       reloc[3]              = (arelent *) xmalloc (sizeof (arelent));
2409       reloc[3]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16U);
2410       reloc[3]->addend      = 0;
2411       reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2412       reloc[3]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2413
2414       reloc[4] = NULL;
2415       break;
2416
2417     case BFD_RELOC_RX_NEG32:
2418       reloc[0]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2419
2420       reloc[1]              = (arelent *) xmalloc (sizeof (arelent));
2421       reloc[1]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_NEG);
2422       reloc[1]->addend      = 0;
2423       reloc[1]->sym_ptr_ptr = reloc[0]->sym_ptr_ptr;
2424       reloc[1]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2425
2426       reloc[2]              = (arelent *) xmalloc (sizeof (arelent));
2427       reloc[2]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32);
2428       reloc[2]->addend      = 0;
2429       reloc[2]->sym_ptr_ptr = reloc[0]->sym_ptr_ptr;
2430       reloc[2]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2431
2432       reloc[3] = NULL;
2433       break;
2434
2435     default:
2436       reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2437       reloc[1] = NULL;
2438       break;
2439     }
2440
2441   return reloc;
2442 }
2443
2444 /* Set the ELF specific flags.  */
2445
2446 void
2447 rx_elf_final_processing (void)
2448 {
2449   elf_elfheader (stdoutput)->e_flags |= elf_flags;
2450 }
2451
2452 /* Scan the current input line for occurances of Renesas
2453    local labels and replace them with the GAS version.  */
2454
2455 void
2456 rx_start_line (void)
2457 {
2458   int in_double_quote = 0;
2459   int in_single_quote = 0;
2460   int done = 0;
2461   char * p = input_line_pointer;
2462
2463   /* Scan the line looking for question marks.  Skip past quote enclosed regions.  */
2464   do
2465     {
2466       switch (*p)
2467         {
2468         case '\n':
2469         case 0:
2470           done = 1;
2471           break;
2472
2473         case '"':
2474           in_double_quote = ! in_double_quote;
2475           break;
2476
2477         case '\'':
2478           in_single_quote = ! in_single_quote;
2479           break;
2480
2481         case '?':
2482           if (in_double_quote || in_single_quote)
2483             break;
2484
2485           if (p[1] == ':')
2486             *p = '1';
2487           else if (p[1] == '+')
2488             {
2489               p[0] = '1';
2490               p[1] = 'f';
2491             }
2492           else if (p[1] == '-')
2493             {
2494               p[0] = '1';
2495               p[1] = 'b';
2496             }
2497           break;
2498
2499         default:
2500           break;
2501         }
2502
2503       p ++;
2504     }
2505   while (! done);
2506 }