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