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