source: trunk/binutils/gas/config/tc-h8500.c@ 2562

Last change on this file since 2562 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 31.7 KB
Line 
1/* tc-h8500.c -- Assemble code for the Renesas H8/500
2 Copyright 1993, 1994, 1995, 1998, 2000, 2001, 2002, 2003
3 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 "bfd.h"
27#include "subsegs.h"
28#define DEFINE_TABLE
29#define ASSEMBLER_TABLE
30#include "opcodes/h8500-opc.h"
31#include "safe-ctype.h"
32
33const char comment_chars[] = "!";
34const char line_separator_chars[] = ";";
35const char line_comment_chars[] = "!#";
36
37/* This table describes all the machine specific pseudo-ops the assembler
38 has to support. The fields are:
39 pseudo-op name without dot
40 function to call to execute this pseudo-op
41 Integer arg to pass to the function
42 */
43
44const pseudo_typeS md_pseudo_table[] =
45{
46 {"int", cons, 2},
47 {"data.b", cons, 1},
48 {"data.w", cons, 2},
49 {"data.l", cons, 4},
50 {"form", listing_psize, 0},
51 {"heading", listing_title, 0},
52 {"import", s_ignore, 0},
53 {"page", listing_eject, 0},
54 {"program", s_ignore, 0},
55 {0, 0, 0}
56};
57
58const int md_reloc_size;
59
60const char EXP_CHARS[] = "eE";
61
62/* Chars that mean this number is a floating point constant */
63/* As in 0f12.456 */
64/* or 0d1.2345e12 */
65const char FLT_CHARS[] = "rRsSfFdDxXpP";
66
67#define C(a,b) ENCODE_RELAX(a,b)
68#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
69
70#define GET_WHAT(x) ((x>>2))
71
72#define BYTE_DISP 1
73#define WORD_DISP 2
74#define UNDEF_BYTE_DISP 0
75#define UNDEF_WORD_DISP 3
76
77#define BRANCH 1
78#define SCB_F 2
79#define SCB_TST 3
80#define END 4
81
82#define BYTE_F 127
83#define BYTE_B -126
84#define WORD_F 32767
85#define WORD_B 32768
86
87relax_typeS md_relax_table[C (END, 0)] = {
88 { 0, 0, 0, 0 },
89 { 0, 0, 0, 0 },
90 { 0, 0, 0, 0 },
91 { 0, 0, 0, 0 },
92
93 /* BRANCH */
94 { 0, 0, 0, 0 },
95 { BYTE_F, BYTE_B, 2, C (BRANCH, WORD_DISP) },
96 { WORD_F, WORD_B, 3, 0 },
97 { 0, 0, 3, 0 },
98
99 /* SCB_F */
100 { 0, 0, 0, 0 },
101 { BYTE_F, BYTE_B, 3, C (SCB_F, WORD_DISP) },
102 { WORD_F, WORD_B, 8, 0 },
103 { 0, 0, 8, 0 },
104
105 /* SCB_TST */
106 { 0, 0, 0, 0 },
107 { BYTE_F, BYTE_B, 3, C (SCB_TST, WORD_DISP) },
108 { WORD_F, WORD_B, 10, 0 },
109 { 0, 0, 10, 0 }
110
111};
112
113static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
114
115/*
116 This function is called once, at assembler startup time. This should
117 set up all the tables, etc. that the MD part of the assembler needs
118 */
119
120void
121md_begin ()
122{
123 const h8500_opcode_info *opcode;
124 char prev_buffer[100];
125 int idx = 0;
126
127 opcode_hash_control = hash_new ();
128 prev_buffer[0] = 0;
129
130 /* Insert unique names into hash table */
131 for (opcode = h8500_table; opcode->name; opcode++)
132 {
133 if (idx != opcode->idx)
134 {
135 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
136 idx++;
137 }
138 }
139}
140
141static int rn; /* register number used by RN */
142static int rs; /* register number used by RS */
143static int rd; /* register number used by RD */
144static int crb; /* byte size cr */
145static int crw; /* word sized cr */
146static int cr; /* unknown size cr */
147
148static expressionS displacement;/* displacement expression */
149
150static int immediate_inpage;
151static expressionS immediate; /* immediate expression */
152
153static expressionS absolute; /* absolute expression */
154
155typedef struct
156{
157 int type;
158 int reg;
159 expressionS exp;
160 int page;
161}
162
163h8500_operand_info;
164
165/* Try to parse a reg name. Return the number of chars consumed. */
166
167static int parse_reg PARAMS ((char *, int *, int *));
168
169static int
170parse_reg (src, mode, reg)
171 char *src;
172 int *mode;
173 int *reg;
174{
175 char *end;
176 int len;
177
178 /* Cribbed from get_symbol_end(). */
179 if (!is_name_beginner (*src) || *src == '\001')
180 return 0;
181 end = src + 1;
182 while (is_part_of_name (*end) || *end == '\001')
183 end++;
184 len = end - src;
185
186 if (len == 2 && src[0] == 'r')
187 {
188 if (src[1] >= '0' && src[1] <= '7')
189 {
190 *mode = RN;
191 *reg = (src[1] - '0');
192 return len;
193 }
194 }
195 if (len == 2 && src[0] == 's' && src[1] == 'p')
196 {
197 *mode = RN;
198 *reg = 7;
199 return len;
200 }
201 if (len == 3 && src[0] == 'c' && src[1] == 'c' && src[2] == 'r')
202 {
203 *mode = CRB;
204 *reg = 1;
205 return len;
206 }
207 if (len == 2 && src[0] == 's' && src[1] == 'r')
208 {
209 *mode = CRW;
210 *reg = 0;
211 return len;
212 }
213 if (len == 2 && src[0] == 'b' && src[1] == 'r')
214 {
215 *mode = CRB;
216 *reg = 3;
217 return len;
218 }
219 if (len == 2 && src[0] == 'e' && src[1] == 'p')
220 {
221 *mode = CRB;
222 *reg = 4;
223 return len;
224 }
225 if (len == 2 && src[0] == 'd' && src[1] == 'p')
226 {
227 *mode = CRB;
228 *reg = 5;
229 return len;
230 }
231 if (len == 2 && src[0] == 't' && src[1] == 'p')
232 {
233 *mode = CRB;
234 *reg = 7;
235 return len;
236 }
237 if (len == 2 && src[0] == 'f' && src[1] == 'p')
238 {
239 *mode = RN;
240 *reg = 6;
241 return len;
242 }
243 return 0;
244}
245
246static char *parse_exp PARAMS ((char *, expressionS *, int *));
247
248static char *
249parse_exp (s, op, page)
250 char *s;
251 expressionS *op;
252 int *page;
253{
254 char *save;
255 char *new;
256
257 save = input_line_pointer;
258
259 *page = 0;
260 if (s[0] == '%')
261 {
262 if (s[1] == 'p' && s[2] == 'a' && s[3] == 'g' && s[4] == 'e')
263 {
264 s += 5;
265 *page = 'p';
266 }
267 if (s[1] == 'h' && s[2] == 'i' && s[3] == '1' && s[4] == '6')
268 {
269 s += 5;
270 *page = 'h';
271 }
272 else if (s[1] == 'o' && s[2] == 'f' && s[3] == 'f')
273 {
274 s += 4;
275 *page = 'o';
276 }
277 }
278
279 input_line_pointer = s;
280
281 expression (op);
282 if (op->X_op == O_absent)
283 as_bad (_("missing operand"));
284 new = input_line_pointer;
285 input_line_pointer = save;
286 return new;
287}
288
289typedef enum
290 {
291 exp_signed, exp_unsigned, exp_sandu
292 } sign_type;
293
294static char *skip_colonthing
295 PARAMS ((sign_type, char *, h8500_operand_info *, int, int, int, int));
296
297static char *
298skip_colonthing (sign, ptr, exp, def, size8, size16, size24)
299 sign_type sign;
300 char *ptr;
301 h8500_operand_info *exp;
302 int def;
303 int size8;
304 int size16;
305 int size24;
306{
307 ptr = parse_exp (ptr, &exp->exp, &exp->page);
308 if (*ptr == ':')
309 {
310 ptr++;
311 if (*ptr == '8')
312 {
313 ptr++;
314 exp->type = size8;
315 }
316 else if (ptr[0] == '1' && ptr[1] == '6')
317 {
318 ptr += 2;
319 exp->type = size16;
320 }
321 else if (ptr[0] == '2' && ptr[1] == '4')
322 {
323 if (!size24)
324 {
325 as_bad (_(":24 not valid for this opcode"));
326 }
327 ptr += 2;
328 exp->type = size24;
329 }
330 else
331 {
332 as_bad (_("expect :8,:16 or :24"));
333 exp->type = size16;
334 }
335 }
336 else
337 {
338 if (exp->page == 'p')
339 {
340 exp->type = IMM8;
341 }
342 else if (exp->page == 'h')
343 {
344 exp->type = IMM16;
345 }
346 else
347 {
348 /* Let's work out the size from the context */
349 int n = exp->exp.X_add_number;
350 if (size8
351 && exp->exp.X_op == O_constant
352 && ((sign == exp_signed && (n >= -128 && n <= 127))
353 || (sign == exp_unsigned && (n >= 0 && (n <= 255)))
354 || (sign == exp_sandu && (n >= -128 && (n <= 255)))))
355 {
356 exp->type = size8;
357 }
358 else
359 {
360 exp->type = def;
361 }
362 }
363 }
364 return ptr;
365}
366
367static int parse_reglist PARAMS ((char *, h8500_operand_info *));
368
369static int
370parse_reglist (src, op)
371 char *src;
372 h8500_operand_info *op;
373{
374 int mode;
375 int rn;
376 int mask = 0;
377 int rm;
378 int idx = 1; /* skip ( */
379
380 while (src[idx] && src[idx] != ')')
381 {
382 int done = parse_reg (src + idx, &mode, &rn);
383
384 if (done)
385 {
386 idx += done;
387 mask |= 1 << rn;
388 }
389 else
390 {
391 as_bad (_("syntax error in reg list"));
392 return 0;
393 }
394 if (src[idx] == '-')
395 {
396 idx++;
397 done = parse_reg (src + idx, &mode, &rm);
398 if (done)
399 {
400 idx += done;
401 while (rn <= rm)
402 {
403 mask |= 1 << rn;
404 rn++;
405 }
406 }
407 else
408 {
409 as_bad (_("missing final register in range"));
410 }
411 }
412 if (src[idx] == ',')
413 idx++;
414 }
415 idx++;
416 op->exp.X_add_symbol = 0;
417 op->exp.X_op_symbol = 0;
418 op->exp.X_add_number = mask;
419 op->exp.X_op = O_constant;
420 op->exp.X_unsigned = 1;
421 op->type = IMM8;
422 return idx;
423
424}
425
426/* The many forms of operand:
427
428 Rn Register direct
429 @Rn Register indirect
430 @(disp[:size], Rn) Register indirect with displacement
431 @Rn+
432 @-Rn
433 @aa[:size] absolute
434 #xx[:size] immediate data
435
436 */
437
438static void get_operand PARAMS ((char **, h8500_operand_info *, char));
439
440static void
441get_operand (ptr, op, ispage)
442 char **ptr;
443 h8500_operand_info *op;
444 char ispage;
445{
446 char *src = *ptr;
447 int mode;
448 unsigned int num;
449 unsigned int len;
450 op->page = 0;
451 if (src[0] == '(' && src[1] == 'r')
452 {
453 /* This is a register list */
454 *ptr = src + parse_reglist (src, op);
455 return;
456 }
457
458 len = parse_reg (src, &op->type, &op->reg);
459
460 if (len)
461 {
462 *ptr = src + len;
463 return;
464 }
465
466 if (*src == '@')
467 {
468 src++;
469 if (*src == '-')
470 {
471 src++;
472 len = parse_reg (src, &mode, &num);
473 if (len == 0)
474 {
475 /* Oops, not a reg after all, must be ordinary exp */
476 src--;
477 /* must be a symbol */
478 *ptr = skip_colonthing (exp_unsigned, src,
479 op, ABS16, ABS8, ABS16, ABS24);
480 return;
481 }
482
483 op->type = RNDEC;
484 op->reg = num;
485 *ptr = src + len;
486 return;
487 }
488 if (*src == '(')
489 {
490 /* Disp */
491 src++;
492
493 src = skip_colonthing (exp_signed, src,
494 op, RNIND_D16, RNIND_D8, RNIND_D16, 0);
495
496 if (*src != ',')
497 {
498 as_bad (_("expected @(exp, Rn)"));
499 return;
500 }
501 src++;
502 len = parse_reg (src, &mode, &op->reg);
503 if (len == 0 || mode != RN)
504 {
505 as_bad (_("expected @(exp, Rn)"));
506 return;
507 }
508 src += len;
509 if (*src != ')')
510 {
511 as_bad (_("expected @(exp, Rn)"));
512 return;
513 }
514 *ptr = src + 1;
515 return;
516 }
517 len = parse_reg (src, &mode, &num);
518
519 if (len)
520 {
521 src += len;
522 if (*src == '+')
523 {
524 src++;
525 if (mode != RN)
526 {
527 as_bad (_("@Rn+ needs word register"));
528 return;
529 }
530 op->type = RNINC;
531 op->reg = num;
532 *ptr = src;
533 return;
534 }
535 if (mode != RN)
536 {
537 as_bad (_("@Rn needs word register"));
538 return;
539 }
540 op->type = RNIND;
541 op->reg = num;
542 *ptr = src;
543 return;
544 }
545 else
546 {
547 /* must be a symbol */
548 *ptr =
549 skip_colonthing (exp_unsigned, src, op,
550 ispage ? ABS24 : ABS16, ABS8, ABS16, ABS24);
551 return;
552 }
553 }
554
555 if (*src == '#')
556 {
557 src++;
558 *ptr = skip_colonthing (exp_sandu, src, op, IMM16, IMM8, IMM16, ABS24);
559 return;
560 }
561 else
562 {
563 *ptr = skip_colonthing (exp_signed, src, op,
564 ispage ? ABS24 : PCREL8, PCREL8, PCREL16, ABS24);
565 }
566}
567
568static char *get_operands
569 PARAMS ((h8500_opcode_info *, char *, h8500_operand_info *));
570
571static char *
572get_operands (info, args, operand)
573 h8500_opcode_info *info;
574 char *args;
575 h8500_operand_info *operand;
576{
577 char *ptr = args;
578
579 switch (info->nargs)
580 {
581 case 0:
582 operand[0].type = 0;
583 operand[1].type = 0;
584 break;
585
586 case 1:
587 ptr++;
588 get_operand (&ptr, operand + 0, info->name[0] == 'p');
589 operand[1].type = 0;
590 break;
591
592 case 2:
593 ptr++;
594 get_operand (&ptr, operand + 0, 0);
595 if (*ptr == ',')
596 ptr++;
597 get_operand (&ptr, operand + 1, 0);
598 break;
599
600 default:
601 abort ();
602 }
603
604 return ptr;
605}
606
607/* Passed a pointer to a list of opcodes which use different
608 addressing modes, return the opcode which matches the opcodes
609 provided. */
610
611int pcrel8; /* Set when we've seen a pcrel operand */
612
613static h8500_opcode_info *get_specific
614 PARAMS ((h8500_opcode_info *, h8500_operand_info *));
615
616static h8500_opcode_info *
617get_specific (opcode, operands)
618 h8500_opcode_info *opcode;
619 h8500_operand_info *operands;
620{
621 h8500_opcode_info *this_try = opcode;
622 int found = 0;
623 unsigned int noperands = opcode->nargs;
624 int this_index = opcode->idx;
625
626 while (this_index == opcode->idx && !found)
627 {
628 unsigned int i;
629
630 this_try = opcode++;
631
632 /* look at both operands needed by the opcodes and provided by
633 the user*/
634 for (i = 0; i < noperands; i++)
635 {
636 h8500_operand_info *user = operands + i;
637
638 switch (this_try->arg_type[i])
639 {
640 case FPIND_D8:
641 /* Opcode needs (disp:8,fp) */
642 if (user->type == RNIND_D8 && user->reg == 6)
643 {
644 displacement = user->exp;
645 continue;
646 }
647 break;
648 case RDIND_D16:
649 if (user->type == RNIND_D16)
650 {
651 displacement = user->exp;
652 rd = user->reg;
653 continue;
654 }
655 break;
656 case RDIND_D8:
657 if (user->type == RNIND_D8)
658 {
659 displacement = user->exp;
660 rd = user->reg;
661 continue;
662 }
663 break;
664 case RNIND_D16:
665 case RNIND_D8:
666 if (user->type == this_try->arg_type[i])
667 {
668 displacement = user->exp;
669 rn = user->reg;
670 continue;
671 }
672 break;
673
674 case SPDEC:
675 if (user->type == RNDEC && user->reg == 7)
676 {
677 continue;
678 }
679 break;
680 case SPINC:
681 if (user->type == RNINC && user->reg == 7)
682 {
683 continue;
684 }
685 break;
686 case ABS16:
687 if (user->type == ABS16)
688 {
689 absolute = user->exp;
690 continue;
691 }
692 break;
693 case ABS8:
694 if (user->type == ABS8)
695 {
696 absolute = user->exp;
697 continue;
698 }
699 break;
700 case ABS24:
701 if (user->type == ABS24)
702 {
703 absolute = user->exp;
704 continue;
705 }
706 break;
707
708 case CRB:
709 if ((user->type == CRB || user->type == CR) && user->reg != 0)
710 {
711 crb = user->reg;
712 continue;
713 }
714 break;
715 case CRW:
716 if ((user->type == CRW || user->type == CR) && user->reg == 0)
717 {
718 crw = user->reg;
719 continue;
720 }
721 break;
722 case DISP16:
723 if (user->type == DISP16)
724 {
725 displacement = user->exp;
726 continue;
727 }
728 break;
729 case DISP8:
730 if (user->type == DISP8)
731 {
732 displacement = user->exp;
733 continue;
734 }
735 break;
736 case FP:
737 if (user->type == RN && user->reg == 6)
738 {
739 continue;
740 }
741 break;
742 case PCREL16:
743 if (user->type == PCREL16)
744 {
745 displacement = user->exp;
746 continue;
747 }
748 break;
749 case PCREL8:
750 if (user->type == PCREL8)
751 {
752 displacement = user->exp;
753 pcrel8 = 1;
754 continue;
755 }
756 break;
757
758 case IMM16:
759 if (user->type == IMM16
760 || user->type == IMM8)
761 {
762 immediate_inpage = user->page;
763 immediate = user->exp;
764 continue;
765 }
766 break;
767 case RLIST:
768 case IMM8:
769 if (user->type == IMM8)
770 {
771 immediate_inpage = user->page;
772 immediate = user->exp;
773 continue;
774 }
775 break;
776 case IMM4:
777 if (user->type == IMM8)
778 {
779 immediate_inpage = user->page;
780 immediate = user->exp;
781 continue;
782 }
783 break;
784 case QIM:
785 if (user->type == IMM8
786 && user->exp.X_op == O_constant
787 &&
788 (user->exp.X_add_number == -2
789 || user->exp.X_add_number == -1
790 || user->exp.X_add_number == 1
791 || user->exp.X_add_number == 2))
792 {
793 immediate_inpage = user->page;
794 immediate = user->exp;
795 continue;
796 }
797 break;
798 case RD:
799 if (user->type == RN)
800 {
801 rd = user->reg;
802 continue;
803 }
804 break;
805 case RS:
806 if (user->type == RN)
807 {
808 rs = user->reg;
809 continue;
810 }
811 break;
812 case RDIND:
813 if (user->type == RNIND)
814 {
815 rd = user->reg;
816 continue;
817
818 }
819 break;
820 case RNINC:
821 case RNIND:
822 case RNDEC:
823 case RN:
824
825 if (user->type == this_try->arg_type[i])
826 {
827 rn = user->reg;
828 continue;
829 }
830 break;
831 case SP:
832 if (user->type == RN && user->reg == 7)
833 {
834 continue;
835 }
836 break;
837 default:
838 printf (_("unhandled %d\n"), this_try->arg_type[i]);
839 break;
840 }
841
842 /* If we get here this didn't work out */
843 goto fail;
844 }
845 found = 1;
846 fail:;
847
848 }
849
850 if (found)
851 return this_try;
852 else
853 return 0;
854}
855
856static int check PARAMS ((expressionS *, int, int));
857
858static int
859check (operand, low, high)
860 expressionS *operand;
861 int low;
862 int high;
863{
864 if (operand->X_op != O_constant
865 || operand->X_add_number < low
866 || operand->X_add_number > high)
867 {
868 as_bad (_("operand must be absolute in range %d..%d"), low, high);
869 }
870 return operand->X_add_number;
871}
872
873static void insert PARAMS ((char *, int, expressionS *, int, int));
874
875static void
876insert (output, index, exp, reloc, pcrel)
877 char *output;
878 int index;
879 expressionS *exp;
880 int reloc;
881 int pcrel;
882{
883 fix_new_exp (frag_now,
884 output - frag_now->fr_literal + index,
885 4, /* always say size is 4, but we know better */
886 exp,
887 pcrel,
888 reloc);
889}
890
891static void build_relaxable_instruction
892 PARAMS ((h8500_opcode_info *, h8500_operand_info *));
893
894static void
895build_relaxable_instruction (opcode, operand)
896 h8500_opcode_info *opcode;
897 h8500_operand_info *operand ATTRIBUTE_UNUSED;
898{
899 /* All relaxable instructions start life as two bytes but can become
900 three bytes long if a lonely branch and up to 9 bytes if long
901 scb. */
902 char *p;
903 int len;
904 int type;
905
906 if (opcode->bytes[0].contents == 0x01)
907 {
908 type = SCB_F;
909 }
910 else if (opcode->bytes[0].contents == 0x06
911 || opcode->bytes[0].contents == 0x07)
912 {
913 type = SCB_TST;
914 }
915 else
916 {
917 type = BRANCH;
918 }
919
920 p = frag_var (rs_machine_dependent,
921 md_relax_table[C (type, WORD_DISP)].rlx_length,
922 len = md_relax_table[C (type, BYTE_DISP)].rlx_length,
923 C (type, UNDEF_BYTE_DISP),
924 displacement.X_add_symbol,
925 displacement.X_add_number,
926 0);
927
928 p[0] = opcode->bytes[0].contents;
929 if (type != BRANCH)
930 {
931 p[1] = opcode->bytes[1].contents | rs;
932 }
933}
934
935/* Now we know what sort of opcodes it is, let's build the bytes. */
936
937static void build_bytes PARAMS ((h8500_opcode_info *, h8500_operand_info *));
938
939static void
940build_bytes (opcode, operand)
941 h8500_opcode_info *opcode;
942 h8500_operand_info *operand;
943{
944 int index;
945
946 if (pcrel8)
947 {
948 pcrel8 = 0;
949 build_relaxable_instruction (opcode, operand);
950 }
951 else
952 {
953 char *output = frag_more (opcode->length);
954
955 memset (output, 0, opcode->length);
956 for (index = 0; index < opcode->length; index++)
957 {
958 output[index] = opcode->bytes[index].contents;
959
960 switch (opcode->bytes[index].insert)
961 {
962 default:
963 printf (_("failed for %d\n"), opcode->bytes[index].insert);
964 break;
965 case 0:
966 break;
967 case RN:
968 output[index] |= rn;
969 break;
970 case RD:
971 case RDIND:
972 output[index] |= rd;
973 break;
974 case RS:
975 output[index] |= rs;
976 break;
977 case DISP16:
978 insert (output, index, &displacement, R_H8500_IMM16, 0);
979 index++;
980 break;
981 case DISP8:
982 case FPIND_D8:
983 insert (output, index, &displacement, R_H8500_IMM8, 0);
984 break;
985 case IMM16:
986 {
987 int p;
988
989 switch (immediate_inpage)
990 {
991 case 'p':
992 p = R_H8500_HIGH16;
993 break;
994 case 'h':
995 p = R_H8500_HIGH16;
996 break;
997 default:
998 p = R_H8500_IMM16;
999 break;
1000 }
1001 insert (output, index, &immediate, p, 0);
1002 }
1003 index++;
1004 break;
1005 case RLIST:
1006 case IMM8:
1007 if (immediate_inpage)
1008 insert (output, index, &immediate, R_H8500_HIGH8, 0);
1009 else
1010 insert (output, index, &immediate, R_H8500_IMM8, 0);
1011 break;
1012 case PCREL16:
1013 insert (output, index, &displacement, R_H8500_PCREL16, 1);
1014 index++;
1015 break;
1016 case PCREL8:
1017 insert (output, index, &displacement, R_H8500_PCREL8, 1);
1018 break;
1019 case IMM4:
1020 output[index] |= check (&immediate, 0, 15);
1021 break;
1022 case CR:
1023 output[index] |= cr;
1024 if (cr == 0)
1025 output[0] |= 0x8;
1026 else
1027 output[0] &= ~0x8;
1028 break;
1029 case CRB:
1030 output[index] |= crb;
1031 output[0] &= ~0x8;
1032 break;
1033 case CRW:
1034 output[index] |= crw;
1035 output[0] |= 0x8;
1036 break;
1037 case ABS24:
1038 insert (output, index, &absolute, R_H8500_IMM24, 0);
1039 index += 2;
1040 break;
1041 case ABS16:
1042 insert (output, index, &absolute, R_H8500_IMM16, 0);
1043 index++;
1044 break;
1045 case ABS8:
1046 insert (output, index, &absolute, R_H8500_IMM8, 0);
1047 break;
1048 case QIM:
1049 switch (immediate.X_add_number)
1050 {
1051 case -2:
1052 output[index] |= 0x5;
1053 break;
1054 case -1:
1055 output[index] |= 0x4;
1056 break;
1057 case 1:
1058 output[index] |= 0;
1059 break;
1060 case 2:
1061 output[index] |= 1;
1062 break;
1063 }
1064 break;
1065 }
1066 }
1067 }
1068}
1069
1070/* This is the guts of the machine-dependent assembler. STR points to
1071 a machine dependent instruction. This function is supposed to emit
1072 the frags/bytes it assembles to. */
1073
1074void
1075md_assemble (str)
1076 char *str;
1077{
1078 char *op_start;
1079 char *op_end;
1080 h8500_operand_info operand[2];
1081 h8500_opcode_info *opcode;
1082 h8500_opcode_info *prev_opcode;
1083 char name[11];
1084
1085 int nlen = 0;
1086
1087 /* Drop leading whitespace. */
1088 while (*str == ' ')
1089 str++;
1090
1091 /* Find the op code end. */
1092 for (op_start = op_end = str;
1093 !is_end_of_line[(unsigned char) *op_end] && *op_end != ' ';
1094 op_end++)
1095 {
1096 if ( /**op_end != '.'
1097 && *op_end != ':'
1098 && */ nlen < 10)
1099 {
1100 name[nlen++] = *op_end;
1101 }
1102 }
1103 name[nlen] = 0;
1104
1105 if (op_end == op_start)
1106 as_bad (_("can't find opcode "));
1107
1108 opcode = (h8500_opcode_info *) hash_find (opcode_hash_control, name);
1109
1110 if (opcode == NULL)
1111 {
1112 as_bad (_("unknown opcode"));
1113 return;
1114 }
1115
1116 get_operands (opcode, op_end, operand);
1117 prev_opcode = opcode;
1118
1119 opcode = get_specific (opcode, operand);
1120
1121 if (opcode == 0)
1122 {
1123 /* Couldn't find an opcode which matched the operands */
1124 char *where = frag_more (2);
1125
1126 where[0] = 0x0;
1127 where[1] = 0x0;
1128 as_bad (_("invalid operands for opcode"));
1129 return;
1130 }
1131
1132 build_bytes (opcode, operand);
1133}
1134
1135void
1136tc_crawl_symbol_chain (headers)
1137 object_headers *headers ATTRIBUTE_UNUSED;
1138{
1139 printf (_("call to tc_crawl_symbol_chain \n"));
1140}
1141
1142symbolS *
1143md_undefined_symbol (name)
1144 char *name ATTRIBUTE_UNUSED;
1145{
1146 return 0;
1147}
1148
1149void
1150tc_headers_hook (headers)
1151 object_headers *headers ATTRIBUTE_UNUSED;
1152{
1153 printf (_("call to tc_headers_hook \n"));
1154}
1155
1156/* Various routines to kill one day. */
1157/* Equal to MAX_PRECISION in atof-ieee.c. */
1158#define MAX_LITTLENUMS 6
1159
1160/* Turn a string in input_line_pointer into a floating point constant
1161 of type type, and store the appropriate bytes in *LITP. The number
1162 of LITTLENUMS emitted is stored in *SIZEP. An error message is
1163 returned, or NULL on OK. */
1164
1165char *
1166md_atof (type, litP, sizeP)
1167 char type;
1168 char *litP;
1169 int *sizeP;
1170{
1171 int prec;
1172 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1173 LITTLENUM_TYPE *wordP;
1174 char *t;
1175
1176 switch (type)
1177 {
1178 case 'f':
1179 case 'F':
1180 case 's':
1181 case 'S':
1182 prec = 2;
1183 break;
1184
1185 case 'd':
1186 case 'D':
1187 case 'r':
1188 case 'R':
1189 prec = 4;
1190 break;
1191
1192 case 'x':
1193 case 'X':
1194 prec = 6;
1195 break;
1196
1197 case 'p':
1198 case 'P':
1199 prec = 6;
1200 break;
1201
1202 default:
1203 *sizeP = 0;
1204 return _("Bad call to MD_ATOF()");
1205 }
1206 t = atof_ieee (input_line_pointer, type, words);
1207 if (t)
1208 input_line_pointer = t;
1209
1210 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1211 for (wordP = words; prec--;)
1212 {
1213 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
1214 litP += sizeof (LITTLENUM_TYPE);
1215 }
1216 return 0;
1217}
1218
1219
1220const char *md_shortopts = "";
1221struct option md_longopts[] = {
1222 {NULL, no_argument, NULL, 0}
1223};
1224size_t md_longopts_size = sizeof (md_longopts);
1225
1226int
1227md_parse_option (c, arg)
1228 int c ATTRIBUTE_UNUSED;
1229 char *arg ATTRIBUTE_UNUSED;
1230{
1231 return 0;
1232}
1233
1234void
1235md_show_usage (stream)
1236 FILE *stream ATTRIBUTE_UNUSED;
1237{
1238}
1239
1240
1241static void wordify_scb PARAMS ((char *, int *, int *));
1242
1243static void
1244wordify_scb (buffer, disp_size, inst_size)
1245 char *buffer;
1246 int *disp_size;
1247 int *inst_size;
1248{
1249 int rn = buffer[1] & 0x7;
1250
1251 switch (buffer[0])
1252 {
1253 case 0x0e: /* BSR */
1254 case 0x20:
1255 case 0x21:
1256 case 0x22:
1257 case 0x23:
1258 case 0x24:
1259 case 0x25:
1260 case 0x26:
1261 case 0x27:
1262 case 0x28:
1263 case 0x29:
1264 case 0x2a:
1265 case 0x2b:
1266 case 0x2c:
1267 case 0x2d:
1268 case 0x2e:
1269 case 0x2f:
1270 buffer[0] |= 0x10;
1271 buffer[1] = 0;
1272 buffer[2] = 0;
1273 *disp_size = 2;
1274 *inst_size = 1;
1275 return;
1276 default:
1277 abort ();
1278
1279 case 0x01:
1280 *inst_size = 6;
1281 *disp_size = 2;
1282 break;
1283 case 0x06:
1284 *inst_size = 8;
1285 *disp_size = 2;
1286
1287 *buffer++ = 0x26; /* bne + 8 */
1288 *buffer++ = 0x08;
1289 break;
1290 case 0x07:
1291 *inst_size = 8;
1292 *disp_size = 2;
1293 *buffer++ = 0x27; /* bne + 8 */
1294 *buffer++ = 0x08;
1295 break;
1296
1297 }
1298 *buffer++ = 0xa8 | rn; /* addq -1,rn */
1299 *buffer++ = 0x0c;
1300 *buffer++ = 0x04; /* cmp #0xff:8, rn */
1301 *buffer++ = 0xff;
1302 *buffer++ = 0x70 | rn;
1303 *buffer++ = 0x36; /* bne ... */
1304 *buffer++ = 0;
1305 *buffer++ = 0;
1306}
1307
1308/* Called after relaxing, change the frags so they know how big they
1309 are. */
1310
1311void
1312md_convert_frag (headers, seg, fragP)
1313 object_headers *headers ATTRIBUTE_UNUSED;
1314 segT seg ATTRIBUTE_UNUSED;
1315 fragS *fragP;
1316{
1317 int disp_size = 0;
1318 int inst_size = 0;
1319 char *buffer = fragP->fr_fix + fragP->fr_literal;
1320
1321 switch (fragP->fr_subtype)
1322 {
1323 case C (BRANCH, BYTE_DISP):
1324 disp_size = 1;
1325 inst_size = 1;
1326 break;
1327
1328 case C (SCB_F, BYTE_DISP):
1329 case C (SCB_TST, BYTE_DISP):
1330 disp_size = 1;
1331 inst_size = 2;
1332 break;
1333
1334 /* Branches to a known 16 bit displacement. */
1335
1336 /* Turn on the 16bit bit. */
1337 case C (BRANCH, WORD_DISP):
1338 case C (SCB_F, WORD_DISP):
1339 case C (SCB_TST, WORD_DISP):
1340 wordify_scb (buffer, &disp_size, &inst_size);
1341 break;
1342
1343 case C (BRANCH, UNDEF_WORD_DISP):
1344 case C (SCB_F, UNDEF_WORD_DISP):
1345 case C (SCB_TST, UNDEF_WORD_DISP):
1346 /* This tried to be relaxed, but didn't manage it, it now needs
1347 a fix. */
1348 wordify_scb (buffer, &disp_size, &inst_size);
1349
1350 /* Make a reloc */
1351 fix_new (fragP,
1352 fragP->fr_fix + inst_size,
1353 4,
1354 fragP->fr_symbol,
1355 fragP->fr_offset,
1356 0,
1357 R_H8500_PCREL16);
1358
1359 fragP->fr_fix += disp_size + inst_size;
1360 return;
1361 break;
1362 default:
1363 abort ();
1364 }
1365 if (inst_size)
1366 {
1367 /* Get the address of the end of the instruction */
1368 int next_inst = fragP->fr_fix + fragP->fr_address + disp_size + inst_size;
1369 int targ_addr = (S_GET_VALUE (fragP->fr_symbol) +
1370 fragP->fr_offset);
1371 int disp = targ_addr - next_inst;
1372
1373 md_number_to_chars (buffer + inst_size, disp, disp_size);
1374 fragP->fr_fix += disp_size + inst_size;
1375 }
1376}
1377
1378valueT
1379md_section_align (seg, size)
1380 segT seg ;
1381 valueT size;
1382{
1383 return ((size + (1 << section_alignment[(int) seg]) - 1)
1384 & (-1 << section_alignment[(int) seg]));
1385
1386}
1387
1388void
1389md_apply_fix3 (fixP, valP, seg)
1390 fixS *fixP;
1391 valueT * valP;
1392 segT seg ATTRIBUTE_UNUSED;
1393{
1394 long val = * (long *) valP;
1395 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1396
1397 if (fixP->fx_r_type == 0)
1398 fixP->fx_r_type = fixP->fx_size == 4 ? R_H8500_IMM32 : R_H8500_IMM16;
1399
1400 switch (fixP->fx_r_type)
1401 {
1402 case R_H8500_IMM8:
1403 case R_H8500_PCREL8:
1404 *buf++ = val;
1405 break;
1406 case R_H8500_IMM16:
1407 case R_H8500_LOW16:
1408 case R_H8500_PCREL16:
1409 *buf++ = (val >> 8);
1410 *buf++ = val;
1411 break;
1412 case R_H8500_HIGH8:
1413 *buf++ = val >> 16;
1414 break;
1415 case R_H8500_HIGH16:
1416 *buf++ = val >> 24;
1417 *buf++ = val >> 16;
1418 break;
1419 case R_H8500_IMM24:
1420 *buf++ = (val >> 16);
1421 *buf++ = (val >> 8);
1422 *buf++ = val;
1423 break;
1424 case R_H8500_IMM32:
1425 *buf++ = (val >> 24);
1426 *buf++ = (val >> 16);
1427 *buf++ = (val >> 8);
1428 *buf++ = val;
1429 break;
1430 default:
1431 abort ();
1432 }
1433
1434 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1435 fixP->fx_done = 1;
1436}
1437
1438/* Called just before address relaxation, return the length
1439 by which a fragment must grow to reach it's destination. */
1440
1441int
1442md_estimate_size_before_relax (fragP, segment_type)
1443 register fragS *fragP;
1444 register segT segment_type;
1445{
1446 int what;
1447
1448 switch (fragP->fr_subtype)
1449 {
1450 default:
1451 abort ();
1452
1453 case C (BRANCH, UNDEF_BYTE_DISP):
1454 case C (SCB_F, UNDEF_BYTE_DISP):
1455 case C (SCB_TST, UNDEF_BYTE_DISP):
1456 what = GET_WHAT (fragP->fr_subtype);
1457 /* used to be a branch to somewhere which was unknown */
1458 if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
1459 {
1460 /* Got a symbol and it's defined in this segment, become byte
1461 sized - maybe it will fix up. */
1462 fragP->fr_subtype = C (what, BYTE_DISP);
1463 }
1464 else
1465 {
1466 /* Its got a segment, but its not ours, so it will always be
1467 long. */
1468 fragP->fr_subtype = C (what, UNDEF_WORD_DISP);
1469 }
1470 break;
1471
1472 case C (BRANCH, BYTE_DISP):
1473 case C (BRANCH, WORD_DISP):
1474 case C (BRANCH, UNDEF_WORD_DISP):
1475 case C (SCB_F, BYTE_DISP):
1476 case C (SCB_F, WORD_DISP):
1477 case C (SCB_F, UNDEF_WORD_DISP):
1478 case C (SCB_TST, BYTE_DISP):
1479 case C (SCB_TST, WORD_DISP):
1480 case C (SCB_TST, UNDEF_WORD_DISP):
1481 /* When relaxing a section for the second time, we don't need to
1482 do anything besides return the current size. */
1483 break;
1484 }
1485
1486 return md_relax_table[fragP->fr_subtype].rlx_length;
1487}
1488
1489/* Put number into target byte order. */
1490
1491void
1492md_number_to_chars (ptr, use, nbytes)
1493 char *ptr;
1494 valueT use;
1495 int nbytes;
1496{
1497 number_to_chars_bigendian (ptr, use, nbytes);
1498}
1499
1500long
1501md_pcrel_from (fixP)
1502 fixS *fixP;
1503{
1504 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
1505}
1506
1507void
1508tc_coff_symbol_emit_hook (ignore)
1509 symbolS *ignore ATTRIBUTE_UNUSED;
1510{
1511}
1512
1513short
1514tc_coff_fix2rtype (fix_ptr)
1515 fixS *fix_ptr;
1516{
1517 if (fix_ptr->fx_r_type == RELOC_32)
1518 {
1519 /* cons likes to create reloc32's whatever the size of the reloc..
1520 */
1521 switch (fix_ptr->fx_size)
1522 {
1523 case 2:
1524 return R_H8500_IMM16;
1525 break;
1526 case 1:
1527 return R_H8500_IMM8;
1528 break;
1529 default:
1530 abort ();
1531 }
1532 }
1533 return fix_ptr->fx_r_type;
1534}
1535
1536void
1537tc_reloc_mangle (fix_ptr, intr, base)
1538 fixS *fix_ptr;
1539 struct internal_reloc *intr;
1540 bfd_vma base;
1541
1542{
1543 symbolS *symbol_ptr;
1544
1545 symbol_ptr = fix_ptr->fx_addsy;
1546
1547 /* If this relocation is attached to a symbol then it's ok
1548 to output it */
1549 if (fix_ptr->fx_r_type == RELOC_32)
1550 {
1551 /* cons likes to create reloc32's whatever the size of the reloc..
1552 */
1553 switch (fix_ptr->fx_size)
1554 {
1555 case 2:
1556 intr->r_type = R_IMM16;
1557 break;
1558 case 1:
1559 intr->r_type = R_IMM8;
1560 break;
1561 default:
1562 abort ();
1563 }
1564 }
1565 else
1566 {
1567 intr->r_type = fix_ptr->fx_r_type;
1568 }
1569
1570 intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
1571 intr->r_offset = fix_ptr->fx_offset;
1572
1573 /* Turn the segment of the symbol into an offset. */
1574 if (symbol_ptr)
1575 {
1576 symbolS *dot;
1577
1578 dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
1579 if (dot)
1580 {
1581#if 0
1582 intr->r_offset -=
1583 segment_info[S_GET_SEGMENT (symbol_ptr)].scnhdr.s_paddr;
1584#endif
1585 intr->r_offset += S_GET_VALUE (symbol_ptr);
1586 intr->r_symndx = dot->sy_number;
1587 }
1588 else
1589 {
1590 intr->r_symndx = symbol_ptr->sy_number;
1591 }
1592
1593 }
1594 else
1595 {
1596 intr->r_symndx = -1;
1597 }
1598
1599}
1600
1601int
1602start_label (ptr)
1603 char *ptr;
1604{
1605 /* Check for :s.w */
1606 if (ISALPHA (ptr[1]) && ptr[2] == '.')
1607 return 0;
1608 /* Check for :s */
1609 if (ISALPHA (ptr[1]) && !ISALPHA (ptr[2]))
1610 return 0;
1611 return 1;
1612}
1613
1614int
1615tc_coff_sizemachdep (frag)
1616 fragS *frag;
1617{
1618 return md_relax_table[frag->fr_subtype].rlx_length;
1619}
Note: See TracBrowser for help on using the repository browser.