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