1 /* tc-i860.c -- Assembler for the Intel i860 architecture.
2 Copyright 1989, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003
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;
91 /* If true, then XP support is enabled. */
92 static int target_xp
= 0;
95 static void i860_process_insn (char *);
96 static void s_dual (int);
97 static void s_enddual (int);
98 static void s_atmp (int);
99 static int i860_get_expression (char *);
100 static bfd_reloc_code_real_type
obtain_reloc_for_imm16 (fixS
*, long *);
102 static void print_insn (struct i860_it
*);
105 const pseudo_typeS md_pseudo_table
[] =
108 {"align", s_align_bytes
, 0},
111 {"enddual", s_enddual
, 0},
116 /* Dual-instruction mode handling. */
119 DUAL_OFF
= 0, DUAL_ON
, DUAL_DDOT
, DUAL_ONDDOT
,
121 static enum dual dual_mode
= DUAL_OFF
;
123 /* Handle ".dual" directive. */
125 s_dual (int ignore ATTRIBUTE_UNUSED
)
130 /* Handle ".enddual" directive. */
132 s_enddual (int ignore ATTRIBUTE_UNUSED
)
134 dual_mode
= DUAL_OFF
;
137 /* Temporary register used when expanding assembler pseudo operations. */
138 static int atmp
= 31;
141 s_atmp (int ignore ATTRIBUTE_UNUSED
)
144 if (strncmp (input_line_pointer
, "sp", 2) == 0)
146 input_line_pointer
+= 2;
149 else if (strncmp (input_line_pointer
, "fp", 2) == 0)
151 input_line_pointer
+= 2;
154 else if (strncmp (input_line_pointer
, "r", 1) == 0)
156 input_line_pointer
+= 1;
157 temp
= get_absolute_expression ();
158 if (temp
>= 0 && temp
<= 31)
161 as_bad (_("Unknown temporary pseudo register"));
165 as_bad (_("Unknown temporary pseudo register"));
167 demand_empty_rest_of_line ();
170 /* This function is called once, at assembler startup time. It should
171 set up all the tables and data structures that the MD part of the
172 assembler will need. */
176 const char *retval
= NULL
;
180 op_hash
= hash_new ();
182 while (i860_opcodes
[i
].name
!= NULL
)
184 const char *name
= i860_opcodes
[i
].name
;
185 retval
= hash_insert (op_hash
, name
, (PTR
)&i860_opcodes
[i
]);
188 fprintf (stderr
, _("internal error: can't hash `%s': %s\n"),
189 i860_opcodes
[i
].name
, retval
);
194 if (i860_opcodes
[i
].match
& i860_opcodes
[i
].lose
)
197 _("internal error: losing opcode: `%s' \"%s\"\n"),
198 i860_opcodes
[i
].name
, i860_opcodes
[i
].args
);
203 while (i860_opcodes
[i
].name
!= NULL
204 && strcmp (i860_opcodes
[i
].name
, name
) == 0);
208 as_fatal (_("Defective assembler. No assembly attempted."));
211 /* This is the core of the machine-dependent assembler. STR points to a
212 machine dependent instruction. This function emits the frags/bytes
215 md_assemble (char *str
)
220 struct i860_it pseudo
[3];
225 /* Assemble the instruction. */
226 i860_process_insn (str
);
228 /* Check for expandable flag to produce pseudo-instructions. This
229 is an undesirable feature that should be avoided. */
230 if (the_insn
.expand
!= 0 && the_insn
.expand
!= XP_ONLY
231 && ! (the_insn
.fi
[0].fup
& (OP_SEL_HA
| OP_SEL_H
| OP_SEL_L
| OP_SEL_GOT
232 | OP_SEL_GOTOFF
| OP_SEL_PLT
)))
234 for (i
= 0; i
< 3; i
++)
235 pseudo
[i
] = the_insn
;
238 switch (the_insn
.expand
)
246 if (the_insn
.fi
[0].exp
.X_add_symbol
== NULL
247 && the_insn
.fi
[0].exp
.X_op_symbol
== NULL
248 && (the_insn
.fi
[0].exp
.X_add_number
< (1 << 15)
249 && the_insn
.fi
[0].exp
.X_add_number
>= -(1 << 15)))
252 /* Emit "or l%const,r0,ireg_dest". */
253 pseudo
[0].opcode
= (the_insn
.opcode
& 0x001f0000) | 0xe4000000;
254 pseudo
[0].fi
[0].fup
= (OP_IMM_S16
| OP_SEL_L
);
256 /* Emit "orh h%const,ireg_dest,ireg_dest". */
257 pseudo
[1].opcode
= (the_insn
.opcode
& 0x03ffffff) | 0xec000000
258 | ((the_insn
.opcode
& 0x001f0000) << 5);
259 pseudo
[1].fi
[0].fup
= (OP_IMM_S16
| OP_SEL_H
);
265 if (the_insn
.fi
[0].exp
.X_add_symbol
== NULL
266 && the_insn
.fi
[0].exp
.X_op_symbol
== NULL
267 && (the_insn
.fi
[0].exp
.X_add_number
< (1 << 15)
268 && the_insn
.fi
[0].exp
.X_add_number
>= -(1 << 15)))
271 /* Emit "orh ha%addr_expr,r0,r31". */
272 pseudo
[0].opcode
= 0xec000000 | (atmp
<< 16);
273 pseudo
[0].fi
[0].fup
= (OP_IMM_S16
| OP_SEL_HA
);
275 /* Emit "l%addr_expr(r31),ireg_dest". We pick up the fixup
276 information from the original instruction. */
277 pseudo
[1].opcode
= (the_insn
.opcode
& ~0x03e00000) | (atmp
<< 21);
278 pseudo
[1].fi
[0].fup
= the_insn
.fi
[0].fup
| OP_SEL_L
;
284 if (the_insn
.fi
[0].exp
.X_add_symbol
== NULL
285 && the_insn
.fi
[0].exp
.X_op_symbol
== NULL
286 && (the_insn
.fi
[0].exp
.X_add_number
< (1 << 16)
287 && the_insn
.fi
[0].exp
.X_add_number
>= 0))
290 /* Emit "$(opcode)h h%const,ireg_src2,r31". */
291 pseudo
[0].opcode
= (the_insn
.opcode
& 0xf3e0ffff) | 0x0c000000
293 pseudo
[0].fi
[0].fup
= (OP_IMM_S16
| OP_SEL_H
);
295 /* Emit "$(opcode) l%const,r31,ireg_dest". */
296 pseudo
[1].opcode
= (the_insn
.opcode
& 0xf01f0000) | 0x04000000
298 pseudo
[1].fi
[0].fup
= (OP_IMM_S16
| OP_SEL_L
);
304 if (the_insn
.fi
[0].exp
.X_add_symbol
== NULL
305 && the_insn
.fi
[0].exp
.X_op_symbol
== NULL
306 && (the_insn
.fi
[0].exp
.X_add_number
< (1 << 16)
307 && the_insn
.fi
[0].exp
.X_add_number
>= 0))
310 /* Emit "andnot h%const,ireg_src2,r31". */
311 pseudo
[0].opcode
= (the_insn
.opcode
& 0x03e0ffff) | 0xd4000000
313 pseudo
[0].fi
[0].fup
= (OP_IMM_S16
| OP_SEL_H
);
314 pseudo
[0].fi
[0].exp
.X_add_number
=
315 -1 - the_insn
.fi
[0].exp
.X_add_number
;
317 /* Emit "andnot l%const,r31,ireg_dest". */
318 pseudo
[1].opcode
= (the_insn
.opcode
& 0x001f0000) | 0xd4000000
320 pseudo
[1].fi
[0].fup
= (OP_IMM_S16
| OP_SEL_L
);
321 pseudo
[1].fi
[0].exp
.X_add_number
=
322 -1 - the_insn
.fi
[0].exp
.X_add_number
;
328 if (the_insn
.fi
[0].exp
.X_add_symbol
== NULL
329 && the_insn
.fi
[0].exp
.X_op_symbol
== NULL
330 && (the_insn
.fi
[0].exp
.X_add_number
< (1 << 15)
331 && the_insn
.fi
[0].exp
.X_add_number
>= -(1 << 15)))
334 /* Emit "orh h%const,r0,r31". */
335 pseudo
[0].opcode
= 0xec000000 | (atmp
<< 16);
336 pseudo
[0].fi
[0].fup
= (OP_IMM_S16
| OP_SEL_H
);
338 /* Emit "or l%const,r31,r31". */
339 pseudo
[1].opcode
= 0xe4000000 | (atmp
<< 21) | (atmp
<< 16);
340 pseudo
[1].fi
[0].fup
= (OP_IMM_S16
| OP_SEL_L
);
342 /* Emit "r31,ireg_src2,ireg_dest". */
343 pseudo
[2].opcode
= (the_insn
.opcode
& ~0x0400ffff) | (atmp
<< 11);
344 pseudo
[2].fi
[0].fup
= OP_IMM_S16
;
350 as_fatal (_("failed sanity check."));
353 the_insn
= pseudo
[0];
355 /* Warn if an opcode is expanded after a delayed branch. */
356 if (num_opcodes
> 1 && last_expand
== 1)
357 as_warn (_("Expanded opcode after delayed branch: `%s'"), str
);
359 /* Warn if an opcode is expanded in dual mode. */
360 if (num_opcodes
> 1 && dual_mode
!= DUAL_OFF
)
361 as_warn (_("Expanded opcode in dual mode: `%s'"), str
);
363 /* Notify if any expansions happen. */
364 if (target_warn_expand
&& num_opcodes
> 1)
365 as_warn (_("An instruction was expanded (%s)"), str
);
373 /* Output the opcode. Note that the i860 always reads instructions
374 as little-endian data. */
375 destp
= frag_more (4);
376 number_to_chars_littleendian (destp
, the_insn
.opcode
, 4);
378 /* Check for expanded opcode after branch or in dual mode. */
379 last_expand
= the_insn
.fi
[0].pcrel
;
381 /* Output the symbol-dependent stuff. Only btne and bte will ever
382 loop more than once here, since only they (possibly) have more
384 for (tmp
= 0; tmp
< fc
; tmp
++)
386 if (the_insn
.fi
[tmp
].fup
!= OP_NONE
)
389 fix
= fix_new_exp (frag_now
,
390 destp
- frag_now
->fr_literal
,
392 &the_insn
.fi
[tmp
].exp
,
393 the_insn
.fi
[tmp
].pcrel
,
394 the_insn
.fi
[tmp
].reloc
);
396 /* Despite the odd name, this is a scratch field. We use
397 it to encode operand type information. */
398 fix
->fx_addnumber
= the_insn
.fi
[tmp
].fup
;
401 the_insn
= pseudo
[++i
];
403 while (--num_opcodes
> 0);
407 /* Assemble the instruction pointed to by STR. */
409 i860_process_insn (char *str
)
414 struct i860_opcode
*insn
;
416 unsigned long opcode
;
421 #if 1 /* For compiler warnings. */
428 for (s
= str
; ISLOWER (*s
) || *s
== '.' || *s
== '3'
429 || *s
== '2' || *s
== '1'; ++s
)
447 as_fatal (_("Unknown opcode: `%s'"), str
);
450 /* Check for dual mode ("d.") opcode prefix. */
451 if (strncmp (str
, "d.", 2) == 0)
453 if (dual_mode
== DUAL_ON
)
454 dual_mode
= DUAL_ONDDOT
;
456 dual_mode
= DUAL_DDOT
;
460 if ((insn
= (struct i860_opcode
*) hash_find (op_hash
, str
)) == NULL
)
462 if (dual_mode
== DUAL_DDOT
|| dual_mode
== DUAL_ONDDOT
)
464 as_bad (_("Unknown opcode: `%s'"), str
);
475 opcode
= insn
->match
;
476 memset (&the_insn
, '\0', sizeof (the_insn
));
478 for (t
= 0; t
< MAX_FIXUPS
; t
++)
480 the_insn
.fi
[t
].reloc
= BFD_RELOC_NONE
;
481 the_insn
.fi
[t
].pcrel
= 0;
482 the_insn
.fi
[t
].fup
= OP_NONE
;
485 /* Build the opcode, checking as we go that the operands match. */
486 for (args
= insn
->args
; ; ++args
)
500 /* These must match exactly. */
510 /* Must be at least one digit. */
520 /* Next operand must be a register. */
524 /* Check for register prefix if necessary. */
525 if (reg_prefix
&& *s
!= reg_prefix
)
552 /* Any register r0..r31. */
555 if (!ISDIGIT (c
= *s
++))
561 if ((c
= 10 * (c
- '0') + (*s
++ - '0')) >= 32)
569 /* Not this opcode. */
574 /* Obtained the register, now place it in the opcode. */
578 opcode
|= mask
<< 11;
582 opcode
|= mask
<< 21;
586 opcode
|= mask
<< 16;
592 /* Next operand is a floating point register. */
596 /* Check for register prefix if necessary. */
597 if (reg_prefix
&& *s
!= reg_prefix
)
602 if (*s
++ == 'f' && ISDIGIT (*s
))
607 mask
= 10 * (mask
- '0') + (*s
++ - '0');
620 opcode
|= mask
<< 11;
624 opcode
|= mask
<< 21;
628 opcode
|= mask
<< 16;
629 if (dual_mode
!= DUAL_OFF
)
631 if (dual_mode
== DUAL_DDOT
)
632 dual_mode
= DUAL_OFF
;
633 if (dual_mode
== DUAL_ONDDOT
)
635 if ((opcode
& (1 << 10)) && mask
!= 0
636 && (mask
== ((opcode
>> 11) & 0x1f)))
637 as_warn (_("Pipelined instruction: fsrc1 = fdest"));
643 /* Next operand must be a control register. */
645 /* Check for register prefix if necessary. */
646 if (reg_prefix
&& *s
!= reg_prefix
)
651 if (strncmp (s
, "fir", 3) == 0)
657 if (strncmp (s
, "psr", 3) == 0)
663 if (strncmp (s
, "dirbase", 7) == 0)
669 if (strncmp (s
, "db", 2) == 0)
675 if (strncmp (s
, "fsr", 3) == 0)
681 if (strncmp (s
, "epsr", 4) == 0)
687 /* The remaining control registers are XP only. */
688 if (target_xp
&& strncmp (s
, "bear", 4) == 0)
694 if (target_xp
&& strncmp (s
, "ccr", 3) == 0)
700 if (target_xp
&& strncmp (s
, "p0", 2) == 0)
706 if (target_xp
&& strncmp (s
, "p1", 2) == 0)
712 if (target_xp
&& strncmp (s
, "p2", 2) == 0)
718 if (target_xp
&& strncmp (s
, "p3", 2) == 0)
726 /* 5-bit immediate in src1. */
728 if (! i860_get_expression (s
))
731 the_insn
.fi
[fc
].fup
|= OP_IMM_U5
;
737 /* 26-bit immediate, relative branch (lbroff). */
739 the_insn
.fi
[fc
].pcrel
= 1;
740 the_insn
.fi
[fc
].fup
|= OP_IMM_BR26
;
743 /* 16-bit split immediate, relative branch (sbroff). */
745 the_insn
.fi
[fc
].pcrel
= 1;
746 the_insn
.fi
[fc
].fup
|= OP_IMM_BR16
;
749 /* 16-bit split immediate. */
751 the_insn
.fi
[fc
].fup
|= OP_IMM_SPLIT16
;
754 /* 16-bit split immediate, byte aligned (st.b). */
756 the_insn
.fi
[fc
].fup
|= OP_IMM_SPLIT16
;
759 /* 16-bit split immediate, half-word aligned (st.s). */
761 the_insn
.fi
[fc
].fup
|= (OP_IMM_SPLIT16
| OP_ENCODE1
| OP_ALIGN2
);
764 /* 16-bit split immediate, word aligned (st.l). */
766 the_insn
.fi
[fc
].fup
|= (OP_IMM_SPLIT16
| OP_ENCODE1
| OP_ALIGN4
);
769 /* 16-bit immediate. */
771 the_insn
.fi
[fc
].fup
|= OP_IMM_S16
;
774 /* 16-bit immediate, byte aligned (ld.b). */
776 the_insn
.fi
[fc
].fup
|= OP_IMM_S16
;
779 /* 16-bit immediate, half-word aligned (ld.s). */
781 the_insn
.fi
[fc
].fup
|= (OP_IMM_S16
| OP_ENCODE1
| OP_ALIGN2
);
784 /* 16-bit immediate, word aligned (ld.l, {p}fld.l, fst.l). */
786 if (insn
->name
[0] == 'l')
787 the_insn
.fi
[fc
].fup
|= (OP_IMM_S16
| OP_ENCODE1
| OP_ALIGN4
);
789 the_insn
.fi
[fc
].fup
|= (OP_IMM_S16
| OP_ENCODE2
| OP_ALIGN4
);
792 /* 16-bit immediate, double-word aligned ({p}fld.d, fst.d). */
794 the_insn
.fi
[fc
].fup
|= (OP_IMM_S16
| OP_ENCODE3
| OP_ALIGN8
);
797 /* 16-bit immediate, quad-word aligned (fld.q, fst.q). */
799 the_insn
.fi
[fc
].fup
|= (OP_IMM_S16
| OP_ENCODE3
| OP_ALIGN16
);
803 /* Handle the immediate for either the Intel syntax or
804 SVR4 syntax. The Intel syntax is "ha%immediate"
805 whereas SVR4 syntax is "[immediate]@ha". */
811 /* Note that if i860_get_expression() fails, we will still
812 have created U entries in the symbol table for the
813 'symbols' in the input string. Try not to create U
814 symbols for registers, etc. */
815 if (! i860_get_expression (s
))
820 if (strncmp (s
, "@ha", 3) == 0)
822 the_insn
.fi
[fc
].fup
|= OP_SEL_HA
;
825 else if (strncmp (s
, "@h", 2) == 0)
827 the_insn
.fi
[fc
].fup
|= OP_SEL_H
;
830 else if (strncmp (s
, "@l", 2) == 0)
832 the_insn
.fi
[fc
].fup
|= OP_SEL_L
;
835 else if (strncmp (s
, "@gotoff", 7) == 0
836 || strncmp (s
, "@GOTOFF", 7) == 0)
838 as_bad (_("Assembler does not yet support PIC"));
839 the_insn
.fi
[fc
].fup
|= OP_SEL_GOTOFF
;
842 else if (strncmp (s
, "@got", 4) == 0
843 || strncmp (s
, "@GOT", 4) == 0)
845 as_bad (_("Assembler does not yet support PIC"));
846 the_insn
.fi
[fc
].fup
|= OP_SEL_GOT
;
849 else if (strncmp (s
, "@plt", 4) == 0
850 || strncmp (s
, "@PLT", 4) == 0)
852 as_bad (_("Assembler does not yet support PIC"));
853 the_insn
.fi
[fc
].fup
|= OP_SEL_PLT
;
857 the_insn
.expand
= insn
->expand
;
861 #else /* ! SYNTAX_SVR4 */
864 if (strncmp (s
, "ha%", 3) == 0)
866 the_insn
.fi
[fc
].fup
|= OP_SEL_HA
;
869 else if (strncmp (s
, "h%", 2) == 0)
871 the_insn
.fi
[fc
].fup
|= OP_SEL_H
;
874 else if (strncmp (s
, "l%", 2) == 0)
876 the_insn
.fi
[fc
].fup
|= OP_SEL_L
;
879 the_insn
.expand
= insn
->expand
;
881 /* Note that if i860_get_expression() fails, we will still
882 have created U entries in the symbol table for the
883 'symbols' in the input string. Try not to create U
884 symbols for registers, etc. */
885 if (! i860_get_expression (s
))
892 #endif /* SYNTAX_SVR4 */
896 as_fatal (_("failed sanity check."));
903 /* Args don't match. */
904 if (insn
[1].name
!= NULL
905 && ! strcmp (insn
->name
, insn
[1].name
))
913 as_bad (_("Illegal operands for %s"), insn
->name
);
920 the_insn
.opcode
= opcode
;
922 /* Only recognize XP instructions when the user has requested it. */
923 if (insn
->expand
== XP_ONLY
&& ! target_xp
)
924 as_bad (_("Unknown opcode: `%s'"), insn
->name
);
928 i860_get_expression (char *str
)
933 save_in
= input_line_pointer
;
934 input_line_pointer
= str
;
935 seg
= expression (&the_insn
.fi
[fc
].exp
);
936 if (seg
!= absolute_section
937 && seg
!= undefined_section
938 && ! SEG_NORMAL (seg
))
940 the_insn
.error
= _("bad segment");
941 expr_end
= input_line_pointer
;
942 input_line_pointer
= save_in
;
945 expr_end
= input_line_pointer
;
946 input_line_pointer
= save_in
;
950 /* Turn a string in input_line_pointer into a floating point constant of
951 type TYPE, and store the appropriate bytes in *LITP. The number of
952 LITTLENUMS emitted is stored in *SIZEP. An error message is returned,
955 /* Equal to MAX_PRECISION in atof-ieee.c. */
956 #define MAX_LITTLENUMS 6
959 md_atof (int type
, char *litP
, int *sizeP
)
962 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
963 LITTLENUM_TYPE
*wordP
;
994 return _("Bad call to MD_ATOF()");
996 t
= atof_ieee (input_line_pointer
, type
, words
);
998 input_line_pointer
= t
;
999 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1000 for (wordP
= words
; prec
--;)
1002 md_number_to_chars (litP
, (long) (*wordP
++), sizeof (LITTLENUM_TYPE
));
1003 litP
+= sizeof (LITTLENUM_TYPE
);
1008 /* Write out in current endian mode. */
1010 md_number_to_chars (char *buf
, valueT val
, int n
)
1012 if (target_big_endian
)
1013 number_to_chars_bigendian (buf
, val
, n
);
1015 number_to_chars_littleendian (buf
, val
, n
);
1018 /* This should never be called for i860. */
1020 md_estimate_size_before_relax (register fragS
*fragP ATTRIBUTE_UNUSED
,
1021 segT segtype ATTRIBUTE_UNUSED
)
1023 as_fatal (_("i860_estimate_size_before_relax\n"));
1028 print_insn (struct i860_it
*insn
)
1031 fprintf (stderr
, "ERROR: %s\n", insn
->error
);
1033 fprintf (stderr
, "opcode = 0x%08lx\t", insn
->opcode
);
1034 fprintf (stderr
, "expand = 0x%x\t", insn
->expand
);
1035 fprintf (stderr
, "reloc = %s\t\n",
1036 bfd_get_reloc_code_name (insn
->reloc
));
1037 fprintf (stderr
, "exp = {\n");
1038 fprintf (stderr
, "\t\tX_add_symbol = %s\n",
1039 insn
->exp
.X_add_symbol
?
1040 (S_GET_NAME (insn
->exp
.X_add_symbol
) ?
1041 S_GET_NAME (insn
->exp
.X_add_symbol
) : "???") : "0");
1042 fprintf (stderr
, "\t\tX_op_symbol = %s\n",
1043 insn
->exp
.X_op_symbol
?
1044 (S_GET_NAME (insn
->exp
.X_op_symbol
) ?
1045 S_GET_NAME (insn
->exp
.X_op_symbol
) : "???") : "0");
1046 fprintf (stderr
, "\t\tX_add_number = %lx\n",
1047 insn
->exp
.X_add_number
);
1048 fprintf (stderr
, "}\n");
1050 #endif /* DEBUG_I860 */
1054 const char *md_shortopts
= "VQ:";
1056 const char *md_shortopts
= "";
1059 #define OPTION_EB (OPTION_MD_BASE + 0)
1060 #define OPTION_EL (OPTION_MD_BASE + 1)
1061 #define OPTION_WARN_EXPAND (OPTION_MD_BASE + 2)
1062 #define OPTION_XP (OPTION_MD_BASE + 3)
1064 struct option md_longopts
[] = {
1065 { "EB", no_argument
, NULL
, OPTION_EB
},
1066 { "EL", no_argument
, NULL
, OPTION_EL
},
1067 { "mwarn-expand", no_argument
, NULL
, OPTION_WARN_EXPAND
},
1068 { "mxp", no_argument
, NULL
, OPTION_XP
},
1069 { NULL
, no_argument
, NULL
, 0 }
1071 size_t md_longopts_size
= sizeof (md_longopts
);
1074 md_parse_option (int c
, char *arg ATTRIBUTE_UNUSED
)
1079 target_big_endian
= 1;
1083 target_big_endian
= 0;
1086 case OPTION_WARN_EXPAND
:
1087 target_warn_expand
= 1;
1095 /* SVR4 argument compatibility (-V): print version ID. */
1097 print_version_id ();
1100 /* SVR4 argument compatibility (-Qy, -Qn): controls whether
1101 a .comment section should be emitted or not (ignored). */
1114 md_show_usage (FILE *stream
)
1116 fprintf (stream
, _("\
1117 -EL generate code for little endian mode (default)\n\
1118 -EB generate code for big endian mode\n\
1119 -mwarn-expand warn if pseudo operations are expanded\n\
1120 -mxp enable i860XP support (disabled by default)\n"));
1122 /* SVR4 compatibility flags. */
1123 fprintf (stream
, _("\
1124 -V print assembler version number\n\
1125 -Qy, -Qn ignored\n"));
1130 /* We have no need to default values of symbols. */
1132 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
1137 /* The i860 denotes auto-increment with '++'. */
1139 md_operand (expressionS
*exp
)
1143 for (s
= input_line_pointer
; *s
; s
++)
1145 if (s
[0] == '+' && s
[1] == '+')
1147 input_line_pointer
+= 2;
1148 exp
->X_op
= O_register
;
1154 /* Round up a section size to the appropriate boundary. */
1156 md_section_align (segT segment ATTRIBUTE_UNUSED
,
1157 valueT size ATTRIBUTE_UNUSED
)
1159 /* Byte alignment is fine. */
1163 /* On the i860, a PC-relative offset is relative to the address of the
1164 of the offset plus its size. */
1166 md_pcrel_from (fixS
*fixP
)
1168 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1171 /* Determine the relocation needed for non PC-relative 16-bit immediates.
1172 Also adjust the given immediate as necessary. Finally, check that
1173 all constraints (such as alignment) are satisfied. */
1174 static bfd_reloc_code_real_type
1175 obtain_reloc_for_imm16 (fixS
*fix
, long *val
)
1177 valueT fup
= fix
->fx_addnumber
;
1178 bfd_reloc_code_real_type reloc
;
1183 /* Check alignment restrictions. */
1184 if ((fup
& OP_ALIGN2
) && (*val
& 0x1))
1185 as_bad_where (fix
->fx_file
, fix
->fx_line
,
1186 _("This immediate requires 0 MOD 2 alignment"));
1187 else if ((fup
& OP_ALIGN4
) && (*val
& 0x3))
1188 as_bad_where (fix
->fx_file
, fix
->fx_line
,
1189 _("This immediate requires 0 MOD 4 alignment"));
1190 else if ((fup
& OP_ALIGN8
) && (*val
& 0x7))
1191 as_bad_where (fix
->fx_file
, fix
->fx_line
,
1192 _("This immediate requires 0 MOD 8 alignment"));
1193 else if ((fup
& OP_ALIGN16
) && (*val
& 0xf))
1194 as_bad_where (fix
->fx_file
, fix
->fx_line
,
1195 _("This immediate requires 0 MOD 16 alignment"));
1197 if (fup
& OP_SEL_HA
)
1199 *val
= (*val
>> 16) + (*val
& 0x8000 ? 1 : 0);
1200 reloc
= BFD_RELOC_860_HIGHADJ
;
1202 else if (fup
& OP_SEL_H
)
1205 reloc
= BFD_RELOC_860_HIGH
;
1207 else if (fup
& OP_SEL_L
)
1210 if (fup
& OP_IMM_SPLIT16
)
1212 if (fup
& OP_ENCODE1
)
1215 reloc
= BFD_RELOC_860_SPLIT1
;
1217 else if (fup
& OP_ENCODE2
)
1220 reloc
= BFD_RELOC_860_SPLIT2
;
1225 reloc
= BFD_RELOC_860_SPLIT0
;
1230 if (fup
& OP_ENCODE1
)
1233 reloc
= BFD_RELOC_860_LOW1
;
1235 else if (fup
& OP_ENCODE2
)
1238 reloc
= BFD_RELOC_860_LOW2
;
1240 else if (fup
& OP_ENCODE3
)
1243 reloc
= BFD_RELOC_860_LOW3
;
1248 reloc
= BFD_RELOC_860_LOW0
;
1252 /* Preserve size encode bits. */
1253 *val
&= ~((1 << num_encode
) - 1);
1257 /* No selector. What reloc do we generate (???)? */
1258 reloc
= BFD_RELOC_32
;
1264 /* Attempt to simplify or eliminate a fixup. To indicate that a fixup
1265 has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL,
1266 we will have to generate a reloc entry. */
1269 md_apply_fix3 (fixS
*fix
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
1276 buf
= fix
->fx_frag
->fr_literal
+ fix
->fx_where
;
1278 /* Recall that earlier we stored the opcode little-endian. */
1279 insn
= bfd_getl32 (buf
);
1281 /* We stored a fix-up in this oddly-named scratch field. */
1282 fup
= fix
->fx_addnumber
;
1284 /* Determine the necessary relocations as well as inserting an
1285 immediate into the instruction. */
1286 if (fup
& OP_IMM_U5
)
1289 as_bad_where (fix
->fx_file
, fix
->fx_line
,
1290 _("5-bit immediate too large"));
1292 as_bad_where (fix
->fx_file
, fix
->fx_line
,
1293 _("5-bit field must be absolute"));
1295 insn
|= (val
& 0x1f) << 11;
1296 bfd_putl32 (insn
, buf
);
1297 fix
->fx_r_type
= BFD_RELOC_NONE
;
1300 else if (fup
& OP_IMM_S16
)
1302 fix
->fx_r_type
= obtain_reloc_for_imm16 (fix
, &val
);
1304 /* Insert the immediate. */
1309 insn
|= val
& 0xffff;
1310 bfd_putl32 (insn
, buf
);
1311 fix
->fx_r_type
= BFD_RELOC_NONE
;
1315 else if (fup
& OP_IMM_U16
)
1318 else if (fup
& OP_IMM_SPLIT16
)
1320 fix
->fx_r_type
= obtain_reloc_for_imm16 (fix
, &val
);
1322 /* Insert the immediate. */
1327 insn
|= val
& 0x7ff;
1328 insn
|= (val
& 0xf800) << 5;
1329 bfd_putl32 (insn
, buf
);
1330 fix
->fx_r_type
= BFD_RELOC_NONE
;
1334 else if (fup
& OP_IMM_BR16
)
1337 as_bad_where (fix
->fx_file
, fix
->fx_line
,
1338 _("A branch offset requires 0 MOD 4 alignment"));
1342 /* Insert the immediate. */
1346 fix
->fx_r_type
= BFD_RELOC_860_PC16
;
1350 insn
|= (val
& 0x7ff);
1351 insn
|= ((val
& 0xf800) << 5);
1352 bfd_putl32 (insn
, buf
);
1353 fix
->fx_r_type
= BFD_RELOC_NONE
;
1357 else if (fup
& OP_IMM_BR26
)
1360 as_bad_where (fix
->fx_file
, fix
->fx_line
,
1361 _("A branch offset requires 0 MOD 4 alignment"));
1365 /* Insert the immediate. */
1368 fix
->fx_r_type
= BFD_RELOC_860_PC26
;
1373 insn
|= (val
& 0x3ffffff);
1374 bfd_putl32 (insn
, buf
);
1375 fix
->fx_r_type
= BFD_RELOC_NONE
;
1379 else if (fup
!= OP_NONE
)
1381 as_bad_where (fix
->fx_file
, fix
->fx_line
,
1382 _("Unrecognized fix-up (0x%08lx)"), (unsigned long) fup
);
1387 /* I believe only fix-ups such as ".long .ep.main-main+0xc8000000"
1388 reach here (???). */
1391 fix
->fx_r_type
= BFD_RELOC_32
;
1396 insn
|= (val
& 0xffffffff);
1397 bfd_putl32 (insn
, buf
);
1398 fix
->fx_r_type
= BFD_RELOC_NONE
;
1404 /* Generate a machine dependent reloc from a fixup. */
1406 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
,
1411 reloc
= xmalloc (sizeof (*reloc
));
1412 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1413 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1414 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1415 reloc
->addend
= fixp
->fx_offset
;
1416 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1420 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1421 "Cannot represent %s relocation in object file",
1422 bfd_get_reloc_code_name (fixp
->fx_r_type
));