1 /* tc-i860.c -- Assembler for the Intel i860 architecture.
2    Copyright (C) 1989-2016 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.  */
31 static struct hash_control *op_hash = NULL;
32 
33 /* These characters always start a comment.  */
34 const char comment_chars[] = "#!/";
35 
36 /* These characters start a comment at the beginning of a line.  */
37 const char line_comment_chars[] = "#/";
38 
39 const char line_separator_chars[] = ";";
40 
41 /* Characters that can be used to separate the mantissa from the exponent
42    in floating point numbers.  */
43 const char EXP_CHARS[] = "eE";
44 
45 /* Characters that indicate this number is a floating point constant.
46    As in 0f12.456 or 0d1.2345e12.  */
47 const char FLT_CHARS[] = "rRsSfFdDxXpP";
48 
49 /* Register prefix (depends on syntax).  */
50 static char reg_prefix;
51 
52 #define MAX_FIXUPS 2
53 
54 struct 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.  */
69 static int fc;
70 
71 static char *expr_end;
72 
73 /* Indicates error if a pseudo operation was expanded after a branch.  */
74 static char last_expand;
75 
76 /* If true, then warn if any pseudo operations were expanded.  */
77 static int target_warn_expand = 0;
78 
79 /* If true, then XP support is enabled.  */
80 static int target_xp = 0;
81 
82 /* If true, then Intel syntax is enabled (default to AT&T/SVR4 syntax).  */
83 static int target_intel_syntax = 0;
84 
85 
86 /* Prototypes.  */
87 static void i860_process_insn (char *);
88 static void s_dual (int);
89 static void s_enddual (int);
90 static void s_atmp (int);
91 static void s_align_wrapper (int);
92 static int i860_get_expression (char *);
93 static bfd_reloc_code_real_type obtain_reloc_for_imm16 (fixS *, long *);
94 #ifdef DEBUG_I860
95 static void print_insn (struct i860_it *);
96 #endif
97 
98 const 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.  */
108 enum dual
109 {
110   DUAL_OFF = 0, DUAL_ON, DUAL_DDOT, DUAL_ONDDOT,
111 };
112 static enum dual dual_mode = DUAL_OFF;
113 
114 /* Handle ".dual" directive.  */
115 static void
s_dual(int ignore ATTRIBUTE_UNUSED)116 s_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.  */
125 static void
s_enddual(int ignore ATTRIBUTE_UNUSED)126 s_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.  */
135 static int atmp = 31;
136 
137 static void
s_atmp(int ignore ATTRIBUTE_UNUSED)138 s_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.  */
181 static void
s_align_wrapper(int arg)182 s_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.  */
211 void
md_begin(void)212 md_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.  */
255 void
md_assemble(char * str)256 md_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.  */
451 static void
i860_process_insn(char * str)452 i860_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 
990 static int
i860_get_expression(char * str)991 i860_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 
1013 const char *
md_atof(int type,char * litP,int * sizeP)1014 md_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.  */
1020 void
md_number_to_chars(char * buf,valueT val,int n)1021 md_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.  */
1030 int
md_estimate_size_before_relax(fragS * fragP ATTRIBUTE_UNUSED,segT segtype ATTRIBUTE_UNUSED)1031 md_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
1038 static void
print_insn(struct i860_it * insn)1039 print_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
1065 const char *md_shortopts = "VQ:";
1066 #else
1067 const 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 
1076 struct 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 };
1084 size_t md_longopts_size = sizeof (md_longopts);
1085 
1086 int
md_parse_option(int c,const char * arg ATTRIBUTE_UNUSED)1087 md_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 
1130 void
md_show_usage(FILE * stream)1131 md_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.  */
1149 symbolS *
md_undefined_symbol(char * name ATTRIBUTE_UNUSED)1150 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1151 {
1152   return 0;
1153 }
1154 
1155 /* The i860 denotes auto-increment with '++'.  */
1156 void
md_operand(expressionS * exp)1157 md_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.  */
1173 valueT
md_section_align(segT segment ATTRIBUTE_UNUSED,valueT size ATTRIBUTE_UNUSED)1174 md_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.  */
1183 long
md_pcrel_from(fixS * fixP)1184 md_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.   */
1192 static bfd_reloc_code_real_type
obtain_reloc_for_imm16(fixS * fix,long * val)1193 obtain_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 
1286 void
md_apply_fix(fixS * fix,valueT * valP,segT seg ATTRIBUTE_UNUSED)1287 md_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.  */
1423 arelent*
tc_gen_reloc(asection * section ATTRIBUTE_UNUSED,fixS * fixp)1424 tc_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 
1448 void
i860_handle_align(fragS * fragp)1449 i860_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 
1481 void
i860_check_label(symbolS * labelsym)1482 i860_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