diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 23 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 30 |
3 files changed, 54 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 21de680..1f7d286 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,12 @@ 2009-01-06 Jan Hubicka <jh@suse.cz> Kai Tietz <kai.tietz@onevision.com> + * i386.md (*msabi_syvabi): Add SSE regs clobbers. + * i386.c (ix86_expand_call): Add clobbers. + +2009-01-06 Jan Hubicka <jh@suse.cz> + Kai Tietz <kai.tietz@onevision.com> + * i386.h (CONDITIONAL_CALL_USAGE): SSE regs are not used for w64 ABI. * i386.c (struct ix86_frame): Add padding0 and nsseregs. (ix86_nsaved_regs): Count only general purpose regs. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 73a717d..91af83a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -18501,16 +18501,29 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, 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. - */ + /* 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)); + static int clobbered_registers[] ={27, 28, 45, 46, 47, 48, 49, 50, 51, 52, SI_REG, DI_REG}; + static const int nclobbered_registers = sizeof (clobbered_registers) / sizeof (int); + int i; + rtx vec[nclobbered_registers + 2]; rtx unspec = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, const0_rtx), UNSPEC_MS_TO_SYSV_CALL); + + vec[0] = call; + vec[1] = unspec; + for (i = 0; i < nclobbered_registers; i++) + vec[i + 2] = gen_rtx_CLOBBER (SSE_REGNO_P (clobbered_registers[i]) + ? TImode : DImode, + gen_rtx_REG + (SSE_REGNO_P (clobbered_registers[i]) + ? TImode : DImode, + clobbered_registers[i])); + call = gen_rtx_PARALLEL (VOIDmode, - gen_rtvec (4, call, unspec, clobber1, clobber2)); + gen_rtvec_v (nclobbered_registers + 2, vec)); } call = emit_call_insn (call); diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index f0bec12..0569f04 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -15043,6 +15043,16 @@ [(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:TI 27)) + (clobber (reg:TI 28)) + (clobber (reg:TI 45)) + (clobber (reg:TI 46)) + (clobber (reg:TI 47)) + (clobber (reg:TI 48)) + (clobber (reg:TI 49)) + (clobber (reg:TI 50)) + (clobber (reg:TI 51)) + (clobber (reg:TI 52)) (clobber (reg:DI SI_REG)) (clobber (reg:DI DI_REG))] "!SIBLING_CALL_P (insn) && TARGET_64BIT" @@ -21380,6 +21390,16 @@ (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:TI 27)) + (clobber (reg:TI 28)) + (clobber (reg:TI 45)) + (clobber (reg:TI 46)) + (clobber (reg:TI 47)) + (clobber (reg:TI 48)) + (clobber (reg:TI 49)) + (clobber (reg:TI 50)) + (clobber (reg:TI 51)) + (clobber (reg:TI 52)) (clobber (reg:DI SI_REG)) (clobber (reg:DI DI_REG))] "!SIBLING_CALL_P (insn) && TARGET_64BIT" @@ -21433,6 +21453,16 @@ (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:TI 27)) + (clobber (reg:TI 28)) + (clobber (reg:TI 45)) + (clobber (reg:TI 46)) + (clobber (reg:TI 47)) + (clobber (reg:TI 48)) + (clobber (reg:TI 49)) + (clobber (reg:TI 50)) + (clobber (reg:TI 51)) + (clobber (reg:TI 52)) (clobber (reg:DI SI_REG)) (clobber (reg:DI DI_REG))] "!SIBLING_CALL_P (insn) && TARGET_64BIT" |