[3.2 PATCH] PowerPC fixes

David Edelsohn dje@watson.ibm.com
Tue Nov 26 08:09:00 GMT 2002


	This patch merges some mainline fixes: the load multiple fix
allowing the removal of the libstdc++/testsuite/abi_check.cc kludge and
more accurate test for local symbols without binds_local_p functionality
available on mainline.

David


        * config/rs6000/rs6000.c (rs6000_flag_pic): New variable.
        (rs6000_override_options): Save original flag_pic value.
        (rs6000_encode_section_info): More accurate test for "local" symbol.

        PR 8362
        * config/rs6000/rs6000.c (rs6000_outout_load_multiple): New function.
        * config/rs6000/rs6000.md (ldmsi[3-8]): New patterns.

Index: rs6000-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000-protos.h,v
retrieving revision 1.30.6.2
diff -c -p -r1.30.6.2 rs6000-protos.h
*** rs6000-protos.h	8 Aug 2002 14:51:47 -0000	1.30.6.2
--- rs6000-protos.h	26 Nov 2002 15:45:47 -0000
*************** extern int constant_pool_expr_p PARAMS (
*** 77,82 ****
--- 77,83 ----
  extern int toc_relative_expr_p PARAMS ((rtx));
  extern int expand_block_move PARAMS ((rtx[]));
  extern int load_multiple_operation PARAMS ((rtx, enum machine_mode));
+ extern const char * rs6000_output_load_multiple PARAMS ((rtx[]));
  extern int store_multiple_operation PARAMS ((rtx, enum machine_mode));
  extern int branch_comparison_operator PARAMS ((rtx, enum machine_mode));
  extern int branch_positive_comparison_operator 
Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.291.2.13.2.11
diff -c -p -r1.291.2.13.2.11 rs6000.c
*** rs6000.c	7 Nov 2002 07:04:20 -0000	1.291.2.13.2.11
--- rs6000.c	26 Nov 2002 15:45:48 -0000
*************** int rs6000_altivec_abi;
*** 77,82 ****
--- 77,85 ----
  /* Set to non-zero once AIX common-mode calls have been defined.  */
  static int common_mode_defined;
  
+ /* Private copy of original value of flag_pic for ABI_AIX.  */
+ static int rs6000_flag_pic;
+ 
  /* Save information from a "cmpxx" operation until the branch or scc is
     emitted.  */
  rtx rs6000_compare_op0, rs6000_compare_op1;
*************** rs6000_override_options (default_cpu)
*** 484,494 ****
  
    if (flag_pic != 0 && DEFAULT_ABI == ABI_AIX)
      {
        flag_pic = 0;
- 
-       if (extra_warnings)
- 	warning ("-f%s ignored (all code is position independent)",
- 		 (flag_pic > 1) ? "PIC" : "pic");
      }
  
  #ifdef XCOFF_DEBUGGING_INFO
--- 487,494 ----
  
    if (flag_pic != 0 && DEFAULT_ABI == ABI_AIX)
      {
+       rs6000_flag_pic = flag_pic;
        flag_pic = 0;
      }
  
  #ifdef XCOFF_DEBUGGING_INFO
*************** store_multiple_operation (op, mode)
*** 5220,5225 ****
--- 5220,5283 ----
    return 1;
  }
  
+ /* Return a string to perform a load_multiple operation.
+    operands[0] is the vector.
+    operands[1] is the source address.
+    operands[2] is the first destination register.  */
+ 
+ const char *
+ rs6000_output_load_multiple (operands)
+      rtx operands[2];
+ {
+   /* We have to handle the case where the pseudo used to contain the address
+      is assigned to one of the output registers.  */
+   int i, j;
+   int words = XVECLEN (operands[0], 0);
+   rtx xop[10];
+ 
+   if (XVECLEN (operands[0], 0) == 1)
+     return "{l|lwz} %2,0(%1)";
+ 
+   for (i = 0; i < words; i++)
+     if (refers_to_regno_p (REGNO (operands[2]) + i,
+ 			   REGNO (operands[2]) + i + 1, operands[1], 0))
+       {
+ 	if (i == words-1)
+ 	  {
+ 	    xop[0] = GEN_INT (4 * (words-1));
+ 	    xop[1] = operands[1];
+ 	    xop[2] = operands[2];
+ 	    output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
+ 	    return "";
+ 	  }
+ 	else if (i == 0)
+ 	  {
+ 	    xop[0] = GEN_INT (4 * (words-1));
+ 	    xop[1] = operands[1];
+ 	    xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
+ 	    output_asm_insn ("{cal %1,4(%1)|addi %1,%1,4}\n\t{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,-4(%1)", xop);
+ 	    return "";
+ 	  }
+ 	else
+ 	  {
+ 	    for (j = 0; j < words; j++)
+ 	      if (j != i)
+ 		{
+ 		  xop[0] = GEN_INT (j * 4);
+ 		  xop[1] = operands[1];
+ 		  xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
+ 		  output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
+ 		}
+ 	    xop[0] = GEN_INT (i * 4);
+ 	    xop[1] = operands[1];
+ 	    output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
+ 	    return "";
+ 	  }
+       }
+ 
+   return "{lsi|lswi} %2,%1,%N0";
+ }
+ 
  /* Return 1 for a parallel vrsave operation.  */
  
  int
