Patchwork [i386] : Introduce split_double_mode

login
register
mail settings
Submitter Uros Bizjak
Date Sept. 19, 2010, 12:45 p.m.
Message ID <AANLkTike39HT6QTGR9v_=FXi=qNYtM6DN16-9nzWgSP5@mail.gmail.com>
Download mbox | patch
Permalink /patch/65156/
State New
Headers show

Comments

Uros Bizjak - Sept. 19, 2010, 12:45 p.m.
Hello!

This function substitutes both split_di and split_ti, mainly to avoid
constructs like:

(mode == DImode ? split_di : split_ti) (...)

2010-09-19  Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/i386-protos.h (split_double_mode): New prototype.
	(split_di, split_ti): Remove prototypes.
	* config/i386/i386.c (split_double_mode): New function.
	(split_di, split_ti): Remove.
	(ix86_expand_branch): Use split_double_mode.
	(ix86_split_to_parts): Ditto.
	(ix86_split_ashl): Ditto.
	(ix86_split_ashr): Ditto.
	(ix86_split_lshr): Ditto.
	(ix86_force_to_memory): Ditto.
	* config/i386/i386.md: Use split_double_mode in double-mode splitters.

Tested on x86_64-pc-linux-gnu {,-m32}, committed to mainline SVN.

Uros.

Patch

