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