diff options
author | Uros Bizjak <ubizjak@gmail.com> | 2012-07-03 13:58:12 +0200 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2012-07-03 13:58:12 +0200 |
commit | 19d7dc0dfadb205e6ab119f930a42732e2787686 (patch) | |
tree | 8289a420b95ae310df243f25e137487982be9460 /gcc | |
parent | 1fcd23ac0dc27ed94b8cf1fe00f5b7b4c3fb9c64 (diff) | |
download | gcc-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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 34 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/pr53811.C | 29 |
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); +} |