]> Git Repo - binutils.git/blob - gas/config/tc-i860.c
* libelf.h (relocate_section): New argument "output_names" added
[binutils.git] / gas / config / tc-i860.c
1 /* tc-i860.c -- Assemble for the I860
2    Copyright (C) 1989, 1992 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
18    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #include "as.h"
21
22 #include "opcode/i860.h"
23
24 void md_begin ();
25 void md_end ();
26 void md_number_to_chars ();
27 void md_assemble ();
28 char *md_atof ();
29 void md_convert_frag ();
30 void md_create_short_jump ();
31 void md_create_long_jump ();
32 int md_estimate_size_before_relax ();
33 void md_number_to_imm ();
34 void md_number_to_disp ();
35 void md_number_to_field ();
36 void md_ri_to_chars ();
37 static void i860_ip ();
38 /* void emit_machine_reloc(); */
39
40 const int md_reloc_size = sizeof (struct relocation_info);
41
42 /* void (*md_emit_relocations)() = emit_machine_reloc; */
43
44 const relax_typeS md_relax_table[] =
45 {0};
46
47 /* handle of the OPCODE hash table */
48 static struct hash_control *op_hash = NULL;
49
50 static void s_dual (), s_enddual ();
51 static void s_atmp ();
52
53 const pseudo_typeS
54   md_pseudo_table[] =
55 {
56   {"dual", s_dual, 4},
57   {"enddual", s_enddual, 4},
58   {"atmp", s_atmp, 4},
59   {NULL, 0, 0},
60 };
61
62 int md_short_jump_size = 4;
63 int md_long_jump_size = 4;
64
65 /* This array holds the chars that always start a comment.  If the
66    pre-processor is disabled, these aren't very useful */
67 const char comment_chars[] = "!/";      /* JF removed '|' from comment_chars */
68
69 /* This array holds the chars that only start a comment at the beginning of
70    a line.  If the line seems to have the form '# 123 filename'
71    .line and .file directives will appear in the pre-processed output */
72 /* Note that input_file.c hand checks for '#' at the beginning of the
73    first line of the input file.  This is because the compiler outputs
74    #NO_APP at the beginning of its output. */
75 /* Also note that comments like this one will always work. */
76 const char line_comment_chars[] = "#/";
77
78 const char line_separator_chars[] = "";
79
80 /* Chars that can be used to separate mant from exp in floating point nums */
81 const char EXP_CHARS[] = "eE";
82
83 /* Chars that mean this number is a floating point constant */
84 /* As in 0f12.456 */
85 /* or    0d1.2345e12 */
86 const char FLT_CHARS[] = "rRsSfFdDxXpP";
87
88 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
89    changed in read.c .  Ideally it shouldn't have to know about it at all,
90    but nothing is ideal around here.
91    */
92 int size_reloc_info = sizeof (struct relocation_info);
93
94 static unsigned char octal[256];
95 #define isoctal(c)  octal[c]
96 static unsigned char toHex[256];
97
98 struct i860_it
99   {
100     char *error;
101     unsigned long opcode;
102     struct nlist *nlistp;
103     expressionS exp;
104     int pcrel;
105     enum expand_type expand;
106     enum highlow_type highlow;
107     enum reloc_type reloc;
108   } the_insn;
109
110 #if __STDC__ == 1
111
112 static void print_insn (struct i860_it *insn);
113 static int getExpression (char *str);
114
115 #else /* not __STDC__ */
116
117 static void print_insn ();
118 static int getExpression ();
119
120 #endif /* not __STDC__ */
121
122 static char *expr_end;
123 static char last_expand;        /* error if expansion after branch */
124
125 enum dual
126 {
127   DUAL_OFF = 0, DUAL_ON, DUAL_DDOT, DUAL_ONDDOT,
128 };
129 static enum dual dual_mode = DUAL_OFF;  /* dual-instruction mode */
130
131 static void
132 s_dual ()                       /* floating point instructions have dual set */
133 {
134   dual_mode = DUAL_ON;
135 }
136
137 static void
138 s_enddual ()                    /* floating point instructions have dual set */
139 {
140   dual_mode = DUAL_OFF;
141 }
142
143 static int atmp = 31;           /* temporary register for pseudo's */
144
145 static void
146 s_atmp ()
147 {
148   register int temp;
149   if (strncmp (input_line_pointer, "sp", 2) == 0)
150     {
151       input_line_pointer += 2;
152       atmp = 2;
153     }
154   else if (strncmp (input_line_pointer, "fp", 2) == 0)
155     {
156       input_line_pointer += 2;
157       atmp = 3;
158     }
159   else if (strncmp (input_line_pointer, "r", 1) == 0)
160     {
161       input_line_pointer += 1;
162       temp = get_absolute_expression ();
163       if (temp >= 0 && temp <= 31)
164         atmp = temp;
165       else
166         as_bad ("Unknown temporary pseudo register");
167     }
168   else
169     {
170       as_bad ("Unknown temporary pseudo register");
171     }
172   demand_empty_rest_of_line ();
173   return;
174 }
175
176 /* This function is called once, at assembler startup time.  It should
177    set up all the tables, etc. that the MD part of the assembler will need.  */
178 void
179 md_begin ()
180 {
181   register char *retval = NULL;
182   int lose = 0;
183   register unsigned int i = 0;
184
185   op_hash = hash_new ();
186   if (op_hash == NULL)
187     as_fatal ("Virtual memory exhausted");
188
189   while (i < NUMOPCODES)
190     {
191       const char *name = i860_opcodes[i].name;
192       retval = hash_insert (op_hash, name, &i860_opcodes[i]);
193       if (retval != NULL && *retval != '\0')
194         {
195           fprintf (stderr, "internal error: can't hash `%s': %s\n",
196                    i860_opcodes[i].name, retval);
197           lose = 1;
198         }
199       do
200         {
201           if (i860_opcodes[i].match & i860_opcodes[i].lose)
202             {
203               fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n",
204                        i860_opcodes[i].name, i860_opcodes[i].args);
205               lose = 1;
206             }
207           ++i;
208         }
209       while (i < NUMOPCODES
210              && !strcmp (i860_opcodes[i].name, name));
211     }
212
213   if (lose)
214     as_fatal ("Broken assembler.  No assembly attempted.");
215
216   for (i = '0'; i < '8'; ++i)
217     octal[i] = 1;
218   for (i = '0'; i <= '9'; ++i)
219     toHex[i] = i - '0';
220   for (i = 'a'; i <= 'f'; ++i)
221     toHex[i] = i + 10 - 'a';
222   for (i = 'A'; i <= 'F'; ++i)
223     toHex[i] = i + 10 - 'A';
224 }
225
226 void
227 md_end ()
228 {
229   return;
230 }
231
232 void
233 md_assemble (str)
234      char *str;
235 {
236   char *toP;
237   int rsd;
238   int no_opcodes = 1;
239   int i;
240   struct i860_it pseudo[3];
241
242   assert (str);
243   i860_ip (str);
244
245   /* check for expandable flag to produce pseudo-instructions */
246   if (the_insn.expand != 0 && the_insn.highlow == NO_SPEC)
247     {
248       for (i = 0; i < 3; i++)
249         pseudo[i] = the_insn;
250
251       switch (the_insn.expand)
252         {
253
254         case E_DELAY:
255           no_opcodes = 1;
256           break;
257
258         case E_MOV:
259           if (the_insn.exp.X_add_symbol == NULL &&
260               the_insn.exp.X_subtract_symbol == NULL &&
261               (the_insn.exp.X_add_number < (1 << 15) &&
262                the_insn.exp.X_add_number >= -(1 << 15)))
263             break;
264           /* or l%const,r0,ireg_dest */
265           pseudo[0].opcode = (the_insn.opcode & 0x001f0000) | 0xe4000000;
266           pseudo[0].highlow = PAIR;
267           /* orh h%const,ireg_dest,ireg_dest */
268           pseudo[1].opcode = (the_insn.opcode & 0x03ffffff) | 0xec000000 |
269             ((the_insn.opcode & 0x001f0000) << 5);
270           pseudo[1].highlow = HIGH;
271           no_opcodes = 2;
272           break;
273
274         case E_ADDR:
275           if (the_insn.exp.X_add_symbol == NULL &&
276               the_insn.exp.X_subtract_symbol == NULL)
277             break;
278           /* orh ha%addr_expr,r0,r31 */
279           pseudo[0].opcode = 0xec000000 | (atmp << 16);
280           pseudo[0].highlow = HIGHADJ;
281           pseudo[0].reloc = LOW0;       /* must overwrite */
282           /* l%addr_expr(r31),ireg_dest */
283           pseudo[1].opcode = (the_insn.opcode & ~0x003e0000) | (atmp << 21);
284           pseudo[1].highlow = PAIR;
285           no_opcodes = 2;
286           break;
287
288         case E_U32:             /* 2nd version emulates Intel as, not doc. */
289           if (the_insn.exp.X_add_symbol == NULL &&
290               the_insn.exp.X_subtract_symbol == NULL &&
291               (the_insn.exp.X_add_number < (1 << 16) &&
292                the_insn.exp.X_add_number >= 0))
293             break;
294           /* $(opcode)h h%const,ireg_src2,ireg_dest
295                            pseudo[0].opcode = (the_insn.opcode & 0xf3ffffff) | 0x0c000000; */
296           /* $(opcode)h h%const,ireg_src2,r31 */
297           pseudo[0].opcode = (the_insn.opcode & 0xf3e0ffff) | 0x0c000000 |
298             (atmp << 16);
299           pseudo[0].highlow = HIGH;
300           /* $(opcode) l%const,ireg_dest,ireg_dest
301                            pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000 |
302                            ((the_insn.opcode & 0x001f0000) << 5); */
303           /* $(opcode) l%const,r31,ireg_dest */
304           pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000 |
305             (atmp << 21);
306           pseudo[1].highlow = PAIR;
307           no_opcodes = 2;
308           break;
309
310         case E_AND:             /* 2nd version emulates Intel as, not doc. */
311           if (the_insn.exp.X_add_symbol == NULL &&
312               the_insn.exp.X_subtract_symbol == NULL &&
313               (the_insn.exp.X_add_number < (1 << 16) &&
314                the_insn.exp.X_add_number >= 0))
315             break;
316           /* andnot h%const,ireg_src2,ireg_dest
317                            pseudo[0].opcode = (the_insn.opcode & 0x03ffffff) | 0xd4000000; */
318           /* andnot h%const,ireg_src2,r31 */
319           pseudo[0].opcode = (the_insn.opcode & 0x03e0ffff) | 0xd4000000 |
320             (atmp << 16);
321           pseudo[0].highlow = HIGH;
322           pseudo[0].exp.X_add_number = -1 - the_insn.exp.X_add_number;
323           /* andnot l%const,ireg_dest,ireg_dest
324                            pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000 |
325                            ((the_insn.opcode & 0x001f0000) << 5); */
326           /* andnot l%const,r31,ireg_dest */
327           pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000 |
328             (atmp << 21);
329           pseudo[1].highlow = PAIR;
330           pseudo[1].exp.X_add_number = -1 - the_insn.exp.X_add_number;
331           no_opcodes = 2;
332           break;
333
334         case E_S32:
335           if (the_insn.exp.X_add_symbol == NULL &&
336               the_insn.exp.X_subtract_symbol == NULL &&
337               (the_insn.exp.X_add_number < (1 << 15) &&
338                the_insn.exp.X_add_number >= -(1 << 15)))
339             break;
340           /* orh h%const,r0,r31 */
341           pseudo[0].opcode = 0xec000000 | (atmp << 16);
342           pseudo[0].highlow = HIGH;
343           /* or l%const,r31,r31 */
344           pseudo[1].opcode = 0xe4000000 | (atmp << 21) | (atmp << 16);
345           pseudo[1].highlow = PAIR;
346           /* r31,ireg_src2,ireg_dest */
347           pseudo[2].opcode = (the_insn.opcode & ~0x0400ffff) | (atmp << 11);
348           pseudo[2].reloc = NO_RELOC;
349           no_opcodes = 3;
350           break;
351
352         default:
353           as_fatal ("failed sanity check.");
354         }
355
356       the_insn = pseudo[0];
357       /* check for expanded opcode after branch or in dual */
358       if (no_opcodes > 1 && last_expand == 1)
359         as_warn ("Expanded opcode after delayed branch: `%s'", str);
360       if (no_opcodes > 1 && dual_mode != DUAL_OFF)
361         as_warn ("Expanded opcode in dual mode: `%s'", str);
362     }
363
364   i = 0;
365   do
366     {                           /* always produce at least one opcode */
367       toP = frag_more (4);
368       /* put out the opcode */
369       md_number_to_chars (toP, the_insn.opcode, 4);
370
371       /* check for expanded opcode after branch or in dual */
372       last_expand = the_insn.pcrel;
373
374       /* put out the symbol-dependent stuff */
375       if (the_insn.reloc != NO_RELOC)
376         {
377           fix_new (frag_now,    /* which frag */
378                    (toP - frag_now->fr_literal),        /* where */
379                    4,           /* size */
380                    the_insn.exp.X_add_symbol,
381                    the_insn.exp.X_subtract_symbol,
382                    the_insn.exp.X_add_number,
383                    the_insn.pcrel,
384           /* merge bit fields into one argument */
385           (int) (((the_insn.highlow & 0x3) << 4) | (the_insn.reloc & 0xf)));
386         }
387       the_insn = pseudo[++i];
388     }
389   while (--no_opcodes > 0);
390
391 }
392
393 static void
394 i860_ip (str)
395      char *str;
396 {
397   char *s;
398   const char *args;
399   char c;
400   unsigned long i;
401   struct i860_opcode *insn;
402   char *argsStart;
403   unsigned long opcode;
404   unsigned int mask;
405   int match = 0;
406   int comma = 0;
407
408
409   for (s = str; islower (*s) || *s == '.' || *s == '3'; ++s)
410     ;
411   switch (*s)
412     {
413
414     case '\0':
415       break;
416
417     case ',':
418       comma = 1;
419
420       /*FALLTHROUGH*/
421
422     case ' ':
423       *s++ = '\0';
424       break;
425
426     default:
427       as_bad ("Unknown opcode: `%s'", str);
428       exit (1);
429     }
430
431   if (strncmp (str, "d.", 2) == 0)
432     {                           /* check for d. opcode prefix */
433       if (dual_mode == DUAL_ON)
434         dual_mode = DUAL_ONDDOT;
435       else
436         dual_mode = DUAL_DDOT;
437       str += 2;
438     }
439
440   if ((insn = (struct i860_opcode *) hash_find (op_hash, str)) == NULL)
441     {
442       if (dual_mode == DUAL_DDOT || dual_mode == DUAL_ONDDOT)
443         str -= 2;
444       as_bad ("Unknown opcode: `%s'", str);
445       return;
446     }
447   if (comma)
448     {
449       *--s = ',';
450     }
451   argsStart = s;
452   for (;;)
453     {
454       opcode = insn->match;
455       memset (&the_insn, '\0', sizeof (the_insn));
456       the_insn.reloc = NO_RELOC;
457
458       /*
459                  * Build the opcode, checking as we go to make
460                  * sure that the operands match
461                  */
462       for (args = insn->args;; ++args)
463         {
464           switch (*args)
465             {
466
467             case '\0':          /* end of args */
468               if (*s == '\0')
469                 {
470                   match = 1;
471                 }
472               break;
473
474             case '+':
475             case '(':           /* these must match exactly */
476             case ')':
477             case ',':
478             case ' ':
479               if (*s++ == *args)
480                 continue;
481               break;
482
483             case '#':           /* must be at least one digit */
484               if (isdigit (*s++))
485                 {
486                   while (isdigit (*s))
487                     {
488                       ++s;
489                     }
490                   continue;
491                 }
492               break;
493
494             case '1':           /* next operand must be a register */
495             case '2':
496             case 'd':
497               switch (*s)
498                 {
499
500                 case 'f':       /* frame pointer */
501                   s++;
502                   if (*s++ == 'p')
503                     {
504                       mask = 0x3;
505                       break;
506                     }
507                   goto error;
508
509                 case 's':       /* stack pointer */
510                   s++;
511                   if (*s++ == 'p')
512                     {
513                       mask = 0x2;
514                       break;
515                     }
516                   goto error;
517
518                 case 'r':       /* any register */
519                   s++;
520                   if (!isdigit (c = *s++))
521                     {
522                       goto error;
523                     }
524                   if (isdigit (*s))
525                     {
526                       if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
527                         {
528                           goto error;
529                         }
530                     }
531                   else
532                     {
533                       c -= '0';
534                     }
535                   mask = c;
536                   break;
537
538                 default:        /* not this opcode */
539                   goto error;
540                 }
541               /*
542                                  * Got the register, now figure out where
543                                  * it goes in the opcode.
544                                  */
545               switch (*args)
546                 {
547
548                 case '1':
549                   opcode |= mask << 11;
550                   continue;
551
552                 case '2':
553                   opcode |= mask << 21;
554                   continue;
555
556                 case 'd':
557                   opcode |= mask << 16;
558                   continue;
559
560                 }
561               break;
562
563             case 'e':           /* next operand is a floating point register */
564             case 'f':
565             case 'g':
566               if (*s++ == 'f' && isdigit (*s))
567                 {
568                   mask = *s++;
569                   if (isdigit (*s))
570                     {
571                       mask = 10 * (mask - '0') + (*s++ - '0');
572                       if (mask >= 32)
573                         {
574                           break;
575                         }
576                     }
577                   else
578                     {
579                       mask -= '0';
580                     }
581                   switch (*args)
582                     {
583
584                     case 'e':
585                       opcode |= mask << 11;
586                       continue;
587
588                     case 'f':
589                       opcode |= mask << 21;
590                       continue;
591
592                     case 'g':
593                       opcode |= mask << 16;
594                       if (dual_mode != DUAL_OFF)
595                         opcode |= (1 << 9);     /* dual mode instruction */
596                       if (dual_mode == DUAL_DDOT)
597                         dual_mode = DUAL_OFF;
598                       if (dual_mode == DUAL_ONDDOT)
599                         dual_mode = DUAL_ON;
600                       if ((opcode & (1 << 10)) && (mask == ((opcode >> 11) & 0x1f)))
601                         as_warn ("Fsr1 equals fdest with Pipelining");
602                       continue;
603                     }
604                 }
605               break;
606
607             case 'c':           /* next operand must be a control register */
608               if (strncmp (s, "fir", 3) == 0)
609                 {
610                   opcode |= 0x0 << 21;
611                   s += 3;
612                   continue;
613                 }
614               if (strncmp (s, "psr", 3) == 0)
615                 {
616                   opcode |= 0x1 << 21;
617                   s += 3;
618                   continue;
619                 }
620               if (strncmp (s, "dirbase", 7) == 0)
621                 {
622                   opcode |= 0x2 << 21;
623                   s += 7;
624                   continue;
625                 }
626               if (strncmp (s, "db", 2) == 0)
627                 {
628                   opcode |= 0x3 << 21;
629                   s += 2;
630                   continue;
631                 }
632               if (strncmp (s, "fsr", 3) == 0)
633                 {
634                   opcode |= 0x4 << 21;
635                   s += 3;
636                   continue;
637                 }
638               if (strncmp (s, "epsr", 4) == 0)
639                 {
640                   opcode |= 0x5 << 21;
641                   s += 4;
642                   continue;
643                 }
644               break;
645
646             case '5':           /* 5 bit immediate in src1 */
647               memset (&the_insn, '\0', sizeof (the_insn));
648               if (!getExpression (s))
649                 {
650                   s = expr_end;
651                   if (the_insn.exp.X_add_number & ~0x1f)
652                     as_bad ("5-bit immediate too large");
653                   opcode |= (the_insn.exp.X_add_number & 0x1f) << 11;
654                   memset (&the_insn, '\0', sizeof (the_insn));
655                   the_insn.reloc = NO_RELOC;
656                   continue;
657                 }
658               break;
659
660             case 'l':           /* 26 bit immediate, relative branch */
661               the_insn.reloc = BRADDR;
662               the_insn.pcrel = 1;
663               goto immediate;
664
665             case 's':           /* 16 bit immediate, split relative branch */
666               /* upper 5 bits of offset in dest field */
667               the_insn.pcrel = 1;
668               the_insn.reloc = SPLIT0;
669               goto immediate;
670
671             case 'S':           /* 16 bit immediate, split (st), aligned */
672               if (opcode & (1 << 28))
673                 if (opcode & 0x1)
674                   the_insn.reloc = SPLIT2;
675                 else
676                   the_insn.reloc = SPLIT1;
677               else
678                 the_insn.reloc = SPLIT0;
679               goto immediate;
680
681             case 'I':           /* 16 bit immediate, aligned */
682               if (opcode & (1 << 28))
683                 if (opcode & 0x1)
684                   the_insn.reloc = LOW2;
685                 else
686                   the_insn.reloc = LOW1;
687               else
688                 the_insn.reloc = LOW0;
689               goto immediate;
690
691             case 'i':           /* 16 bit immediate */
692               the_insn.reloc = LOW0;
693
694               /*FALLTHROUGH*/
695
696             immediate:
697               if (*s == ' ')
698                 s++;
699               if (strncmp (s, "ha%", 3) == 0)
700                 {
701                   the_insn.highlow = HIGHADJ;
702                   s += 3;
703                 }
704               else if (strncmp (s, "h%", 2) == 0)
705                 {
706                   the_insn.highlow = HIGH;
707                   s += 2;
708                 }
709               else if (strncmp (s, "l%", 2) == 0)
710                 {
711                   the_insn.highlow = PAIR;
712                   s += 2;
713                 }
714               the_insn.expand = insn->expand;
715
716               /* Note that if the getExpression() fails, we will still have
717                                    created U entries in the symbol table for the 'symbols'
718                                    in the input string.  Try not to create U symbols for
719                                    registers, etc. */
720
721               if (!getExpression (s))
722                 {
723                   s = expr_end;
724                   continue;
725                 }
726               break;
727
728             default:
729               as_fatal ("failed sanity check.");
730             }
731           break;
732         }
733     error:
734       if (match == 0)
735         {
736           /* Args don't match.  */
737           if (&insn[1] - i860_opcodes < NUMOPCODES
738               && !strcmp (insn->name, insn[1].name))
739             {
740               ++insn;
741               s = argsStart;
742               continue;
743             }
744           else
745             {
746               as_bad ("Illegal operands");
747               return;
748             }
749         }
750       break;
751     }
752
753   the_insn.opcode = opcode;
754   return;
755 }
756
757 static int
758 getExpression (str)
759      char *str;
760 {
761   char *save_in;
762   segT seg;
763
764   save_in = input_line_pointer;
765   input_line_pointer = str;
766   switch (seg = expression (&the_insn.exp))
767     {
768
769     case SEG_ABSOLUTE:
770     case SEG_TEXT:
771     case SEG_DATA:
772     case SEG_BSS:
773     case SEG_UNKNOWN:
774     case SEG_DIFFERENCE:
775     case SEG_BIG:
776     case SEG_ABSENT:
777       break;
778
779     default:
780       the_insn.error = "bad segment";
781       expr_end = input_line_pointer;
782       input_line_pointer = save_in;
783       return 1;
784     }
785   expr_end = input_line_pointer;
786   input_line_pointer = save_in;
787   return 0;
788 }
789
790
791 /*
792   This is identical to the md_atof in m68k.c.  I think this is right,
793   but I'm not sure.
794
795   Turn a string in input_line_pointer into a floating point constant of type
796   type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
797   emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
798   */
799
800 /* Equal to MAX_PRECISION in atof-ieee.c */
801 #define MAX_LITTLENUMS 6
802
803 char *
804 md_atof (type, litP, sizeP)
805      char type;
806      char *litP;
807      int *sizeP;
808 {
809   int prec;
810   LITTLENUM_TYPE words[MAX_LITTLENUMS];
811   LITTLENUM_TYPE *wordP;
812   char *t;
813   char *atof_ieee ();
814
815   switch (type)
816     {
817
818     case 'f':
819     case 'F':
820     case 's':
821     case 'S':
822       prec = 2;
823       break;
824
825     case 'd':
826     case 'D':
827     case 'r':
828     case 'R':
829       prec = 4;
830       break;
831
832     case 'x':
833     case 'X':
834       prec = 6;
835       break;
836
837     case 'p':
838     case 'P':
839       prec = 6;
840       break;
841
842     default:
843       *sizeP = 0;
844       return "Bad call to MD_ATOF()";
845     }
846   t = atof_ieee (input_line_pointer, type, words);
847   if (t)
848     input_line_pointer = t;
849   *sizeP = prec * sizeof (LITTLENUM_TYPE);
850   for (wordP = words; prec--;)
851     {
852       md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
853       litP += sizeof (LITTLENUM_TYPE);
854     }
855   return "";                    /* Someone should teach Dean about null pointers */
856 }
857
858 /*
859  * Write out big-endian.
860  */
861 void
862 md_number_to_chars (buf, val, n)
863      char *buf;
864      valueT val;
865      int n;
866 {
867   switch (n)
868     {
869
870     case 4:
871       *buf++ = val >> 24;
872       *buf++ = val >> 16;
873     case 2:
874       *buf++ = val >> 8;
875     case 1:
876       *buf = val;
877       break;
878
879     default:
880       as_fatal ("failed sanity check.");
881     }
882   return;
883 }
884
885 void
886 md_number_to_imm (buf, val, n, fixP)
887      char *buf;
888      long val;
889      int n;
890      fixS *fixP;
891 {
892   enum reloc_type reloc = fixP->fx_r_type & 0xf;
893   enum highlow_type highlow = (fixP->fx_r_type >> 4) & 0x3;
894
895   assert (buf);
896   assert (n == 4);              /* always on i860 */
897
898   switch (highlow)
899     {
900
901     case HIGHADJ:               /* adjusts the high-order 16-bits */
902       if (val & (1 << 15))
903         val += (1 << 16);
904
905       /*FALLTHROUGH*/
906
907     case HIGH:                  /* selects the high-order 16-bits */
908       val >>= 16;
909       break;
910
911     case PAIR:                  /* selects the low-order 16-bits */
912       val = val & 0xffff;
913       break;
914
915     default:
916       break;
917     }
918
919   switch (reloc)
920     {
921
922     case BRADDR:                /* br,call,bc,bc.t,bnc,bnc.t w/26-bit immediate */
923       if (fixP->fx_pcrel != 1)
924         as_bad ("26-bit branch w/o pc relative set: 0x%08x", val);
925       val >>= 2;                /* align pcrel offset, see manual */
926
927       if (val >= (1 << 25) || val < -(1 << 25)) /* check for overflow */
928         as_bad ("26-bit branch offset overflow: 0x%08x", val);
929       buf[0] = (buf[0] & 0xfc) | ((val >> 24) & 0x3);
930       buf[1] = val >> 16;
931       buf[2] = val >> 8;
932       buf[3] = val;
933       break;
934
935     case SPLIT2:                /* 16 bit immediate, 4-byte aligned */
936       if (val & 0x3)
937         as_bad ("16-bit immediate 4-byte alignment error: 0x%08x", val);
938       val &= ~0x3;              /* 4-byte align value */
939       /*FALLTHROUGH*/
940     case SPLIT1:                /* 16 bit immediate, 2-byte aligned */
941       if (val & 0x1)
942         as_bad ("16-bit immediate 2-byte alignment error: 0x%08x", val);
943       val &= ~0x1;              /* 2-byte align value */
944       /*FALLTHROUGH*/
945     case SPLIT0:                /* st,bla,bte,btne w/16-bit immediate */
946       if (fixP->fx_pcrel == 1)
947         val >>= 2;              /* align pcrel offset, see manual */
948       /* check for bounds */
949       if (highlow != PAIR && (val >= (1 << 16) || val < -(1 << 15)))
950         as_bad ("16-bit branch offset overflow: 0x%08x", val);
951       buf[1] = (buf[1] & ~0x1f) | ((val >> 11) & 0x1f);
952       buf[2] = (buf[2] & ~0x7) | ((val >> 8) & 0x7);
953       buf[3] |= val;            /* perserve bottom opcode bits */
954       break;
955
956     case LOW4:                  /* fld,pfld,pst,flush 16-byte aligned */
957       if (val & 0xf)
958         as_bad ("16-bit immediate 16-byte alignment error: 0x%08x", val);
959       val &= ~0xf;              /* 16-byte align value */
960       /*FALLTHROUGH*/
961     case LOW3:                  /* fld,pfld,pst,flush 8-byte aligned */
962       if (val & 0x7)
963         as_bad ("16-bit immediate 8-byte alignment error: 0x%08x", val);
964       val &= ~0x7;              /* 8-byte align value */
965       /*FALLTHROUGH*/
966     case LOW2:                  /* 16 bit immediate, 4-byte aligned */
967       if (val & 0x3)
968         as_bad ("16-bit immediate 4-byte alignment error: 0x%08x", val);
969       val &= ~0x3;              /* 4-byte align value */
970       /*FALLTHROUGH*/
971     case LOW1:                  /* 16 bit immediate, 2-byte aligned */
972       if (val & 0x1)
973         as_bad ("16-bit immediate 2-byte alignment error: 0x%08x", val);
974       val &= ~0x1;              /* 2-byte align value */
975       /*FALLTHROUGH*/
976     case LOW0:                  /* 16 bit immediate, byte aligned */
977       /* check for bounds */
978       if (highlow != PAIR && (val >= (1 << 16) || val < -(1 << 15)))
979         as_bad ("16-bit immediate overflow: 0x%08x", val);
980       buf[2] = val >> 8;
981       buf[3] |= val;            /* perserve bottom opcode bits */
982       break;
983
984     case NO_RELOC:
985     default:
986       as_bad ("bad relocation type: 0x%02x", reloc);
987       break;
988     }
989   return;
990 }
991
992 /* should never be called for i860 */
993 void
994 md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
995      char *ptr;
996      addressT from_addr, to_addr;
997      fragS *frag;
998      symbolS *to_symbol;
999 {
1000   as_fatal ("i860_create_short_jmp\n");
1001 }
1002
1003 /* should never be called for i860 */
1004 void
1005 md_number_to_disp (buf, val, n)
1006      char *buf;
1007      long val;
1008 {
1009   as_fatal ("md_number_to_disp\n");
1010 }
1011
1012 /* should never be called for i860 */
1013 void
1014 md_number_to_field (buf, val, fix)
1015      char *buf;
1016      long val;
1017      void *fix;
1018 {
1019   as_fatal ("i860_number_to_field\n");
1020 }
1021
1022 /* the bit-field entries in the relocation_info struct plays hell
1023    with the byte-order problems of cross-assembly.  So as a hack,
1024    I added this mach. dependent ri twiddler.  Ugly, but it gets
1025    you there. -KWK */
1026 /* on i860: first 4 bytes are normal unsigned long address, next three
1027    bytes are index, most sig. byte first.  Byte 7 is broken up with
1028    bit 7 as pcrel, bit 6 as extern, and the lower six bits as
1029    relocation type (highlow 5-4).  Next 4 bytes are long addend. */
1030 /* Thanx and a tip of the hat to Michael Bloom, [email protected] */
1031 void
1032 md_ri_to_chars (ri_p, ri)
1033      struct relocation_info *ri_p, ri;
1034 {
1035 #if 0
1036   unsigned char the_bytes[sizeof (*ri_p)];
1037
1038   /* this is easy */
1039   md_number_to_chars (the_bytes, ri.r_address, sizeof (ri.r_address));
1040   /* now the fun stuff */
1041   the_bytes[4] = (ri.r_index >> 16) & 0x0ff;
1042   the_bytes[5] = (ri.r_index >> 8) & 0x0ff;
1043   the_bytes[6] = ri.r_index & 0x0ff;
1044   the_bytes[7] = ((ri.r_extern << 7) & 0x80) | (0 & 0x60) | (ri.r_type & 0x1F);
1045   /* Also easy */
1046   md_number_to_chars (&the_bytes[8], ri.r_addend, sizeof (ri.r_addend));
1047   /* now put it back where you found it, Junior... */
1048   memcpy ((char *) ri_p, the_bytes, sizeof (*ri_p));
1049 #endif
1050 }
1051
1052 /* should never be called for i860 */
1053 void
1054 md_convert_frag (headers, fragP)
1055      object_headers *headers;
1056      register fragS *fragP;
1057 {
1058   as_fatal ("i860_convert_frag\n");
1059 }
1060
1061 /* should never be called for i860 */
1062 void
1063 md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
1064      char *ptr;
1065      addressT from_addr, to_addr;
1066      fragS *frag;
1067      symbolS *to_symbol;
1068 {
1069   as_fatal ("i860_create_long_jump\n");
1070 }
1071
1072 /* should never be called for i860 */
1073 int
1074 md_estimate_size_before_relax (fragP, segtype)
1075      register fragS *fragP;
1076      segT segtype;
1077 {
1078   as_fatal ("i860_estimate_size_before_relax\n");
1079 }
1080
1081 /* for debugging only, must match enum reloc_type */
1082 static char *Reloc[] =
1083 {
1084   "NO_RELOC",
1085   "BRADDR",
1086   "LOW0",
1087   "LOW1",
1088   "LOW2",
1089   "LOW3",
1090   "LOW4",
1091   "SPLIT0",
1092   "SPLIT1",
1093   "SPLIT2",
1094   "RELOC_32",
1095 };
1096 static char *Highlow[] =
1097 {
1098   "NO_SPEC",
1099   "PAIR",
1100   "HIGH",
1101   "HIGHADJ",
1102 };
1103 static void
1104 print_insn (insn)
1105      struct i860_it *insn;
1106 {
1107   if (insn->error)
1108     {
1109       fprintf (stderr, "ERROR: %s\n");
1110     }
1111   fprintf (stderr, "opcode=0x%08x\t", insn->opcode);
1112   fprintf (stderr, "expand=0x%08x\t", insn->expand);
1113   fprintf (stderr, "reloc = %s\t", Reloc[insn->reloc]);
1114   fprintf (stderr, "highlow = %s\n", Highlow[insn->highlow]);
1115   fprintf (stderr, "exp =  {\n");
1116   fprintf (stderr, "\t\tX_add_symbol = %s\n",
1117            insn->exp.X_add_symbol ?
1118            (S_GET_NAME (insn->exp.X_add_symbol) ?
1119             S_GET_NAME (insn->exp.X_add_symbol) : "???") : "0");
1120   fprintf (stderr, "\t\tX_sub_symbol = %s\n",
1121            insn->exp.X_subtract_symbol ?
1122            (S_GET_NAME (insn->exp.X_subtract_symbol) ?
1123             S_GET_NAME (insn->exp.X_subtract_symbol) : "???") : "0");
1124   fprintf (stderr, "\t\tX_add_number = %d\n",
1125            insn->exp.X_add_number);
1126   fprintf (stderr, "}\n");
1127   return;
1128 }
1129
1130 int
1131 md_parse_option (argP, cntP, vecP)
1132      char **argP;
1133      int *cntP;
1134      char ***vecP;
1135 {
1136   return 1;
1137 }
1138
1139 #ifdef comment
1140 /*
1141  * I860 relocations are completely different, so it needs
1142  * this machine dependent routine to emit them.
1143  */
1144 void
1145 emit_machine_reloc (fixP, segment_address_in_file)
1146      register fixS *fixP;
1147      relax_addressT segment_address_in_file;
1148 {
1149   struct reloc_info_i860 ri;
1150   register symbolS *symbolP;
1151   extern char *next_object_file_charP;
1152   long add_number;
1153
1154   memset ((char *) &ri, '\0', sizeof (ri));
1155   for (; fixP; fixP = fixP->fx_next)
1156     {
1157
1158       if (fixP->fx_r_type & ~0x3f)
1159         {
1160           as_fatal ("fixP->fx_r_type = %d\n", fixP->fx_r_type);
1161         }
1162       ri.r_pcrel = fixP->fx_pcrel;
1163       ri.r_type = fixP->fx_r_type;
1164
1165       if ((symbolP = fixP->fx_addsy) != NULL)
1166         {
1167           ri.r_address = fixP->fx_frag->fr_address +
1168             fixP->fx_where - segment_address_in_file;
1169           if (!S_IS_DEFINED (symbolP))
1170             {
1171               ri.r_extern = 1;
1172               ri.r_symbolnum = symbolP->sy_number;
1173             }
1174           else
1175             {
1176               ri.r_extern = 0;
1177               ri.r_symbolnum = S_GET_TYPE (symbolP);
1178             }
1179           if (symbolP && symbolP->sy_frag)
1180             {
1181               ri.r_addend = symbolP->sy_frag->fr_address;
1182             }
1183           ri.r_type = fixP->fx_r_type;
1184           if (fixP->fx_pcrel)
1185             {
1186               /* preserve actual offset vs. pc + 4 */
1187               ri.r_addend -= (ri.r_address + 4);
1188             }
1189           else
1190             {
1191               ri.r_addend = fixP->fx_addnumber;
1192             }
1193
1194           md_ri_to_chars ((char *) &ri, ri);
1195           append (&next_object_file_charP, (char *) &ri, sizeof (ri));
1196         }
1197     }
1198   return;
1199 }
1200
1201 #endif /* comment */
1202
1203 #ifdef OBJ_AOUT
1204
1205 /* on i860: first 4 bytes are normal unsigned long address, next three
1206    bytes are index, most sig. byte first.  Byte 7 is broken up with
1207    bit 7 as pcrel, bit 6 as extern, and the lower six bits as
1208    relocation type (highlow 5-4).  Next 4 bytes are long addend. */
1209
1210 void
1211 tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
1212      char *where;
1213      fixS *fixP;
1214      relax_addressT segment_address_in_file;
1215 {
1216   long r_index;
1217   long r_extern;
1218   long r_addend = 0;
1219   long r_address;
1220
1221   know (fixP->fx_addsy);
1222   know (!(fixP->fx_r_type & ~0x3f));
1223
1224   if (!S_IS_DEFINED (fixP->fx_addsy))
1225     {
1226       r_extern = 1;
1227       r_index = fixP->fx_addsy->sy_number;
1228     }
1229   else
1230     {
1231       r_extern = 0;
1232       r_index = S_GET_TYPE (fixP->fx_addsy);
1233     }
1234
1235   md_number_to_chars (where,
1236                       r_address = fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
1237                       4);
1238
1239   where[4] = (r_index >> 16) & 0x0ff;
1240   where[5] = (r_index >> 8) & 0x0ff;
1241   where[6] = r_index & 0x0ff;
1242   where[7] = (((fixP->fx_pcrel << 7) & 0x80)
1243               | ((r_extern << 6) & 0x40)
1244               | (fixP->fx_r_type & 0x3F));
1245
1246   if (fixP->fx_addsy->sy_frag)
1247     {
1248       r_addend = fixP->fx_addsy->sy_frag->fr_address;
1249     }
1250
1251   if (fixP->fx_pcrel)
1252     {
1253       /* preserve actual offset vs. pc + 4 */
1254       r_addend -= (r_address + 4);
1255     }
1256   else
1257     {
1258       r_addend = fixP->fx_addnumber;
1259     }
1260
1261   md_number_to_chars (&where[8], r_addend, 4);
1262
1263   return;
1264 }                               /* tc_aout_fix_to_chars() */
1265
1266 #endif /* OBJ_AOUT */
1267
1268 /* Parse an operand that is machine-specific.
1269    We just return without modifying the expression if we have nothing
1270    to do.  */
1271
1272 /* ARGSUSED */
1273 void
1274 md_operand (expressionP)
1275      expressionS *expressionP;
1276 {
1277 }
1278
1279 /* We have no need to default values of symbols.  */
1280
1281 /* ARGSUSED */
1282 symbolS *
1283 md_undefined_symbol (name)
1284      char *name;
1285 {
1286   return 0;
1287 }
1288
1289 /* Round up a section size to the appropriate boundary.  */
1290 valueT
1291 md_section_align (segment, size)
1292      segT segment;
1293      valueT size;
1294 {
1295   return size;                  /* Byte alignment is fine */
1296 }
1297
1298 /* Exactly what point is a PC-relative offset relative TO?
1299    On the i860, they're relative to the address of the offset, plus
1300    its size. (??? Is this right?  FIXME-SOON!) */
1301 long
1302 md_pcrel_from (fixP)
1303      fixS *fixP;
1304 {
1305   return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
1306 }
1307
1308 void
1309 md_apply_fix (fixP, val)
1310      fixS *fixP;
1311      long val;
1312 {
1313   char *place = fixP->fx_where + fixP->fx_frag->fr_literal;
1314
1315   /* looks to me like i860 never has bit fixes. Let's see. xoxorich. */
1316   know (fixP->fx_bit_fixP == NULL);
1317   if (!fixP->fx_bit_fixP)
1318     {
1319
1320       /* also looks like fx_im_disp is always 0.  Let's see.  xoxorich. */
1321       know (fixP->fx_im_disp == 0);
1322       switch (fixP->fx_im_disp)
1323         {
1324         case 0:
1325           fixP->fx_addnumber = val;
1326           md_number_to_imm (place, val, fixP->fx_size, fixP);
1327           break;
1328         case 1:
1329           md_number_to_disp (place,
1330                          fixP->fx_pcrel ? val + fixP->fx_pcrel_adjust : val,
1331                              fixP->fx_size);
1332           break;
1333         case 2:         /* fix requested for .long .word etc */
1334           md_number_to_chars (place, val, fixP->fx_size);
1335           break;
1336         default:
1337           as_fatal ("Internal error in md_apply_fix() in file \"%s\"", __FILE__);
1338         }                       /* OVE: maybe one ought to put _imm _disp _chars in one md-func */
1339     }
1340   else
1341     {
1342       md_number_to_field (place, val, fixP->fx_bit_fixP);
1343     }
1344
1345   return;
1346 }                               /* md_apply_fix() */
1347
1348 /*
1349  * Local Variables:
1350  * fill-column: 131
1351  * comment-column: 0
1352  * End:
1353  */
1354
1355 /* end of tc-i860.c */
This page took 0.099897 seconds and 4 git commands to generate.