tc-rl78.c revision 1.5 1 1.1 christos /* tc-rl78.c -- Assembler for the Renesas RL78
2 1.5 christos Copyright (C) 2011-2016 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos This file is part of GAS, the GNU Assembler.
5 1.1 christos
6 1.1 christos GAS is free software; you can redistribute it and/or modify
7 1.1 christos it under the terms of the GNU General Public License as published by
8 1.1 christos the Free Software Foundation; either version 3, or (at your option)
9 1.1 christos any later version.
10 1.1 christos
11 1.1 christos GAS is distributed in the hope that it will be useful,
12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.1 christos GNU General Public License for more details.
15 1.1 christos
16 1.1 christos You should have received a copy of the GNU General Public License
17 1.1 christos along with GAS; see the file COPYING. If not, write to the Free
18 1.1 christos Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19 1.1 christos 02110-1301, USA. */
20 1.1 christos
21 1.1 christos #include "as.h"
22 1.1 christos #include "struc-symbol.h"
23 1.1 christos #include "safe-ctype.h"
24 1.1 christos #include "dwarf2dbg.h"
25 1.1 christos #include "libbfd.h"
26 1.1 christos #include "elf/common.h"
27 1.1 christos #include "elf/rl78.h"
28 1.1 christos #include "rl78-defs.h"
29 1.1 christos #include "filenames.h"
30 1.1 christos #include "listing.h"
31 1.1 christos #include "sb.h"
32 1.1 christos #include "macro.h"
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.3 christos /* Use something that isn't going to be needed by any expressions or
40 1.3 christos other syntax. */
41 1.3 christos const char line_separator_chars[] = "@";
42 1.1 christos
43 1.1 christos const char EXP_CHARS[] = "eE";
44 1.1 christos const char FLT_CHARS[] = "dD";
45 1.1 christos
46 1.3 christos /* ELF flags to set in the output file header. */
47 1.3 christos static int elf_flags = 0;
48 1.3 christos
49 1.1 christos /*------------------------------------------------------------------*/
50 1.1 christos
51 1.1 christos char * rl78_lex_start;
52 1.1 christos char * rl78_lex_end;
53 1.1 christos
54 1.1 christos typedef struct rl78_bytesT
55 1.1 christos {
56 1.1 christos char prefix[1];
57 1.1 christos int n_prefix;
58 1.1 christos char base[4];
59 1.1 christos int n_base;
60 1.1 christos char ops[8];
61 1.1 christos int n_ops;
62 1.1 christos struct
63 1.1 christos {
64 1.1 christos expressionS exp;
65 1.1 christos char offset;
66 1.1 christos char nbits;
67 1.1 christos char type; /* RL78REL_*. */
68 1.1 christos int reloc;
69 1.1 christos fixS * fixP;
70 1.1 christos } fixups[2];
71 1.1 christos int n_fixups;
72 1.1 christos struct
73 1.1 christos {
74 1.1 christos char type;
75 1.1 christos char field_pos;
76 1.1 christos char val_ofs;
77 1.1 christos } relax[2];
78 1.1 christos int n_relax;
79 1.1 christos int link_relax;
80 1.1 christos fixS *link_relax_fixP;
81 1.1 christos char times_grown;
82 1.1 christos char times_shrank;
83 1.1 christos } rl78_bytesT;
84 1.1 christos
85 1.1 christos static rl78_bytesT rl78_bytes;
86 1.1 christos
87 1.1 christos void
88 1.3 christos rl78_relax (int type, int pos)
89 1.3 christos {
90 1.3 christos rl78_bytes.relax[rl78_bytes.n_relax].type = type;
91 1.3 christos rl78_bytes.relax[rl78_bytes.n_relax].field_pos = pos;
92 1.3 christos rl78_bytes.relax[rl78_bytes.n_relax].val_ofs = rl78_bytes.n_base + rl78_bytes.n_ops;
93 1.3 christos rl78_bytes.n_relax ++;
94 1.3 christos }
95 1.3 christos
96 1.3 christos void
97 1.1 christos rl78_linkrelax_addr16 (void)
98 1.1 christos {
99 1.1 christos rl78_bytes.link_relax |= RL78_RELAXA_ADDR16;
100 1.1 christos }
101 1.1 christos
102 1.1 christos void
103 1.1 christos rl78_linkrelax_branch (void)
104 1.1 christos {
105 1.5 christos rl78_relax (RL78_RELAX_BRANCH, 0);
106 1.1 christos rl78_bytes.link_relax |= RL78_RELAXA_BRA;
107 1.1 christos }
108 1.1 christos
109 1.1 christos static void
110 1.1 christos rl78_fixup (expressionS exp, int offsetbits, int nbits, int type)
111 1.1 christos {
112 1.1 christos rl78_bytes.fixups[rl78_bytes.n_fixups].exp = exp;
113 1.1 christos rl78_bytes.fixups[rl78_bytes.n_fixups].offset = offsetbits;
114 1.1 christos rl78_bytes.fixups[rl78_bytes.n_fixups].nbits = nbits;
115 1.1 christos rl78_bytes.fixups[rl78_bytes.n_fixups].type = type;
116 1.1 christos rl78_bytes.fixups[rl78_bytes.n_fixups].reloc = exp.X_md;
117 1.1 christos rl78_bytes.n_fixups ++;
118 1.1 christos }
119 1.1 christos
120 1.1 christos #define rl78_field_fixup(exp, offset, nbits, type) \
121 1.1 christos rl78_fixup (exp, offset + 8 * rl78_bytes.n_prefix), nbits, type)
122 1.1 christos
123 1.1 christos #define rl78_op_fixup(exp, offset, nbits, type) \
124 1.1 christos rl78_fixup (exp, offset + 8 * (rl78_bytes.n_prefix + rl78_bytes.n_base), nbits, type)
125 1.1 christos
126 1.1 christos void
127 1.1 christos rl78_prefix (int p)
128 1.1 christos {
129 1.1 christos rl78_bytes.prefix[0] = p;
130 1.1 christos rl78_bytes.n_prefix = 1;
131 1.1 christos }
132 1.1 christos
133 1.1 christos int
134 1.5 christos rl78_has_prefix (void)
135 1.1 christos {
136 1.1 christos return rl78_bytes.n_prefix;
137 1.1 christos }
138 1.1 christos
139 1.1 christos void
140 1.1 christos rl78_base1 (int b1)
141 1.1 christos {
142 1.1 christos rl78_bytes.base[0] = b1;
143 1.1 christos rl78_bytes.n_base = 1;
144 1.1 christos }
145 1.1 christos
146 1.1 christos void
147 1.1 christos rl78_base2 (int b1, int b2)
148 1.1 christos {
149 1.1 christos rl78_bytes.base[0] = b1;
150 1.1 christos rl78_bytes.base[1] = b2;
151 1.1 christos rl78_bytes.n_base = 2;
152 1.1 christos }
153 1.1 christos
154 1.1 christos void
155 1.1 christos rl78_base3 (int b1, int b2, int b3)
156 1.1 christos {
157 1.1 christos rl78_bytes.base[0] = b1;
158 1.1 christos rl78_bytes.base[1] = b2;
159 1.1 christos rl78_bytes.base[2] = b3;
160 1.1 christos rl78_bytes.n_base = 3;
161 1.1 christos }
162 1.1 christos
163 1.1 christos void
164 1.1 christos rl78_base4 (int b1, int b2, int b3, int b4)
165 1.1 christos {
166 1.1 christos rl78_bytes.base[0] = b1;
167 1.1 christos rl78_bytes.base[1] = b2;
168 1.1 christos rl78_bytes.base[2] = b3;
169 1.1 christos rl78_bytes.base[3] = b4;
170 1.1 christos rl78_bytes.n_base = 4;
171 1.1 christos }
172 1.1 christos
173 1.1 christos #define F_PRECISION 2
174 1.1 christos
175 1.1 christos void
176 1.1 christos rl78_op (expressionS exp, int nbytes, int type)
177 1.1 christos {
178 1.1 christos int v = 0;
179 1.1 christos
180 1.1 christos if ((exp.X_op == O_constant || exp.X_op == O_big)
181 1.1 christos && type != RL78REL_PCREL)
182 1.1 christos {
183 1.1 christos if (exp.X_op == O_big && exp.X_add_number <= 0)
184 1.1 christos {
185 1.1 christos LITTLENUM_TYPE w[2];
186 1.1 christos char * ip = rl78_bytes.ops + rl78_bytes.n_ops;
187 1.1 christos
188 1.1 christos gen_to_words (w, F_PRECISION, 8);
189 1.1 christos ip[3] = w[0] >> 8;
190 1.1 christos ip[2] = w[0];
191 1.1 christos ip[1] = w[1] >> 8;
192 1.1 christos ip[0] = w[1];
193 1.1 christos rl78_bytes.n_ops += 4;
194 1.1 christos }
195 1.1 christos else
196 1.1 christos {
197 1.1 christos v = exp.X_add_number;
198 1.1 christos while (nbytes)
199 1.1 christos {
200 1.1 christos rl78_bytes.ops[rl78_bytes.n_ops++] =v & 0xff;
201 1.1 christos v >>= 8;
202 1.1 christos nbytes --;
203 1.1 christos }
204 1.1 christos }
205 1.1 christos }
206 1.1 christos else
207 1.1 christos {
208 1.3 christos if (nbytes > 2
209 1.3 christos && exp.X_md == BFD_RELOC_RL78_CODE)
210 1.3 christos exp.X_md = 0;
211 1.3 christos
212 1.3 christos if (nbytes == 1
213 1.3 christos && (exp.X_md == BFD_RELOC_RL78_LO16
214 1.3 christos || exp.X_md == BFD_RELOC_RL78_HI16))
215 1.3 christos as_bad (_("16-bit relocation used in 8-bit operand"));
216 1.3 christos
217 1.3 christos if (nbytes == 2
218 1.3 christos && exp.X_md == BFD_RELOC_RL78_HI8)
219 1.3 christos as_bad (_("8-bit relocation used in 16-bit operand"));
220 1.3 christos
221 1.1 christos rl78_op_fixup (exp, rl78_bytes.n_ops * 8, nbytes * 8, type);
222 1.1 christos memset (rl78_bytes.ops + rl78_bytes.n_ops, 0, nbytes);
223 1.1 christos rl78_bytes.n_ops += nbytes;
224 1.1 christos }
225 1.1 christos }
226 1.1 christos
227 1.1 christos /* This gets complicated when the field spans bytes, because fields
228 1.1 christos are numbered from the MSB of the first byte as zero, and bits are
229 1.1 christos stored LSB towards the LSB of the byte. Thus, a simple four-bit
230 1.1 christos insertion of 12 at position 4 of 0x00 yields: 0x0b. A three-bit
231 1.1 christos insertion of b'MXL at position 7 is like this:
232 1.1 christos
233 1.1 christos - - - - - - - - - - - - - - - -
234 1.1 christos M X L */
235 1.1 christos
236 1.1 christos void
237 1.1 christos rl78_field (int val, int pos, int sz)
238 1.1 christos {
239 1.1 christos int valm;
240 1.1 christos int bytep, bitp;
241 1.1 christos
242 1.1 christos if (sz > 0)
243 1.1 christos {
244 1.1 christos if (val < 0 || val >= (1 << sz))
245 1.1 christos as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, sz);
246 1.1 christos }
247 1.1 christos else
248 1.1 christos {
249 1.1 christos sz = - sz;
250 1.1 christos if (val < -(1 << (sz - 1)) || val >= (1 << (sz - 1)))
251 1.1 christos as_bad (_("Value %d doesn't fit in signed %d-bit field"), val, sz);
252 1.1 christos }
253 1.1 christos
254 1.1 christos /* This code points at 'M' in the above example. */
255 1.1 christos bytep = pos / 8;
256 1.1 christos bitp = pos % 8;
257 1.1 christos
258 1.1 christos while (bitp + sz > 8)
259 1.1 christos {
260 1.1 christos int ssz = 8 - bitp;
261 1.1 christos int svalm;
262 1.1 christos
263 1.1 christos svalm = val >> (sz - ssz);
264 1.1 christos svalm = svalm & ((1 << ssz) - 1);
265 1.1 christos svalm = svalm << (8 - bitp - ssz);
266 1.1 christos gas_assert (bytep < rl78_bytes.n_base);
267 1.1 christos rl78_bytes.base[bytep] |= svalm;
268 1.1 christos
269 1.1 christos bitp = 0;
270 1.1 christos sz -= ssz;
271 1.1 christos bytep ++;
272 1.1 christos }
273 1.1 christos valm = val & ((1 << sz) - 1);
274 1.1 christos valm = valm << (8 - bitp - sz);
275 1.1 christos gas_assert (bytep < rl78_bytes.n_base);
276 1.1 christos rl78_bytes.base[bytep] |= valm;
277 1.1 christos }
278 1.1 christos
279 1.1 christos /*------------------------------------------------------------------*/
280 1.1 christos
281 1.1 christos enum options
282 1.1 christos {
283 1.1 christos OPTION_RELAX = OPTION_MD_BASE,
284 1.5 christos OPTION_NORELAX,
285 1.3 christos OPTION_G10,
286 1.3 christos OPTION_G13,
287 1.3 christos OPTION_G14,
288 1.3 christos OPTION_32BIT_DOUBLES,
289 1.3 christos OPTION_64BIT_DOUBLES,
290 1.1 christos };
291 1.1 christos
292 1.1 christos #define RL78_SHORTOPTS ""
293 1.1 christos const char * md_shortopts = RL78_SHORTOPTS;
294 1.1 christos
295 1.1 christos /* Assembler options. */
296 1.1 christos struct option md_longopts[] =
297 1.1 christos {
298 1.1 christos {"relax", no_argument, NULL, OPTION_RELAX},
299 1.5 christos {"norelax", no_argument, NULL, OPTION_NORELAX},
300 1.3 christos {"mg10", no_argument, NULL, OPTION_G10},
301 1.3 christos {"mg13", no_argument, NULL, OPTION_G13},
302 1.3 christos {"mg14", no_argument, NULL, OPTION_G14},
303 1.3 christos {"mrl78", no_argument, NULL, OPTION_G14},
304 1.3 christos {"m32bit-doubles", no_argument, NULL, OPTION_32BIT_DOUBLES},
305 1.3 christos {"m64bit-doubles", no_argument, NULL, OPTION_64BIT_DOUBLES},
306 1.1 christos {NULL, no_argument, NULL, 0}
307 1.1 christos };
308 1.1 christos size_t md_longopts_size = sizeof (md_longopts);
309 1.1 christos
310 1.1 christos int
311 1.5 christos md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
312 1.1 christos {
313 1.1 christos switch (c)
314 1.1 christos {
315 1.1 christos case OPTION_RELAX:
316 1.1 christos linkrelax = 1;
317 1.1 christos return 1;
318 1.5 christos case OPTION_NORELAX:
319 1.5 christos linkrelax = 0;
320 1.5 christos return 1;
321 1.1 christos
322 1.3 christos case OPTION_G10:
323 1.3 christos elf_flags &= ~ E_FLAG_RL78_CPU_MASK;
324 1.3 christos elf_flags |= E_FLAG_RL78_G10;
325 1.3 christos return 1;
326 1.3 christos
327 1.3 christos case OPTION_G13:
328 1.3 christos elf_flags &= ~ E_FLAG_RL78_CPU_MASK;
329 1.3 christos elf_flags |= E_FLAG_RL78_G13;
330 1.3 christos return 1;
331 1.3 christos
332 1.3 christos case OPTION_G14:
333 1.3 christos elf_flags &= ~ E_FLAG_RL78_CPU_MASK;
334 1.3 christos elf_flags |= E_FLAG_RL78_G14;
335 1.3 christos return 1;
336 1.3 christos
337 1.3 christos case OPTION_32BIT_DOUBLES:
338 1.3 christos elf_flags &= ~ E_FLAG_RL78_64BIT_DOUBLES;
339 1.3 christos return 1;
340 1.3 christos
341 1.3 christos case OPTION_64BIT_DOUBLES:
342 1.3 christos elf_flags |= E_FLAG_RL78_64BIT_DOUBLES;
343 1.3 christos return 1;
344 1.1 christos }
345 1.1 christos return 0;
346 1.1 christos }
347 1.1 christos
348 1.3 christos int
349 1.3 christos rl78_isa_g10 (void)
350 1.3 christos {
351 1.3 christos return (elf_flags & E_FLAG_RL78_CPU_MASK) == E_FLAG_RL78_G10;
352 1.3 christos }
353 1.3 christos
354 1.3 christos int
355 1.3 christos rl78_isa_g13 (void)
356 1.3 christos {
357 1.3 christos return (elf_flags & E_FLAG_RL78_CPU_MASK) == E_FLAG_RL78_G13;
358 1.3 christos }
359 1.3 christos
360 1.3 christos int
361 1.3 christos rl78_isa_g14 (void)
362 1.3 christos {
363 1.3 christos return (elf_flags & E_FLAG_RL78_CPU_MASK) == E_FLAG_RL78_G14;
364 1.3 christos }
365 1.3 christos
366 1.1 christos void
367 1.3 christos md_show_usage (FILE * stream)
368 1.1 christos {
369 1.3 christos fprintf (stream, _(" RL78 specific command line options:\n"));
370 1.3 christos fprintf (stream, _(" --mrelax Enable link time relaxation\n"));
371 1.3 christos fprintf (stream, _(" --mg10 Enable support for G10 variant\n"));
372 1.3 christos fprintf (stream, _(" --mg13 Selects the G13 core.\n"));
373 1.3 christos fprintf (stream, _(" --mg14 Selects the G14 core [default]\n"));
374 1.3 christos fprintf (stream, _(" --mrl78 Alias for --mg14\n"));
375 1.3 christos fprintf (stream, _(" --m32bit-doubles [default]\n"));
376 1.3 christos fprintf (stream, _(" --m64bit-doubles Source code uses 64-bit doubles\n"));
377 1.1 christos }
378 1.1 christos
379 1.1 christos static void
380 1.1 christos s_bss (int ignore ATTRIBUTE_UNUSED)
381 1.1 christos {
382 1.1 christos int temp;
383 1.1 christos
384 1.1 christos temp = get_absolute_expression ();
385 1.1 christos subseg_set (bss_section, (subsegT) temp);
386 1.1 christos demand_empty_rest_of_line ();
387 1.1 christos }
388 1.1 christos
389 1.3 christos static void
390 1.3 christos rl78_float_cons (int ignore ATTRIBUTE_UNUSED)
391 1.3 christos {
392 1.3 christos if (elf_flags & E_FLAG_RL78_64BIT_DOUBLES)
393 1.3 christos return float_cons ('d');
394 1.3 christos return float_cons ('f');
395 1.3 christos }
396 1.3 christos
397 1.1 christos /* The target specific pseudo-ops which we support. */
398 1.1 christos const pseudo_typeS md_pseudo_table[] =
399 1.1 christos {
400 1.3 christos /* Our "standard" pseudos. */
401 1.3 christos { "double", rl78_float_cons, 'd' },
402 1.3 christos { "bss", s_bss, 0 },
403 1.3 christos { "3byte", cons, 3 },
404 1.3 christos { "int", cons, 4 },
405 1.3 christos { "word", cons, 4 },
406 1.1 christos
407 1.1 christos /* End of list marker. */
408 1.1 christos { NULL, NULL, 0 }
409 1.1 christos };
410 1.1 christos
411 1.3 christos static symbolS * rl78_abs_sym = NULL;
412 1.3 christos
413 1.1 christos void
414 1.1 christos md_begin (void)
415 1.1 christos {
416 1.3 christos rl78_abs_sym = symbol_make ("__rl78_abs__");
417 1.1 christos }
418 1.1 christos
419 1.1 christos void
420 1.1 christos rl78_md_end (void)
421 1.1 christos {
422 1.1 christos }
423 1.1 christos
424 1.3 christos /* Set the ELF specific flags. */
425 1.3 christos void
426 1.3 christos rl78_elf_final_processing (void)
427 1.3 christos {
428 1.3 christos elf_elfheader (stdoutput)->e_flags |= elf_flags;
429 1.3 christos }
430 1.3 christos
431 1.1 christos /* Write a value out to the object file, using the appropriate endianness. */
432 1.1 christos void
433 1.1 christos md_number_to_chars (char * buf, valueT val, int n)
434 1.1 christos {
435 1.1 christos number_to_chars_littleendian (buf, val, n);
436 1.1 christos }
437 1.1 christos
438 1.3 christos static void
439 1.5 christos require_end_of_expr (const char *fname)
440 1.3 christos {
441 1.3 christos while (* input_line_pointer == ' '
442 1.3 christos || * input_line_pointer == '\t')
443 1.3 christos input_line_pointer ++;
444 1.3 christos
445 1.3 christos if (! * input_line_pointer
446 1.3 christos || strchr ("\n\r,", * input_line_pointer)
447 1.3 christos || strchr (comment_chars, * input_line_pointer)
448 1.3 christos || strchr (line_comment_chars, * input_line_pointer)
449 1.3 christos || strchr (line_separator_chars, * input_line_pointer))
450 1.3 christos return;
451 1.3 christos
452 1.3 christos as_bad (_("%%%s() must be outermost term in expression"), fname);
453 1.3 christos }
454 1.3 christos
455 1.1 christos static struct
456 1.1 christos {
457 1.5 christos const char * fname;
458 1.1 christos int reloc;
459 1.1 christos }
460 1.1 christos reloc_functions[] =
461 1.1 christos {
462 1.3 christos { "code", BFD_RELOC_RL78_CODE },
463 1.1 christos { "lo16", BFD_RELOC_RL78_LO16 },
464 1.1 christos { "hi16", BFD_RELOC_RL78_HI16 },
465 1.1 christos { "hi8", BFD_RELOC_RL78_HI8 },
466 1.1 christos { 0, 0 }
467 1.1 christos };
468 1.1 christos
469 1.1 christos void
470 1.1 christos md_operand (expressionS * exp ATTRIBUTE_UNUSED)
471 1.1 christos {
472 1.1 christos int reloc = 0;
473 1.1 christos int i;
474 1.1 christos
475 1.1 christos for (i = 0; reloc_functions[i].fname; i++)
476 1.1 christos {
477 1.1 christos int flen = strlen (reloc_functions[i].fname);
478 1.1 christos
479 1.1 christos if (input_line_pointer[0] == '%'
480 1.1 christos && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
481 1.1 christos && input_line_pointer[flen + 1] == '(')
482 1.1 christos {
483 1.1 christos reloc = reloc_functions[i].reloc;
484 1.1 christos input_line_pointer += flen + 2;
485 1.1 christos break;
486 1.1 christos }
487 1.1 christos }
488 1.1 christos if (reloc == 0)
489 1.1 christos return;
490 1.1 christos
491 1.1 christos expression (exp);
492 1.1 christos if (* input_line_pointer == ')')
493 1.1 christos input_line_pointer ++;
494 1.1 christos
495 1.1 christos exp->X_md = reloc;
496 1.3 christos
497 1.3 christos require_end_of_expr (reloc_functions[i].fname);
498 1.1 christos }
499 1.1 christos
500 1.1 christos void
501 1.1 christos rl78_frag_init (fragS * fragP)
502 1.1 christos {
503 1.1 christos if (rl78_bytes.n_relax || rl78_bytes.link_relax)
504 1.1 christos {
505 1.5 christos fragP->tc_frag_data = XNEW (rl78_bytesT);
506 1.1 christos memcpy (fragP->tc_frag_data, & rl78_bytes, sizeof (rl78_bytesT));
507 1.1 christos }
508 1.1 christos else
509 1.1 christos fragP->tc_frag_data = 0;
510 1.1 christos }
511 1.1 christos
512 1.1 christos /* When relaxing, we need to output a reloc for any .align directive
513 1.1 christos so that we can retain this alignment as we adjust opcode sizes. */
514 1.1 christos void
515 1.1 christos rl78_handle_align (fragS * frag)
516 1.1 christos {
517 1.1 christos if (linkrelax
518 1.1 christos && (frag->fr_type == rs_align
519 1.1 christos || frag->fr_type == rs_align_code)
520 1.1 christos && frag->fr_address + frag->fr_fix > 0
521 1.1 christos && frag->fr_offset > 0
522 1.1 christos && now_seg != bss_section)
523 1.1 christos {
524 1.1 christos fix_new (frag, frag->fr_fix, 0,
525 1.1 christos &abs_symbol, RL78_RELAXA_ALIGN + frag->fr_offset,
526 1.1 christos 0, BFD_RELOC_RL78_RELAX);
527 1.1 christos /* For the purposes of relaxation, this relocation is attached
528 1.1 christos to the byte *after* the alignment - i.e. the byte that must
529 1.1 christos remain aligned. */
530 1.1 christos fix_new (frag->fr_next, 0, 0,
531 1.1 christos &abs_symbol, RL78_RELAXA_ELIGN + frag->fr_offset,
532 1.1 christos 0, BFD_RELOC_RL78_RELAX);
533 1.1 christos }
534 1.1 christos }
535 1.1 christos
536 1.5 christos const char *
537 1.1 christos md_atof (int type, char * litP, int * sizeP)
538 1.1 christos {
539 1.1 christos return ieee_md_atof (type, litP, sizeP, target_big_endian);
540 1.1 christos }
541 1.1 christos
542 1.1 christos symbolS *
543 1.1 christos md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
544 1.1 christos {
545 1.1 christos return NULL;
546 1.1 christos }
547 1.1 christos
548 1.1 christos #define APPEND(B, N_B) \
549 1.1 christos if (rl78_bytes.N_B) \
550 1.1 christos { \
551 1.1 christos memcpy (bytes + idx, rl78_bytes.B, rl78_bytes.N_B); \
552 1.1 christos idx += rl78_bytes.N_B; \
553 1.1 christos }
554 1.1 christos
555 1.1 christos
556 1.1 christos void
557 1.1 christos md_assemble (char * str)
558 1.1 christos {
559 1.1 christos char * bytes;
560 1.1 christos fragS * frag_then = frag_now;
561 1.1 christos int idx = 0;
562 1.1 christos int i;
563 1.1 christos int rel;
564 1.1 christos expressionS *exp;
565 1.1 christos
566 1.1 christos /*printf("\033[32mASM: %s\033[0m\n", str);*/
567 1.1 christos
568 1.1 christos dwarf2_emit_insn (0);
569 1.1 christos
570 1.1 christos memset (& rl78_bytes, 0, sizeof (rl78_bytes));
571 1.1 christos
572 1.1 christos rl78_lex_init (str, str + strlen (str));
573 1.1 christos
574 1.1 christos rl78_parse ();
575 1.1 christos
576 1.1 christos /* This simplifies the relaxation code. */
577 1.3 christos if (rl78_bytes.n_relax || rl78_bytes.link_relax)
578 1.1 christos {
579 1.1 christos int olen = rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops;
580 1.1 christos /* We do it this way because we want the frag to have the
581 1.3 christos rl78_bytes in it, which we initialize above. The extra bytes
582 1.3 christos are for relaxing. */
583 1.3 christos bytes = frag_more (olen + 3);
584 1.1 christos frag_then = frag_now;
585 1.1 christos frag_variant (rs_machine_dependent,
586 1.1 christos olen /* max_chars */,
587 1.1 christos 0 /* var */,
588 1.1 christos olen /* subtype */,
589 1.1 christos 0 /* symbol */,
590 1.1 christos 0 /* offset */,
591 1.1 christos 0 /* opcode */);
592 1.1 christos frag_then->fr_opcode = bytes;
593 1.1 christos frag_then->fr_fix = olen + (bytes - frag_then->fr_literal);
594 1.1 christos frag_then->fr_subtype = olen;
595 1.1 christos frag_then->fr_var = 0;
596 1.1 christos }
597 1.1 christos else
598 1.1 christos {
599 1.1 christos bytes = frag_more (rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops);
600 1.1 christos frag_then = frag_now;
601 1.1 christos }
602 1.1 christos
603 1.1 christos APPEND (prefix, n_prefix);
604 1.1 christos APPEND (base, n_base);
605 1.1 christos APPEND (ops, n_ops);
606 1.1 christos
607 1.1 christos if (rl78_bytes.link_relax)
608 1.1 christos {
609 1.1 christos fixS * f;
610 1.1 christos
611 1.1 christos f = fix_new (frag_then,
612 1.1 christos (char *) bytes - frag_then->fr_literal,
613 1.1 christos 0,
614 1.1 christos abs_section_sym,
615 1.1 christos rl78_bytes.link_relax | rl78_bytes.n_fixups,
616 1.1 christos 0,
617 1.1 christos BFD_RELOC_RL78_RELAX);
618 1.1 christos frag_then->tc_frag_data->link_relax_fixP = f;
619 1.1 christos }
620 1.1 christos
621 1.1 christos for (i = 0; i < rl78_bytes.n_fixups; i ++)
622 1.1 christos {
623 1.1 christos /* index: [nbytes][type] */
624 1.1 christos static int reloc_map[5][4] =
625 1.1 christos {
626 1.1 christos { 0, 0 },
627 1.1 christos { BFD_RELOC_8, BFD_RELOC_8_PCREL },
628 1.1 christos { BFD_RELOC_16, BFD_RELOC_16_PCREL },
629 1.1 christos { BFD_RELOC_24, BFD_RELOC_24_PCREL },
630 1.1 christos { BFD_RELOC_32, BFD_RELOC_32_PCREL },
631 1.1 christos };
632 1.1 christos fixS * f;
633 1.1 christos
634 1.1 christos idx = rl78_bytes.fixups[i].offset / 8;
635 1.1 christos rel = reloc_map [rl78_bytes.fixups[i].nbits / 8][(int) rl78_bytes.fixups[i].type];
636 1.1 christos
637 1.1 christos if (rl78_bytes.fixups[i].reloc)
638 1.1 christos rel = rl78_bytes.fixups[i].reloc;
639 1.1 christos
640 1.1 christos if (frag_then->tc_frag_data)
641 1.1 christos exp = & frag_then->tc_frag_data->fixups[i].exp;
642 1.1 christos else
643 1.1 christos exp = & rl78_bytes.fixups[i].exp;
644 1.1 christos
645 1.1 christos f = fix_new_exp (frag_then,
646 1.1 christos (char *) bytes + idx - frag_then->fr_literal,
647 1.1 christos rl78_bytes.fixups[i].nbits / 8,
648 1.1 christos exp,
649 1.1 christos rl78_bytes.fixups[i].type == RL78REL_PCREL ? 1 : 0,
650 1.1 christos rel);
651 1.1 christos if (frag_then->tc_frag_data)
652 1.1 christos frag_then->tc_frag_data->fixups[i].fixP = f;
653 1.1 christos }
654 1.1 christos }
655 1.1 christos
656 1.1 christos void
657 1.1 christos rl78_cons_fix_new (fragS * frag,
658 1.1 christos int where,
659 1.1 christos int size,
660 1.1 christos expressionS * exp)
661 1.1 christos {
662 1.1 christos bfd_reloc_code_real_type type;
663 1.3 christos fixS *fixP;
664 1.1 christos
665 1.1 christos switch (size)
666 1.1 christos {
667 1.1 christos case 1:
668 1.1 christos type = BFD_RELOC_8;
669 1.1 christos break;
670 1.1 christos case 2:
671 1.1 christos type = BFD_RELOC_16;
672 1.1 christos break;
673 1.1 christos case 3:
674 1.1 christos type = BFD_RELOC_24;
675 1.1 christos break;
676 1.1 christos case 4:
677 1.1 christos type = BFD_RELOC_32;
678 1.1 christos break;
679 1.1 christos default:
680 1.1 christos as_bad (_("unsupported constant size %d\n"), size);
681 1.1 christos return;
682 1.1 christos }
683 1.1 christos
684 1.3 christos switch (exp->X_md)
685 1.3 christos {
686 1.3 christos case BFD_RELOC_RL78_CODE:
687 1.3 christos if (size == 2)
688 1.3 christos type = exp->X_md;
689 1.3 christos break;
690 1.3 christos case BFD_RELOC_RL78_LO16:
691 1.3 christos case BFD_RELOC_RL78_HI16:
692 1.3 christos if (size != 2)
693 1.3 christos {
694 1.3 christos /* Fixups to assembler generated expressions do not use %hi or %lo. */
695 1.3 christos if (frag->fr_file)
696 1.3 christos as_bad (_("%%hi16/%%lo16 only applies to .short or .hword"));
697 1.3 christos }
698 1.3 christos else
699 1.3 christos type = exp->X_md;
700 1.3 christos break;
701 1.3 christos case BFD_RELOC_RL78_HI8:
702 1.3 christos if (size != 1)
703 1.3 christos {
704 1.3 christos /* Fixups to assembler generated expressions do not use %hi or %lo. */
705 1.3 christos if (frag->fr_file)
706 1.3 christos as_bad (_("%%hi8 only applies to .byte"));
707 1.3 christos }
708 1.3 christos else
709 1.3 christos type = exp->X_md;
710 1.3 christos break;
711 1.3 christos default:
712 1.3 christos break;
713 1.3 christos }
714 1.3 christos
715 1.1 christos if (exp->X_op == O_subtract && exp->X_op_symbol)
716 1.1 christos {
717 1.1 christos if (size != 4 && size != 2 && size != 1)
718 1.1 christos as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
719 1.1 christos else
720 1.1 christos type = BFD_RELOC_RL78_DIFF;
721 1.1 christos }
722 1.1 christos
723 1.3 christos fixP = fix_new_exp (frag, where, (int) size, exp, 0, type);
724 1.3 christos switch (exp->X_md)
725 1.3 christos {
726 1.3 christos /* These are intended to have values larger than the container,
727 1.3 christos since the backend puts only the portion we need in it.
728 1.3 christos However, we don't have a backend-specific reloc for them as
729 1.3 christos they're handled with complex relocations. */
730 1.3 christos case BFD_RELOC_RL78_LO16:
731 1.3 christos case BFD_RELOC_RL78_HI16:
732 1.3 christos case BFD_RELOC_RL78_HI8:
733 1.3 christos fixP->fx_no_overflow = 1;
734 1.3 christos break;
735 1.3 christos default:
736 1.3 christos break;
737 1.3 christos }
738 1.3 christos }
739 1.3 christos
740 1.3 christos
741 1.3 christos /*----------------------------------------------------------------------*/
743 1.3 christos /* To recap: we estimate everything based on md_estimate_size, then
744 1.3 christos adjust based on rl78_relax_frag. When it all settles, we call
745 1.3 christos md_convert frag to update the bytes. The relaxation types and
746 1.3 christos relocations are in fragP->tc_frag_data, which is a copy of that
747 1.3 christos rl78_bytes.
748 1.3 christos
749 1.3 christos Our scheme is as follows: fr_fix has the size of the smallest
750 1.3 christos opcode (like BRA.S). We store the number of total bytes we need in
751 1.3 christos fr_subtype. When we're done relaxing, we use fr_subtype and the
752 1.3 christos existing opcode bytes to figure out what actual opcode we need to
753 1.3 christos put in there. If the fixup isn't resolvable now, we use the
754 1.3 christos maximal size. */
755 1.3 christos
756 1.3 christos #define TRACE_RELAX 0
757 1.3 christos #define tprintf if (TRACE_RELAX) printf
758 1.3 christos
759 1.3 christos
760 1.3 christos typedef enum
761 1.3 christos {
762 1.3 christos OT_other,
763 1.3 christos OT_bt,
764 1.3 christos OT_bt_sfr,
765 1.3 christos OT_bt_es,
766 1.5 christos OT_bc,
767 1.5 christos OT_bh,
768 1.5 christos OT_sk,
769 1.5 christos OT_call,
770 1.3 christos OT_br,
771 1.3 christos } op_type_T;
772 1.3 christos
773 1.3 christos /* We're looking for these types of relaxations:
774 1.3 christos
775 1.3 christos BT 00110001 sbit0cc1 addr---- (cc is 10 (BF) or 01 (BT))
776 1.3 christos B~T 00110001 sbit0cc1 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
777 1.3 christos
778 1.3 christos BT sfr 00110001 sbit0cc0 sfr----- addr----
779 1.3 christos BT ES: 00010001 00101110 sbit0cc1 addr----
780 1.3 christos
781 1.3 christos BC 110111cc addr----
782 1.3 christos B~C 110111cc 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
783 1.3 christos
784 1.3 christos BH 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
785 1.3 christos B~H 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
786 1.3 christos */
787 1.3 christos
788 1.3 christos /* Given the opcode bytes at OP, figure out which opcode it is and
789 1.3 christos return the type of opcode. We use this to re-encode the opcode as
790 1.3 christos a different size later. */
791 1.3 christos
792 1.5 christos static op_type_T
793 1.3 christos rl78_opcode_type (char * ops)
794 1.5 christos {
795 1.5 christos unsigned char *op = (unsigned char *)ops;
796 1.3 christos
797 1.3 christos if (op[0] == 0x31
798 1.3 christos && ((op[1] & 0x0f) == 0x05
799 1.3 christos || (op[1] & 0x0f) == 0x03))
800 1.3 christos return OT_bt;
801 1.3 christos
802 1.3 christos if (op[0] == 0x31
803 1.3 christos && ((op[1] & 0x0f) == 0x04
804 1.3 christos || (op[1] & 0x0f) == 0x02))
805 1.3 christos return OT_bt_sfr;
806 1.3 christos
807 1.3 christos if (op[0] == 0x11
808 1.3 christos && op[1] == 0x31
809 1.3 christos && ((op[2] & 0x0f) == 0x05
810 1.3 christos || (op[2] & 0x0f) == 0x03))
811 1.3 christos return OT_bt_es;
812 1.3 christos
813 1.3 christos if ((op[0] & 0xfc) == 0xdc)
814 1.3 christos return OT_bc;
815 1.3 christos
816 1.3 christos if (op[0] == 0x61
817 1.3 christos && (op[1] & 0xef) == 0xc3)
818 1.3 christos return OT_bh;
819 1.5 christos
820 1.5 christos if (op[0] == 0x61
821 1.5 christos && (op[1] & 0xcf) == 0xc8)
822 1.5 christos return OT_sk;
823 1.5 christos
824 1.5 christos if (op[0] == 0x61
825 1.5 christos && (op[1] & 0xef) == 0xe3)
826 1.5 christos return OT_sk;
827 1.5 christos
828 1.5 christos if (op[0] == 0xfc)
829 1.5 christos return OT_call;
830 1.5 christos
831 1.5 christos if ((op[0] & 0xec) == 0xec)
832 1.5 christos return OT_br;
833 1.3 christos
834 1.3 christos return OT_other;
835 1.3 christos }
836 1.3 christos
837 1.3 christos /* Returns zero if *addrP has the target address. Else returns nonzero
838 1.3 christos if we cannot compute the target address yet. */
839 1.3 christos
840 1.3 christos static int
841 1.3 christos rl78_frag_fix_value (fragS * fragP,
842 1.3 christos segT segment,
843 1.3 christos int which,
844 1.3 christos addressT * addrP,
845 1.3 christos int need_diff,
846 1.3 christos addressT * sym_addr)
847 1.3 christos {
848 1.3 christos addressT addr = 0;
849 1.3 christos rl78_bytesT * b = fragP->tc_frag_data;
850 1.3 christos expressionS * exp = & b->fixups[which].exp;
851 1.3 christos
852 1.3 christos if (need_diff && exp->X_op != O_subtract)
853 1.3 christos return 1;
854 1.3 christos
855 1.3 christos if (exp->X_add_symbol)
856 1.3 christos {
857 1.3 christos if (S_FORCE_RELOC (exp->X_add_symbol, 1))
858 1.3 christos return 1;
859 1.3 christos if (S_GET_SEGMENT (exp->X_add_symbol) != segment)
860 1.3 christos return 1;
861 1.3 christos addr += S_GET_VALUE (exp->X_add_symbol);
862 1.3 christos }
863 1.3 christos
864 1.3 christos if (exp->X_op_symbol)
865 1.3 christos {
866 1.3 christos if (exp->X_op != O_subtract)
867 1.3 christos return 1;
868 1.3 christos if (S_FORCE_RELOC (exp->X_op_symbol, 1))
869 1.3 christos return 1;
870 1.3 christos if (S_GET_SEGMENT (exp->X_op_symbol) != segment)
871 1.3 christos return 1;
872 1.3 christos addr -= S_GET_VALUE (exp->X_op_symbol);
873 1.3 christos }
874 1.3 christos if (sym_addr)
875 1.3 christos * sym_addr = addr;
876 1.3 christos addr += exp->X_add_number;
877 1.3 christos * addrP = addr;
878 1.1 christos return 0;
879 1.1 christos }
880 1.3 christos
881 1.3 christos /* Estimate how big the opcode is after this relax pass. The return
882 1.3 christos value is the difference between fr_fix and the actual size. We
883 1.3 christos compute the total size in rl78_relax_frag and store it in fr_subtype,
884 1.3 christos so we only need to subtract fx_fix and return it. */
885 1.1 christos
886 1.1 christos int
887 1.1 christos md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
888 1.3 christos {
889 1.3 christos int opfixsize;
890 1.3 christos int delta;
891 1.3 christos
892 1.3 christos /* This is the size of the opcode that's accounted for in fr_fix. */
893 1.3 christos opfixsize = fragP->fr_fix - (fragP->fr_opcode - fragP->fr_literal);
894 1.3 christos /* This is the size of the opcode that isn't. */
895 1.3 christos delta = (fragP->fr_subtype - opfixsize);
896 1.3 christos
897 1.3 christos tprintf (" -> opfixsize %d delta %d\n", opfixsize, delta);
898 1.3 christos return delta;
899 1.3 christos }
900 1.3 christos
901 1.3 christos /* Given the new addresses for this relax pass, figure out how big
902 1.3 christos each opcode must be. We store the total number of bytes needed in
903 1.3 christos fr_subtype. The return value is the difference between the size
904 1.3 christos after the last pass and the size after this pass, so we use the old
905 1.3 christos fr_subtype to calculate the difference. */
906 1.3 christos
907 1.3 christos int
908 1.3 christos rl78_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
909 1.3 christos {
910 1.3 christos addressT addr0, sym_addr;
911 1.3 christos addressT mypc;
912 1.3 christos int disp;
913 1.3 christos int oldsize = fragP->fr_subtype;
914 1.3 christos int newsize = oldsize;
915 1.3 christos op_type_T optype;
916 1.3 christos int ri;
917 1.3 christos
918 1.3 christos mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
919 1.3 christos
920 1.3 christos /* If we ever get more than one reloc per opcode, this is the one
921 1.3 christos we're relaxing. */
922 1.3 christos ri = 0;
923 1.3 christos
924 1.3 christos optype = rl78_opcode_type (fragP->fr_opcode);
925 1.3 christos /* Try to get the target address. */
926 1.3 christos if (rl78_frag_fix_value (fragP, segment, ri, & addr0,
927 1.3 christos fragP->tc_frag_data->relax[ri].type != RL78_RELAX_BRANCH,
928 1.3 christos & sym_addr))
929 1.5 christos {
930 1.5 christos /* If we don't expect the linker to do relaxing, don't emit
931 1.5 christos expanded opcodes that only the linker will relax. */
932 1.5 christos if (!linkrelax)
933 1.5 christos return newsize - oldsize;
934 1.3 christos
935 1.3 christos /* If we don't, we must use the maximum size for the linker. */
936 1.3 christos switch (fragP->tc_frag_data->relax[ri].type)
937 1.3 christos {
938 1.3 christos case RL78_RELAX_BRANCH:
939 1.3 christos switch (optype)
940 1.3 christos {
941 1.3 christos case OT_bt:
942 1.3 christos newsize = 6;
943 1.3 christos break;
944 1.3 christos case OT_bt_sfr:
945 1.3 christos case OT_bt_es:
946 1.3 christos newsize = 7;
947 1.3 christos break;
948 1.3 christos case OT_bc:
949 1.3 christos newsize = 5;
950 1.3 christos break;
951 1.3 christos case OT_bh:
952 1.3 christos newsize = 6;
953 1.5 christos break;
954 1.5 christos case OT_sk:
955 1.5 christos newsize = 2;
956 1.5 christos break;
957 1.3 christos default:
958 1.3 christos newsize = oldsize;
959 1.3 christos break;
960 1.3 christos }
961 1.3 christos break;
962 1.3 christos
963 1.3 christos }
964 1.3 christos fragP->fr_subtype = newsize;
965 1.3 christos tprintf (" -> new %d old %d delta %d (external)\n", newsize, oldsize, newsize-oldsize);
966 1.3 christos return newsize - oldsize;
967 1.3 christos }
968 1.3 christos
969 1.3 christos if (sym_addr > mypc)
970 1.3 christos addr0 += stretch;
971 1.3 christos
972 1.3 christos switch (fragP->tc_frag_data->relax[ri].type)
973 1.3 christos {
974 1.3 christos case RL78_RELAX_BRANCH:
975 1.3 christos disp = (int) addr0 - (int) mypc;
976 1.3 christos
977 1.3 christos switch (optype)
978 1.3 christos {
979 1.3 christos case OT_bt:
980 1.3 christos if (disp >= -128 && (disp - (oldsize-2)) <= 127)
981 1.3 christos newsize = 3;
982 1.3 christos else
983 1.3 christos newsize = 6;
984 1.3 christos break;
985 1.3 christos case OT_bt_sfr:
986 1.3 christos case OT_bt_es:
987 1.3 christos if (disp >= -128 && (disp - (oldsize-3)) <= 127)
988 1.3 christos newsize = 4;
989 1.3 christos else
990 1.3 christos newsize = 7;
991 1.3 christos break;
992 1.3 christos case OT_bc:
993 1.3 christos if (disp >= -128 && (disp - (oldsize-1)) <= 127)
994 1.3 christos newsize = 2;
995 1.3 christos else
996 1.3 christos newsize = 5;
997 1.3 christos break;
998 1.3 christos case OT_bh:
999 1.3 christos if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1000 1.3 christos newsize = 3;
1001 1.3 christos else
1002 1.3 christos newsize = 6;
1003 1.5 christos break;
1004 1.5 christos case OT_sk:
1005 1.5 christos newsize = 2;
1006 1.5 christos break;
1007 1.3 christos default:
1008 1.3 christos newsize = oldsize;
1009 1.3 christos break;
1010 1.3 christos }
1011 1.3 christos break;
1012 1.3 christos }
1013 1.3 christos
1014 1.3 christos /* This prevents infinite loops in align-heavy sources. */
1015 1.3 christos if (newsize < oldsize)
1016 1.3 christos {
1017 1.3 christos if (fragP->tc_frag_data->times_shrank > 10
1018 1.3 christos && fragP->tc_frag_data->times_grown > 10)
1019 1.3 christos newsize = oldsize;
1020 1.3 christos if (fragP->tc_frag_data->times_shrank < 20)
1021 1.3 christos fragP->tc_frag_data->times_shrank ++;
1022 1.3 christos }
1023 1.3 christos else if (newsize > oldsize)
1024 1.3 christos {
1025 1.3 christos if (fragP->tc_frag_data->times_grown < 20)
1026 1.3 christos fragP->tc_frag_data->times_grown ++;
1027 1.3 christos }
1028 1.3 christos
1029 1.3 christos fragP->fr_subtype = newsize;
1030 1.3 christos tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
1031 1.1 christos return newsize - oldsize;
1032 1.1 christos }
1033 1.3 christos
1034 1.3 christos /* This lets us test for the opcode type and the desired size in a
1035 1.3 christos switch statement. */
1036 1.3 christos #define OPCODE(type,size) ((type) * 16 + (size))
1037 1.3 christos
1038 1.3 christos /* Given the opcode stored in fr_opcode and the number of bytes we
1039 1.3 christos think we need, encode a new opcode. We stored a pointer to the
1040 1.3 christos fixup for this opcode in the tc_frag_data structure. If we can do
1041 1.3 christos the fixup here, we change the relocation type to "none" (we test
1042 1.3 christos for that in tc_gen_reloc) else we change it to the right type for
1043 1.3 christos the new (biggest) opcode. */
1044 1.3 christos
1045 1.3 christos void
1046 1.3 christos md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1047 1.3 christos segT segment ATTRIBUTE_UNUSED,
1048 1.3 christos fragS * fragP ATTRIBUTE_UNUSED)
1049 1.3 christos {
1050 1.3 christos rl78_bytesT * rl78b = fragP->tc_frag_data;
1051 1.3 christos addressT addr0, mypc;
1052 1.3 christos int disp;
1053 1.3 christos int reloc_type, reloc_adjust;
1054 1.3 christos char * op = fragP->fr_opcode;
1055 1.3 christos int keep_reloc = 0;
1056 1.3 christos int ri;
1057 1.3 christos int fi = (rl78b->n_fixups > 1) ? 1 : 0;
1058 1.3 christos fixS * fix = rl78b->fixups[fi].fixP;
1059 1.3 christos
1060 1.3 christos /* If we ever get more than one reloc per opcode, this is the one
1061 1.3 christos we're relaxing. */
1062 1.3 christos ri = 0;
1063 1.3 christos
1064 1.3 christos /* We used a new frag for this opcode, so the opcode address should
1065 1.3 christos be the frag address. */
1066 1.3 christos mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1067 1.3 christos tprintf ("\033[32mmypc: 0x%x\033[0m\n", (int)mypc);
1068 1.3 christos
1069 1.3 christos /* Try to get the target address. If we fail here, we just use the
1070 1.3 christos largest format. */
1071 1.3 christos if (rl78_frag_fix_value (fragP, segment, 0, & addr0,
1072 1.3 christos fragP->tc_frag_data->relax[ri].type != RL78_RELAX_BRANCH, 0))
1073 1.3 christos {
1074 1.3 christos /* We don't know the target address. */
1075 1.3 christos keep_reloc = 1;
1076 1.3 christos addr0 = 0;
1077 1.3 christos disp = 0;
1078 1.3 christos tprintf ("unknown addr ? - %x = ?\n", (int)mypc);
1079 1.3 christos }
1080 1.3 christos else
1081 1.3 christos {
1082 1.3 christos /* We know the target address, and it's in addr0. */
1083 1.3 christos disp = (int) addr0 - (int) mypc;
1084 1.3 christos tprintf ("known addr %x - %x = %d\n", (int)addr0, (int)mypc, disp);
1085 1.3 christos }
1086 1.3 christos
1087 1.3 christos if (linkrelax)
1088 1.3 christos keep_reloc = 1;
1089 1.3 christos
1090 1.3 christos reloc_type = BFD_RELOC_NONE;
1091 1.3 christos reloc_adjust = 0;
1092 1.3 christos
1093 1.3 christos switch (fragP->tc_frag_data->relax[ri].type)
1094 1.3 christos {
1095 1.3 christos case RL78_RELAX_BRANCH:
1096 1.3 christos switch (OPCODE (rl78_opcode_type (fragP->fr_opcode), fragP->fr_subtype))
1097 1.3 christos {
1098 1.3 christos
1099 1.3 christos case OPCODE (OT_bt, 3): /* BT A,$ - no change. */
1100 1.3 christos disp -= 3;
1101 1.5 christos op[2] = disp;
1102 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1103 1.3 christos break;
1104 1.3 christos
1105 1.3 christos case OPCODE (OT_bt, 6): /* BT A,$ - long version. */
1106 1.3 christos disp -= 3;
1107 1.3 christos op[1] ^= 0x06; /* toggle conditional. */
1108 1.3 christos op[2] = 3; /* displacement over long branch. */
1109 1.3 christos disp -= 3;
1110 1.3 christos op[3] = 0xEE; /* BR $!addr20 */
1111 1.3 christos op[4] = disp & 0xff;
1112 1.3 christos op[5] = disp >> 8;
1113 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1114 1.3 christos reloc_adjust = 2;
1115 1.3 christos break;
1116 1.3 christos
1117 1.3 christos case OPCODE (OT_bt_sfr, 4): /* BT PSW,$ - no change. */
1118 1.3 christos disp -= 4;
1119 1.5 christos op[3] = disp;
1120 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1121 1.3 christos break;
1122 1.3 christos
1123 1.3 christos case OPCODE (OT_bt_sfr, 7): /* BT PSW,$ - long version. */
1124 1.3 christos disp -= 4;
1125 1.3 christos op[1] ^= 0x06; /* toggle conditional. */
1126 1.3 christos op[3] = 3; /* displacement over long branch. */
1127 1.3 christos disp -= 3;
1128 1.3 christos op[4] = 0xEE; /* BR $!addr20 */
1129 1.3 christos op[5] = disp & 0xff;
1130 1.3 christos op[6] = disp >> 8;
1131 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1132 1.3 christos reloc_adjust = 2;
1133 1.3 christos break;
1134 1.3 christos
1135 1.3 christos case OPCODE (OT_bt_es, 4): /* BT ES:[HL],$ - no change. */
1136 1.3 christos disp -= 4;
1137 1.5 christos op[3] = disp;
1138 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1139 1.3 christos break;
1140 1.3 christos
1141 1.3 christos case OPCODE (OT_bt_es, 7): /* BT PSW,$ - long version. */
1142 1.3 christos disp -= 4;
1143 1.3 christos op[2] ^= 0x06; /* toggle conditional. */
1144 1.3 christos op[3] = 3; /* displacement over long branch. */
1145 1.3 christos disp -= 3;
1146 1.3 christos op[4] = 0xEE; /* BR $!addr20 */
1147 1.3 christos op[5] = disp & 0xff;
1148 1.3 christos op[6] = disp >> 8;
1149 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1150 1.3 christos reloc_adjust = 2;
1151 1.3 christos break;
1152 1.3 christos
1153 1.3 christos case OPCODE (OT_bc, 2): /* BC $ - no change. */
1154 1.3 christos disp -= 2;
1155 1.5 christos op[1] = disp;
1156 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1157 1.3 christos break;
1158 1.3 christos
1159 1.3 christos case OPCODE (OT_bc, 5): /* BC $ - long version. */
1160 1.3 christos disp -= 2;
1161 1.3 christos op[0] ^= 0x02; /* toggle conditional. */
1162 1.3 christos op[1] = 3;
1163 1.3 christos disp -= 3;
1164 1.3 christos op[2] = 0xEE; /* BR $!addr20 */
1165 1.3 christos op[3] = disp & 0xff;
1166 1.3 christos op[4] = disp >> 8;
1167 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1168 1.3 christos reloc_adjust = 2;
1169 1.3 christos break;
1170 1.3 christos
1171 1.3 christos case OPCODE (OT_bh, 3): /* BH $ - no change. */
1172 1.3 christos disp -= 3;
1173 1.5 christos op[2] = disp;
1174 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1175 1.3 christos break;
1176 1.3 christos
1177 1.3 christos case OPCODE (OT_bh, 6): /* BC $ - long version. */
1178 1.3 christos disp -= 3;
1179 1.3 christos op[1] ^= 0x10; /* toggle conditional. */
1180 1.3 christos op[2] = 3;
1181 1.3 christos disp -= 3;
1182 1.3 christos op[3] = 0xEE; /* BR $!addr20 */
1183 1.3 christos op[4] = disp & 0xff;
1184 1.3 christos op[5] = disp >> 8;
1185 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1186 1.3 christos reloc_adjust = 2;
1187 1.3 christos break;
1188 1.5 christos
1189 1.5 christos case OPCODE (OT_sk, 2): /* SK<cond> - no change */
1190 1.5 christos reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1191 1.5 christos break;
1192 1.3 christos
1193 1.5 christos default:
1194 1.5 christos reloc_type = fix ? fix->fx_r_type : BFD_RELOC_NONE;
1195 1.3 christos break;
1196 1.3 christos }
1197 1.3 christos break;
1198 1.3 christos
1199 1.3 christos default:
1200 1.3 christos if (rl78b->n_fixups)
1201 1.3 christos {
1202 1.3 christos reloc_type = fix->fx_r_type;
1203 1.3 christos reloc_adjust = 0;
1204 1.3 christos }
1205 1.3 christos break;
1206 1.3 christos }
1207 1.3 christos
1208 1.3 christos if (rl78b->n_fixups)
1209 1.3 christos {
1210 1.3 christos
1211 1.3 christos fix->fx_r_type = reloc_type;
1212 1.3 christos fix->fx_where += reloc_adjust;
1213 1.3 christos switch (reloc_type)
1214 1.3 christos {
1215 1.3 christos case BFD_RELOC_NONE:
1216 1.3 christos fix->fx_size = 0;
1217 1.3 christos break;
1218 1.3 christos case BFD_RELOC_8:
1219 1.3 christos fix->fx_size = 1;
1220 1.3 christos break;
1221 1.3 christos case BFD_RELOC_16_PCREL:
1222 1.3 christos fix->fx_size = 2;
1223 1.3 christos break;
1224 1.3 christos }
1225 1.3 christos }
1226 1.3 christos
1227 1.3 christos fragP->fr_fix = fragP->fr_subtype + (fragP->fr_opcode - fragP->fr_literal);
1228 1.3 christos tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP->fr_fix,
1229 1.3 christos fragP->fr_subtype, fragP->fr_opcode, fragP->fr_literal);
1230 1.3 christos fragP->fr_var = 0;
1231 1.3 christos
1232 1.3 christos tprintf ("compare 0x%lx vs 0x%lx - 0x%lx = 0x%lx (%p)\n",
1233 1.3 christos (long)fragP->fr_fix,
1234 1.3 christos (long)fragP->fr_next->fr_address, (long)fragP->fr_address,
1235 1.3 christos (long)(fragP->fr_next->fr_address - fragP->fr_address),
1236 1.3 christos fragP->fr_next);
1237 1.3 christos
1238 1.3 christos if (fragP->fr_next != NULL
1239 1.3 christos && ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
1240 1.3 christos != fragP->fr_fix))
1241 1.3 christos as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
1242 1.3 christos (long) fragP->fr_fix,
1243 1.3 christos (long) fragP->fr_address, (long) fragP->fr_next->fr_address);
1244 1.3 christos }
1245 1.3 christos
1246 1.3 christos /* End of relaxation code.
1247 1.3 christos ----------------------------------------------------------------------*/
1248 1.3 christos
1249 1.1 christos
1251 1.1 christos arelent **
1252 1.1 christos tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
1253 1.1 christos {
1254 1.1 christos static arelent * reloc[8];
1255 1.1 christos int rp;
1256 1.1 christos
1257 1.1 christos if (fixp->fx_r_type == BFD_RELOC_NONE)
1258 1.1 christos {
1259 1.1 christos reloc[0] = NULL;
1260 1.1 christos return reloc;
1261 1.5 christos }
1262 1.5 christos
1263 1.5 christos if (fixp->fx_r_type == BFD_RELOC_RL78_RELAX && !linkrelax)
1264 1.5 christos {
1265 1.5 christos reloc[0] = NULL;
1266 1.5 christos return reloc;
1267 1.1 christos }
1268 1.1 christos
1269 1.1 christos if (fixp->fx_subsy
1270 1.1 christos && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
1271 1.1 christos {
1272 1.1 christos fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
1273 1.1 christos fixp->fx_subsy = NULL;
1274 1.5 christos }
1275 1.5 christos
1276 1.1 christos reloc[0] = XNEW (arelent);
1277 1.1 christos reloc[0]->sym_ptr_ptr = XNEW (asymbol *);
1278 1.1 christos * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1279 1.1 christos reloc[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
1280 1.1 christos reloc[0]->addend = fixp->fx_offset;
1281 1.1 christos
1282 1.1 christos if (fixp->fx_r_type == BFD_RELOC_RL78_32_OP
1283 1.1 christos && fixp->fx_subsy)
1284 1.1 christos {
1285 1.1 christos fixp->fx_r_type = BFD_RELOC_RL78_DIFF;
1286 1.1 christos }
1287 1.5 christos
1288 1.5 christos #define OPX(REL,SYM,ADD) \
1289 1.1 christos reloc[rp] = XNEW (arelent); \
1290 1.1 christos reloc[rp]->sym_ptr_ptr = XNEW (asymbol *); \
1291 1.1 christos reloc[rp]->howto = bfd_reloc_type_lookup (stdoutput, REL); \
1292 1.1 christos reloc[rp]->addend = ADD; \
1293 1.1 christos * reloc[rp]->sym_ptr_ptr = SYM; \
1294 1.1 christos reloc[rp]->address = fixp->fx_frag->fr_address + fixp->fx_where; \
1295 1.3 christos reloc[++rp] = NULL
1296 1.3 christos #define OPSYM(SYM) OPX(BFD_RELOC_RL78_SYM, SYM, 0)
1297 1.3 christos
1298 1.3 christos /* FIXME: We cannot do the normal thing for an immediate value reloc,
1299 1.3 christos ie creating a RL78_SYM reloc in the *ABS* section with an offset
1300 1.3 christos equal to the immediate value we want to store. This fails because
1301 1.3 christos the reloc processing in bfd_perform_relocation and bfd_install_relocation
1302 1.3 christos will short circuit such relocs and never pass them on to the special
1303 1.3 christos reloc processing code. So instead we create a RL78_SYM reloc against
1304 1.3 christos the __rl78_abs__ symbol and arrange for the linker scripts to place
1305 1.3 christos this symbol at address 0. */
1306 1.1 christos #define OPIMM(IMM) OPX (BFD_RELOC_RL78_SYM, symbol_get_bfdsym (rl78_abs_sym), IMM)
1307 1.1 christos
1308 1.1 christos #define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0)
1309 1.1 christos #define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM)
1310 1.1 christos
1311 1.1 christos rp = 1;
1312 1.1 christos
1313 1.1 christos /* Certain BFD relocations cannot be translated directly into
1314 1.1 christos a single (non-Red Hat) RL78 relocation, but instead need
1315 1.1 christos multiple RL78 relocations - handle them here. */
1316 1.1 christos switch (fixp->fx_r_type)
1317 1.1 christos {
1318 1.1 christos case BFD_RELOC_RL78_DIFF:
1319 1.1 christos SYM0 ();
1320 1.1 christos OPSYM (symbol_get_bfdsym (fixp->fx_subsy));
1321 1.1 christos OP(OP_SUBTRACT);
1322 1.1 christos
1323 1.1 christos switch (fixp->fx_size)
1324 1.1 christos {
1325 1.1 christos case 1:
1326 1.1 christos OP(ABS8);
1327 1.1 christos break;
1328 1.1 christos case 2:
1329 1.1 christos OP (ABS16);
1330 1.1 christos break;
1331 1.1 christos case 4:
1332 1.1 christos OP (ABS32);
1333 1.1 christos break;
1334 1.1 christos }
1335 1.1 christos break;
1336 1.1 christos
1337 1.1 christos case BFD_RELOC_RL78_NEG32:
1338 1.1 christos SYM0 ();
1339 1.1 christos OP (OP_NEG);
1340 1.1 christos OP (ABS32);
1341 1.3 christos break;
1342 1.3 christos
1343 1.3 christos case BFD_RELOC_RL78_CODE:
1344 1.3 christos reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_16U);
1345 1.3 christos reloc[1] = NULL;
1346 1.1 christos break;
1347 1.1 christos
1348 1.1 christos case BFD_RELOC_RL78_LO16:
1349 1.1 christos SYM0 ();
1350 1.1 christos OPIMM (0xffff);
1351 1.1 christos OP (OP_AND);
1352 1.1 christos OP (ABS16);
1353 1.1 christos break;
1354 1.1 christos
1355 1.1 christos case BFD_RELOC_RL78_HI16:
1356 1.1 christos SYM0 ();
1357 1.1 christos OPIMM (16);
1358 1.1 christos OP (OP_SHRA);
1359 1.1 christos OP (ABS16);
1360 1.1 christos break;
1361 1.1 christos
1362 1.1 christos case BFD_RELOC_RL78_HI8:
1363 1.1 christos SYM0 ();
1364 1.1 christos OPIMM (16);
1365 1.1 christos OP (OP_SHRA);
1366 1.1 christos OPIMM (0xff);
1367 1.1 christos OP (OP_AND);
1368 1.1 christos OP (ABS8);
1369 1.1 christos break;
1370 1.1 christos
1371 1.1 christos default:
1372 1.1 christos reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1373 1.1 christos reloc[1] = NULL;
1374 1.1 christos break;
1375 1.1 christos }
1376 1.1 christos
1377 1.1 christos return reloc;
1378 1.1 christos }
1379 1.1 christos
1380 1.1 christos int
1381 1.1 christos rl78_validate_fix_sub (struct fix * f)
1382 1.1 christos {
1383 1.1 christos /* We permit the subtraction of two symbols in a few cases. */
1384 1.1 christos /* mov #sym1-sym2, R3 */
1385 1.1 christos if (f->fx_r_type == BFD_RELOC_RL78_32_OP)
1386 1.1 christos return 1;
1387 1.1 christos /* .long sym1-sym2 */
1388 1.1 christos if (f->fx_r_type == BFD_RELOC_RL78_DIFF
1389 1.1 christos && ! f->fx_pcrel
1390 1.1 christos && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
1391 1.1 christos return 1;
1392 1.1 christos return 0;
1393 1.1 christos }
1394 1.1 christos
1395 1.1 christos long
1396 1.1 christos md_pcrel_from_section (fixS * fixP, segT sec)
1397 1.1 christos {
1398 1.1 christos long rv;
1399 1.1 christos
1400 1.1 christos if (fixP->fx_addsy != NULL
1401 1.1 christos && (! S_IS_DEFINED (fixP->fx_addsy)
1402 1.1 christos || S_GET_SEGMENT (fixP->fx_addsy) != sec))
1403 1.1 christos /* The symbol is undefined (or is defined but not in this section).
1404 1.1 christos Let the linker figure it out. */
1405 1.1 christos return 0;
1406 1.1 christos
1407 1.1 christos rv = fixP->fx_frag->fr_address + fixP->fx_where;
1408 1.1 christos switch (fixP->fx_r_type)
1409 1.1 christos {
1410 1.1 christos case BFD_RELOC_8_PCREL:
1411 1.1 christos rv += 1;
1412 1.1 christos break;
1413 1.1 christos case BFD_RELOC_16_PCREL:
1414 1.1 christos rv += 2;
1415 1.1 christos break;
1416 1.1 christos default:
1417 1.1 christos break;
1418 1.1 christos }
1419 1.1 christos return rv;
1420 1.1 christos }
1421 1.1 christos
1422 1.1 christos void
1423 1.1 christos md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
1424 1.1 christos valueT * t ATTRIBUTE_UNUSED,
1425 1.1 christos segT s ATTRIBUTE_UNUSED)
1426 1.1 christos {
1427 1.1 christos char * op;
1428 1.5 christos unsigned long val;
1429 1.5 christos
1430 1.5 christos /* We always defer overflow checks for these to the linker, as it
1431 1.5 christos needs to do PLT stuff. */
1432 1.5 christos if (f->fx_r_type == BFD_RELOC_RL78_CODE)
1433 1.1 christos f->fx_no_overflow = 1;
1434 1.1 christos
1435 1.1 christos if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
1436 1.1 christos return;
1437 1.1 christos if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
1438 1.1 christos return;
1439 1.1 christos
1440 1.1 christos op = f->fx_frag->fr_literal + f->fx_where;
1441 1.5 christos val = (unsigned long) * t;
1442 1.5 christos
1443 1.5 christos if (f->fx_addsy == NULL)
1444 1.1 christos f->fx_done = 1;
1445 1.1 christos
1446 1.1 christos switch (f->fx_r_type)
1447 1.1 christos {
1448 1.1 christos case BFD_RELOC_NONE:
1449 1.1 christos break;
1450 1.5 christos
1451 1.1 christos case BFD_RELOC_RL78_RELAX:
1452 1.1 christos f->fx_done = 0;
1453 1.3 christos break;
1454 1.3 christos
1455 1.3 christos case BFD_RELOC_8_PCREL:
1456 1.3 christos if ((long)val < -128 || (long)val > 127)
1457 1.3 christos as_bad_where (f->fx_file, f->fx_line,
1458 1.3 christos _("value of %ld too large for 8-bit branch"),
1459 1.1 christos val);
1460 1.3 christos /* Fall through. */
1461 1.1 christos case BFD_RELOC_8:
1462 1.1 christos case BFD_RELOC_RL78_SADDR: /* We need to store the 8 LSB, but this works. */
1463 1.1 christos op[0] = val;
1464 1.3 christos break;
1465 1.3 christos
1466 1.3 christos case BFD_RELOC_16_PCREL:
1467 1.3 christos if ((long)val < -32768 || (long)val > 32767)
1468 1.3 christos as_bad_where (f->fx_file, f->fx_line,
1469 1.3 christos _("value of %ld too large for 16-bit branch"),
1470 1.1 christos val);
1471 1.3 christos /* Fall through. */
1472 1.1 christos case BFD_RELOC_16:
1473 1.1 christos case BFD_RELOC_RL78_CODE:
1474 1.1 christos op[0] = val;
1475 1.1 christos op[1] = val >> 8;
1476 1.1 christos break;
1477 1.1 christos
1478 1.1 christos case BFD_RELOC_24:
1479 1.1 christos op[0] = val;
1480 1.1 christos op[1] = val >> 8;
1481 1.1 christos op[2] = val >> 16;
1482 1.1 christos break;
1483 1.1 christos
1484 1.1 christos case BFD_RELOC_32:
1485 1.1 christos op[0] = val;
1486 1.1 christos op[1] = val >> 8;
1487 1.1 christos op[2] = val >> 16;
1488 1.1 christos op[3] = val >> 24;
1489 1.3 christos break;
1490 1.3 christos
1491 1.3 christos case BFD_RELOC_RL78_DIFF:
1492 1.3 christos op[0] = val;
1493 1.3 christos if (f->fx_size > 1)
1494 1.3 christos op[1] = val >> 8;
1495 1.3 christos if (f->fx_size > 2)
1496 1.3 christos op[2] = val >> 16;
1497 1.3 christos if (f->fx_size > 3)
1498 1.3 christos op[3] = val >> 24;
1499 1.3 christos break;
1500 1.3 christos
1501 1.3 christos case BFD_RELOC_RL78_HI8:
1502 1.3 christos val = val >> 16;
1503 1.3 christos op[0] = val;
1504 1.3 christos break;
1505 1.3 christos
1506 1.3 christos case BFD_RELOC_RL78_HI16:
1507 1.3 christos val = val >> 16;
1508 1.3 christos op[0] = val;
1509 1.3 christos op[1] = val >> 8;
1510 1.3 christos break;
1511 1.3 christos
1512 1.3 christos case BFD_RELOC_RL78_LO16:
1513 1.3 christos op[0] = val;
1514 1.3 christos op[1] = val >> 8;
1515 1.1 christos break;
1516 1.1 christos
1517 1.1 christos default:
1518 1.1 christos as_bad (_("Unknown reloc in md_apply_fix: %s"),
1519 1.1 christos bfd_get_reloc_code_name (f->fx_r_type));
1520 1.1 christos break;
1521 1.1 christos }
1522 1.1 christos
1523 1.1 christos }
1524 1.1 christos
1525 1.1 christos valueT
1526 1.1 christos md_section_align (segT segment, valueT size)
1527 1.3 christos {
1528 1.1 christos int align = bfd_get_section_alignment (stdoutput, segment);
1529 return ((size + (1 << align) - 1) & -(1 << align));
1530 }
1531