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