Prevent the V850 assembler from generating an internal error if it is asked to
[deliverable/binutils-gdb.git] / gas / config / tc-moxie.c
CommitLineData
20135e4c 1/* tc-moxie.c -- Assemble code for moxie
4b95cf5c 2 Copyright (C) 2009-2014 Free Software Foundation, Inc.
20135e4c
NC
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
19 Boston, MA 02110-1301, USA. */
20
21/* Contributed by Anthony Green <green@moxielogic.com>. */
22
23#include "as.h"
24#include "safe-ctype.h"
25#include "opcode/moxie.h"
26#include "elf/moxie.h"
27
28extern const moxie_opc_info_t moxie_opc_info[128];
29
30const char comment_chars[] = "#";
31const char line_separator_chars[] = ";";
32const char line_comment_chars[] = "#";
33
34static int pending_reloc;
35static struct hash_control *opcode_hash_control;
36
37const pseudo_typeS md_pseudo_table[] =
38{
39 {0, 0, 0}
40};
41
42const char FLT_CHARS[] = "rRsSfFdDxXpP";
43const char EXP_CHARS[] = "eE";
44
e202fa84
AG
45static valueT md_chars_to_number (char * buf, int n);
46
47/* Byte order. */
48extern int target_big_endian;
49const char *moxie_target_format = DEFAULT_TARGET_FORMAT;
f865a31d 50
20135e4c
NC
51void
52md_operand (expressionS *op __attribute__((unused)))
53{
54 /* Empty for now. */
55}
56
57/* This function is called once, at assembler startup time. It sets
58 up the hash table with all the opcodes in it, and also initializes
59 some aliases for compatibility with other assemblers. */
60
61void
62md_begin (void)
63{
64 int count;
65 const moxie_opc_info_t *opcode;
66 opcode_hash_control = hash_new ();
67
68 /* Insert names into hash table. */
69 for (count = 0, opcode = moxie_form1_opc_info; count++ < 64; opcode++)
70 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
71
72 for (count = 0, opcode = moxie_form2_opc_info; count++ < 4; opcode++)
73 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
74
f865a31d 75 for (count = 0, opcode = moxie_form3_opc_info; count++ < 10; opcode++)
20135e4c
NC
76 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
77
78 bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
79}
80
81/* Parse an expression and then restore the input line pointer. */
82
83static char *
84parse_exp_save_ilp (char *s, expressionS *op)
85{
86 char *save = input_line_pointer;
87
88 input_line_pointer = s;
89 expression (op);
90 s = input_line_pointer;
91 input_line_pointer = save;
92 return s;
93}
94
95static int
96parse_register_operand (char **ptr)
97{
98 int reg;
99 char *s = *ptr;
100
101 if (*s != '$')
102 {
20203fb9 103 as_bad (_("expecting register"));
20135e4c
NC
104 ignore_rest_of_line ();
105 return -1;
106 }
107 if (s[1] == 'f' && s[2] == 'p')
108 {
109 *ptr += 3;
110 return 0;
111 }
112 if (s[1] == 's' && s[2] == 'p')
113 {
114 *ptr += 3;
115 return 1;
116 }
117 if (s[1] == 'r')
118 {
119 reg = s[2] - '0';
120 if ((reg < 0) || (reg > 9))
121 {
20203fb9 122 as_bad (_("illegal register number"));
20135e4c
NC
123 ignore_rest_of_line ();
124 return -1;
125 }
126 if (reg == 1)
127 {
128 int r2 = s[3] - '0';
129 if ((r2 >= 0) && (r2 <= 3))
130 {
131 reg = 10 + r2;
132 *ptr += 1;
133 }
134 }
135 }
136 else
137 {
20203fb9 138 as_bad (_("illegal register number"));
20135e4c
NC
139 ignore_rest_of_line ();
140 return -1;
141 }
142
143 *ptr += 3;
144
145 return reg + 2;
146}
147
148/* This is the guts of the machine-dependent assembler. STR points to
149 a machine dependent instruction. This function is supposed to emit
150 the frags/bytes it assembles to. */
151
152void
153md_assemble (char *str)
154{
155 char *op_start;
156 char *op_end;
157
158 moxie_opc_info_t *opcode;
159 char *p;
160 char pend;
161
162 unsigned short iword = 0;
163
164 int nlen = 0;
165
166 /* Drop leading whitespace. */
167 while (*str == ' ')
168 str++;
169
170 /* Find the op code end. */
171 op_start = str;
172 for (op_end = str;
173 *op_end && !is_end_of_line[*op_end & 0xff] && *op_end != ' ';
174 op_end++)
175 nlen++;
176
177 pend = *op_end;
178 *op_end = 0;
179
180 if (nlen == 0)
181 as_bad (_("can't find opcode "));
182 opcode = (moxie_opc_info_t *) hash_find (opcode_hash_control, op_start);
183 *op_end = pend;
184
185 if (opcode == NULL)
186 {
187 as_bad (_("unknown opcode %s"), op_start);
188 return;
189 }
190
191 p = frag_more (2);
192
193 switch (opcode->itype)
194 {
195 case MOXIE_F2_A8V:
196 iword = (1<<15) | (opcode->opcode << 12);
197 while (ISSPACE (*op_end))
198 op_end++;
199 {
200 expressionS arg;
201 int reg;
202 reg = parse_register_operand (&op_end);
203 iword += (reg << 8);
204 if (*op_end != ',')
2cbd2211 205 as_warn (_("expecting comma delimited register operands"));
20135e4c
NC
206 op_end++;
207 op_end = parse_exp_save_ilp (op_end, &arg);
208 fix_new_exp (frag_now,
e202fa84 209 ((p + (target_big_endian ? 1 : 0)) - frag_now->fr_literal),
20135e4c
NC
210 1,
211 &arg,
212 0,
213 BFD_RELOC_8);
214 }
215 break;
216 case MOXIE_F1_AB:
217 iword = opcode->opcode << 8;
218 while (ISSPACE (*op_end))
219 op_end++;
220 {
221 int dest, src;
222 dest = parse_register_operand (&op_end);
223 if (*op_end != ',')
2cbd2211 224 as_warn (_("expecting comma delimited register operands"));
20135e4c
NC
225 op_end++;
226 src = parse_register_operand (&op_end);
227 iword += (dest << 4) + src;
228 while (ISSPACE (*op_end))
229 op_end++;
230 if (*op_end != 0)
20203fb9 231 as_warn (_("extra stuff on line ignored"));
20135e4c
NC
232 }
233 break;
234 case MOXIE_F1_A4:
235 iword = opcode->opcode << 8;
236 while (ISSPACE (*op_end))
237 op_end++;
238 {
239 expressionS arg;
240 char *where;
241 int regnum;
242
243 regnum = parse_register_operand (&op_end);
244 while (ISSPACE (*op_end))
245 op_end++;
246
247 iword += (regnum << 4);
248
249 if (*op_end != ',')
250 {
20203fb9 251 as_bad (_("expecting comma delimited operands"));
20135e4c
NC
252 ignore_rest_of_line ();
253 return;
254 }
255 op_end++;
256
257 op_end = parse_exp_save_ilp (op_end, &arg);
258 where = frag_more (4);
259 fix_new_exp (frag_now,
260 (where - frag_now->fr_literal),
261 4,
262 &arg,
263 0,
264 BFD_RELOC_32);
265 }
266 break;
d7a5ed35 267 case MOXIE_F1_M:
20135e4c
NC
268 case MOXIE_F1_4:
269 iword = opcode->opcode << 8;
270 while (ISSPACE (*op_end))
271 op_end++;
272 {
273 expressionS arg;
274 char *where;
275
276 op_end = parse_exp_save_ilp (op_end, &arg);
277 where = frag_more (4);
278 fix_new_exp (frag_now,
279 (where - frag_now->fr_literal),
280 4,
281 &arg,
282 0,
283 BFD_RELOC_32);
284 }
285 break;
286 case MOXIE_F1_NARG:
287 iword = opcode->opcode << 8;
288 while (ISSPACE (*op_end))
289 op_end++;
290 if (*op_end != 0)
20203fb9 291 as_warn (_("extra stuff on line ignored"));
20135e4c
NC
292 break;
293 case MOXIE_F1_A:
294 iword = opcode->opcode << 8;
295 while (ISSPACE (*op_end))
296 op_end++;
297 {
298 int reg;
299 reg = parse_register_operand (&op_end);
300 while (ISSPACE (*op_end))
301 op_end++;
302 if (*op_end != 0)
20203fb9 303 as_warn (_("extra stuff on line ignored"));
20135e4c
NC
304 iword += (reg << 4);
305 }
306 break;
307 case MOXIE_F1_ABi:
308 iword = opcode->opcode << 8;
309 while (ISSPACE (*op_end))
310 op_end++;
311 {
312 int a, b;
313 a = parse_register_operand (&op_end);
314 if (*op_end != ',')
2cbd2211 315 as_warn (_("expecting comma delimited register operands"));
20135e4c
NC
316 op_end++;
317 if (*op_end != '(')
318 {
20203fb9 319 as_bad (_("expecting indirect register `($rA)'"));
20135e4c
NC
320 ignore_rest_of_line ();
321 return;
322 }
323 op_end++;
324 b = parse_register_operand (&op_end);
325 if (*op_end != ')')
326 {
20203fb9 327 as_bad (_("missing closing parenthesis"));
20135e4c
NC
328 ignore_rest_of_line ();
329 return;
330 }
331 op_end++;
332 iword += (a << 4) + b;
333 while (ISSPACE (*op_end))
334 op_end++;
335 if (*op_end != 0)
20203fb9 336 as_warn (_("extra stuff on line ignored"));
20135e4c
NC
337 }
338 break;
339 case MOXIE_F1_AiB:
340 iword = opcode->opcode << 8;
341 while (ISSPACE (*op_end))
342 op_end++;
343 {
344 int a, b;
345 if (*op_end != '(')
346 {
20203fb9 347 as_bad (_("expecting indirect register `($rA)'"));
20135e4c
NC
348 ignore_rest_of_line ();
349 return;
350 }
351 op_end++;
352 a = parse_register_operand (&op_end);
353 if (*op_end != ')')
354 {
20203fb9 355 as_bad (_("missing closing parenthesis"));
20135e4c
NC
356 ignore_rest_of_line ();
357 return;
358 }
359 op_end++;
360 if (*op_end != ',')
2cbd2211 361 as_warn (_("expecting comma delimited register operands"));
20135e4c
NC
362 op_end++;
363 b = parse_register_operand (&op_end);
364 iword += (a << 4) + b;
365 while (ISSPACE (*op_end))
366 op_end++;
367 if (*op_end != 0)
20203fb9 368 as_warn (_("extra stuff on line ignored"));
20135e4c
NC
369 }
370 break;
371 case MOXIE_F1_4A:
372 iword = opcode->opcode << 8;
373 while (ISSPACE (*op_end))
374 op_end++;
375 {
376 expressionS arg;
377 char *where;
378 int a;
379
380 op_end = parse_exp_save_ilp (op_end, &arg);
381 where = frag_more (4);
382 fix_new_exp (frag_now,
383 (where - frag_now->fr_literal),
384 4,
385 &arg,
386 0,
387 BFD_RELOC_32);
388
389 if (*op_end != ',')
390 {
20203fb9 391 as_bad (_("expecting comma delimited operands"));
20135e4c
NC
392 ignore_rest_of_line ();
393 return;
394 }
395 op_end++;
396
397 a = parse_register_operand (&op_end);
398 while (ISSPACE (*op_end))
399 op_end++;
400 if (*op_end != 0)
20203fb9 401 as_warn (_("extra stuff on line ignored"));
20135e4c
NC
402
403 iword += (a << 4);
404 }
405 break;
406 case MOXIE_F1_ABi4:
407 iword = opcode->opcode << 8;
408 while (ISSPACE (*op_end))
409 op_end++;
410 {
411 expressionS arg;
412 char *offset;
413 int a, b;
414
415 a = parse_register_operand (&op_end);
416 while (ISSPACE (*op_end))
417 op_end++;
418
419 if (*op_end != ',')
420 {
20203fb9 421 as_bad (_("expecting comma delimited operands"));
20135e4c
NC
422 ignore_rest_of_line ();
423 return;
424 }
425 op_end++;
426
427 op_end = parse_exp_save_ilp (op_end, &arg);
428 offset = frag_more (4);
429 fix_new_exp (frag_now,
430 (offset - frag_now->fr_literal),
431 4,
432 &arg,
433 0,
434 BFD_RELOC_32);
435
436 if (*op_end != '(')
437 {
20203fb9 438 as_bad (_("expecting indirect register `($rX)'"));
20135e4c
NC
439 ignore_rest_of_line ();
440 return;
441 }
442 op_end++;
443 b = parse_register_operand (&op_end);
444 if (*op_end != ')')
445 {
20203fb9 446 as_bad (_("missing closing parenthesis"));
20135e4c
NC
447 ignore_rest_of_line ();
448 return;
449 }
450 op_end++;
451
452 while (ISSPACE (*op_end))
453 op_end++;
454 if (*op_end != 0)
20203fb9 455 as_warn (_("extra stuff on line ignored"));
20135e4c
NC
456
457 iword += (a << 4) + b;
458 }
459 break;
460 case MOXIE_F1_AiB4:
461 iword = opcode->opcode << 8;
462 while (ISSPACE (*op_end))
463 op_end++;
464 {
465 expressionS arg;
466 char *offset;
467 int a, b;
468
469 op_end = parse_exp_save_ilp (op_end, &arg);
470 offset = frag_more (4);
471 fix_new_exp (frag_now,
472 (offset - frag_now->fr_literal),
473 4,
474 &arg,
475 0,
476 BFD_RELOC_32);
477
478 if (*op_end != '(')
479 {
20203fb9 480 as_bad (_("expecting indirect register `($rX)'"));
20135e4c
NC
481 ignore_rest_of_line ();
482 return;
483 }
484 op_end++;
485 a = parse_register_operand (&op_end);
486 if (*op_end != ')')
487 {
20203fb9 488 as_bad (_("missing closing parenthesis"));
20135e4c
NC
489 ignore_rest_of_line ();
490 return;
491 }
492 op_end++;
493
494 if (*op_end != ',')
495 {
20203fb9 496 as_bad (_("expecting comma delimited operands"));
20135e4c
NC
497 ignore_rest_of_line ();
498 return;
499 }
500 op_end++;
501
502 b = parse_register_operand (&op_end);
503 while (ISSPACE (*op_end))
504 op_end++;
505
506 while (ISSPACE (*op_end))
507 op_end++;
508 if (*op_end != 0)
20203fb9 509 as_warn (_("extra stuff on line ignored"));
20135e4c
NC
510
511 iword += (a << 4) + b;
512 }
513 break;
514 case MOXIE_F2_NARG:
515 iword = opcode->opcode << 12;
516 while (ISSPACE (*op_end))
517 op_end++;
518 if (*op_end != 0)
20203fb9 519 as_warn (_("extra stuff on line ignored"));
20135e4c 520 break;
f865a31d
AG
521 case MOXIE_F3_PCREL:
522 iword = (3<<14) | (opcode->opcode << 10);
523 while (ISSPACE (*op_end))
524 op_end++;
525 {
526 expressionS arg;
527
528 op_end = parse_exp_save_ilp (op_end, &arg);
529 fix_new_exp (frag_now,
530 (p - frag_now->fr_literal),
531 2,
532 &arg,
533 TRUE,
534 BFD_RELOC_MOXIE_10_PCREL);
535 }
536 break;
20135e4c 537 default:
20203fb9 538 abort ();
20135e4c
NC
539 }
540
541 md_number_to_chars (p, iword, 2);
542
543 while (ISSPACE (*op_end))
544 op_end++;
545
546 if (*op_end != 0)
20203fb9 547 as_warn (_("extra stuff on line ignored"));
20135e4c
NC
548
549 if (pending_reloc)
20203fb9 550 as_bad (_("Something forgot to clean up\n"));
20135e4c
NC
551}
552
553/* Turn a string in input_line_pointer into a floating point constant
554 of type type, and store the appropriate bytes in *LITP. The number
555 of LITTLENUMS emitted is stored in *SIZEP . An error message is
556 returned, or NULL on OK. */
557
558char *
559md_atof (int type, char *litP, int *sizeP)
560{
561 int prec;
562 LITTLENUM_TYPE words[4];
563 char *t;
564 int i;
565
566 switch (type)
567 {
568 case 'f':
569 prec = 2;
570 break;
571
572 case 'd':
573 prec = 4;
574 break;
575
576 default:
577 *sizeP = 0;
578 return _("bad call to md_atof");
579 }
580
581 t = atof_ieee (input_line_pointer, type, words);
582 if (t)
583 input_line_pointer = t;
584
585 *sizeP = prec * 2;
586
587 for (i = prec - 1; i >= 0; i--)
588 {
589 md_number_to_chars (litP, (valueT) words[i], 2);
590 litP += 2;
591 }
592
593 return NULL;
594}
e202fa84
AG
595
596enum options
597{
598 OPTION_EB = OPTION_MD_BASE,
599 OPTION_EL,
600};
20135e4c
NC
601
602struct option md_longopts[] =
603{
e202fa84
AG
604 { "EB", no_argument, NULL, OPTION_EB},
605 { "EL", no_argument, NULL, OPTION_EL},
606 { NULL, no_argument, NULL, 0}
20135e4c 607};
e202fa84 608
20135e4c 609size_t md_longopts_size = sizeof (md_longopts);
e202fa84
AG
610\f
611const char *md_shortopts = "";
20135e4c 612
20135e4c
NC
613int
614md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
615{
e202fa84
AG
616 switch (c)
617 {
618 case OPTION_EB:
619 target_big_endian = 1;
620 moxie_target_format = "elf32-bigmoxie";
621 break;
622 case OPTION_EL:
623 target_big_endian = 0;
624 moxie_target_format = "elf32-littlemoxie";
625 break;
626 default:
627 return 0;
628 }
629
630 return 1;
20135e4c
NC
631}
632
633void
634md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
635{
e202fa84
AG
636 fprintf (stream, _("\
637 -EB assemble for a big endian system (default)\n\
638 -EL assemble for a little endian system\n"));
20135e4c
NC
639}
640
641/* Apply a fixup to the object file. */
642
643void
f865a31d
AG
644md_apply_fix (fixS *fixP ATTRIBUTE_UNUSED,
645 valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED)
20135e4c
NC
646{
647 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
648 long val = *valP;
f865a31d 649 long newval;
20135e4c 650 long max, min;
20135e4c
NC
651
652 max = min = 0;
20135e4c
NC
653 switch (fixP->fx_r_type)
654 {
655 case BFD_RELOC_32:
e202fa84
AG
656 if (target_big_endian)
657 {
658 buf[0] = val >> 24;
659 buf[1] = val >> 16;
660 buf[2] = val >> 8;
661 buf[3] = val >> 0;
662 }
663 else
664 {
665 buf[3] = val >> 24;
666 buf[2] = val >> 16;
667 buf[1] = val >> 8;
668 buf[0] = val >> 0;
669 }
670 buf += 4;
20135e4c
NC
671 break;
672
673 case BFD_RELOC_16:
e202fa84
AG
674 if (target_big_endian)
675 {
676 buf[0] = val >> 8;
677 buf[1] = val >> 0;
678 }
679 else
680 {
681 buf[1] = val >> 8;
682 buf[0] = val >> 0;
683 }
684 buf += 2;
20135e4c
NC
685 break;
686
687 case BFD_RELOC_8:
688 *buf++ = val;
689 break;
690
f865a31d
AG
691 case BFD_RELOC_MOXIE_10_PCREL:
692 if (!val)
693 break;
694 if (val < -1024 || val > 1022)
695 as_bad_where (fixP->fx_file, fixP->fx_line,
696 _("pcrel too far BFD_RELOC_MOXIE_10"));
697 /* 11 bit offset even numbered, so we remove right bit. */
698 val >>= 1;
699 newval = md_chars_to_number (buf, 2);
700 newval |= val & 0x03ff;
701 md_number_to_chars (buf, newval, 2);
702 break;
703
20135e4c
NC
704 default:
705 abort ();
706 }
707
708 if (max != 0 && (val < min || val > max))
709 as_bad_where (fixP->fx_file, fixP->fx_line, _("offset out of range"));
710
711 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
712 fixP->fx_done = 1;
713}
714
e202fa84 715/* Put number into target byte order. */
20135e4c
NC
716
717void
e202fa84 718md_number_to_chars (char * ptr, valueT use, int nbytes)
20135e4c 719{
e202fa84
AG
720 if (target_big_endian)
721 number_to_chars_bigendian (ptr, use, nbytes);
722 else
723 number_to_chars_littleendian (ptr, use, nbytes);
20135e4c
NC
724}
725
f865a31d
AG
726/* Convert from target byte order to host byte order. */
727
e202fa84
AG
728static valueT
729md_chars_to_number (char * buf, int n)
f865a31d 730{
e202fa84
AG
731 valueT result = 0;
732 unsigned char * where = (unsigned char *) buf;
f865a31d 733
e202fa84
AG
734 if (target_big_endian)
735 {
736 while (n--)
737 {
738 result <<= 8;
739 result |= (*where++ & 255);
740 }
741 }
742 else
f865a31d 743 {
e202fa84
AG
744 while (n--)
745 {
746 result <<= 8;
747 result |= (where[n] & 255);
748 }
f865a31d
AG
749 }
750
e202fa84 751 return result;
f865a31d
AG
752}
753
20135e4c
NC
754/* Generate a machine-dependent relocation. */
755arelent *
756tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
757{
758 arelent *relP;
759 bfd_reloc_code_real_type code;
760
761 switch (fixP->fx_r_type)
762 {
763 case BFD_RELOC_32:
764 code = fixP->fx_r_type;
765 break;
f865a31d
AG
766 case BFD_RELOC_MOXIE_10_PCREL:
767 code = fixP->fx_r_type;
768 break;
20135e4c
NC
769 default:
770 as_bad_where (fixP->fx_file, fixP->fx_line,
771 _("Semantics error. This type of operand can not be relocated, it must be an assembly-time constant"));
772 return 0;
773 }
774
775 relP = xmalloc (sizeof (arelent));
9c2799c2 776 gas_assert (relP != 0);
20135e4c
NC
777 relP->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
778 *relP->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
779 relP->address = fixP->fx_frag->fr_address + fixP->fx_where;
780
781 relP->addend = fixP->fx_offset;
782
783 /* This is the standard place for KLUDGEs to work around bugs in
784 bfd_install_relocation (first such note in the documentation
785 appears with binutils-2.8).
786
787 That function bfd_install_relocation does the wrong thing with
788 putting stuff into the addend of a reloc (it should stay out) for a
789 weak symbol. The really bad thing is that it adds the
790 "segment-relative offset" of the symbol into the reloc. In this
791 case, the reloc should instead be relative to the symbol with no
792 other offset than the assembly code shows; and since the symbol is
793 weak, any local definition should be ignored until link time (or
794 thereafter).
795 To wit: weaksym+42 should be weaksym+42 in the reloc,
796 not weaksym+(offset_from_segment_of_local_weaksym_definition)
797
798 To "work around" this, we subtract the segment-relative offset of
799 "known" weak symbols. This evens out the extra offset.
800
801 That happens for a.out but not for ELF, since for ELF,
802 bfd_install_relocation uses the "special function" field of the
803 howto, and does not execute the code that needs to be undone. */
804
805 if (OUTPUT_FLAVOR == bfd_target_aout_flavour
806 && fixP->fx_addsy && S_IS_WEAK (fixP->fx_addsy)
807 && ! bfd_is_und_section (S_GET_SEGMENT (fixP->fx_addsy)))
808 {
809 relP->addend -= S_GET_VALUE (fixP->fx_addsy);
810 }
811
812 relP->howto = bfd_reloc_type_lookup (stdoutput, code);
813 if (! relP->howto)
814 {
815 const char *name;
816
817 name = S_GET_NAME (fixP->fx_addsy);
818 if (name == NULL)
819 name = _("<unknown>");
820 as_fatal (_("Cannot generate relocation type for symbol %s, code %s"),
821 name, bfd_get_reloc_code_name (code));
822 }
823
824 return relP;
825}
826
827/* Decide from what point a pc-relative relocation is relative to,
828 relative to the pc-relative fixup. Er, relatively speaking. */
829long
830md_pcrel_from (fixS *fixP)
831{
832 valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
833
20135e4c
NC
834 switch (fixP->fx_r_type)
835 {
836 case BFD_RELOC_32:
837 return addr + 4;
f865a31d 838 case BFD_RELOC_MOXIE_10_PCREL:
7078b409
AG
839 /* Offset is from the end of the instruction. */
840 return addr + 2;
20135e4c
NC
841 default:
842 abort ();
843 return addr;
844 }
845}
This page took 0.270653 seconds and 4 git commands to generate.