ChangeLog rotatation and copyright year update
[deliverable/binutils-gdb.git] / gas / config / tc-rx.c
1 /* tc-rx.c -- Assembler for the Renesas RX
2 Copyright (C) 2008-2015 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 \f
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
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
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
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
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 *
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
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
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
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
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
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
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
562 rx_nop (int ignore ATTRIBUTE_UNUSED)
563 {
564 ignore_rest_of_line ();
565 }
566
567 static void
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
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
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
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
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
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
788 rx_linkrelax_branch (void)
789 {
790 rx_bytes.link_relax |= RX_RELAXA_BRA;
791 }
792
793 static void
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
811 rx_base1 (int b1)
812 {
813 rx_bytes.base[0] = b1;
814 rx_bytes.n_base = 1;
815 }
816
817 void
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
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
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
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
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
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
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
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
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
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
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
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
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
1178 rx_md_end (void)
1179 {
1180 }
1181
1182 /* Write a value out to the object file, using the appropriate endianness. */
1183
1184 void
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
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
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
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 *
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 *
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
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
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
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 *
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
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
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 \f
2131 int
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
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
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
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 **
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
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
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 }
This page took 0.177662 seconds and 4 git commands to generate.