This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[mep] check for near-far mismatched VLIW sibcalls
- From: DJ Delorie <dj at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 14 Jul 2009 17:46:19 -0400
- Subject: [mep] check for near-far mismatched VLIW sibcalls
The 24-bit JMP opcode preserves the top four bits of the address, so
it will not work if the *source* of the jump is in a "far" function.
Committed.
* config/mep/mep.c (mep_vliw_jmp_match): New function.
* config/mep/mep-protos.h (mep_vliw_jmp_match): Prototype it.
* config/mep/mep.md (sibcall_internal): Change test from
mep_vliw_mode_match to mep_vliw_jmp_match.
(sibcall_value_internal): Likewise.
Index: config/mep/mep.md
===================================================================
--- config/mep/mep.md (revision 149643)
+++ config/mep/mep.md (working copy)
@@ -1920,13 +1920,13 @@
(use (match_operand:SI 2 "const_int_operand" ""))
(use (reg:SI LP_REGNO))
(clobber (reg:SI REGSAVE_CONTROL_TEMP))
]
"SIBLING_CALL_P (insn)"
{
- if (mep_vliw_mode_match (operands[2]))
+ if (mep_vliw_jmp_match (operands[2]))
return "jmp\t%0";
else
return
"ldc $12, $lp\n\
movh $11, %%hi(%0)\n\
xor3 $12, $12, 1\n\
@@ -1991,13 +1991,13 @@
(use (match_operand:SI 3 "const_int_operand" ""))
(use (reg:SI LP_REGNO))
(clobber (reg:SI REGSAVE_CONTROL_TEMP))
]
"SIBLING_CALL_P (insn)"
{
- if (mep_vliw_mode_match (operands[3]))
+ if (mep_vliw_jmp_match (operands[3]))
return "jmp\t%1";
else
return
"ldc $12, $lp\n\
movh $11, %%hi(%1)\n\
xor3 $12, $12, 1\n\
Index: config/mep/mep-protos.h
===================================================================
--- config/mep/mep-protos.h (revision 149643)
+++ config/mep/mep-protos.h (working copy)
@@ -30,12 +30,13 @@ extern rtx mep_mulr_source (rtx, rtx, rt
extern bool mep_reuse_lo_p (rtx, rtx, rtx, bool);
extern bool mep_use_post_modify_p (rtx, rtx, rtx);
extern bool mep_allow_clip (rtx, rtx, int);
extern bool mep_bit_position_p (rtx, bool);
extern bool mep_split_mov (rtx *, int);
extern bool mep_vliw_mode_match (rtx);
+extern bool mep_vliw_jmp_match (rtx);
extern bool mep_multi_slot (rtx);
extern bool mep_legitimate_address (enum machine_mode, rtx, int);
extern int mep_legitimize_address (rtx *, rtx, enum machine_mode);
#ifdef MAX_RELOADS
extern int mep_legitimize_reload_address (rtx *, enum machine_mode, int, enum reload_type, int);
#endif
Index: config/mep/mep.c
===================================================================
--- config/mep/mep.c (revision 149643)
+++ config/mep/mep.c (working copy)
@@ -1179,12 +1179,26 @@ mep_vliw_mode_match (rtx tgt)
bool src_vliw = mep_vliw_function_p (cfun->decl);
bool tgt_vliw = INTVAL (tgt);
return src_vliw == tgt_vliw;
}
+/* Like the above, but also test for near/far mismatches. */
+
+bool
+mep_vliw_jmp_match (rtx tgt)
+{
+ bool src_vliw = mep_vliw_function_p (cfun->decl);
+ bool tgt_vliw = INTVAL (tgt);
+
+ if (mep_section_tag (DECL_RTL (cfun->decl)) == 'f')
+ return false;
+
+ return src_vliw == tgt_vliw;
+}
+
bool
mep_multi_slot (rtx x)
{
return get_attr_slot (x) == SLOT_MULTI;
}