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