Index: i386.md
===================================================================
--- i386.md	(revision 164410)
+++ i386.md	(working copy)
@@ -1640,7 +1640,7 @@ 
   [(set (match_dup 0) (match_dup 1))
    (set (match_dup 2) (match_dup 3))]
 {
-  split_di (&operands[1], 1, &operands[2], &operands[3]);
+  split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
 
   operands[1] = gen_lowpart (DImode, operands[2]);
   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
@@ -1657,7 +1657,7 @@ 
   [(set (match_dup 0) (match_dup 1))
    (set (match_dup 2) (match_dup 3))]
 {
-  split_di (&operands[1], 1, &operands[2], &operands[3]);
+  split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
 
   operands[1] = gen_lowpart (DImode, operands[2]);
   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
@@ -2050,7 +2050,7 @@ 
    && !x86_64_immediate_operand (operands[1], DImode) && 1"
   [(set (match_dup 2) (match_dup 3))
    (set (match_dup 4) (match_dup 5))]
-  "split_di (&operands[0], 2, &operands[2], &operands[4]);")
+  "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
 
 (define_split
   [(set (match_operand:DI 0 "memory_operand" "")
@@ -2061,7 +2061,7 @@ 
    && !x86_64_immediate_operand (operands[1], DImode)"
   [(set (match_dup 2) (match_dup 3))
    (set (match_dup 4) (match_dup 5))]
-  "split_di (&operands[0], 2, &operands[2], &operands[4]);")
+  "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
 
 (define_insn "*movdi_internal"
   [(set (match_operand:DI 0 "nonimmediate_operand"
@@ -3598,7 +3598,7 @@ 
      	(zero_extend:DI (match_dup 0)))]
   "TARGET_64BIT"
   [(set (match_dup 4) (const_int 0))]
-  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
 
 ;; %%% Kill me once multi-word ops are sane.
 (define_insn "zero_extendsidi2_1"
@@ -3626,7 +3626,7 @@ 
   "!TARGET_64BIT && reload_completed
    && true_regnum (operands[0]) == true_regnum (operands[1])"
   [(set (match_dup 4) (const_int 0))]
-  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
 
 (define_split
   [(set (match_operand:DI 0 "nonimmediate_operand" "")
@@ -3636,7 +3636,7 @@ 
    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
   [(set (match_dup 3) (match_dup 1))
    (set (match_dup 4) (const_int 0))]
-  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
 
 (define_insn "zero_extend<mode>di2"
   [(set (match_operand:DI 0 "register_operand" "=r")
@@ -3801,7 +3801,7 @@ 
    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
 	      (clobber (reg:CC FLAGS_REG))])
    (set (match_dup 4) (match_dup 1))]
-  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
 
 ;; Extend to memory case when source register does not die.
 (define_split
@@ -3812,7 +3812,7 @@ 
   "reload_completed"
   [(const_int 0)]
 {
-  split_di (&operands[0], 1, &operands[3], &operands[4]);
+  split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
 
   emit_move_insn (operands[3], operands[1]);
 
@@ -3842,7 +3842,7 @@ 
   "reload_completed"
   [(const_int 0)]
 {
-  split_di (&operands[0], 1, &operands[3], &operands[4]);
+  split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
 
   if (true_regnum (operands[3]) != true_regnum (operands[1]))
     emit_move_insn (operands[3], operands[1]);
@@ -5570,7 +5570,7 @@ 
 		       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
 		       (match_dup 5))))
 	      (clobber (reg:CC FLAGS_REG))])]
-  "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
+  "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
 
 (define_insn "*add<mode>3_cc"
   [(set (reg:CC FLAGS_REG)
@@ -6600,7 +6600,7 @@ 
 		       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
 		       (match_dup 5))))
 	      (clobber (reg:CC FLAGS_REG))])]
-  "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
+  "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
 
 (define_insn "*sub<mode>_1"
   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
@@ -8593,7 +8593,7 @@ 
     [(set (match_dup 2)
 	  (neg:DWIH (match_dup 2)))
      (clobber (reg:CC FLAGS_REG))])]
-  "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
+  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
 
 (define_insn "*neg<mode>2_1"
   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
@@ -10072,7 +10072,7 @@ 
 {
   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
 
-  split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
+  split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
 })
 
 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
@@ -10100,7 +10100,7 @@ 
 {
   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
 
-  split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
+  split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
 })
 
 (define_insn "*<rotate_insn><mode>3_1"
@@ -16055,8 +16055,8 @@ 
 		      (match_dup 7)
 		      (match_dup 8)))]
 {
-  split_di (&operands[2], 2, &operands[5], &operands[7]);
-  split_di (&operands[0], 1, &operands[2], &operands[3]);
+  split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
+  split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
 })
 
 (define_insn "*movxfcc_1"
Index: i386-protos.h
===================================================================
--- i386-protos.h	(revision 164410)
+++ i386-protos.h	(working copy)
@@ -64,8 +64,7 @@  extern bool legitimate_pic_address_disp_
 extern void print_reg (rtx, int, FILE*);
 extern void ix86_print_operand (FILE *, rtx, int);
 
-extern void split_di (rtx[], int, rtx[], rtx[]);
-extern void split_ti (rtx[], int, rtx[], rtx[]);
+extern void split_double_mode (enum machine_mode, rtx[], int, rtx[], rtx[]);
 
 extern const char *output_set_got (rtx, rtx);
 extern const char *output_387_binary_op (rtx, rtx*);
Index: i386.c
===================================================================
--- i386.c	(revision 164410)
+++ i386.c	(working copy)
@@ -13248,15 +13248,33 @@  i386_asm_output_addr_const_extra (FILE *
   return true;
 }
 
-/* Split one or more DImode RTL references into pairs of SImode
+/* Split one or more double-mode RTL references into pairs of half-mode
    references.  The RTL can be REG, offsettable MEM, integer constant, or
-   CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
+   CONST_DOUBLE.  "operands" is a pointer to an array of double-mode RTLs to
    split and "num" is its length.  lo_half and hi_half are output arrays
    that parallel "operands".  */
 
 void
-split_di (rtx operands[], int num, rtx lo_half[], rtx hi_half[])
+split_double_mode (enum machine_mode mode, rtx operands[],
+		   int num, rtx lo_half[], rtx hi_half[])
 {
+  enum machine_mode half_mode;
+  unsigned int byte;
+
+  switch (mode)
+    {
+    case TImode:
+      half_mode = DImode;
+      break;
+    case DImode:
+      half_mode = SImode;
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  byte = GET_MODE_SIZE (half_mode);
+
   while (num--)
     {
       rtx op = operands[num];
@@ -13265,44 +13283,17 @@  split_di (rtx operands[], int num, rtx l
          but we still have to handle it.  */
       if (MEM_P (op))
 	{
-	  lo_half[num] = adjust_address (op, SImode, 0);
-	  hi_half[num] = adjust_address (op, SImode, 4);
+	  lo_half[num] = adjust_address (op, half_mode, 0);
+	  hi_half[num] = adjust_address (op, half_mode, byte);
 	}
       else
 	{
-	  lo_half[num] = simplify_gen_subreg (SImode, op,
+	  lo_half[num] = simplify_gen_subreg (half_mode, op,
 					      GET_MODE (op) == VOIDmode
-					      ? DImode : GET_MODE (op), 0);
-	  hi_half[num] = simplify_gen_subreg (SImode, op,
+					      ? mode : GET_MODE (op), 0);
+	  hi_half[num] = simplify_gen_subreg (half_mode, op,
 					      GET_MODE (op) == VOIDmode
-					      ? DImode : GET_MODE (op), 4);
-	}
-    }
-}
-/* Split one or more TImode RTL references into pairs of DImode
-   references.  The RTL can be REG, offsettable MEM, integer constant, or
-   CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
-   split and "num" is its length.  lo_half and hi_half are output arrays
-   that parallel "operands".  */
-
-void
-split_ti (rtx operands[], int num, rtx lo_half[], rtx hi_half[])
-{
-  while (num--)
-    {
-      rtx op = operands[num];
-
-      /* simplify_subreg refuse to split volatile memory addresses, but we
-         still have to handle it.  */
-      if (MEM_P (op))
-	{
-	  lo_half[num] = adjust_address (op, DImode, 0);
-	  hi_half[num] = adjust_address (op, DImode, 8);
-	}
-      else
-	{
-	  lo_half[num] = simplify_gen_subreg (DImode, op, TImode, 0);
-	  hi_half[num] = simplify_gen_subreg (DImode, op, TImode, 8);
+					      ? mode : GET_MODE (op), byte);
 	}
     }
 }
@@ -16273,9 +16264,10 @@  ix86_expand_compare (enum rtx_code code,
 void
 ix86_expand_branch (enum rtx_code code, rtx op0, rtx op1, rtx label)
 {
+  enum machine_mode mode = GET_MODE (op0);
   rtx tmp;
 
-  switch (GET_MODE (op0))
+  switch (mode)
     {
     case SFmode:
     case DFmode:
@@ -16306,18 +16298,11 @@  ix86_expand_branch (enum rtx_code code, 
 	    tmp = op0, op0 = op1, op1 = tmp;
 	    code = swap_condition (code);
 	  }
-	if (GET_MODE (op0) == DImode)
-	  {
-	    split_di (&op0, 1, lo+0, hi+0);
-	    split_di (&op1, 1, lo+1, hi+1);
-	    submode = SImode;
-	  }
-	else
-	  {
-	    split_ti (&op0, 1, lo+0, hi+0);
-	    split_ti (&op1, 1, lo+1, hi+1);
-	    submode = DImode;
-	  }
+
+	split_double_mode (mode, &op0, 1, lo+0, hi+0);
+	split_double_mode (mode, &op1, 1, lo+1, hi+1);
+
+	submode = mode == DImode ? SImode : DImode;
 
 	/* When comparing for equality, we can use (hi0^hi1)|(lo0^lo1) to
 	   avoid two branches.  This costs one extra insn, so disable when
@@ -16474,7 +16459,7 @@  ix86_expand_carry_flag_compare (enum rtx
   enum machine_mode mode =
     GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
 
-  /* Do not handle DImode compares that go through special path.  */
+  /* Do not handle double-mode compares that go through special path.  */
   if (mode == (TARGET_64BIT ? TImode : DImode))
     return false;
 
@@ -17686,8 +17671,8 @@  ix86_expand_int_addcc (rtx operands[])
 }
 
 
-/* Split operands 0 and 1 into SImode parts.  Similar to split_di, but
-   works for floating pointer parameters and nonoffsetable memories.
+/* Split operands 0 and 1 into half-mode parts.  Similar to split_double_mode,
+   but works for floating pointer parameters and nonoffsetable memories.
    For pushes, it returns just stack offsets; the values will be saved
    in the right order.  Maximally three parts are generated.  */
 
@@ -17740,7 +17725,7 @@  ix86_split_to_parts (rtx operand, rtx *p
   if (!TARGET_64BIT)
     {
       if (mode == DImode)
-	split_di (&operand, 1, &parts[0], &parts[1]);
+	split_double_mode (mode, &operand, 1, &parts[0], &parts[1]);
       else
 	{
 	  int i;
@@ -17791,7 +17776,7 @@  ix86_split_to_parts (rtx operand, rtx *p
   else
     {
       if (mode == TImode)
-	split_ti (&operand, 1, &parts[0], &parts[1]);
+	split_double_mode (mode, &operand, 1, &parts[0], &parts[1]);
       if (mode == XFmode || mode == TFmode)
 	{
 	  enum machine_mode upper_mode = mode==XFmode ? SImode : DImode;
@@ -17862,7 +17847,7 @@  ix86_split_long_move (rtx operands[])
   /* The DFmode expanders may ask us to move double.
      For 64bit target this is single move.  By hiding the fact
      here we simplify i386.md splitters.  */
-  if (GET_MODE_SIZE (GET_MODE (operands[0])) == 8 && TARGET_64BIT)
+  if (TARGET_64BIT && GET_MODE_SIZE (GET_MODE (operands[0])) == 8)
     {
       /* Optimize constant pool reference to immediates.  This is used by
 	 fp moves, that force all constants to memory to allow combining.  */
@@ -18104,7 +18089,7 @@  ix86_split_ashl (rtx *operands, rtx scra
 
   if (CONST_INT_P (operands[2]))
     {
-      (mode == DImode ? split_di : split_ti) (operands, 2, low, high);
+      split_double_mode (mode, operands, 2, low, high);
       count = INTVAL (operands[2]) & (single_width * 2 - 1);
 
       if (count >= single_width)
@@ -18127,7 +18112,7 @@  ix86_split_ashl (rtx *operands, rtx scra
       return;
     }
 
-  (mode == DImode ? split_di : split_ti) (operands, 1, low, high);
+  split_double_mode (mode, operands, 1, low, high);
 
   if (operands[1] == const1_rtx)
     {
@@ -18204,7 +18189,7 @@  ix86_split_ashl (rtx *operands, rtx scra
       if (!rtx_equal_p (operands[0], operands[1]))
 	emit_move_insn (operands[0], operands[1]);
 
-      (mode == DImode ? split_di : split_ti) (operands, 1, low, high);
+      split_double_mode (mode, operands, 1, low, high);
       emit_insn ((mode == DImode
 		  ? gen_x86_shld
 		  : gen_x86_64_shld) (high[0], low[0], operands[2]));
@@ -18237,7 +18222,7 @@  ix86_split_ashr (rtx *operands, rtx scra
 
   if (CONST_INT_P (operands[2]))
     {
-      (mode == DImode ? split_di : split_ti) (operands, 2, low, high);
+      split_double_mode (mode, operands, 2, low, high);
       count = INTVAL (operands[2]) & (single_width * 2 - 1);
 
       if (count == single_width * 2 - 1)
@@ -18281,7 +18266,7 @@  ix86_split_ashr (rtx *operands, rtx scra
       if (!rtx_equal_p (operands[0], operands[1]))
 	emit_move_insn (operands[0], operands[1]);
 
-      (mode == DImode ? split_di : split_ti) (operands, 1, low, high);
+      split_double_mode (mode, operands, 1, low, high);
 
       emit_insn ((mode == DImode
 		  ? gen_x86_shrd
@@ -18318,7 +18303,7 @@  ix86_split_lshr (rtx *operands, rtx scra
 
   if (CONST_INT_P (operands[2]))
     {
-      (mode == DImode ? split_di : split_ti) (operands, 2, low, high);
+      split_double_mode (mode, operands, 2, low, high);
       count = INTVAL (operands[2]) & (single_width * 2 - 1);
 
       if (count >= single_width)
@@ -18349,7 +18334,7 @@  ix86_split_lshr (rtx *operands, rtx scra
       if (!rtx_equal_p (operands[0], operands[1]))
 	emit_move_insn (operands[0], operands[1]);
 
-      (mode == DImode ? split_di : split_ti) (operands, 1, low, high);
+      split_double_mode (mode, operands, 1, low, high);
 
       emit_insn ((mode == DImode
 		  ? gen_x86_shrd
@@ -26144,7 +26129,7 @@  ix86_force_to_memory (enum machine_mode 
 	case DImode:
 	  {
 	    rtx operands[2];
-	    split_di (&operand, 1, operands, operands + 1);
+	    split_double_mode (mode, &operand, 1, operands, operands + 1);
 	    emit_insn (
 			gen_rtx_SET (VOIDmode,
 				     gen_rtx_MEM (SImode,