From: hubicka Date: Sun, 21 Dec 2008 13:28:26 +0000 (+0000) Subject: * i376.md (UNSPEC_MS_TO_SYSV_CALL): New constant. X-Git-Url: http://git.sourceforge.jp/view?a=commitdiff_plain;h=199169a26374c040030691e4d08721a5b1cbd31e;p=pf3gnuchains%2Fgcc-fork.git * i376.md (UNSPEC_MS_TO_SYSV_CALL): New constant. (call_1_rex64_ms_sysv, call_value_0_rex64_ms_sysv, call_value_1_rex64_ms_sysv): New patterns. * i386.c (function_arg_ms_64): Pass magical value of -2 as callarg. (ix86_expand_call): Emit extra clobbers for ms->sysv ABI calls. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@142859 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 98b4531d230..17054a96d0b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2008-12-21 Jan Hubicka + Kai Tietz + + * i376.md (UNSPEC_MS_TO_SYSV_CALL): New constant. + (call_1_rex64_ms_sysv, call_value_0_rex64_ms_sysv, + call_value_1_rex64_ms_sysv): New patterns. + * i386.c (function_arg_ms_64): Pass magical value of -2 as callarg. + (ix86_expand_call): Emit extra clobbers for ms->sysv ABI calls. + 2008-12-21 Uros Bizjak * config/alpha/alpha.c (alpha_pad_noreturn): New static function. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 824a11dc230..bae3f42657a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -5690,9 +5690,10 @@ function_arg_ms_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode, { unsigned int regno; - /* Avoid the AL settings for the Unix64 ABI. */ + /* We need to add clobber for MS_ABI->SYSV ABI calls in expand_call. + We use value of -2 to specify that current function call is MSABI. */ if (mode == VOIDmode) - return constm1_rtx; + return GEN_INT (-2); /* If we've run out of registers, it goes on the stack. */ if (cum->nregs == 0) @@ -18095,11 +18096,16 @@ construct_plt_address (rtx symbol) void ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, - rtx callarg2 ATTRIBUTE_UNUSED, + rtx callarg2, rtx pop, int sibcall) { rtx use = NULL, call; + enum calling_abi function_call_abi; + if (callarg2 && INTVAL (callarg2) == -2) + function_call_abi = MS_ABI; + else + function_call_abi = SYSV_ABI; if (pop == const0_rtx) pop = NULL; gcc_assert (!TARGET_64BIT || !pop); @@ -18155,6 +18161,18 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, pop = gen_rtx_PLUS (Pmode, stack_pointer_rtx, pop); pop = gen_rtx_SET (VOIDmode, stack_pointer_rtx, pop); call = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, call, pop)); + gcc_assert (ix86_cfun_abi () != MS_ABI || function_call_abi != SYSV_ABI); + } + /* We need to represent that SI and DI registers are clobbered by SYSV calls. + */ + if (ix86_cfun_abi () == MS_ABI && function_call_abi == SYSV_ABI) + { + rtx clobber1 = gen_rtx_CLOBBER (DImode, gen_rtx_REG (DImode, SI_REG)); + rtx clobber2 = gen_rtx_CLOBBER (DImode, gen_rtx_REG (DImode, DI_REG)); + rtx unspec = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, const0_rtx), + UNSPEC_MS_TO_SYSV_CALL); + call = gen_rtx_PARALLEL (VOIDmode, + gen_rtvec (4, call, unspec, clobber1, clobber2)); } call = emit_call_insn (call); diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 068738d2296..c7223899b4b 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -105,6 +105,7 @@ (UNSPEC_LFENCE 45) (UNSPEC_PSADBW 46) (UNSPEC_LDDQU 47) + (UNSPEC_MS_TO_SYSV_CALL 48) ; Generic math support (UNSPEC_COPYSIGN 50) @@ -15039,6 +15040,20 @@ } [(set_attr "type" "call")]) +(define_insn "*call_1_rex64_ms_sysv" + [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm")) + (match_operand 1 "" "")) + (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) + (clobber (reg:DI SI_REG)) + (clobber (reg:DI DI_REG))] + "!SIBLING_CALL_P (insn) && TARGET_64BIT" +{ + if (constant_call_address_operand (operands[0], Pmode)) + return "call\t%P0"; + return "call\t%A0"; +} + [(set_attr "type" "call")]) + (define_insn "*call_1_rex64_large" [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm")) (match_operand 1 "" ""))] @@ -21361,6 +21376,22 @@ } [(set_attr "type" "callv")]) +(define_insn "*call_value_0_rex64_ms_sysv" + [(set (match_operand 0 "" "") + (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) + (match_operand:DI 2 "const_int_operand" ""))) + (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) + (clobber (reg:DI SI_REG)) + (clobber (reg:DI DI_REG))] + "!SIBLING_CALL_P (insn) && TARGET_64BIT" +{ + if (SIBLING_CALL_P (insn)) + return "jmp\t%P1"; + else + return "call\t%P1"; +} + [(set_attr "type" "callv")]) + (define_insn "*call_value_1" [(set (match_operand 0 "" "") (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm")) @@ -21398,6 +21429,21 @@ } [(set_attr "type" "callv")]) +(define_insn "*call_value_1_rex64_ms_sysv" + [(set (match_operand 0 "" "") + (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm")) + (match_operand:DI 2 "" ""))) + (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) + (clobber (reg:DI SI_REG)) + (clobber (reg:DI DI_REG))] + "!SIBLING_CALL_P (insn) && TARGET_64BIT" +{ + if (constant_call_address_operand (operands[1], Pmode)) + return "call\t%P1"; + return "call\t%A1"; +} + [(set_attr "type" "callv")]) + (define_insn "*call_value_1_rex64_large" [(set (match_operand 0 "" "") (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))