aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2012-07-03 13:58:12 +0200
committerUros Bizjak <uros@gcc.gnu.org>2012-07-03 13:58:12 +0200
commit19d7dc0dfadb205e6ab119f930a42732e2787686 (patch)
tree8289a420b95ae310df243f25e137487982be9460
parent1fcd23ac0dc27ed94b8cf1fe00f5b7b4c3fb9c64 (diff)
downloadgcc-19d7dc0dfadb205e6ab119f930a42732e2787686.zip
gcc-19d7dc0dfadb205e6ab119f930a42732e2787686.tar.gz
gcc-19d7dc0dfadb205e6ab119f930a42732e2787686.tar.bz2
re PR target/53811 (ICE: in insn_default_length, at config/i386/i386.md:529 (unrecognizable insn) with -mcmodel=large)
PR target/53811 * config/i386/i386.c (x86_output_mi_thunk): Check if fnaddr satisfies sibcall_insn_operand. Move it to a temporary register if not. testsuite/ChangLog: PR target/53811 * g++.dg/other/pr53811.C: New test. From-SVN: r189218
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/i386.c34
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/other/pr53811.C29
4 files changed, 62 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 76a6585..52be9ec 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2012-07-03 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/53811
+ * config/i386/i386.c (x86_output_mi_thunk): Check if fnaddr satisfies
+ sibcall_insn_operand. Move it to a temporary register if not.
+
2012-07-03 Andreas Schwab <schwab@linux-m68k.org>
PR target/28896
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index aae8a4d..1a95ca4 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -32931,6 +32931,18 @@ x86_output_mi_thunk (FILE *file,
{
rtx this_param = x86_this_parameter (function);
rtx this_reg, tmp, fnaddr;
+ unsigned int tmp_regno;
+
+ if (TARGET_64BIT)
+ tmp_regno = R10_REG;
+ else
+ {
+ unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (function));
+ if ((ccvt & (IX86_CALLCVT_FASTCALL | IX86_CALLCVT_THISCALL)) != 0)
+ tmp_regno = AX_REG;
+ else
+ tmp_regno = CX_REG;
+ }
emit_note (NOTE_INSN_PROLOGUE_END);
@@ -32957,7 +32969,7 @@ x86_output_mi_thunk (FILE *file,
{
if (!x86_64_general_operand (delta_rtx, Pmode))
{
- tmp = gen_rtx_REG (Pmode, R10_REG);
+ tmp = gen_rtx_REG (Pmode, tmp_regno);
emit_move_insn (tmp, delta_rtx);
delta_rtx = tmp;
}
@@ -32970,18 +32982,7 @@ x86_output_mi_thunk (FILE *file,
if (vcall_offset)
{
rtx vcall_addr, vcall_mem, this_mem;
- unsigned int tmp_regno;
- if (TARGET_64BIT)
- tmp_regno = R10_REG;
- else
- {
- unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (function));
- if ((ccvt & (IX86_CALLCVT_FASTCALL | IX86_CALLCVT_THISCALL)) != 0)
- tmp_regno = AX_REG;
- else
- tmp_regno = CX_REG;
- }
tmp = gen_rtx_REG (Pmode, tmp_regno);
this_mem = gen_rtx_MEM (ptr_mode, this_reg);
@@ -33056,6 +33057,15 @@ x86_output_mi_thunk (FILE *file,
emit_jump_insn (gen_indirect_jump (fnaddr));
else
{
+ if (!sibcall_insn_operand (fnaddr, word_mode))
+ {
+ tmp = gen_rtx_REG (word_mode, tmp_regno);
+ if (GET_MODE (fnaddr) != word_mode)
+ fnaddr = gen_rtx_ZERO_EXTEND (word_mode, fnaddr);
+ emit_move_insn (tmp, fnaddr);
+ fnaddr = tmp;
+ }
+
tmp = gen_rtx_MEM (QImode, fnaddr);
tmp = gen_rtx_CALL (VOIDmode, tmp, const0_rtx);
tmp = emit_call_insn (tmp);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 671d5c1..3d51a0c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2012-07-03 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/53811
+ * g++.dg/other/pr53811.C: New test.
+
2012-07-03 Andreas Schwab <schwab@linux-m68k.org>
PR target/28896
diff --git a/gcc/testsuite/g++.dg/other/pr53811.C b/gcc/testsuite/g++.dg/other/pr53811.C
new file mode 100644
index 0000000..c00b7f6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/pr53811.C
@@ -0,0 +1,29 @@
+// { dg-do compile }
+// { dg-options "-mcmodel=large" { target { { i?86-*-* x86_64-*-* } && lp64 } } }
+
+struct ICCStringClass
+{
+ virtual void *
+ CreateString (const char *fromText) = 0;
+};
+
+struct AGSCCDynamicObject
+{
+ virtual void
+ Unserialize (int index, const char *serializedData, int dataSize) = 0;
+};
+
+
+struct ScriptString:AGSCCDynamicObject, ICCStringClass
+{
+ virtual void *CreateString (const char *fromText);
+};
+
+const char *
+CreateNewScriptString (const char *fromText, bool reAllocate = true);
+
+void *
+ScriptString::CreateString (const char *fromText)
+{
+ return (void *) CreateNewScriptString (fromText);
+}