*************** rs6000_encode_section_info (decl)
*** 10897,10904 ****
    if (TREE_CODE (decl) == FUNCTION_DECL)
      {
        rtx sym_ref = XEXP (DECL_RTL (decl), 0);
!       if ((TREE_ASM_WRITTEN (decl) || ! TREE_PUBLIC (decl))
!           && ! DECL_WEAK (decl))
  	SYMBOL_REF_FLAG (sym_ref) = 1;
  
        if (DEFAULT_ABI == ABI_AIX)
--- 10955,10966 ----
    if (TREE_CODE (decl) == FUNCTION_DECL)
      {
        rtx sym_ref = XEXP (DECL_RTL (decl), 0);
!       if (!TREE_PUBLIC (decl)
! 	  || (!DECL_EXTERNAL (decl)
! 	      && !DECL_ONE_ONLY (decl)
! 	      && !DECL_WEAK (decl)
! 	      && !flag_pic
! 	      && !rs6000_flag_pic))
  	SYMBOL_REF_FLAG (sym_ref) = 1;
  
        if (DEFAULT_ABI == ABI_AIX)
Index: rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.170.2.11.2.3
diff -c -p -r1.170.2.11.2.3 rs6000.md
*** rs6000.md	7 Oct 2002 04:21:05 -0000	1.170.2.11.2.3
--- rs6000.md	26 Nov 2002 15:45:48 -0000
***************
*** 8734,8798 ****
  		     adjust_address (op1, SImode, i * 4));
  }")
  
! (define_insn ""
    [(match_parallel 0 "load_multiple_operation"
! 		   [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
! 			 (mem:SI (match_operand:SI 2 "gpc_reg_operand" "b")))])]
!   "TARGET_STRING"
    "*
