]> Git Repo - binutils.git/blob - gas/config/tc-i860.c
Fix sh-elf linker relaxation:
[binutils.git] / gas / config / tc-i860.c
1 /* tc-i860.c -- Assembler for the Intel i860 architecture.
2    Copyright 1989, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002
3    Free Software Foundation, Inc.
4
5    Brought back from the dead and completely reworked
6    by Jason Eckhardt <[email protected]>.
7
8    This file is part of GAS, the GNU Assembler.
9
10    GAS is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2, or (at your option)
13    any later version.
14
15    GAS is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License along
21    with GAS; see the file COPYING.  If not, write to the Free Software
22    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
23
24 #include <stdio.h>
25 #include <string.h>
26 #include "as.h"
27 #include "safe-ctype.h"
28 #include "subsegs.h"
29 #include "opcode/i860.h"
30 #include "elf/i860.h"
31
32 /* Defined by default since this is primarily a SVR4/860 assembler.
33    However, I'm trying to leave the door open for Intel syntax. Of course,
34    if full support for anything other than SVR4 is done, then we should
35    select this based on a command-line flag.  */
36 #define SYNTAX_SVR4
37
38 /* The opcode hash table.  */
39 static struct hash_control *op_hash = NULL;
40
41 /* These characters always start a comment.  */
42 const char comment_chars[] = "#!/";
43
44 /* These characters start a comment at the beginning of a line.  */
45 const char line_comment_chars[] = "#/";
46
47 const char line_separator_chars[] = ";";
48
49 /* Characters that can be used to separate the mantissa from the exponent
50    in floating point numbers.  */
51 const char EXP_CHARS[] = "eE";
52
53 /* Characters that indicate this number is a floating point constant.
54    As in 0f12.456 or 0d1.2345e12.  */
55 const char FLT_CHARS[] = "rRsSfFdDxXpP";
56
57 /* Register prefix.  */
58 #ifdef SYNTAX_SVR4
59 static const char reg_prefix = '%';
60 #else
61 static const char reg_prefix = 0;
62 #endif
63
64 struct i860_it
65 {
66   char *error;
67   unsigned long opcode;
68   expressionS exp;
69   enum expand_type expand;
70   bfd_reloc_code_real_type reloc;
71   int pcrel;
72   valueT fup;
73 } the_insn;
74
75 static char *expr_end;
76
77 /* Indicates error if a pseudo operation was expanded after a branch.  */
78 static char last_expand;
79
80 /* If true, then warn if any pseudo operations were expanded.  */
81 static int target_warn_expand = 0;
82
83 /* Prototypes.  */
84 static void i860_process_insn   PARAMS ((char *));
85 static void s_dual              PARAMS ((int));
86 static void s_enddual           PARAMS ((int));
87 static void s_atmp              PARAMS ((int));
88 static int i860_get_expression  PARAMS ((char *));
89 static bfd_reloc_code_real_type obtain_reloc_for_imm16
90   PARAMS ((fixS *, long *));
91 #ifdef DEBUG_I860
92 static void print_insn          PARAMS ((struct i860_it *));
93 #endif
94
95 const pseudo_typeS md_pseudo_table[] =
96 {
97 #ifdef OBJ_ELF
98   {"align",   s_align_bytes, 0},
99 #endif
100   {"dual",    s_dual,        0},
101   {"enddual", s_enddual,     0},
102   {"atmp",    s_atmp,        0},
103   {NULL,      0,             0},
104 };
105
106 /* Dual-instruction mode handling.  */
107 enum dual
108 {
109   DUAL_OFF = 0, DUAL_ON, DUAL_DDOT, DUAL_ONDDOT,
110 };
111 static enum dual dual_mode = DUAL_OFF;
112
113 /* Handle ".dual" directive.  */
114 static void
115 s_dual (ignore)
116      int ignore ATTRIBUTE_UNUSED;
117 {
118   dual_mode = DUAL_ON;
119 }
120
121 /* Handle ".enddual" directive.  */
122 static void
123 s_enddual (ignore)
124      int ignore ATTRIBUTE_UNUSED;
125 {
126   dual_mode = DUAL_OFF;
127 }
128
129 /* Temporary register used when expanding assembler pseudo operations.  */
130 static int atmp = 31;
131
132 static void
133 s_atmp (ignore)
134      int ignore ATTRIBUTE_UNUSED;
135 {
136   register int temp;
137   if (strncmp (input_line_pointer, "sp", 2) == 0)
138     {
139       input_line_pointer += 2;
140       atmp = 2;
141     }
142   else if (strncmp (input_line_pointer, "fp", 2) == 0)
143     {
144       input_line_pointer += 2;
145       atmp = 3;
146     }
147   else if (strncmp (input_line_pointer, "r", 1) == 0)
148     {
149       input_line_pointer += 1;
150       temp = get_absolute_expression ();
151       if (temp >= 0 && temp <= 31)
152         atmp = temp;
153       else
154         as_bad (_("Unknown temporary pseudo register"));
155     }
156   else
157     {
158       as_bad (_("Unknown temporary pseudo register"));
159     }
160   demand_empty_rest_of_line ();
161 }
162
163 /* This function is called once, at assembler startup time.  It should
164    set up all the tables and data structures that the MD part of the
165    assembler will need.  */
166 void
167 md_begin ()
168 {
169   const char *retval = NULL;
170   int lose = 0;
171   unsigned int i = 0;
172
173   op_hash = hash_new ();
174
175   while (i860_opcodes[i].name != NULL)
176     {
177       const char *name = i860_opcodes[i].name;
178       retval = hash_insert (op_hash, name, (PTR)&i860_opcodes[i]);
179       if (retval != NULL)
180         {
181           fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
182                    i860_opcodes[i].name, retval);
183           lose = 1;
184         }
185       do
186         {
187           if (i860_opcodes[i].match & i860_opcodes[i].lose)
188             {
189               fprintf (stderr,
190                        _("internal error: losing opcode: `%s' \"%s\"\n"),
191                        i860_opcodes[i].name, i860_opcodes[i].args);
192               lose = 1;
193             }
194           ++i;
195         }
196       while (i860_opcodes[i].name != NULL
197              && strcmp (i860_opcodes[i].name, name) == 0);
198     }
199
200   if (lose)
201     as_fatal (_("Defective assembler.  No assembly attempted."));
202 }
203
204 /* This is the core of the machine-dependent assembler.  STR points to a
205    machine dependent instruction.  This function emits the frags/bytes
206    it assembles to.  */
207 void
208 md_assemble (str)
209      char *str;
210 {
211   char *destp;
212   int num_opcodes = 1;
213   int i;
214   struct i860_it pseudo[3];
215
216   assert (str);
217
218   /* Assemble the instruction.  */
219   i860_process_insn (str);
220
221   /* Check for expandable flag to produce pseudo-instructions.  This
222      is an undesirable feature that should be avoided.  */
223   if (the_insn.expand != 0
224       && ! (the_insn.fup & (OP_SEL_HA | OP_SEL_H | OP_SEL_L | OP_SEL_GOT
225                             | OP_SEL_GOTOFF | OP_SEL_PLT)))
226     {
227       for (i = 0; i < 3; i++)
228         pseudo[i] = the_insn;
229
230       switch (the_insn.expand)
231         {
232
233         case E_DELAY:
234           num_opcodes = 1;
235           break;
236
237         case E_MOV:
238           if (the_insn.exp.X_add_symbol == NULL
239               && the_insn.exp.X_op_symbol == NULL
240               && (the_insn.exp.X_add_number < (1 << 15)
241                   && the_insn.exp.X_add_number >= -(1 << 15)))
242             break;
243
244           /* Emit "or l%const,r0,ireg_dest".  */
245           pseudo[0].opcode = (the_insn.opcode & 0x001f0000) | 0xe4000000;
246           pseudo[0].fup = (OP_IMM_S16 | OP_SEL_L);
247
248           /* Emit "orh h%const,ireg_dest,ireg_dest".  */
249           pseudo[1].opcode = (the_insn.opcode & 0x03ffffff) | 0xec000000
250                               | ((the_insn.opcode & 0x001f0000) << 5);
251           pseudo[1].fup = (OP_IMM_S16 | OP_SEL_H);
252
253           num_opcodes = 2;
254           break;
255
256         case E_ADDR:
257           if (the_insn.exp.X_add_symbol == NULL
258               && the_insn.exp.X_op_symbol == NULL
259               && (the_insn.exp.X_add_number < (1 << 15)
260                   && the_insn.exp.X_add_number >= -(1 << 15)))
261             break;
262
263           /* Emit "orh ha%addr_expr,r0,r31".  */
264           pseudo[0].opcode = 0xec000000 | (atmp << 16);
265           pseudo[0].fup = (OP_IMM_S16 | OP_SEL_HA);
266
267           /* Emit "l%addr_expr(r31),ireg_dest".  We pick up the fixup
268              information from the original instruction.   */
269           pseudo[1].opcode = (the_insn.opcode & ~0x03e00000) | (atmp << 21);
270           pseudo[1].fup = the_insn.fup | OP_SEL_L;
271
272           num_opcodes = 2;
273           break;
274
275         case E_U32:
276           if (the_insn.exp.X_add_symbol == NULL
277               && the_insn.exp.X_op_symbol == NULL
278               && (the_insn.exp.X_add_number < (1 << 16)
279                   && the_insn.exp.X_add_number >= 0))
280             break;
281
282           /* Emit "$(opcode)h h%const,ireg_src2,r31".  */
283           pseudo[0].opcode = (the_insn.opcode & 0xf3e0ffff) | 0x0c000000
284                               | (atmp << 16);
285           pseudo[0].fup = (OP_IMM_S16 | OP_SEL_H);
286
287           /* Emit "$(opcode) l%const,r31,ireg_dest".  */
288           pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000
289                               | (atmp << 21);
290           pseudo[1].fup = (OP_IMM_S16 | OP_SEL_L);
291
292           num_opcodes = 2;
293           break;
294
295         case E_AND:
296           if (the_insn.exp.X_add_symbol == NULL
297               && the_insn.exp.X_op_symbol == NULL
298               && (the_insn.exp.X_add_number < (1 << 16)
299                   && the_insn.exp.X_add_number >= 0))
300             break;
301
302           /* Emit "andnot h%const,ireg_src2,r31".  */
303           pseudo[0].opcode = (the_insn.opcode & 0x03e0ffff) | 0xd4000000
304                               | (atmp << 16);
305           pseudo[0].fup = (OP_IMM_S16 | OP_SEL_H);
306           pseudo[0].exp.X_add_number = -1 - the_insn.exp.X_add_number;
307
308           /* Emit "andnot l%const,r31,ireg_dest".  */
309           pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000
310                               | (atmp << 21);
311           pseudo[1].fup = (OP_IMM_S16 | OP_SEL_L);
312           pseudo[1].exp.X_add_number = -1 - the_insn.exp.X_add_number;
313
314           num_opcodes = 2;
315           break;
316
317         case E_S32:
318           if (the_insn.exp.X_add_symbol == NULL
319               && the_insn.exp.X_op_symbol == NULL
320               && (the_insn.exp.X_add_number < (1 << 15)
321                   && the_insn.exp.X_add_number >= -(1 << 15)))
322             break;
323
324           /* Emit "orh h%const,r0,r31".  */
325           pseudo[0].opcode = 0xec000000 | (atmp << 16);
326           pseudo[0].fup = (OP_IMM_S16 | OP_SEL_H);
327
328           /* Emit "or l%const,r31,r31".  */
329           pseudo[1].opcode = 0xe4000000 | (atmp << 21) | (atmp << 16);
330           pseudo[1].fup = (OP_IMM_S16 | OP_SEL_L);
331
332           /* Emit "r31,ireg_src2,ireg_dest".  */
333           pseudo[2].opcode = (the_insn.opcode & ~0x0400ffff) | (atmp << 11);
334           pseudo[2].fup = OP_IMM_S16;
335
336           num_opcodes = 3;
337           break;
338
339         default:
340           as_fatal (_("failed sanity check."));
341         }
342
343       the_insn = pseudo[0];
344
345       /* Warn if an opcode is expanded after a delayed branch.  */
346       if (num_opcodes > 1 && last_expand == 1)
347         as_warn (_("Expanded opcode after delayed branch: `%s'"), str);
348
349       /* Warn if an opcode is expanded in dual mode.  */
350       if (num_opcodes > 1 && dual_mode != DUAL_OFF)
351         as_warn (_("Expanded opcode in dual mode: `%s'"), str);
352
353       /* Notify if any expansions happen.  */
354       if (target_warn_expand && num_opcodes > 1)
355         as_warn (_("An instruction was expanded (%s)"), str);
356     }
357
358   i = 0;
359   do
360     {
361       /* Output the opcode.  Note that the i860 always reads instructions
362          as little-endian data.  */
363       destp = frag_more (4);
364       number_to_chars_littleendian (destp, the_insn.opcode, 4);
365
366       /* Check for expanded opcode after branch or in dual mode.  */
367       last_expand = the_insn.pcrel;
368
369       /* Output the symbol-dependent stuff.  */
370       if (the_insn.fup != OP_NONE)
371         {
372           fixS *fix;
373           fix = fix_new_exp (frag_now,
374                              destp - frag_now->fr_literal,
375                              4,
376                              &the_insn.exp,
377                              the_insn.pcrel,
378                              the_insn.reloc);
379
380           /* Despite the odd name, this is a scratch field.  We use
381              it to encode operand type information.  */
382           fix->fx_addnumber = the_insn.fup;
383         }
384       the_insn = pseudo[++i];
385     }
386   while (--num_opcodes > 0);
387
388 }
389
390 /* Assemble the instruction pointed to by STR.  */
391 static void
392 i860_process_insn (str)
393      char *str;
394 {
395   char *s;
396   const char *args;
397   char c;
398   struct i860_opcode *insn;
399   char *args_start;
400   unsigned long opcode;
401   unsigned int mask;
402   int match = 0;
403   int comma = 0;
404
405 #if 1 /* For compiler warnings.  */
406   args = 0;
407   insn = 0;
408   args_start = 0;
409   opcode = 0;
410 #endif
411
412   for (s = str; ISLOWER (*s) || *s == '.' || *s == '3'
413        || *s == '2' || *s == '1'; ++s)
414     ;
415
416   switch (*s)
417     {
418     case '\0':
419       break;
420
421     case ',':
422       comma = 1;
423
424       /*FALLTHROUGH*/
425
426     case ' ':
427       *s++ = '\0';
428       break;
429
430     default:
431       as_fatal (_("Unknown opcode: `%s'"), str);
432     }
433
434   /* Check for dual mode ("d.") opcode prefix.  */
435   if (strncmp (str, "d.", 2) == 0)
436     {
437       if (dual_mode == DUAL_ON)
438         dual_mode = DUAL_ONDDOT;
439       else
440         dual_mode = DUAL_DDOT;
441       str += 2;
442     }
443
444   if ((insn = (struct i860_opcode *) hash_find (op_hash, str)) == NULL)
445     {
446       if (dual_mode == DUAL_DDOT || dual_mode == DUAL_ONDDOT)
447         str -= 2;
448       as_bad (_("Unknown opcode: `%s'"), str);
449       return;
450     }
451
452   if (comma)
453     *--s = ',';
454
455   args_start = s;
456   for (;;)
457     {
458       opcode = insn->match;
459       memset (&the_insn, '\0', sizeof (the_insn));
460       the_insn.reloc = BFD_RELOC_NONE;
461       the_insn.pcrel = 0;
462       the_insn.fup = OP_NONE;
463
464       /* Build the opcode, checking as we go that the operands match.  */
465       for (args = insn->args; ; ++args)
466         {
467           switch (*args)
468             {
469
470             /* End of args.  */
471             case '\0':
472               if (*s == '\0')
473                 match = 1;
474               break;
475
476             /* These must match exactly.  */
477             case '+':
478             case '(':
479             case ')':
480             case ',':
481             case ' ':
482               if (*s++ == *args)
483                 continue;
484               break;
485
486             /* Must be at least one digit.  */
487             case '#':
488               if (ISDIGIT (*s++))
489                 {
490                   while (ISDIGIT (*s))
491                     ++s;
492                   continue;
493                 }
494               break;
495
496             /* Next operand must be a register.  */
497             case '1':
498             case '2':
499             case 'd':
500               /* Check for register prefix if necessary.  */
501               if (reg_prefix && *s != reg_prefix)
502                 goto error;
503               else
504                 s++;
505
506               switch (*s)
507                 {
508                 /* Frame pointer.  */
509                 case 'f':
510                   s++;
511                   if (*s++ == 'p')
512                     {
513                       mask = 0x3;
514                       break;
515                     }
516                   goto error;
517
518                 /* Stack pointer.  */
519                 case 's':
520                   s++;
521                   if (*s++ == 'p')
522                     {
523                       mask = 0x2;
524                       break;
525                     }
526                   goto error;
527
528                 /* Any register r0..r31.  */
529                 case 'r':
530                   s++;
531                   if (!ISDIGIT (c = *s++))
532                     {
533                       goto error;
534                     }
535                   if (ISDIGIT (*s))
536                     {
537                       if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
538                         goto error;
539                     }
540                   else
541                     c -= '0';
542                   mask = c;
543                   break;
544
545                 /* Not this opcode.  */
546                 default:
547                   goto error;
548                 }
549
550               /* Obtained the register, now place it in the opcode.  */
551               switch (*args)
552                 {
553                 case '1':
554                   opcode |= mask << 11;
555                   continue;
556
557                 case '2':
558                   opcode |= mask << 21;
559                   continue;
560
561                 case 'd':
562                   opcode |= mask << 16;
563                   continue;
564
565                 }
566               break;
567
568             /* Next operand is a floating point register.  */
569             case 'e':
570             case 'f':
571             case 'g':
572               /* Check for register prefix if necessary.  */
573               if (reg_prefix && *s != reg_prefix)
574                 goto error;
575               else
576                 s++;
577
578               if (*s++ == 'f' && ISDIGIT (*s))
579                 {
580                   mask = *s++;
581                   if (ISDIGIT (*s))
582                     {
583                       mask = 10 * (mask - '0') + (*s++ - '0');
584                       if (mask >= 32)
585                         {
586                           break;
587                         }
588                     }
589                   else
590                     mask -= '0';
591
592                   switch (*args)
593                     {
594
595                     case 'e':
596                       opcode |= mask << 11;
597                       continue;
598
599                     case 'f':
600                       opcode |= mask << 21;
601                       continue;
602
603                     case 'g':
604                       opcode |= mask << 16;
605                       if (dual_mode != DUAL_OFF)
606                         opcode |= (1 << 9);
607                       if (dual_mode == DUAL_DDOT)
608                         dual_mode = DUAL_OFF;
609                       if (dual_mode == DUAL_ONDDOT)
610                         dual_mode = DUAL_ON;
611                       if ((opcode & (1 << 10)) && mask != 0
612                           && (mask == ((opcode >> 11) & 0x1f)))
613                         as_warn (_("Pipelined instruction: fsrc1 = fdest"));
614                       continue;
615                     }
616                 }
617               break;
618
619             /* Next operand must be a control register.  */
620             case 'c':
621               /* Check for register prefix if necessary.  */
622               if (reg_prefix && *s != reg_prefix)
623                 goto error;
624               else
625                 s++;
626
627               if (strncmp (s, "fir", 3) == 0)
628                 {
629                   opcode |= 0x0 << 21;
630                   s += 3;
631                   continue;
632                 }
633               if (strncmp (s, "psr", 3) == 0)
634                 {
635                   opcode |= 0x1 << 21;
636                   s += 3;
637                   continue;
638                 }
639               if (strncmp (s, "dirbase", 7) == 0)
640                 {
641                   opcode |= 0x2 << 21;
642                   s += 7;
643                   continue;
644                 }
645               if (strncmp (s, "db", 2) == 0)
646                 {
647                   opcode |= 0x3 << 21;
648                   s += 2;
649                   continue;
650                 }
651               if (strncmp (s, "fsr", 3) == 0)
652                 {
653                   opcode |= 0x4 << 21;
654                   s += 3;
655                   continue;
656                 }
657               if (strncmp (s, "epsr", 4) == 0)
658                 {
659                   opcode |= 0x5 << 21;
660                   s += 4;
661                   continue;
662                 }
663               break;
664
665             /* 5-bit immediate in src1.  */
666             case '5':
667               if (! i860_get_expression (s))
668                 {
669                   s = expr_end;
670                   the_insn.fup |= OP_IMM_U5;
671                   continue;
672                 }
673               break;
674
675             /* 26-bit immediate, relative branch (lbroff).  */
676             case 'l':
677               the_insn.pcrel = 1;
678               the_insn.fup |= OP_IMM_BR26;
679               goto immediate;
680
681             /* 16-bit split immediate, relative branch (sbroff).  */
682             case 'r':
683               the_insn.pcrel = 1;
684               the_insn.fup |= OP_IMM_BR16;
685               goto immediate;
686
687             /* 16-bit split immediate.  */
688             case 's':
689               the_insn.fup |= OP_IMM_SPLIT16;
690               goto immediate;
691
692             /* 16-bit split immediate, byte aligned (st.b).  */
693             case 'S':
694               the_insn.fup |= OP_IMM_SPLIT16;
695               goto immediate;
696
697             /* 16-bit split immediate, half-word aligned (st.s).  */
698             case 'T':
699               the_insn.fup |= (OP_IMM_SPLIT16 | OP_ENCODE1 | OP_ALIGN2);
700               goto immediate;
701
702             /* 16-bit split immediate, word aligned (st.l).  */
703             case 'U':
704               the_insn.fup |= (OP_IMM_SPLIT16 | OP_ENCODE1 | OP_ALIGN4);
705               goto immediate;
706
707             /* 16-bit immediate.  */
708             case 'i':
709               the_insn.fup |= OP_IMM_S16;
710               goto immediate;
711
712             /* 16-bit immediate, byte aligned (ld.b).  */
713             case 'I':
714               the_insn.fup |= OP_IMM_S16;
715               goto immediate;
716
717             /* 16-bit immediate, half-word aligned (ld.s).  */
718             case 'J':
719               the_insn.fup |= (OP_IMM_S16 | OP_ENCODE1 | OP_ALIGN2);
720               goto immediate;
721
722             /* 16-bit immediate, word aligned (ld.l, {p}fld.l, fst.l).  */
723             case 'K':
724               if (insn->name[0] == 'l')
725                 the_insn.fup |= (OP_IMM_S16 | OP_ENCODE1 | OP_ALIGN4);
726               else
727                 the_insn.fup |= (OP_IMM_S16 | OP_ENCODE2 | OP_ALIGN4);
728               goto immediate;
729
730             /* 16-bit immediate, double-word aligned ({p}fld.d, fst.d).  */
731             case 'L':
732               the_insn.fup |= (OP_IMM_S16 | OP_ENCODE3 | OP_ALIGN8);
733               goto immediate;
734
735             /* 16-bit immediate, quad-word aligned (fld.q, fst.q).  */
736             case 'M':
737               the_insn.fup |= (OP_IMM_S16 | OP_ENCODE3 | OP_ALIGN16);
738
739               /*FALLTHROUGH*/
740
741               /* Handle the immediate for either the Intel syntax or
742                  SVR4 syntax. The Intel syntax is "ha%immediate"
743                  whereas SVR4 syntax is "[immediate]@ha".  */
744             immediate:
745 #ifdef SYNTAX_SVR4
746               if (*s == ' ')
747                 s++;
748
749               /* Note that if i860_get_expression() fails, we will still
750                  have created U entries in the symbol table for the
751                  'symbols' in the input string.  Try not to create U
752                  symbols for registers, etc.  */
753               if (! i860_get_expression (s))
754                 s = expr_end;
755               else
756                 goto error;
757
758               if (strncmp (s, "@ha", 3) == 0)
759                 {
760                   the_insn.fup |= OP_SEL_HA;
761                   s += 3;
762                 }
763               else if (strncmp (s, "@h", 2) == 0)
764                 {
765                   the_insn.fup |= OP_SEL_H;
766                   s += 2;
767                 }
768               else if (strncmp (s, "@l", 2) == 0)
769                 {
770                   the_insn.fup |= OP_SEL_L;
771                   s += 2;
772                 }
773               else if (strncmp (s, "@gotoff", 7) == 0
774                        || strncmp (s, "@GOTOFF", 7) == 0)
775                 {
776                   as_bad (_("Assembler does not yet support PIC"));
777                   the_insn.fup |= OP_SEL_GOTOFF;
778                   s += 7;
779                 }
780               else if (strncmp (s, "@got", 4) == 0
781                        || strncmp (s, "@GOT", 4) == 0)
782                 {
783                   as_bad (_("Assembler does not yet support PIC"));
784                   the_insn.fup |= OP_SEL_GOT;
785                   s += 4;
786                 }
787               else if (strncmp (s, "@plt", 4) == 0
788                        || strncmp (s, "@PLT", 4) == 0)
789                 {
790                   as_bad (_("Assembler does not yet support PIC"));
791                   the_insn.fup |= OP_SEL_PLT;
792                   s += 4;
793                 }
794
795               the_insn.expand = insn->expand;
796
797               continue;
798 #else /* ! SYNTAX_SVR4 */
799               if (*s == ' ')
800                 s++;
801               if (strncmp (s, "ha%", 3) == 0)
802                 {
803                   the_insn.fup |= OP_SEL_HA;
804                   s += 3;
805                 }
806               else if (strncmp (s, "h%", 2) == 0)
807                 {
808                   the_insn.fup |= OP_SEL_H;
809                   s += 2;
810                 }
811               else if (strncmp (s, "l%", 2) == 0)
812                 {
813                   the_insn.fup |= OP_SEL_L;
814                   s += 2;
815                 }
816               the_insn.expand = insn->expand;
817
818               /* Note that if i860_get_expression() fails, we will still
819                  have created U entries in the symbol table for the
820                  'symbols' in the input string.  Try not to create U
821                  symbols for registers, etc.  */
822               if (! i860_get_expression (s))
823                 s = expr_end;
824               else
825                 goto error;
826
827               continue;
828 #endif /* SYNTAX_SVR4 */
829               break;
830
831             default:
832               as_fatal (_("failed sanity check."));
833             }
834           break;
835         }
836     error:
837       if (match == 0)
838         {
839           /* Args don't match.  */
840           if (insn[1].name != NULL
841               && ! strcmp (insn->name, insn[1].name))
842             {
843               ++insn;
844               s = args_start;
845               continue;
846             }
847           else
848             {
849               as_bad (_("Illegal operands for %s"), insn->name);
850               return;
851             }
852         }
853       break;
854     }
855
856   the_insn.opcode = opcode;
857 }
858
859 static int
860 i860_get_expression (str)
861      char *str;
862 {
863   char *save_in;
864   segT seg;
865
866   save_in = input_line_pointer;
867   input_line_pointer = str;
868   seg = expression (&the_insn.exp);
869   if (seg != absolute_section
870       && seg != undefined_section
871       && ! SEG_NORMAL (seg))
872     {
873       the_insn.error = _("bad segment");
874       expr_end = input_line_pointer;
875       input_line_pointer = save_in;
876       return 1;
877     }
878   expr_end = input_line_pointer;
879   input_line_pointer = save_in;
880   return 0;
881 }
882
883 /* Turn a string in input_line_pointer into a floating point constant of
884    type TYPE, and store the appropriate bytes in *LITP.  The number of
885    LITTLENUMS emitted is stored in *SIZEP.  An error message is returned,
886    or NULL on OK.  */
887
888 /* Equal to MAX_PRECISION in atof-ieee.c.  */
889 #define MAX_LITTLENUMS 6
890
891 char *
892 md_atof (type, litP, sizeP)
893      char type;
894      char *litP;
895      int *sizeP;
896 {
897   int prec;
898   LITTLENUM_TYPE words[MAX_LITTLENUMS];
899   LITTLENUM_TYPE *wordP;
900   char *t;
901
902   switch (type)
903     {
904     case 'f':
905     case 'F':
906     case 's':
907     case 'S':
908       prec = 2;
909       break;
910
911     case 'd':
912     case 'D':
913     case 'r':
914     case 'R':
915       prec = 4;
916       break;
917
918     case 'x':
919     case 'X':
920       prec = 6;
921       break;
922
923     case 'p':
924     case 'P':
925       prec = 6;
926       break;
927
928     default:
929       *sizeP = 0;
930       return _("Bad call to MD_ATOF()");
931     }
932   t = atof_ieee (input_line_pointer, type, words);
933   if (t)
934     input_line_pointer = t;
935   *sizeP = prec * sizeof (LITTLENUM_TYPE);
936   for (wordP = words; prec--;)
937     {
938       md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
939       litP += sizeof (LITTLENUM_TYPE);
940     }
941   return 0;
942 }
943
944 /* Write out in current endian mode.  */
945 void
946 md_number_to_chars (buf, val, n)
947      char *buf;
948      valueT val;
949      int n;
950 {
951   if (target_big_endian)
952     number_to_chars_bigendian (buf, val, n);
953   else
954     number_to_chars_littleendian (buf, val, n);
955 }
956
957 /* This should never be called for i860.  */
958 int
959 md_estimate_size_before_relax (fragP, segtype)
960      register fragS *fragP ATTRIBUTE_UNUSED;
961      segT segtype ATTRIBUTE_UNUSED;
962 {
963   as_fatal (_("i860_estimate_size_before_relax\n"));
964 }
965
966 #ifdef DEBUG_I860
967 static void
968 print_insn (insn)
969      struct i860_it *insn;
970 {
971   if (insn->error)
972     fprintf (stderr, "ERROR: %s\n", insn->error);
973
974   fprintf (stderr, "opcode = 0x%08lx\t", insn->opcode);
975   fprintf (stderr, "expand = 0x%x\t", insn->expand);
976   fprintf (stderr, "reloc = %s\t\n",
977            bfd_get_reloc_code_name (insn->reloc));
978   fprintf (stderr, "exp =  {\n");
979   fprintf (stderr, "\t\tX_add_symbol = %s\n",
980            insn->exp.X_add_symbol ?
981            (S_GET_NAME (insn->exp.X_add_symbol) ?
982             S_GET_NAME (insn->exp.X_add_symbol) : "???") : "0");
983   fprintf (stderr, "\t\tX_op_symbol = %s\n",
984            insn->exp.X_op_symbol ?
985            (S_GET_NAME (insn->exp.X_op_symbol) ?
986             S_GET_NAME (insn->exp.X_op_symbol) : "???") : "0");
987   fprintf (stderr, "\t\tX_add_number = %lx\n",
988            insn->exp.X_add_number);
989   fprintf (stderr, "}\n");
990 }
991 #endif /* DEBUG_I860 */
992
993 \f
994 #ifdef OBJ_ELF
995 const char *md_shortopts = "VQ:";
996 #else
997 const char *md_shortopts = "";
998 #endif
999
1000 #define OPTION_EB               (OPTION_MD_BASE + 0)
1001 #define OPTION_EL               (OPTION_MD_BASE + 1)
1002 #define OPTION_WARN_EXPAND      (OPTION_MD_BASE + 2)
1003
1004 struct option md_longopts[] = {
1005   { "EB",           no_argument, NULL, OPTION_EB },
1006   { "EL",           no_argument, NULL, OPTION_EL },
1007   { "mwarn-expand", no_argument, NULL, OPTION_WARN_EXPAND },
1008   { NULL,           no_argument, NULL, 0 }
1009 };
1010 size_t md_longopts_size = sizeof (md_longopts);
1011
1012 int
1013 md_parse_option (c, arg)
1014      int c;
1015      char *arg ATTRIBUTE_UNUSED;
1016 {
1017   switch (c)
1018     {
1019     case OPTION_EB:
1020       target_big_endian = 1;
1021       break;
1022
1023     case OPTION_EL:
1024       target_big_endian = 0;
1025       break;
1026
1027     case OPTION_WARN_EXPAND:
1028       target_warn_expand = 1;
1029       break;
1030
1031 #ifdef OBJ_ELF
1032     /* SVR4 argument compatibility (-V): print version ID.  */
1033     case 'V':
1034       print_version_id ();
1035       break;
1036
1037     /* SVR4 argument compatibility (-Qy, -Qn): controls whether
1038        a .comment section should be emitted or not (ignored).  */
1039     case 'Q':
1040       break;
1041 #endif
1042
1043     default:
1044       return 0;
1045     }
1046
1047   return 1;
1048 }
1049
1050 void
1051 md_show_usage (stream)
1052      FILE *stream;
1053 {
1054   fprintf (stream, _("\
1055   -EL                     generate code for little endian mode (default)\n\
1056   -EB                     generate code for big endian mode\n\
1057   -mwarn-expand           warn if pseudo operations are expanded\n"));
1058 #ifdef OBJ_ELF
1059   /* SVR4 compatibility flags.  */
1060   fprintf (stream, _("\
1061   -V                      print assembler version number\n\
1062   -Qy, -Qn                ignored\n"));
1063 #endif
1064 }
1065
1066 \f
1067 /* We have no need to default values of symbols.  */
1068 symbolS *
1069 md_undefined_symbol (name)
1070      char *name ATTRIBUTE_UNUSED;
1071 {
1072   return 0;
1073 }
1074
1075 /* The i860 denotes auto-increment with '++'.  */
1076 void
1077 md_operand (exp)
1078      expressionS *exp;
1079 {
1080   char *s;
1081
1082   for (s = input_line_pointer; *s; s++)
1083     {
1084       if (s[0] == '+' && s[1] == '+')
1085         {
1086           input_line_pointer += 2;
1087           exp->X_op = O_register;
1088           break;
1089         }
1090     }
1091 }
1092
1093 /* Round up a section size to the appropriate boundary.  */
1094 valueT
1095 md_section_align (segment, size)
1096      segT segment ATTRIBUTE_UNUSED;
1097      valueT size ATTRIBUTE_UNUSED;
1098 {
1099   /* Byte alignment is fine.  */
1100   return size;
1101 }
1102
1103 /* On the i860, a PC-relative offset is relative to the address of the
1104    of the offset plus its size.  */
1105 long
1106 md_pcrel_from (fixP)
1107      fixS *fixP;
1108 {
1109   return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
1110 }
1111
1112 /* Determine the relocation needed for non PC-relative 16-bit immediates.
1113    Also adjust the given immediate as necessary.  Finally, check that
1114    all constraints (such as alignment) are satisfied.   */
1115 static bfd_reloc_code_real_type
1116 obtain_reloc_for_imm16 (fix, val)
1117      fixS *fix;
1118      long *val;
1119 {
1120   valueT fup = fix->fx_addnumber;
1121   bfd_reloc_code_real_type reloc;
1122
1123   if (fix->fx_pcrel)
1124     abort ();
1125
1126   /* Check alignment restrictions.  */
1127   if ((fup & OP_ALIGN2) && (*val & 0x1))
1128     as_bad_where (fix->fx_file, fix->fx_line,
1129                   _("This immediate requires 0 MOD 2 alignment"));
1130   else if ((fup & OP_ALIGN4) && (*val & 0x3))
1131     as_bad_where (fix->fx_file, fix->fx_line,
1132                   _("This immediate requires 0 MOD 4 alignment"));
1133   else if ((fup & OP_ALIGN8) && (*val & 0x7))
1134     as_bad_where (fix->fx_file, fix->fx_line,
1135                   _("This immediate requires 0 MOD 8 alignment"));
1136   else if ((fup & OP_ALIGN16) && (*val & 0xf))
1137     as_bad_where (fix->fx_file, fix->fx_line,
1138                   _("This immediate requires 0 MOD 16 alignment"));
1139
1140   if (fup & OP_SEL_HA)
1141     {
1142       *val = (*val >> 16) + (*val & 0x8000 ? 1 : 0);
1143       reloc = BFD_RELOC_860_HIGHADJ;
1144     }
1145   else if (fup & OP_SEL_H)
1146     {
1147       *val >>= 16;
1148       reloc = BFD_RELOC_860_HIGH;
1149     }
1150   else if (fup & OP_SEL_L)
1151     {
1152       int num_encode;
1153       if (fup & OP_IMM_SPLIT16)
1154         {
1155           if (fup & OP_ENCODE1)
1156             {
1157               num_encode = 1;
1158               reloc = BFD_RELOC_860_SPLIT1;
1159             }
1160           else if (fup & OP_ENCODE2)
1161             {
1162               num_encode = 2;
1163               reloc = BFD_RELOC_860_SPLIT2;
1164             }
1165           else
1166             {
1167               num_encode = 0;
1168               reloc = BFD_RELOC_860_SPLIT0;
1169             }
1170         }
1171       else
1172         {
1173           if (fup & OP_ENCODE1)
1174             {
1175               num_encode = 1;
1176               reloc = BFD_RELOC_860_LOW1;
1177             }
1178           else if (fup & OP_ENCODE2)
1179             {
1180               num_encode = 2;
1181               reloc = BFD_RELOC_860_LOW2;
1182             }
1183           else if (fup & OP_ENCODE3)
1184             {
1185               num_encode = 3;
1186               reloc = BFD_RELOC_860_LOW3;
1187             }
1188           else
1189             {
1190               num_encode = 0;
1191               reloc = BFD_RELOC_860_LOW0;
1192             }
1193         }
1194
1195       /* Preserve size encode bits.  */
1196       *val &= ~((1 << num_encode) - 1);
1197     }
1198   else
1199     {
1200       /* No selector.  What reloc do we generate (???)?  */
1201       reloc = BFD_RELOC_32;
1202     }
1203
1204   return reloc;
1205 }
1206
1207 /* Attempt to simplify or eliminate a fixup. To indicate that a fixup
1208    has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL,
1209    we will have to generate a reloc entry.  */
1210
1211 void
1212 md_apply_fix3 (fix, valP, seg)
1213      fixS * fix;
1214      valueT * valP;
1215      segT seg ATTRIBUTE_UNUSED;
1216 {
1217   char *buf;
1218   long val = *valP;
1219   unsigned long insn;
1220   valueT fup;
1221
1222   buf = fix->fx_frag->fr_literal + fix->fx_where;
1223
1224   /* Recall that earlier we stored the opcode little-endian.  */
1225   insn = bfd_getl32 (buf);
1226
1227   /* We stored a fix-up in this oddly-named scratch field.  */
1228   fup = fix->fx_addnumber;
1229
1230   /* Determine the necessary relocations as well as inserting an
1231      immediate into the instruction.   */
1232   if (fup == OP_IMM_U5)
1233     {
1234       if (val & ~0x1f)
1235         as_bad_where (fix->fx_file, fix->fx_line,
1236                       _("5-bit immediate too large"));
1237       if (fix->fx_addsy)
1238         as_bad_where (fix->fx_file, fix->fx_line,
1239                       _("5-bit field must be absolute"));
1240
1241       insn |= (val & 0x1f) << 11;
1242       bfd_putl32 (insn, buf);
1243       fix->fx_r_type = BFD_RELOC_NONE;
1244       fix->fx_done = 1;
1245     }
1246   else if (fup & OP_IMM_S16)
1247     {
1248       fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val);
1249
1250       /* Insert the immediate.  */
1251       if (fix->fx_addsy)
1252         fix->fx_done = 0;
1253       else
1254         {
1255           insn |= val & 0xffff;
1256           bfd_putl32 (insn, buf);
1257           fix->fx_r_type = BFD_RELOC_NONE;
1258           fix->fx_done = 1;
1259         }
1260     }
1261   else if (fup & OP_IMM_U16)
1262     abort ();
1263
1264   else if (fup & OP_IMM_SPLIT16)
1265     {
1266       fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val);
1267
1268       /* Insert the immediate.  */
1269       if (fix->fx_addsy)
1270         fix->fx_done = 0;
1271       else
1272         {
1273           insn |= val & 0x7ff;
1274           insn |= (val & 0xf800) << 5;
1275           bfd_putl32 (insn, buf);
1276           fix->fx_r_type = BFD_RELOC_NONE;
1277           fix->fx_done = 1;
1278         }
1279     }
1280   else if (fup & OP_IMM_BR16)
1281     {
1282       if (val & 0x3)
1283         as_bad_where (fix->fx_file, fix->fx_line,
1284                       _("A branch offset requires 0 MOD 4 alignment"));
1285
1286       val = val >> 2;
1287
1288       /* Insert the immediate.  */
1289       if (fix->fx_addsy)
1290         {
1291           fix->fx_done = 0;
1292           fix->fx_r_type = BFD_RELOC_860_PC16;
1293         }
1294       else
1295         {
1296           insn |= (val & 0x7ff);
1297           insn |= ((val & 0xf800) << 5);
1298           bfd_putl32 (insn, buf);
1299           fix->fx_r_type = BFD_RELOC_NONE;
1300           fix->fx_done = 1;
1301         }
1302     }
1303   else if (fup & OP_IMM_BR26)
1304     {
1305       if (val & 0x3)
1306         as_bad_where (fix->fx_file, fix->fx_line,
1307                       _("A branch offset requires 0 MOD 4 alignment"));
1308
1309       val >>= 2;
1310
1311       /* Insert the immediate.  */
1312       if (fix->fx_addsy)
1313         {
1314           fix->fx_r_type = BFD_RELOC_860_PC26;
1315           fix->fx_done = 0;
1316         }
1317       else
1318         {
1319           insn |= (val & 0x3ffffff);
1320           bfd_putl32 (insn, buf);
1321           fix->fx_r_type = BFD_RELOC_NONE;
1322           fix->fx_done = 1;
1323         }
1324     }
1325   else if (fup != OP_NONE)
1326     {
1327       as_bad_where (fix->fx_file, fix->fx_line,
1328                     _("Unrecognized fix-up (0x%08lx)"), (unsigned long) fup);
1329       abort ();
1330     }
1331   else
1332     {
1333       /* I believe only fix-ups such as ".long .ep.main-main+0xc8000000"
1334          reach here (???).  */
1335       if (fix->fx_addsy)
1336         {
1337           fix->fx_r_type = BFD_RELOC_32;
1338           fix->fx_done = 0;
1339         }
1340       else
1341         {
1342           insn |= (val & 0xffffffff);
1343           bfd_putl32 (insn, buf);
1344           fix->fx_r_type = BFD_RELOC_NONE;
1345           fix->fx_done = 1;
1346         }
1347     }
1348 }
1349
1350 /* Generate a machine dependent reloc from a fixup.  */
1351 arelent*
1352 tc_gen_reloc (section, fixp)
1353      asection *section ATTRIBUTE_UNUSED;
1354      fixS *fixp;
1355 {
1356   arelent *reloc;
1357
1358   reloc = xmalloc (sizeof (*reloc));
1359   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1360   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1361   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1362   reloc->addend = fixp->fx_offset;
1363   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1364
1365   if (! reloc->howto)
1366     {
1367       as_bad_where (fixp->fx_file, fixp->fx_line,
1368                     "Cannot represent %s relocation in object file",
1369                     bfd_get_reloc_code_name (fixp->fx_r_type));
1370     }
1371   return reloc;
1372 }
This page took 0.099676 seconds and 4 git commands to generate.