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