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