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