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