#include file moved
[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 /* 
22   Written By Steve Chamberlain
23   sac@cygnus.com
24   */
25
26 #include <stdio.h>
27 #define DEFINE_TABLE
28 #include "../opcodes/z8k-opc.h"
29
30 #include "as.h"
31 #include "bfd.h"
32 #include <ctype.h>
33 #include "listing.h"
34
35 char  comment_chars[]  = { ';',0 };
36 char line_separator_chars[] = { '$' ,0};
37
38 extern int machine;
39 extern int coff_flags;
40 int segmented_mode;
41 int  md_reloc_size ;
42
43 /* This table describes all the machine specific pseudo-ops the assembler
44    has to support.  The fields are:
45    pseudo-op name without dot
46    function to call to execute this pseudo-op
47    Integer arg to pass to the function
48    */
49
50 void cons();
51
52
53 void s_segm()
54 {
55   segmented_mode = 1;
56   machine = bfd_mach_z8001;
57   coff_flags = F_Z8001;
58 }
59
60 void s_unseg()
61 {
62   segmented_mode = 0;
63   machine = bfd_mach_z8002;
64   coff_flags = F_Z8002;
65 }
66 const pseudo_typeS md_pseudo_table[] = 
67 {
68 { "int",        cons,           2       },
69 { "data.b",     cons,           1      },
70 { "data.w",     cons,            2      },
71 { "data.l",     cons,           4      },
72 { "form",       listing_psize,  0      },
73 { "heading",    listing_title,  0},
74 { "import",     s_ignore,       0},
75 { "page",       listing_eject,  0},
76 { "program",    s_ignore,       0},
77 { "SEGM",       s_segm,         0},
78 { "UNSEG",       s_unseg,         0},
79 { 0,0,0 }
80 };
81
82
83 const char EXP_CHARS[] = "eE";
84
85 /* Chars that mean this number is a floating point constant */
86 /* As in 0f12.456 */
87 /* or    0d1.2345e12 */
88 char FLT_CHARS[] = "rRsSfFdDxXpP";
89
90
91 const relax_typeS md_relax_table[1];
92
93
94 static struct hash_control *opcode_hash_control;        /* Opcode mnemonics */
95
96
97
98 void md_begin () 
99 {
100   opcode_entry_type *opcode;
101   char *prev_name= "";
102   int idx = 0;
103         
104   opcode_hash_control = hash_new();
105
106         
107   for (opcode = z8k_table; opcode->name; opcode++) 
108   {
109     /* Only enter unique codes into the table */
110     char *src= opcode->name;
111
112     if (strcmp(opcode->name, prev_name)) 
113     {
114       hash_insert(opcode_hash_control, opcode->name, (char *)opcode);
115       idx++;
116     }
117     opcode->idx = idx;
118     prev_name = opcode->name;
119   }
120         
121 }
122
123
124 struct z8k_exp {
125         char *e_beg;
126         char *e_end;
127         expressionS e_exp;
128 };
129 typedef struct z8k_op 
130 {
131   char regsize;   /* 'b','w','r','q' */
132   unsigned int reg; /* 0..15 */
133
134   int mode;
135
136   unsigned int x_reg;/* any other register associated with the mode */
137   expressionS exp; /* any expression */
138 } op_type;
139
140
141
142 static op_type *da_address;
143 static op_type *imm_operand;
144
145 int the_cc;
146
147 char * 
148 DEFUN(whatreg,(reg, src),
149       int *reg AND
150       char *src)
151 {
152   if (isdigit(src[1])) 
153   {
154     *reg = (src[0] - '0') * 10 +src[1] - '0';
155     return src+2;
156   }
157   else
158   {
159     *reg = (src[0] - '0');
160     return src+1;
161   }
162 return 0;
163 }
164
165 /*
166   parse operands        
167
168   rh0-rh7, rl0-rl7
169   r0-r15
170   rr0-rr14
171   rq0--rq12
172   WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp
173   r0l,r0h,..r7l,r7h
174   @WREG
175   @WREG+
176   @-WREG
177   #const
178   
179   */
180
181
182 /* try and parse a reg name, returns number of chars consumed */
183 char*
184 DEFUN(parse_reg,(src, mode, reg),
185       char *src AND
186       int * mode AND
187       unsigned int *reg)
188 {
189   char *res = 0;
190   if (src[0] == 'R') 
191   {
192     if (src[1] == 'R')
193     {
194       *mode = CLASS_REG_LONG;
195       res =   whatreg(reg, src+2);
196     }
197     else  if (src[1] == 'H')
198     {
199       *mode = CLASS_REG_BYTE;
200       res = whatreg(reg, src+2);
201     }
202     else if (src[1] == 'L')
203     {
204       *mode = CLASS_REG_BYTE;
205       res = whatreg(reg, src+2);
206     }
207     else if (src[1] == 'Q')
208     {
209     * mode = CLASS_REG_QUAD;
210       res = whatreg(reg, src+2);
211     }
212     else 
213     {
214       *mode = CLASS_REG_WORD;
215       res = whatreg(reg, src+1);
216     }
217   }
218   return res;
219
220
221 }
222
223 char *
224 DEFUN(parse_exp,(s, op),
225       char *s AND
226       expressionS *op)
227 {
228         char *save = input_line_pointer;
229         char *new;
230         segT seg;
231         input_line_pointer = s;
232         seg = expr(0,op);
233         new = input_line_pointer;
234         input_line_pointer = save;
235         if (SEG_NORMAL(seg)) 
236             return new;
237         switch (seg) {
238         case SEG_ABSOLUTE:
239         case SEG_UNKNOWN:
240         case SEG_DIFFERENCE:
241         case SEG_BIG:
242         case SEG_REGISTER:
243                 return new;
244         case SEG_ABSENT:
245                 as_bad("Missing operand");
246                 return new;
247         default:
248                 as_bad("Don't understand operand of type %s", segment_name (seg));
249                 return new;
250         }
251 }
252
253
254 /* The many forms of operand:
255    
256    <rb>
257    <r>
258    <rr>
259    <rq>
260    @r
261    #exp 
262    exp
263    exp(r)
264    r(#exp)
265    r(r)
266
267
268    
269    */
270
271 static
272 char *
273 DEFUN(checkfor,(ptr, what),
274       char *ptr AND
275       char what)
276 {
277 if (*ptr == what) ptr++;
278 else {
279 as_bad("expected %c", what);
280 }
281 return ptr;
282 }
283
284 /* Make sure the mode supplied is the size of a word */
285 static void 
286 DEFUN(regword,(mode, string),
287       int mode AND 
288       char *string)
289 {
290   int ok;
291   ok = CLASS_REG_WORD;
292   if (ok != mode) 
293   {  
294     as_bad("register is wrong size for a word %s", string);
295   }
296 }
297
298 /* Make sure the mode supplied is the size of an address */
299 static void 
300 DEFUN(regaddr,(mode, string),
301       int mode AND
302       char *string)
303 {
304   int ok;
305   ok = segmented_mode ? CLASS_REG_LONG : CLASS_REG_WORD;
306   if (ok != mode) 
307   {  
308     as_bad("register is wrong size for address %s", string);
309   }
310 }
311
312 struct cc_names {
313 int value;
314 char *name;
315
316
317 };
318
319 struct cc_names table[] = 
320 {
321   0x0,"F",
322   0x6,"Z",
323   0xe,"NZ",
324   0x7,"C",
325   0xf,"NC",
326   0xd,"PL",
327   0x5,"MI",
328   0xe,"NE",
329   0x6,"EQ",
330   0x4,"OV",
331   0xc,"NOV",
332   0x4,"PE",
333   0xC,"PO",
334   0x9,"GE",
335   0x1,"LT",
336   0xa,"GT",
337   0x2,"LE",
338   0xf,"UGE",
339   0x7,"ULT",
340   0xb,"UGT",
341   0x3,"ULE",
342   0,0
343  };
344
345 static void
346 DEFUN(get_cc_operand,(ptr, mode, dst),
347       char **ptr AND 
348       struct z8k_op *mode AND 
349       unsigned int dst)
350 {
351   char *src = *ptr;
352   int r;
353   int i;
354   mode->mode = CLASS_CC;
355   for (i = 0; table[i].name; i++)
356   {
357     int j;
358     for (j = 0; table[i].name[j]; j++) 
359     {
360       if (table[i].name[j] != src[j])
361        goto fail;
362     }
363    the_cc = table[i].value;
364     *ptr = src + j;
365     return;
366    fail:;
367   }
368 the_cc = 0x8;
369   return ;
370 }
371
372 static void 
373 DEFUN(get_operand,(ptr, mode, dst),
374       char **ptr AND 
375       struct z8k_op *mode AND 
376       unsigned int dst)
377 {
378   char *src = *ptr;
379   char *end;
380   unsigned   int num;
381   unsigned  int len;
382   unsigned int size;
383   mode->mode = 0;
384
385   if (*src == '#') 
386   {
387     mode->mode = CLASS_IMM;
388     imm_operand = mode;
389     src = parse_exp(src+1, &(mode->exp));
390   }     
391   else if (*src == '@') {
392     int d;
393     mode->mode = CLASS_IR;
394     src= parse_reg(src+1, &d, &mode->reg);
395   }
396   else 
397   {
398     int reg;
399     end = parse_reg(src, &mode->mode, &reg);
400
401     if (end)
402     {
403       int nw, nr;
404       src = end;
405       if (*src == '(') 
406       {
407         src++;
408         end = parse_reg(src, &nw, &nr);
409         if (end) 
410         {
411           /* Got Ra(Rb) */
412           src = end;
413
414           if (*src != ')')
415           {
416             as_bad("Missing ) in ra(rb)");
417           }
418           else
419           {
420             src++;
421           }
422           
423           regaddr(mode->mode,"ra(rb) ra");
424           regword(mode->mode,"ra(rb) rb");
425           mode->mode = CLASS_BX;
426           mode->reg = reg;
427           mode->x_reg = nr;
428
429         }
430         else 
431         {
432           /* Got Ra(disp) */
433           if (*src == '#')
434            src++;
435           src = parse_exp(src, &(mode->exp));
436           src = checkfor(src, ')');
437           mode->mode = CLASS_BA;
438           mode->reg = reg;
439           mode->x_reg = 0;
440         }
441       }
442       else
443       {
444         mode->reg = reg;
445         mode->x_reg = 0;
446       }
447     }
448     else 
449     {
450       /* No initial reg */
451       src = parse_exp(src, &(mode->exp));
452       if (*src == '(') 
453       {
454         src++;
455         end = parse_reg(src, &(mode->mode), &reg);
456         regword(mode->mode,"addr(Ra) ra");
457         mode->mode = CLASS_X;
458         mode->reg = reg;
459         mode->x_reg =0;
460         da_address = mode;
461         src = checkfor(end, ')');
462       }
463       else 
464       {
465         /* Just an address */
466         mode->mode = CLASS_DA;
467         mode->reg = 0;
468         mode->x_reg = 0;
469         da_address = mode;
470       }
471     }
472   }
473   *ptr = src;
474 }
475
476 static
477 char *
478 DEFUN(get_operands,(opcode, op_end, operand),
479       opcode_entry_type *opcode AND
480       char *op_end AND
481       op_type *operand) 
482 {
483   char *ptr = op_end;
484   switch (opcode->noperands) 
485   {
486    case 0:
487     operand[0].mode = 0;
488     operand[1].mode = 0;
489     break;
490                     
491    case 1:    
492     ptr++;
493     get_operand(& ptr, operand +0,0);
494     operand[1].mode =0;
495     break;
496                     
497    case 2:
498     ptr++;
499     if (opcode->arg_info[0] == CLASS_CC) 
500     {
501       get_cc_operand(&ptr, operand+0,0);
502     }
503     else
504     {
505       get_operand(& ptr, operand +0,0);
506     }
507     if (*ptr == ',') ptr++;
508     get_operand(& ptr, operand +1, 1);
509     break;
510                     
511    default:
512     abort();    
513   }
514         
515         
516   return ptr;    
517 }
518
519 /* Passed a pointer to a list of opcodes which use different
520    addressing modes, return the opcode which matches the opcodes
521    provided
522    */
523
524 int reg[16];
525 expressionS disp;
526
527 static
528 opcode_entry_type *
529 DEFUN(get_specific,(opcode,  operands),
530       opcode_entry_type *opcode AND
531       op_type *operands)
532
533 {
534   opcode_entry_type *this_try = opcode ;
535   int found = 0;
536   unsigned int noperands = opcode->noperands;
537         
538   unsigned int dispreg;
539   unsigned int this_index = opcode->idx;
540
541   while (this_index == opcode->idx && !found) 
542   {
543     unsigned int i;
544                     
545     this_try  = opcode ++;
546     for (i = 0; i < noperands; i++) 
547     {
548       int mode = operands[i].mode;
549
550       if ((mode&CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK)) goto fail;
551
552       reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
553     }
554
555     found =1;
556    fail: ;
557   }
558   if (found) 
559    return this_try;
560   else 
561    return 0;
562 }
563
564 static void
565 DEFUN(check_operand,(operand, width, string),
566           struct z8k_op *operand AND
567           unsigned int width AND
568           char *string)
569 {
570   if (operand->exp.X_add_symbol == 0 
571       && operand->exp.X_subtract_symbol == 0)
572   {
573                     
574     /* No symbol involved, let's look at offset, it's dangerous if any of
575        the high bits are not 0 or ff's, find out by oring or anding with
576        the width and seeing if the answer is 0 or all fs*/
577     if ((operand->exp.X_add_number & ~width) != 0 &&
578         (operand->exp.X_add_number | width)!= (~0))
579     {
580       as_warn("operand %s0x%x out of range.", string, operand->exp.X_add_number);
581     }
582   }
583         
584 }
585
586 static void 
587 DEFUN(newfix,(ptr, type, operand),
588       int ptr AND
589       int type AND
590       op_type *operand)
591 {
592
593   fix_new(frag_now,
594           ptr,
595           1,
596           operand->exp.X_add_symbol,
597           operand->exp.X_subtract_symbol,
598           operand->exp.X_add_number,
599           0,
600           type);
601 }
602
603
604 /* Now we know what sort of opcodes it is, lets build the bytes -
605  */
606 static void 
607     DEFUN (build_bytes,(this_try, operand),
608            opcode_entry_type *this_try AND
609            struct z8k_op *operand)
610 {
611   unsigned int i;
612   char buffer[20];
613   int length;
614   char *output;
615   char *output_ptr = buffer;
616   char part;
617   int c;
618   char high;
619   int nib;
620   int nibble;
621   unsigned short *class_ptr;
622   length = this_try->length;
623   if (segmented_mode && da_address) 
624   {
625     /* two more bytes when in segmented mode and using da address
626        mode */
627     length += 2;        
628   }
629   output  = frag_more(length);
630 memset(buffer, 20, 0);  
631   class_ptr = this_try->byte_info;
632  top: ;
633
634   for (nibble = 0; c = *class_ptr++; nibble++)
635   {
636
637     switch (c & CLASS_MASK) 
638     {
639      default:
640       abort();
641      case CLASS_ADDRESS:
642       /* Direct address, we don't cope with the SS mode right now */
643       if (segmented_mode) {
644         newfix((output_ptr-buffer)/2, R_DA | R_SEG, da_address);
645         output_ptr += 8;
646       }
647       else {
648         newfix((output_ptr-buffer)/2, R_DA, da_address);
649         output_ptr += 4;
650       }
651       da_address = 0;
652       break;
653      case CLASS_CC:
654       *output_ptr++ = the_cc;
655       break;
656      case CLASS_BIT:
657       *output_ptr++ = c & 0xf;
658       break;
659      case CLASS_REGN0:
660       if (reg[c&0xf] == 0) 
661       {
662         as_bad("can't use R0 here");
663       }
664      case CLASS_REG:
665      case CLASS_REG_BYTE:
666      case CLASS_REG_WORD:
667      case CLASS_REG_LONG:
668      case CLASS_REG_QUAD:
669       /* Insert bit mattern of
670          right reg */
671       *output_ptr++ =  reg[c & 0xf];
672       break;
673      case CLASS_IMM:
674      {
675        nib = 0;
676        switch (c & ARG_MASK)
677        {
678         case ARG_IMM4:
679          newfix((output_ptr-buffer)/2, R_IMM4L, imm_operand);
680          *output_ptr++ = 0;
681          break;
682
683         case   ARG_IMM8:  
684          newfix((output_ptr-buffer)/2, R_IMM8, imm_operand);
685          *output_ptr++ = 0;
686          *output_ptr++ = 0;
687
688         case   ARG_IMM16:  
689          newfix((output_ptr-buffer)/2, R_IMM16, imm_operand);
690          *output_ptr++ = 0;
691          *output_ptr++ = 0;
692          *output_ptr++ = 0;
693          *output_ptr++ = 0;
694          break;
695
696         case   ARG_IMM32:  
697          newfix((output_ptr-buffer)/2, R_IMM32, imm_operand);
698          *output_ptr++ = 0;
699          *output_ptr++ = 0;
700          *output_ptr++ = 0;
701          *output_ptr++ = 0;
702
703          *output_ptr++ = 0;
704          *output_ptr++ = 0;
705          *output_ptr++ = 0;
706          *output_ptr++ = 0;
707
708          break;
709
710         default:
711          abort();
712
713
714        }
715      }
716     }
717   }
718
719   /* Copy from the nibble buffer into the frag */
720
721  {
722    char *src = buffer;
723    char *fragp = output;
724    while (src < output_ptr) 
725    {
726      *fragp = (src[0] << 4) | src[1];
727      src+=2;
728      fragp++;
729    }
730
731         
732  }
733
734 }
735
736 /* This is the guts of the machine-dependent assembler.  STR points to a
737    machine dependent instruction.  This funciton is supposed to emit
738    the frags/bytes it assembles to.
739    */
740
741
742
743 void 
744     DEFUN(md_assemble,(str),
745           char *str)
746 {
747   char *op_start;
748   char *op_end;
749   unsigned int i;
750   struct       z8k_op operand[2];  
751   opcode_entry_type *opcode;
752   opcode_entry_type * prev_opcode;
753         
754   char *dot = 0;
755   char c;    
756   /* Drop leading whitespace */
757   while (*str == ' ')
758    str++;
759         
760   /* find the op code end */
761   for (op_start = op_end = str;
762        *op_end != 0 && *op_end != ' ';
763        op_end ++) 
764   {
765   }
766         
767   ;
768         
769   if (op_end == op_start) 
770   {
771     as_bad("can't find opcode ");
772   }
773   c = *op_end;
774         
775   *op_end = 0;
776         
777   opcode = (opcode_entry_type *) hash_find(opcode_hash_control,
778                                            op_start);
779         
780   if (opcode == NULL) 
781   {
782     as_bad("unknown opcode");
783     return;
784   }
785         
786
787   input_line_pointer =   get_operands(opcode, op_end,
788                                       operand);
789   *op_end = c;
790   prev_opcode = opcode;
791         
792   opcode = get_specific(opcode,  operand);
793         
794   if (opcode == 0)  
795   {
796     /* Couldn't find an opcode which matched the operands */
797     char *where =frag_more(2);
798     where[0] = 0x0;
799     where[1] = 0x0;
800
801     as_bad("Can't find opcode to match operands");
802     return;
803   }
804         
805   build_bytes(opcode, operand);
806 }       
807
808
809 void 
810     DEFUN(tc_crawl_symbol_chain, (headers),
811           object_headers *headers)
812 {
813         printf("call to tc_crawl_symbol_chain \n");
814 }
815
816 symbolS *DEFUN(md_undefined_symbol,(name),
817                char *name)
818 {
819         return 0;
820 }
821
822 void 
823     DEFUN(tc_headers_hook,(headers),
824           object_headers *headers)
825 {
826         printf("call to tc_headers_hook \n"); 
827 }
828 void
829     DEFUN_VOID(md_end) 
830 {
831 }
832
833 /* Various routines to kill one day */
834 /* Equal to MAX_PRECISION in atof-ieee.c */
835 #define MAX_LITTLENUMS 6
836
837 /* Turn a string in input_line_pointer into a floating point constant of type
838    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
839    emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
840    */
841 char *
842     md_atof(type,litP,sizeP)
843 char type;
844 char *litP;
845 int *sizeP;
846 {
847         int     prec;
848         LITTLENUM_TYPE words[MAX_LITTLENUMS];
849         LITTLENUM_TYPE *wordP;
850         char    *t;
851         char    *atof_ieee();
852         
853         switch(type) {
854         case 'f':
855         case 'F':
856         case 's':
857         case 'S':
858                 prec = 2;
859                 break;
860                 
861         case 'd':
862         case 'D':
863         case 'r':
864         case 'R':
865                 prec = 4;
866                 break;
867                 
868         case 'x':
869         case 'X':
870                 prec = 6;
871                 break;
872                 
873         case 'p':
874         case 'P':
875                 prec = 6;
876                 break;
877                 
878         default:
879                 *sizeP=0;
880                 return "Bad call to MD_ATOF()";
881         }
882         t=atof_ieee(input_line_pointer,type,words);
883         if(t)
884             input_line_pointer=t;
885         
886         *sizeP=prec * sizeof(LITTLENUM_TYPE);
887         for(wordP=words;prec--;) {
888                 md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
889                 litP+=sizeof(LITTLENUM_TYPE);
890         }
891         return "";      /* Someone should teach Dean about null pointers */
892 }
893
894 int
895     md_parse_option(argP, cntP, vecP)
896 char **argP;
897 int *cntP;
898 char ***vecP;
899
900 {
901         return 0;
902         
903 }
904
905 int md_short_jump_size;
906
907 void tc_aout_fix_to_chars () { printf("call to tc_aout_fix_to_chars \n");
908                                abort(); }
909 void md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol)
910 char *ptr;
911 long from_addr;
912 long to_addr;
913 fragS *frag;
914 symbolS *to_symbol;
915 {
916         as_fatal("failed sanity check.");
917 }
918
919 void
920     md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol)
921 char *ptr;
922 long from_addr, to_addr;
923 fragS *frag;
924 symbolS *to_symbol;
925 {
926         as_fatal("failed sanity check.");
927 }
928
929 void
930     md_convert_frag(headers, fragP)
931 object_headers *headers;
932 fragS * fragP;
933
934 { printf("call to md_convert_frag \n"); abort(); }
935
936 long
937     DEFUN(md_section_align,(seg, size),
938           segT seg AND
939           long size)
940 {
941         return((size + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg]));
942         
943 }
944
945 void
946     md_apply_fix(fixP, val)
947 fixS *fixP;
948 long val;
949 {
950   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
951         
952   switch(fixP->fx_r_type) {
953    case R_IMM4L:
954     buf[0] = (buf[0] & 0xf0) | ((buf[0] + val) & 0xf);
955     break;
956
957    case R_IMM8:
958     buf[0] += val;
959     break;
960
961    case R_DA:
962    case R_IMM16:
963     *buf++=(val>>8);
964     *buf++=val;
965     break;
966    case R_IMM32:
967     *buf++=(val>>24);
968     *buf++=(val>>16);
969     *buf++=(val>>8);
970     *buf++=val;
971     break;
972    case R_DA | R_SEG:
973     *buf++ = (val>>16);
974     *buf++ = 0x00;
975     *buf++ = (val>>8);
976     *buf++ = val;
977     break;
978    default:
979     abort();
980                 
981   }
982 }
983
984 void DEFUN(md_operand, (expressionP),expressionS *expressionP) 
985 { }
986
987 int  md_long_jump_size;
988 int
989     md_estimate_size_before_relax(fragP, segment_type)
990 register fragS *fragP;
991 register segT segment_type;
992
993         printf("call tomd_estimate_size_before_relax \n"); abort(); }
994 /* Put number into target byte order */
995
996 void DEFUN(md_number_to_chars,(ptr, use, nbytes),
997            char *ptr AND
998            long use AND
999            int nbytes)
1000 {
1001         switch (nbytes) {
1002         case 4: *ptr++ = (use >> 24) & 0xff;
1003         case 3: *ptr++ = (use >> 16) & 0xff;
1004         case 2: *ptr++ = (use >> 8) & 0xff;
1005         case 1: *ptr++ = (use >> 0) & 0xff;
1006                 break;
1007         default:
1008                 abort();
1009         }
1010 }
1011 long md_pcrel_from(fixP) 
1012 fixS *fixP; { abort(); }
1013
1014 void tc_coff_symbol_emit_hook() { }
1015
1016
1017 void tc_reloc_mangle(fix_ptr, intr, base)
1018 fixS *fix_ptr;
1019 struct internal_reloc *intr;
1020 bfd_vma base;
1021
1022 {
1023   symbolS *symbol_ptr;
1024         
1025   symbol_ptr = fix_ptr->fx_addsy;
1026         
1027   /* If this relocation is attached to a symbol then it's ok
1028      to output it */
1029   if (fix_ptr->fx_r_type == RELOC_32) {
1030     /* cons likes to create reloc32's whatever the size of the reloc..
1031      */
1032     switch (fix_ptr->fx_size) 
1033     {
1034                             
1035      case 2:
1036       intr->r_type = R_IMM16;
1037       break;
1038      case 1:
1039       intr->r_type = R_IMM8;
1040       break;
1041      default:
1042       abort();
1043                             
1044     }
1045                 
1046   }
1047   else {  
1048     intr->r_type = fix_ptr->fx_r_type;
1049   }
1050         
1051   intr->r_vaddr = fix_ptr->fx_frag->fr_address +  fix_ptr->fx_where  +base;
1052   intr->r_offset = fix_ptr->fx_offset;
1053         
1054   if (symbol_ptr)
1055    intr->r_symndx = symbol_ptr->sy_number;
1056   else
1057    intr->r_symndx = -1;
1058         
1059         
1060 }
1061
1062