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
38const 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.  */
42const char line_comment_chars[]   = "#";
43const char line_separator_chars[] = "!";
44
45const char EXP_CHARS[]            = "eE";
46const char FLT_CHARS[]            = "dD";
47
48/* ELF flags to set in the output file header.  */
49static int elf_flags = 0;
50
51bfd_boolean rx_use_conventional_section_names = FALSE;
52static bfd_boolean rx_use_small_data_limit = FALSE;
53
54enum 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 ""
67const char * md_shortopts = RX_SHORTOPTS;
68
69/* Assembler options.  */
70struct 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};
88size_t md_longopts_size = sizeof (md_longopts);
89
90int
91md_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
130void
131md_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
143static void
144s_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
153static void
154rx_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
161static char *
162rx_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
185static void
186rx_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
336static void
337parse_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
433static void
434rx_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
470static void
471rx_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
486static void
487rx_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
496static void
497rx_cons (int size)
498{
499  SKIP_WHITESPACE ();
500
501  if (* input_line_pointer == '"')
502    stringer (8+0);
503  else
504    cons (size);
505}
506
507static void
508rx_nop (int ignore ATTRIBUTE_UNUSED)
509{
510  ignore_rest_of_line ();
511}
512
513static void
514rx_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.  */
522const 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
586static asymbol * gp_symbol;
587
588void
589md_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
599char * rx_lex_start;
600char * rx_lex_end;
601
602typedef 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
631static rx_bytesT rx_bytes;
632
633void
634rx_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
642void
643rx_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
659void
660rx_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
673void
674rx_linkrelax_branch (void)
675{
676  rx_bytes.link_relax |= RX_RELAXA_BRA;
677}
678
679static void
680rx_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
696void
697rx_base1 (int b1)
698{
699  rx_bytes.base[0] = b1;
700  rx_bytes.n_base = 1;
701}
702
703void
704rx_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
711void
712rx_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
720void
721rx_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
739void
740rx_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
784void
785rx_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
794void
795rx_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
807void
808rx_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
821void
822rx_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
871int
872rx_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
884void
885rx_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
899static void
900rx_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
929static bfd_boolean
930scan_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
965void
966md_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
1059void
1060rx_md_end (void)
1061{
1062}
1063
1064/* Write a value out to the object file, using the appropriate endianness.  */
1065
1066void
1067md_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
1075static struct
1076{
1077  char * fname;
1078  int    reloc;
1079}
1080reloc_functions[] =
1081{
1082  { "gp", BFD_RELOC_GPREL16 },
1083  { 0, 0 }
1084};
1085
1086void
1087md_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
1115valueT
1116md_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 */
1123static unsigned char nop_1[] = { 0x03};
1124				/* MOV.L R0,R0 - 1 cycle */
1125static unsigned char nop_2[] = { 0xef, 0x00};
1126				/* MAX R0,R0 - 1 cycle */
1127static unsigned char nop_3[] = { 0xfc, 0x13, 0x00 };
1128				/* MUL #1,R0 - 1 cycle */
1129static unsigned char nop_4[] = { 0x76, 0x10, 0x01, 0x00 };
1130				/* MUL #1,R0 - 1 cycle */
1131static unsigned char nop_5[] = { 0x77, 0x10, 0x01, 0x00, 0x00 };
1132				/* MUL #1,R0 - 1 cycle */
1133static unsigned char nop_6[] = { 0x74, 0x10, 0x01, 0x00, 0x00, 0x00 };
1134				/* BRA.S .+7 - 1 cycle */
1135static unsigned char nop_7[] = { 0x0F, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
1136
1137static 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.  */
1142void
1143rx_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
1186char *
1187md_atof (int type, char * litP, int * sizeP)
1188{
1189  return ieee_md_atof (type, litP, sizeP, target_big_endian);
1190}
1191
1192symbolS *
1193md_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
1215typedef 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
1257static op_type_T
1258rx_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
1294static int
1295rx_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
1340int
1341md_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
1367int
1368rx_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
1566void
1567md_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  /* Try to get the target address.  If we fail here, we just use the
1607     largest format.  */
1608  if (rx_frag_fix_value (fragP, segment, 0, & addr0,
1609			 fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH, 0))
1610    keep_reloc = 1;
1611
1612  if (linkrelax)
1613    keep_reloc = 1;
1614
1615  /* We used a new frag for this opcode, so the opcode address should
1616     be the frag address.  */
1617  mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1618  disp = (int) addr0 - (int) mypc;
1619
1620  reloc_type = BFD_RELOC_NONE;
1621  reloc_adjust = 0;
1622
1623  tprintf ("convert, op is %d, disp %d (%lx-%lx)\n",
1624	   rx_opcode_type (fragP->fr_opcode), disp,
1625	   (unsigned long) addr0, (unsigned long) mypc);
1626  switch (fragP->tc_frag_data->relax[ri].type)
1627    {
1628    case RX_RELAX_BRANCH:
1629      switch (OPCODE (rx_opcode_type (fragP->fr_opcode), fragP->fr_subtype))
1630	{
1631	case OPCODE (OT_bra, 1): /* BRA.S - no change.  */
1632	  op[0] = 0x08 + (disp & 7);
1633	  break;
1634	case OPCODE (OT_bra, 2): /* BRA.B - 8 bit.  */
1635	  op[0] = 0x2e;
1636	  op[1] = disp;
1637	  reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1638	  reloc_adjust = 1;
1639	  break;
1640	case OPCODE (OT_bra, 3): /* BRA.W - 16 bit.  */
1641	  op[0] = 0x38;
1642#if RX_OPCODE_BIG_ENDIAN
1643	  op[1] = (disp >> 8) & 0xff;
1644	  op[2] = disp;
1645#else
1646	  op[2] = (disp >> 8) & 0xff;
1647	  op[1] = disp;
1648#endif
1649	  reloc_adjust = 1;
1650	  reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1651	  break;
1652	case OPCODE (OT_bra, 4): /* BRA.A - 24 bit.  */
1653	  op[0] = 0x04;
1654#if RX_OPCODE_BIG_ENDIAN
1655	  op[1] = (disp >> 16) & 0xff;
1656	  op[2] = (disp >> 8) & 0xff;
1657	  op[3] = disp;
1658#else
1659	  op[3] = (disp >> 16) & 0xff;
1660	  op[2] = (disp >> 8) & 0xff;
1661	  op[1] = disp;
1662#endif
1663	  reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1664	  reloc_adjust = 1;
1665	  break;
1666
1667	case OPCODE (OT_beq, 1): /* BEQ.S - no change.  */
1668	  op[0] = 0x10 + (disp & 7);
1669	  break;
1670	case OPCODE (OT_beq, 2): /* BEQ.B - 8 bit.  */
1671	  op[0] = 0x20;
1672	  op[1] = disp;
1673	  reloc_adjust = 1;
1674	  reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1675	  break;
1676	case OPCODE (OT_beq, 3): /* BEQ.W - 16 bit.  */
1677	  op[0] = 0x3a;
1678#if RX_OPCODE_BIG_ENDIAN
1679	  op[1] = (disp >> 8) & 0xff;
1680	  op[2] = disp;
1681#else
1682	  op[2] = (disp >> 8) & 0xff;
1683	  op[1] = disp;
1684#endif
1685	  reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1686	  reloc_adjust = 1;
1687	  break;
1688	case OPCODE (OT_beq, 5): /* BEQ.A - synthetic.  */
1689	  op[0] = 0x1e; /* bne.s .+4.  */
1690	  op[1] = 0x04; /* bra.a dsp:24.  */
1691	  disp -= 1;
1692#if RX_OPCODE_BIG_ENDIAN
1693	  op[2] = (disp >> 16) & 0xff;
1694	  op[3] = (disp >> 8) & 0xff;
1695	  op[4] = disp;
1696#else
1697	  op[4] = (disp >> 16) & 0xff;
1698	  op[3] = (disp >> 8) & 0xff;
1699	  op[2] = disp;
1700#endif
1701	  reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1702	  reloc_adjust = 2;
1703	  break;
1704
1705	case OPCODE (OT_bne, 1): /* BNE.S - no change.  */
1706	  op[0] = 0x18 + (disp & 7);
1707	  break;
1708	case OPCODE (OT_bne, 2): /* BNE.B - 8 bit.  */
1709	  op[0] = 0x21;
1710	  op[1] = disp;
1711	  reloc_adjust = 1;
1712	  reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1713	  break;
1714	case OPCODE (OT_bne, 3): /* BNE.W - 16 bit.  */
1715	  op[0] = 0x3b;
1716#if RX_OPCODE_BIG_ENDIAN
1717	  op[1] = (disp >> 8) & 0xff;
1718	  op[2] = disp;
1719#else
1720	  op[2] = (disp >> 8) & 0xff;
1721	  op[1] = disp;
1722#endif
1723	  reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1724	  reloc_adjust = 1;
1725	  break;
1726	case OPCODE (OT_bne, 5): /* BNE.A - synthetic.  */
1727	  op[0] = 0x15; /* beq.s .+4.  */
1728	  op[1] = 0x04; /* bra.a dsp:24.  */
1729	  disp -= 1;
1730#if RX_OPCODE_BIG_ENDIAN
1731	  op[2] = (disp >> 16) & 0xff;
1732	  op[3] = (disp >> 8) & 0xff;
1733	  op[4] = disp;
1734#else
1735	  op[4] = (disp >> 16) & 0xff;
1736	  op[3] = (disp >> 8) & 0xff;
1737	  op[2] = disp;
1738#endif
1739	  reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1740	  reloc_adjust = 2;
1741	  break;
1742
1743	case OPCODE (OT_bsr, 3): /* BSR.W - 16 bit.  */
1744	  op[0] = 0x39;
1745#if RX_OPCODE_BIG_ENDIAN
1746	  op[1] = (disp >> 8) & 0xff;
1747	  op[2] = disp;
1748#else
1749	  op[2] = (disp >> 8) & 0xff;
1750	  op[1] = disp;
1751#endif
1752	  reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1753	  reloc_adjust = 0;
1754	  break;
1755	case OPCODE (OT_bsr, 4): /* BSR.A - 24 bit.  */
1756	  op[0] = 0x05;
1757#if RX_OPCODE_BIG_ENDIAN
1758	  op[1] = (disp >> 16) & 0xff;
1759	  op[2] = (disp >> 8) & 0xff;
1760	  op[3] = disp;
1761#else
1762	  op[3] = (disp >> 16) & 0xff;
1763	  op[2] = (disp >> 8) & 0xff;
1764	  op[1] = disp;
1765#endif
1766	  reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1767	  reloc_adjust = 0;
1768	  break;
1769
1770	case OPCODE (OT_bcc, 2): /* Bcond.B - 8 bit.  */
1771	  op[1] = disp;
1772	  reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1773	  break;
1774	case OPCODE (OT_bcc, 5): /* Bcond.W - synthetic.  */
1775	  op[0] ^= 1; /* Invert condition.  */
1776	  op[1] = 5;  /* Displacement.  */
1777	  op[2] = 0x38;
1778	  disp -= 2;
1779#if RX_OPCODE_BIG_ENDIAN
1780	  op[3] = (disp >> 8) & 0xff;
1781	  op[4] = disp;
1782#else
1783	  op[4] = (disp >> 8) & 0xff;
1784	  op[3] = disp;
1785#endif
1786	  reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1787	  reloc_adjust = 2;
1788	  break;
1789	case OPCODE (OT_bcc, 6): /* Bcond.S - synthetic.  */
1790	  op[0] ^= 1; /* Invert condition.  */
1791	  op[1] = 6;  /* Displacement.  */
1792	  op[2] = 0x04;
1793	  disp -= 2;
1794#if RX_OPCODE_BIG_ENDIAN
1795	  op[3] = (disp >> 16) & 0xff;
1796	  op[4] = (disp >> 8) & 0xff;
1797	  op[5] = disp;
1798#else
1799	  op[5] = (disp >> 16) & 0xff;
1800	  op[4] = (disp >> 8) & 0xff;
1801	  op[3] = disp;
1802#endif
1803	  reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1804	  reloc_adjust = 2;
1805	  break;
1806
1807	default:
1808	  /* These are opcodes we'll relax in th linker, later.  */
1809	  if (rxb->n_fixups)
1810	    reloc_type = rxb->fixups[ri].fixP->fx_r_type;
1811	  break;
1812	}
1813      break;
1814
1815    case RX_RELAX_IMM:
1816      {
1817	int nbytes = fragP->fr_subtype - fragP->tc_frag_data->relax[ri].val_ofs;
1818	int li;
1819	char * imm = op + fragP->tc_frag_data->relax[ri].val_ofs;
1820
1821	switch (nbytes)
1822	  {
1823	  case 1:
1824	    li = 1;
1825	    imm[0] = addr0;
1826	    reloc_type = BFD_RELOC_8;
1827	    break;
1828	  case 2:
1829	    li = 2;
1830#if RX_OPCODE_BIG_ENDIAN
1831	    imm[1] = addr0;
1832	    imm[0] = addr0 >> 8;
1833#else
1834	    imm[0] = addr0;
1835	    imm[1] = addr0 >> 8;
1836#endif
1837	    reloc_type = BFD_RELOC_RX_16_OP;
1838	    break;
1839	  case 3:
1840	    li = 3;
1841#if RX_OPCODE_BIG_ENDIAN
1842	    imm[2] = addr0;
1843	    imm[1] = addr0 >> 8;
1844	    imm[0] = addr0 >> 16;
1845#else
1846	    imm[0] = addr0;
1847	    imm[1] = addr0 >> 8;
1848	    imm[2] = addr0 >> 16;
1849#endif
1850	    reloc_type = BFD_RELOC_RX_24_OP;
1851	    break;
1852	  case 4:
1853	    li = 0;
1854#if RX_OPCODE_BIG_ENDIAN
1855	    imm[3] = addr0;
1856	    imm[2] = addr0 >> 8;
1857	    imm[1] = addr0 >> 16;
1858	    imm[0] = addr0 >> 24;
1859#else
1860	    imm[0] = addr0;
1861	    imm[1] = addr0 >> 8;
1862	    imm[2] = addr0 >> 16;
1863	    imm[3] = addr0 >> 24;
1864#endif
1865	    reloc_type = BFD_RELOC_RX_32_OP;
1866	    break;
1867	  default:
1868	    as_bad (_("invalid immediate size"));
1869	    li = -1;
1870	  }
1871
1872	switch (fragP->tc_frag_data->relax[ri].field_pos)
1873	  {
1874	  case 6:
1875	    op[0] &= 0xfc;
1876	    op[0] |= li;
1877	    break;
1878	  case 12:
1879	    op[1] &= 0xf3;
1880	    op[1] |= li << 2;
1881	    break;
1882	  case 20:
1883	    op[2] &= 0xf3;
1884	    op[2] |= li << 2;
1885	    break;
1886	  default:
1887	    as_bad (_("invalid immediate field position"));
1888	  }
1889      }
1890      break;
1891
1892    default:
1893      if (rxb->n_fixups)
1894	{
1895	  reloc_type = fix->fx_r_type;
1896	  reloc_adjust = 0;
1897	}
1898      break;
1899    }
1900
1901  if (rxb->n_fixups)
1902    {
1903
1904      fix->fx_r_type = reloc_type;
1905      fix->fx_where += reloc_adjust;
1906      switch (reloc_type)
1907	{
1908	case BFD_RELOC_NONE:
1909	  fix->fx_size = 0;
1910	  break;
1911	case BFD_RELOC_8:
1912	  fix->fx_size = 1;
1913	  break;
1914	case BFD_RELOC_16_PCREL:
1915	case BFD_RELOC_RX_16_OP:
1916	  fix->fx_size = 2;
1917	  break;
1918	case BFD_RELOC_24_PCREL:
1919	case BFD_RELOC_RX_24_OP:
1920	  fix->fx_size = 3;
1921	  break;
1922	case BFD_RELOC_RX_32_OP:
1923	  fix->fx_size = 4;
1924	  break;
1925	}
1926    }
1927
1928  fragP->fr_fix = fragP->fr_subtype + (fragP->fr_opcode - fragP->fr_literal);
1929  tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP->fr_fix,
1930	  fragP->fr_subtype, fragP->fr_opcode, fragP->fr_literal);
1931  fragP->fr_var = 0;
1932
1933  if (fragP->fr_next != NULL
1934	  && ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
1935	      != fragP->fr_fix))
1936    as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
1937	    (long) fragP->fr_fix,
1938	    (long) fragP->fr_address, (long) fragP->fr_next->fr_address);
1939}
1940
1941#undef OPCODE
1942
1943int
1944rx_validate_fix_sub (struct fix * f)
1945{
1946  /* We permit the subtraction of two symbols as a 32-bit relocation.  */
1947  if (f->fx_r_type == BFD_RELOC_RX_DIFF
1948      && ! f->fx_pcrel
1949      && f->fx_size == 4)
1950    return 1;
1951  return 0;
1952}
1953
1954long
1955md_pcrel_from_section (fixS * fixP, segT sec)
1956{
1957  long rv;
1958
1959  if (fixP->fx_addsy != NULL
1960      && (! S_IS_DEFINED (fixP->fx_addsy)
1961	  || S_GET_SEGMENT (fixP->fx_addsy) != sec))
1962    /* The symbol is undefined (or is defined but not in this section).
1963       Let the linker figure it out.  */
1964    return 0;
1965
1966  rv = fixP->fx_frag->fr_address + fixP->fx_where;
1967  switch (fixP->fx_r_type)
1968    {
1969    case BFD_RELOC_RX_DIR3U_PCREL:
1970      return rv;
1971    default:
1972      return rv - 1;
1973    }
1974}
1975
1976void
1977rx_cons_fix_new (fragS *	frag,
1978		 int		where,
1979		 int		size,
1980		 expressionS *  exp)
1981{
1982  bfd_reloc_code_real_type type;
1983
1984  switch (size)
1985    {
1986    case 1:
1987      type = BFD_RELOC_8;
1988      break;
1989    case 2:
1990      type = BFD_RELOC_16;
1991      break;
1992    case 3:
1993      type = BFD_RELOC_24;
1994      break;
1995    case 4:
1996      type = BFD_RELOC_32;
1997      break;
1998    default:
1999      as_bad (_("unsupported constant size %d\n"), size);
2000      return;
2001    }
2002
2003  if (exp->X_op == O_subtract && exp->X_op_symbol)
2004    {
2005      if (size != 4 && size != 2 && size != 1)
2006	as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
2007      else
2008	type = BFD_RELOC_RX_DIFF;
2009    }
2010
2011  fix_new_exp (frag, where, (int) size, exp, 0, type);
2012}
2013
2014void
2015md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
2016	      valueT *     t ATTRIBUTE_UNUSED,
2017	      segT         s ATTRIBUTE_UNUSED)
2018{
2019  /* Instruction bytes are always little endian.  */
2020  char * op;
2021  unsigned long val;
2022
2023  if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
2024    return;
2025  if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
2026    return;
2027
2028#define OP2(x) op[target_big_endian ? 1-x : x]
2029#define OP3(x) op[target_big_endian ? 2-x : x]
2030#define OP4(x) op[target_big_endian ? 3-x : x]
2031
2032  op = f->fx_frag->fr_literal + f->fx_where;
2033  val = (unsigned long) * t;
2034
2035  /* Opcode words are always the same endian.  Data words are either
2036     big or little endian.  */
2037
2038  switch (f->fx_r_type)
2039    {
2040    case BFD_RELOC_NONE:
2041      break;
2042
2043    case BFD_RELOC_RX_RELAX:
2044      f->fx_done = 1;
2045      break;
2046
2047    case BFD_RELOC_RX_DIR3U_PCREL:
2048      if (val < 3 || val > 10)
2049	as_bad_where (f->fx_file, f->fx_line,
2050		      _("jump not 3..10 bytes away (is %d)"), (int) val);
2051      op[0] &= 0xf8;
2052      op[0] |= val & 0x07;
2053      break;
2054
2055    case BFD_RELOC_8:
2056    case BFD_RELOC_8_PCREL:
2057    case BFD_RELOC_RX_8U:
2058      op[0] = val;
2059      break;
2060
2061    case BFD_RELOC_16:
2062      OP2(1) = val & 0xff;
2063      OP2(0) = (val >> 8) & 0xff;
2064      break;
2065
2066    case BFD_RELOC_16_PCREL:
2067    case BFD_RELOC_RX_16_OP:
2068    case BFD_RELOC_RX_16U:
2069#if RX_OPCODE_BIG_ENDIAN
2070      op[1] = val & 0xff;
2071      op[0] = (val >> 8) & 0xff;
2072#else
2073      op[0] = val & 0xff;
2074      op[1] = (val >> 8) & 0xff;
2075#endif
2076      break;
2077
2078    case BFD_RELOC_24:
2079      OP3(0) = val & 0xff;
2080      OP3(1) = (val >> 8) & 0xff;
2081      OP3(2) = (val >> 16) & 0xff;
2082      break;
2083
2084    case BFD_RELOC_24_PCREL:
2085    case BFD_RELOC_RX_24_OP:
2086    case BFD_RELOC_RX_24U:
2087#if RX_OPCODE_BIG_ENDIAN
2088      op[2] = val & 0xff;
2089      op[1] = (val >> 8) & 0xff;
2090      op[0] = (val >> 16) & 0xff;
2091#else
2092      op[0] = val & 0xff;
2093      op[1] = (val >> 8) & 0xff;
2094      op[2] = (val >> 16) & 0xff;
2095#endif
2096      break;
2097
2098    case BFD_RELOC_RX_DIFF:
2099      switch (f->fx_size)
2100	{
2101	case 1:
2102	  op[0] = val & 0xff;
2103	  break;
2104	case 2:
2105	  OP2(0) = val & 0xff;
2106	  OP2(1) = (val >> 8) & 0xff;
2107	  break;
2108	case 4:
2109	  OP4(0) = val & 0xff;
2110	  OP4(1) = (val >> 8) & 0xff;
2111	  OP4(2) = (val >> 16) & 0xff;
2112	  OP4(3) = (val >> 24) & 0xff;
2113	  break;
2114	}
2115      break;
2116
2117    case BFD_RELOC_32:
2118      OP4(0) = val & 0xff;
2119      OP4(1) = (val >> 8) & 0xff;
2120      OP4(2) = (val >> 16) & 0xff;
2121      OP4(3) = (val >> 24) & 0xff;
2122      break;
2123
2124    case BFD_RELOC_RX_32_OP:
2125#if RX_OPCODE_BIG_ENDIAN
2126      op[3] = val & 0xff;
2127      op[2] = (val >> 8) & 0xff;
2128      op[1] = (val >> 16) & 0xff;
2129      op[0] = (val >> 24) & 0xff;
2130#else
2131      op[0] = val & 0xff;
2132      op[1] = (val >> 8) & 0xff;
2133      op[2] = (val >> 16) & 0xff;
2134      op[3] = (val >> 24) & 0xff;
2135#endif
2136      break;
2137
2138    case BFD_RELOC_RX_NEG8:
2139      op[0] = - val;
2140      break;
2141
2142    case BFD_RELOC_RX_NEG16:
2143      val = -val;
2144#if RX_OPCODE_BIG_ENDIAN
2145      op[1] = val & 0xff;
2146      op[0] = (val >> 8) & 0xff;
2147#else
2148      op[0] = val & 0xff;
2149      op[1] = (val >> 8) & 0xff;
2150#endif
2151      break;
2152
2153    case BFD_RELOC_RX_NEG24:
2154      val = -val;
2155#if RX_OPCODE_BIG_ENDIAN
2156      op[2] = val & 0xff;
2157      op[1] = (val >> 8) & 0xff;
2158      op[0] = (val >> 16) & 0xff;
2159#else
2160      op[0] = val & 0xff;
2161      op[1] = (val >> 8) & 0xff;
2162      op[2] = (val >> 16) & 0xff;
2163#endif
2164      break;
2165
2166    case BFD_RELOC_RX_NEG32:
2167      val = -val;
2168#if RX_OPCODE_BIG_ENDIAN
2169      op[3] = val & 0xff;
2170      op[2] = (val >> 8) & 0xff;
2171      op[1] = (val >> 16) & 0xff;
2172      op[0] = (val >> 24) & 0xff;
2173#else
2174      op[0] = val & 0xff;
2175      op[1] = (val >> 8) & 0xff;
2176      op[2] = (val >> 16) & 0xff;
2177      op[3] = (val >> 24) & 0xff;
2178#endif
2179      break;
2180
2181    case BFD_RELOC_RX_GPRELL:
2182      val >>= 1;
2183    case BFD_RELOC_RX_GPRELW:
2184      val >>= 1;
2185    case BFD_RELOC_RX_GPRELB:
2186#if RX_OPCODE_BIG_ENDIAN
2187      op[1] = val & 0xff;
2188      op[0] = (val >> 8) & 0xff;
2189#else
2190      op[0] = val & 0xff;
2191      op[1] = (val >> 8) & 0xff;
2192#endif
2193      break;
2194
2195    default:
2196      as_bad (_("Unknown reloc in md_apply_fix: %s"),
2197	      bfd_get_reloc_code_name (f->fx_r_type));
2198      break;
2199    }
2200
2201  if (f->fx_addsy == NULL)
2202    f->fx_done = 1;
2203}
2204
2205arelent **
2206tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
2207{
2208  static arelent * reloc[5];
2209
2210  if (fixp->fx_r_type == BFD_RELOC_NONE)
2211    {
2212      reloc[0] = NULL;
2213      return reloc;
2214    }
2215
2216  if (fixp->fx_subsy
2217      && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
2218    {
2219      fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
2220      fixp->fx_subsy = NULL;
2221    }
2222
2223  reloc[0]		  = (arelent *) xmalloc (sizeof (arelent));
2224  reloc[0]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));
2225  * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2226  reloc[0]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
2227  reloc[0]->addend        = fixp->fx_offset;
2228
2229  /* Certain BFD relocations cannot be translated directly into
2230     a single (non-Red Hat) RX relocation, but instead need
2231     multiple RX relocations - handle them here.  */
2232  switch (fixp->fx_r_type)
2233    {
2234    case BFD_RELOC_RX_DIFF:
2235      reloc[0]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2236
2237      reloc[1]		      = (arelent *) xmalloc (sizeof (arelent));
2238      reloc[1]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));
2239      * reloc[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
2240      reloc[1]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
2241      reloc[1]->addend        = 0;
2242      reloc[1]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2243
2244      reloc[2]		      = (arelent *) xmalloc (sizeof (arelent));
2245      reloc[2]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2246      reloc[2]->addend        = 0;
2247      reloc[2]->sym_ptr_ptr   = reloc[1]->sym_ptr_ptr;
2248      reloc[2]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
2249
2250      reloc[3]		      = (arelent *) xmalloc (sizeof (arelent));
2251      switch (fixp->fx_size)
2252	{
2253	case 1:
2254	  reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS8);
2255	  break;
2256	case 2:
2257	  reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16);
2258	  break;
2259	case 4:
2260	  reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32);
2261	  break;
2262	}
2263      reloc[3]->addend      = 0;
2264      reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2265      reloc[3]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2266
2267      reloc[4] = NULL;
2268      break;
2269
2270    case BFD_RELOC_RX_GPRELL:
2271      reloc[0]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2272
2273      reloc[1]		      = (arelent *) xmalloc (sizeof (arelent));
2274      reloc[1]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));
2275      if (gp_symbol == NULL)
2276	{
2277	  if (symbol_table_frozen)
2278	    {
2279	      symbolS * gp;
2280
2281	      gp = symbol_find ("__gp");
2282	      if (gp == NULL)
2283		as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2284	      else
2285		gp_symbol = symbol_get_bfdsym (gp);
2286	    }
2287	  else
2288	    gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2289	}
2290      * reloc[1]->sym_ptr_ptr = gp_symbol;
2291      reloc[1]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
2292      reloc[1]->addend        = 0;
2293      reloc[1]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2294
2295      reloc[2]		    = (arelent *) xmalloc (sizeof (arelent));
2296      reloc[2]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2297      reloc[2]->addend      = 0;
2298      reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2299      reloc[2]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2300
2301      reloc[3]		    = (arelent *) xmalloc (sizeof (arelent));
2302      reloc[3]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UL);
2303      reloc[3]->addend      = 0;
2304      reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2305      reloc[3]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2306
2307      reloc[4] = NULL;
2308      break;
2309
2310    case BFD_RELOC_RX_GPRELW:
2311      reloc[0]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2312
2313      reloc[1]		      = (arelent *) xmalloc (sizeof (arelent));
2314      reloc[1]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));
2315      if (gp_symbol == NULL)
2316	{
2317	  if (symbol_table_frozen)
2318	    {
2319	      symbolS * gp;
2320
2321	      gp = symbol_find ("__gp");
2322	      if (gp == NULL)
2323		as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2324	      else
2325		gp_symbol = symbol_get_bfdsym (gp);
2326	    }
2327	  else
2328	    gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2329	}
2330      * reloc[1]->sym_ptr_ptr = gp_symbol;
2331      reloc[1]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
2332      reloc[1]->addend        = 0;
2333      reloc[1]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2334
2335      reloc[2]		    = (arelent *) xmalloc (sizeof (arelent));
2336      reloc[2]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2337      reloc[2]->addend      = 0;
2338      reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2339      reloc[2]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2340
2341      reloc[3]		    = (arelent *) xmalloc (sizeof (arelent));
2342      reloc[3]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UW);
2343      reloc[3]->addend      = 0;
2344      reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2345      reloc[3]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2346
2347      reloc[4] = NULL;
2348      break;
2349
2350    case BFD_RELOC_RX_GPRELB:
2351      reloc[0]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2352
2353      reloc[1]		      = (arelent *) xmalloc (sizeof (arelent));
2354      reloc[1]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));
2355      if (gp_symbol == NULL)
2356	{
2357	  if (symbol_table_frozen)
2358	    {
2359	      symbolS * gp;
2360
2361	      gp = symbol_find ("__gp");
2362	      if (gp == NULL)
2363		as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2364	      else
2365		gp_symbol = symbol_get_bfdsym (gp);
2366	    }
2367	  else
2368	    gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2369	}
2370      * reloc[1]->sym_ptr_ptr = gp_symbol;
2371      reloc[1]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
2372      reloc[1]->addend        = 0;
2373      reloc[1]->howto         = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2374
2375      reloc[2]		    = (arelent *) xmalloc (sizeof (arelent));
2376      reloc[2]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2377      reloc[2]->addend      = 0;
2378      reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2379      reloc[2]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2380
2381      reloc[3]		    = (arelent *) xmalloc (sizeof (arelent));
2382      reloc[3]->howto       = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16U);
2383      reloc[3]->addend      = 0;
2384      reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2385      reloc[3]->address     = fixp->fx_frag->fr_address + fixp->fx_where;
2386
2387      reloc[4] = NULL;
2388      break;
2389
2390    default:
2391      reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2392      reloc[1] = NULL;
2393      break;
2394    }
2395
2396  return reloc;
2397}
2398
2399/* Set the ELF specific flags.  */
2400
2401void
2402rx_elf_final_processing (void)
2403{
2404  elf_elfheader (stdoutput)->e_flags |= elf_flags;
2405}
2406
2407/* Scan the current input line for occurances of Renesas
2408   local labels and replace them with the GAS version.  */
2409
2410void
2411rx_start_line (void)
2412{
2413  int in_double_quote = 0;
2414  int in_single_quote = 0;
2415  int done = 0;
2416  char * p = input_line_pointer;
2417
2418  /* Scan the line looking for question marks.  Skip past quote enclosed regions.  */
2419  do
2420    {
2421      switch (*p)
2422	{
2423	case '\n':
2424	case 0:
2425	  done = 1;
2426	  break;
2427
2428	case '"':
2429	  in_double_quote = ! in_double_quote;
2430	  break;
2431
2432	case '\'':
2433	  in_single_quote = ! in_single_quote;
2434	  break;
2435
2436	case '?':
2437	  if (in_double_quote || in_single_quote)
2438	    break;
2439
2440	  if (p[1] == ':')
2441	    *p = '1';
2442	  else if (p[1] == '+')
2443	    {
2444	      p[0] = '1';
2445	      p[1] = 'f';
2446	    }
2447	  else if (p[1] == '-')
2448	    {
2449	      p[0] = '1';
2450	      p[1] = 'b';
2451	    }
2452	  break;
2453
2454	default:
2455	  break;
2456	}
2457
2458      p ++;
2459    }
2460  while (! done);
2461}
2462