From 19d7dc0dfadb205e6ab119f930a42732e2787686 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Tue, 3 Jul 2012 13:58:12 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 +++++ gcc/config/i386/i386.c | 34 ++++++++++++++++++---------- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/other/pr53811.C | 29 ++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/g++.dg/other/pr53811.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 76a65856c9f9..52be9ecf0bcd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-07-03 Uros Bizjak + + 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 PR target/28896 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index aae8a4d58141..1a95ca410fc5 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 671d5c119adf..3d51a0c574fa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-07-03 Uros Bizjak + + PR target/53811 + * g++.dg/other/pr53811.C: New test. + 2012-07-03 Andreas Schwab 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 000000000000..c00b7f6d4dd2 --- /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); +}