aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2004-07-27 11:37:12 +0000
committerNick Clifton <nickc@redhat.com>2004-07-27 11:37:12 +0000
commit670ec21de99faddc3a86f9e18fb9ef1a093b3dbf (patch)
treed809163639cab84dd83ef7b8229321767c541388 /gas
parent575eebb19f60c85a0e4973dfa9e2f8b1a197005a (diff)
downloadfsf-binutils-gdb-670ec21de99faddc3a86f9e18fb9ef1a093b3dbf.zip
fsf-binutils-gdb-670ec21de99faddc3a86f9e18fb9ef1a093b3dbf.tar.gz
fsf-binutils-gdb-670ec21de99faddc3a86f9e18fb9ef1a093b3dbf.tar.bz2
Add CRX insns: pushx, popx
Add support to GAS for expressions which are the difference of two symbols
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog8
-rw-r--r--gas/config/obj-coff.c2
-rw-r--r--gas/config/tc-crx.c73
-rw-r--r--gas/config/tc-crx.h8
-rw-r--r--gas/config/tc-ppc.c9
-rw-r--r--gas/testsuite/ChangeLog4
-rw-r--r--gas/testsuite/gas/all/gas.exp3
-rw-r--r--gas/testsuite/gas/macros/strings.s1
8 files changed, 89 insertions, 19 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 70bf40c..7fa3398 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,4 +1,10 @@
-2004-07-26 H.J. Lu <hongjiu.lu@intel.com>
+2004-07-27 Tomer Levi <Tomer.Levi@nsc.com>
+
+ * config/tc-crx.c: Support evaluating the difference between two
+ symbols.
+ * config/tc-crx.h: Likewise.
+
+ 2004-07-26 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-ia64.c (start_unwind_section): Set the linked-to
section.
diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c
index ee37b08..1451d9d 100644
--- a/gas/config/obj-coff.c
+++ b/gas/config/obj-coff.c
@@ -1327,7 +1327,7 @@ coff_frob_symbol (symp, punt)
order to call SA_SET_SYM_ENDNDX correctly. */
if (! symbol_used_in_reloc_p (symp)
&& ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
- || (! S_IS_EXTERNAL (symp)
+ || (! (S_IS_EXTERNAL (symp) || S_IS_WEAK (symp))
&& ! symbol_get_tc (symp)->output
&& S_GET_STORAGE_CLASS (symp) != C_FILE)))
*punt = 1;
diff --git a/gas/config/tc-crx.c b/gas/config/tc-crx.c
index 3b3c49e..3062118 100644
--- a/gas/config/tc-crx.c
+++ b/gas/config/tc-crx.c
@@ -292,6 +292,34 @@ reset_vars (char *op, ins *crx_ins)
strcpy (ins_parse, op);
}
+/* This macro decides whether a particular reloc is an entry in a
+ switch table. It is used when relaxing, because the linker needs
+ to know about all such entries so that it can adjust them if
+ necessary. */
+
+#define SWITCH_TABLE(fix) \
+ ( (fix)->fx_addsy != NULL \
+ && (fix)->fx_subsy != NULL \
+ && S_GET_SEGMENT ((fix)->fx_addsy) == \
+ S_GET_SEGMENT ((fix)->fx_subsy) \
+ && S_GET_SEGMENT (fix->fx_addsy) != undefined_section \
+ && ( (fix)->fx_r_type == BFD_RELOC_CRX_NUM8 \
+ || (fix)->fx_r_type == BFD_RELOC_CRX_NUM16 \
+ || (fix)->fx_r_type == BFD_RELOC_CRX_NUM32))
+
+/* See whether we need to force a relocation into the output file.
+ This is used to force out switch and PC relative relocations when
+ relaxing. */
+
+int
+crx_force_relocation (fixS *fix)
+{
+ if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
+ return 1;
+
+ return 0;
+}
+
/* Generate a relocation entry for a fixup. */
arelent *
@@ -306,15 +334,42 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
reloc->addend = fixP->fx_offset;
if (fixP->fx_subsy != NULL)
- /* We don't resolve difference expressions. */
- as_bad_where (fixP->fx_file, fixP->fx_line,
- _("can't resolve `%s' {%s section} - `%s' {%s section}"),
- fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0",
- segment_name (fixP->fx_addsy
- ? S_GET_SEGMENT (fixP->fx_addsy)
- : absolute_section),
- S_GET_NAME (fixP->fx_subsy),
- segment_name (S_GET_SEGMENT (fixP->fx_addsy)));
+ {
+ if (SWITCH_TABLE (fixP))
+ {
+ /* Keep the current difference in the addend. */
+ reloc->addend = (S_GET_VALUE (fixP->fx_addsy)
+ - S_GET_VALUE (fixP->fx_subsy) + fixP->fx_offset);
+
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_CRX_NUM8:
+ fixP->fx_r_type = BFD_RELOC_CRX_SWITCH8;
+ break;
+ case BFD_RELOC_CRX_NUM16:
+ fixP->fx_r_type = BFD_RELOC_CRX_SWITCH16;
+ break;
+ case BFD_RELOC_CRX_NUM32:
+ fixP->fx_r_type = BFD_RELOC_CRX_SWITCH32;
+ break;
+ default:
+ abort ();
+ break;
+ }
+ }
+ else
+ {
+ /* We only resolve difference expressions in the same section. */
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("can't resolve `%s' {%s section} - `%s' {%s section}"),
+ fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0",
+ segment_name (fixP->fx_addsy
+ ? S_GET_SEGMENT (fixP->fx_addsy)
+ : absolute_section),
+ S_GET_NAME (fixP->fx_subsy),
+ segment_name (S_GET_SEGMENT (fixP->fx_addsy)));
+ }
+ }
assert ((int) fixP->fx_r_type > 0);
reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
diff --git a/gas/config/tc-crx.h b/gas/config/tc-crx.h
index dc26a70..29e59fe 100644
--- a/gas/config/tc-crx.h
+++ b/gas/config/tc-crx.h
@@ -48,6 +48,10 @@ extern const struct relax_type md_relax_table[];
linker relaxations easier. */
#define tc_fix_adjustable(fixP) 0
+/* We need to force out some relocations when relaxing. */
+#define TC_FORCE_RELOCATION(FIXP) crx_force_relocation (FIXP)
+extern int crx_force_relocation (struct fix *);
+
/* Fixup debug sections since we will never relax them. */
#define TC_LINKRELAX_FIXUP(seg) (seg->flags & SEC_ALLOC)
@@ -58,8 +62,8 @@ extern const struct relax_type md_relax_table[];
/* This is called by emit_expr when creating a reloc for a cons.
We could use the definition there, except that we want to handle
the CRX reloc type specially, rather than the BFD_RELOC type. */
-#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) \
- fix_new_exp (FRAG, OFF, (int)LEN, EXP, 0, \
+#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP) \
+ fix_new_exp (FRAG, OFF, (int) LEN, EXP, 0, \
LEN == 1 ? BFD_RELOC_CRX_NUM8 \
: LEN == 2 ? BFD_RELOC_CRX_NUM16 \
: LEN == 4 ? BFD_RELOC_CRX_NUM32 \
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index d4893e7..7bc7011 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -1918,9 +1918,8 @@ ppc_frob_file_before_adjust ()
free (dotname);
if (dotsym != NULL && (symbol_used_p (dotsym)
|| symbol_used_in_reloc_p (dotsym)))
- {
- symbol_mark_used (symp);
- }
+ symbol_mark_used (symp);
+
}
/* Don't emit .TOC. symbol. */
@@ -4843,7 +4842,7 @@ ppc_frob_symbol (sym)
table. */
if (! symbol_used_in_reloc_p (sym)
&& ((symbol_get_bfdsym (sym)->flags & BSF_SECTION_SYM) != 0
- || (! S_IS_EXTERNAL (sym)
+ || (! (S_IS_EXTERNAL (sym) || S_IS_WEAK (sym))
&& ! symbol_get_tc (sym)->output
&& S_GET_STORAGE_CLASS (sym) != C_FILE)))
return 1;
@@ -4909,7 +4908,7 @@ ppc_frob_symbol (sym)
}
}
- if (! S_IS_EXTERNAL (sym)
+ if (! (S_IS_EXTERNAL (sym) || S_IS_WEAK (sym))
&& (symbol_get_bfdsym (sym)->flags & BSF_SECTION_SYM) == 0
&& S_GET_STORAGE_CLASS (sym) != C_FILE
&& S_GET_STORAGE_CLASS (sym) != C_FCN
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 77428e4..13815bb 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2004-07-27 Tomer Levi <Tomer.Levi@nsc.com>
+
+ * gas/all/gas.exp (do_930509a): Disable test for crx.
+
2004-07-22 H.J. Lu <hongjiu.lu@intel.com>
* gas/i386/x86-64-inval.l: Remove the leading `+'.
diff --git a/gas/testsuite/gas/all/gas.exp b/gas/testsuite/gas/all/gas.exp
index 31cfa4e..df8d71d 100644
--- a/gas/testsuite/gas/all/gas.exp
+++ b/gas/testsuite/gas/all/gas.exp
@@ -85,12 +85,13 @@ proc do_930509a {} {
if !$x then { fail $testname }
}
-# This test is meaningless for the PA; the difference of two symbols
+# This test is meaningless for the PA and CRX; the difference of two symbols
# must not be resolved by the assembler.
# C54x assembler (for compatibility) does not allow differences between
# forward references
# C30 counts a four byte offset as a difference of one.
if { ![istarget hppa*-*-*] &&
+ ![istarget crx*-*-*] &&
![istarget *c30*-*-*] &&
![istarget *c4x*-*-*] &&
![istarget *c54x*-*-*] } then {
diff --git a/gas/testsuite/gas/macros/strings.s b/gas/testsuite/gas/macros/strings.s
index 291a0dc..9e98c85 100644
--- a/gas/testsuite/gas/macros/strings.s
+++ b/gas/testsuite/gas/macros/strings.s
@@ -1,3 +1,4 @@
+#NO_APP
.macro M arg1
.ascii "\arg1"
.endm