OSDN Git Service

* config/atof-tahoe.c: Fix comment typos.
[pf3gnuchains/pf3gnuchains3x.git] / gas / config / tc-w65.c
1 /* tc-w65.c -- Assemble code for the W65816
2    Copyright 1995, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
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 /* Written By Steve Chamberlain <sac@cygnus.com>.  */
22
23 #include <stdio.h>
24 #include "as.h"
25 #include "bfd.h"
26 #include "subsegs.h"
27 #define DEFINE_TABLE
28 #include "../opcodes/w65-opc.h"
29
30 const char comment_chars[] = "!";
31 const char line_separator_chars[] = ";";
32 const char line_comment_chars[] = "!#";
33
34 /* This table describes all the machine specific pseudo-ops the assembler
35    has to support.  The fields are:
36
37    pseudo-op name without dot
38    function to call to execute this pseudo-op
39    Integer arg to pass to the function  */
40
41 #define OP_BCC  0x90
42 #define OP_BCS  0xB0
43 #define OP_BEQ  0xF0
44 #define OP_BMI  0x30
45 #define OP_BNE  0xD0
46 #define OP_BPL  0x10
47 #define OP_BRA  0x80
48 #define OP_BRL  0x82
49 #define OP_BVC  0x50
50 #define OP_BVS  0x70
51
52 static void s_longa PARAMS ((int));
53 static char *parse_exp PARAMS ((char *));
54 static char *get_operands PARAMS ((const struct opinfo *, char *));
55 static const struct opinfo *get_specific PARAMS ((const struct opinfo *));
56 static void build_Mytes PARAMS ((const struct opinfo *));
57
58
59 const pseudo_typeS md_pseudo_table[] = {
60   {"int", cons, 2},
61   {"word", cons, 2},
62   {"longa", s_longa, 0},
63   {"longi", s_longa, 1},
64   {0, 0, 0}
65 };
66
67 #if 0
68 int md_reloc_size;
69 #endif
70
71 const char EXP_CHARS[] = "eE";
72
73 /* Chars that mean this number is a floating point constant.  */
74 /* As in 0f12.456 */
75 /* or    0d1.2345e12 */
76 const char FLT_CHARS[] = "rRsSfFdDxXpP";
77
78 /* Opcode mnemonics */
79 static struct hash_control *opcode_hash_control;
80
81 int M;                          /* M flag */
82 int X;                          /* X flag */
83
84 #define C(a,b) ENCODE_RELAX(a,b)
85 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
86
87 #define GET_WHAT(x) ((x>>2))
88
89 #define BYTE_DISP 1
90 #define WORD_DISP 2
91 #define UNDEF_BYTE_DISP 0
92 #define UNDEF_WORD_DISP 3
93
94 #define COND_BRANCH     1
95 #define UNCOND_BRANCH   2
96 #define END     3
97
98 #define BYTE_F 127              /* How far we can branch forwards */
99 #define BYTE_B -126             /* How far we can branch backwards */
100 #define WORD_F 32767
101 #define WORD_B 32768
102
103 relax_typeS md_relax_table[C (END, 0)] = {
104   { 0, 0, 0, 0 },
105   { 0, 0, 0, 0 },
106   { 0, 0, 0, 0 },
107   { 0, 0, 0, 0 },
108
109   /* COND_BRANCH */
110   { 0,       0,       0,  0 },                          /* UNDEF_BYTE_DISP */
111   { BYTE_F,  BYTE_B,  2,  C (COND_BRANCH, WORD_DISP) }, /* BYTE_DISP */
112   { WORD_F,  WORD_B,  5,  0 },                          /* WORD_DISP */
113   { 0,       0,       5,  0 },                          /* UNDEF_WORD_DISP */
114
115   /* UNCOND_BRANCH */
116   { 0,       0,       0,  0 },                            /* UNDEF_BYTE_DISP */
117   { BYTE_F,  BYTE_B,  2,  C (UNCOND_BRANCH, WORD_DISP) }, /* BYTE_DISP */
118   { WORD_F,  WORD_B,  3,  0 },                            /* WORD_DISP */
119   { 0,       0,       3,  0 }                             /* UNDEF_WORD_DISP */
120
121 };
122
123 /* This function is called once, at assembler startup time.  This
124    should set up all the tables, etc that the MD part of the assembler
125    needs.  */
126
127 static void
128 s_longa (xmode)
129      int xmode;
130 {
131   int *p = xmode ? &X : &M;
132   while (*input_line_pointer == ' ')
133     input_line_pointer++;
134   if (strncmp (input_line_pointer, "on", 2) == 0)
135     {
136       input_line_pointer += 2;
137       *p = 0;
138     }
139   else if (strncmp (input_line_pointer, "off", 3) == 0)
140     {
141       *p = 1;
142       input_line_pointer += 3;
143     }
144   else
145     as_bad (_("need on or off."));
146   demand_empty_rest_of_line ();
147 }
148
149 void
150 md_begin ()
151 {
152   const struct opinfo *opcode;
153   char *prev_name = "";
154
155   opcode_hash_control = hash_new ();
156
157   /* Insert unique names into hash table.  */
158   for (opcode = optable; opcode->name; opcode++)
159     {
160       if (strcmp (prev_name, opcode->name))
161         {
162           prev_name = opcode->name;
163           hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
164         }
165     }
166
167   flag_signed_overflow_ok = 1;
168 }
169
170 static expressionS immediate;   /* absolute expression */
171 static expressionS immediate1;  /* absolute expression */
172 int expr_size;
173 int expr_shift;
174 int tc_cons_reloc;
175
176 void
177 w65_expression (dest)
178      expressionS *dest;
179 {
180   expr_size = 0;
181   expr_shift = 0;
182   tc_cons_reloc = 0;
183   while (*input_line_pointer == ' ')
184     input_line_pointer++;
185
186   if (*input_line_pointer == '<')
187     {
188       expr_size = 1;
189       input_line_pointer++;
190     }
191   else if (*input_line_pointer == '>')
192     {
193       expr_shift = 1;
194       input_line_pointer++;
195     }
196   else if (*input_line_pointer == '^')
197     {
198       expr_shift = 2;
199       input_line_pointer++;
200     }
201
202   expr (0, dest);
203 }
204
205 int amode;
206
207 static char *
208 parse_exp (s)
209      char *s;
210 {
211   char *save;
212   char *new;
213
214   save = input_line_pointer;
215   input_line_pointer = s;
216   w65_expression (&immediate);
217   if (immediate.X_op == O_absent)
218     as_bad (_("missing operand"));
219   new = input_line_pointer;
220   input_line_pointer = save;
221   return new;
222 }
223
224 static char *
225 get_operands (info, ptr)
226      const struct opinfo *info;
227      char *ptr;
228 {
229   register int override_len = 0;
230   register int bytes = 0;
231
232   while (*ptr == ' ')
233     ptr++;
234
235   if (ptr[0] == '#')
236     {
237       ptr++;
238       switch (info->amode)
239         {
240         case ADDR_IMMTOI:
241           bytes = X ? 1 : 2;
242           amode = ADDR_IMMTOI;
243           break;
244         case ADDR_IMMTOA:
245           bytes = M ? 1 : 2;
246           amode = ADDR_IMMTOA;
247           break;
248         case ADDR_IMMCOP:
249           bytes = 1;
250           amode = ADDR_IMMCOP;
251           break;
252         case ADDR_DIR:
253           bytes = 2;
254           amode = ADDR_ABS;
255           break;
256         default:
257           abort ();
258           break;
259         }
260       ptr = parse_exp (ptr);
261     }
262   else if (ptr[0] == '!')
263     {
264       ptr = parse_exp (ptr + 1);
265       if (ptr[0] == ',')
266         {
267           if (ptr[1] == 'y')
268             {
269               amode = ADDR_ABS_IDX_Y;
270               bytes = 2;
271               ptr += 2;
272             }
273           else if (ptr[1] == 'x')
274             {
275               amode = ADDR_ABS_IDX_X;
276               bytes = 2;
277               ptr += 2;
278             }
279           else
280             {
281               as_bad (_("syntax error after <exp"));
282             }
283         }
284       else
285         {
286           amode = ADDR_ABS;
287           bytes = 2;
288         }
289     }
290   else if (ptr[0] == '>')
291     {
292       ptr = parse_exp (ptr + 1);
293       if (ptr[0] == ',' && ptr[1] == 'x')
294         {
295           amode = ADDR_ABS_LONG_IDX_X;
296           bytes = 3;
297           ptr += 2;
298         }
299       else
300         {
301           amode = ADDR_ABS_LONG;
302           bytes = 3;
303         }
304     }
305   else if (ptr[0] == '<')
306     {
307       ptr = parse_exp (ptr + 1);
308       if (ptr[0] == ',')
309         {
310           if (ptr[1] == 'y')
311             {
312               amode = ADDR_DIR_IDX_Y;
313               ptr += 2;
314               bytes = 2;
315             }
316           else if (ptr[1] == 'x')
317             {
318               amode = ADDR_DIR_IDX_X;
319               ptr += 2;
320               bytes = 2;
321             }
322           else
323             {
324               as_bad (_("syntax error after <exp"));
325             }
326         }
327       else
328         {
329           amode = ADDR_DIR;
330           bytes = 1;
331         }
332     }
333   else if (ptr[0] == 'a')
334     {
335       amode = ADDR_ACC;
336     }
337   else if (ptr[0] == '(')
338     {
339       /* Look for (exp),y
340          (<exp),y
341          (exp,x)
342          (<exp,x)
343          (exp)
344          (!exp)
345          (exp)
346          (<exp)
347          (exp,x)
348          (!exp,x)
349          (exp,s)
350          (exp,s),y */
351
352       ptr++;
353       if (ptr[0] == '<')
354         {
355           override_len = 1;
356           ptr++;
357         }
358       else if (ptr[0] == '!')
359         {
360           override_len = 2;
361           ptr++;
362         }
363       else if (ptr[0] == '>')
364         {
365           override_len = 3;
366           ptr++;
367         }
368       else
369         {
370           override_len = 0;
371         }
372       ptr = parse_exp (ptr);
373
374       if (ptr[0] == ',')
375         {
376           ptr++;
377           if (ptr[0] == 'x' && ptr[1] == ')')
378             {
379               ptr += 2;
380
381               if (override_len == 1)
382                 {
383                   amode = ADDR_DIR_IDX_IND_X;
384                   bytes = 2;
385                 }
386               else
387                 {
388                   amode = ADDR_ABS_IND_IDX;
389                   bytes = 2;
390                 }
391             }
392           else if (ptr[0] == 's' && ptr[1] == ')'
393                    && ptr[2] == ',' && ptr[3] == 'y')
394             {
395               amode = ADDR_STACK_REL_INDX_IDX;
396               bytes = 1;
397               ptr += 4;
398             }
399         }
400       else if (ptr[0] == ')')
401         {
402           if (ptr[1] == ',' && ptr[2] == 'y')
403             {
404               amode = ADDR_DIR_IND_IDX_Y;
405               ptr += 3;
406               bytes = 2;
407             }
408           else
409             {
410               if (override_len == 1)
411                 {
412                   amode = ADDR_DIR_IND;
413                   bytes = 1;
414                 }
415               else
416                 {
417                   amode = ADDR_ABS_IND;
418                   bytes = 2;
419                 }
420               ptr++;
421
422             }
423         }
424     }
425   else if (ptr[0] == '[')
426     {
427       ptr = parse_exp (ptr + 1);
428       if (ptr[0] == ']')
429         {
430           ptr++;
431           if (ptr[0] == ',' && ptr[1] == 'y')
432             {
433               bytes = 1;
434               amode = ADDR_DIR_IND_IDX_Y_LONG;
435               ptr += 2;
436             }
437           else
438             {
439               if (info->code == O_jmp)
440                 {
441                   bytes = 2;
442                   amode = ADDR_ABS_IND_LONG;
443                 }
444               else
445                 {
446                   bytes = 1;
447                   amode = ADDR_DIR_IND_LONG;
448                 }
449             }
450         }
451     }
452   else
453     {
454       ptr = parse_exp (ptr);
455       if (ptr[0] == ',')
456         {
457           if (ptr[1] == 'y')
458             {
459               if (override_len == 1)
460                 {
461                   bytes = 1;
462                   amode = ADDR_DIR_IDX_Y;
463                 }
464               else
465                 {
466                   amode = ADDR_ABS_IDX_Y;
467                   bytes = 2;
468                 }
469               ptr += 2;
470             }
471           else if (ptr[1] == 'x')
472             {
473               if (override_len == 1)
474                 {
475                   amode = ADDR_DIR_IDX_X;
476                   bytes = 1;
477                 }
478               else
479                 {
480                   amode = ADDR_ABS_IDX_X;
481                   bytes = 2;
482                 }
483               ptr += 2;
484             }
485           else if (ptr[1] == 's')
486             {
487               bytes = 1;
488               amode = ADDR_STACK_REL;
489               ptr += 2;
490             }
491           else
492             {
493               bytes = 1;
494               immediate1 = immediate;
495               ptr = parse_exp (ptr + 1);
496               amode = ADDR_BLOCK_MOVE;
497             }
498         }
499       else
500         {
501           switch (info->amode)
502             {
503             case ADDR_PC_REL:
504               amode = ADDR_PC_REL;
505               bytes = 1;
506               break;
507             case ADDR_PC_REL_LONG:
508               amode = ADDR_PC_REL_LONG;
509               bytes = 2;
510               break;
511             default:
512               if (override_len == 1)
513                 {
514                   amode = ADDR_DIR;
515                   bytes = 1;
516                 }
517               else if (override_len == 3)
518                 {
519                   bytes = 3;
520                   amode = ADDR_ABS_LONG;
521                 }
522               else
523                 {
524                   amode = ADDR_ABS;
525                   bytes = 2;
526                 }
527             }
528         }
529     }
530
531   switch (bytes)
532     {
533     case 1:
534       switch (expr_shift)
535         {
536         case 0:
537           if (amode == ADDR_DIR)
538             tc_cons_reloc = R_W65_DP;
539           else
540             tc_cons_reloc = R_W65_ABS8;
541           break;
542         case 1:
543           tc_cons_reloc = R_W65_ABS8S8;
544           break;
545         case 2:
546           tc_cons_reloc = R_W65_ABS8S16;
547           break;
548         }
549       break;
550     case 2:
551       switch (expr_shift)
552         {
553         case 0:
554           tc_cons_reloc = R_W65_ABS16;
555           break;
556         case 1:
557           tc_cons_reloc = R_W65_ABS16S8;
558           break;
559         case 2:
560           tc_cons_reloc = R_W65_ABS16S16;
561           break;
562         }
563     }
564   return ptr;
565 }
566
567 /* Passed a pointer to a list of opcodes which use different
568    addressing modes, return the opcode which matches the opcodes
569    provided.  */
570
571 static const struct opinfo *
572 get_specific (opcode)
573      const struct opinfo *opcode;
574 {
575   int ocode = opcode->code;
576
577   for (; opcode->code == ocode; opcode++)
578     {
579       if (opcode->amode == amode)
580         return opcode;
581     }
582   return 0;
583 }
584
585 /* Now we know what sort of opcodes it is, let's build the bytes.  */
586
587 static void
588 build_Mytes (opcode)
589      const struct opinfo *opcode;
590 {
591   int size;
592   int type;
593   int pcrel;
594   char *output;
595
596   if (opcode->amode == ADDR_IMPLIED)
597     {
598       output = frag_more (1);
599     }
600   else if (opcode->amode == ADDR_PC_REL)
601     {
602       int type;
603
604       /* This is a relaxable insn, so we do some special handling.  */
605       type = opcode->val == OP_BRA ? UNCOND_BRANCH : COND_BRANCH;
606       output = frag_var (rs_machine_dependent,
607                          md_relax_table[C (type, WORD_DISP)].rlx_length,
608                          md_relax_table[C (type, BYTE_DISP)].rlx_length,
609                          C (type, UNDEF_BYTE_DISP),
610                          immediate.X_add_symbol,
611                          immediate.X_add_number,
612                          0);
613     }
614   else
615     {
616       switch (opcode->amode)
617         {
618           GETINFO (size, type, pcrel);
619         default:
620           abort ();
621         }
622
623       /* If something special was done in the expression modify the
624          reloc type.  */
625       if (tc_cons_reloc)
626         type = tc_cons_reloc;
627
628       /* 1 byte for the opcode + the bytes for the addrmode.  */
629       output = frag_more (size + 1);
630
631       if (opcode->amode == ADDR_BLOCK_MOVE)
632         {
633           /* Two relocs for this one.  */
634           fix_new_exp (frag_now,
635                        output + 1 - frag_now->fr_literal,
636                        1,
637                        &immediate,
638                        0,
639                        R_W65_ABS8S16);
640
641           fix_new_exp (frag_now,
642                        output + 2 - frag_now->fr_literal,
643                        1,
644                        &immediate1,
645                        0,
646                        R_W65_ABS8S16);
647         }
648       else if (type >= 0
649                && opcode->amode != ADDR_IMPLIED
650                && opcode->amode != ADDR_ACC
651                && opcode->amode != ADDR_STACK)
652         {
653           fix_new_exp (frag_now,
654                        output + 1 - frag_now->fr_literal,
655                        size,
656                        &immediate,
657                        pcrel,
658                        type);
659         }
660     }
661   output[0] = opcode->val;
662 }
663
664 /* This is the guts of the machine-dependent assembler.  STR points to
665    a machine dependent instruction.  This function is supposed to emit
666    the frags/bytes it assembles to.  */
667
668 void
669 md_assemble (str)
670      char *str;
671 {
672   const struct opinfo *opcode;
673   char name[20];
674
675   /* Drop leading whitespace */
676   while (*str == ' ')
677     str++;
678
679   /* all opcodes are three letters */
680   name[0] = str[0];
681   name[1] = str[1];
682   name[2] = str[2];
683   name[3] = 0;
684
685   tc_cons_reloc = 0;
686   str += 3;
687   opcode = (struct opinfo *) hash_find (opcode_hash_control, name);
688
689   if (opcode == NULL)
690     {
691       as_bad (_("unknown opcode"));
692       return;
693     }
694
695   if (opcode->amode != ADDR_IMPLIED
696       && opcode->amode != ADDR_STACK)
697     {
698       get_operands (opcode, str);
699       opcode = get_specific (opcode);
700     }
701
702   if (opcode == 0)
703     {
704       /* Couldn't find an opcode which matched the operands.  */
705
706       char *where = frag_more (1);
707
708       where[0] = 0x0;
709       where[1] = 0x0;
710       as_bad (_("invalid operands for opcode"));
711       return;
712     }
713
714   build_Mytes (opcode);
715 }
716
717 symbolS *
718 md_undefined_symbol (name)
719      char *name ATTRIBUTE_UNUSED;
720 {
721   return 0;
722 }
723
724 /* Various routines to kill one day.  */
725 /* Equal to MAX_PRECISION in atof-ieee.c.  */
726 #define MAX_LITTLENUMS 6
727
728 /* Turn a string in input_line_pointer into a floating point constant
729    of type TYPE, and store the appropriate bytes in *LITP.  The number
730    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
731    returned, or NULL on OK.  */
732
733 char *
734 md_atof (type, litP, sizeP)
735      char type;
736      char *litP;
737      int *sizeP;
738 {
739   int prec;
740   LITTLENUM_TYPE words[MAX_LITTLENUMS];
741   LITTLENUM_TYPE *wordP;
742   char *t;
743
744   switch (type)
745     {
746     case 'f':
747     case 'F':
748     case 's':
749     case 'S':
750       prec = 2;
751       break;
752
753     case 'd':
754     case 'D':
755     case 'r':
756     case 'R':
757       prec = 4;
758       break;
759
760     case 'x':
761     case 'X':
762       prec = 6;
763       break;
764
765     case 'p':
766     case 'P':
767       prec = 6;
768       break;
769
770     default:
771       *sizeP = 0;
772       return _("Bad call to MD_NTOF()");
773     }
774   t = atof_ieee (input_line_pointer, type, words);
775   if (t)
776     input_line_pointer = t;
777
778   *sizeP = prec * sizeof (LITTLENUM_TYPE);
779   for (wordP = words + prec - 1; prec--;)
780     {
781       md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
782       litP += sizeof (LITTLENUM_TYPE);
783     }
784   return 0;
785 }
786
787 int
788 md_parse_option (c, a)
789      int c ATTRIBUTE_UNUSED;
790      char *a ATTRIBUTE_UNUSED;
791 {
792   return 0;
793 }
794
795 /* Called after relaxing, change the frags so they know how big they
796    are.  */
797
798 void
799 md_convert_frag (headers, seg, fragP)
800      object_headers *headers ATTRIBUTE_UNUSED;
801      segT seg ATTRIBUTE_UNUSED;
802      fragS *fragP;
803 {
804   int disp_size = 0;
805   int inst_size = 0;
806   unsigned char *buffer =
807     (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
808
809   switch (fragP->fr_subtype)
810     {
811     case C (COND_BRANCH, BYTE_DISP):
812     case C (UNCOND_BRANCH, BYTE_DISP):
813       disp_size = 1;
814       inst_size = 1;
815       break;
816
817       /* Conditional branches to a known 16 bit displacement.  */
818     case C (COND_BRANCH, WORD_DISP):
819       switch (buffer[0])
820         {
821         case OP_BCC:
822         case OP_BCS:
823         case OP_BEQ:
824         case OP_BMI:
825         case OP_BNE:
826         case OP_BPL:
827         case OP_BVS:
828         case OP_BVC:
829           /* Invert the sense of the test */
830           buffer[0] ^= 0x20;
831           buffer[1] = 3;        /* Jump over following brl */
832           buffer[2] = OP_BRL;
833           buffer[3] = 0;
834           buffer[4] = 0;
835           disp_size = 2;
836           inst_size = 3;
837           break;
838         default:
839           abort ();
840         }
841       break;
842     case C (UNCOND_BRANCH, WORD_DISP):
843       /* Unconditional branches to a known 16 bit displacement.  */
844
845       switch (buffer[0])
846         {
847         case OP_BRA:
848           buffer[0] = OP_BRL;
849           disp_size = 2;
850           inst_size = 1;
851           break;
852         default:
853           abort ();
854         }
855       break;
856       /* Got to create a branch over a reloc here.  */
857     case C (COND_BRANCH, UNDEF_WORD_DISP):
858       buffer[0] ^= 0x20;        /* invert test */
859       buffer[1] = 3;
860       buffer[2] = OP_BRL;
861       buffer[3] = 0;
862       buffer[4] = 0;
863       fix_new (fragP,
864                fragP->fr_fix + 3,
865                4,
866                fragP->fr_symbol,
867                fragP->fr_offset,
868                0,
869                R_W65_PCR16);
870
871       fragP->fr_fix += disp_size + inst_size;
872       fragP->fr_var = 0;
873       break;
874     case C (UNCOND_BRANCH, UNDEF_WORD_DISP):
875       buffer[0] = OP_BRL;
876       buffer[1] = 0;
877       buffer[2] = 0;
878       fix_new (fragP,
879                fragP->fr_fix + 1,
880                4,
881                fragP->fr_symbol,
882                fragP->fr_offset,
883                0,
884                R_W65_PCR16);
885
886       fragP->fr_fix += disp_size + inst_size;
887       fragP->fr_var = 0;
888       break;
889     default:
890       abort ();
891     }
892   if (inst_size)
893     {
894       /* Get the address of the end of the instruction.  */
895       int next_inst = (fragP->fr_fix + fragP->fr_address
896                        + disp_size + inst_size);
897       int targ_addr = (S_GET_VALUE (fragP->fr_symbol) +
898                        fragP->fr_offset);
899       int disp = targ_addr - next_inst;
900
901       md_number_to_chars (buffer + inst_size, disp, disp_size);
902       fragP->fr_fix += disp_size + inst_size;
903       fragP->fr_var = 0;
904     }
905 }
906
907 valueT
908 md_section_align (seg, size)
909      segT seg;
910      valueT size;
911 {
912   return ((size + (1 << section_alignment[(int) seg]) - 1)
913           & (-1 << section_alignment[(int) seg]));
914 }
915
916 void
917 md_apply_fix3 (fixP, valP, seg)
918      fixS *fixP;
919      valueT * valP;
920      segT seg ATTRIBUTE_UNUSED;
921 {
922   long val = * (long *) valP;
923   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
924   int addr = fixP->fx_frag->fr_address + fixP->fx_where;
925
926   if (fixP->fx_r_type == 0)
927     {
928       if (fixP->fx_size == 1)
929         fixP->fx_r_type = R_W65_ABS8;
930       else
931         fixP->fx_r_type = R_W65_ABS16;
932     }
933
934   switch (fixP->fx_r_type)
935     {
936     case R_W65_ABS8S16:
937       val >>= 8;
938     case R_W65_ABS8S8:
939       val >>= 8;
940     case R_W65_ABS8:
941       *buf++ = val;
942       break;
943     case R_W65_ABS16S16:
944       val >>= 8;
945     case R_W65_ABS16S8:
946       val >>= 8;
947     case R_W65_ABS16:
948       *buf++ = val >> 0;
949       *buf++ = val >> 8;
950       break;
951     case R_W65_ABS24:
952       *buf++ = val >> 0;
953       *buf++ = val >> 8;
954       *buf++ = val >> 16;
955       break;
956     case R_W65_PCR8:
957       *buf++ = val - addr - 1;
958       break;
959     case R_W65_PCR16:
960       val = val - addr - 1;
961       *buf++ = val;
962       *buf++ = val >> 8;
963       break;
964     case R_W65_DP:
965       *buf++ = val;
966       break;
967
968     default:
969       abort ();
970     }
971
972   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
973     fixP->fx_done = 1;
974 }
975
976 /* Put number into target byte order.  */
977
978 void
979 md_number_to_chars (ptr, use, nbytes)
980      char *ptr;
981      valueT use;
982      int nbytes;
983 {
984   number_to_chars_littleendian (ptr, use, nbytes);
985 }
986
987 long
988 md_pcrel_from (fixP)
989      fixS *fixP;
990 {
991   int gap = fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address - 1;
992   return gap;
993 }
994
995 void
996 tc_coff_symbol_emit_hook (x)
997      symbolS *x ATTRIBUTE_UNUSED;
998 {
999 }
1000
1001 short
1002 tc_coff_fix2rtype (fix_ptr)
1003      fixS *fix_ptr;
1004 {
1005   return fix_ptr->fx_r_type;
1006 }
1007
1008 void
1009 tc_reloc_mangle (fix_ptr, intr, base)
1010      fixS *fix_ptr;
1011      struct internal_reloc *intr;
1012      bfd_vma base;
1013
1014 {
1015   symbolS *symbol_ptr;
1016
1017   symbol_ptr = fix_ptr->fx_addsy;
1018
1019   /* If this relocation is attached to a symbol then it's ok
1020      to output it */
1021   if (fix_ptr->fx_r_type == RELOC_32)
1022     {
1023       /* cons likes to create reloc32's whatever the size of the reloc..
1024        */
1025       switch (fix_ptr->fx_size)
1026         {
1027         case 2:
1028           intr->r_type = R_IMM16;
1029           break;
1030         case 1:
1031           intr->r_type = R_IMM8;
1032           break;
1033         default:
1034           abort ();
1035         }
1036     }
1037   else
1038     {
1039       if (fix_ptr->fx_size == 4)
1040         intr->r_type = R_W65_ABS24;
1041       else
1042         intr->r_type = fix_ptr->fx_r_type;
1043     }
1044
1045   intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
1046   intr->r_offset = fix_ptr->fx_offset;
1047
1048   /* Turn the segment of the symbol into an offset.  */
1049   if (symbol_ptr)
1050     {
1051       symbolS *dot;
1052
1053       dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
1054       if (dot)
1055         {
1056           intr->r_offset += S_GET_VALUE (symbol_ptr);
1057           intr->r_symndx = dot->sy_number;
1058         }
1059       else
1060         {
1061           intr->r_symndx = symbol_ptr->sy_number;
1062         }
1063     }
1064   else
1065     {
1066       intr->r_symndx = -1;
1067     }
1068 }
1069
1070 int
1071 tc_coff_sizemachdep (frag)
1072      fragS *frag;
1073 {
1074   return md_relax_table[frag->fr_subtype].rlx_length;
1075 }
1076
1077 /* Called just before address relaxation, return the length by which a
1078    fragment must grow to reach it's destination.  */
1079
1080 int
1081 md_estimate_size_before_relax (fragP, segment_type)
1082      register fragS *fragP;
1083      register segT segment_type;
1084 {
1085   int what;
1086
1087   switch (fragP->fr_subtype)
1088     {
1089     default:
1090       abort ();
1091
1092     case C (COND_BRANCH, UNDEF_BYTE_DISP):
1093     case C (UNCOND_BRANCH, UNDEF_BYTE_DISP):
1094       what = GET_WHAT (fragP->fr_subtype);
1095       /* Used to be a branch to somewhere which was unknown.  */
1096       if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
1097         {
1098           /* Got a symbol and it's defined in this segment, become byte
1099              sized - maybe it will fix up.  */
1100           fragP->fr_subtype = C (what, BYTE_DISP);
1101         }
1102       else
1103         {
1104           /* Its got a segment, but its not ours, so it will always be
1105              long.  */
1106           fragP->fr_subtype = C (what, UNDEF_WORD_DISP);
1107         }
1108       break;
1109
1110     case C (COND_BRANCH, BYTE_DISP):
1111     case C (COND_BRANCH, WORD_DISP):
1112     case C (COND_BRANCH, UNDEF_WORD_DISP):
1113     case C (UNCOND_BRANCH, BYTE_DISP):
1114     case C (UNCOND_BRANCH, WORD_DISP):
1115     case C (UNCOND_BRANCH, UNDEF_WORD_DISP):
1116       /* When relaxing a section for the second time, we don't need to
1117          do anything besides return the current size.  */
1118       break;
1119     }
1120
1121   fragP->fr_var = md_relax_table[fragP->fr_subtype].rlx_length;
1122   return fragP->fr_var;
1123 }
1124
1125 const char *md_shortopts = "";
1126 struct option md_longopts[] = {
1127 #define OPTION_RELAX (OPTION_MD_BASE)
1128   {NULL, no_argument, NULL, 0}
1129 };
1130
1131 void
1132 md_show_usage (stream)
1133      FILE *stream ATTRIBUTE_UNUSED;
1134 {
1135 }
1136
1137 size_t md_longopts_size = sizeof (md_longopts);