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