* doc/c-ppc.texi (PowerPC-Opts): Add -mpower4 and -maltivec.
[deliverable/binutils-gdb.git] / gas / config / tc-h8300.c
CommitLineData
252b5132 1/* tc-h8300.c -- Assemble code for the Hitachi H8/300
7e0de7bf 2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001
f7e42eb4 3 Free Software Foundation, Inc.
252b5132
RH
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
bc0d738a 22/* Written By Steve Chamberlain <sac@cygnus.com>. */
252b5132
RH
23
24#include <stdio.h>
25#include "as.h"
26#include "subsegs.h"
27#include "bfd.h"
28#define DEFINE_TABLE
29#define h8_opcodes ops
30#include "opcode/h8300.h"
3882b010 31#include "safe-ctype.h"
252b5132 32
7e0de7bf
JL
33#ifdef OBJ_ELF
34#include "elf/h8.h"
7e0de7bf
JL
35#endif
36
63a0b638 37const char comment_chars[] = ";";
252b5132 38const char line_comment_chars[] = "#";
63a0b638 39const char line_separator_chars[] = "";
252b5132
RH
40
41/* This table describes all the machine specific pseudo-ops the assembler
42 has to support. The fields are:
43 pseudo-op name without dot
44 function to call to execute this pseudo-op
45 Integer arg to pass to the function
46 */
47
48void cons ();
49
50int Hmode;
51int Smode;
52#define PSIZE (Hmode ? L_32 : L_16)
53#define DMODE (L_16)
54#define DSYMMODE (Hmode ? L_24 : L_16)
55int bsize = L_8; /* default branch displacement */
56
252b5132
RH
57void
58h8300hmode ()
59{
60 Hmode = 1;
61 Smode = 0;
83e20b45
JL
62#ifdef BFD_ASSEMBLER
63 if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300h))
64 as_warn (_("could not set architecture and machine"));
65#endif
252b5132
RH
66}
67
68void
69h8300smode ()
70{
71 Smode = 1;
72 Hmode = 1;
83e20b45
JL
73#ifdef BFD_ASSEMBLER
74 if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300s))
75 as_warn (_("could not set architecture and machine"));
76#endif
252b5132 77}
70d6ecf3 78
252b5132
RH
79void
80sbranch (size)
81 int size;
82{
83 bsize = size;
84}
85
70d6ecf3
AM
86static void
87pint ()
252b5132
RH
88{
89 cons (Hmode ? 4 : 2);
90}
91
92const pseudo_typeS md_pseudo_table[] =
93{
252b5132
RH
94 {"h8300h", h8300hmode, 0},
95 {"h8300s", h8300smode, 0},
96 {"sbranch", sbranch, L_8},
97 {"lbranch", sbranch, L_16},
98
99 {"int", pint, 0},
100 {"data.b", cons, 1},
101 {"data.w", cons, 2},
102 {"data.l", cons, 4},
103 {"form", listing_psize, 0},
104 {"heading", listing_title, 0},
105 {"import", s_ignore, 0},
106 {"page", listing_eject, 0},
107 {"program", s_ignore, 0},
108 {0, 0, 0}
109};
110
111const int md_reloc_size;
112
113const char EXP_CHARS[] = "eE";
114
115/* Chars that mean this number is a floating point constant */
116/* As in 0f12.456 */
117/* or 0d1.2345e12 */
118const char FLT_CHARS[] = "rRsSfFdDxXpP";
119
120static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
121
70d6ecf3
AM
122/* This function is called once, at assembler startup time. This
123 should set up all the tables, etc. that the MD part of the assembler
124 needs. */
252b5132
RH
125void
126md_begin ()
127{
128 struct h8_opcode *opcode;
129 char prev_buffer[100];
130 int idx = 0;
131
83e20b45
JL
132#ifdef BFD_ASSEMBLER
133 if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300))
134 as_warn (_("could not set architecture and machine"));
135#endif
136
252b5132
RH
137 opcode_hash_control = hash_new ();
138 prev_buffer[0] = 0;
139
140 for (opcode = h8_opcodes; opcode->name; opcode++)
141 {
142 /* Strip off any . part when inserting the opcode and only enter
70d6ecf3 143 unique codes into the hash table. */
252b5132
RH
144 char *src = opcode->name;
145 unsigned int len = strlen (src);
146 char *dst = malloc (len + 1);
147 char *buffer = dst;
148
149 opcode->size = 0;
150 while (*src)
151 {
152 if (*src == '.')
153 {
154 src++;
155 opcode->size = *src;
156 break;
157 }
158 *dst++ = *src++;
159 }
160 *dst++ = 0;
161 if (strcmp (buffer, prev_buffer))
162 {
163 hash_insert (opcode_hash_control, buffer, (char *) opcode);
164 strcpy (prev_buffer, buffer);
165 idx++;
166 }
167 opcode->idx = idx;
168
70d6ecf3 169 /* Find the number of operands. */
252b5132
RH
170 opcode->noperands = 0;
171 while (opcode->args.nib[opcode->noperands] != E)
172 opcode->noperands++;
70d6ecf3
AM
173
174 /* Find the length of the opcode in bytes. */
252b5132
RH
175 opcode->length = 0;
176 while (opcode->data.nib[opcode->length * 2] != E)
177 opcode->length++;
178 }
179
180 linkrelax = 1;
181}
182
252b5132
RH
183struct h8_exp
184{
185 char *e_beg;
186 char *e_end;
187 expressionS e_exp;
188};
70d6ecf3 189
252b5132
RH
190int dispreg;
191int opsize; /* Set when a register size is seen */
192
252b5132
RH
193struct h8_op
194{
195 op_type mode;
196 unsigned reg;
197 expressionS exp;
198};
199
200/*
201 parse operands
202 WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp
203 r0l,r0h,..r7l,r7h
204 @WREG
205 @WREG+
206 @-WREG
207 #const
208 ccr
209*/
210
bc0d738a
NC
211/* Try to parse a reg name. Return the number of chars consumed. */
212
40f09f82 213static int
252b5132
RH
214parse_reg (src, mode, reg, direction)
215 char *src;
216 op_type *mode;
217 unsigned int *reg;
218 int direction;
219
220{
221 char *end;
222 int len;
223
70d6ecf3 224 /* Cribbed from get_symbol_end. */
252b5132
RH
225 if (!is_name_beginner (*src) || *src == '\001')
226 return 0;
70d6ecf3 227 end = src + 1;
252b5132
RH
228 while (is_part_of_name (*end) || *end == '\001')
229 end++;
230 len = end - src;
231
232 if (len == 2 && src[0] == 's' && src[1] == 'p')
233 {
234 *mode = PSIZE | REG | direction;
235 *reg = 7;
236 return len;
237 }
238 if (len == 3 && src[0] == 'c' && src[1] == 'c' && src[2] == 'r')
239 {
240 *mode = CCR;
241 *reg = 0;
242 return len;
243 }
244 if (len == 3 && src[0] == 'e' && src[1] == 'x' && src[2] == 'r')
245 {
246 *mode = EXR;
247 *reg = 0;
248 return len;
249 }
250 if (len == 2 && src[0] == 'f' && src[1] == 'p')
251 {
252 *mode = PSIZE | REG | direction;
253 *reg = 6;
254 return len;
255 }
256 if (len == 3 && src[0] == 'e' && src[1] == 'r'
257 && src[2] >= '0' && src[2] <= '7')
258 {
259 *mode = L_32 | REG | direction;
260 *reg = src[2] - '0';
261 if (!Hmode)
262 as_warn (_("Reg not valid for H8/300"));
263 return len;
264 }
265 if (len == 2 && src[0] == 'e' && src[1] >= '0' && src[1] <= '7')
266 {
267 *mode = L_16 | REG | direction;
268 *reg = src[1] - '0' + 8;
269 if (!Hmode)
270 as_warn (_("Reg not valid for H8/300"));
271 return len;
272 }
273
274 if (src[0] == 'r')
275 {
276 if (src[1] >= '0' && src[1] <= '7')
277 {
278 if (len == 3 && src[2] == 'l')
279 {
280 *mode = L_8 | REG | direction;
281 *reg = (src[1] - '0') + 8;
282 return len;
283 }
284 if (len == 3 && src[2] == 'h')
285 {
286 *mode = L_8 | REG | direction;
287 *reg = (src[1] - '0');
288 return len;
289 }
290 if (len == 2)
291 {
292 *mode = L_16 | REG | direction;
293 *reg = (src[1] - '0');
294 return len;
295 }
296 }
297 }
298
299 return 0;
300}
301
40f09f82 302static char *
252b5132
RH
303parse_exp (s, op)
304 char *s;
70d6ecf3 305 expressionS *op;
252b5132
RH
306{
307 char *save = input_line_pointer;
308 char *new;
309
310 input_line_pointer = s;
311 expression (op);
312 if (op->X_op == O_absent)
313 as_bad (_("missing operand"));
314 new = input_line_pointer;
315 input_line_pointer = save;
316 return new;
317}
318
319static char *
320skip_colonthing (ptr, exp, mode)
321 char *ptr;
dbbc7809 322 expressionS *exp ATTRIBUTE_UNUSED;
252b5132
RH
323 int *mode;
324{
325 if (*ptr == ':')
326 {
327 ptr++;
328 *mode &= ~SIZE;
329 if (*ptr == '8')
330 {
331 ptr++;
332 /* ff fill any 8 bit quantity */
70d6ecf3 333 /* exp->X_add_number -= 0x100; */
252b5132
RH
334 *mode |= L_8;
335 }
336 else
337 {
338 if (*ptr == '2')
339 {
340 *mode |= L_24;
341 }
342 else if (*ptr == '3')
343 {
344 *mode |= L_32;
345 }
346 else if (*ptr == '1')
347 {
348 *mode |= L_16;
349 }
3882b010 350 while (ISDIGIT (*ptr))
252b5132
RH
351 ptr++;
352 }
353 }
354 return ptr;
355}
356
357/* The many forms of operand:
358
359 Rn Register direct
360 @Rn Register indirect
361 @(exp[:16], Rn) Register indirect with displacement
362 @Rn+
363 @-Rn
70d6ecf3
AM
364 @aa:8 absolute 8 bit
365 @aa:16 absolute 16 bit
252b5132
RH
366 @aa absolute 16 bit
367
368 #xx[:size] immediate data
70d6ecf3 369 @(exp:[8], pc) pc rel
252b5132
RH
370 @@aa[:8] memory indirect
371
372 */
373
374char *
375colonmod24 (op, src)
376 struct h8_op *op;
377 char *src;
378
379{
380 int mode = 0;
381 src = skip_colonthing (src, &op->exp, &mode);
382
383 if (!mode)
384 {
70d6ecf3 385 /* Choose a default mode. */
252b5132
RH
386 if (op->exp.X_add_number < -32768
387 || op->exp.X_add_number > 32767)
388 {
389 if (Hmode)
390 mode = L_24;
391 else
392 mode = L_16;
393 }
394 else if (op->exp.X_add_symbol
395 || op->exp.X_op_symbol)
396 mode = DSYMMODE;
397 else
398 mode = DMODE;
399 }
400 op->mode |= mode;
401 return src;
402
403}
404
252b5132
RH
405static void
406get_operand (ptr, op, dst, direction)
407 char **ptr;
408 struct h8_op *op;
dbbc7809 409 unsigned int dst ATTRIBUTE_UNUSED;
252b5132
RH
410 int direction;
411{
412 char *src = *ptr;
413 op_type mode;
414 unsigned int num;
415 unsigned int len;
416
417 op->mode = E;
418
419 /* Gross. Gross. ldm and stm have a format not easily handled
420 by get_operand. We deal with it explicitly here. */
3882b010
L
421 if (src[0] == 'e' && src[1] == 'r' && ISDIGIT (src[2])
422 && src[3] == '-' && src[4] == 'e' && src[5] == 'r' && ISDIGIT (src[6]))
252b5132
RH
423 {
424 int low, high;
425
426 low = src[2] - '0';
427 high = src[6] - '0';
428
429 if (high < low)
430 as_bad (_("Invalid register list for ldm/stm\n"));
431
432 if (low % 2)
433 as_bad (_("Invalid register list for ldm/stm\n"));
434
435 if (high - low > 3)
436 as_bad (_("Invalid register list for ldm/stm\n"));
437
438 if (high - low != 1
439 && low % 4)
440 as_bad (_("Invalid register list for ldm/stm\n"));
441
442 /* Even sicker. We encode two registers into op->reg. One
443 for the low register to save, the other for the high
444 register to save; we also set the high bit in op->reg
445 so we know this is "very special". */
446 op->reg = 0x80000000 | (high << 8) | low;
447 op->mode = REG;
448 *ptr = src + 7;
449 return;
450 }
451
452 len = parse_reg (src, &op->mode, &op->reg, direction);
453 if (len)
454 {
455 *ptr = src + len;
456 return;
457 }
458
459 if (*src == '@')
460 {
461 src++;
462 if (*src == '@')
463 {
464 src++;
465 src = parse_exp (src, &op->exp);
466
467 src = skip_colonthing (src, &op->exp, &op->mode);
468
469 *ptr = src;
470
471 op->mode = MEMIND;
472 return;
252b5132
RH
473 }
474
252b5132
RH
475 if (*src == '-')
476 {
477 src++;
478 len = parse_reg (src, &mode, &num, direction);
479 if (len == 0)
480 {
70d6ecf3 481 /* Oops, not a reg after all, must be ordinary exp. */
252b5132 482 src--;
70d6ecf3 483 /* Must be a symbol. */
252b5132
RH
484 op->mode = ABS | PSIZE | direction;
485 *ptr = skip_colonthing (parse_exp (src, &op->exp),
486 &op->exp, &op->mode);
487
488 return;
252b5132
RH
489 }
490
252b5132
RH
491 if ((mode & SIZE) != PSIZE)
492 as_bad (_("Wrong size pointer register for architecture."));
493 op->mode = RDDEC;
494 op->reg = num;
495 *ptr = src + len;
496 return;
497 }
498 if (*src == '(')
499 {
70d6ecf3 500 /* Disp. */
252b5132
RH
501 src++;
502
70d6ecf3 503 /* Start off assuming a 16 bit offset. */
252b5132
RH
504
505 src = parse_exp (src, &op->exp);
506
507 src = colonmod24 (op, src);
508
509 if (*src == ')')
510 {
511 src++;
512 op->mode |= ABS | direction;
513 *ptr = src;
514 return;
515 }
516
517 if (*src != ',')
518 {
519 as_bad (_("expected @(exp, reg16)"));
520 return;
521
522 }
523 src++;
524
525 len = parse_reg (src, &mode, &op->reg, direction);
526 if (len == 0 || !(mode & REG))
527 {
528 as_bad (_("expected @(exp, reg16)"));
529 return;
530 }
531 op->mode |= DISP | direction;
532 dispreg = op->reg;
533 src += len;
534 src = skip_colonthing (src, &op->exp, &op->mode);
535
536 if (*src != ')' && '(')
537 {
538 as_bad (_("expected @(exp, reg16)"));
539 return;
540 }
541 *ptr = src + 1;
542
543 return;
544 }
545 len = parse_reg (src, &mode, &num, direction);
546
547 if (len)
548 {
549 src += len;
550 if (*src == '+')
551 {
552 src++;
553 if ((mode & SIZE) != PSIZE)
554 as_bad (_("Wrong size pointer register for architecture."));
555 op->mode = RSINC;
556 op->reg = num;
557 *ptr = src;
558 return;
559 }
560 if ((mode & SIZE) != PSIZE)
561 as_bad (_("Wrong size pointer register for architecture."));
562
563 op->mode = direction | IND | PSIZE;
564 op->reg = num;
565 *ptr = src;
566
567 return;
568 }
569 else
570 {
571 /* must be a symbol */
572
573 op->mode = ABS | direction;
574 src = parse_exp (src, &op->exp);
575
576 *ptr = colonmod24 (op, src);
577
578 return;
579 }
580 }
581
252b5132
RH
582 if (*src == '#')
583 {
584 src++;
585 op->mode = IMM;
586 src = parse_exp (src, &op->exp);
587 *ptr = skip_colonthing (src, &op->exp, &op->mode);
588
589 return;
590 }
591 else if (strncmp (src, "mach", 4) == 0
592 || strncmp (src, "macl", 4) == 0)
593 {
594 op->reg = src[3] == 'l';
595 op->mode = MACREG;
596 *ptr = src + 4;
597 return;
598 }
599 else
600 {
601 src = parse_exp (src, &op->exp);
602 /* Trailing ':' size ? */
603 if (*src == ':')
604 {
605 if (src[1] == '1' && src[2] == '6')
606 {
607 op->mode = PCREL | L_16;
608 src += 3;
609 }
610 else if (src[1] == '8')
611 {
612 op->mode = PCREL | L_8;
613 src += 2;
614 }
615 else
616 {
617 as_bad (_("expect :8 or :16 here"));
618 }
619 }
620 else
621 {
622 op->mode = PCREL | bsize;
623 }
624 *ptr = src;
625 }
626}
627
70d6ecf3 628static char *
252b5132
RH
629get_operands (noperands, op_end, operand)
630 unsigned int noperands;
631 char *op_end;
632 struct h8_op *operand;
633{
634 char *ptr = op_end;
635
636 switch (noperands)
637 {
638 case 0:
639 operand[0].mode = 0;
640 operand[1].mode = 0;
641 break;
642
643 case 1:
644 ptr++;
645 get_operand (&ptr, operand + 0, 0, SRC);
646 if (*ptr == ',')
647 {
648 ptr++;
649 get_operand (&ptr, operand + 1, 1, DST);
650 }
651 else
652 {
653 operand[1].mode = 0;
654 }
252b5132 655 break;
70d6ecf3 656
252b5132
RH
657 case 2:
658 ptr++;
659 get_operand (&ptr, operand + 0, 0, SRC);
660 if (*ptr == ',')
661 ptr++;
662 get_operand (&ptr, operand + 1, 1, DST);
663 break;
664
665 default:
666 abort ();
667 }
668
252b5132
RH
669 return ptr;
670}
671
672/* Passed a pointer to a list of opcodes which use different
673 addressing modes, return the opcode which matches the opcodes
70d6ecf3
AM
674 provided. */
675static struct h8_opcode *
252b5132
RH
676get_specific (opcode, operands, size)
677 struct h8_opcode *opcode;
678 struct h8_op *operands;
679 int size;
680{
681 struct h8_opcode *this_try = opcode;
682 int found = 0;
683
684 unsigned int this_index = opcode->idx;
685
686 /* There's only one ldm/stm and it's easier to just
687 get out quick for them. */
688 if (strcmp (opcode->name, "stm.l") == 0
689 || strcmp (opcode->name, "ldm.l") == 0)
690 return this_try;
691
692 while (this_index == opcode->idx && !found)
693 {
694 found = 1;
695
696 this_try = opcode++;
697 if (this_try->noperands == 0)
698 {
699 int this_size;
700
701 this_size = this_try->how & SN;
702 if (this_size != size && (this_size != SB || size != SN))
703 found = 0;
704 }
705 else
706 {
707 unsigned int i;
708
709 for (i = 0; i < this_try->noperands && found; i++)
710 {
711 op_type op = this_try->args.nib[i];
712 int x = operands[i].mode;
713
714 if ((op & (DISP | REG)) == (DISP | REG)
715 && ((x & (DISP | REG)) == (DISP | REG)))
716 {
717 dispreg = operands[i].reg;
718 }
719 else if (op & REG)
720 {
721 if (!(x & REG))
722 found = 0;
723
724 if (x & L_P)
725 x = (x & ~L_P) | (Hmode ? L_32 : L_16);
726 if (op & L_P)
727 op = (op & ~L_P) | (Hmode ? L_32 : L_16);
728
729 opsize = op & SIZE;
730
70d6ecf3 731 /* The size of the reg is v important. */
252b5132
RH
732 if ((op & SIZE) != (x & SIZE))
733 found = 0;
734 }
735 else if ((op & ABSJMP) && (x & ABS))
736 {
737 operands[i].mode &= ~ABS;
738 operands[i].mode |= ABSJMP;
70d6ecf3 739 /* But it may not be 24 bits long. */
252b5132
RH
740 if (!Hmode)
741 {
742 operands[i].mode &= ~SIZE;
743 operands[i].mode |= L_16;
744 }
745 }
746 else if ((op & (KBIT | DBIT)) && (x & IMM))
747 {
70d6ecf3 748 /* This is ok if the immediate value is sensible. */
252b5132
RH
749 }
750 else if (op & PCREL)
751 {
70d6ecf3 752 /* The size of the displacement is important. */
252b5132
RH
753 if ((op & SIZE) != (x & SIZE))
754 found = 0;
755 }
756 else if ((op & (DISP | IMM | ABS))
757 && (op & (DISP | IMM | ABS)) == (x & (DISP | IMM | ABS)))
758 {
759 /* Promote a L_24 to L_32 if it makes us match. */
760 if ((x & L_24) && (op & L_32))
761 {
762 x &= ~L_24;
763 x |= L_32;
764 }
765 /* Promote an L8 to L_16 if it makes us match. */
70d6ecf3 766 if (op & ABS && op & L_8 && op & DISP)
252b5132
RH
767 {
768 if (x & L_16)
70d6ecf3 769 found = 1;
252b5132
RH
770 }
771 else if ((x & SIZE) != 0
772 && ((op & SIZE) != (x & SIZE)))
773 found = 0;
774 }
775 else if ((op & MACREG) != (x & MACREG))
776 {
777 found = 0;
778 }
779 else if ((op & MODE) != (x & MODE))
780 {
781 found = 0;
70d6ecf3 782 }
252b5132
RH
783 }
784 }
785 }
786 if (found)
787 return this_try;
788 else
789 return 0;
790}
791
792static void
793check_operand (operand, width, string)
794 struct h8_op *operand;
795 unsigned int width;
796 char *string;
797{
798 if (operand->exp.X_add_symbol == 0
799 && operand->exp.X_op_symbol == 0)
800 {
70d6ecf3
AM
801 /* No symbol involved, let's look at offset, it's dangerous if
802 any of the high bits are not 0 or ff's, find out by oring or
803 anding with the width and seeing if the answer is 0 or all
804 fs. */
252b5132 805
252b5132
RH
806 if ((operand->exp.X_add_number & ~width) != 0 &&
807 (operand->exp.X_add_number | width) != (~0))
808 {
70d6ecf3 809 if (width == 255
252b5132
RH
810 && (operand->exp.X_add_number & 0xff00) == 0xff00)
811 {
812 /* Just ignore this one - which happens when trying to
813 fit a 16 bit address truncated into an 8 bit address
814 of something like bset. */
815 }
166e23f9
KH
816 else if (strcmp (string, "@") == 0
817 && width == 0xffff
818 && (operand->exp.X_add_number & 0xff8000) == 0xff8000)
819 {
820 /* Just ignore this one - which happens when trying to
821 fit a 24 bit address truncated into a 16 bit address
822 of something like mov.w. */
823 }
70d6ecf3 824 else
252b5132
RH
825 {
826 as_warn (_("operand %s0x%lx out of range."), string,
827 (unsigned long) operand->exp.X_add_number);
828 }
829 }
830 }
252b5132
RH
831}
832
833/* RELAXMODE has one of 3 values:
834
835 0 Output a "normal" reloc, no relaxing possible for this insn/reloc
836
837 1 Output a relaxable 24bit absolute mov.w address relocation
838 (may relax into a 16bit absolute address).
839
840 2 Output a relaxable 16/24 absolute mov.b address relocation
841 (may relax into an 8bit absolute address). */
842
843static void
844do_a_fix_imm (offset, operand, relaxmode)
845 int offset;
846 struct h8_op *operand;
847 int relaxmode;
848{
849 int idx;
850 int size;
851 int where;
852
252b5132
RH
853 char *t = operand->mode & IMM ? "#" : "@";
854
855 if (operand->exp.X_add_symbol == 0)
856 {
857 char *bytes = frag_now->fr_literal + offset;
858 switch (operand->mode & SIZE)
859 {
860 case L_2:
861 check_operand (operand, 0x3, t);
862 bytes[0] |= (operand->exp.X_add_number) << 4;
863 break;
864 case L_3:
865 check_operand (operand, 0x7, t);
866 bytes[0] |= (operand->exp.X_add_number) << 4;
867 break;
868 case L_8:
869 check_operand (operand, 0xff, t);
870 bytes[0] = operand->exp.X_add_number;
871 break;
872 case L_16:
873 check_operand (operand, 0xffff, t);
874 bytes[0] = operand->exp.X_add_number >> 8;
875 bytes[1] = operand->exp.X_add_number >> 0;
876 break;
877 case L_24:
878 check_operand (operand, 0xffffff, t);
879 bytes[0] = operand->exp.X_add_number >> 16;
880 bytes[1] = operand->exp.X_add_number >> 8;
881 bytes[2] = operand->exp.X_add_number >> 0;
882 break;
883
884 case L_32:
70d6ecf3 885 /* This should be done with bfd. */
252b5132
RH
886 bytes[0] = operand->exp.X_add_number >> 24;
887 bytes[1] = operand->exp.X_add_number >> 16;
888 bytes[2] = operand->exp.X_add_number >> 8;
889 bytes[3] = operand->exp.X_add_number >> 0;
4132022d
AM
890 if (relaxmode != 0)
891 {
892 idx = (relaxmode == 2) ? R_MOV24B1 : R_MOVL1;
893 fix_new_exp (frag_now, offset, 4, &operand->exp, 0, idx);
894 }
252b5132
RH
895 break;
896 }
252b5132
RH
897 }
898 else
899 {
900 switch (operand->mode & SIZE)
901 {
252b5132
RH
902 case L_24:
903 case L_32:
904 size = 4;
905 where = (operand->mode & SIZE) == L_24 ? -1 : 0;
906 if (relaxmode == 2)
907 idx = R_MOV24B1;
908 else if (relaxmode == 1)
909 idx = R_MOVL1;
910 else
911 idx = R_RELLONG;
912 break;
913 default:
70d6ecf3 914 as_bad (_("Can't work out size of operand.\n"));
252b5132
RH
915 case L_16:
916 size = 2;
917 where = 0;
918 if (relaxmode == 2)
919 idx = R_MOV16B1;
920 else
921 idx = R_RELWORD;
4132022d
AM
922 operand->exp.X_add_number =
923 ((operand->exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;
252b5132
RH
924 break;
925 case L_8:
926 size = 1;
927 where = 0;
928 idx = R_RELBYTE;
4132022d
AM
929 operand->exp.X_add_number =
930 ((operand->exp.X_add_number & 0xff) ^ 0x80) - 0x80;
252b5132
RH
931 }
932
933 fix_new_exp (frag_now,
934 offset + where,
935 size,
936 &operand->exp,
937 0,
938 idx);
939 }
252b5132
RH
940}
941
70d6ecf3 942/* Now we know what sort of opcodes it is, let's build the bytes. */
252b5132
RH
943static void
944build_bytes (this_try, operand)
945 struct h8_opcode *this_try;
946 struct h8_op *operand;
947{
948 unsigned int i;
949
950 char *output = frag_more (this_try->length);
951 op_type *nibble_ptr = this_try->data.nib;
952 op_type c;
953 unsigned int nibble_count = 0;
954 int absat;
955 int immat;
956 int nib;
957 int movb = 0;
958 char asnibbles[30];
959 char *p = asnibbles;
960
961 if (!(this_try->inbase || Hmode))
962 as_warn (_("Opcode `%s' with these operand types not available in H8/300 mode"),
963 this_try->name);
964
965 while (*nibble_ptr != E)
966 {
967 int d;
968 c = *nibble_ptr++;
969
970 d = (c & (DST | SRC_IN_DST)) != 0;
971
972 if (c < 16)
973 {
974 nib = c;
975 }
976 else
977 {
252b5132
RH
978 if (c & (REG | IND | INC | DEC))
979 {
980 nib = operand[d].reg;
981 }
982 else if ((c & DISPREG) == (DISPREG))
983 {
984 nib = dispreg;
985 }
70d6ecf3 986 else if (c & ABS)
252b5132
RH
987 {
988 operand[d].mode = c;
989 absat = nibble_count / 2;
990 nib = 0;
991 }
992 else if (c & (IMM | PCREL | ABS | ABSJMP | DISP))
993 {
994 operand[d].mode = c;
995 immat = nibble_count / 2;
996 nib = 0;
997 }
998 else if (c & IGNORE)
999 {
1000 nib = 0;
1001 }
1002 else if (c & DBIT)
1003 {
1004 switch (operand[0].exp.X_add_number)
1005 {
1006 case 1:
1007 nib = c;
1008 break;
1009 case 2:
1010 nib = 0x8 | c;
1011 break;
1012 default:
1013 as_bad (_("Need #1 or #2 here"));
1014 }
1015 }
1016 else if (c & KBIT)
1017 {
1018 switch (operand[0].exp.X_add_number)
1019 {
1020 case 1:
1021 nib = 0;
1022 break;
1023 case 2:
1024 nib = 8;
1025 break;
1026 case 4:
1027 if (!Hmode)
1028 as_warn (_("#4 not valid on H8/300."));
1029 nib = 9;
1030 break;
1031
1032 default:
1033 as_bad (_("Need #1 or #2 here"));
1034 break;
1035 }
70d6ecf3 1036 /* Stop it making a fix. */
252b5132
RH
1037 operand[0].mode = 0;
1038 }
1039
1040 if (c & MEMRELAX)
1041 {
1042 operand[d].mode |= MEMRELAX;
1043 }
1044
1045 if (c & B31)
1046 {
1047 nib |= 0x8;
1048 }
1049
1050 if (c & MACREG)
1051 {
f0c56b90
NC
1052 if (operand[0].mode == MACREG)
1053 /* stmac has mac[hl] as the first operand. */
1054 nib = 2 + operand[0].reg;
1055 else
1056 /* ldmac has mac[hl] as the second operand. */
1057 nib = 2 + operand[1].reg;
252b5132
RH
1058 }
1059 }
1060 nibble_count++;
1061
1062 *p++ = nib;
1063 }
1064
1065 /* Disgusting. Why, oh why didn't someone ask us for advice
1066 on the assembler format. */
1067 if (strcmp (this_try->name, "stm.l") == 0
1068 || strcmp (this_try->name, "ldm.l") == 0)
1069 {
1070 int high, low;
1071 high = (operand[this_try->name[0] == 'l' ? 1 : 0].reg >> 8) & 0xf;
1072 low = operand[this_try->name[0] == 'l' ? 1 : 0].reg & 0xf;
1073
1074 asnibbles[2] = high - low;
1075 asnibbles[7] = (this_try->name[0] == 'l') ? high : low;
1076 }
1077
1078 for (i = 0; i < this_try->length; i++)
1079 {
1080 output[i] = (asnibbles[i * 2] << 4) | asnibbles[i * 2 + 1];
1081 }
1082
1083 /* Note if this is a movb instruction -- there's a special relaxation
1084 which only applies to them. */
1085 if (strcmp (this_try->name, "mov.b") == 0)
1086 movb = 1;
1087
70d6ecf3 1088 /* Output any fixes. */
252b5132
RH
1089 for (i = 0; i < 2; i++)
1090 {
1091 int x = operand[i].mode;
1092
1093 if (x & (IMM | DISP))
1094 {
1095 do_a_fix_imm (output - frag_now->fr_literal + immat,
1096 operand + i, x & MEMRELAX != 0);
1097 }
1098 else if (x & ABS)
1099 {
1100 do_a_fix_imm (output - frag_now->fr_literal + absat,
1101 operand + i, x & MEMRELAX ? movb + 1 : 0);
1102 }
1103 else if (x & PCREL)
1104 {
1105 int size16 = x & L_16;
1106 int where = size16 ? 2 : 1;
1107 int size = size16 ? 2 : 1;
1108 int type = size16 ? R_PCRWORD : R_PCRBYTE;
36ed2fff 1109 fixS *fixP;
252b5132
RH
1110
1111 check_operand (operand + i, size16 ? 0x7fff : 0x7f, "@");
1112
1113 if (operand[i].exp.X_add_number & 1)
1114 {
1115 as_warn (_("branch operand has odd offset (%lx)\n"),
1116 (unsigned long) operand->exp.X_add_number);
1117 }
1118
36ed2fff
JL
1119#ifndef OBJ_ELF
1120 /* The COFF port has always been off by one, changing it
1121 now would be an incompatible change, so we leave it as-is.
1122
1123 We don't want to do this for ELF as we want to be
1124 compatible with the proposed ELF format from Hitachi. */
252b5132 1125 operand[i].exp.X_add_number -= 1;
36ed2fff
JL
1126#endif
1127
4132022d
AM
1128 operand[i].exp.X_add_number =
1129 ((operand[i].exp.X_add_number & 0xff) ^ 0x80) - 0x80;
252b5132 1130
36ed2fff
JL
1131 fixP = fix_new_exp (frag_now,
1132 output - frag_now->fr_literal + where,
1133 size,
1134 &operand[i].exp,
1135 1,
1136 type);
1137 fixP->fx_signed = 1;
252b5132
RH
1138 }
1139 else if (x & MEMIND)
1140 {
252b5132
RH
1141 check_operand (operand + i, 0xff, "@@");
1142 fix_new_exp (frag_now,
1143 output - frag_now->fr_literal + 1,
1144 1,
1145 &operand[i].exp,
1146 0,
1147 R_MEM_INDIRECT);
1148 }
1149 else if (x & ABSJMP)
1150 {
3c1ba8a3
JL
1151 int where = 0;
1152
1153#ifdef OBJ_ELF
1154 /* To be compatible with the proposed H8 ELF format, we
1155 want the relocation's offset to point to the first byte
1156 that will be modified, not to the start of the instruction. */
1157 where += 1;
3c1ba8a3 1158#endif
de342d07 1159
70d6ecf3 1160 /* This jmp may be a jump or a branch. */
252b5132
RH
1161
1162 check_operand (operand + i, Hmode ? 0xffffff : 0xffff, "@");
1163 if (operand[i].exp.X_add_number & 1)
1164 {
1165 as_warn (_("branch operand has odd offset (%lx)\n"),
1166 (unsigned long) operand->exp.X_add_number);
1167 }
1168 if (!Hmode)
70d6ecf3 1169 operand[i].exp.X_add_number =
4132022d 1170 ((operand[i].exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;
252b5132 1171 fix_new_exp (frag_now,
3c1ba8a3 1172 output - frag_now->fr_literal + where,
252b5132
RH
1173 4,
1174 &operand[i].exp,
1175 0,
1176 R_JMPL1);
1177 }
1178 }
252b5132
RH
1179}
1180
70d6ecf3
AM
1181/* Try to give an intelligent error message for common and simple to
1182 detect errors. */
252b5132
RH
1183static void
1184clever_message (opcode, operand)
1185 struct h8_opcode *opcode;
1186 struct h8_op *operand;
1187{
70d6ecf3 1188 /* Find out if there was more than one possible opcode. */
252b5132
RH
1189
1190 if ((opcode + 1)->idx != opcode->idx)
1191 {
1192 unsigned int argn;
1193
70d6ecf3
AM
1194 /* Only one opcode of this flavour, try to guess which operand
1195 didn't match. */
252b5132
RH
1196 for (argn = 0; argn < opcode->noperands; argn++)
1197 {
1198 switch (opcode->args.nib[argn])
1199 {
1200 case RD16:
1201 if (operand[argn].mode != RD16)
1202 {
1203 as_bad (_("destination operand must be 16 bit register"));
1204 return;
1205
1206 }
1207 break;
1208
1209 case RS8:
252b5132
RH
1210 if (operand[argn].mode != RS8)
1211 {
1212 as_bad (_("source operand must be 8 bit register"));
1213 return;
1214 }
1215 break;
1216
1217 case ABS16DST:
1218 if (operand[argn].mode != ABS16DST)
1219 {
1220 as_bad (_("destination operand must be 16bit absolute address"));
1221 return;
1222 }
1223 break;
1224 case RD8:
1225 if (operand[argn].mode != RD8)
1226 {
1227 as_bad (_("destination operand must be 8 bit register"));
1228 return;
1229 }
1230 break;
1231
252b5132
RH
1232 case ABS16SRC:
1233 if (operand[argn].mode != ABS16SRC)
1234 {
1235 as_bad (_("source operand must be 16bit absolute address"));
1236 return;
1237 }
1238 break;
1239
1240 }
1241 }
1242 }
1243 as_bad (_("invalid operands"));
1244}
1245
70d6ecf3
AM
1246/* This is the guts of the machine-dependent assembler. STR points to
1247 a machine dependent instruction. This function is supposed to emit
1248 the frags/bytes it assembles. */
252b5132
RH
1249void
1250md_assemble (str)
1251 char *str;
1252{
1253 char *op_start;
1254 char *op_end;
1255 struct h8_op operand[2];
1256 struct h8_opcode *opcode;
1257 struct h8_opcode *prev_opcode;
1258
1259 char *dot = 0;
1260 char c;
1261 int size;
1262
70d6ecf3 1263 /* Drop leading whitespace. */
252b5132
RH
1264 while (*str == ' ')
1265 str++;
1266
70d6ecf3 1267 /* Find the op code end. */
252b5132
RH
1268 for (op_start = op_end = str;
1269 *op_end != 0 && *op_end != ' ';
1270 op_end++)
1271 {
1272 if (*op_end == '.')
1273 {
1274 dot = op_end + 1;
1275 *op_end = 0;
1276 op_end += 2;
1277 break;
1278 }
1279 }
1280
252b5132
RH
1281 if (op_end == op_start)
1282 {
1283 as_bad (_("can't find opcode "));
1284 }
1285 c = *op_end;
1286
1287 *op_end = 0;
1288
1289 opcode = (struct h8_opcode *) hash_find (opcode_hash_control,
1290 op_start);
1291
1292 if (opcode == NULL)
1293 {
1294 as_bad (_("unknown opcode"));
1295 return;
1296 }
1297
70d6ecf3 1298 /* We used to set input_line_pointer to the result of get_operands,
252b5132
RH
1299 but that is wrong. Our caller assumes we don't change it. */
1300
1301 (void) get_operands (opcode->noperands, op_end, operand);
1302 *op_end = c;
1303 prev_opcode = opcode;
1304
1305 size = SN;
1306 if (dot)
1307 {
1308 switch (*dot)
1309 {
1310 case 'b':
1311 size = SB;
1312 break;
1313
1314 case 'w':
1315 size = SW;
1316 break;
1317
1318 case 'l':
1319 size = SL;
1320 break;
1321 }
1322 }
1323 opcode = get_specific (opcode, operand, size);
1324
1325 if (opcode == 0)
1326 {
70d6ecf3 1327 /* Couldn't find an opcode which matched the operands. */
252b5132
RH
1328 char *where = frag_more (2);
1329
1330 where[0] = 0x0;
1331 where[1] = 0x0;
1332 clever_message (prev_opcode, operand);
1333
1334 return;
1335 }
1336 if (opcode->size && dot)
1337 {
1338 if (opcode->size != *dot)
1339 {
1340 as_warn (_("mismatch between opcode size and operand size"));
1341 }
1342 }
1343
1344 build_bytes (opcode, operand);
252b5132
RH
1345}
1346
5facebfc 1347#ifndef BFD_ASSEMBLER
252b5132
RH
1348void
1349tc_crawl_symbol_chain (headers)
70d6ecf3 1350 object_headers *headers ATTRIBUTE_UNUSED;
252b5132
RH
1351{
1352 printf (_("call to tc_crawl_symbol_chain \n"));
1353}
f333765f 1354#endif
252b5132
RH
1355
1356symbolS *
1357md_undefined_symbol (name)
dbbc7809 1358 char *name ATTRIBUTE_UNUSED;
252b5132
RH
1359{
1360 return 0;
1361}
1362
5facebfc 1363#ifndef BFD_ASSEMBLER
252b5132
RH
1364void
1365tc_headers_hook (headers)
70d6ecf3 1366 object_headers *headers ATTRIBUTE_UNUSED;
252b5132
RH
1367{
1368 printf (_("call to tc_headers_hook \n"));
1369}
f333765f 1370#endif
252b5132
RH
1371
1372/* Various routines to kill one day */
1373/* Equal to MAX_PRECISION in atof-ieee.c */
1374#define MAX_LITTLENUMS 6
1375
70d6ecf3
AM
1376/* Turn a string in input_line_pointer into a floating point constant
1377 of type TYPE, and store the appropriate bytes in *LITP. The number
bc0d738a 1378 of LITTLENUMS emitted is stored in *SIZEP. An error message is
70d6ecf3 1379 returned, or NULL on OK. */
bc0d738a 1380
252b5132
RH
1381char *
1382md_atof (type, litP, sizeP)
1383 char type;
1384 char *litP;
1385 int *sizeP;
1386{
1387 int prec;
1388 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1389 LITTLENUM_TYPE *wordP;
1390 char *t;
1391 char *atof_ieee ();
1392
1393 switch (type)
1394 {
1395 case 'f':
1396 case 'F':
1397 case 's':
1398 case 'S':
1399 prec = 2;
1400 break;
1401
1402 case 'd':
1403 case 'D':
1404 case 'r':
1405 case 'R':
1406 prec = 4;
1407 break;
1408
1409 case 'x':
1410 case 'X':
1411 prec = 6;
1412 break;
1413
1414 case 'p':
1415 case 'P':
1416 prec = 6;
1417 break;
1418
1419 default:
1420 *sizeP = 0;
1421 return _("Bad call to MD_ATOF()");
1422 }
1423 t = atof_ieee (input_line_pointer, type, words);
1424 if (t)
1425 input_line_pointer = t;
1426
1427 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1428 for (wordP = words; prec--;)
1429 {
1430 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
1431 litP += sizeof (LITTLENUM_TYPE);
1432 }
1433 return 0;
1434}
1435\f
1436CONST char *md_shortopts = "";
1437struct option md_longopts[] = {
1438 {NULL, no_argument, NULL, 0}
1439};
70d6ecf3
AM
1440
1441size_t md_longopts_size = sizeof (md_longopts);
252b5132
RH
1442
1443int
1444md_parse_option (c, arg)
dbbc7809
JL
1445 int c ATTRIBUTE_UNUSED;
1446 char *arg ATTRIBUTE_UNUSED;
252b5132
RH
1447{
1448 return 0;
1449}
1450
1451void
1452md_show_usage (stream)
dbbc7809 1453 FILE *stream ATTRIBUTE_UNUSED;
252b5132
RH
1454{
1455}
1456\f
1457void
1458tc_aout_fix_to_chars ()
1459{
1460 printf (_("call to tc_aout_fix_to_chars \n"));
1461 abort ();
1462}
1463
1464void
1465md_convert_frag (headers, seg, fragP)
36ed2fff
JL
1466#ifdef BFD_ASSEMBLER
1467 bfd *headers ATTRIBUTE_UNUSED;
1468#else
dbbc7809 1469 object_headers *headers ATTRIBUTE_UNUSED;
36ed2fff 1470#endif
dbbc7809
JL
1471 segT seg ATTRIBUTE_UNUSED;
1472 fragS *fragP ATTRIBUTE_UNUSED;
252b5132
RH
1473{
1474 printf (_("call to md_convert_frag \n"));
1475 abort ();
1476}
1477
3c1ba8a3
JL
1478#ifdef BFD_ASSEMBLER
1479valueT
1480md_section_align (segment, size)
1481 segT segment;
1482 valueT size;
1483{
1484 int align = bfd_get_section_alignment (stdoutput, segment);
1485 return ((size + (1 << align) - 1) & (-1 << align));
1486}
1487#else
70d6ecf3 1488valueT
252b5132
RH
1489md_section_align (seg, size)
1490 segT seg;
1491 valueT size;
1492{
70d6ecf3 1493 return ((size + (1 << section_alignment[(int) seg]) - 1)
3c1ba8a3 1494 & (-1 << section_alignment[(int) seg]));
252b5132 1495}
3c1ba8a3
JL
1496#endif
1497
252b5132
RH
1498
1499void
94f592af 1500md_apply_fix3 (fixP, valP, seg)
252b5132 1501 fixS *fixP;
94f592af
NC
1502 valueT *valP;
1503 segT seg ATTRIBUTE_UNUSED;
252b5132
RH
1504{
1505 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
94f592af 1506 long val = * (long *) valP;
252b5132
RH
1507
1508 switch (fixP->fx_size)
1509 {
1510 case 1:
1511 *buf++ = val;
1512 break;
1513 case 2:
1514 *buf++ = (val >> 8);
1515 *buf++ = val;
1516 break;
1517 case 4:
1518 *buf++ = (val >> 24);
1519 *buf++ = (val >> 16);
1520 *buf++ = (val >> 8);
1521 *buf++ = val;
1522 break;
1523 default:
1524 abort ();
1525 }
94f592af
NC
1526
1527 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1528 fixP->fx_done = 1;
252b5132
RH
1529}
1530
1531int
1532md_estimate_size_before_relax (fragP, segment_type)
dbbc7809
JL
1533 register fragS *fragP ATTRIBUTE_UNUSED;
1534 register segT segment_type ATTRIBUTE_UNUSED;
252b5132
RH
1535{
1536 printf (_("call tomd_estimate_size_before_relax \n"));
1537 abort ();
1538}
1539
70d6ecf3 1540/* Put number into target byte order. */
252b5132
RH
1541void
1542md_number_to_chars (ptr, use, nbytes)
1543 char *ptr;
1544 valueT use;
1545 int nbytes;
1546{
1547 number_to_chars_bigendian (ptr, use, nbytes);
1548}
70d6ecf3 1549
252b5132
RH
1550long
1551md_pcrel_from (fixP)
dbbc7809 1552 fixS *fixP ATTRIBUTE_UNUSED;
252b5132
RH
1553{
1554 abort ();
1555}
1556
5facebfc 1557#ifndef BFD_ASSEMBLER
252b5132
RH
1558void
1559tc_reloc_mangle (fix_ptr, intr, base)
1560 fixS *fix_ptr;
1561 struct internal_reloc *intr;
1562 bfd_vma base;
1563
1564{
1565 symbolS *symbol_ptr;
1566
1567 symbol_ptr = fix_ptr->fx_addsy;
1568
1569 /* If this relocation is attached to a symbol then it's ok
70d6ecf3 1570 to output it. */
252b5132
RH
1571 if (fix_ptr->fx_r_type == TC_CONS_RELOC)
1572 {
1573 /* cons likes to create reloc32's whatever the size of the reloc..
1574 */
1575 switch (fix_ptr->fx_size)
1576 {
1577 case 4:
1578 intr->r_type = R_RELLONG;
1579 break;
1580 case 2:
1581 intr->r_type = R_RELWORD;
1582 break;
1583 case 1:
1584 intr->r_type = R_RELBYTE;
1585 break;
1586 default:
1587 abort ();
252b5132 1588 }
252b5132
RH
1589 }
1590 else
1591 {
1592 intr->r_type = fix_ptr->fx_r_type;
1593 }
1594
1595 intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
1596 intr->r_offset = fix_ptr->fx_offset;
1597
1598 if (symbol_ptr)
1599 {
1600 if (symbol_ptr->sy_number != -1)
1601 intr->r_symndx = symbol_ptr->sy_number;
1602 else
1603 {
1604 symbolS *segsym;
1605
1606 /* This case arises when a reference is made to `.'. */
1607 segsym = seg_info (S_GET_SEGMENT (symbol_ptr))->dot;
1608 if (segsym == NULL)
1609 intr->r_symndx = -1;
1610 else
1611 {
1612 intr->r_symndx = segsym->sy_number;
1613 intr->r_offset += S_GET_VALUE (symbol_ptr);
1614 }
1615 }
1616 }
1617 else
1618 intr->r_symndx = -1;
252b5132 1619}
5facebfc 1620#else /* BFD_ASSEMBLER */
f333765f
JL
1621arelent *
1622tc_gen_reloc (section, fixp)
1623 asection *section ATTRIBUTE_UNUSED;
1624 fixS *fixp;
1625{
1626 arelent *rel;
1627 bfd_reloc_code_real_type r_type;
1628
de342d07
JL
1629 if (fixp->fx_addsy && fixp->fx_subsy)
1630 {
1631 if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
1632 || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
1633 {
1634 as_bad_where (fixp->fx_file, fixp->fx_line,
1635 "Difference of symbols in different sections is not supported");
1636 return NULL;
1637 }
1638 }
1639
f333765f
JL
1640 rel = (arelent *) xmalloc (sizeof (arelent));
1641 rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1642 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1643 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
1644 rel->addend = fixp->fx_offset;
1645
1646 r_type = fixp->fx_r_type;
1647
1648#define DEBUG 0
1649#if DEBUG
1650 fprintf (stderr, "%s\n", bfd_get_reloc_code_name (r_type));
1651 fflush(stderr);
1652#endif
1653 rel->howto = bfd_reloc_type_lookup (stdoutput, r_type);
1654 if (rel->howto == NULL)
1655 {
1656 as_bad_where (fixp->fx_file, fixp->fx_line,
1657 _("Cannot represent relocation type %s"),
1658 bfd_get_reloc_code_name (r_type));
1659 return NULL;
1660 }
1661
1662 return rel;
1663}
1664#endif
This page took 0.175003 seconds and 4 git commands to generate.