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