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