Fix spelling typo
[deliverable/binutils-gdb.git] / gas / config / tc-z8k.c
CommitLineData
252b5132 1/* tc-z8k.c -- Assemble code for the Zilog Z800n
c0fecd35
AM
2 Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 99, 2000
3 Free Software Foundation.
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
22/*
23 Written By Steve Chamberlain
24 sac@cygnus.com
25 */
26#define DEFINE_TABLE
27#include <stdio.h>
28
29#include "opcodes/z8k-opc.h"
30
31#include "as.h"
32#include "bfd.h"
33#include <ctype.h>
34
63a0b638
AM
35const char comment_chars[] = "!";
36const char line_comment_chars[] = "#";
37const char line_separator_chars[] = ";";
252b5132
RH
38
39extern int machine;
40extern int coff_flags;
41int segmented_mode;
42const int md_reloc_size;
43
44/* This table describes all the machine specific pseudo-ops the assembler
45 has to support. The fields are:
46 pseudo-op name without dot
47 function to call to execute this pseudo-op
48 Integer arg to pass to the function
49 */
50
51void cons ();
52
53void
54s_segm ()
55{
56 segmented_mode = 1;
57 machine = bfd_mach_z8001;
58 coff_flags = F_Z8001;
59}
60
61void
62s_unseg ()
63{
64 segmented_mode = 0;
65 machine = bfd_mach_z8002;
66 coff_flags = F_Z8002;
67}
68
69static
70void
71even ()
72{
73 frag_align (1, 0, 0);
74 record_alignment (now_seg, 1);
75}
76
77void obj_coff_section ();
78
79int
80tohex (c)
81 int c;
82{
83 if (isdigit (c))
84 return c - '0';
85 if (islower (c))
86 return c - 'a' + 10;
87 return c - 'A' + 10;
88}
89
90void
91sval ()
92{
93
94 SKIP_WHITESPACE ();
95 if (*input_line_pointer == '\'')
96 {
97 int c;
98 input_line_pointer++;
99 c = *input_line_pointer++;
100 while (c != '\'')
101 {
102 if (c == '%')
103 {
104 c = (tohex (input_line_pointer[0]) << 4)
105 | tohex (input_line_pointer[1]);
106 input_line_pointer += 2;
107 }
108 FRAG_APPEND_1_CHAR (c);
109 c = *input_line_pointer++;
110 }
111 demand_empty_rest_of_line ();
112 }
113
114}
115const pseudo_typeS md_pseudo_table[] =
116{
117 {"int", cons, 2},
118 {"data.b", cons, 1},
119 {"data.w", cons, 2},
120 {"data.l", cons, 4},
121 {"form", listing_psize, 0},
122 {"heading", listing_title, 0},
123 {"import", s_ignore, 0},
124 {"page", listing_eject, 0},
125 {"program", s_ignore, 0},
126 {"z8001", s_segm, 0},
127 {"z8002", s_unseg, 0},
128
129
130 {"segm", s_segm, 0},
131 {"unsegm", s_unseg, 0},
132 {"unseg", s_unseg, 0},
133 {"name", s_app_file, 0},
134 {"global", s_globl, 0},
135 {"wval", cons, 2},
136 {"lval", cons, 4},
137 {"bval", cons, 1},
138 {"sval", sval, 0},
139 {"rsect", obj_coff_section, 0},
140 {"sect", obj_coff_section, 0},
141 {"block", s_space, 0},
142 {"even", even, 0},
143 {0, 0, 0}
144};
145
146const char EXP_CHARS[] = "eE";
147
148/* Chars that mean this number is a floating point constant */
149/* As in 0f12.456 */
150/* or 0d1.2345e12 */
151const char FLT_CHARS[] = "rRsSfFdDxXpP";
152
153static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
154
155void
156md_begin ()
157{
158 opcode_entry_type *opcode;
159 char *prev_name = "";
160 int idx = 0;
161
162 opcode_hash_control = hash_new ();
163
164 for (opcode = z8k_table; opcode->name; opcode++)
165 {
166 /* Only enter unique codes into the table */
167 char *src = opcode->name;
168
169 if (strcmp (opcode->name, prev_name))
170 {
171 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
172 idx++;
173 }
174 opcode->idx = idx;
175 prev_name = opcode->name;
176 }
177
178 /* default to z8002 */
179 s_unseg ();
180
181 /* insert the pseudo ops too */
182 for (idx = 0; md_pseudo_table[idx].poc_name; idx++)
183 {
184 opcode_entry_type *fake_opcode;
185 fake_opcode = (opcode_entry_type *) malloc (sizeof (opcode_entry_type));
186 fake_opcode->name = md_pseudo_table[idx].poc_name,
187 fake_opcode->func = (void *) (md_pseudo_table + idx);
188 fake_opcode->opcode = 250;
189 hash_insert (opcode_hash_control, fake_opcode->name, fake_opcode);
190 }
191
192 linkrelax = 1;
193}
194
195struct z8k_exp
196{
197 char *e_beg;
198 char *e_end;
199 expressionS e_exp;
200};
201typedef struct z8k_op
202{
203 char regsize; /* 'b','w','r','q' */
204 unsigned int reg; /* 0..15 */
205
206 int mode;
207
208 unsigned int x_reg; /* any other register associated with the mode */
209 expressionS exp; /* any expression */
210}
211
212op_type;
213
214static expressionS *da_operand;
215static expressionS *imm_operand;
216
217int reg[16];
218int the_cc;
219int the_ctrl;
220int the_flags;
221int the_interrupt;
222
223char *
c0fecd35
AM
224whatreg (reg, src)
225 int *reg;
226 char *src;
252b5132
RH
227{
228 if (isdigit (src[1]))
229 {
230 *reg = (src[0] - '0') * 10 + src[1] - '0';
231 return src + 2;
232 }
233 else
234 {
235 *reg = (src[0] - '0');
236 return src + 1;
237 }
238}
239
240/*
241 parse operands
242
243 rh0-rh7, rl0-rl7
244 r0-r15
245 rr0-rr14
246 rq0--rq12
247 WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp
248 r0l,r0h,..r7l,r7h
249 @WREG
250 @WREG+
251 @-WREG
252 #const
253
254 */
255
256/* try and parse a reg name, returns number of chars consumed */
257char *
c0fecd35
AM
258parse_reg (src, mode, reg)
259 char *src;
260 int *mode;
261 unsigned int *reg;
252b5132
RH
262{
263 char *res = 0;
264 char regno;
265
266 if (src[0] == 's' && src[1] == 'p')
267 {
268 if (segmented_mode)
269 {
270 *mode = CLASS_REG_LONG;
271 *reg = 14;
272 }
273 else
274 {
275 *mode = CLASS_REG_WORD;
276 *reg = 15;
277 }
278 return src + 2;
279 }
280 if (src[0] == 'r')
281 {
282 if (src[1] == 'r')
283 {
284 *mode = CLASS_REG_LONG;
285 res = whatreg (reg, src + 2);
286 regno = *reg;
287 if (regno > 14)
288 as_warn (_("register rr%d, out of range."),regno);
289 }
290 else if (src[1] == 'h')
291 {
292 *mode = CLASS_REG_BYTE;
293 res = whatreg (reg, src + 2);
294 regno = *reg;
295 if (regno > 7)
296 as_warn (_("register rh%d, out of range."),regno);
297 }
298 else if (src[1] == 'l')
299 {
300 *mode = CLASS_REG_BYTE;
301 res = whatreg (reg, src + 2);
302 regno = *reg;
303 if (regno > 7)
304 as_warn (_("register rl%d, out of range."),regno);
305 *reg += 8;
306 }
307 else if (src[1] == 'q')
308 {
309 *mode = CLASS_REG_QUAD;
310 res = whatreg (reg, src + 2);
311 regno = *reg;
312 if (regno > 12)
313 as_warn (_("register rq%d, out of range."),regno);
314 }
315 else
316 {
317 *mode = CLASS_REG_WORD;
318 res = whatreg (reg, src + 1);
319 regno = *reg;
320 if (regno > 15)
321 as_warn (_("register r%d, out of range."),regno);
322 }
323 }
324 return res;
325
326}
327
328char *
c0fecd35
AM
329parse_exp (s, op)
330 char *s;
331 expressionS *op;
252b5132
RH
332{
333 char *save = input_line_pointer;
334 char *new;
335
336 input_line_pointer = s;
337 expression (op);
338 if (op->X_op == O_absent)
339 as_bad (_("missing operand"));
340 new = input_line_pointer;
341 input_line_pointer = save;
342 return new;
343}
344
345/* The many forms of operand:
346
347 <rb>
348 <r>
349 <rr>
350 <rq>
351 @r
352 #exp
353 exp
354 exp(r)
355 r(#exp)
356 r(r)
357
358
359
360 */
361
362static
363char *
c0fecd35
AM
364checkfor (ptr, what)
365 char *ptr;
366 char what;
252b5132
RH
367{
368 if (*ptr == what)
369 ptr++;
370 else
371 {
372 as_bad (_("expected %c"), what);
373 }
374 return ptr;
375}
376
377/* Make sure the mode supplied is the size of a word */
378static void
c0fecd35
AM
379regword (mode, string)
380 int mode;
381 char *string;
252b5132
RH
382{
383 int ok;
384
385 ok = CLASS_REG_WORD;
386 if (ok != mode)
387 {
388 as_bad (_("register is wrong size for a word %s"), string);
389 }
390}
391
392/* Make sure the mode supplied is the size of an address */
393static void
c0fecd35
AM
394regaddr (mode, string)
395 int mode;
396 char *string;
252b5132
RH
397{
398 int ok;
399
400 ok = segmented_mode ? CLASS_REG_LONG : CLASS_REG_WORD;
401 if (ok != mode)
402 {
403 as_bad (_("register is wrong size for address %s"), string);
404 }
405}
406
407struct ctrl_names
408{
409 int value;
410 char *name;
411};
412
413struct ctrl_names ctrl_table[] =
414{
415 0x2, "fcw",
416 0X3, "refresh",
417 0x4, "psapseg",
418 0x5, "psapoff",
419 0x5, "psap",
420 0x6, "nspseg",
421 0x7, "nspoff",
422 0x7, "nsp",
423 0, 0
424};
425
426static void
c0fecd35
AM
427get_ctrl_operand (ptr, mode, dst)
428 char **ptr;
429 struct z8k_op *mode;
430 unsigned int dst;
252b5132
RH
431{
432 char *src = *ptr;
433 int r;
434 int i;
435
436 while (*src == ' ')
437 src++;
438
439 mode->mode = CLASS_CTRL;
440 for (i = 0; ctrl_table[i].name; i++)
441 {
442 int j;
443
444 for (j = 0; ctrl_table[i].name[j]; j++)
445 {
446 if (ctrl_table[i].name[j] != src[j])
447 goto fail;
448 }
449 the_ctrl = ctrl_table[i].value;
450 *ptr = src + j;
451 return;
452 fail:;
453 }
454 the_ctrl = 0;
455 return;
456}
457
458struct flag_names
459{
460 int value;
461 char *name;
462
463};
464
465struct flag_names flag_table[] =
466{
467 0x1, "p",
468 0x1, "v",
469 0x2, "s",
470 0x4, "z",
471 0x8, "c",
472 0x0, "+",
473 0, 0
474};
475
476static void
c0fecd35
AM
477get_flags_operand (ptr, mode, dst)
478 char **ptr;
479 struct z8k_op *mode;
480 unsigned int dst;
252b5132
RH
481{
482 char *src = *ptr;
483 int r;
484 int i;
485 int j;
486
487 while (*src == ' ')
488 src++;
489
490 mode->mode = CLASS_FLAGS;
491 the_flags = 0;
492 for (j = 0; j <= 9; j++)
493 {
494 if (!src[j])
495 goto done;
496 for (i = 0; flag_table[i].name; i++)
497 {
498 if (flag_table[i].name[0] == src[j])
499 {
500 the_flags = the_flags | flag_table[i].value;
501 goto match;
502 }
503 }
504 goto done;
505 match:
506 ;
507 }
508 done:
509 *ptr = src + j;
510 return;
511}
512
513
514struct interrupt_names
515{
516 int value;
517 char *name;
518
519};
520
521struct interrupt_names intr_table[] =
522{
523 0x1, "nvi",
524 0x2, "vi",
525 0x3, "both",
526 0x3, "all",
527 0, 0
528};
529
530static void
c0fecd35
AM
531get_interrupt_operand (ptr, mode, dst)
532 char **ptr;
533 struct z8k_op *mode;
534 unsigned int dst;
252b5132
RH
535{
536 char *src = *ptr;
537 int r;
538 int i;
539
540 while (*src == ' ')
541 src++;
542
543 mode->mode = CLASS_IMM;
544 for (i = 0; intr_table[i].name; i++)
545 {
546 int j;
547
548 for (j = 0; intr_table[i].name[j]; j++)
549 {
550 if (intr_table[i].name[j] != src[j])
551 goto fail;
552 }
553 the_interrupt = intr_table[i].value;
554 *ptr = src + j;
555 return;
556 fail:;
557 }
558 the_interrupt = 0x0;
559 return;
560}
561
562struct cc_names
563{
564 int value;
565 char *name;
566
567};
568
569struct cc_names table[] =
570{
571 0x0, "f",
572 0x1, "lt",
573 0x2, "le",
574 0x3, "ule",
575 0x4, "ov",
576 0x4, "pe",
577 0x5, "mi",
578 0x6, "eq",
579 0x6, "z",
580 0x7, "c",
581 0x7, "ult",
582 0x8, "t",
583 0x9, "ge",
584 0xa, "gt",
585 0xb, "ugt",
586 0xc, "nov",
587 0xc, "po",
588 0xd, "pl",
589 0xe, "ne",
590 0xe, "nz",
591 0xf, "nc",
592 0xf, "uge",
593 0, 0
594};
595
596static void
c0fecd35
AM
597get_cc_operand (ptr, mode, dst)
598 char **ptr;
599 struct z8k_op *mode;
600 unsigned int dst;
252b5132
RH
601{
602 char *src = *ptr;
603 int r;
604 int i;
605
606 while (*src == ' ')
607 src++;
608
609 mode->mode = CLASS_CC;
610 for (i = 0; table[i].name; i++)
611 {
612 int j;
613
614 for (j = 0; table[i].name[j]; j++)
615 {
616 if (table[i].name[j] != src[j])
617 goto fail;
618 }
619 the_cc = table[i].value;
620 *ptr = src + j;
621 return;
622 fail:;
623 }
624 the_cc = 0x8;
625}
626
627static void
628get_operand (ptr, mode, dst)
629 char **ptr;
630 struct z8k_op *mode;
631 unsigned int dst;
632{
633 char *src = *ptr;
634 char *end;
635 unsigned int num;
636 unsigned int len;
637 unsigned int size;
638
639 mode->mode = 0;
640
641 while (*src == ' ')
642 src++;
643 if (*src == '#')
644 {
645 mode->mode = CLASS_IMM;
646 imm_operand = &(mode->exp);
647 src = parse_exp (src + 1, &(mode->exp));
648 }
649 else if (*src == '@')
650 {
651 int d;
652
653 mode->mode = CLASS_IR;
654 src = parse_reg (src + 1, &d, &mode->reg);
655 }
656 else
657 {
658 int regn;
659
660 end = parse_reg (src, &mode->mode, &regn);
661
662 if (end)
663 {
664 int nw, nr;
665
666 src = end;
667 if (*src == '(')
668 {
669 src++;
670 end = parse_reg (src, &nw, &nr);
671 if (end)
672 {
673 /* Got Ra(Rb) */
674 src = end;
675
676 if (*src != ')')
677 {
678 as_bad (_("Missing ) in ra(rb)"));
679 }
680 else
681 {
682 src++;
683 }
684
685 regaddr (mode->mode, "ra(rb) ra");
686/* regword (mode->mode, "ra(rb) rb");*/
687 mode->mode = CLASS_BX;
688 mode->reg = regn;
689 mode->x_reg = nr;
690 reg[ARG_RX] = nr;
691 }
692 else
693 {
694 /* Got Ra(disp) */
695 if (*src == '#')
696 src++;
697 src = parse_exp (src, &(mode->exp));
698 src = checkfor (src, ')');
699 mode->mode = CLASS_BA;
700 mode->reg = regn;
701 mode->x_reg = 0;
702 imm_operand = &(mode->exp);
703 }
704 }
705 else
706 {
707 mode->reg = regn;
708 mode->x_reg = 0;
709 }
710 }
711 else
712 {
713 /* No initial reg */
714 src = parse_exp (src, &(mode->exp));
715 if (*src == '(')
716 {
717 src++;
718 end = parse_reg (src, &(mode->mode), &regn);
719 regword (mode->mode, "addr(Ra) ra");
720 mode->mode = CLASS_X;
721 mode->reg = regn;
722 mode->x_reg = 0;
723 da_operand = &(mode->exp);
724 src = checkfor (end, ')');
725 }
726 else
727 {
728 /* Just an address */
729 mode->mode = CLASS_DA;
730 mode->reg = 0;
731 mode->x_reg = 0;
732 da_operand = &(mode->exp);
733 }
734 }
735 }
736 *ptr = src;
737}
738
739static
740char *
741get_operands (opcode, op_end, operand)
742 opcode_entry_type *opcode;
743 char *op_end;
744 op_type *operand;
745{
746 char *ptr = op_end;
747char *savptr;
748 switch (opcode->noperands)
749 {
750 case 0:
751 operand[0].mode = 0;
752 operand[1].mode = 0;
753 break;
754
755 case 1:
756 ptr++;
757 if (opcode->arg_info[0] == CLASS_CC)
758 {
759 get_cc_operand (&ptr, operand + 0, 0);
760 }
761 else if (opcode->arg_info[0] == CLASS_FLAGS)
762 {
763 get_flags_operand (&ptr, operand + 0, 0);
764 }
765 else if (opcode->arg_info[0] == (CLASS_IMM +(ARG_IMM2)))
766 {
767 get_interrupt_operand (&ptr, operand + 0, 0);
768 }
769 else
770 {
771 get_operand (&ptr, operand + 0, 0);
772 }
773 operand[1].mode = 0;
774 break;
775
776 case 2:
777 ptr++;
778 savptr = ptr;
779 if (opcode->arg_info[0] == CLASS_CC)
780 {
781 get_cc_operand (&ptr, operand + 0, 0);
782 }
783 else if (opcode->arg_info[0] == CLASS_CTRL)
784 {
785 get_ctrl_operand (&ptr, operand + 0, 0);
786 if (the_ctrl == 0)
787 {
788 ptr = savptr;
789 get_operand (&ptr, operand + 0, 0);
790 if (ptr == 0)
791 return;
792 if (*ptr == ',')
793 ptr++;
794 get_ctrl_operand (&ptr, operand + 1, 1);
795 return ptr;
796 }
797 }
798 else
799 {
800 get_operand (&ptr, operand + 0, 0);
801 }
802 if (ptr == 0)
803 return;
804 if (*ptr == ',')
805 ptr++;
806 get_operand (&ptr, operand + 1, 1);
807 break;
808
809 case 3:
810 ptr++;
811 get_operand (&ptr, operand + 0, 0);
812 if (*ptr == ',')
813 ptr++;
814 get_operand (&ptr, operand + 1, 1);
815 if (*ptr == ',')
816 ptr++;
817 get_operand (&ptr, operand + 2, 2);
818 break;
819
820 case 4:
821 ptr++;
822 get_operand (&ptr, operand + 0, 0);
823 if (*ptr == ',')
824 ptr++;
825 get_operand (&ptr, operand + 1, 1);
826 if (*ptr == ',')
827 ptr++;
828 get_operand (&ptr, operand + 2, 2);
829 if (*ptr == ',')
830 ptr++;
831 get_cc_operand (&ptr, operand + 3, 3);
832 break;
833 default:
834 abort ();
835 }
836
837 return ptr;
838}
839
840/* Passed a pointer to a list of opcodes which use different
841 addressing modes, return the opcode which matches the opcodes
842 provided
843 */
844
845static
846opcode_entry_type *
c0fecd35
AM
847get_specific (opcode, operands)
848 opcode_entry_type *opcode;
849 op_type *operands;
252b5132
RH
850
851{
852 opcode_entry_type *this_try = opcode;
853 int found = 0;
854 unsigned int noperands = opcode->noperands;
855
856 unsigned int dispreg;
857 unsigned int this_index = opcode->idx;
858
859 while (this_index == opcode->idx && !found)
860 {
861 unsigned int i;
862
863 this_try = opcode++;
864 for (i = 0; i < noperands; i++)
865 {
866 int mode = operands[i].mode;
867
868 if ((mode & CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK))
869 {
870 /* it could be an pc rel operand, if this is a da mode and
871 we like disps, then insert it */
872
873 if (mode == CLASS_DA && this_try->arg_info[i] == CLASS_DISP)
874 {
875 /* This is the case */
876 operands[i].mode = CLASS_DISP;
877 }
878 else if (mode == CLASS_BA && this_try->arg_info[i])
879 {
880 /* Can't think of a way to turn what we've been given into
881 something that's ok */
882 goto fail;
883 }
884 else if (this_try->arg_info[i] & CLASS_PR)
885 {
886 if (mode == CLASS_REG_LONG && segmented_mode)
887 {
888 /* ok */
889 }
890 else if (mode == CLASS_REG_WORD && !segmented_mode)
891 {
892 /* ok */
893 }
894 else
895 goto fail;
896 }
897 else
898 goto fail;
899 }
900 switch (mode & CLASS_MASK)
901 {
902 default:
903 break;
904 case CLASS_X:
905 case CLASS_IR:
906 case CLASS_BA:
907 case CLASS_BX:
908 case CLASS_DISP:
909 case CLASS_REG:
910 case CLASS_REG_WORD:
911 case CLASS_REG_BYTE:
912 case CLASS_REG_QUAD:
913 case CLASS_REG_LONG:
914 case CLASS_REGN0:
915 reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
916 break;
917 }
918 }
919
920 found = 1;
921 fail:;
922 }
923 if (found)
924 return this_try;
925 else
926 return 0;
927}
928
929static void
c0fecd35
AM
930check_operand (operand, width, string)
931 struct z8k_op *operand;
932 unsigned int width;
933 char *string;
252b5132
RH
934{
935 if (operand->exp.X_add_symbol == 0
936 && operand->exp.X_op_symbol == 0)
937 {
938
939 /* No symbol involved, let's look at offset, it's dangerous if any of
940 the high bits are not 0 or ff's, find out by oring or anding with
941 the width and seeing if the answer is 0 or all fs*/
942 if ((operand->exp.X_add_number & ~width) != 0 &&
943 (operand->exp.X_add_number | width) != (~0))
944 {
945 as_warn (_("operand %s0x%x out of range."), string, operand->exp.X_add_number);
946 }
947 }
948
949}
950
951static char buffer[20];
952
953static void
c0fecd35
AM
954newfix (ptr, type, operand)
955 int ptr;
956 int type;
957 expressionS *operand;
252b5132
RH
958{
959 if (operand->X_add_symbol
960 || operand->X_op_symbol
961 || operand->X_add_number)
962 {
963 fix_new_exp (frag_now,
964 ptr,
965 1,
966 operand,
967 0,
968 type);
969 }
970}
971
972static char *
c0fecd35
AM
973apply_fix (ptr, type, operand, size)
974 char *ptr;
975 int type;
976 expressionS *operand;
977 int size;
252b5132
RH
978{
979 int n = operand->X_add_number;
980
981 operand->X_add_number = n;
982 newfix ((ptr - buffer) / 2, type, operand);
983#if 1
984 switch (size)
985 {
986 case 8: /* 8 nibbles == 32 bits */
987 *ptr++ = n >> 28;
988 *ptr++ = n >> 24;
989 *ptr++ = n >> 20;
990 *ptr++ = n >> 16;
991 case 4: /* 4 niblles == 16 bits */
992 *ptr++ = n >> 12;
993 *ptr++ = n >> 8;
994 case 2:
995 *ptr++ = n >> 4;
996 case 1:
997 *ptr++ = n >> 0;
998 break;
999 }
1000#endif
1001 return ptr;
1002
1003}
1004
1005/* Now we know what sort of opcodes it is, lets build the bytes -
1006 */
1007#define INSERT(x,y) *x++ = y>>24; *x++ = y>> 16; *x++=y>>8; *x++ =y;
1008static void
1009build_bytes (this_try, operand)
1010 opcode_entry_type * this_try;
1011 struct z8k_op *operand;
1012{
1013 unsigned int i;
1014
1015 int length;
1016 char *output;
1017 char *output_ptr = buffer;
1018 char part;
1019 int c;
1020 char high;
1021 int nib;
1022 int nibble;
1023 unsigned int *class_ptr;
1024
1025 frag_wane (frag_now);
1026 frag_new (0);
1027
1028 memset (buffer, 20, 0);
1029 class_ptr = this_try->byte_info;
1030top:;
1031
1032 for (nibble = 0; c = *class_ptr++; nibble++)
1033 {
1034
1035 switch (c & CLASS_MASK)
1036 {
1037 default:
1038
1039 abort ();
1040 case CLASS_ADDRESS:
1041 /* Direct address, we don't cope with the SS mode right now */
1042 if (segmented_mode)
1043 {
1044 da_operand->X_add_number |= 0x80000000;
1045 output_ptr = apply_fix (output_ptr, R_IMM32, da_operand, 8);
1046 }
1047 else
1048 {
1049 output_ptr = apply_fix (output_ptr, R_IMM16, da_operand, 4);
1050 }
1051 da_operand = 0;
1052 break;
1053 case CLASS_DISP8:
1054 /* pc rel 8 bit */
1055 output_ptr = apply_fix (output_ptr, R_JR, da_operand, 2);
1056 da_operand = 0;
1057 break;
1058
1059 case CLASS_0DISP7:
1060 /* pc rel 7 bit */
1061 *output_ptr = 0;
1062 output_ptr = apply_fix (output_ptr, R_DISP7, da_operand, 2);
1063 da_operand = 0;
1064 break;
1065
1066 case CLASS_1DISP7:
1067 /* pc rel 7 bit */
1068 *output_ptr = 0x80;
1069 output_ptr = apply_fix (output_ptr, R_DISP7, da_operand, 2);
1070 output_ptr[-2] = 0x8;
1071 da_operand = 0;
1072 break;
1073
1074 case CLASS_BIT_1OR2:
1075 *output_ptr = c & 0xf;
1076 if (imm_operand)
1077 {
1078 if (imm_operand->X_add_number == 2)
1079 {
1080 *output_ptr |= 2;
1081 }
1082 else if (imm_operand->X_add_number != 1)
1083 {
1084 as_bad (_("immediate must be 1 or 2"));
1085 }
1086 }
1087 else
1088 {
1089 as_bad (_("immediate 1 or 2 expected"));
1090 }
1091 output_ptr++;
1092 break;
1093 case CLASS_CC:
1094 *output_ptr++ = the_cc;
1095 break;
1096 case CLASS_0CCC:
1097 *output_ptr++ = the_ctrl;
1098 break;
1099 case CLASS_1CCC:
1100 *output_ptr++ = the_ctrl | 0x8;
1101 break;
1102 case CLASS_00II:
1103 *output_ptr++ = (~the_interrupt & 0x3);
1104 break;
1105 case CLASS_01II:
1106 *output_ptr++ = (~the_interrupt & 0x3) | 0x4;
1107 break;
1108 case CLASS_FLAGS:
1109 *output_ptr++ = the_flags;
1110 break;
1111 case CLASS_BIT:
1112 *output_ptr++ = c & 0xf;
1113 break;
1114 case CLASS_REGN0:
1115 if (reg[c & 0xf] == 0)
1116 {
1117 as_bad (_("can't use R0 here"));
1118 }
1119 case CLASS_REG:
1120 case CLASS_REG_BYTE:
1121 case CLASS_REG_WORD:
1122 case CLASS_REG_LONG:
1123 case CLASS_REG_QUAD:
1124 /* Insert bit mattern of
1125 right reg */
1126 *output_ptr++ = reg[c & 0xf];
1127 break;
1128 case CLASS_DISP:
1129 output_ptr = apply_fix (output_ptr, R_IMM16, da_operand, 4);
1130 da_operand = 0;
1131 break;
1132
1133 case CLASS_IMM:
1134 {
1135 nib = 0;
1136 switch (c & ARG_MASK)
1137 {
1138 case ARG_IMM4:
1139 output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
1140 break;
1141 case ARG_IMM4M1:
1142 imm_operand->X_add_number--;
1143 output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
1144 break;
1145 case ARG_IMMNMINUS1:
1146 imm_operand->X_add_number--;
1147 output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
1148 break;
1149 case ARG_NIM8:
1150 imm_operand->X_add_number = -imm_operand->X_add_number;
1151 case ARG_IMM8:
1152 output_ptr = apply_fix (output_ptr, R_IMM8, imm_operand, 2);
1153 break;
1154 case ARG_IMM16:
1155 output_ptr = apply_fix (output_ptr, R_IMM16, imm_operand, 4);
1156 break;
1157
1158 case ARG_IMM32:
1159 output_ptr = apply_fix (output_ptr, R_IMM32, imm_operand, 8);
1160 break;
1161
1162 default:
1163 abort ();
1164 }
1165 }
1166 }
1167 }
1168
1169 /* Copy from the nibble buffer into the frag */
1170
1171 {
1172 int length = (output_ptr - buffer) / 2;
1173 char *src = buffer;
1174 char *fragp = frag_more (length);
1175
1176 while (src < output_ptr)
1177 {
1178 *fragp = (src[0] << 4) | src[1];
1179 src += 2;
1180 fragp++;
1181 }
1182
1183 }
1184
1185}
1186
1187/* This is the guts of the machine-dependent assembler. STR points to a
1188 machine dependent instruction. This funciton is supposed to emit
1189 the frags/bytes it assembles to.
1190 */
1191
1192void
c0fecd35
AM
1193md_assemble (str)
1194 char *str;
252b5132
RH
1195{
1196 char *op_start;
1197 char *op_end;
1198 unsigned int i;
1199 struct z8k_op operand[3];
1200 opcode_entry_type *opcode;
1201 opcode_entry_type *prev_opcode;
1202
1203 char *dot = 0;
1204 char c;
1205
1206 /* Drop leading whitespace */
1207 while (*str == ' ')
1208 str++;
1209
1210 /* find the op code end */
1211 for (op_start = op_end = str;
1212 *op_end != 0 && *op_end != ' ';
1213 op_end++)
1214 {
1215 }
1216
1217 ;
1218
1219 if (op_end == op_start)
1220 {
1221 as_bad (_("can't find opcode "));
1222 }
1223 c = *op_end;
1224
1225 *op_end = 0;
1226
1227 opcode = (opcode_entry_type *) hash_find (opcode_hash_control,
1228 op_start);
1229
1230
1231 if (opcode == NULL)
1232 {
1233 as_bad (_("unknown opcode"));
1234 return;
1235 }
1236
1237 if (opcode->opcode == 250)
1238 {
1239 /* was really a pseudo op */
1240
1241 pseudo_typeS *p;
1242 char oc;
1243
1244 char *old = input_line_pointer;
1245 *op_end = c;
1246
1247
1248 input_line_pointer = op_end;
1249
1250 oc = *old;
1251 *old = '\n';
1252 while (*input_line_pointer == ' ')
1253 input_line_pointer++;
1254 p = (pseudo_typeS *) (opcode->func);
1255
1256 (p->poc_handler) (p->poc_val);
1257 input_line_pointer = old;
1258 *old = oc;
1259 }
1260 else
1261 {
1262 input_line_pointer = get_operands (opcode, op_end,
1263 operand);
1264 prev_opcode = opcode;
1265
1266 opcode = get_specific (opcode, operand);
1267
1268 if (opcode == 0)
1269 {
1270 /* Couldn't find an opcode which matched the operands */
1271 char *where = frag_more (2);
1272
1273 where[0] = 0x0;
1274 where[1] = 0x0;
1275
1276 as_bad (_("Can't find opcode to match operands"));
1277 return;
1278 }
1279
1280 build_bytes (opcode, operand);
1281 }
1282}
1283
1284void
c0fecd35
AM
1285tc_crawl_symbol_chain (headers)
1286 object_headers *headers;
252b5132
RH
1287{
1288 printf (_("call to tc_crawl_symbol_chain \n"));
1289}
1290
1291symbolS *
c0fecd35
AM
1292md_undefined_symbol (name)
1293 char *name;
252b5132
RH
1294{
1295 return 0;
1296}
1297
1298void
c0fecd35
AM
1299tc_headers_hook (headers)
1300 object_headers *headers;
252b5132
RH
1301{
1302 printf (_("call to tc_headers_hook \n"));
1303}
1304
1305/* Various routines to kill one day */
1306/* Equal to MAX_PRECISION in atof-ieee.c */
1307#define MAX_LITTLENUMS 6
1308
1309/* Turn a string in input_line_pointer into a floating point constant of type
1310 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1311 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
1312 */
1313char *
1314md_atof (type, litP, sizeP)
1315 char type;
1316 char *litP;
1317 int *sizeP;
1318{
1319 int prec;
1320 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1321 LITTLENUM_TYPE *wordP;
1322 char *t;
1323 char *atof_ieee ();
1324
1325 switch (type)
1326 {
1327 case 'f':
1328 case 'F':
1329 case 's':
1330 case 'S':
1331 prec = 2;
1332 break;
1333
1334 case 'd':
1335 case 'D':
1336 case 'r':
1337 case 'R':
1338 prec = 4;
1339 break;
1340
1341 case 'x':
1342 case 'X':
1343 prec = 6;
1344 break;
1345
1346 case 'p':
1347 case 'P':
1348 prec = 6;
1349 break;
1350
1351 default:
1352 *sizeP = 0;
1353 return _("Bad call to MD_ATOF()");
1354 }
1355 t = atof_ieee (input_line_pointer, type, words);
1356 if (t)
1357 input_line_pointer = t;
1358
1359 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1360 for (wordP = words; prec--;)
1361 {
1362 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
1363 litP += sizeof (LITTLENUM_TYPE);
1364 }
1365 return 0;
1366}
1367\f
1368CONST char *md_shortopts = "z:";
1369struct option md_longopts[] = {
1370 {NULL, no_argument, NULL, 0}
1371};
1372size_t md_longopts_size = sizeof(md_longopts);
1373
1374int
1375md_parse_option (c, arg)
1376 int c;
1377 char *arg;
1378{
1379 switch (c)
1380 {
1381 case 'z':
1382 if (!strcmp (arg, "8001"))
1383 s_segm ();
1384 else if (!strcmp (arg, "8002"))
1385 s_unseg ();
1386 else
1387 {
1388 as_bad (_("invalid architecture -z%s"), arg);
1389 return 0;
1390 }
1391 break;
1392
1393 default:
1394 return 0;
1395 }
1396
1397 return 1;
1398}
1399
1400void
1401md_show_usage (stream)
1402 FILE *stream;
1403{
1404 fprintf(stream, _("\
1405Z8K options:\n\
1406-z8001 generate segmented code\n\
1407-z8002 generate unsegmented code\n"));
1408}
1409\f
1410void
1411tc_aout_fix_to_chars ()
1412{
1413 printf (_("call to tc_aout_fix_to_chars \n"));
1414 abort ();
1415}
1416
1417void
1418md_convert_frag (headers, seg, fragP)
1419 object_headers *headers;
1420 segT seg;
1421 fragS *fragP;
1422{
1423 printf (_("call to md_convert_frag \n"));
1424 abort ();
1425}
1426
1427valueT
c0fecd35
AM
1428md_section_align (seg, size)
1429 segT seg;
1430 valueT size;
252b5132
RH
1431{
1432 return ((size + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg]));
1433
1434}
1435
1436void
1437md_apply_fix (fixP, val)
1438 fixS *fixP;
1439 long val;
1440{
1441 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1442
1443 switch (fixP->fx_r_type)
1444 {
1445 case R_IMM4L:
1446 buf[0] = (buf[0] & 0xf0) | ((buf[0] + val) & 0xf);
1447 break;
1448
1449 case R_JR:
1450
1451 *buf++ = val;
1452 /* if (val != 0) abort();*/
1453 break;
1454
1455 case R_DISP7:
1456
1457 *buf++ += val;
1458 /* if (val != 0) abort();*/
1459 break;
1460
1461 case R_IMM8:
1462 buf[0] += val;
1463 break;
1464 case R_IMM16:
1465 *buf++ = (val >> 8);
1466 *buf++ = val;
1467 break;
1468 case R_IMM32:
1469 *buf++ = (val >> 24);
1470 *buf++ = (val >> 16);
1471 *buf++ = (val >> 8);
1472 *buf++ = val;
1473 break;
1474#if 0
1475 case R_DA | R_SEG:
1476 *buf++ = (val >> 16);
1477 *buf++ = 0x00;
1478 *buf++ = (val >> 8);
1479 *buf++ = val;
1480 break;
1481#endif
1482
1483 case 0:
1484 md_number_to_chars (buf, val, fixP->fx_size);
1485 break;
1486
1487 default:
1488 abort ();
1489
1490 }
1491}
1492
1493int
1494md_estimate_size_before_relax (fragP, segment_type)
1495 register fragS *fragP;
1496 register segT segment_type;
1497{
1498 printf (_("call tomd_estimate_size_before_relax \n"));
1499 abort ();
1500}
1501
1502/* Put number into target byte order */
1503
1504void
c0fecd35
AM
1505md_number_to_chars (ptr, use, nbytes)
1506 char *ptr;
1507 valueT use;
1508 int nbytes;
252b5132
RH
1509{
1510 number_to_chars_bigendian (ptr, use, nbytes);
1511}
1512long
1513md_pcrel_from (fixP)
1514 fixS *fixP;
1515{
1516 abort ();
1517}
1518
1519void
1520tc_coff_symbol_emit_hook (s)
49309057 1521 symbolS *s;
252b5132
RH
1522{
1523}
1524
1525void
1526tc_reloc_mangle (fix_ptr, intr, base)
1527 fixS *fix_ptr;
1528 struct internal_reloc *intr;
1529 bfd_vma base;
1530
1531{
1532 symbolS *symbol_ptr;
1533
1534 if (fix_ptr->fx_addsy &&
1535 fix_ptr->fx_subsy)
1536 {
1537 symbolS *add = fix_ptr->fx_addsy;
1538 symbolS *sub = fix_ptr->fx_subsy;
1539 if (S_GET_SEGMENT(add) != S_GET_SEGMENT(sub))
1540 {
1541 as_bad(_("Can't subtract symbols in different sections %s %s"),
1542 S_GET_NAME(add), S_GET_NAME(sub));
1543 }
1544 else {
1545 int diff = S_GET_VALUE(add) - S_GET_VALUE(sub);
1546 fix_ptr->fx_addsy = 0;
1547 fix_ptr->fx_subsy = 0;
1548 fix_ptr->fx_offset += diff;
1549 }
1550 }
1551 symbol_ptr = fix_ptr->fx_addsy;
1552
1553 /* If this relocation is attached to a symbol then it's ok
1554 to output it */
1555 if (fix_ptr->fx_r_type == 0)
1556 {
1557 /* cons likes to create reloc32's whatever the size of the reloc.. */
1558 switch (fix_ptr->fx_size)
1559 {
1560 case 2:
1561 intr->r_type = R_IMM16;
1562 break;
1563 case 1:
1564 intr->r_type = R_IMM8;
1565 break;
1566 case 4:
1567 intr->r_type = R_IMM32;
1568 break;
1569 default:
1570 abort ();
1571 }
1572
1573 }
1574 else
1575 {
1576 intr->r_type = fix_ptr->fx_r_type;
1577 }
1578
1579 intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
1580 intr->r_offset = fix_ptr->fx_offset;
1581
1582 if (symbol_ptr)
1583 intr->r_symndx = symbol_ptr->sy_number;
1584 else
1585 intr->r_symndx = -1;
1586}
1587
This page took 0.161824 seconds and 4 git commands to generate.