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