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