1 /* tc-rx.c -- Assembler for the Renesas RX
2 Copyright (C) 2008-2018 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
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)
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.
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
22 #include "struc-symbol.h"
23 #include "safe-ctype.h"
24 #include "dwarf2dbg.h"
25 #include "elf/common.h"
28 #include "filenames.h"
33 #define RX_OPCODE_BIG_ENDIAN 0
35 const char comment_chars[] = ";";
36 /* Note that input_file.c hand checks for '#' at the beginning of the
37 first line of the input file. This is because the compiler outputs
38 #NO_APP at the beginning of its output. */
39 const char line_comment_chars[] = "#";
40 const char line_separator_chars[] = "!";
42 const char EXP_CHARS[] = "eE";
43 const char FLT_CHARS[] = "dD";
45 /* ELF flags to set in the output file header. */
46 static int elf_flags = E_FLAG_RX_ABI;
48 bfd_boolean rx_use_conventional_section_names = FALSE;
49 static bfd_boolean rx_use_small_data_limit = FALSE;
51 static bfd_boolean rx_pid_mode = FALSE;
52 static int rx_num_int_regs = 0;
56 enum rx_cpu_types rx_cpu = RX600;
58 static void rx_fetchalign (int ignore ATTRIBUTE_UNUSED);
62 OPTION_BIG = OPTION_MD_BASE,
66 OPTION_CONVENTIONAL_SECTION_NAMES,
67 OPTION_RENESAS_SECTION_NAMES,
68 OPTION_SMALL_DATA_LIMIT,
75 OPTION_DISALLOW_STRING_INSNS,
78 #define RX_SHORTOPTS ""
79 const char * md_shortopts = RX_SHORTOPTS;
81 /* Assembler options. */
82 struct option md_longopts[] =
84 {"mbig-endian-data", no_argument, NULL, OPTION_BIG},
85 {"mlittle-endian-data", no_argument, NULL, OPTION_LITTLE},
86 /* The next two switches are here because the
87 generic parts of the linker testsuite uses them. */
88 {"EB", no_argument, NULL, OPTION_BIG},
89 {"EL", no_argument, NULL, OPTION_LITTLE},
90 {"m32bit-doubles", no_argument, NULL, OPTION_32BIT_DOUBLES},
91 {"m64bit-doubles", no_argument, NULL, OPTION_64BIT_DOUBLES},
92 /* This option is here mainly for the binutils testsuites,
93 as many of their tests assume conventional section naming. */
94 {"muse-conventional-section-names", no_argument, NULL, OPTION_CONVENTIONAL_SECTION_NAMES},
95 {"muse-renesas-section-names", no_argument, NULL, OPTION_RENESAS_SECTION_NAMES},
96 {"msmall-data-limit", no_argument, NULL, OPTION_SMALL_DATA_LIMIT},
97 {"relax", no_argument, NULL, OPTION_RELAX},
98 {"mpid", no_argument, NULL, OPTION_PID},
99 {"mint-register", required_argument, NULL, OPTION_INT_REGS},
100 {"mgcc-abi", no_argument, NULL, OPTION_USES_GCC_ABI},
101 {"mrx-abi", no_argument, NULL, OPTION_USES_RX_ABI},
102 {"mcpu", required_argument, NULL, OPTION_CPU},
103 {"mno-allow-string-insns", no_argument, NULL, OPTION_DISALLOW_STRING_INSNS},
104 {NULL, no_argument, NULL, 0}
106 size_t md_longopts_size = sizeof (md_longopts);
110 const char *cpu_name;
111 enum rx_cpu_types type;
114 struct cpu_type cpu_type_list[] =
124 md_parse_option (int c ATTRIBUTE_UNUSED, const char * arg ATTRIBUTE_UNUSED)
129 target_big_endian = 1;
133 target_big_endian = 0;
136 case OPTION_32BIT_DOUBLES:
137 elf_flags &= ~ E_FLAG_RX_64BIT_DOUBLES;
140 case OPTION_64BIT_DOUBLES:
141 elf_flags |= E_FLAG_RX_64BIT_DOUBLES;
144 case OPTION_CONVENTIONAL_SECTION_NAMES:
145 rx_use_conventional_section_names = TRUE;
148 case OPTION_RENESAS_SECTION_NAMES:
149 rx_use_conventional_section_names = FALSE;
152 case OPTION_SMALL_DATA_LIMIT:
153 rx_use_small_data_limit = TRUE;
162 elf_flags |= E_FLAG_RX_PID;
165 case OPTION_INT_REGS:
166 rx_num_int_regs = atoi (optarg);
169 case OPTION_USES_GCC_ABI:
170 elf_flags &= ~ E_FLAG_RX_ABI;
173 case OPTION_USES_RX_ABI:
174 elf_flags |= E_FLAG_RX_ABI;
180 for (i = 0; i < ARRAY_SIZE (cpu_type_list); i++)
182 if (strcasecmp (arg, cpu_type_list[i].cpu_name) == 0)
184 rx_cpu = cpu_type_list[i].type;
186 elf_flags |= E_FLAG_RX_V2;
190 as_warn (_("unrecognised RX CPU type %s"), arg);
194 case OPTION_DISALLOW_STRING_INSNS:
195 elf_flags |= E_FLAG_RX_SINSNS_SET | E_FLAG_RX_SINSNS_NO;
203 md_show_usage (FILE * stream)
205 fprintf (stream, _(" RX specific command line options:\n"));
206 fprintf (stream, _(" --mbig-endian-data\n"));
207 fprintf (stream, _(" --mlittle-endian-data [default]\n"));
208 fprintf (stream, _(" --m32bit-doubles [default]\n"));
209 fprintf (stream, _(" --m64bit-doubles\n"));
210 fprintf (stream, _(" --muse-conventional-section-names\n"));
211 fprintf (stream, _(" --muse-renesas-section-names [default]\n"));
212 fprintf (stream, _(" --msmall-data-limit\n"));
213 fprintf (stream, _(" --mrelax\n"));
214 fprintf (stream, _(" --mpid\n"));
215 fprintf (stream, _(" --mint-register=<value>\n"));
216 fprintf (stream, _(" --mcpu=<rx100|rx200|rx600|rx610|rxv2>\n"));
217 fprintf (stream, _(" --mno-allow-string-insns"));
221 s_bss (int ignore ATTRIBUTE_UNUSED)
225 temp = get_absolute_expression ();
226 subseg_set (bss_section, (subsegT) temp);
227 demand_empty_rest_of_line ();
231 rx_float_cons (int ignore ATTRIBUTE_UNUSED)
233 if (elf_flags & E_FLAG_RX_64BIT_DOUBLES)
234 return float_cons ('d');
235 return float_cons ('f');
239 rx_strcasestr (const char *string, const char *sub)
245 return (char *)string;
248 strl = strlen (string);
252 /* strncasecmp is in libiberty. */
253 if (strncasecmp (string, sub, subl) == 0)
254 return (char *)string;
263 rx_include (int ignore)
268 const char * current_filename;
276 /* The RX version of the .INCLUDE pseudo-op does not
277 have to have the filename inside double quotes. */
279 if (*input_line_pointer == '"')
281 /* Treat as the normal GAS .include pseudo-op. */
286 /* Get the filename. Spaces are allowed, NUL characters are not. */
287 filename = input_line_pointer;
288 last_char = find_end_of_line (filename, FALSE);
289 input_line_pointer = last_char;
291 while (last_char >= filename && (* last_char == ' ' || * last_char == '\n'))
293 end_char = *(++ last_char);
295 if (last_char == filename)
297 as_bad (_("no filename following .INCLUDE pseudo-op"));
298 * last_char = end_char;
302 current_filename = as_where (NULL);
303 f = XNEWVEC (char, strlen (current_filename) + strlen (filename) + 1);
305 /* Check the filename. If [@]..FILE[@] is found then replace
306 this with the current assembler source filename, stripped
307 of any directory prefixes or extensions. */
308 if ((p = rx_strcasestr (filename, "..file")) != NULL)
312 len = 6; /* strlen ("..file"); */
314 if (p > filename && p[-1] == '@')
320 for (d = c = current_filename; *c; c++)
321 if (IS_DIR_SEPARATOR (* c))
327 sprintf (f, "%.*s%.*s%.*s", (int) (p - filename), filename,
329 (int) (strlen (filename) - ((p + len) - filename)),
333 strcpy (f, filename);
335 /* RX .INCLUDE semantics say that 'filename' is located by:
337 1. If filename is absolute, just try that. Otherwise...
339 2. If the current source file includes a directory component
340 then prepend that to the filename and try. Otherwise...
342 3. Try any directories specified by the -I command line
345 4 .Try a directory specified by the INC100 environment variable. */
347 if (IS_ABSOLUTE_PATH (f))
348 try = fopen (path = f, FOPEN_RT);
351 char * env = getenv ("INC100");
355 len = strlen (current_filename);
356 if ((size_t) include_dir_maxlen > len)
357 len = include_dir_maxlen;
358 if (env && strlen (env) > len)
361 path = XNEWVEC (char, strlen (f) + len + 5);
363 if (current_filename != NULL)
365 for (d = NULL, p = current_filename; *p; p++)
366 if (IS_DIR_SEPARATOR (* p))
371 sprintf (path, "%.*s/%s", (int) (d - current_filename), current_filename,
373 try = fopen (path, FOPEN_RT);
381 for (i = 0; i < include_dir_count; i++)
383 sprintf (path, "%s/%s", include_dirs[i], f);
384 if ((try = fopen (path, FOPEN_RT)) != NULL)
389 if (try == NULL && env != NULL)
391 sprintf (path, "%s/%s", env, f);
392 try = fopen (path, FOPEN_RT);
400 as_bad (_("unable to locate include file: %s"), filename);
406 register_dependency (path);
407 input_scrub_insert_file (path);
410 * last_char = end_char;
414 parse_rx_section (char * name)
418 int attr = SHF_ALLOC | SHF_EXECINSTR;
427 for (p = input_line_pointer; *p && strchr ("\n\t, =", *p) == NULL; p++)
432 if (strcasecmp (input_line_pointer, "ALIGN") == 0)
447 case '2': align = 1; break;
448 case '4': align = 2; break;
449 case '8': align = 3; break;
451 as_bad (_("unrecognised alignment value in .SECTION directive: %s"), p);
452 ignore_rest_of_line ();
460 else if (strcasecmp (input_line_pointer, "CODE") == 0)
461 attr = SHF_ALLOC | SHF_EXECINSTR;
462 else if (strcasecmp (input_line_pointer, "DATA") == 0)
463 attr = SHF_ALLOC | SHF_WRITE;
464 else if (strcasecmp (input_line_pointer, "ROMDATA") == 0)
468 as_bad (_("unknown parameter following .SECTION directive: %s"),
472 input_line_pointer = p + 1;
473 ignore_rest_of_line ();
478 input_line_pointer = p + 1;
480 while (end_char != '\n' && end_char != 0);
482 if ((sec = bfd_get_section_by_name (stdoutput, name)) == NULL)
484 if (strcmp (name, "B") && strcmp (name, "B_1") && strcmp (name, "B_2"))
489 obj_elf_change_section (name, type, 0, attr, 0, NULL, FALSE, FALSE);
491 else /* Try not to redefine a section, especially B_1. */
493 int flags = sec->flags;
495 type = elf_section_type (sec);
497 attr = ((flags & SEC_READONLY) ? 0 : SHF_WRITE)
498 | ((flags & SEC_ALLOC) ? SHF_ALLOC : 0)
499 | ((flags & SEC_CODE) ? SHF_EXECINSTR : 0)
500 | ((flags & SEC_MERGE) ? SHF_MERGE : 0)
501 | ((flags & SEC_STRINGS) ? SHF_STRINGS : 0)
502 | ((flags & SEC_THREAD_LOCAL) ? SHF_TLS : 0);
504 obj_elf_change_section (name, type, 0, attr, 0, NULL, FALSE, FALSE);
507 bfd_set_section_alignment (stdoutput, now_seg, align);
511 rx_section (int ignore)
515 /* The as100 assembler supports a different syntax for the .section
516 pseudo-op. So check for it and handle it here if necessary. */
519 /* Peek past the section name to see if arguments follow. */
520 for (p = input_line_pointer; *p; p++)
521 if (*p == ',' || *p == '\n')
526 int len = p - input_line_pointer;
528 while (ISSPACE (*++p))
531 if (*p != '"' && *p != '#')
533 char *name = xmemdup0 (input_line_pointer, len);
535 input_line_pointer = p;
536 parse_rx_section (name);
541 obj_elf_section (ignore);
545 rx_list (int ignore ATTRIBUTE_UNUSED)
549 if (strncasecmp (input_line_pointer, "OFF", 3))
551 else if (strncasecmp (input_line_pointer, "ON", 2))
554 as_warn (_("expecting either ON or OFF after .list"));
557 /* Like the .rept pseudo op, but supports the
558 use of ..MACREP inside the repeated region. */
561 rx_rept (int ignore ATTRIBUTE_UNUSED)
563 size_t count = get_absolute_expression ();
565 do_repeat_with_expander (count, "MREPEAT", "ENDR", "..MACREP");
568 /* Like cons() accept that strings are allowed. */
575 if (* input_line_pointer == '"')
582 rx_nop (int ignore ATTRIBUTE_UNUSED)
584 ignore_rest_of_line ();
590 as_warn (_("The \".%s\" pseudo-op is not implemented\n"),
591 md_pseudo_table[idx].poc_name);
592 ignore_rest_of_line ();
595 /* The target specific pseudo-ops which we support. */
596 const pseudo_typeS md_pseudo_table[] =
598 /* These are unimplemented. They're listed first so that we can use
599 the poc_value as the index into this array, to get the name of
600 the pseudo. So, keep these (1) first, and (2) in order, with (3)
601 the poc_value's in sequence. */
602 { "btglb", rx_unimp, 0 },
603 { "call", rx_unimp, 1 },
604 { "einsf", rx_unimp, 2 },
605 { "fb", rx_unimp, 3 },
606 { "fbsym", rx_unimp, 4 },
607 { "id", rx_unimp, 5 },
608 { "initsct", rx_unimp, 6 },
609 { "insf", rx_unimp, 7 },
610 { "instr", rx_unimp, 8 },
611 { "lbba", rx_unimp, 9 },
612 { "len", rx_unimp, 10 },
613 { "optj", rx_unimp, 11 },
614 { "rvector", rx_unimp, 12 },
615 { "sb", rx_unimp, 13 },
616 { "sbbit", rx_unimp, 14 },
617 { "sbsym", rx_unimp, 15 },
618 { "sbsym16", rx_unimp, 16 },
620 /* These are the do-nothing pseudos. */
621 { "stk", rx_nop, 0 },
622 /* The manual documents ".stk" but the compiler emits ".stack". */
623 { "stack", rx_nop, 0 },
625 /* These are Renesas as100 assembler pseudo-ops that we do support. */
626 { "addr", rx_cons, 3 },
627 { "align", s_align_bytes, 2 },
628 { "byte", rx_cons, 1 },
629 { "fixed", float_cons, 'f' },
630 { "form", listing_psize, 0 },
631 { "glb", s_globl, 0 },
632 { "include", rx_include, 0 },
633 { "list", rx_list, 0 },
634 { "lword", rx_cons, 4 },
635 { "mrepeat", rx_rept, 0 },
636 { "section", rx_section, 0 },
638 /* FIXME: The following pseudo-ops place their values (and associated
639 label if present) in the data section, regardless of whatever
640 section we are currently in. At the moment this code does not
641 implement that part of the semantics. */
642 { "blka", s_space, 3 },
643 { "blkb", s_space, 1 },
644 { "blkd", s_space, 8 },
645 { "blkf", s_space, 4 },
646 { "blkl", s_space, 4 },
647 { "blkw", s_space, 2 },
649 /* Our "standard" pseudos. */
650 { "double", rx_float_cons, 0 },
652 { "3byte", cons, 3 },
656 { "fetchalign", rx_fetchalign, 0 },
658 /* End of list marker. */
662 static asymbol * gp_symbol;
663 static asymbol * rx_pid_symbol;
665 static symbolS * rx_pidreg_symbol;
666 static symbolS * rx_gpreg_symbol;
671 /* Make the __gp and __pid_base symbols now rather
672 than after the symbol table is frozen. We only do this
673 when supporting small data limits because otherwise we
674 pollute the symbol table. */
676 /* The meta-registers %pidreg and %gpreg depend on what other
677 options are specified. The __rx_*_defined symbols exist so we
678 can .ifdef asm code based on what options were passed to gas,
679 without needing a preprocessor */
683 rx_pid_register = 13 - rx_num_int_regs;
684 rx_pid_symbol = symbol_get_bfdsym (symbol_find_or_make ("__pid_base"));
685 rx_pidreg_symbol = symbol_find_or_make ("__rx_pidreg_defined");
686 S_SET_VALUE (rx_pidreg_symbol, rx_pid_register);
687 S_SET_SEGMENT (rx_pidreg_symbol, absolute_section);
690 if (rx_use_small_data_limit)
693 rx_gp_register = rx_pid_register - 1;
695 rx_gp_register = 13 - rx_num_int_regs;
696 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
697 rx_gpreg_symbol = symbol_find_or_make ("__rx_gpreg_defined");
698 S_SET_VALUE (rx_gpreg_symbol, rx_gp_register);
699 S_SET_SEGMENT (rx_gpreg_symbol, absolute_section);
706 /* These negative numbers are found in rx_bytesT.n_base for non-opcode
708 #define RX_NBASE_FETCHALIGN -1
710 typedef struct rx_bytesT
713 /* If this is negative, it's a special-purpose frag as per the defines above. */
722 char type; /* RXREL_*. */
735 fixS *link_relax_fixP;
740 static rx_bytesT rx_bytes;
741 /* We set n_ops to be "size of next opcode" if the next opcode doesn't relax. */
742 static rx_bytesT *fetchalign_bytes = NULL;
745 rx_fetchalign (int ignore ATTRIBUTE_UNUSED)
750 memset (& rx_bytes, 0, sizeof (rx_bytes));
751 rx_bytes.n_base = RX_NBASE_FETCHALIGN;
753 bytes = frag_more (8);
754 frag_then = frag_now;
755 frag_variant (rs_machine_dependent,
762 frag_then->fr_opcode = bytes;
763 frag_then->fr_subtype = 0;
764 fetchalign_bytes = frag_then->tc_frag_data;
768 rx_relax (int type, int pos)
770 rx_bytes.relax[rx_bytes.n_relax].type = type;
771 rx_bytes.relax[rx_bytes.n_relax].field_pos = pos;
772 rx_bytes.relax[rx_bytes.n_relax].val_ofs = rx_bytes.n_base + rx_bytes.n_ops;
777 rx_linkrelax_dsp (int pos)
782 rx_bytes.link_relax |= RX_RELAXA_DSP4;
785 rx_bytes.link_relax |= RX_RELAXA_DSP6;
788 rx_bytes.link_relax |= RX_RELAXA_DSP14;
794 rx_linkrelax_imm (int pos)
799 rx_bytes.link_relax |= RX_RELAXA_IMM6;
802 rx_bytes.link_relax |= RX_RELAXA_IMM12;
808 rx_linkrelax_branch (void)
810 rx_bytes.link_relax |= RX_RELAXA_BRA;
814 rx_fixup (expressionS exp, int offsetbits, int nbits, int type)
816 rx_bytes.fixups[rx_bytes.n_fixups].exp = exp;
817 rx_bytes.fixups[rx_bytes.n_fixups].offset = offsetbits;
818 rx_bytes.fixups[rx_bytes.n_fixups].nbits = nbits;
819 rx_bytes.fixups[rx_bytes.n_fixups].type = type;
820 rx_bytes.fixups[rx_bytes.n_fixups].reloc = exp.X_md;
821 rx_bytes.n_fixups ++;
824 #define rx_field_fixup(exp, offset, nbits, type) \
825 rx_fixup (exp, offset, nbits, type)
827 #define rx_op_fixup(exp, offset, nbits, type) \
828 rx_fixup (exp, offset + 8 * rx_bytes.n_base, nbits, type)
833 rx_bytes.base[0] = b1;
838 rx_base2 (int b1, int b2)
840 rx_bytes.base[0] = b1;
841 rx_bytes.base[1] = b2;
846 rx_base3 (int b1, int b2, int b3)
848 rx_bytes.base[0] = b1;
849 rx_bytes.base[1] = b2;
850 rx_bytes.base[2] = b3;
855 rx_base4 (int b1, int b2, int b3, int b4)
857 rx_bytes.base[0] = b1;
858 rx_bytes.base[1] = b2;
859 rx_bytes.base[2] = b3;
860 rx_bytes.base[3] = b4;
864 /* This gets complicated when the field spans bytes, because fields
865 are numbered from the MSB of the first byte as zero, and bits are
866 stored LSB towards the LSB of the byte. Thus, a simple four-bit
867 insertion of 12 at position 4 of 0x00 yields: 0x0b. A three-bit
868 insertion of b'MXL at position 7 is like this:
870 - - - - - - - - - - - - - - - -
874 rx_field (int val, int pos, int sz)
881 if (val < 0 || val >= (1 << sz))
882 as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, sz);
887 if (val < -(1 << (sz - 1)) || val >= (1 << (sz - 1)))
888 as_bad (_("Value %d doesn't fit in signed %d-bit field"), val, sz);
891 /* This code points at 'M' in the above example. */
895 while (bitp + sz > 8)
900 svalm = val >> (sz - ssz);
901 svalm = svalm & ((1 << ssz) - 1);
902 svalm = svalm << (8 - bitp - ssz);
903 gas_assert (bytep < rx_bytes.n_base);
904 rx_bytes.base[bytep] |= svalm;
910 valm = val & ((1 << sz) - 1);
911 valm = valm << (8 - bitp - sz);
912 gas_assert (bytep < rx_bytes.n_base);
913 rx_bytes.base[bytep] |= valm;
916 /* Special case of the above, for 3-bit displacements of 2..9. */
919 rx_disp3 (expressionS exp, int pos)
921 rx_field_fixup (exp, pos, 3, RXREL_PCREL);
924 /* Special case of the above, for split 5-bit displacements. Assumes
925 the displacement has been checked with rx_disp5op. */
926 /* ---- -432 1--- 0--- */
929 rx_field5s (expressionS exp)
933 val = exp.X_add_number;
934 rx_bytes.base[0] |= val >> 2;
935 rx_bytes.base[1] |= (val << 6) & 0x80;
936 rx_bytes.base[1] |= (val << 3) & 0x08;
939 /* ---- ---- 4--- 3210 */
942 rx_field5s2 (expressionS exp)
946 val = exp.X_add_number;
947 rx_bytes.base[1] |= (val << 3) & 0x80;
948 rx_bytes.base[1] |= (val ) & 0x0f;
951 #define OP(x) rx_bytes.ops[rx_bytes.n_ops++] = (x)
953 #define F_PRECISION 2
956 rx_op (expressionS exp, int nbytes, int type)
960 if ((exp.X_op == O_constant || exp.X_op == O_big)
961 && type != RXREL_PCREL)
963 if (exp.X_op == O_big)
965 if (exp.X_add_number == -1)
968 char * ip = rx_bytes.ops + rx_bytes.n_ops;
970 gen_to_words (w, F_PRECISION, 8);
971 #if RX_OPCODE_BIG_ENDIAN
986 v = ((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
987 | (generic_bignum[0] & LITTLENUM_MASK);
991 v = exp.X_add_number;
995 #if RX_OPCODE_BIG_ENDIAN
996 OP ((v >> (8 * (nbytes - 1))) & 0xff);
1006 rx_op_fixup (exp, rx_bytes.n_ops * 8, nbytes * 8, type);
1007 memset (rx_bytes.ops + rx_bytes.n_ops, 0, nbytes);
1008 rx_bytes.n_ops += nbytes;
1018 #define APPEND(B, N_B) \
1021 memcpy (bytes + idx, rx_bytes.B, rx_bytes.N_B); \
1022 idx += rx_bytes.N_B; \
1026 rx_frag_init (fragS * fragP)
1028 if (rx_bytes.n_relax || rx_bytes.link_relax || rx_bytes.n_base < 0)
1030 fragP->tc_frag_data = XNEW (rx_bytesT);
1031 memcpy (fragP->tc_frag_data, & rx_bytes, sizeof (rx_bytesT));
1034 fragP->tc_frag_data = 0;
1037 /* Handle the as100's version of the .equ pseudo-op. It has the syntax:
1038 <symbol_name> .equ <expression> */
1041 rx_equ (char * name, char * expression)
1043 char saved_name_end_char;
1047 while (ISSPACE (* name))
1050 for (name_end = name + 1; *name_end; name_end ++)
1051 if (! ISALNUM (* name_end))
1054 saved_name_end_char = * name_end;
1057 saved_ilp = input_line_pointer;
1058 input_line_pointer = expression;
1062 input_line_pointer = saved_ilp;
1063 * name_end = saved_name_end_char;
1066 /* Look for Renesas as100 pseudo-ops that occur after a symbol name
1067 rather than at the start of a line. (eg .EQU or .DEFINE). If one
1068 is found, process it and return TRUE otherwise return FALSE. */
1071 scan_for_infix_rx_pseudo_ops (char * str)
1075 char * dot = strchr (str, '.');
1077 if (dot == NULL || dot == str)
1080 /* A real pseudo-op must be preceded by whitespace. */
1081 if (dot[-1] != ' ' && dot[-1] != '\t')
1084 pseudo_op = dot + 1;
1086 if (!ISALNUM (* pseudo_op))
1089 for (p = pseudo_op + 1; ISALNUM (* p); p++)
1092 if (strncasecmp ("EQU", pseudo_op, p - pseudo_op) == 0)
1094 else if (strncasecmp ("DEFINE", pseudo_op, p - pseudo_op) == 0)
1095 as_warn (_("The .DEFINE pseudo-op is not implemented"));
1096 else if (strncasecmp ("MACRO", pseudo_op, p - pseudo_op) == 0)
1097 as_warn (_("The .MACRO pseudo-op is not implemented"));
1098 else if (strncasecmp ("BTEQU", pseudo_op, p - pseudo_op) == 0)
1099 as_warn (_("The .BTEQU pseudo-op is not implemented."));
1107 md_assemble (char * str)
1112 fragS * frag_then = frag_now;
1115 memset (& rx_bytes, 0, sizeof (rx_bytes));
1117 rx_lex_init (str, str + strlen (str));
1118 if (scan_for_infix_rx_pseudo_ops (str))
1122 /* This simplifies the relaxation code. */
1123 if (rx_bytes.n_relax || rx_bytes.link_relax)
1125 /* We do it this way because we want the frag to have the
1126 rx_bytes in it, which we initialize above. */
1127 bytes = frag_more (12);
1128 frag_then = frag_now;
1129 frag_variant (rs_machine_dependent,
1136 frag_then->fr_opcode = bytes;
1137 frag_then->fr_fix += rx_bytes.n_base + rx_bytes.n_ops;
1138 frag_then->fr_subtype = rx_bytes.n_base + rx_bytes.n_ops;
1142 bytes = frag_more (rx_bytes.n_base + rx_bytes.n_ops);
1143 frag_then = frag_now;
1144 if (fetchalign_bytes)
1145 fetchalign_bytes->n_ops = rx_bytes.n_base + rx_bytes.n_ops;
1148 fetchalign_bytes = NULL;
1150 APPEND (base, n_base);
1151 APPEND (ops, n_ops);
1153 if (rx_bytes.link_relax && rx_bytes.n_fixups)
1157 f = fix_new (frag_then,
1158 (char *) bytes - frag_then->fr_literal,
1161 rx_bytes.link_relax | rx_bytes.n_fixups,
1163 BFD_RELOC_RX_RELAX);
1164 frag_then->tc_frag_data->link_relax_fixP = f;
1167 for (i = 0; i < rx_bytes.n_fixups; i ++)
1169 /* index: [nbytes][type] */
1170 static int reloc_map[5][4] =
1172 { 0, 0, 0, BFD_RELOC_RX_DIR3U_PCREL },
1173 { BFD_RELOC_8, BFD_RELOC_RX_8U, BFD_RELOC_RX_NEG8, BFD_RELOC_8_PCREL },
1174 { BFD_RELOC_RX_16_OP, BFD_RELOC_RX_16U, BFD_RELOC_RX_NEG16, BFD_RELOC_16_PCREL },
1175 { BFD_RELOC_RX_24_OP, BFD_RELOC_RX_24U, BFD_RELOC_RX_NEG24, BFD_RELOC_24_PCREL },
1176 { BFD_RELOC_RX_32_OP, BFD_RELOC_32, BFD_RELOC_RX_NEG32, BFD_RELOC_32_PCREL },
1180 idx = rx_bytes.fixups[i].offset / 8;
1181 rel = reloc_map [rx_bytes.fixups[i].nbits / 8][(int) rx_bytes.fixups[i].type];
1183 if (rx_bytes.fixups[i].reloc)
1184 rel = rx_bytes.fixups[i].reloc;
1186 if (frag_then->tc_frag_data)
1187 exp = & frag_then->tc_frag_data->fixups[i].exp;
1189 exp = & rx_bytes.fixups[i].exp;
1191 f = fix_new_exp (frag_then,
1192 (char *) bytes + idx - frag_then->fr_literal,
1193 rx_bytes.fixups[i].nbits / 8,
1195 rx_bytes.fixups[i].type == RXREL_PCREL ? 1 : 0,
1197 if (frag_then->tc_frag_data)
1198 frag_then->tc_frag_data->fixups[i].fixP = f;
1201 dwarf2_emit_insn (idx);
1209 /* Write a value out to the object file, using the appropriate endianness. */
1212 md_number_to_chars (char * buf, valueT val, int n)
1214 if (target_big_endian)
1215 number_to_chars_bigendian (buf, val, n);
1217 number_to_chars_littleendian (buf, val, n);
1227 { "gp", BFD_RELOC_GPREL16 },
1232 md_operand (expressionS * exp ATTRIBUTE_UNUSED)
1237 for (i = 0; reloc_functions[i].fname; i++)
1239 int flen = strlen (reloc_functions[i].fname);
1241 if (input_line_pointer[0] == '%'
1242 && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
1243 && input_line_pointer[flen + 1] == '(')
1245 reloc = reloc_functions[i].reloc;
1246 input_line_pointer += flen + 2;
1254 if (* input_line_pointer == ')')
1255 input_line_pointer ++;
1261 md_section_align (segT segment, valueT size)
1263 int align = bfd_get_section_alignment (stdoutput, segment);
1264 return ((size + (1 << align) - 1) & -(1 << align));
1268 static unsigned char nop_1[] = { 0x03};
1269 /* MOV.L R0,R0 - 1 cycle */
1270 static unsigned char nop_2[] = { 0xef, 0x00};
1271 /* MAX R0,R0 - 1 cycle */
1272 static unsigned char nop_3[] = { 0xfc, 0x13, 0x00 };
1273 /* MUL #1,R0 - 1 cycle */
1274 static unsigned char nop_4[] = { 0x76, 0x10, 0x01, 0x00 };
1275 /* MUL #1,R0 - 1 cycle */
1276 static unsigned char nop_5[] = { 0x77, 0x10, 0x01, 0x00, 0x00 };
1277 /* MUL #1,R0 - 1 cycle */
1278 static unsigned char nop_6[] = { 0x74, 0x10, 0x01, 0x00, 0x00, 0x00 };
1279 /* MAX 0x80000000,R0 - 1 cycle */
1280 static unsigned char nop_7[] = { 0xFD, 0x70, 0x40, 0x00, 0x00, 0x00, 0x80 };
1282 static unsigned char *nops[] = { NULL, nop_1, nop_2, nop_3, nop_4, nop_5, nop_6, nop_7 };
1283 #define BIGGEST_NOP 7
1285 /* When relaxing, we need to output a reloc for any .align directive
1286 so that we can retain this alignment as we adjust opcode sizes. */
1288 rx_handle_align (fragS * frag)
1290 /* If handling an alignment frag, use an optimal NOP pattern.
1291 Only do this if a fill value has not already been provided.
1292 FIXME: This test fails if the provided fill value is zero. */
1293 if ((frag->fr_type == rs_align
1294 || frag->fr_type == rs_align_code)
1295 && subseg_text_p (now_seg))
1297 int count = (frag->fr_next->fr_address
1300 unsigned char *base = (unsigned char *)frag->fr_literal + frag->fr_fix;
1304 if (count > BIGGEST_NOP)
1312 memcpy (base, nops[count], count);
1313 frag->fr_var = count;
1319 && (frag->fr_type == rs_align
1320 || frag->fr_type == rs_align_code)
1321 && frag->fr_address + frag->fr_fix > 0
1322 && frag->fr_offset > 0
1323 && now_seg != bss_section)
1325 fix_new (frag, frag->fr_fix, 0,
1326 &abs_symbol, RX_RELAXA_ALIGN + frag->fr_offset,
1327 0, BFD_RELOC_RX_RELAX);
1328 /* For the purposes of relaxation, this relocation is attached
1329 to the byte *after* the alignment - i.e. the byte that must
1331 fix_new (frag->fr_next, 0, 0,
1332 &abs_symbol, RX_RELAXA_ELIGN + frag->fr_offset,
1333 0, BFD_RELOC_RX_RELAX);
1338 md_atof (int type, char * litP, int * sizeP)
1340 return ieee_md_atof (type, litP, sizeP, target_big_endian);
1344 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1349 /*----------------------------------------------------------------------*/
1350 /* To recap: we estimate everything based on md_estimate_size, then
1351 adjust based on rx_relax_frag. When it all settles, we call
1352 md_convert frag to update the bytes. The relaxation types and
1353 relocations are in fragP->tc_frag_data, which is a copy of that
1356 Our scheme is as follows: fr_fix has the size of the smallest
1357 opcode (like BRA.S). We store the number of total bytes we need in
1358 fr_subtype. When we're done relaxing, we use fr_subtype and the
1359 existing opcode bytes to figure out what actual opcode we need to
1360 put in there. If the fixup isn't resolvable now, we use the
1363 #define TRACE_RELAX 0
1364 #define tprintf if (TRACE_RELAX) printf
1376 /* We're looking for these types of relaxations:
1379 BRA.B 00101110 dspppppp
1380 BRA.W 00111000 dspppppp pppppppp
1381 BRA.A 00000100 dspppppp pppppppp pppppppp
1384 BEQ.B 00100000 dspppppp
1385 BEQ.W 00111010 dspppppp pppppppp
1388 BNE.B 00100001 dspppppp
1389 BNE.W 00111011 dspppppp pppppppp
1391 BSR.W 00111001 dspppppp pppppppp
1392 BSR.A 00000101 dspppppp pppppppp pppppppp
1394 Bcc.B 0010cond dspppppp
1396 Additionally, we can synthesize longer conditional branches using
1397 pairs of opcodes, one with an inverted conditional (flip LSB):
1399 Bcc.W 0010ncnd 00000110 00111000 dspppppp pppppppp
1400 Bcc.A 0010ncnd 00000111 00000100 dspppppp pppppppp pppppppp
1401 BEQ.A 00011100 00000100 dspppppp pppppppp pppppppp
1402 BNE.A 00010100 00000100 dspppppp pppppppp pppppppp */
1404 /* Given the opcode bytes at OP, figure out which opcode it is and
1405 return the type of opcode. We use this to re-encode the opcode as
1406 a different size later. */
1409 rx_opcode_type (char * op)
1411 unsigned char b = (unsigned char) op[0];
1415 case 0x08: return OT_bra;
1416 case 0x10: return OT_beq;
1417 case 0x18: return OT_bne;
1422 case 0x2e: return OT_bra;
1423 case 0x38: return OT_bra;
1424 case 0x04: return OT_bra;
1426 case 0x20: return OT_beq;
1427 case 0x3a: return OT_beq;
1429 case 0x21: return OT_bne;
1430 case 0x3b: return OT_bne;
1432 case 0x39: return OT_bsr;
1433 case 0x05: return OT_bsr;
1436 if ((b & 0xf0) == 0x20)
1442 /* Returns zero if *addrP has the target address. Else returns nonzero
1443 if we cannot compute the target address yet. */
1446 rx_frag_fix_value (fragS * fragP,
1451 addressT * sym_addr)
1454 rx_bytesT * b = fragP->tc_frag_data;
1455 expressionS * exp = & b->fixups[which].exp;
1457 if (need_diff && exp->X_op != O_subtract)
1460 if (exp->X_add_symbol)
1462 if (S_FORCE_RELOC (exp->X_add_symbol, 1))
1464 if (S_GET_SEGMENT (exp->X_add_symbol) != segment)
1466 addr += S_GET_VALUE (exp->X_add_symbol);
1469 if (exp->X_op_symbol)
1471 if (exp->X_op != O_subtract)
1473 if (S_FORCE_RELOC (exp->X_op_symbol, 1))
1475 if (S_GET_SEGMENT (exp->X_op_symbol) != segment)
1477 addr -= S_GET_VALUE (exp->X_op_symbol);
1481 addr += exp->X_add_number;
1486 /* Estimate how big the opcode is after this relax pass. The return
1487 value is the difference between fr_fix and the actual size. We
1488 compute the total size in rx_relax_frag and store it in fr_subtype,
1489 so we only need to subtract fx_fix and return it. */
1492 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
1497 tprintf ("\033[32m est frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n",
1498 (unsigned long) (fragP->fr_address
1499 + (fragP->fr_opcode - fragP->fr_literal)),
1500 (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
1501 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype);
1503 /* This is the size of the opcode that's accounted for in fr_fix. */
1504 opfixsize = fragP->fr_fix - (fragP->fr_opcode - fragP->fr_literal);
1505 /* This is the size of the opcode that isn't. */
1506 delta = (fragP->fr_subtype - opfixsize);
1508 tprintf (" -> opfixsize %d delta %d\n", opfixsize, delta);
1512 /* Given a frag FRAGP, return the "next" frag that contains an
1513 opcode. Assumes the next opcode is relaxable, and thus rs_machine_dependent. */
1516 rx_next_opcode (fragS *fragP)
1519 fragP = fragP->fr_next;
1520 } while (fragP && fragP->fr_type != rs_machine_dependent);
1524 /* Given the new addresses for this relax pass, figure out how big
1525 each opcode must be. We store the total number of bytes needed in
1526 fr_subtype. The return value is the difference between the size
1527 after the last pass and the size after this pass, so we use the old
1528 fr_subtype to calculate the difference. */
1531 rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
1533 addressT addr0, sym_addr;
1536 int oldsize = fragP->fr_subtype;
1537 int newsize = oldsize;
1539 /* Index of relaxation we care about. */
1542 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",
1543 (unsigned long) (fragP->fr_address
1544 + (fragP->fr_opcode - fragP->fr_literal)),
1545 (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
1546 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype, stretch);
1548 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1550 if (fragP->tc_frag_data->n_base == RX_NBASE_FETCHALIGN)
1552 unsigned int next_size;
1553 if (fragP->fr_next == NULL)
1556 next_size = fragP->tc_frag_data->n_ops;
1559 fragS *n = rx_next_opcode (fragP);
1560 next_size = n->fr_subtype;
1563 fragP->fr_subtype = (8-(mypc & 7)) & 7;
1564 tprintf("subtype %u\n", fragP->fr_subtype);
1565 if (fragP->fr_subtype >= next_size)
1566 fragP->fr_subtype = 0;
1567 tprintf ("\033[34m -> mypc %lu next_size %u new %d old %d delta %d (fetchalign)\033[0m\n",
1568 (unsigned long) (mypc & 7),
1569 next_size, fragP->fr_subtype, oldsize, fragP->fr_subtype-oldsize);
1571 newsize = fragP->fr_subtype;
1573 return newsize - oldsize;
1576 optype = rx_opcode_type (fragP->fr_opcode);
1578 /* In the one case where we have both a disp and imm relaxation, we want
1579 the imm relaxation here. */
1581 if (fragP->tc_frag_data->n_relax > 1
1582 && fragP->tc_frag_data->relax[0].type == RX_RELAX_DISP)
1585 /* Try to get the target address. */
1586 if (rx_frag_fix_value (fragP, segment, ri, & addr0,
1587 fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH,
1590 /* If we don't, we must use the maximum size for the linker.
1591 Note that we don't use synthetically expanded conditionals
1593 switch (fragP->tc_frag_data->relax[ri].type)
1595 case RX_RELAX_BRANCH:
1616 newsize = fragP->tc_frag_data->relax[ri].val_ofs + 4;
1619 fragP->fr_subtype = newsize;
1620 tprintf (" -> new %d old %d delta %d (external)\n", newsize, oldsize, newsize-oldsize);
1621 return newsize - oldsize;
1624 if (sym_addr > mypc)
1627 switch (fragP->tc_frag_data->relax[ri].type)
1629 case RX_RELAX_BRANCH:
1630 tprintf ("branch, addr %08lx pc %08lx disp %ld\n",
1631 (unsigned long) addr0, (unsigned long) mypc,
1632 (long) (addr0 - mypc));
1633 disp = (int) addr0 - (int) mypc;
1638 if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1641 else if (disp >= -32768 && (disp - (oldsize-5)) <= 32767)
1651 if ((disp - (oldsize-1)) >= 3 && (disp - (oldsize-1)) <= 10 && !linkrelax)
1654 else if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1657 else if (disp >= -32768 && (disp - (oldsize-3)) <= 32767)
1667 if ((disp - (oldsize-1)) >= 3 && (disp - (oldsize-1)) <= 10 && !linkrelax)
1670 else if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1673 else if (disp >= -32768 && (disp - (oldsize-3)) <= 32767)
1684 tprintf (" - newsize %d\n", newsize);
1688 tprintf ("other, addr %08lx pc %08lx LI %d OF %d\n",
1689 (unsigned long) addr0, (unsigned long) mypc,
1690 fragP->tc_frag_data->relax[ri].field_pos,
1691 fragP->tc_frag_data->relax[ri].val_ofs);
1693 newsize = fragP->tc_frag_data->relax[ri].val_ofs;
1695 if ((long) addr0 >= -128 && (long) addr0 <= 127)
1697 else if ((long) addr0 >= -32768 && (long) addr0 <= 32767)
1699 else if ((long) addr0 >= -8388608 && (long) addr0 <= 8388607)
1709 if (fragP->tc_frag_data->relax[ri].type == RX_RELAX_BRANCH)
1725 /* This prevents infinite loops in align-heavy sources. */
1726 if (newsize < oldsize)
1728 if (fragP->tc_frag_data->times_shrank > 10
1729 && fragP->tc_frag_data->times_grown > 10)
1731 if (fragP->tc_frag_data->times_shrank < 20)
1732 fragP->tc_frag_data->times_shrank ++;
1734 else if (newsize > oldsize)
1736 if (fragP->tc_frag_data->times_grown < 20)
1737 fragP->tc_frag_data->times_grown ++;
1740 fragP->fr_subtype = newsize;
1741 tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
1742 return newsize - oldsize;
1745 /* This lets us test for the opcode type and the desired size in a
1746 switch statement. */
1747 #define OPCODE(type,size) ((type) * 16 + (size))
1749 /* Given the opcode stored in fr_opcode and the number of bytes we
1750 think we need, encode a new opcode. We stored a pointer to the
1751 fixup for this opcode in the tc_frag_data structure. If we can do
1752 the fixup here, we change the relocation type to "none" (we test
1753 for that in tc_gen_reloc) else we change it to the right type for
1754 the new (biggest) opcode. */
1757 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1758 segT segment ATTRIBUTE_UNUSED,
1759 fragS * fragP ATTRIBUTE_UNUSED)
1761 rx_bytesT * rxb = fragP->tc_frag_data;
1762 addressT addr0, mypc;
1765 bfd_reloc_code_real_type reloc_type;
1766 char * op = fragP->fr_opcode;
1769 int fi = (rxb->n_fixups > 1) ? 1 : 0;
1770 fixS * fix = rxb->fixups[fi].fixP;
1772 tprintf ("\033[31mconvrt frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n",
1773 (unsigned long) (fragP->fr_address
1774 + (fragP->fr_opcode - fragP->fr_literal)),
1775 (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
1776 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type,
1783 printf ("lit 0x%p opc 0x%p", fragP->fr_literal, fragP->fr_opcode);
1784 for (i = 0; i < 10; i++)
1785 printf (" %02x", (unsigned char) (fragP->fr_opcode[i]));
1790 if (fragP->tc_frag_data->n_base == RX_NBASE_FETCHALIGN)
1792 int count = fragP->fr_subtype;
1795 else if (count > BIGGEST_NOP)
1802 memcpy (op, nops[count], count);
1806 /* In the one case where we have both a disp and imm relaxation, we want
1807 the imm relaxation here. */
1809 if (fragP->tc_frag_data->n_relax > 1
1810 && fragP->tc_frag_data->relax[0].type == RX_RELAX_DISP)
1813 /* We used a new frag for this opcode, so the opcode address should
1814 be the frag address. */
1815 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1817 /* Try to get the target address. If we fail here, we just use the
1819 if (rx_frag_fix_value (fragP, segment, 0, & addr0,
1820 fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH, 0))
1822 /* We don't know the target address. */
1829 /* We know the target address, and it's in addr0. */
1830 disp = (int) addr0 - (int) mypc;
1836 reloc_type = BFD_RELOC_NONE;
1839 tprintf ("convert, op is %d, disp %d (%lx-%lx)\n",
1840 rx_opcode_type (fragP->fr_opcode), disp,
1841 (unsigned long) addr0, (unsigned long) mypc);
1842 switch (fragP->tc_frag_data->relax[ri].type)
1844 case RX_RELAX_BRANCH:
1845 switch (OPCODE (rx_opcode_type (fragP->fr_opcode), fragP->fr_subtype))
1847 case OPCODE (OT_bra, 1): /* BRA.S - no change. */
1848 op[0] = 0x08 + (disp & 7);
1850 case OPCODE (OT_bra, 2): /* BRA.B - 8 bit. */
1853 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1856 case OPCODE (OT_bra, 3): /* BRA.W - 16 bit. */
1858 #if RX_OPCODE_BIG_ENDIAN
1859 op[1] = (disp >> 8) & 0xff;
1862 op[2] = (disp >> 8) & 0xff;
1866 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1868 case OPCODE (OT_bra, 4): /* BRA.A - 24 bit. */
1870 #if RX_OPCODE_BIG_ENDIAN
1871 op[1] = (disp >> 16) & 0xff;
1872 op[2] = (disp >> 8) & 0xff;
1875 op[3] = (disp >> 16) & 0xff;
1876 op[2] = (disp >> 8) & 0xff;
1879 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1883 case OPCODE (OT_beq, 1): /* BEQ.S - no change. */
1884 op[0] = 0x10 + (disp & 7);
1886 case OPCODE (OT_beq, 2): /* BEQ.B - 8 bit. */
1890 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1892 case OPCODE (OT_beq, 3): /* BEQ.W - 16 bit. */
1894 #if RX_OPCODE_BIG_ENDIAN
1895 op[1] = (disp >> 8) & 0xff;
1898 op[2] = (disp >> 8) & 0xff;
1901 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1904 case OPCODE (OT_beq, 5): /* BEQ.A - synthetic. */
1905 op[0] = 0x1d; /* bne.s .+5. */
1906 op[1] = 0x04; /* bra.a dsp:24. */
1908 #if RX_OPCODE_BIG_ENDIAN
1909 op[2] = (disp >> 16) & 0xff;
1910 op[3] = (disp >> 8) & 0xff;
1913 op[4] = (disp >> 16) & 0xff;
1914 op[3] = (disp >> 8) & 0xff;
1917 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1921 case OPCODE (OT_bne, 1): /* BNE.S - no change. */
1922 op[0] = 0x18 + (disp & 7);
1924 case OPCODE (OT_bne, 2): /* BNE.B - 8 bit. */
1928 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1930 case OPCODE (OT_bne, 3): /* BNE.W - 16 bit. */
1932 #if RX_OPCODE_BIG_ENDIAN
1933 op[1] = (disp >> 8) & 0xff;
1936 op[2] = (disp >> 8) & 0xff;
1939 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1942 case OPCODE (OT_bne, 5): /* BNE.A - synthetic. */
1943 op[0] = 0x15; /* beq.s .+5. */
1944 op[1] = 0x04; /* bra.a dsp:24. */
1946 #if RX_OPCODE_BIG_ENDIAN
1947 op[2] = (disp >> 16) & 0xff;
1948 op[3] = (disp >> 8) & 0xff;
1951 op[4] = (disp >> 16) & 0xff;
1952 op[3] = (disp >> 8) & 0xff;
1955 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1959 case OPCODE (OT_bsr, 3): /* BSR.W - 16 bit. */
1961 #if RX_OPCODE_BIG_ENDIAN
1962 op[1] = (disp >> 8) & 0xff;
1965 op[2] = (disp >> 8) & 0xff;
1968 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1971 case OPCODE (OT_bsr, 4): /* BSR.A - 24 bit. */
1973 #if RX_OPCODE_BIG_ENDIAN
1974 op[1] = (disp >> 16) & 0xff;
1975 op[2] = (disp >> 8) & 0xff;
1978 op[3] = (disp >> 16) & 0xff;
1979 op[2] = (disp >> 8) & 0xff;
1982 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1986 case OPCODE (OT_bcc, 2): /* Bcond.B - 8 bit. */
1988 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1990 case OPCODE (OT_bcc, 5): /* Bcond.W - synthetic. */
1991 op[0] ^= 1; /* Invert condition. */
1992 op[1] = 5; /* Displacement. */
1995 #if RX_OPCODE_BIG_ENDIAN
1996 op[3] = (disp >> 8) & 0xff;
1999 op[4] = (disp >> 8) & 0xff;
2002 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
2005 case OPCODE (OT_bcc, 6): /* Bcond.S - synthetic. */
2006 op[0] ^= 1; /* Invert condition. */
2007 op[1] = 6; /* Displacement. */
2010 #if RX_OPCODE_BIG_ENDIAN
2011 op[3] = (disp >> 16) & 0xff;
2012 op[4] = (disp >> 8) & 0xff;
2015 op[5] = (disp >> 16) & 0xff;
2016 op[4] = (disp >> 8) & 0xff;
2019 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
2024 /* These are opcodes we'll relax in th linker, later. */
2026 reloc_type = rxb->fixups[ri].fixP->fx_r_type;
2033 int nbytes = fragP->fr_subtype - fragP->tc_frag_data->relax[ri].val_ofs;
2035 char * imm = op + fragP->tc_frag_data->relax[ri].val_ofs;
2042 reloc_type = BFD_RELOC_8;
2046 #if RX_OPCODE_BIG_ENDIAN
2048 imm[0] = addr0 >> 8;
2051 imm[1] = addr0 >> 8;
2053 reloc_type = BFD_RELOC_RX_16_OP;
2057 #if RX_OPCODE_BIG_ENDIAN
2059 imm[1] = addr0 >> 8;
2060 imm[0] = addr0 >> 16;
2063 imm[1] = addr0 >> 8;
2064 imm[2] = addr0 >> 16;
2066 reloc_type = BFD_RELOC_RX_24_OP;
2070 #if RX_OPCODE_BIG_ENDIAN
2072 imm[2] = addr0 >> 8;
2073 imm[1] = addr0 >> 16;
2074 imm[0] = addr0 >> 24;
2077 imm[1] = addr0 >> 8;
2078 imm[2] = addr0 >> 16;
2079 imm[3] = addr0 >> 24;
2081 reloc_type = BFD_RELOC_RX_32_OP;
2084 as_bad (_("invalid immediate size"));
2088 switch (fragP->tc_frag_data->relax[ri].field_pos)
2103 as_bad (_("invalid immediate field position"));
2111 reloc_type = fix->fx_r_type;
2120 fix->fx_r_type = reloc_type;
2121 fix->fx_where += reloc_adjust;
2124 case BFD_RELOC_NONE:
2130 case BFD_RELOC_16_PCREL:
2131 case BFD_RELOC_RX_16_OP:
2134 case BFD_RELOC_24_PCREL:
2135 case BFD_RELOC_RX_24_OP:
2138 case BFD_RELOC_RX_32_OP:
2146 fragP->fr_fix = fragP->fr_subtype + (fragP->fr_opcode - fragP->fr_literal);
2147 tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP->fr_fix,
2148 fragP->fr_subtype, fragP->fr_opcode, fragP->fr_literal);
2151 if (fragP->fr_next != NULL
2152 && ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
2154 as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
2155 (long) fragP->fr_fix,
2156 (long) fragP->fr_address, (long) fragP->fr_next->fr_address);
2162 rx_validate_fix_sub (struct fix * f)
2164 /* We permit the subtraction of two symbols in a few cases. */
2165 /* mov #sym1-sym2, R3 */
2166 if (f->fx_r_type == BFD_RELOC_RX_32_OP)
2168 /* .long sym1-sym2 */
2169 if (f->fx_r_type == BFD_RELOC_RX_DIFF
2171 && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
2177 md_pcrel_from_section (fixS * fixP, segT sec)
2181 if (fixP->fx_addsy != NULL
2182 && (! S_IS_DEFINED (fixP->fx_addsy)
2183 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
2184 /* The symbol is undefined (or is defined but not in this section).
2185 Let the linker figure it out. */
2188 rv = fixP->fx_frag->fr_address + fixP->fx_where;
2189 switch (fixP->fx_r_type)
2191 case BFD_RELOC_RX_DIR3U_PCREL:
2199 rx_cons_fix_new (fragS * frag,
2203 bfd_reloc_code_real_type type)
2211 type = BFD_RELOC_16;
2214 type = BFD_RELOC_24;
2217 type = BFD_RELOC_32;
2220 as_bad (_("unsupported constant size %d\n"), size);
2224 if (exp->X_op == O_subtract && exp->X_op_symbol)
2226 if (size != 4 && size != 2 && size != 1)
2227 as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
2229 type = BFD_RELOC_RX_DIFF;
2232 fix_new_exp (frag, where, (int) size, exp, 0, type);
2236 md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
2237 valueT * t ATTRIBUTE_UNUSED,
2238 segT s ATTRIBUTE_UNUSED)
2240 /* Instruction bytes are always little endian. */
2244 if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
2246 if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
2249 #define OP2(x) op[target_big_endian ? 1-x : x]
2250 #define OP3(x) op[target_big_endian ? 2-x : x]
2251 #define OP4(x) op[target_big_endian ? 3-x : x]
2253 op = f->fx_frag->fr_literal + f->fx_where;
2254 val = (unsigned long) * t;
2256 /* Opcode words are always the same endian. Data words are either
2257 big or little endian. */
2259 switch (f->fx_r_type)
2261 case BFD_RELOC_NONE:
2264 case BFD_RELOC_RX_RELAX:
2268 case BFD_RELOC_RX_DIR3U_PCREL:
2269 if (val < 3 || val > 10)
2270 as_bad_where (f->fx_file, f->fx_line,
2271 _("jump not 3..10 bytes away (is %d)"), (int) val);
2273 op[0] |= val & 0x07;
2277 case BFD_RELOC_8_PCREL:
2278 case BFD_RELOC_RX_8U:
2283 OP2(1) = val & 0xff;
2284 OP2(0) = (val >> 8) & 0xff;
2287 case BFD_RELOC_16_PCREL:
2288 case BFD_RELOC_RX_16_OP:
2289 case BFD_RELOC_RX_16U:
2290 #if RX_OPCODE_BIG_ENDIAN
2292 op[0] = (val >> 8) & 0xff;
2295 op[1] = (val >> 8) & 0xff;
2300 OP3(0) = val & 0xff;
2301 OP3(1) = (val >> 8) & 0xff;
2302 OP3(2) = (val >> 16) & 0xff;
2305 case BFD_RELOC_24_PCREL:
2306 case BFD_RELOC_RX_24_OP:
2307 case BFD_RELOC_RX_24U:
2308 #if RX_OPCODE_BIG_ENDIAN
2310 op[1] = (val >> 8) & 0xff;
2311 op[0] = (val >> 16) & 0xff;
2314 op[1] = (val >> 8) & 0xff;
2315 op[2] = (val >> 16) & 0xff;
2319 case BFD_RELOC_RX_DIFF:
2326 OP2(0) = val & 0xff;
2327 OP2(1) = (val >> 8) & 0xff;
2330 OP4(0) = val & 0xff;
2331 OP4(1) = (val >> 8) & 0xff;
2332 OP4(2) = (val >> 16) & 0xff;
2333 OP4(3) = (val >> 24) & 0xff;
2339 OP4(0) = val & 0xff;
2340 OP4(1) = (val >> 8) & 0xff;
2341 OP4(2) = (val >> 16) & 0xff;
2342 OP4(3) = (val >> 24) & 0xff;
2345 case BFD_RELOC_RX_32_OP:
2346 #if RX_OPCODE_BIG_ENDIAN
2348 op[2] = (val >> 8) & 0xff;
2349 op[1] = (val >> 16) & 0xff;
2350 op[0] = (val >> 24) & 0xff;
2353 op[1] = (val >> 8) & 0xff;
2354 op[2] = (val >> 16) & 0xff;
2355 op[3] = (val >> 24) & 0xff;
2359 case BFD_RELOC_RX_NEG8:
2363 case BFD_RELOC_RX_NEG16:
2365 #if RX_OPCODE_BIG_ENDIAN
2367 op[0] = (val >> 8) & 0xff;
2370 op[1] = (val >> 8) & 0xff;
2374 case BFD_RELOC_RX_NEG24:
2376 #if RX_OPCODE_BIG_ENDIAN
2378 op[1] = (val >> 8) & 0xff;
2379 op[0] = (val >> 16) & 0xff;
2382 op[1] = (val >> 8) & 0xff;
2383 op[2] = (val >> 16) & 0xff;
2387 case BFD_RELOC_RX_NEG32:
2389 #if RX_OPCODE_BIG_ENDIAN
2391 op[2] = (val >> 8) & 0xff;
2392 op[1] = (val >> 16) & 0xff;
2393 op[0] = (val >> 24) & 0xff;
2396 op[1] = (val >> 8) & 0xff;
2397 op[2] = (val >> 16) & 0xff;
2398 op[3] = (val >> 24) & 0xff;
2402 case BFD_RELOC_RX_GPRELL:
2405 case BFD_RELOC_RX_GPRELW:
2408 case BFD_RELOC_RX_GPRELB:
2409 #if RX_OPCODE_BIG_ENDIAN
2411 op[0] = (val >> 8) & 0xff;
2414 op[1] = (val >> 8) & 0xff;
2419 as_bad (_("Unknown reloc in md_apply_fix: %s"),
2420 bfd_get_reloc_code_name (f->fx_r_type));
2424 if (f->fx_addsy == NULL)
2429 tc_gen_reloc (asection * sec ATTRIBUTE_UNUSED, fixS * fixp)
2431 static arelent * reloc[5];
2432 bfd_boolean is_opcode = FALSE;
2434 if (fixp->fx_r_type == BFD_RELOC_NONE)
2441 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
2443 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
2444 fixp->fx_subsy = NULL;
2447 reloc[0] = XNEW (arelent);
2448 reloc[0]->sym_ptr_ptr = XNEW (asymbol *);
2449 * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2450 reloc[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2451 reloc[0]->addend = fixp->fx_offset;
2453 if (fixp->fx_r_type == BFD_RELOC_RX_32_OP
2456 fixp->fx_r_type = BFD_RELOC_RX_DIFF;
2460 is_opcode = sec->flags & SEC_CODE;
2462 /* Certain BFD relocations cannot be translated directly into
2463 a single (non-Red Hat) RX relocation, but instead need
2464 multiple RX relocations - handle them here. */
2465 switch (fixp->fx_r_type)
2467 case BFD_RELOC_RX_DIFF:
2468 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2470 reloc[1] = XNEW (arelent);
2471 reloc[1]->sym_ptr_ptr = XNEW (asymbol *);
2472 * reloc[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
2473 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2474 reloc[1]->addend = 0;
2475 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2477 reloc[2] = XNEW (arelent);
2478 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2479 reloc[2]->addend = 0;
2480 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2481 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2483 reloc[3] = XNEW (arelent);
2484 switch (fixp->fx_size)
2487 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS8);
2490 if (!is_opcode && target_big_endian)
2491 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16_REV);
2493 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UL);
2495 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16);
2498 if (!is_opcode && target_big_endian)
2499 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32_REV);
2501 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32);
2504 reloc[3]->addend = 0;
2505 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2506 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2511 case BFD_RELOC_RX_GPRELL:
2512 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2514 reloc[1] = XNEW (arelent);
2515 reloc[1]->sym_ptr_ptr = XNEW (asymbol *);
2516 if (gp_symbol == NULL)
2518 if (symbol_table_frozen)
2522 gp = symbol_find ("__gp");
2524 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2526 gp_symbol = symbol_get_bfdsym (gp);
2529 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2531 * reloc[1]->sym_ptr_ptr = gp_symbol;
2532 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2533 reloc[1]->addend = 0;
2534 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2536 reloc[2] = XNEW (arelent);
2537 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2538 reloc[2]->addend = 0;
2539 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2540 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2542 reloc[3] = XNEW (arelent);
2543 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UL);
2544 reloc[3]->addend = 0;
2545 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2546 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2551 case BFD_RELOC_RX_GPRELW:
2552 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2554 reloc[1] = XNEW (arelent);
2555 reloc[1]->sym_ptr_ptr = XNEW (asymbol *);
2556 if (gp_symbol == NULL)
2558 if (symbol_table_frozen)
2562 gp = symbol_find ("__gp");
2564 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2566 gp_symbol = symbol_get_bfdsym (gp);
2569 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2571 * reloc[1]->sym_ptr_ptr = gp_symbol;
2572 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2573 reloc[1]->addend = 0;
2574 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2576 reloc[2] = XNEW (arelent);
2577 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2578 reloc[2]->addend = 0;
2579 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2580 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2582 reloc[3] = XNEW (arelent);
2583 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UW);
2584 reloc[3]->addend = 0;
2585 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2586 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2591 case BFD_RELOC_RX_GPRELB:
2592 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2594 reloc[1] = XNEW (arelent);
2595 reloc[1]->sym_ptr_ptr = XNEW (asymbol *);
2596 if (gp_symbol == NULL)
2598 if (symbol_table_frozen)
2602 gp = symbol_find ("__gp");
2604 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2606 gp_symbol = symbol_get_bfdsym (gp);
2609 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2611 * reloc[1]->sym_ptr_ptr = gp_symbol;
2612 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2613 reloc[1]->addend = 0;
2614 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2616 reloc[2] = XNEW (arelent);
2617 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2618 reloc[2]->addend = 0;
2619 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2620 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2622 reloc[3] = XNEW (arelent);
2623 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16U);
2624 reloc[3]->addend = 0;
2625 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2626 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2631 case BFD_RELOC_RX_NEG32:
2632 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2634 reloc[1] = XNEW (arelent);
2635 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_NEG);
2636 reloc[1]->addend = 0;
2637 reloc[1]->sym_ptr_ptr = reloc[0]->sym_ptr_ptr;
2638 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2640 reloc[2] = XNEW (arelent);
2641 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32);
2642 reloc[2]->addend = 0;
2643 reloc[2]->sym_ptr_ptr = reloc[0]->sym_ptr_ptr;
2644 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2650 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2659 rx_note_string_insn_use (void)
2661 if ((elf_flags & E_FLAG_RX_SINSNS_MASK) == (E_FLAG_RX_SINSNS_SET | E_FLAG_RX_SINSNS_NO))
2662 as_bad (_("Use of an RX string instruction detected in a file being assembled without string instruction support"));
2663 elf_flags |= E_FLAG_RX_SINSNS_SET | E_FLAG_RX_SINSNS_YES;
2666 /* Set the ELF specific flags. */
2669 rx_elf_final_processing (void)
2671 elf_elfheader (stdoutput)->e_flags |= elf_flags;
2674 /* Scan the current input line for occurrences of Renesas
2675 local labels and replace them with the GAS version. */
2678 rx_start_line (void)
2680 int in_double_quote = 0;
2681 int in_single_quote = 0;
2683 char * p = input_line_pointer;
2686 /* Scan the line looking for question marks. Skip past quote enclosed regions. */
2697 /* Handle escaped double quote \" inside a string. */
2698 if (prev_char != '\\')
2699 in_double_quote = ! in_double_quote;
2703 in_single_quote = ! in_single_quote;
2707 if (in_double_quote || in_single_quote)
2712 else if (p[1] == '+')
2717 else if (p[1] == '-')