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