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