Back to index

cell-binutils  2.17cvs20070401
tc-i860.c
Go to the documentation of this file.
00001 /* tc-i860.c -- Assembler for the Intel i860 architecture.
00002    Copyright 1989, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002,
00003    2003, 2006 Free Software Foundation, Inc.
00004 
00005    Brought back from the dead and completely reworked
00006    by Jason Eckhardt <jle@cygnus.com>.
00007 
00008    This file is part of GAS, the GNU Assembler.
00009 
00010    GAS is free software; you can redistribute it and/or modify
00011    it under the terms of the GNU General Public License as published by
00012    the Free Software Foundation; either version 2, or (at your option)
00013    any later version.
00014 
00015    GAS is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019 
00020    You should have received a copy of the GNU General Public License along
00021    with GAS; see the file COPYING.  If not, write to the Free Software
00022    Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00023 
00024 #include "as.h"
00025 #include "safe-ctype.h"
00026 #include "subsegs.h"
00027 #include "opcode/i860.h"
00028 #include "elf/i860.h"
00029 
00030 
00031 /* The opcode hash table.  */
00032 static struct hash_control *op_hash = NULL;
00033 
00034 /* These characters always start a comment.  */
00035 const char comment_chars[] = "#!/";
00036 
00037 /* These characters start a comment at the beginning of a line.  */
00038 const char line_comment_chars[] = "#/";
00039 
00040 const char line_separator_chars[] = ";";
00041 
00042 /* Characters that can be used to separate the mantissa from the exponent
00043    in floating point numbers.  */
00044 const char EXP_CHARS[] = "eE";
00045 
00046 /* Characters that indicate this number is a floating point constant.
00047    As in 0f12.456 or 0d1.2345e12.  */
00048 const char FLT_CHARS[] = "rRsSfFdDxXpP";
00049 
00050 /* Register prefix (depends on syntax).  */
00051 static char reg_prefix;
00052 
00053 #define MAX_FIXUPS 2
00054 
00055 struct i860_it
00056 {
00057   char *error;
00058   unsigned long opcode;
00059   enum expand_type expand;
00060   struct i860_fi
00061   {
00062     expressionS exp;
00063     bfd_reloc_code_real_type reloc;
00064     int pcrel;
00065     valueT fup;
00066   } fi[MAX_FIXUPS];
00067 } the_insn;
00068 
00069 /* The current fixup count.  */
00070 static int fc;
00071 
00072 static char *expr_end;
00073 
00074 /* Indicates error if a pseudo operation was expanded after a branch.  */
00075 static char last_expand;
00076 
00077 /* If true, then warn if any pseudo operations were expanded.  */
00078 static int target_warn_expand = 0;
00079 
00080 /* If true, then XP support is enabled.  */
00081 static int target_xp = 0;
00082 
00083 /* If true, then Intel syntax is enabled (default to AT&T/SVR4 syntax).  */
00084 static int target_intel_syntax = 0;
00085 
00086 
00087 /* Prototypes.  */
00088 static void i860_process_insn (char *);
00089 static void s_dual (int);
00090 static void s_enddual (int);
00091 static void s_atmp (int);
00092 static void s_align_wrapper (int);
00093 static int i860_get_expression (char *);
00094 static bfd_reloc_code_real_type obtain_reloc_for_imm16 (fixS *, long *); 
00095 #ifdef DEBUG_I860
00096 static void print_insn (struct i860_it *);
00097 #endif
00098 
00099 const pseudo_typeS md_pseudo_table[] =
00100 {
00101   {"align",   s_align_wrapper, 0},
00102   {"dual",    s_dual,          0},
00103   {"enddual", s_enddual,       0},
00104   {"atmp",    s_atmp,          0},
00105   {NULL,      0,               0},
00106 };
00107 
00108 /* Dual-instruction mode handling.  */
00109 enum dual
00110 {
00111   DUAL_OFF = 0, DUAL_ON, DUAL_DDOT, DUAL_ONDDOT,
00112 };
00113 static enum dual dual_mode = DUAL_OFF;
00114 
00115 /* Handle ".dual" directive.  */
00116 static void
00117 s_dual (int ignore ATTRIBUTE_UNUSED)
00118 {
00119   if (target_intel_syntax)
00120     dual_mode = DUAL_ON;
00121   else
00122     as_bad (_("Directive .dual available only with -mintel-syntax option"));
00123 }
00124 
00125 /* Handle ".enddual" directive.  */
00126 static void
00127 s_enddual (int ignore ATTRIBUTE_UNUSED)
00128 {
00129   if (target_intel_syntax)
00130     dual_mode = DUAL_OFF;
00131   else
00132     as_bad (_("Directive .enddual available only with -mintel-syntax option"));
00133 }
00134 
00135 /* Temporary register used when expanding assembler pseudo operations.  */
00136 static int atmp = 31;
00137 
00138 static void
00139 s_atmp (int ignore ATTRIBUTE_UNUSED)
00140 {
00141   int temp;
00142 
00143   if (! target_intel_syntax)
00144     {
00145       as_bad (_("Directive .atmp available only with -mintel-syntax option"));
00146       demand_empty_rest_of_line ();
00147       return;
00148     }
00149 
00150   if (strncmp (input_line_pointer, "sp", 2) == 0)
00151     {
00152       input_line_pointer += 2;
00153       atmp = 2;
00154     }
00155   else if (strncmp (input_line_pointer, "fp", 2) == 0)
00156     {
00157       input_line_pointer += 2;
00158       atmp = 3;
00159     }
00160   else if (strncmp (input_line_pointer, "r", 1) == 0)
00161     {
00162       input_line_pointer += 1;
00163       temp = get_absolute_expression ();
00164       if (temp >= 0 && temp <= 31)
00165        atmp = temp;
00166       else
00167        as_bad (_("Unknown temporary pseudo register"));
00168     }
00169   else
00170     {
00171       as_bad (_("Unknown temporary pseudo register"));
00172     }
00173   demand_empty_rest_of_line ();
00174 }
00175 
00176 /* Handle ".align" directive depending on syntax mode.
00177    AT&T/SVR4 syntax uses the standard align directive.  However, 
00178    the Intel syntax additionally allows keywords for the alignment
00179    parameter: ".align type", where type is one of {.short, .long,
00180    .quad, .single, .double} representing alignments of 2, 4,
00181    16, 4, and 8, respectively.  */
00182 static void
00183 s_align_wrapper (int arg)
00184 {
00185   char *parm = input_line_pointer;
00186 
00187   if (target_intel_syntax)
00188     {
00189       /* Replace a keyword with the equivalent integer so the
00190          standard align routine can parse the directive.  */
00191       if (strncmp (parm, ".short", 6) == 0)
00192         strncpy (parm, "     2", 6);
00193       else if (strncmp (parm, ".long", 5) == 0)
00194         strncpy (parm, "    4", 5);
00195       else if (strncmp (parm, ".quad", 5) == 0)
00196         strncpy (parm, "   16", 5);
00197       else if (strncmp (parm, ".single", 7) == 0)
00198         strncpy (parm, "      4", 7);
00199       else if (strncmp (parm, ".double", 7) == 0)
00200         strncpy (parm, "      8", 7);
00201      
00202       while (*input_line_pointer == ' ')
00203         ++input_line_pointer;
00204     }
00205 
00206   s_align_bytes (arg);
00207 }
00208 
00209 /* This function is called once, at assembler startup time.  It should
00210    set up all the tables and data structures that the MD part of the
00211    assembler will need.  */
00212 void
00213 md_begin (void)
00214 {
00215   const char *retval = NULL;
00216   int lose = 0;
00217   unsigned int i = 0;
00218 
00219   op_hash = hash_new ();
00220 
00221   while (i860_opcodes[i].name != NULL)
00222     {
00223       const char *name = i860_opcodes[i].name;
00224       retval = hash_insert (op_hash, name, (PTR)&i860_opcodes[i]);
00225       if (retval != NULL)
00226        {
00227          fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
00228                  i860_opcodes[i].name, retval);
00229          lose = 1;
00230        }
00231       do
00232        {
00233          if (i860_opcodes[i].match & i860_opcodes[i].lose)
00234            {
00235              fprintf (stderr,
00236                      _("internal error: losing opcode: `%s' \"%s\"\n"),
00237                      i860_opcodes[i].name, i860_opcodes[i].args);
00238              lose = 1;
00239            }
00240          ++i;
00241        }
00242       while (i860_opcodes[i].name != NULL
00243             && strcmp (i860_opcodes[i].name, name) == 0);
00244     }
00245 
00246   if (lose)
00247     as_fatal (_("Defective assembler.  No assembly attempted."));
00248 
00249   /* Set the register prefix for either Intel or AT&T/SVR4 syntax.  */
00250   reg_prefix = target_intel_syntax ? 0 : '%';
00251 }
00252 
00253 /* This is the core of the machine-dependent assembler.  STR points to a
00254    machine dependent instruction.  This function emits the frags/bytes
00255    it assembles to.  */
00256 void
00257 md_assemble (char *str)
00258 {
00259   char *destp;
00260   int num_opcodes = 1;
00261   int i;
00262   struct i860_it pseudo[3];
00263 
00264   assert (str);
00265   fc = 0;
00266 
00267   /* Assemble the instruction.  */
00268   i860_process_insn (str);
00269 
00270   /* Check for expandable flag to produce pseudo-instructions.  This
00271      is an undesirable feature that should be avoided.  */
00272   if (the_insn.expand != 0 && the_insn.expand != XP_ONLY
00273       && ! (the_insn.fi[0].fup & (OP_SEL_HA | OP_SEL_H | OP_SEL_L | OP_SEL_GOT
00274                          | OP_SEL_GOTOFF | OP_SEL_PLT)))
00275     {
00276       for (i = 0; i < 3; i++)
00277        pseudo[i] = the_insn;
00278 
00279       fc = 1;
00280       switch (the_insn.expand)
00281        {
00282 
00283        case E_DELAY:
00284          num_opcodes = 1;
00285          break;
00286 
00287        case E_MOV:
00288          if (the_insn.fi[0].exp.X_add_symbol == NULL
00289              && the_insn.fi[0].exp.X_op_symbol == NULL
00290              && (the_insn.fi[0].exp.X_add_number < (1 << 15)
00291                 && the_insn.fi[0].exp.X_add_number >= -(1 << 15)))
00292            break;
00293 
00294          /* Emit "or l%const,r0,ireg_dest".  */
00295          pseudo[0].opcode = (the_insn.opcode & 0x001f0000) | 0xe4000000;
00296          pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
00297 
00298          /* Emit "orh h%const,ireg_dest,ireg_dest".  */
00299          pseudo[1].opcode = (the_insn.opcode & 0x03ffffff) | 0xec000000
00300                            | ((the_insn.opcode & 0x001f0000) << 5);
00301          pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
00302 
00303          num_opcodes = 2;
00304          break;
00305 
00306        case E_ADDR:
00307          if (the_insn.fi[0].exp.X_add_symbol == NULL
00308              && the_insn.fi[0].exp.X_op_symbol == NULL
00309              && (the_insn.fi[0].exp.X_add_number < (1 << 15)
00310                 && the_insn.fi[0].exp.X_add_number >= -(1 << 15)))
00311            break;
00312 
00313          /* Emit "orh ha%addr_expr,ireg_src2,r31".  */
00314          pseudo[0].opcode = 0xec000000 | (the_insn.opcode & 0x03e00000)
00315                           | (atmp << 16);
00316          pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_HA);
00317 
00318          /* Emit "l%addr_expr(r31),ireg_dest".  We pick up the fixup
00319             information from the original instruction.   */
00320          pseudo[1].opcode = (the_insn.opcode & ~0x03e00000) | (atmp << 21);
00321          pseudo[1].fi[0].fup = the_insn.fi[0].fup | OP_SEL_L;
00322 
00323          num_opcodes = 2;
00324          break;
00325 
00326        case E_U32:
00327          if (the_insn.fi[0].exp.X_add_symbol == NULL
00328              && the_insn.fi[0].exp.X_op_symbol == NULL
00329              && (the_insn.fi[0].exp.X_add_number < (1 << 16)
00330                 && the_insn.fi[0].exp.X_add_number >= 0))
00331            break;
00332 
00333          /* Emit "$(opcode)h h%const,ireg_src2,r31".  */
00334          pseudo[0].opcode = (the_insn.opcode & 0xf3e0ffff) | 0x0c000000
00335                            | (atmp << 16);
00336          pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
00337 
00338          /* Emit "$(opcode) l%const,r31,ireg_dest".  */
00339          pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000
00340                            | (atmp << 21);
00341          pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
00342 
00343          num_opcodes = 2;
00344          break;
00345 
00346        case E_AND:
00347          if (the_insn.fi[0].exp.X_add_symbol == NULL
00348              && the_insn.fi[0].exp.X_op_symbol == NULL
00349              && (the_insn.fi[0].exp.X_add_number < (1 << 16)
00350                 && the_insn.fi[0].exp.X_add_number >= 0))
00351            break;
00352 
00353          /* Emit "andnot h%const,ireg_src2,r31".  */
00354          pseudo[0].opcode = (the_insn.opcode & 0x03e0ffff) | 0xd4000000
00355                            | (atmp << 16);
00356          pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
00357          pseudo[0].fi[0].exp.X_add_number =
00358             -1 - the_insn.fi[0].exp.X_add_number;
00359 
00360          /* Emit "andnot l%const,r31,ireg_dest".  */
00361          pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000
00362                            | (atmp << 21);
00363          pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
00364          pseudo[1].fi[0].exp.X_add_number =
00365             -1 - the_insn.fi[0].exp.X_add_number;
00366 
00367          num_opcodes = 2;
00368          break;
00369 
00370        case E_S32:
00371          if (the_insn.fi[0].exp.X_add_symbol == NULL
00372              && the_insn.fi[0].exp.X_op_symbol == NULL
00373              && (the_insn.fi[0].exp.X_add_number < (1 << 15)
00374                 && the_insn.fi[0].exp.X_add_number >= -(1 << 15)))
00375            break;
00376 
00377          /* Emit "orh h%const,r0,r31".  */
00378          pseudo[0].opcode = 0xec000000 | (atmp << 16);
00379          pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
00380 
00381          /* Emit "or l%const,r31,r31".  */
00382          pseudo[1].opcode = 0xe4000000 | (atmp << 21) | (atmp << 16);
00383          pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
00384 
00385          /* Emit "r31,ireg_src2,ireg_dest".  */
00386          pseudo[2].opcode = (the_insn.opcode & ~0x0400ffff) | (atmp << 11);
00387          pseudo[2].fi[0].fup = OP_IMM_S16;
00388 
00389          num_opcodes = 3;
00390          break;
00391 
00392        default:
00393          as_fatal (_("failed sanity check."));
00394        }
00395 
00396       the_insn = pseudo[0];
00397 
00398       /* Warn if an opcode is expanded after a delayed branch.  */
00399       if (num_opcodes > 1 && last_expand == 1)
00400        as_warn (_("Expanded opcode after delayed branch: `%s'"), str);
00401 
00402       /* Warn if an opcode is expanded in dual mode.  */
00403       if (num_opcodes > 1 && dual_mode != DUAL_OFF)
00404        as_warn (_("Expanded opcode in dual mode: `%s'"), str);
00405 
00406       /* Notify if any expansions happen.  */
00407       if (target_warn_expand && num_opcodes > 1)
00408        as_warn (_("An instruction was expanded (%s)"), str);
00409     }
00410 
00411   i = 0;
00412   do
00413     {
00414       int tmp;
00415 
00416       /* Output the opcode.  Note that the i860 always reads instructions
00417         as little-endian data.  */
00418       destp = frag_more (4);
00419       number_to_chars_littleendian (destp, the_insn.opcode, 4);
00420 
00421       /* Check for expanded opcode after branch or in dual mode.  */
00422       last_expand = the_insn.fi[0].pcrel;
00423 
00424       /* Output the symbol-dependent stuff.  Only btne and bte will ever
00425          loop more than once here, since only they (possibly) have more
00426          than one fixup.  */
00427       for (tmp = 0; tmp < fc; tmp++)
00428         {
00429           if (the_insn.fi[tmp].fup != OP_NONE)
00430            {
00431              fixS *fix;
00432              fix = fix_new_exp (frag_now,
00433                               destp - frag_now->fr_literal,
00434                               4,
00435                               &the_insn.fi[tmp].exp,
00436                               the_insn.fi[tmp].pcrel,
00437                               the_insn.fi[tmp].reloc);
00438 
00439             /* Despite the odd name, this is a scratch field.  We use
00440                it to encode operand type information.  */
00441             fix->fx_addnumber = the_insn.fi[tmp].fup;
00442           }
00443         }
00444       the_insn = pseudo[++i];
00445     }
00446   while (--num_opcodes > 0);
00447 
00448 }
00449 
00450 /* Assemble the instruction pointed to by STR.  */
00451 static void
00452 i860_process_insn (char *str)
00453 {
00454   char *s;
00455   const char *args;
00456   char c;
00457   struct i860_opcode *insn;
00458   char *args_start;
00459   unsigned long opcode;
00460   unsigned int mask;
00461   int match = 0;
00462   int comma = 0;
00463 
00464 #if 1 /* For compiler warnings.  */
00465   args = 0;
00466   insn = 0;
00467   args_start = 0;
00468   opcode = 0;
00469 #endif
00470 
00471   for (s = str; ISLOWER (*s) || *s == '.' || *s == '3'
00472        || *s == '2' || *s == '1'; ++s)
00473     ;
00474 
00475   switch (*s)
00476     {
00477     case '\0':
00478       break;
00479 
00480     case ',':
00481       comma = 1;
00482 
00483       /*FALLTHROUGH*/
00484 
00485     case ' ':
00486       *s++ = '\0';
00487       break;
00488 
00489     default:
00490       as_fatal (_("Unknown opcode: `%s'"), str);
00491     }
00492 
00493   /* Check for dual mode ("d.") opcode prefix.  */
00494   if (strncmp (str, "d.", 2) == 0)
00495     {
00496       if (dual_mode == DUAL_ON)
00497        dual_mode = DUAL_ONDDOT;
00498       else
00499        dual_mode = DUAL_DDOT;
00500       str += 2;
00501     }
00502 
00503   if ((insn = (struct i860_opcode *) hash_find (op_hash, str)) == NULL)
00504     {
00505       if (dual_mode == DUAL_DDOT || dual_mode == DUAL_ONDDOT)
00506        str -= 2;
00507       as_bad (_("Unknown opcode: `%s'"), str);
00508       return;
00509     }
00510 
00511   if (comma)
00512     *--s = ',';
00513 
00514   args_start = s;
00515   for (;;)
00516     {
00517       int t;
00518       opcode = insn->match;
00519       memset (&the_insn, '\0', sizeof (the_insn));
00520       fc = 0;
00521       for (t = 0; t < MAX_FIXUPS; t++)
00522         {
00523           the_insn.fi[t].reloc = BFD_RELOC_NONE;
00524           the_insn.fi[t].pcrel = 0;
00525           the_insn.fi[t].fup = OP_NONE;
00526         }
00527 
00528       /* Build the opcode, checking as we go that the operands match.  */
00529       for (args = insn->args; ; ++args)
00530        {
00531           if (fc > MAX_FIXUPS)
00532             abort ();
00533 
00534          switch (*args)
00535            {
00536 
00537            /* End of args.  */
00538            case '\0':
00539              if (*s == '\0')
00540               match = 1;
00541              break;
00542 
00543            /* These must match exactly.  */
00544            case '+':
00545            case '(':
00546            case ')':
00547            case ',':
00548            case ' ':
00549              if (*s++ == *args)
00550               continue;
00551              break;
00552 
00553            /* Must be at least one digit.  */
00554            case '#':
00555              if (ISDIGIT (*s++))
00556               {
00557                 while (ISDIGIT (*s))
00558                   ++s;
00559                 continue;
00560               }
00561              break;
00562 
00563            /* Next operand must be a register.  */
00564            case '1':
00565            case '2':
00566            case 'd':
00567              /* Check for register prefix if necessary.  */
00568              if (reg_prefix && *s != reg_prefix)
00569               goto error;
00570              else if (reg_prefix)
00571               s++;
00572 
00573              switch (*s)
00574               {
00575               /* Frame pointer.  */
00576               case 'f':
00577                 s++;
00578                 if (*s++ == 'p')
00579                   {
00580                     mask = 0x3;
00581                     break;
00582                   }
00583                 goto error;
00584 
00585               /* Stack pointer.  */
00586               case 's':
00587                 s++;
00588                 if (*s++ == 'p')
00589                   {
00590                     mask = 0x2;
00591                     break;
00592                   }
00593                 goto error;
00594 
00595               /* Any register r0..r31.  */
00596               case 'r':
00597                 s++;
00598                 if (!ISDIGIT (c = *s++))
00599                   {
00600                     goto error;
00601                   }
00602                 if (ISDIGIT (*s))
00603                   {
00604                     if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
00605                      goto error;
00606                   }
00607                 else
00608                   c -= '0';
00609                 mask = c;
00610                 break;
00611 
00612               /* Not this opcode.  */
00613               default:
00614                 goto error;
00615               }
00616 
00617              /* Obtained the register, now place it in the opcode.  */
00618              switch (*args)
00619               {
00620               case '1':
00621                 opcode |= mask << 11;
00622                 continue;
00623 
00624               case '2':
00625                 opcode |= mask << 21;
00626                 continue;
00627 
00628               case 'd':
00629                 opcode |= mask << 16;
00630                 continue;
00631 
00632               }
00633              break;
00634 
00635            /* Next operand is a floating point register.  */
00636            case 'e':
00637            case 'f':
00638            case 'g':
00639              /* Check for register prefix if necessary.  */
00640              if (reg_prefix && *s != reg_prefix)
00641               goto error;
00642              else if (reg_prefix)
00643               s++;
00644 
00645              if (*s++ == 'f' && ISDIGIT (*s))
00646               {
00647                 mask = *s++;
00648                 if (ISDIGIT (*s))
00649                   {
00650                     mask = 10 * (mask - '0') + (*s++ - '0');
00651                     if (mask >= 32)
00652                      {
00653                        break;
00654                      }
00655                   }
00656                 else
00657                   mask -= '0';
00658 
00659                 switch (*args)
00660                   {
00661 
00662                   case 'e':
00663                     opcode |= mask << 11;
00664                     continue;
00665 
00666                   case 'f':
00667                     opcode |= mask << 21;
00668                     continue;
00669 
00670                   case 'g':
00671                     opcode |= mask << 16;
00672                     if ((opcode & (1 << 10)) && mask != 0
00673                        && (mask == ((opcode >> 11) & 0x1f)))
00674                      as_warn (_("Pipelined instruction: fsrc1 = fdest"));
00675                     continue;
00676                   }
00677               }
00678              break;
00679 
00680            /* Next operand must be a control register.  */
00681            case 'c':
00682              /* Check for register prefix if necessary.  */
00683              if (reg_prefix && *s != reg_prefix)
00684               goto error;
00685              else if (reg_prefix)
00686               s++;
00687 
00688              if (strncmp (s, "fir", 3) == 0)
00689               {
00690                 opcode |= 0x0 << 21;
00691                 s += 3;
00692                 continue;
00693               }
00694              if (strncmp (s, "psr", 3) == 0)
00695               {
00696                 opcode |= 0x1 << 21;
00697                 s += 3;
00698                 continue;
00699               }
00700              if (strncmp (s, "dirbase", 7) == 0)
00701               {
00702                 opcode |= 0x2 << 21;
00703                 s += 7;
00704                 continue;
00705               }
00706              if (strncmp (s, "db", 2) == 0)
00707               {
00708                 opcode |= 0x3 << 21;
00709                 s += 2;
00710                 continue;
00711               }
00712              if (strncmp (s, "fsr", 3) == 0)
00713               {
00714                 opcode |= 0x4 << 21;
00715                 s += 3;
00716                 continue;
00717               }
00718              if (strncmp (s, "epsr", 4) == 0)
00719               {
00720                 opcode |= 0x5 << 21;
00721                 s += 4;
00722                 continue;
00723               }
00724              /* The remaining control registers are XP only.  */
00725              if (target_xp && strncmp (s, "bear", 4) == 0)
00726               {
00727                 opcode |= 0x6 << 21;
00728                 s += 4;
00729                 continue;
00730               }
00731              if (target_xp && strncmp (s, "ccr", 3) == 0)
00732               {
00733                 opcode |= 0x7 << 21;
00734                 s += 3;
00735                 continue;
00736               }
00737              if (target_xp && strncmp (s, "p0", 2) == 0)
00738               {
00739                 opcode |= 0x8 << 21;
00740                 s += 2;
00741                 continue;
00742               }
00743              if (target_xp && strncmp (s, "p1", 2) == 0)
00744               {
00745                 opcode |= 0x9 << 21;
00746                 s += 2;
00747                 continue;
00748               }
00749              if (target_xp && strncmp (s, "p2", 2) == 0)
00750               {
00751                 opcode |= 0xa << 21;
00752                 s += 2;
00753                 continue;
00754               }
00755              if (target_xp && strncmp (s, "p3", 2) == 0)
00756               {
00757                 opcode |= 0xb << 21;
00758                 s += 2;
00759                 continue;
00760               }
00761              break;
00762 
00763            /* 5-bit immediate in src1.  */
00764            case '5':
00765              if (! i860_get_expression (s))
00766               {
00767                 s = expr_end;
00768                 the_insn.fi[fc].fup |= OP_IMM_U5;
00769                 fc++;
00770                 continue;
00771               }
00772              break;
00773 
00774            /* 26-bit immediate, relative branch (lbroff).  */
00775            case 'l':
00776              the_insn.fi[fc].pcrel = 1;
00777              the_insn.fi[fc].fup |= OP_IMM_BR26;
00778              goto immediate;
00779 
00780            /* 16-bit split immediate, relative branch (sbroff).  */
00781            case 'r':
00782              the_insn.fi[fc].pcrel = 1;
00783              the_insn.fi[fc].fup |= OP_IMM_BR16;
00784              goto immediate;
00785 
00786            /* 16-bit split immediate.  */
00787            case 's':
00788              the_insn.fi[fc].fup |= OP_IMM_SPLIT16;
00789              goto immediate;
00790 
00791            /* 16-bit split immediate, byte aligned (st.b).  */
00792            case 'S':
00793              the_insn.fi[fc].fup |= OP_IMM_SPLIT16;
00794              goto immediate;
00795 
00796            /* 16-bit split immediate, half-word aligned (st.s).  */
00797            case 'T':
00798              the_insn.fi[fc].fup |= (OP_IMM_SPLIT16 | OP_ENCODE1 | OP_ALIGN2);
00799              goto immediate;
00800 
00801            /* 16-bit split immediate, word aligned (st.l).  */
00802            case 'U':
00803              the_insn.fi[fc].fup |= (OP_IMM_SPLIT16 | OP_ENCODE1 | OP_ALIGN4);
00804              goto immediate;
00805 
00806            /* 16-bit immediate.  */
00807            case 'i':
00808              the_insn.fi[fc].fup |= OP_IMM_S16;
00809              goto immediate;
00810 
00811            /* 16-bit immediate, byte aligned (ld.b).  */
00812            case 'I':
00813              the_insn.fi[fc].fup |= OP_IMM_S16;
00814              goto immediate;
00815 
00816            /* 16-bit immediate, half-word aligned (ld.s).  */
00817            case 'J':
00818              the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE1 | OP_ALIGN2);
00819              goto immediate;
00820 
00821            /* 16-bit immediate, word aligned (ld.l, {p}fld.l, fst.l).  */
00822            case 'K':
00823              if (insn->name[0] == 'l')
00824               the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE1 | OP_ALIGN4);
00825              else
00826               the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE2 | OP_ALIGN4);
00827              goto immediate;
00828 
00829            /* 16-bit immediate, double-word aligned ({p}fld.d, fst.d).  */
00830            case 'L':
00831              the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE3 | OP_ALIGN8);
00832              goto immediate;
00833 
00834            /* 16-bit immediate, quad-word aligned (fld.q, fst.q).  */
00835            case 'M':
00836              the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE3 | OP_ALIGN16);
00837 
00838              /*FALLTHROUGH*/
00839 
00840              /* Handle the immediate for either the Intel syntax or
00841                SVR4 syntax. The Intel syntax is "ha%immediate"
00842                whereas SVR4 syntax is "[immediate]@ha".  */
00843            immediate:
00844              if (target_intel_syntax == 0)
00845               {
00846                 /* AT&T/SVR4 syntax.  */
00847                  if (*s == ' ')
00848                   s++;
00849 
00850                  /* Note that if i860_get_expression() fails, we will still
00851                    have created U entries in the symbol table for the
00852                    'symbols' in the input string.  Try not to create U
00853                    symbols for registers, etc.  */
00854                  if (! i860_get_expression (s))
00855                   s = expr_end;
00856                  else
00857                   goto error;
00858 
00859                  if (strncmp (s, "@ha", 3) == 0)
00860                   {
00861                     the_insn.fi[fc].fup |= OP_SEL_HA;
00862                     s += 3;
00863                   }
00864                  else if (strncmp (s, "@h", 2) == 0)
00865                   {
00866                     the_insn.fi[fc].fup |= OP_SEL_H;
00867                     s += 2;
00868                   }
00869                  else if (strncmp (s, "@l", 2) == 0)
00870                   {
00871                     the_insn.fi[fc].fup |= OP_SEL_L;
00872                     s += 2;
00873                   }
00874                  else if (strncmp (s, "@gotoff", 7) == 0
00875                          || strncmp (s, "@GOTOFF", 7) == 0)
00876                   {
00877                     as_bad (_("Assembler does not yet support PIC"));
00878                     the_insn.fi[fc].fup |= OP_SEL_GOTOFF;
00879                     s += 7;
00880                   }
00881                  else if (strncmp (s, "@got", 4) == 0
00882                          || strncmp (s, "@GOT", 4) == 0)
00883                   {
00884                     as_bad (_("Assembler does not yet support PIC"));
00885                     the_insn.fi[fc].fup |= OP_SEL_GOT;
00886                     s += 4;
00887                   }
00888                  else if (strncmp (s, "@plt", 4) == 0
00889                          || strncmp (s, "@PLT", 4) == 0)
00890                   {
00891                     as_bad (_("Assembler does not yet support PIC"));
00892                     the_insn.fi[fc].fup |= OP_SEL_PLT;
00893                     s += 4;
00894                   }
00895 
00896                  the_insn.expand = insn->expand;
00897                   fc++;
00898               
00899                  continue;
00900               }
00901              else
00902               {
00903                 /* Intel syntax.  */
00904                  if (*s == ' ')
00905                   s++;
00906                  if (strncmp (s, "ha%", 3) == 0)
00907                   {
00908                     the_insn.fi[fc].fup |= OP_SEL_HA;
00909                     s += 3;
00910                   }
00911                  else if (strncmp (s, "h%", 2) == 0)
00912                   {
00913                     the_insn.fi[fc].fup |= OP_SEL_H;
00914                     s += 2;
00915                   }
00916                  else if (strncmp (s, "l%", 2) == 0)
00917                   {
00918                     the_insn.fi[fc].fup |= OP_SEL_L;
00919                     s += 2;
00920                   }
00921                  the_insn.expand = insn->expand;
00922 
00923                  /* Note that if i860_get_expression() fails, we will still
00924                    have created U entries in the symbol table for the
00925                    'symbols' in the input string.  Try not to create U
00926                    symbols for registers, etc.  */
00927                  if (! i860_get_expression (s))
00928                   s = expr_end;
00929                  else
00930                   goto error;
00931 
00932                   fc++;
00933                  continue;
00934               }
00935              break;
00936 
00937            default:
00938              as_fatal (_("failed sanity check."));
00939            }
00940          break;
00941        }
00942     error:
00943       if (match == 0)
00944        {
00945          /* Args don't match.  */
00946          if (insn[1].name != NULL
00947              && ! strcmp (insn->name, insn[1].name))
00948            {
00949              ++insn;
00950              s = args_start;
00951              continue;
00952            }
00953          else
00954            {
00955              as_bad (_("Illegal operands for %s"), insn->name);
00956              return;
00957            }
00958        }
00959       break;
00960     }
00961 
00962   /* Set the dual bit on this instruction if necessary.  */
00963   if (dual_mode != DUAL_OFF)
00964     {
00965       if ((opcode & 0xfc000000) == 0x48000000 || opcode == 0xb0000000)
00966         {
00967          /* The instruction is a flop or a fnop, so set its dual bit
00968             (but check that it is 8-byte aligned).  */
00969          if (((frag_now->fr_address + frag_now_fix_octets ()) & 7) == 0)
00970            opcode |= (1 << 9);
00971          else
00972             as_bad (_("'d.%s' must be 8-byte aligned"), insn->name);
00973 
00974           if (dual_mode == DUAL_DDOT)
00975            dual_mode = DUAL_OFF;
00976           else if (dual_mode == DUAL_ONDDOT)
00977            dual_mode = DUAL_ON;
00978         }
00979       else if (dual_mode == DUAL_DDOT || dual_mode == DUAL_ONDDOT)
00980         as_bad (_("Prefix 'd.' invalid for instruction `%s'"), insn->name);
00981     }
00982 
00983   the_insn.opcode = opcode;
00984 
00985   /* Only recognize XP instructions when the user has requested it.  */
00986   if (insn->expand == XP_ONLY && ! target_xp)
00987     as_bad (_("Unknown opcode: `%s'"), insn->name);
00988 }
00989 
00990 static int
00991 i860_get_expression (char *str)
00992 {
00993   char *save_in;
00994   segT seg;
00995 
00996   save_in = input_line_pointer;
00997   input_line_pointer = str;
00998   seg = expression (&the_insn.fi[fc].exp);
00999   if (seg != absolute_section
01000       && seg != undefined_section
01001       && ! SEG_NORMAL (seg))
01002     {
01003       the_insn.error = _("bad segment");
01004       expr_end = input_line_pointer;
01005       input_line_pointer = save_in;
01006       return 1;
01007     }
01008   expr_end = input_line_pointer;
01009   input_line_pointer = save_in;
01010   return 0;
01011 }
01012 
01013 /* Turn a string in input_line_pointer into a floating point constant of
01014    type TYPE, and store the appropriate bytes in *LITP.  The number of
01015    LITTLENUMS emitted is stored in *SIZEP.  An error message is returned,
01016    or NULL on OK.  */
01017 
01018 /* Equal to MAX_PRECISION in atof-ieee.c.  */
01019 #define MAX_LITTLENUMS 6
01020 
01021 char *
01022 md_atof (int type, char *litP, int *sizeP)
01023 {
01024   int prec;
01025   LITTLENUM_TYPE words[MAX_LITTLENUMS];
01026   LITTLENUM_TYPE *wordP;
01027   char *t;
01028 
01029   switch (type)
01030     {
01031     case 'f':
01032     case 'F':
01033     case 's':
01034     case 'S':
01035       prec = 2;
01036       break;
01037 
01038     case 'd':
01039     case 'D':
01040     case 'r':
01041     case 'R':
01042       prec = 4;
01043       break;
01044 
01045     case 'x':
01046     case 'X':
01047       prec = 6;
01048       break;
01049 
01050     case 'p':
01051     case 'P':
01052       prec = 6;
01053       break;
01054 
01055     default:
01056       *sizeP = 0;
01057       return _("Bad call to MD_ATOF()");
01058     }
01059   t = atof_ieee (input_line_pointer, type, words);
01060   if (t)
01061     input_line_pointer = t;
01062   *sizeP = prec * sizeof (LITTLENUM_TYPE);
01063   for (wordP = words; prec--;)
01064     {
01065       md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
01066       litP += sizeof (LITTLENUM_TYPE);
01067     }
01068   return 0;
01069 }
01070 
01071 /* Write out in current endian mode.  */
01072 void
01073 md_number_to_chars (char *buf, valueT val, int n)
01074 {
01075   if (target_big_endian)
01076     number_to_chars_bigendian (buf, val, n);
01077   else
01078     number_to_chars_littleendian (buf, val, n);
01079 }
01080 
01081 /* This should never be called for i860.  */
01082 int
01083 md_estimate_size_before_relax (register fragS *fragP ATTRIBUTE_UNUSED,
01084                             segT segtype ATTRIBUTE_UNUSED)
01085 {
01086   as_fatal (_("i860_estimate_size_before_relax\n"));
01087 }
01088 
01089 #ifdef DEBUG_I860
01090 static void
01091 print_insn (struct i860_it *insn)
01092 {
01093   if (insn->error)
01094     fprintf (stderr, "ERROR: %s\n", insn->error);
01095 
01096   fprintf (stderr, "opcode = 0x%08lx\t", insn->opcode);
01097   fprintf (stderr, "expand = 0x%x\t", insn->expand);
01098   fprintf (stderr, "reloc = %s\t\n",
01099           bfd_get_reloc_code_name (insn->reloc));
01100   fprintf (stderr, "exp =  {\n");
01101   fprintf (stderr, "\t\tX_add_symbol = %s\n",
01102           insn->exp.X_add_symbol ?
01103           (S_GET_NAME (insn->exp.X_add_symbol) ?
01104            S_GET_NAME (insn->exp.X_add_symbol) : "???") : "0");
01105   fprintf (stderr, "\t\tX_op_symbol = %s\n",
01106           insn->exp.X_op_symbol ?
01107           (S_GET_NAME (insn->exp.X_op_symbol) ?
01108            S_GET_NAME (insn->exp.X_op_symbol) : "???") : "0");
01109   fprintf (stderr, "\t\tX_add_number = %lx\n",
01110           insn->exp.X_add_number);
01111   fprintf (stderr, "}\n");
01112 }
01113 #endif /* DEBUG_I860 */
01114 
01115 
01116 #ifdef OBJ_ELF
01117 const char *md_shortopts = "VQ:";
01118 #else
01119 const char *md_shortopts = "";
01120 #endif
01121 
01122 #define OPTION_EB           (OPTION_MD_BASE + 0)
01123 #define OPTION_EL           (OPTION_MD_BASE + 1)
01124 #define OPTION_WARN_EXPAND  (OPTION_MD_BASE + 2)
01125 #define OPTION_XP           (OPTION_MD_BASE + 3)
01126 #define OPTION_INTEL_SYNTAX (OPTION_MD_BASE + 4)
01127 
01128 struct option md_longopts[] = {
01129   { "EB",         no_argument, NULL, OPTION_EB },
01130   { "EL",         no_argument, NULL, OPTION_EL },
01131   { "mwarn-expand", no_argument, NULL, OPTION_WARN_EXPAND },
01132   { "mxp",        no_argument, NULL, OPTION_XP },
01133   { "mintel-syntax",no_argument, NULL, OPTION_INTEL_SYNTAX },
01134   { NULL,         no_argument, NULL, 0 }
01135 };
01136 size_t md_longopts_size = sizeof (md_longopts);
01137 
01138 int
01139 md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
01140 {
01141   switch (c)
01142     {
01143     case OPTION_EB:
01144       target_big_endian = 1;
01145       break;
01146 
01147     case OPTION_EL:
01148       target_big_endian = 0;
01149       break;
01150 
01151     case OPTION_WARN_EXPAND:
01152       target_warn_expand = 1;
01153       break;
01154 
01155     case OPTION_XP:
01156       target_xp = 1;
01157       break;
01158 
01159     case OPTION_INTEL_SYNTAX:
01160       target_intel_syntax = 1;
01161       break;
01162 
01163 #ifdef OBJ_ELF
01164     /* SVR4 argument compatibility (-V): print version ID.  */
01165     case 'V':
01166       print_version_id ();
01167       break;
01168 
01169     /* SVR4 argument compatibility (-Qy, -Qn): controls whether
01170        a .comment section should be emitted or not (ignored).  */
01171     case 'Q':
01172       break;
01173 #endif
01174 
01175     default:
01176       return 0;
01177     }
01178 
01179   return 1;
01180 }
01181 
01182 void
01183 md_show_usage (FILE *stream)
01184 {
01185   fprintf (stream, _("\
01186   -EL                  generate code for little endian mode (default)\n\
01187   -EB                  generate code for big endian mode\n\
01188   -mwarn-expand               warn if pseudo operations are expanded\n\
01189   -mxp                 enable i860XP support (disabled by default)\n\
01190   -mintel-syntax       enable Intel syntax (default to AT&T/SVR4)\n"));
01191 #ifdef OBJ_ELF
01192   /* SVR4 compatibility flags.  */
01193   fprintf (stream, _("\
01194   -V                   print assembler version number\n\
01195   -Qy, -Qn             ignored\n"));
01196 #endif
01197 }
01198 
01199 
01200 /* We have no need to default values of symbols.  */
01201 symbolS *
01202 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
01203 {
01204   return 0;
01205 }
01206 
01207 /* The i860 denotes auto-increment with '++'.  */
01208 void
01209 md_operand (expressionS *exp)
01210 {
01211   char *s;
01212 
01213   for (s = input_line_pointer; *s; s++)
01214     {
01215       if (s[0] == '+' && s[1] == '+')
01216        {
01217          input_line_pointer += 2;
01218          exp->X_op = O_register;
01219          break;
01220        }
01221     }
01222 }
01223 
01224 /* Round up a section size to the appropriate boundary.  */
01225 valueT
01226 md_section_align (segT segment ATTRIBUTE_UNUSED,
01227                 valueT size ATTRIBUTE_UNUSED)
01228 {
01229   /* Byte alignment is fine.  */
01230   return size;
01231 }
01232 
01233 /* On the i860, a PC-relative offset is relative to the address of the
01234    offset plus its size.  */
01235 long
01236 md_pcrel_from (fixS *fixP)
01237 {
01238   return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
01239 }
01240 
01241 /* Determine the relocation needed for non PC-relative 16-bit immediates.
01242    Also adjust the given immediate as necessary.  Finally, check that
01243    all constraints (such as alignment) are satisfied.   */
01244 static bfd_reloc_code_real_type
01245 obtain_reloc_for_imm16 (fixS *fix, long *val)
01246 {
01247   valueT fup = fix->fx_addnumber;
01248   bfd_reloc_code_real_type reloc;
01249 
01250   if (fix->fx_pcrel)
01251     abort ();
01252 
01253   /* Check alignment restrictions.  */
01254   if ((fup & OP_ALIGN2) && (*val & 0x1))
01255     as_bad_where (fix->fx_file, fix->fx_line,
01256                 _("This immediate requires 0 MOD 2 alignment"));
01257   else if ((fup & OP_ALIGN4) && (*val & 0x3))
01258     as_bad_where (fix->fx_file, fix->fx_line,
01259                 _("This immediate requires 0 MOD 4 alignment"));
01260   else if ((fup & OP_ALIGN8) && (*val & 0x7))
01261     as_bad_where (fix->fx_file, fix->fx_line,
01262                 _("This immediate requires 0 MOD 8 alignment"));
01263   else if ((fup & OP_ALIGN16) && (*val & 0xf))
01264     as_bad_where (fix->fx_file, fix->fx_line,
01265                 _("This immediate requires 0 MOD 16 alignment"));
01266 
01267   if (fup & OP_SEL_HA)
01268     {
01269       *val = (*val >> 16) + (*val & 0x8000 ? 1 : 0);
01270       reloc = BFD_RELOC_860_HIGHADJ;
01271     }
01272   else if (fup & OP_SEL_H)
01273     {
01274       *val >>= 16;
01275       reloc = BFD_RELOC_860_HIGH;
01276     }
01277   else if (fup & OP_SEL_L)
01278     {
01279       int num_encode;
01280       if (fup & OP_IMM_SPLIT16)
01281        {
01282          if (fup & OP_ENCODE1)
01283            {
01284              num_encode = 1;
01285              reloc = BFD_RELOC_860_SPLIT1;
01286            }
01287          else if (fup & OP_ENCODE2)
01288            {
01289              num_encode = 2;
01290              reloc = BFD_RELOC_860_SPLIT2;
01291            }
01292          else
01293            {
01294              num_encode = 0;
01295              reloc = BFD_RELOC_860_SPLIT0;
01296            }
01297        }
01298       else
01299        {
01300          if (fup & OP_ENCODE1)
01301            {
01302              num_encode = 1;
01303              reloc = BFD_RELOC_860_LOW1;
01304            }
01305          else if (fup & OP_ENCODE2)
01306            {
01307              num_encode = 2;
01308              reloc = BFD_RELOC_860_LOW2;
01309            }
01310          else if (fup & OP_ENCODE3)
01311            {
01312              num_encode = 3;
01313              reloc = BFD_RELOC_860_LOW3;
01314            }
01315          else
01316            {
01317              num_encode = 0;
01318              reloc = BFD_RELOC_860_LOW0;
01319            }
01320        }
01321 
01322       /* Preserve size encode bits.  */
01323       *val &= ~((1 << num_encode) - 1);
01324     }
01325   else
01326     {
01327       /* No selector.  What reloc do we generate (???)?  */
01328       reloc = BFD_RELOC_32;
01329     }
01330 
01331   return reloc;
01332 }
01333 
01334 /* Attempt to simplify or eliminate a fixup. To indicate that a fixup
01335    has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL,
01336    we will have to generate a reloc entry.  */
01337 
01338 void
01339 md_apply_fix (fixS *fix, valueT *valP, segT seg ATTRIBUTE_UNUSED)
01340 {
01341   char *buf;
01342   long val = *valP;
01343   unsigned long insn;
01344   valueT fup;
01345 
01346   buf = fix->fx_frag->fr_literal + fix->fx_where;
01347 
01348   /* Recall that earlier we stored the opcode little-endian.  */
01349   insn = bfd_getl32 (buf);
01350 
01351   /* We stored a fix-up in this oddly-named scratch field.  */
01352   fup = fix->fx_addnumber;
01353 
01354   /* Determine the necessary relocations as well as inserting an
01355      immediate into the instruction.   */
01356   if (fup & OP_IMM_U5)
01357     {
01358       if (val & ~0x1f)
01359        as_bad_where (fix->fx_file, fix->fx_line,
01360                     _("5-bit immediate too large"));
01361       if (fix->fx_addsy)
01362        as_bad_where (fix->fx_file, fix->fx_line,
01363                     _("5-bit field must be absolute"));
01364 
01365       insn |= (val & 0x1f) << 11;
01366       bfd_putl32 (insn, buf);
01367       fix->fx_r_type = BFD_RELOC_NONE;
01368       fix->fx_done = 1;
01369     }
01370   else if (fup & OP_IMM_S16)
01371     {
01372       fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val);
01373 
01374       /* Insert the immediate.  */
01375       if (fix->fx_addsy)
01376        fix->fx_done = 0;
01377       else
01378        {
01379          insn |= val & 0xffff;
01380          bfd_putl32 (insn, buf);
01381          fix->fx_r_type = BFD_RELOC_NONE;
01382          fix->fx_done = 1;
01383        }
01384     }
01385   else if (fup & OP_IMM_U16)
01386     abort ();
01387 
01388   else if (fup & OP_IMM_SPLIT16)
01389     {
01390       fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val);
01391 
01392       /* Insert the immediate.  */
01393       if (fix->fx_addsy)
01394        fix->fx_done = 0;
01395       else
01396        {
01397          insn |= val & 0x7ff;
01398          insn |= (val & 0xf800) << 5;
01399          bfd_putl32 (insn, buf);
01400          fix->fx_r_type = BFD_RELOC_NONE;
01401          fix->fx_done = 1;
01402        }
01403     }
01404   else if (fup & OP_IMM_BR16)
01405     {
01406       if (val & 0x3)
01407        as_bad_where (fix->fx_file, fix->fx_line,
01408                     _("A branch offset requires 0 MOD 4 alignment"));
01409 
01410       val = val >> 2;
01411 
01412       /* Insert the immediate.  */
01413       if (fix->fx_addsy)
01414        {
01415          fix->fx_done = 0;
01416          fix->fx_r_type = BFD_RELOC_860_PC16;
01417        }
01418       else
01419        {
01420          insn |= (val & 0x7ff);
01421          insn |= ((val & 0xf800) << 5);
01422          bfd_putl32 (insn, buf);
01423          fix->fx_r_type = BFD_RELOC_NONE;
01424          fix->fx_done = 1;
01425        }
01426     }
01427   else if (fup & OP_IMM_BR26)
01428     {
01429       if (val & 0x3)
01430        as_bad_where (fix->fx_file, fix->fx_line,
01431                     _("A branch offset requires 0 MOD 4 alignment"));
01432 
01433       val >>= 2;
01434 
01435       /* Insert the immediate.  */
01436       if (fix->fx_addsy)
01437        {
01438          fix->fx_r_type = BFD_RELOC_860_PC26;
01439          fix->fx_done = 0;
01440        }
01441       else
01442        {
01443          insn |= (val & 0x3ffffff);
01444          bfd_putl32 (insn, buf);
01445          fix->fx_r_type = BFD_RELOC_NONE;
01446          fix->fx_done = 1;
01447        }
01448     }
01449   else if (fup != OP_NONE)
01450     {
01451       as_bad_where (fix->fx_file, fix->fx_line,
01452                   _("Unrecognized fix-up (0x%08lx)"), (unsigned long) fup);
01453       abort ();
01454     }
01455   else
01456     {
01457       /* I believe only fix-ups such as ".long .ep.main-main+0xc8000000"
01458         reach here (???).  */
01459       if (fix->fx_addsy)
01460        {
01461          fix->fx_r_type = BFD_RELOC_32;
01462          fix->fx_done = 0;
01463        }
01464       else
01465        {
01466          insn |= (val & 0xffffffff);
01467          bfd_putl32 (insn, buf);
01468          fix->fx_r_type = BFD_RELOC_NONE;
01469          fix->fx_done = 1;
01470        }
01471     }
01472 }
01473 
01474 /* Generate a machine dependent reloc from a fixup.  */
01475 arelent*
01476 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
01477              fixS *fixp)
01478 {
01479   arelent *reloc;
01480 
01481   reloc = xmalloc (sizeof (*reloc));
01482   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
01483   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
01484   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
01485   reloc->addend = fixp->fx_offset;
01486   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
01487 
01488   if (! reloc->howto)
01489     {
01490       as_bad_where (fixp->fx_file, fixp->fx_line,
01491                     "Cannot represent %s relocation in object file",
01492                     bfd_get_reloc_code_name (fixp->fx_r_type));
01493     }
01494   return reloc;
01495 }
01496 
01497 /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
01498    of an rs_align_code fragment.  */
01499 
01500 void
01501 i860_handle_align (fragS *fragp)
01502 {
01503   /* Instructions are always stored little-endian on the i860.  */
01504   static const unsigned char le_nop[] = { 0x00, 0x00, 0x00, 0xA0 };
01505 
01506   int bytes;
01507   char *p;
01508 
01509   if (fragp->fr_type != rs_align_code)
01510     return;
01511 
01512   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
01513   p = fragp->fr_literal + fragp->fr_fix;
01514 
01515   /* Make sure we are on a 4-byte boundary, in case someone has been
01516      putting data into a text section.  */
01517   if (bytes & 3)
01518     {
01519       int fix = bytes & 3;
01520       memset (p, 0, fix);
01521       p += fix;
01522       fragp->fr_fix += fix;
01523     }
01524 
01525   memcpy (p, le_nop, 4);
01526   fragp->fr_var = 4;
01527 }
01528 
01529 /* This is called after a user-defined label is seen.  We check
01530    if the label has a double colon (valid in Intel syntax mode only),
01531    in which case it should be externalized.  */
01532 
01533 void
01534 i860_check_label (symbolS *labelsym)
01535 {
01536   /* At this point, the current line pointer is sitting on the character
01537      just after the first colon on the label.  */ 
01538   if (target_intel_syntax && *input_line_pointer == ':')
01539     {
01540       S_SET_EXTERNAL (labelsym);
01541       input_line_pointer++;
01542     }
01543 }
01544