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