* arch-utils.c (generic_prepare_to_proceed): Allow for having
[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:
6840198f
NC
1110 switch (c & ARG_MASK)
1111 {
1112 case ARG_DISP12:
1113 output_ptr = apply_fix (output_ptr, R_CALLR, da_operand, 4);
1114 break;
1115 case ARG_DISP16:
1116 output_ptr = apply_fix (output_ptr, R_REL16, da_operand, 4);
1117 break;
1118 default:
252b5132 1119 output_ptr = apply_fix (output_ptr, R_IMM16, da_operand, 4);
6840198f 1120 }
252b5132
RH
1121 da_operand = 0;
1122 break;
1123
1124 case CLASS_IMM:
1125 {
1126 nib = 0;
1127 switch (c & ARG_MASK)
1128 {
1129 case ARG_IMM4:
1130 output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
1131 break;
1132 case ARG_IMM4M1:
1133 imm_operand->X_add_number--;
1134 output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
1135 break;
1136 case ARG_IMMNMINUS1:
1137 imm_operand->X_add_number--;
1138 output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
1139 break;
1140 case ARG_NIM8:
1141 imm_operand->X_add_number = -imm_operand->X_add_number;
1142 case ARG_IMM8:
1143 output_ptr = apply_fix (output_ptr, R_IMM8, imm_operand, 2);
1144 break;
1145 case ARG_IMM16:
1146 output_ptr = apply_fix (output_ptr, R_IMM16, imm_operand, 4);
1147 break;
1148
1149 case ARG_IMM32:
1150 output_ptr = apply_fix (output_ptr, R_IMM32, imm_operand, 8);
1151 break;
1152
1153 default:
1154 abort ();
1155 }
1156 }
1157 }
1158 }
1159
e0c6ed95 1160 /* Copy from the nibble buffer into the frag. */
252b5132
RH
1161 {
1162 int length = (output_ptr - buffer) / 2;
1163 char *src = buffer;
1164 char *fragp = frag_more (length);
1165
1166 while (src < output_ptr)
1167 {
1168 *fragp = (src[0] << 4) | src[1];
1169 src += 2;
1170 fragp++;
1171 }
252b5132 1172 }
252b5132
RH
1173}
1174
1175/* This is the guts of the machine-dependent assembler. STR points to a
1994a7c7
NC
1176 machine dependent instruction. This function is supposed to emit
1177 the frags/bytes it assembles to. */
252b5132
RH
1178
1179void
c0fecd35
AM
1180md_assemble (str)
1181 char *str;
252b5132
RH
1182{
1183 char *op_start;
1184 char *op_end;
1185 unsigned int i;
1186 struct z8k_op operand[3];
1187 opcode_entry_type *opcode;
1188 opcode_entry_type *prev_opcode;
1189
1190 char *dot = 0;
1191 char c;
1192
e0c6ed95 1193 /* Drop leading whitespace. */
252b5132
RH
1194 while (*str == ' ')
1195 str++;
1196
e0c6ed95 1197 /* Find the op code end. */
252b5132
RH
1198 for (op_start = op_end = str;
1199 *op_end != 0 && *op_end != ' ';
1200 op_end++)
e0c6ed95 1201 ;
252b5132
RH
1202
1203 if (op_end == op_start)
1204 {
1205 as_bad (_("can't find opcode "));
1206 }
1207 c = *op_end;
1208
1209 *op_end = 0;
1210
e0c6ed95 1211 opcode = (opcode_entry_type *) hash_find (opcode_hash_control, op_start);
252b5132
RH
1212
1213 if (opcode == NULL)
1214 {
1215 as_bad (_("unknown opcode"));
1216 return;
1217 }
1218
1219 if (opcode->opcode == 250)
1220 {
e0c6ed95 1221 /* Was really a pseudo op. */
252b5132
RH
1222
1223 pseudo_typeS *p;
1224 char oc;
1225
1226 char *old = input_line_pointer;
1227 *op_end = c;
1228
252b5132
RH
1229 input_line_pointer = op_end;
1230
1231 oc = *old;
1232 *old = '\n';
1233 while (*input_line_pointer == ' ')
1234 input_line_pointer++;
1235 p = (pseudo_typeS *) (opcode->func);
1236
1237 (p->poc_handler) (p->poc_val);
1238 input_line_pointer = old;
1239 *old = oc;
1240 }
1241 else
1242 {
e0c6ed95 1243 input_line_pointer = get_operands (opcode, op_end, operand);
252b5132
RH
1244 prev_opcode = opcode;
1245
1246 opcode = get_specific (opcode, operand);
1247
1248 if (opcode == 0)
1249 {
e0c6ed95 1250 /* Couldn't find an opcode which matched the operands. */
252b5132
RH
1251 char *where = frag_more (2);
1252
1253 where[0] = 0x0;
1254 where[1] = 0x0;
1255
1256 as_bad (_("Can't find opcode to match operands"));
1257 return;
1258 }
1259
1260 build_bytes (opcode, operand);
1261 }
1262}
1263
1264void
c0fecd35
AM
1265tc_crawl_symbol_chain (headers)
1266 object_headers *headers;
252b5132
RH
1267{
1268 printf (_("call to tc_crawl_symbol_chain \n"));
1269}
1270
1271symbolS *
c0fecd35
AM
1272md_undefined_symbol (name)
1273 char *name;
252b5132
RH
1274{
1275 return 0;
1276}
1277
1278void
c0fecd35
AM
1279tc_headers_hook (headers)
1280 object_headers *headers;
252b5132
RH
1281{
1282 printf (_("call to tc_headers_hook \n"));
1283}
1284
e0c6ed95
AM
1285/* Various routines to kill one day. */
1286/* Equal to MAX_PRECISION in atof-ieee.c. */
252b5132
RH
1287#define MAX_LITTLENUMS 6
1288
e0c6ed95
AM
1289/* Turn a string in input_line_pointer into a floating point constant
1290 of type TYPE, and store the appropriate bytes in *LITP. The number
1291 of LITTLENUMS emitted is stored in *SIZEP. An error message is
1292 returned, or NULL on OK. */
1293
252b5132
RH
1294char *
1295md_atof (type, litP, sizeP)
1296 char type;
1297 char *litP;
1298 int *sizeP;
1299{
1300 int prec;
1301 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1302 LITTLENUM_TYPE *wordP;
1303 char *t;
1304 char *atof_ieee ();
1305
1306 switch (type)
1307 {
1308 case 'f':
1309 case 'F':
1310 case 's':
1311 case 'S':
1312 prec = 2;
1313 break;
1314
1315 case 'd':
1316 case 'D':
1317 case 'r':
1318 case 'R':
1319 prec = 4;
1320 break;
1321
1322 case 'x':
1323 case 'X':
1324 prec = 6;
1325 break;
1326
1327 case 'p':
1328 case 'P':
1329 prec = 6;
1330 break;
1331
1332 default:
1333 *sizeP = 0;
1334 return _("Bad call to MD_ATOF()");
1335 }
1336 t = atof_ieee (input_line_pointer, type, words);
1337 if (t)
1338 input_line_pointer = t;
1339
1340 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1341 for (wordP = words; prec--;)
1342 {
1343 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
1344 litP += sizeof (LITTLENUM_TYPE);
1345 }
1346 return 0;
1347}
1348\f
1349CONST char *md_shortopts = "z:";
e0c6ed95 1350
252b5132
RH
1351struct option md_longopts[] = {
1352 {NULL, no_argument, NULL, 0}
1353};
e0c6ed95
AM
1354
1355size_t md_longopts_size = sizeof (md_longopts);
252b5132
RH
1356
1357int
1358md_parse_option (c, arg)
1359 int c;
1360 char *arg;
1361{
1362 switch (c)
1363 {
1364 case 'z':
1365 if (!strcmp (arg, "8001"))
1366 s_segm ();
1367 else if (!strcmp (arg, "8002"))
1368 s_unseg ();
1369 else
1370 {
1371 as_bad (_("invalid architecture -z%s"), arg);
1372 return 0;
1373 }
1374 break;
1375
1376 default:
1377 return 0;
1378 }
1379
1380 return 1;
1381}
1382
1383void
1384md_show_usage (stream)
1385 FILE *stream;
1386{
e0c6ed95 1387 fprintf (stream, _("\
252b5132
RH
1388Z8K options:\n\
1389-z8001 generate segmented code\n\
1390-z8002 generate unsegmented code\n"));
1391}
1392\f
1393void
1394tc_aout_fix_to_chars ()
1395{
1396 printf (_("call to tc_aout_fix_to_chars \n"));
1397 abort ();
1398}
1399
1400void
1401md_convert_frag (headers, seg, fragP)
1402 object_headers *headers;
1403 segT seg;
1404 fragS *fragP;
1405{
1406 printf (_("call to md_convert_frag \n"));
1407 abort ();
1408}
1409
1410valueT
c0fecd35
AM
1411md_section_align (seg, size)
1412 segT seg;
1413 valueT size;
252b5132 1414{
e0c6ed95
AM
1415 return ((size + (1 << section_alignment[(int) seg]) - 1)
1416 & (-1 << section_alignment[(int) seg]));
252b5132
RH
1417
1418}
1419
1420void
1421md_apply_fix (fixP, val)
1422 fixS *fixP;
1423 long val;
1424{
1425 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1426
1427 switch (fixP->fx_r_type)
1428 {
1429 case R_IMM4L:
1430 buf[0] = (buf[0] & 0xf0) | ((buf[0] + val) & 0xf);
1431 break;
1432
1433 case R_JR:
1434
1435 *buf++ = val;
e0c6ed95
AM
1436#if 0
1437 if (val != 0)
1438 abort ();
1439#endif
252b5132
RH
1440 break;
1441
1442 case R_DISP7:
1443
1444 *buf++ += val;
e0c6ed95
AM
1445#if 0
1446 if (val != 0)
1447 abort ();
1448#endif
252b5132
RH
1449 break;
1450
1451 case R_IMM8:
1452 buf[0] += val;
1453 break;
1454 case R_IMM16:
1455 *buf++ = (val >> 8);
1456 *buf++ = val;
1457 break;
1458 case R_IMM32:
1459 *buf++ = (val >> 24);
1460 *buf++ = (val >> 16);
1461 *buf++ = (val >> 8);
1462 *buf++ = val;
1463 break;
1464#if 0
1465 case R_DA | R_SEG:
1466 *buf++ = (val >> 16);
1467 *buf++ = 0x00;
1468 *buf++ = (val >> 8);
1469 *buf++ = val;
1470 break;
1471#endif
1472
1473 case 0:
1474 md_number_to_chars (buf, val, fixP->fx_size);
1475 break;
1476
1477 default:
1478 abort ();
252b5132
RH
1479 }
1480}
1481
1482int
1483md_estimate_size_before_relax (fragP, segment_type)
1484 register fragS *fragP;
1485 register segT segment_type;
1486{
1487 printf (_("call tomd_estimate_size_before_relax \n"));
1488 abort ();
1489}
1490
e0c6ed95 1491/* Put number into target byte order. */
252b5132
RH
1492
1493void
c0fecd35
AM
1494md_number_to_chars (ptr, use, nbytes)
1495 char *ptr;
1496 valueT use;
1497 int nbytes;
252b5132
RH
1498{
1499 number_to_chars_bigendian (ptr, use, nbytes);
1500}
e0c6ed95 1501
252b5132
RH
1502long
1503md_pcrel_from (fixP)
1504 fixS *fixP;
1505{
1506 abort ();
1507}
1508
1509void
1510tc_coff_symbol_emit_hook (s)
49309057 1511 symbolS *s;
252b5132
RH
1512{
1513}
1514
1515void
1516tc_reloc_mangle (fix_ptr, intr, base)
1517 fixS *fix_ptr;
1518 struct internal_reloc *intr;
1519 bfd_vma base;
1520
1521{
1522 symbolS *symbol_ptr;
1523
e0c6ed95
AM
1524 if (fix_ptr->fx_addsy
1525 && fix_ptr->fx_subsy)
252b5132
RH
1526 {
1527 symbolS *add = fix_ptr->fx_addsy;
1528 symbolS *sub = fix_ptr->fx_subsy;
e0c6ed95
AM
1529
1530 if (S_GET_SEGMENT (add) != S_GET_SEGMENT (sub))
1531 as_bad (_("Can't subtract symbols in different sections %s %s"),
1532 S_GET_NAME (add), S_GET_NAME (sub));
1533 else
252b5132 1534 {
e0c6ed95
AM
1535 int diff = S_GET_VALUE (add) - S_GET_VALUE (sub);
1536
1537 fix_ptr->fx_addsy = 0;
1538 fix_ptr->fx_subsy = 0;
1539 fix_ptr->fx_offset += diff;
252b5132 1540 }
252b5132
RH
1541 }
1542 symbol_ptr = fix_ptr->fx_addsy;
1543
1544 /* If this relocation is attached to a symbol then it's ok
e0c6ed95 1545 to output it. */
252b5132
RH
1546 if (fix_ptr->fx_r_type == 0)
1547 {
e0c6ed95 1548 /* cons likes to create reloc32's whatever the size of the reloc. */
252b5132
RH
1549 switch (fix_ptr->fx_size)
1550 {
1551 case 2:
1552 intr->r_type = R_IMM16;
1553 break;
1554 case 1:
1555 intr->r_type = R_IMM8;
1556 break;
1557 case 4:
1558 intr->r_type = R_IMM32;
1559 break;
1560 default:
1561 abort ();
1562 }
252b5132
RH
1563 }
1564 else
e0c6ed95 1565 intr->r_type = fix_ptr->fx_r_type;
252b5132
RH
1566
1567 intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
1568 intr->r_offset = fix_ptr->fx_offset;
1569
1570 if (symbol_ptr)
1571 intr->r_symndx = symbol_ptr->sy_number;
1572 else
1573 intr->r_symndx = -1;
1574}
This page took 0.145614 seconds and 4 git commands to generate.