This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

w64 and call clobbered SSE regs


Hi,
MS ABI don't have most of SSE registers calls clobbered, while our
implementation of MS ABI call clobber's them all. This is unforutnate as fixing
this needs adding code to prologue/epilogue to save/restore them as well as
adding clobbers to the cross ABI calls.

This patch adds the clobbers and I will send patch for prologue/epilogue
in followup.  I didn't know about this problem earlier and hope it is still
resonable for this release stage as it can be verified that the non-ms code
paths remain same and releasing compiler with derrivation of MS abi that is not
really MS abi makes no sense at all.

This patch adds the clobbers, I will send prologues/epilogues changes in followup.

Bootstrapped/regtested i686-linux and tested on w65 by Kai. I will commit it tomorrow
if there are no complains.

	* i386.md (*msabi_syvabi): Add SSE regs clobbers.
	* i386.c (ix86_expand_call): Add clobbers.
Index: config/i386/i386.md
===================================================================
*** config/i386/i386.md	(revision 142998)
--- config/i386/i386.md	(working copy)
***************
*** 15044,15049 ****
--- 15044,15059 ----
    [(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"
***************
*** 21381,21386 ****
--- 21391,21406 ----
  	(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"
***************
*** 21434,21439 ****
--- 21454,21469 ----
  	(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"
Index: config/i386/i386.c
===================================================================
*** config/i386/i386.c	(revision 142998)
--- config/i386/i386.c	(working copy)
*************** ix86_expand_call (rtx retval, rtx fnaddr
*** 18363,18378 ****
        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);
--- 18501,18533 ----
        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 sseclobber1 = gen_rtx_CLOBBER (TImode, gen_rtx_REG (TImode, 27));
+       rtx sseclobber2 = gen_rtx_CLOBBER (TImode, gen_rtx_REG (TImode, 28));
+       rtx sseclobber3 = gen_rtx_CLOBBER (TImode, gen_rtx_REG (TImode, 45));
+       rtx sseclobber4 = gen_rtx_CLOBBER (TImode, gen_rtx_REG (TImode, 46));
+       rtx sseclobber5 = gen_rtx_CLOBBER (TImode, gen_rtx_REG (TImode, 47));
+       rtx sseclobber6 = gen_rtx_CLOBBER (TImode, gen_rtx_REG (TImode, 48));
+       rtx sseclobber7 = gen_rtx_CLOBBER (TImode, gen_rtx_REG (TImode, 49));
+       rtx sseclobber8 = gen_rtx_CLOBBER (TImode, gen_rtx_REG (TImode, 50));
+       rtx sseclobber9 = gen_rtx_CLOBBER (TImode, gen_rtx_REG (TImode, 51));
+       rtx sseclobber10 = gen_rtx_CLOBBER (TImode, gen_rtx_REG (TImode, 52));
        rtx unspec = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, const0_rtx),
        				   UNSPEC_MS_TO_SYSV_CALL);
+ 
        call = gen_rtx_PARALLEL (VOIDmode,
!       			       gen_rtvec (14, call, unspec, sseclobber1,
! 			       		  sseclobber2, sseclobber3,
! 			       		  sseclobber4, sseclobber5,
! 			       		  sseclobber6, sseclobber7,
! 			       		  sseclobber8, sseclobber9,
! 					  sseclobber10, clobber1,
! 					  clobber2));
      }
  
    call = emit_call_insn (call);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]