+2008-09-19 Alan Modra <amodra@bigpond.net.au>
+
+ * write.c (md_register_arithmetic): Define.
+ (fixup_segment): Adjust TC_FORCE_RELOCATION_SUB_ABS invocation.
+ Modify error message when registers involved.
+ (TC_FORCE_RELOCATION_SUB_ABS): Heed md_register_arithmetic.
+ * config/tc-sh.h (TC_FORCE_RELOCATION_SUB_ABS): Likewise.
+
2008-09-15 Alan Modra <amodra@bigpond.net.au>
* write.c (install_reloc): Correct EMIT_SECTION_SYMBOLS test.
/* This keeps the subtracted symbol around, for use by PLT_PCREL
relocs. */
-#define TC_FORCE_RELOCATION_SUB_ABS(FIX) \
- ((FIX)->fx_r_type == BFD_RELOC_32_PLT_PCREL)
+#define TC_FORCE_RELOCATION_SUB_ABS(FIX, SEG) \
+ ((FIX)->fx_r_type == BFD_RELOC_32_PLT_PCREL \
+ || (!md_register_arithmetic && (SEG) == reg_section))
/* Don't complain when we leave fx_subsy around. */
#undef TC_VALIDATE_FIX_SUB
(! SEG_NORMAL (SEG))
#endif
+#ifndef md_register_arithmetic
+# define md_register_arithmetic 1
+#endif
+
#ifndef TC_FORCE_RELOCATION_SUB_ABS
-#define TC_FORCE_RELOCATION_SUB_ABS(FIX) 0
+#define TC_FORCE_RELOCATION_SUB_ABS(FIX, SEG) \
+ (!md_register_arithmetic && (SEG) == reg_section)
#endif
#ifndef TC_FORCE_RELOCATION_SUB_LOCAL
#endif
}
else if (sub_symbol_segment == absolute_section
- && !TC_FORCE_RELOCATION_SUB_ABS (fixP))
+ && !TC_FORCE_RELOCATION_SUB_ABS (fixP, add_symbol_segment))
{
add_number -= S_GET_VALUE (fixP->fx_subsy);
fixP->fx_offset = add_number;
}
else if (!TC_VALIDATE_FIX_SUB (fixP))
{
- 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 (add_symbol_segment),
- S_GET_NAME (fixP->fx_subsy),
- segment_name (sub_symbol_segment));
+ if (!md_register_arithmetic
+ && (add_symbol_segment == reg_section
+ || sub_symbol_segment == reg_section))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("register value used as expression"));
+ else
+ 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 (add_symbol_segment),
+ S_GET_NAME (fixP->fx_subsy),
+ segment_name (sub_symbol_segment));
}
}