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