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