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