summaryrefslogtreecommitdiff
path: root/gas/config/tc-i960.c
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1999-05-27 21:57:48 +0000
committerIan Lance Taylor <ian@airs.com>1999-05-27 21:57:48 +0000
commitbedf545c12aa389c181ee2a071d5e10b6da79c9a (patch)
treef8ebc754d437f36e79bea94c51482a550342458f /gas/config/tc-i960.c
parent5379904c275a8bc45f012cc7c9167e1a97ab127f (diff)
downloadbinutils-gdb-bedf545c12aa389c181ee2a071d5e10b6da79c9a.tar.gz
1999-05-28 Martin Dorey <mdorey@madge.com>
* config/tc-i960.c: Several minor changes to add ELF and BFD_ASSEMBLER support. * config/tc-i960.h: Likewise. * configure.in (i960-*-elf*): New target. * aclocal.m4, configure: Rebuild.
Diffstat (limited to 'gas/config/tc-i960.c')
-rw-r--r--gas/config/tc-i960.c154
1 files changed, 145 insertions, 9 deletions
diff --git a/gas/config/tc-i960.c b/gas/config/tc-i960.c
index 936b6621994..a4e8497fc2d 100644
--- a/gas/config/tc-i960.c
+++ b/gas/config/tc-i960.c
@@ -1,5 +1,5 @@
/* tc-i960.c - All the i80960-specific stuff
- Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 1998
+ Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999
Free Software Foundation, Inc.
This file is part of GAS.
@@ -101,7 +101,22 @@
#define TC_S_FORCE_TO_SYSPROC(s) (S_SET_STORAGE_CLASS((s), C_SCALL))
#else /* ! OBJ_COFF */
-you lose;
+#ifdef OBJ_ELF
+#define TC_S_IS_SYSPROC(s) 0
+
+#define TC_S_IS_BALNAME(s) 0
+#define TC_S_IS_CALLNAME(s) 0
+#define TC_S_IS_BADPROC(s) 0
+
+#define TC_S_SET_SYSPROC(s, p)
+#define TC_S_GET_SYSPROC(s) 0
+
+#define TC_S_FORCE_TO_BALNAME(s)
+#define TC_S_FORCE_TO_CALLNAME(s)
+#define TC_S_FORCE_TO_SYSPROC(s)
+#else
+ #error COFF, a.out, b.out, and ELF are the only supported formats.
+#endif /* ! OBJ_ELF */
#endif /* ! OBJ_COFF */
#endif /* ! OBJ_A/BOUT */
@@ -1009,7 +1024,6 @@ md_show_usage (stream)
}
-#ifndef BFD_ASSEMBLER
/*****************************************************************************
md_convert_frag:
Called by base assembler after address relaxation is finished: modify
@@ -1023,11 +1037,19 @@ md_show_usage (stream)
Replace the cobr with a two instructions (a compare and a branch).
*************************************************************************** */
+#ifndef BFD_ASSEMBLER
void
md_convert_frag (headers, seg, fragP)
object_headers *headers;
segT seg;
fragS *fragP;
+#else
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd *abfd;
+ segT sec;
+ fragS *fragP;
+#endif
{
fixS *fixP; /* Structure describing needed address fix */
@@ -1082,6 +1104,7 @@ md_estimate_size_before_relax (fragP, segment_type)
return 0;
} /* md_estimate_size_before_relax() */
+#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
/*****************************************************************************
md_ri_to_chars:
@@ -1096,7 +1119,8 @@ md_estimate_size_before_relax (fragP, segment_type)
does do the reordering (Ian Taylor 28 Aug 92).
*************************************************************************** */
-void
+
+static void
md_ri_to_chars (where, ri)
char *where;
struct relocation_info *ri;
@@ -1114,7 +1138,8 @@ md_ri_to_chars (where, ri)
| (ri->r_callj << 6));
}
-#endif /* BFD_ASSEMBLER */
+#endif /* defined(OBJ_AOUT) | defined(OBJ_BOUT) */
+
/* FOLLOWING ARE THE LOCAL ROUTINES, IN ALPHABETICAL ORDER */
@@ -2819,11 +2844,21 @@ md_pcrel_from (fixP)
return fixP->fx_where + fixP->fx_frag->fr_address;
}
+#ifdef BFD_ASSEMBLER
+int
+md_apply_fix (fixP, valp)
+ fixS *fixP;
+ valueT *valp;
+#else
void
md_apply_fix (fixP, val)
fixS *fixP;
long val;
+#endif
{
+#ifdef BFD_ASSEMBLER
+ long val = *valp;
+#endif
char *place = fixP->fx_where + fixP->fx_frag->fr_literal;
if (!fixP->fx_bit_fixP)
@@ -2833,11 +2868,39 @@ md_apply_fix (fixP, val)
if (fixP->fx_bsr)
val = 0;
+#ifdef OBJ_ELF
+ /* For ELF, we always emit relocations for external or weak
+ symbols. */
+ if (fixP->fx_addsy != NULL
+ && (S_IS_EXTERNAL (fixP->fx_addsy)
+ || S_IS_WEAK (fixP->fx_addsy)))
+ val = 0;
+#endif
+
fixP->fx_addnumber = val;
+
+#ifdef BFD_ASSEMBLER
+ /* HACK: With REL relocations this causes the offset in the code
+ to be doubled.
+
+ Guess: val is the old offset in the code, addnumber gets
+ passed back to md_gen_reloc() where it gets assigned to
+ addend, which the backend then writes back to the code (as
+ we're using REL, not RELA relocations). COFF must be working
+ without this hack, but I don't see how or why.
+
+ apeppere and martindo 22-10-1998. */
+ fixP->fx_addnumber = 0;
+#endif
+
md_number_to_imm (place, val, fixP->fx_size, fixP);
}
else
md_number_to_field (place, val, fixP->fx_bit_fixP);
+
+#ifdef BFD_ASSEMBLER
+ return 0;
+#endif
}
#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
@@ -2937,8 +3000,14 @@ md_section_align (seg, addr)
segT seg;
valueT addr; /* Address to be rounded up */
{
- return ((addr + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg]));
-} /* md_section_align() */
+ int align;
+#ifdef BFD_ASSEMBLER
+ align = bfd_get_section_alignment (stdoutput, seg);
+#else
+ align = section_alignment[(int) seg];
+#endif
+ return (addr + (1 << align) - 1) & (-1 << align);
+}
extern int coff_flags;
@@ -3007,6 +3076,8 @@ tc_headers_hook (headers)
#endif /* OBJ_COFF */
+#ifndef BFD_ASSEMBLER
+
/* Things going on here:
For bout, We need to assure a couple of simplifying
@@ -3066,6 +3137,8 @@ tc_crawl_symbol_chain (headers)
} /* walk the symbol chain */
}
+#endif /* ! BFD_ASSEMBLER */
+
/* For aout or bout, the bal immediately follows the call.
For coff, we cheat and store a pointer to the bal symbol in the
@@ -3105,7 +3178,7 @@ tc_set_bal_of_call (callP, balP)
} /* if not in order */
#else /* ! OBJ_ABOUT */
- (as yet unwritten.);
+ as_fatal ("Only supported for a.out, b.out, or COFF");
#endif /* ! OBJ_ABOUT */
#endif /* ! OBJ_COFF */
}
@@ -3124,7 +3197,7 @@ tc_get_bal_of_call (callP)
#ifdef OBJ_ABOUT
retval = symbol_next (callP);
#else
- (as yet unwritten.);
+ as_fatal ("Only supported for a.out, b.out, or COFF");
#endif /* ! OBJ_ABOUT */
#endif /* ! OBJ_COFF */
@@ -3228,4 +3301,67 @@ i960_validate_fix (fixP, this_segment_type, add_symbolPP)
return 0;
}
+#ifdef BFD_ASSEMBLER
+
+/* From cgen.c: */
+
+static short
+tc_bfd_fix2rtype (fixP)
+ fixS *fixP;
+{
+#if 0
+ if (fixP->fx_bsr)
+ abort ();
+#endif
+
+ if (fixP->fx_pcrel == 0 && fixP->fx_size == 4)
+ return BFD_RELOC_32;
+
+ if (fixP->fx_pcrel != 0 && fixP->fx_size == 4)
+ return BFD_RELOC_24_PCREL;
+
+ abort ();
+ return 0;
+}
+
+/* Translate internal representation of relocation info to BFD target
+ format.
+
+ FIXME: To what extent can we get all relevant targets to use this? */
+
+arelent *
+tc_gen_reloc (section, fixP)
+ asection *section;
+ fixS *fixP;
+{
+ arelent * reloc;
+
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+
+ /* HACK: Is this right? */
+ fixP->fx_r_type = tc_bfd_fix2rtype (fixP);
+
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
+ if (reloc->howto == (reloc_howto_type *) NULL)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ "internal error: can't export reloc type %d (`%s')",
+ fixP->fx_r_type,
+ bfd_get_reloc_code_name (fixP->fx_r_type));
+ return NULL;
+ }
+
+ assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
+
+ reloc->sym_ptr_ptr = &fixP->fx_addsy->bsym;
+ reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
+ reloc->addend = fixP->fx_addnumber;
+
+ return reloc;
+}
+
+/* end from cgen.c */
+
+#endif /* BFD_ASSEMBLER */
+
/* end of tc-i960.c */