Move GDB_MULTI_ARCH selection to configure*. Makes tm.h optional.
[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
bc0d738a
NC
256/* Try to parse a reg name. Return a pointer to the first character
257 in SRC after the reg name. */
258
252b5132 259char *
c0fecd35
AM
260parse_reg (src, mode, reg)
261 char *src;
262 int *mode;
263 unsigned int *reg;
252b5132
RH
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 *
c0fecd35
AM
331parse_exp (s, op)
332 char *s;
333 expressionS *op;
252b5132
RH
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 *
c0fecd35
AM
366checkfor (ptr, what)
367 char *ptr;
368 char what;
252b5132
RH
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
c0fecd35
AM
381regword (mode, string)
382 int mode;
383 char *string;
252b5132
RH
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
c0fecd35
AM
396regaddr (mode, string)
397 int mode;
398 char *string;
252b5132
RH
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
c0fecd35
AM
429get_ctrl_operand (ptr, mode, dst)
430 char **ptr;
431 struct z8k_op *mode;
432 unsigned int dst;
252b5132
RH
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
c0fecd35
AM
479get_flags_operand (ptr, mode, dst)
480 char **ptr;
481 struct z8k_op *mode;
482 unsigned int dst;
252b5132
RH
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
c0fecd35
AM
533get_interrupt_operand (ptr, mode, dst)
534 char **ptr;
535 struct z8k_op *mode;
536 unsigned int dst;
252b5132
RH
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
c0fecd35
AM
599get_cc_operand (ptr, mode, dst)
600 char **ptr;
601 struct z8k_op *mode;
602 unsigned int dst;
252b5132
RH
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 *
c0fecd35
AM
849get_specific (opcode, operands)
850 opcode_entry_type *opcode;
851 op_type *operands;
252b5132
RH
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
c0fecd35
AM
932check_operand (operand, width, string)
933 struct z8k_op *operand;
934 unsigned int width;
935 char *string;
252b5132
RH
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
c0fecd35
AM
956newfix (ptr, type, operand)
957 int ptr;
958 int type;
959 expressionS *operand;
252b5132
RH
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 *
c0fecd35
AM
975apply_fix (ptr, type, operand, size)
976 char *ptr;
977 int type;
978 expressionS *operand;
979 int size;
252b5132
RH
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
1994a7c7
NC
1190 machine dependent instruction. This function is supposed to emit
1191 the frags/bytes it assembles to. */
252b5132
RH
1192
1193void
c0fecd35
AM
1194md_assemble (str)
1195 char *str;
252b5132
RH
1196{
1197 char *op_start;
1198 char *op_end;
1199 unsigned int i;
1200 struct z8k_op operand[3];
1201 opcode_entry_type *opcode;
1202 opcode_entry_type *prev_opcode;
1203
1204 char *dot = 0;
1205 char c;
1206
1207 /* Drop leading whitespace */
1208 while (*str == ' ')
1209 str++;
1210
1211 /* find the op code end */
1212 for (op_start = op_end = str;
1213 *op_end != 0 && *op_end != ' ';
1214 op_end++)
1215 {
1216 }
1217
1218 ;
1219
1220 if (op_end == op_start)
1221 {
1222 as_bad (_("can't find opcode "));
1223 }
1224 c = *op_end;
1225
1226 *op_end = 0;
1227
1228 opcode = (opcode_entry_type *) hash_find (opcode_hash_control,
1229 op_start);
1230
1231
1232 if (opcode == NULL)
1233 {
1234 as_bad (_("unknown opcode"));
1235 return;
1236 }
1237
1238 if (opcode->opcode == 250)
1239 {
1240 /* was really a pseudo op */
1241
1242 pseudo_typeS *p;
1243 char oc;
1244
1245 char *old = input_line_pointer;
1246 *op_end = c;
1247
1248
1249 input_line_pointer = op_end;
1250
1251 oc = *old;
1252 *old = '\n';
1253 while (*input_line_pointer == ' ')
1254 input_line_pointer++;
1255 p = (pseudo_typeS *) (opcode->func);
1256
1257 (p->poc_handler) (p->poc_val);
1258 input_line_pointer = old;
1259 *old = oc;
1260 }
1261 else
1262 {
1263 input_line_pointer = get_operands (opcode, op_end,
1264 operand);
1265 prev_opcode = opcode;
1266
1267 opcode = get_specific (opcode, operand);
1268
1269 if (opcode == 0)
1270 {
1271 /* Couldn't find an opcode which matched the operands */
1272 char *where = frag_more (2);
1273
1274 where[0] = 0x0;
1275 where[1] = 0x0;
1276
1277 as_bad (_("Can't find opcode to match operands"));
1278 return;
1279 }
1280
1281 build_bytes (opcode, operand);
1282 }
1283}
1284
1285void
c0fecd35
AM
1286tc_crawl_symbol_chain (headers)
1287 object_headers *headers;
252b5132
RH
1288{
1289 printf (_("call to tc_crawl_symbol_chain \n"));
1290}
1291
1292symbolS *
c0fecd35
AM
1293md_undefined_symbol (name)
1294 char *name;
252b5132
RH
1295{
1296 return 0;
1297}
1298
1299void
c0fecd35
AM
1300tc_headers_hook (headers)
1301 object_headers *headers;
252b5132
RH
1302{
1303 printf (_("call to tc_headers_hook \n"));
1304}
1305
1306/* Various routines to kill one day */
1307/* Equal to MAX_PRECISION in atof-ieee.c */
1308#define MAX_LITTLENUMS 6
1309
1310/* Turn a string in input_line_pointer into a floating point constant of type
1311 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1312 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
1313 */
1314char *
1315md_atof (type, litP, sizeP)
1316 char type;
1317 char *litP;
1318 int *sizeP;
1319{
1320 int prec;
1321 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1322 LITTLENUM_TYPE *wordP;
1323 char *t;
1324 char *atof_ieee ();
1325
1326 switch (type)
1327 {
1328 case 'f':
1329 case 'F':
1330 case 's':
1331 case 'S':
1332 prec = 2;
1333 break;
1334
1335 case 'd':
1336 case 'D':
1337 case 'r':
1338 case 'R':
1339 prec = 4;
1340 break;
1341
1342 case 'x':
1343 case 'X':
1344 prec = 6;
1345 break;
1346
1347 case 'p':
1348 case 'P':
1349 prec = 6;
1350 break;
1351
1352 default:
1353 *sizeP = 0;
1354 return _("Bad call to MD_ATOF()");
1355 }
1356 t = atof_ieee (input_line_pointer, type, words);
1357 if (t)
1358 input_line_pointer = t;
1359
1360 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1361 for (wordP = words; prec--;)
1362 {
1363 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
1364 litP += sizeof (LITTLENUM_TYPE);
1365 }
1366 return 0;
1367}
1368\f
1369CONST char *md_shortopts = "z:";
1370struct option md_longopts[] = {
1371 {NULL, no_argument, NULL, 0}
1372};
1373size_t md_longopts_size = sizeof(md_longopts);
1374
1375int
1376md_parse_option (c, arg)
1377 int c;
1378 char *arg;
1379{
1380 switch (c)
1381 {
1382 case 'z':
1383 if (!strcmp (arg, "8001"))
1384 s_segm ();
1385 else if (!strcmp (arg, "8002"))
1386 s_unseg ();
1387 else
1388 {
1389 as_bad (_("invalid architecture -z%s"), arg);
1390 return 0;
1391 }
1392 break;
1393
1394 default:
1395 return 0;
1396 }
1397
1398 return 1;
1399}
1400
1401void
1402md_show_usage (stream)
1403 FILE *stream;
1404{
1405 fprintf(stream, _("\
1406Z8K options:\n\
1407-z8001 generate segmented code\n\
1408-z8002 generate unsegmented code\n"));
1409}
1410\f
1411void
1412tc_aout_fix_to_chars ()
1413{
1414 printf (_("call to tc_aout_fix_to_chars \n"));
1415 abort ();
1416}
1417
1418void
1419md_convert_frag (headers, seg, fragP)
1420 object_headers *headers;
1421 segT seg;
1422 fragS *fragP;
1423{
1424 printf (_("call to md_convert_frag \n"));
1425 abort ();
1426}
1427
1428valueT
c0fecd35
AM
1429md_section_align (seg, size)
1430 segT seg;
1431 valueT size;
252b5132
RH
1432{
1433 return ((size + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg]));
1434
1435}
1436
1437void
1438md_apply_fix (fixP, val)
1439 fixS *fixP;
1440 long val;
1441{
1442 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1443
1444 switch (fixP->fx_r_type)
1445 {
1446 case R_IMM4L:
1447 buf[0] = (buf[0] & 0xf0) | ((buf[0] + val) & 0xf);
1448 break;
1449
1450 case R_JR:
1451
1452 *buf++ = val;
1453 /* if (val != 0) abort();*/
1454 break;
1455
1456 case R_DISP7:
1457
1458 *buf++ += val;
1459 /* if (val != 0) abort();*/
1460 break;
1461
1462 case R_IMM8:
1463 buf[0] += val;
1464 break;
1465 case R_IMM16:
1466 *buf++ = (val >> 8);
1467 *buf++ = val;
1468 break;
1469 case R_IMM32:
1470 *buf++ = (val >> 24);
1471 *buf++ = (val >> 16);
1472 *buf++ = (val >> 8);
1473 *buf++ = val;
1474 break;
1475#if 0
1476 case R_DA | R_SEG:
1477 *buf++ = (val >> 16);
1478 *buf++ = 0x00;
1479 *buf++ = (val >> 8);
1480 *buf++ = val;
1481 break;
1482#endif
1483
1484 case 0:
1485 md_number_to_chars (buf, val, fixP->fx_size);
1486 break;
1487
1488 default:
1489 abort ();
1490
1491 }
1492}
1493
1494int
1495md_estimate_size_before_relax (fragP, segment_type)
1496 register fragS *fragP;
1497 register segT segment_type;
1498{
1499 printf (_("call tomd_estimate_size_before_relax \n"));
1500 abort ();
1501}
1502
1503/* Put number into target byte order */
1504
1505void
c0fecd35
AM
1506md_number_to_chars (ptr, use, nbytes)
1507 char *ptr;
1508 valueT use;
1509 int nbytes;
252b5132
RH
1510{
1511 number_to_chars_bigendian (ptr, use, nbytes);
1512}
1513long
1514md_pcrel_from (fixP)
1515 fixS *fixP;
1516{
1517 abort ();
1518}
1519
1520void
1521tc_coff_symbol_emit_hook (s)
49309057 1522 symbolS *s;
252b5132
RH
1523{
1524}
1525
1526void
1527tc_reloc_mangle (fix_ptr, intr, base)
1528 fixS *fix_ptr;
1529 struct internal_reloc *intr;
1530 bfd_vma base;
1531
1532{
1533 symbolS *symbol_ptr;
1534
1535 if (fix_ptr->fx_addsy &&
1536 fix_ptr->fx_subsy)
1537 {
1538 symbolS *add = fix_ptr->fx_addsy;
1539 symbolS *sub = fix_ptr->fx_subsy;
1540 if (S_GET_SEGMENT(add) != S_GET_SEGMENT(sub))
1541 {
1542 as_bad(_("Can't subtract symbols in different sections %s %s"),
1543 S_GET_NAME(add), S_GET_NAME(sub));
1544 }
1545 else {
1546 int diff = S_GET_VALUE(add) - S_GET_VALUE(sub);
1547 fix_ptr->fx_addsy = 0;
1548 fix_ptr->fx_subsy = 0;
1549 fix_ptr->fx_offset += diff;
1550 }
1551 }
1552 symbol_ptr = fix_ptr->fx_addsy;
1553
1554 /* If this relocation is attached to a symbol then it's ok
1555 to output it */
1556 if (fix_ptr->fx_r_type == 0)
1557 {
1558 /* cons likes to create reloc32's whatever the size of the reloc.. */
1559 switch (fix_ptr->fx_size)
1560 {
1561 case 2:
1562 intr->r_type = R_IMM16;
1563 break;
1564 case 1:
1565 intr->r_type = R_IMM8;
1566 break;
1567 case 4:
1568 intr->r_type = R_IMM32;
1569 break;
1570 default:
1571 abort ();
1572 }
1573
1574 }
1575 else
1576 {
1577 intr->r_type = fix_ptr->fx_r_type;
1578 }
1579
1580 intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
1581 intr->r_offset = fix_ptr->fx_offset;
1582
1583 if (symbol_ptr)
1584 intr->r_symndx = symbol_ptr->sy_number;
1585 else
1586 intr->r_symndx = -1;
1587}
1588
This page took 0.141655 seconds and 4 git commands to generate.