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