21051e0a55fe52459e01fd0aa323395c87ed4426
[deliverable/binutils-gdb.git] / gas / config / tc-h8300.c
1 /* tc-h8300.c -- Assemble code for the Renesas H8/300
2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
3 2001, 2002, 2003 Free Software Foundation, Inc.
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
22 /* Written By Steve Chamberlain <sac@cygnus.com>. */
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"
31 #include "safe-ctype.h"
32
33 #ifdef OBJ_ELF
34 #include "elf/h8.h"
35 #endif
36
37 const char comment_chars[] = ";";
38 const char line_comment_chars[] = "#";
39 const char line_separator_chars[] = "";
40
41 void cons PARAMS ((int));
42 void sbranch PARAMS ((int));
43 void h8300hmode PARAMS ((int));
44 void h8300smode PARAMS ((int));
45 static void pint PARAMS ((int));
46
47 int Hmode;
48 int Smode;
49
50 #define PSIZE (Hmode ? L_32 : L_16)
51 #define DMODE (L_16)
52 #define DSYMMODE (Hmode ? L_24 : L_16)
53
54 int bsize = L_8; /* Default branch displacement. */
55
56 struct h8_instruction
57 {
58 int length;
59 int noperands;
60 int idx;
61 int size;
62 const struct h8_opcode *opcode;
63 };
64
65 struct h8_instruction *h8_instructions;
66
67 void
68 h8300hmode (arg)
69 int arg ATTRIBUTE_UNUSED;
70 {
71 Hmode = 1;
72 Smode = 0;
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
77 }
78
79 void
80 h8300smode (arg)
81 int arg ATTRIBUTE_UNUSED;
82 {
83 Smode = 1;
84 Hmode = 1;
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
89 }
90
91 void
92 sbranch (size)
93 int size;
94 {
95 bsize = size;
96 }
97
98 static void
99 pint (arg)
100 int arg ATTRIBUTE_UNUSED;
101 {
102 cons (Hmode ? 4 : 2);
103 }
104
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
111 const pseudo_typeS md_pseudo_table[] =
112 {
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
130 const int md_reloc_size;
131
132 const char EXP_CHARS[] = "eE";
133
134 /* Chars that mean this number is a floating point constant
135 As in 0f12.456
136 or 0d1.2345e12. */
137 const char FLT_CHARS[] = "rRsSfFdDxXpP";
138
139 static struct hash_control *opcode_hash_control; /* Opcode mnemonics. */
140
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. */
144
145 void
146 md_begin ()
147 {
148 unsigned int nopcodes;
149 const struct h8_opcode *p;
150 struct h8_instruction *pi;
151 char prev_buffer[100];
152 int idx = 0;
153
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
159 opcode_hash_control = hash_new ();
160 prev_buffer[0] = 0;
161
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++)
168 {
169 /* Strip off any . part when inserting the opcode and only enter
170 unique codes into the hash table. */
171 char *src = p->name;
172 unsigned int len = strlen (src);
173 char *dst = malloc (len + 1);
174 char *buffer = dst;
175
176 pi->size = 0;
177 while (*src)
178 {
179 if (*src == '.')
180 {
181 src++;
182 pi->size = *src;
183 break;
184 }
185 *dst++ = *src++;
186 }
187 *dst++ = 0;
188 if (strcmp (buffer, prev_buffer))
189 {
190 hash_insert (opcode_hash_control, buffer, (char *) pi);
191 strcpy (prev_buffer, buffer);
192 idx++;
193 }
194 pi->idx = idx;
195
196 /* Find the number of operands. */
197 pi->noperands = 0;
198 while (p->args.nib[pi->noperands] != E)
199 pi->noperands++;
200
201 /* Find the length of the opcode in bytes. */
202 pi->length = 0;
203 while (p->data.nib[pi->length * 2] != E)
204 pi->length++;
205
206 pi->opcode = p;
207 }
208
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
216 linkrelax = 1;
217 }
218
219 struct h8_exp
220 {
221 char *e_beg;
222 char *e_end;
223 expressionS e_exp;
224 };
225
226 int dispreg;
227 int opsize; /* Set when a register size is seen. */
228
229 struct h8_op
230 {
231 op_type mode;
232 unsigned reg;
233 expressionS exp;
234 };
235
236 static void clever_message PARAMS ((const struct h8_instruction *, struct h8_op *));
237 static void build_bytes PARAMS ((const struct h8_instruction *, struct h8_op *));
238 static void do_a_fix_imm PARAMS ((int, struct h8_op *, int));
239 static void check_operand PARAMS ((struct h8_op *, unsigned int, char *));
240 static const struct h8_instruction * get_specific PARAMS ((const struct h8_instruction *, struct h8_op *, int));
241 static char * get_operands PARAMS ((unsigned, char *, struct h8_op *));
242 static void get_operand PARAMS ((char **, struct h8_op *, unsigned, int));
243 static char * skip_colonthing PARAMS ((char *, expressionS *, int *));
244 static char * parse_exp PARAMS ((char *, expressionS *));
245 static int parse_reg PARAMS ((char *, op_type *, unsigned *, int));
246 char * colonmod24 PARAMS ((struct h8_op *, char *));
247
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
259 /* Try to parse a reg name. Return the number of chars consumed. */
260
261 static int
262 parse_reg (src, mode, reg, direction)
263 char *src;
264 op_type *mode;
265 unsigned int *reg;
266 int direction;
267 {
268 char *end;
269 int len;
270
271 /* Cribbed from get_symbol_end. */
272 if (!is_name_beginner (*src) || *src == '\001')
273 return 0;
274 end = src + 1;
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
349 static char *
350 parse_exp (s, op)
351 char *s;
352 expressionS *op;
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
366 static char *
367 skip_colonthing (ptr, exp, mode)
368 char *ptr;
369 expressionS *exp ATTRIBUTE_UNUSED;
370 int *mode;
371 {
372 if (*ptr == ':')
373 {
374 ptr++;
375 *mode &= ~SIZE;
376 if (*ptr == '8')
377 {
378 ptr++;
379 /* ff fill any 8 bit quantity. */
380 /* exp->X_add_number -= 0x100; */
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 }
397 while (ISDIGIT (*ptr))
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
411 @aa:8 absolute 8 bit
412 @aa:16 absolute 16 bit
413 @aa absolute 16 bit
414
415 #xx[:size] immediate data
416 @(exp:[8], pc) pc rel
417 @@aa[:8] memory indirect. */
418
419 char *
420 colonmod24 (op, src)
421 struct h8_op *op;
422 char *src;
423 {
424 int mode = 0;
425 src = skip_colonthing (src, &op->exp, &mode);
426
427 if (!mode)
428 {
429 /* Choose a default mode. */
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 }
444
445 op->mode |= mode;
446 return src;
447 }
448
449 static void
450 get_operand (ptr, op, dst, direction)
451 char **ptr;
452 struct h8_op *op;
453 unsigned int dst ATTRIBUTE_UNUSED;
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
463 /* Check for '(' and ')' for instructions ldm and stm. */
464 if (src[0] == '(' && src[8] == ')')
465 ++ src;
466
467 /* Gross. Gross. ldm and stm have a format not easily handled
468 by get_operand. We deal with it explicitly here. */
469 if (src[0] == 'e' && src[1] == 'r' && ISDIGIT (src[2])
470 && src[3] == '-' && src[4] == 'e' && src[5] == 'r' && ISDIGIT (src[6]))
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;
496 if (src[7] == ')')
497 *ptr = src + 8;
498 else
499 *ptr = src + 7;
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;
524 }
525
526 if (*src == '-')
527 {
528 src++;
529 len = parse_reg (src, &mode, &num, direction);
530 if (len == 0)
531 {
532 /* Oops, not a reg after all, must be ordinary exp. */
533 src--;
534 /* Must be a symbol. */
535 op->mode = ABS | PSIZE | direction;
536 *ptr = skip_colonthing (parse_exp (src, &op->exp),
537 &op->exp, &op->mode);
538
539 return;
540 }
541
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 {
551 /* Disp. */
552 src++;
553
554 /* Start off assuming a 16 bit offset. */
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
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
667 as_bad (_("expect :8 or :16 here"));
668 }
669 else
670 op->mode = PCREL | bsize;
671
672 *ptr = src;
673 }
674 }
675
676 static char *
677 get_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 }
703 break;
704
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
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
722 provided. */
723
724 static const struct h8_instruction *
725 get_specific (instruction, operands, size)
726 const struct h8_instruction *instruction;
727 struct h8_op *operands;
728 int size;
729 {
730 const struct h8_instruction *this_try = instruction;
731 int found = 0;
732 int this_index = instruction->idx;
733
734 /* There's only one ldm/stm and it's easier to just
735 get out quick for them. */
736 if (strcmp (instruction->opcode->name, "stm.l") == 0
737 || strcmp (instruction->opcode->name, "ldm.l") == 0)
738 return this_try;
739
740 while (this_index == instruction->idx && !found)
741 {
742 found = 1;
743
744 this_try = instruction++;
745 if (this_try->noperands == 0)
746 {
747 int this_size;
748
749 this_size = this_try->opcode->how & SN;
750 if (this_size != size && (this_size != SB || size != SN))
751 found = 0;
752 }
753 else
754 {
755 int i;
756
757 for (i = 0; i < this_try->noperands && found; i++)
758 {
759 op_type op = this_try->opcode->args.nib[i];
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
779 /* The size of the reg is v important. */
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;
787 /* But it may not be 24 bits long. */
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 {
796 /* This is ok if the immediate value is sensible. */
797 }
798 else if (op & PCREL)
799 {
800 /* The size of the displacement is important. */
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. */
814 if (op & ABS && op & L_8 && op & DISP)
815 {
816 if (x & L_16)
817 found = 1;
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;
830 }
831 }
832 }
833 }
834 if (found)
835 return this_try;
836 else
837 return 0;
838 }
839
840 static void
841 check_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 {
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. */
853
854 if ((operand->exp.X_add_number & ~width) != 0 &&
855 (operand->exp.X_add_number | width) != (unsigned)(~0))
856 {
857 if (width == 255
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 }
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 }
872 else
873 {
874 as_warn (_("operand %s0x%lx out of range."), string,
875 (unsigned long) operand->exp.X_add_number);
876 }
877 }
878 }
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
891 static void
892 do_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
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:
933 /* This should be done with bfd. */
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;
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 }
943 break;
944 }
945 }
946 else
947 {
948 switch (operand->mode & SIZE)
949 {
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:
962 as_bad (_("Can't work out size of operand.\n"));
963 case L_16:
964 size = 2;
965 where = 0;
966 if (relaxmode == 2)
967 idx = R_MOV16B1;
968 else
969 idx = R_RELWORD;
970 operand->exp.X_add_number =
971 ((operand->exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;
972 break;
973 case L_8:
974 size = 1;
975 where = 0;
976 idx = R_RELBYTE;
977 operand->exp.X_add_number =
978 ((operand->exp.X_add_number & 0xff) ^ 0x80) - 0x80;
979 }
980
981 fix_new_exp (frag_now,
982 offset + where,
983 size,
984 &operand->exp,
985 0,
986 idx);
987 }
988 }
989
990 /* Now we know what sort of opcodes it is, let's build the bytes. */
991
992 static void
993 build_bytes (this_try, operand)
994 const struct h8_instruction *this_try;
995 struct h8_op *operand;
996 {
997 int i;
998 char *output = frag_more (this_try->length);
999 op_type *nibble_ptr = this_try->opcode->data.nib;
1000 op_type c;
1001 unsigned int nibble_count = 0;
1002 int absat = 0;
1003 int immat = 0;
1004 int nib = 0;
1005 int movb = 0;
1006 char asnibbles[30];
1007 char *p = asnibbles;
1008
1009 if (!(this_try->opcode->inbase || Hmode))
1010 as_warn (_("Opcode `%s' with these operand types not available in H8/300 mode"),
1011 this_try->opcode->name);
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)
1021 nib = c;
1022 else
1023 {
1024 if (c & (REG | IND | INC | DEC))
1025 nib = operand[d].reg;
1026
1027 else if ((c & DISPREG) == (DISPREG))
1028 nib = dispreg;
1029
1030 else if (c & ABS)
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)
1043 nib = 0;
1044
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 }
1079 /* Stop it making a fix. */
1080 operand[0].mode = 0;
1081 }
1082
1083 if (c & MEMRELAX)
1084 operand[d].mode |= MEMRELAX;
1085
1086 if (c & B31)
1087 nib |= 0x8;
1088
1089 if (c & MACREG)
1090 {
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;
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. */
1106 if (strcmp (this_try->opcode->name, "stm.l") == 0
1107 || strcmp (this_try->opcode->name, "ldm.l") == 0)
1108 {
1109 int high, low;
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;
1112
1113 asnibbles[2] = high - low;
1114 asnibbles[7] = (this_try->opcode->name[0] == 'l') ? high : low;
1115 }
1116
1117 for (i = 0; i < this_try->length; i++)
1118 output[i] = (asnibbles[i * 2] << 4) | asnibbles[i * 2 + 1];
1119
1120 /* Note if this is a movb instruction -- there's a special relaxation
1121 which only applies to them. */
1122 if (strcmp (this_try->opcode->name, "mov.b") == 0)
1123 movb = 1;
1124
1125 /* Output any fixes. */
1126 for (i = 0; i < 2; i++)
1127 {
1128 int x = operand[i].mode;
1129
1130 if (x & (IMM | DISP))
1131 do_a_fix_imm (output - frag_now->fr_literal + immat,
1132 operand + i, (x & MEMRELAX) != 0);
1133
1134 else if (x & ABS)
1135 do_a_fix_imm (output - frag_now->fr_literal + absat,
1136 operand + i, (x & MEMRELAX) ? movb + 1 : 0);
1137
1138 else if (x & PCREL)
1139 {
1140 int size16 = x & (L_16);
1141 int where = size16 ? 2 : 1;
1142 int size = size16 ? 2 : 1;
1143 int type = size16 ? R_PCRWORD : R_PCRBYTE;
1144 fixS *fixP;
1145
1146 check_operand (operand + i, size16 ? 0x7fff : 0x7f, "@");
1147
1148 if (operand[i].exp.X_add_number & 1)
1149 as_warn (_("branch operand has odd offset (%lx)\n"),
1150 (unsigned long) operand->exp.X_add_number);
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. */
1157 operand[i].exp.X_add_number -= 1;
1158 #endif
1159 operand[i].exp.X_add_number =
1160 ((operand[i].exp.X_add_number & 0xff) ^ 0x80) - 0x80;
1161
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;
1169 }
1170 else if (x & MEMIND)
1171 {
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 {
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;
1189 #endif
1190
1191 /* This jmp may be a jump or a branch. */
1192
1193 check_operand (operand + i, Hmode ? 0xffffff : 0xffff, "@");
1194
1195 if (operand[i].exp.X_add_number & 1)
1196 as_warn (_("branch operand has odd offset (%lx)\n"),
1197 (unsigned long) operand->exp.X_add_number);
1198
1199 if (!Hmode)
1200 operand[i].exp.X_add_number =
1201 ((operand[i].exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;
1202 fix_new_exp (frag_now,
1203 output - frag_now->fr_literal + where,
1204 4,
1205 &operand[i].exp,
1206 0,
1207 R_JMPL1);
1208 }
1209 }
1210 }
1211
1212 /* Try to give an intelligent error message for common and simple to
1213 detect errors. */
1214
1215 static void
1216 clever_message (instruction, operand)
1217 const struct h8_instruction *instruction;
1218 struct h8_op *operand;
1219 {
1220 /* Find out if there was more than one possible opcode. */
1221
1222 if ((instruction + 1)->idx != instruction->idx)
1223 {
1224 int argn;
1225
1226 /* Only one opcode of this flavour, try to guess which operand
1227 didn't match. */
1228 for (argn = 0; argn < instruction->noperands; argn++)
1229 {
1230 switch (instruction->opcode->args.nib[argn])
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:
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
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
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. */
1281
1282 void
1283 md_assemble (str)
1284 char *str;
1285 {
1286 char *op_start;
1287 char *op_end;
1288 struct h8_op operand[2];
1289 const struct h8_instruction *instruction;
1290 const struct h8_instruction *prev_instruction;
1291
1292 char *dot = 0;
1293 char c;
1294 int size;
1295
1296 /* Drop leading whitespace. */
1297 while (*str == ' ')
1298 str++;
1299
1300 /* Find the op code end. */
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
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
1322 instruction = (const struct h8_instruction *)
1323 hash_find (opcode_hash_control, op_start);
1324
1325 if (instruction == NULL)
1326 {
1327 as_bad (_("unknown opcode"));
1328 return;
1329 }
1330
1331 /* We used to set input_line_pointer to the result of get_operands,
1332 but that is wrong. Our caller assumes we don't change it. */
1333
1334 (void) get_operands (instruction->noperands, op_end, operand);
1335 *op_end = c;
1336 prev_instruction = instruction;
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 }
1356 instruction = get_specific (instruction, operand, size);
1357
1358 if (instruction == 0)
1359 {
1360 /* Couldn't find an opcode which matched the operands. */
1361 char *where = frag_more (2);
1362
1363 where[0] = 0x0;
1364 where[1] = 0x0;
1365 clever_message (prev_instruction, operand);
1366
1367 return;
1368 }
1369 if (instruction->size && dot)
1370 {
1371 if (instruction->size != *dot)
1372 {
1373 as_warn (_("mismatch between opcode size and operand size"));
1374 }
1375 }
1376
1377 build_bytes (instruction, operand);
1378 }
1379
1380 #ifndef BFD_ASSEMBLER
1381 void
1382 tc_crawl_symbol_chain (headers)
1383 object_headers *headers ATTRIBUTE_UNUSED;
1384 {
1385 printf (_("call to tc_crawl_symbol_chain \n"));
1386 }
1387 #endif
1388
1389 symbolS *
1390 md_undefined_symbol (name)
1391 char *name ATTRIBUTE_UNUSED;
1392 {
1393 return 0;
1394 }
1395
1396 #ifndef BFD_ASSEMBLER
1397 void
1398 tc_headers_hook (headers)
1399 object_headers *headers ATTRIBUTE_UNUSED;
1400 {
1401 printf (_("call to tc_headers_hook \n"));
1402 }
1403 #endif
1404
1405 /* Various routines to kill one day */
1406 /* Equal to MAX_PRECISION in atof-ieee.c */
1407 #define MAX_LITTLENUMS 6
1408
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
1411 of LITTLENUMS emitted is stored in *SIZEP. An error message is
1412 returned, or NULL on OK. */
1413
1414 char *
1415 md_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;
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
1468 const char *md_shortopts = "";
1469 struct option md_longopts[] = {
1470 {NULL, no_argument, NULL, 0}
1471 };
1472
1473 size_t md_longopts_size = sizeof (md_longopts);
1474
1475 int
1476 md_parse_option (c, arg)
1477 int c ATTRIBUTE_UNUSED;
1478 char *arg ATTRIBUTE_UNUSED;
1479 {
1480 return 0;
1481 }
1482
1483 void
1484 md_show_usage (stream)
1485 FILE *stream ATTRIBUTE_UNUSED;
1486 {
1487 }
1488 \f
1489 void tc_aout_fix_to_chars PARAMS ((void));
1490
1491 void
1492 tc_aout_fix_to_chars ()
1493 {
1494 printf (_("call to tc_aout_fix_to_chars \n"));
1495 abort ();
1496 }
1497
1498 void
1499 md_convert_frag (headers, seg, fragP)
1500 #ifdef BFD_ASSEMBLER
1501 bfd *headers ATTRIBUTE_UNUSED;
1502 #else
1503 object_headers *headers ATTRIBUTE_UNUSED;
1504 #endif
1505 segT seg ATTRIBUTE_UNUSED;
1506 fragS *fragP ATTRIBUTE_UNUSED;
1507 {
1508 printf (_("call to md_convert_frag \n"));
1509 abort ();
1510 }
1511
1512 #ifdef BFD_ASSEMBLER
1513 valueT
1514 md_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
1522 valueT
1523 md_section_align (seg, size)
1524 segT seg;
1525 valueT size;
1526 {
1527 return ((size + (1 << section_alignment[(int) seg]) - 1)
1528 & (-1 << section_alignment[(int) seg]));
1529 }
1530 #endif
1531
1532
1533 void
1534 md_apply_fix3 (fixP, valP, seg)
1535 fixS *fixP;
1536 valueT *valP;
1537 segT seg ATTRIBUTE_UNUSED;
1538 {
1539 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1540 long val = *valP;
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 }
1560
1561 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1562 fixP->fx_done = 1;
1563 }
1564
1565 int
1566 md_estimate_size_before_relax (fragP, segment_type)
1567 register fragS *fragP ATTRIBUTE_UNUSED;
1568 register segT segment_type ATTRIBUTE_UNUSED;
1569 {
1570 printf (_("call tomd_estimate_size_before_relax \n"));
1571 abort ();
1572 }
1573
1574 /* Put number into target byte order. */
1575 void
1576 md_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 }
1583
1584 long
1585 md_pcrel_from (fixP)
1586 fixS *fixP ATTRIBUTE_UNUSED;
1587 {
1588 abort ();
1589 }
1590
1591 #ifndef BFD_ASSEMBLER
1592 void
1593 tc_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
1604 to output it. */
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 ();
1622 }
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;
1653 }
1654 #else /* BFD_ASSEMBLER */
1655 arelent *
1656 tc_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
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
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.086004 seconds and 3 git commands to generate.