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