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