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