! {
!   /* We have to handle the case where the pseudo used to contain the address
!      is assigned to one of the output registers.  */
!   int i, j;
!   int words = XVECLEN (operands[0], 0);
!   rtx xop[10];
! 
!   if (XVECLEN (operands[0], 0) == 1)
!     return \"{l|lwz} %1,0(%2)\";
! 
!   for (i = 0; i < words; i++)
!     if (refers_to_regno_p (REGNO (operands[1]) + i,
! 			   REGNO (operands[1]) + i + 1, operands[2], 0))
!       {
! 	if (i == words-1)
! 	  {
! 	    xop[0] = operands[1];
! 	    xop[1] = operands[2];
! 	    xop[2] = GEN_INT (4 * (words-1));
! 	    output_asm_insn (\"{lsi|lswi} %0,%1,%2\;{l|lwz} %1,%2(%1)\", xop);
! 	    return \"\";
! 	  }
! 	else if (i == 0)
! 	  {
! 	    xop[0] = operands[1];
! 	    xop[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
! 	    xop[2] = GEN_INT (4 * (words-1));
! 	    output_asm_insn (\"{cal %0,4(%0)|addi %0,%0,4}\;{lsi|lswi} %1,%0,%2\;{l|lwz} %0,-4(%0)\", xop);
! 	    return \"\";
! 	  }
! 	else
! 	  {
! 	    for (j = 0; j < words; j++)
! 	      if (j != i)
! 		{
! 		  xop[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + j);
! 		  xop[1] = operands[2];
! 		  xop[2] = GEN_INT (j * 4);
! 		  output_asm_insn (\"{l|lwz} %0,%2(%1)\", xop);
! 		}
! 	    xop[0] = operands[2];
! 	    xop[1] = GEN_INT (i * 4);
! 	    output_asm_insn (\"{l|lwz} %0,%1(%0)\", xop);
! 	    return \"\";
! 	  }
!       }
  
!   return \"{lsi|lswi} %1,%2,%N0\";
! }"
    [(set_attr "type" "load")
     (set_attr "length" "32")])
  
- 
  (define_expand "store_multiple"
    [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
  			  (match_operand:SI 1 "" ""))
--- 8734,8853 ----
  		     adjust_address (op1, SImode, i * 4));
  }")
  
! (define_insn "*ldmsi8"
    [(match_parallel 0 "load_multiple_operation"
!     [(set (match_operand:SI 2 "gpc_reg_operand" "")
!           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
!      (set (match_operand:SI 3 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
!      (set (match_operand:SI 4 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
!      (set (match_operand:SI 5 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
!      (set (match_operand:SI 6 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
!      (set (match_operand:SI 7 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
!      (set (match_operand:SI 8 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
!      (set (match_operand:SI 9 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
!   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
    "*
! { return rs6000_output_load_multiple (operands); }"
!   [(set_attr "type" "load")
!    (set_attr "length" "32")])
! 
! (define_insn "*ldmsi7"
!   [(match_parallel 0 "load_multiple_operation"
!     [(set (match_operand:SI 2 "gpc_reg_operand" "")
!           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
!      (set (match_operand:SI 3 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
!      (set (match_operand:SI 4 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
!      (set (match_operand:SI 5 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
!      (set (match_operand:SI 6 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
!      (set (match_operand:SI 7 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
!      (set (match_operand:SI 8 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
!   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
!   "*
! { return rs6000_output_load_multiple (operands); }"
!   [(set_attr "type" "load")
!    (set_attr "length" "32")])
! 
! (define_insn "*ldmsi6"
!   [(match_parallel 0 "load_multiple_operation"
!     [(set (match_operand:SI 2 "gpc_reg_operand" "")
!           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
!      (set (match_operand:SI 3 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
!      (set (match_operand:SI 4 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
!      (set (match_operand:SI 5 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
!      (set (match_operand:SI 6 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
!      (set (match_operand:SI 7 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
!   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
!   "*
! { return rs6000_output_load_multiple (operands); }"
!   [(set_attr "type" "load")
!    (set_attr "length" "32")])
  
! (define_insn "*ldmsi5"
!   [(match_parallel 0 "load_multiple_operation"
!     [(set (match_operand:SI 2 "gpc_reg_operand" "")
!           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
!      (set (match_operand:SI 3 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
!      (set (match_operand:SI 4 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
!      (set (match_operand:SI 5 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
!      (set (match_operand:SI 6 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
!   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
!   "*
! { return rs6000_output_load_multiple (operands); }"
!   [(set_attr "type" "load")
!    (set_attr "length" "32")])
! 
! (define_insn "*ldmsi4"
!   [(match_parallel 0 "load_multiple_operation"
!     [(set (match_operand:SI 2 "gpc_reg_operand" "")
!           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
!      (set (match_operand:SI 3 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
!      (set (match_operand:SI 4 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
!      (set (match_operand:SI 5 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
!   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
!   "*
! { return rs6000_output_load_multiple (operands); }"
!   [(set_attr "type" "load")
!    (set_attr "length" "32")])
! 
! (define_insn "*ldmsi3"
!   [(match_parallel 0 "load_multiple_operation"
!     [(set (match_operand:SI 2 "gpc_reg_operand" "")
!           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
!      (set (match_operand:SI 3 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
!      (set (match_operand:SI 4 "gpc_reg_operand" "")
!           (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
!   "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
!   "*
! { return rs6000_output_load_multiple (operands); }"
    [(set_attr "type" "load")
     (set_attr "length" "32")])
  
  (define_expand "store_multiple"
    [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
  			  (match_operand:SI 1 "" ""))
***************
*** 8837,8843 ****
  		     gen_rtx_REG (SImode, regno + i));
  }")
  
! (define_insn ""
    [(match_parallel 0 "store_multiple_operation"
  		   [(set (match_operand:SI 1 "indirect_operand" "=Q")
  			 (match_operand:SI 2 "gpc_reg_operand" "r"))
--- 8892,8898 ----
  		     gen_rtx_REG (SImode, regno + i));
  }")
  
! (define_insn "*store_multiple_power"
    [(match_parallel 0 "store_multiple_operation"
  		   [(set (match_operand:SI 1 "indirect_operand" "=Q")
  			 (match_operand:SI 2 "gpc_reg_operand" "r"))
***************
*** 8846,8852 ****
    "{stsi|stswi} %2,%P1,%O0"
    [(set_attr "type" "store")])
  
! (define_insn ""
    [(match_parallel 0 "store_multiple_operation"
  		   [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
  			 (match_operand:SI 2 "gpc_reg_operand" "r"))
--- 8901,8907 ----
    "{stsi|stswi} %2,%P1,%O0"
    [(set_attr "type" "store")])
  
! (define_insn "*store_multiple_string"
    [(match_parallel 0 "store_multiple_operation"
  		   [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
  			 (match_operand:SI 2 "gpc_reg_operand" "r"))



More information about the Gcc-patches mailing list