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)
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. */
27 #include "safe-ctype.h"
29 #include "opcode/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. */
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. */
59 static const char reg_prefix
= '%';
61 static const char reg_prefix
= 0;
70 enum expand_type expand
;
74 bfd_reloc_code_real_type reloc
;
80 /* The current fixup count. */
83 static char *expr_end
;
85 /* Indicates error if a pseudo operation was expanded after a branch. */
86 static char last_expand
;
88 /* If true, then warn if any pseudo operations were expanded. */
89 static int target_warn_expand
= 0;
92 static void i860_process_insn
PARAMS ((char *));
93 static void s_dual
PARAMS ((int));
94 static void s_enddual
PARAMS ((int));
95 static void s_atmp
PARAMS ((int));
96 static int i860_get_expression
PARAMS ((char *));
97 static bfd_reloc_code_real_type obtain_reloc_for_imm16
98 PARAMS ((fixS
*, long *));
100 static void print_insn
PARAMS ((struct i860_it
*));
103 const pseudo_typeS md_pseudo_table
[] =
106 {"align", s_align_bytes
, 0},
109 {"enddual", s_enddual
, 0},
114 /* Dual-instruction mode handling. */
117 DUAL_OFF
= 0, DUAL_ON
, DUAL_DDOT
, DUAL_ONDDOT
,
119 static enum dual dual_mode
= DUAL_OFF
;
121 /* Handle ".dual" directive. */
124 int ignore ATTRIBUTE_UNUSED
;
129 /* Handle ".enddual" directive. */
132 int ignore ATTRIBUTE_UNUSED
;
134 dual_mode
= DUAL_OFF
;
137 /* Temporary register used when expanding assembler pseudo operations. */
138 static int atmp
= 31;
142 int ignore ATTRIBUTE_UNUSED
;
145 if (strncmp (input_line_pointer
, "sp", 2) == 0)
147 input_line_pointer
+= 2;
150 else if (strncmp (input_line_pointer
, "fp", 2) == 0)
152 input_line_pointer
+= 2;
155 else if (strncmp (input_line_pointer
, "r", 1) == 0)
157 input_line_pointer
+= 1;
158 temp
= get_absolute_expression ();
159 if (temp
>= 0 && temp
<= 31)
162 as_bad (_("Unknown temporary pseudo register"));
166 as_bad (_("Unknown temporary pseudo register"));
168 demand_empty_rest_of_line ();
171 /* This function is called once, at assembler startup time. It should
172 set up all the tables and data structures that the MD part of the
173 assembler will need. */
177 const char *retval
= NULL
;
181 op_hash
= hash_new ();
183 while (i860_opcodes
[i
].name
!= NULL
)
185 const char *name
= i860_opcodes
[i
].name
;
186 retval
= hash_insert (op_hash
, name
, (PTR
)&i860_opcodes
[i
]);
189 fprintf (stderr
, _("internal error: can't hash `%s': %s\n"),
190 i860_opcodes
[i
].name
, retval
);
195 if (i860_opcodes
[i
].match
& i860_opcodes
[i
].lose
)
198 _("internal error: losing opcode: `%s' \"%s\"\n"),
199 i860_opcodes
[i
].name
, i860_opcodes
[i
].args
);
204 while (i860_opcodes
[i
].name
!= NULL
205 && strcmp (i860_opcodes
[i
].name
, name
) == 0);
209 as_fatal (_("Defective assembler. No assembly attempted."));
212 /* This is the core of the machine-dependent assembler. STR points to a
213 machine dependent instruction. This function emits the frags/bytes
222 struct i860_it pseudo
[3];
227 /* Assemble the instruction. */
228 i860_process_insn (str
);
230 /* Check for expandable flag to produce pseudo-instructions. This
231 is an undesirable feature that should be avoided. */
232 if (the_insn
.expand
!= 0
233 && ! (the_insn
.fi
[0].fup
& (OP_SEL_HA
| OP_SEL_H
| OP_SEL_L
| OP_SEL_GOT
234 | OP_SEL_GOTOFF
| OP_SEL_PLT
)))
236 for (i
= 0; i
< 3; i
++)
237 pseudo
[i
] = the_insn
;
240 switch (the_insn
.expand
)
248 if (the_insn
.fi
[0].exp
.X_add_symbol
== NULL
249 && the_insn
.fi
[0].exp
.X_op_symbol
== NULL
250 && (the_insn
.fi
[0].exp
.X_add_number
< (1 << 15)
251 && the_insn
.fi
[0].exp
.X_add_number
>= -(1 << 15)))
254 /* Emit "or l%const,r0,ireg_dest". */
255 pseudo
[0].opcode
= (the_insn
.opcode
& 0x001f0000) | 0xe4000000;
256 pseudo
[0].fi
[0].fup
= (OP_IMM_S16
| OP_SEL_L
);
258 /* Emit "orh h%const,ireg_dest,ireg_dest". */
259 pseudo
[1].opcode
= (the_insn
.opcode
& 0x03ffffff) | 0xec000000
260 | ((the_insn
.opcode
& 0x001f0000) << 5);
261 pseudo
[1].fi
[0].fup
= (OP_IMM_S16
| OP_SEL_H
);
267 if (the_insn
.fi
[0].exp
.X_add_symbol
== NULL
268 && the_insn
.fi
[0].exp
.X_op_symbol
== NULL
269 && (the_insn
.fi
[0].exp
.X_add_number
< (1 << 15)
270 && the_insn
.fi
[0].exp
.X_add_number
>= -(1 << 15)))
273 /* Emit "orh ha%addr_expr,r0,r31". */
274 pseudo
[0].opcode
= 0xec000000 | (atmp
<< 16);
275 pseudo
[0].fi
[0].fup
= (OP_IMM_S16
| OP_SEL_HA
);
277 /* Emit "l%addr_expr(r31),ireg_dest". We pick up the fixup
278 information from the original instruction. */
279 pseudo
[1].opcode
= (the_insn
.opcode
& ~0x03e00000) | (atmp
<< 21);
280 pseudo
[1].fi
[0].fup
= the_insn
.fi
[0].fup
| OP_SEL_L
;
286 if (the_insn
.fi
[0].exp
.X_add_symbol
== NULL
287 && the_insn
.fi
[0].exp
.X_op_symbol
== NULL
288 && (the_insn
.fi
[0].exp
.X_add_number
< (1 << 16)
289 && the_insn
.fi
[0].exp
.X_add_number
>= 0))
292 /* Emit "$(opcode)h h%const,ireg_src2,r31". */
293 pseudo
[0].opcode
= (the_insn
.opcode
& 0xf3e0ffff) | 0x0c000000
295 pseudo
[0].fi
[0].fup
= (OP_IMM_S16
| OP_SEL_H
);
297 /* Emit "$(opcode) l%const,r31,ireg_dest". */
298 pseudo
[1].opcode
= (the_insn
.opcode
& 0xf01f0000) | 0x04000000
300 pseudo
[1].fi
[0].fup
= (OP_IMM_S16
| OP_SEL_L
);
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 << 16)
309 && the_insn
.fi
[0].exp
.X_add_number
>= 0))
312 /* Emit "andnot h%const,ireg_src2,r31". */
313 pseudo
[0].opcode
= (the_insn
.opcode
& 0x03e0ffff) | 0xd4000000
315 pseudo
[0].fi
[0].fup
= (OP_IMM_S16
| OP_SEL_H
);
316 pseudo
[0].fi
[0].exp
.X_add_number
=
317 -1 - the_insn
.fi
[0].exp
.X_add_number
;
319 /* Emit "andnot l%const,r31,ireg_dest". */
320 pseudo
[1].opcode
= (the_insn
.opcode
& 0x001f0000) | 0xd4000000
322 pseudo
[1].fi
[0].fup
= (OP_IMM_S16
| OP_SEL_L
);
323 pseudo
[1].fi
[0].exp
.X_add_number
=
324 -1 - the_insn
.fi
[0].exp
.X_add_number
;
330 if (the_insn
.fi
[0].exp
.X_add_symbol
== NULL
331 && the_insn
.fi
[0].exp
.X_op_symbol
== NULL
332 && (the_insn
.fi
[0].exp
.X_add_number
< (1 << 15)
333 && the_insn
.fi
[0].exp
.X_add_number
>= -(1 << 15)))
336 /* Emit "orh h%const,r0,r31". */
337 pseudo
[0].opcode
= 0xec000000 | (atmp
<< 16);
338 pseudo
[0].fi
[0].fup
= (OP_IMM_S16
| OP_SEL_H
);
340 /* Emit "or l%const,r31,r31". */
341 pseudo
[1].opcode
= 0xe4000000 | (atmp
<< 21) | (atmp
<< 16);
342 pseudo
[1].fi
[0].fup
= (OP_IMM_S16
| OP_SEL_L
);
344 /* Emit "r31,ireg_src2,ireg_dest". */
345 pseudo
[2].opcode
= (the_insn
.opcode
& ~0x0400ffff) | (atmp
<< 11);
346 pseudo
[2].fi
[0].fup
= OP_IMM_S16
;
352 as_fatal (_("failed sanity check."));
355 the_insn
= pseudo
[0];
357 /* Warn if an opcode is expanded after a delayed branch. */
358 if (num_opcodes
> 1 && last_expand
== 1)
359 as_warn (_("Expanded opcode after delayed branch: `%s'"), str
);
361 /* Warn if an opcode is expanded in dual mode. */
362 if (num_opcodes
> 1 && dual_mode
!= DUAL_OFF
)
363 as_warn (_("Expanded opcode in dual mode: `%s'"), str
);
365 /* Notify if any expansions happen. */
366 if (target_warn_expand
&& num_opcodes
> 1)
367 as_warn (_("An instruction was expanded (%s)"), str
);
375 /* Output the opcode. Note that the i860 always reads instructions
376 as little-endian data. */
377 destp
= frag_more (4);
378 number_to_chars_littleendian (destp
, the_insn
.opcode
, 4);
380 /* Check for expanded opcode after branch or in dual mode. */
381 last_expand
= the_insn
.fi
[0].pcrel
;
383 /* Output the symbol-dependent stuff. Only btne and bte will ever
384 loop more than once here, since only they (possibly) have more
386 for (tmp
= 0; tmp
< fc
; tmp
++)
388 if (the_insn
.fi
[tmp
].fup
!= OP_NONE
)
391 fix
= fix_new_exp (frag_now
,
392 destp
- frag_now
->fr_literal
,
394 &the_insn
.fi
[tmp
].exp
,
395 the_insn
.fi
[tmp
].pcrel
,
396 the_insn
.fi
[tmp
].reloc
);
398 /* Despite the odd name, this is a scratch field. We use
399 it to encode operand type information. */
400 fix
->fx_addnumber
= the_insn
.fi
[tmp
].fup
;
403 the_insn
= pseudo
[++i
];
405 while (--num_opcodes
> 0);
409 /* Assemble the instruction pointed to by STR. */
411 i860_process_insn (str
)
417 struct i860_opcode
*insn
;
419 unsigned long opcode
;
424 #if 1 /* For compiler warnings. */
431 for (s
= str
; ISLOWER (*s
) || *s
== '.' || *s
== '3'
432 || *s
== '2' || *s
== '1'; ++s
)
450 as_fatal (_("Unknown opcode: `%s'"), str
);
453 /* Check for dual mode ("d.") opcode prefix. */
454 if (strncmp (str
, "d.", 2) == 0)
456 if (dual_mode
== DUAL_ON
)
457 dual_mode
= DUAL_ONDDOT
;
459 dual_mode
= DUAL_DDOT
;
463 if ((insn
= (struct i860_opcode
*) hash_find (op_hash
, str
)) == NULL
)
465 if (dual_mode
== DUAL_DDOT
|| dual_mode
== DUAL_ONDDOT
)
467 as_bad (_("Unknown opcode: `%s'"), str
);
478 opcode
= insn
->match
;
479 memset (&the_insn
, '\0', sizeof (the_insn
));
481 for (t
= 0; t
< MAX_FIXUPS
; t
++)
483 the_insn
.fi
[t
].reloc
= BFD_RELOC_NONE
;
484 the_insn
.fi
[t
].pcrel
= 0;
485 the_insn
.fi
[t
].fup
= OP_NONE
;
488 /* Build the opcode, checking as we go that the operands match. */
489 for (args
= insn
->args
; ; ++args
)
503 /* These must match exactly. */
513 /* Must be at least one digit. */
523 /* Next operand must be a register. */
527 /* Check for register prefix if necessary. */
528 if (reg_prefix
&& *s
!= reg_prefix
)
555 /* Any register r0..r31. */
558 if (!ISDIGIT (c
= *s
++))
564 if ((c
= 10 * (c
- '0') + (*s
++ - '0')) >= 32)
572 /* Not this opcode. */
577 /* Obtained the register, now place it in the opcode. */
581 opcode
|= mask
<< 11;
585 opcode
|= mask
<< 21;
589 opcode
|= mask
<< 16;
595 /* Next operand is a floating point register. */
599 /* Check for register prefix if necessary. */
600 if (reg_prefix
&& *s
!= reg_prefix
)
605 if (*s
++ == 'f' && ISDIGIT (*s
))
610 mask
= 10 * (mask
- '0') + (*s
++ - '0');
623 opcode
|= mask
<< 11;
627 opcode
|= mask
<< 21;
631 opcode
|= mask
<< 16;
632 if (dual_mode
!= DUAL_OFF
)
634 if (dual_mode
== DUAL_DDOT
)
635 dual_mode
= DUAL_OFF
;
636 if (dual_mode
== DUAL_ONDDOT
)
638 if ((opcode
& (1 << 10)) && mask
!= 0
639 && (mask
== ((opcode
>> 11) & 0x1f)))
640 as_warn (_("Pipelined instruction: fsrc1 = fdest"));
646 /* Next operand must be a control register. */
648 /* Check for register prefix if necessary. */
649 if (reg_prefix
&& *s
!= reg_prefix
)
654 if (strncmp (s
, "fir", 3) == 0)
660 if (strncmp (s
, "psr", 3) == 0)
666 if (strncmp (s
, "dirbase", 7) == 0)
672 if (strncmp (s
, "db", 2) == 0)
678 if (strncmp (s
, "fsr", 3) == 0)
684 if (strncmp (s
, "epsr", 4) == 0)
692 /* 5-bit immediate in src1. */
694 if (! i860_get_expression (s
))
697 the_insn
.fi
[fc
].fup
|= OP_IMM_U5
;
703 /* 26-bit immediate, relative branch (lbroff). */
705 the_insn
.fi
[fc
].pcrel
= 1;
706 the_insn
.fi
[fc
].fup
|= OP_IMM_BR26
;
709 /* 16-bit split immediate, relative branch (sbroff). */
711 the_insn
.fi
[fc
].pcrel
= 1;
712 the_insn
.fi
[fc
].fup
|= OP_IMM_BR16
;
715 /* 16-bit split immediate. */
717 the_insn
.fi
[fc
].fup
|= OP_IMM_SPLIT16
;
720 /* 16-bit split immediate, byte aligned (st.b). */
722 the_insn
.fi
[fc
].fup
|= OP_IMM_SPLIT16
;
725 /* 16-bit split immediate, half-word aligned (st.s). */
727 the_insn
.fi
[fc
].fup
|= (OP_IMM_SPLIT16
| OP_ENCODE1
| OP_ALIGN2
);
730 /* 16-bit split immediate, word aligned (st.l). */
732 the_insn
.fi
[fc
].fup
|= (OP_IMM_SPLIT16
| OP_ENCODE1
| OP_ALIGN4
);
735 /* 16-bit immediate. */
737 the_insn
.fi
[fc
].fup
|= OP_IMM_S16
;
740 /* 16-bit immediate, byte aligned (ld.b). */
742 the_insn
.fi
[fc
].fup
|= OP_IMM_S16
;
745 /* 16-bit immediate, half-word aligned (ld.s). */
747 the_insn
.fi
[fc
].fup
|= (OP_IMM_S16
| OP_ENCODE1
| OP_ALIGN2
);
750 /* 16-bit immediate, word aligned (ld.l, {p}fld.l, fst.l). */
752 if (insn
->name
[0] == 'l')
753 the_insn
.fi
[fc
].fup
|= (OP_IMM_S16
| OP_ENCODE1
| OP_ALIGN4
);
755 the_insn
.fi
[fc
].fup
|= (OP_IMM_S16
| OP_ENCODE2
| OP_ALIGN4
);
758 /* 16-bit immediate, double-word aligned ({p}fld.d, fst.d). */
760 the_insn
.fi
[fc
].fup
|= (OP_IMM_S16
| OP_ENCODE3
| OP_ALIGN8
);
763 /* 16-bit immediate, quad-word aligned (fld.q, fst.q). */
765 the_insn
.fi
[fc
].fup
|= (OP_IMM_S16
| OP_ENCODE3
| OP_ALIGN16
);
769 /* Handle the immediate for either the Intel syntax or
770 SVR4 syntax. The Intel syntax is "ha%immediate"
771 whereas SVR4 syntax is "[immediate]@ha". */
777 /* Note that if i860_get_expression() fails, we will still
778 have created U entries in the symbol table for the
779 'symbols' in the input string. Try not to create U
780 symbols for registers, etc. */
781 if (! i860_get_expression (s
))
786 if (strncmp (s
, "@ha", 3) == 0)
788 the_insn
.fi
[fc
].fup
|= OP_SEL_HA
;
791 else if (strncmp (s
, "@h", 2) == 0)
793 the_insn
.fi
[fc
].fup
|= OP_SEL_H
;
796 else if (strncmp (s
, "@l", 2) == 0)
798 the_insn
.fi
[fc
].fup
|= OP_SEL_L
;
801 else if (strncmp (s
, "@gotoff", 7) == 0
802 || strncmp (s
, "@GOTOFF", 7) == 0)
804 as_bad (_("Assembler does not yet support PIC"));
805 the_insn
.fi
[fc
].fup
|= OP_SEL_GOTOFF
;
808 else if (strncmp (s
, "@got", 4) == 0
809 || strncmp (s
, "@GOT", 4) == 0)
811 as_bad (_("Assembler does not yet support PIC"));
812 the_insn
.fi
[fc
].fup
|= OP_SEL_GOT
;
815 else if (strncmp (s
, "@plt", 4) == 0
816 || strncmp (s
, "@PLT", 4) == 0)
818 as_bad (_("Assembler does not yet support PIC"));
819 the_insn
.fi
[fc
].fup
|= OP_SEL_PLT
;
823 the_insn
.expand
= insn
->expand
;
827 #else /* ! SYNTAX_SVR4 */
830 if (strncmp (s
, "ha%", 3) == 0)
832 the_insn
.fi
[fc
].fup
|= OP_SEL_HA
;
835 else if (strncmp (s
, "h%", 2) == 0)
837 the_insn
.fi
[fc
].fup
|= OP_SEL_H
;
840 else if (strncmp (s
, "l%", 2) == 0)
842 the_insn
.fi
[fc
].fup
|= OP_SEL_L
;
845 the_insn
.expand
= insn
->expand
;
847 /* Note that if i860_get_expression() fails, we will still
848 have created U entries in the symbol table for the
849 'symbols' in the input string. Try not to create U
850 symbols for registers, etc. */
851 if (! i860_get_expression (s
))
858 #endif /* SYNTAX_SVR4 */
862 as_fatal (_("failed sanity check."));
869 /* Args don't match. */
870 if (insn
[1].name
!= NULL
871 && ! strcmp (insn
->name
, insn
[1].name
))
879 as_bad (_("Illegal operands for %s"), insn
->name
);
886 the_insn
.opcode
= opcode
;
890 i860_get_expression (str
)
896 save_in
= input_line_pointer
;
897 input_line_pointer
= str
;
898 seg
= expression (&the_insn
.fi
[fc
].exp
);
899 if (seg
!= absolute_section
900 && seg
!= undefined_section
901 && ! SEG_NORMAL (seg
))
903 the_insn
.error
= _("bad segment");
904 expr_end
= input_line_pointer
;
905 input_line_pointer
= save_in
;
908 expr_end
= input_line_pointer
;
909 input_line_pointer
= save_in
;
913 /* Turn a string in input_line_pointer into a floating point constant of
914 type TYPE, and store the appropriate bytes in *LITP. The number of
915 LITTLENUMS emitted is stored in *SIZEP. An error message is returned,
918 /* Equal to MAX_PRECISION in atof-ieee.c. */
919 #define MAX_LITTLENUMS 6
922 md_atof (type
, litP
, sizeP
)
928 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
929 LITTLENUM_TYPE
*wordP
;
960 return _("Bad call to MD_ATOF()");
962 t
= atof_ieee (input_line_pointer
, type
, words
);
964 input_line_pointer
= t
;
965 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
966 for (wordP
= words
; prec
--;)
968 md_number_to_chars (litP
, (long) (*wordP
++), sizeof (LITTLENUM_TYPE
));
969 litP
+= sizeof (LITTLENUM_TYPE
);
974 /* Write out in current endian mode. */
976 md_number_to_chars (buf
, val
, n
)
981 if (target_big_endian
)
982 number_to_chars_bigendian (buf
, val
, n
);
984 number_to_chars_littleendian (buf
, val
, n
);
987 /* This should never be called for i860. */
989 md_estimate_size_before_relax (fragP
, segtype
)
990 register fragS
*fragP ATTRIBUTE_UNUSED
;
991 segT segtype ATTRIBUTE_UNUSED
;
993 as_fatal (_("i860_estimate_size_before_relax\n"));
999 struct i860_it
*insn
;
1002 fprintf (stderr
, "ERROR: %s\n", insn
->error
);
1004 fprintf (stderr
, "opcode = 0x%08lx\t", insn
->opcode
);
1005 fprintf (stderr
, "expand = 0x%x\t", insn
->expand
);
1006 fprintf (stderr
, "reloc = %s\t\n",
1007 bfd_get_reloc_code_name (insn
->reloc
));
1008 fprintf (stderr
, "exp = {\n");
1009 fprintf (stderr
, "\t\tX_add_symbol = %s\n",
1010 insn
->exp
.X_add_symbol
?
1011 (S_GET_NAME (insn
->exp
.X_add_symbol
) ?
1012 S_GET_NAME (insn
->exp
.X_add_symbol
) : "???") : "0");
1013 fprintf (stderr
, "\t\tX_op_symbol = %s\n",
1014 insn
->exp
.X_op_symbol
?
1015 (S_GET_NAME (insn
->exp
.X_op_symbol
) ?
1016 S_GET_NAME (insn
->exp
.X_op_symbol
) : "???") : "0");
1017 fprintf (stderr
, "\t\tX_add_number = %lx\n",
1018 insn
->exp
.X_add_number
);
1019 fprintf (stderr
, "}\n");
1021 #endif /* DEBUG_I860 */
1025 const char *md_shortopts
= "VQ:";
1027 const char *md_shortopts
= "";
1030 #define OPTION_EB (OPTION_MD_BASE + 0)
1031 #define OPTION_EL (OPTION_MD_BASE + 1)
1032 #define OPTION_WARN_EXPAND (OPTION_MD_BASE + 2)
1034 struct option md_longopts
[] = {
1035 { "EB", no_argument
, NULL
, OPTION_EB
},
1036 { "EL", no_argument
, NULL
, OPTION_EL
},
1037 { "mwarn-expand", no_argument
, NULL
, OPTION_WARN_EXPAND
},
1038 { NULL
, no_argument
, NULL
, 0 }
1040 size_t md_longopts_size
= sizeof (md_longopts
);
1043 md_parse_option (c
, arg
)
1045 char *arg ATTRIBUTE_UNUSED
;
1050 target_big_endian
= 1;
1054 target_big_endian
= 0;
1057 case OPTION_WARN_EXPAND
:
1058 target_warn_expand
= 1;
1062 /* SVR4 argument compatibility (-V): print version ID. */
1064 print_version_id ();
1067 /* SVR4 argument compatibility (-Qy, -Qn): controls whether
1068 a .comment section should be emitted or not (ignored). */
1081 md_show_usage (stream
)
1084 fprintf (stream
, _("\
1085 -EL generate code for little endian mode (default)\n\
1086 -EB generate code for big endian mode\n\
1087 -mwarn-expand warn if pseudo operations are expanded\n"));
1089 /* SVR4 compatibility flags. */
1090 fprintf (stream
, _("\
1091 -V print assembler version number\n\
1092 -Qy, -Qn ignored\n"));
1097 /* We have no need to default values of symbols. */
1099 md_undefined_symbol (name
)
1100 char *name ATTRIBUTE_UNUSED
;
1105 /* The i860 denotes auto-increment with '++'. */
1112 for (s
= input_line_pointer
; *s
; s
++)
1114 if (s
[0] == '+' && s
[1] == '+')
1116 input_line_pointer
+= 2;
1117 exp
->X_op
= O_register
;
1123 /* Round up a section size to the appropriate boundary. */
1125 md_section_align (segment
, size
)
1126 segT segment ATTRIBUTE_UNUSED
;
1127 valueT size ATTRIBUTE_UNUSED
;
1129 /* Byte alignment is fine. */
1133 /* On the i860, a PC-relative offset is relative to the address of the
1134 of the offset plus its size. */
1136 md_pcrel_from (fixP
)
1139 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1142 /* Determine the relocation needed for non PC-relative 16-bit immediates.
1143 Also adjust the given immediate as necessary. Finally, check that
1144 all constraints (such as alignment) are satisfied. */
1145 static bfd_reloc_code_real_type
1146 obtain_reloc_for_imm16 (fix
, val
)
1150 valueT fup
= fix
->fx_addnumber
;
1151 bfd_reloc_code_real_type reloc
;
1156 /* Check alignment restrictions. */
1157 if ((fup
& OP_ALIGN2
) && (*val
& 0x1))
1158 as_bad_where (fix
->fx_file
, fix
->fx_line
,
1159 _("This immediate requires 0 MOD 2 alignment"));
1160 else if ((fup
& OP_ALIGN4
) && (*val
& 0x3))
1161 as_bad_where (fix
->fx_file
, fix
->fx_line
,
1162 _("This immediate requires 0 MOD 4 alignment"));
1163 else if ((fup
& OP_ALIGN8
) && (*val
& 0x7))
1164 as_bad_where (fix
->fx_file
, fix
->fx_line
,
1165 _("This immediate requires 0 MOD 8 alignment"));
1166 else if ((fup
& OP_ALIGN16
) && (*val
& 0xf))
1167 as_bad_where (fix
->fx_file
, fix
->fx_line
,
1168 _("This immediate requires 0 MOD 16 alignment"));
1170 if (fup
& OP_SEL_HA
)
1172 *val
= (*val
>> 16) + (*val
& 0x8000 ? 1 : 0);
1173 reloc
= BFD_RELOC_860_HIGHADJ
;
1175 else if (fup
& OP_SEL_H
)
1178 reloc
= BFD_RELOC_860_HIGH
;
1180 else if (fup
& OP_SEL_L
)
1183 if (fup
& OP_IMM_SPLIT16
)
1185 if (fup
& OP_ENCODE1
)
1188 reloc
= BFD_RELOC_860_SPLIT1
;
1190 else if (fup
& OP_ENCODE2
)
1193 reloc
= BFD_RELOC_860_SPLIT2
;
1198 reloc
= BFD_RELOC_860_SPLIT0
;
1203 if (fup
& OP_ENCODE1
)
1206 reloc
= BFD_RELOC_860_LOW1
;
1208 else if (fup
& OP_ENCODE2
)
1211 reloc
= BFD_RELOC_860_LOW2
;
1213 else if (fup
& OP_ENCODE3
)
1216 reloc
= BFD_RELOC_860_LOW3
;
1221 reloc
= BFD_RELOC_860_LOW0
;
1225 /* Preserve size encode bits. */
1226 *val
&= ~((1 << num_encode
) - 1);
1230 /* No selector. What reloc do we generate (???)? */
1231 reloc
= BFD_RELOC_32
;
1237 /* Attempt to simplify or eliminate a fixup. To indicate that a fixup
1238 has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL,
1239 we will have to generate a reloc entry. */
1242 md_apply_fix3 (fix
, valP
, seg
)
1245 segT seg ATTRIBUTE_UNUSED
;
1252 buf
= fix
->fx_frag
->fr_literal
+ fix
->fx_where
;
1254 /* Recall that earlier we stored the opcode little-endian. */
1255 insn
= bfd_getl32 (buf
);
1257 /* We stored a fix-up in this oddly-named scratch field. */
1258 fup
= fix
->fx_addnumber
;
1260 /* Determine the necessary relocations as well as inserting an
1261 immediate into the instruction. */
1262 if (fup
& OP_IMM_U5
)
1265 as_bad_where (fix
->fx_file
, fix
->fx_line
,
1266 _("5-bit immediate too large"));
1268 as_bad_where (fix
->fx_file
, fix
->fx_line
,
1269 _("5-bit field must be absolute"));
1271 insn
|= (val
& 0x1f) << 11;
1272 bfd_putl32 (insn
, buf
);
1273 fix
->fx_r_type
= BFD_RELOC_NONE
;
1276 else if (fup
& OP_IMM_S16
)
1278 fix
->fx_r_type
= obtain_reloc_for_imm16 (fix
, &val
);
1280 /* Insert the immediate. */
1285 insn
|= val
& 0xffff;
1286 bfd_putl32 (insn
, buf
);
1287 fix
->fx_r_type
= BFD_RELOC_NONE
;
1291 else if (fup
& OP_IMM_U16
)
1294 else if (fup
& OP_IMM_SPLIT16
)
1296 fix
->fx_r_type
= obtain_reloc_for_imm16 (fix
, &val
);
1298 /* Insert the immediate. */
1303 insn
|= val
& 0x7ff;
1304 insn
|= (val
& 0xf800) << 5;
1305 bfd_putl32 (insn
, buf
);
1306 fix
->fx_r_type
= BFD_RELOC_NONE
;
1310 else if (fup
& OP_IMM_BR16
)
1313 as_bad_where (fix
->fx_file
, fix
->fx_line
,
1314 _("A branch offset requires 0 MOD 4 alignment"));
1318 /* Insert the immediate. */
1322 fix
->fx_r_type
= BFD_RELOC_860_PC16
;
1326 insn
|= (val
& 0x7ff);
1327 insn
|= ((val
& 0xf800) << 5);
1328 bfd_putl32 (insn
, buf
);
1329 fix
->fx_r_type
= BFD_RELOC_NONE
;
1333 else if (fup
& OP_IMM_BR26
)
1336 as_bad_where (fix
->fx_file
, fix
->fx_line
,
1337 _("A branch offset requires 0 MOD 4 alignment"));
1341 /* Insert the immediate. */
1344 fix
->fx_r_type
= BFD_RELOC_860_PC26
;
1349 insn
|= (val
& 0x3ffffff);
1350 bfd_putl32 (insn
, buf
);
1351 fix
->fx_r_type
= BFD_RELOC_NONE
;
1355 else if (fup
!= OP_NONE
)
1357 as_bad_where (fix
->fx_file
, fix
->fx_line
,
1358 _("Unrecognized fix-up (0x%08lx)"), (unsigned long) fup
);
1363 /* I believe only fix-ups such as ".long .ep.main-main+0xc8000000"
1364 reach here (???). */
1367 fix
->fx_r_type
= BFD_RELOC_32
;
1372 insn
|= (val
& 0xffffffff);
1373 bfd_putl32 (insn
, buf
);
1374 fix
->fx_r_type
= BFD_RELOC_NONE
;
1380 /* Generate a machine dependent reloc from a fixup. */
1382 tc_gen_reloc (section
, fixp
)
1383 asection
*section ATTRIBUTE_UNUSED
;
1388 reloc
= xmalloc (sizeof (*reloc
));
1389 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1390 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1391 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1392 reloc
->addend
= fixp
->fx_offset
;
1393 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1397 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1398 "Cannot represent %s relocation in object file",
1399 bfd_get_reloc_code_name (fixp
->fx_r_type
));