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