public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] fold-const.c use of BRANCH_COST
@ 2003-04-09 19:34 David Edelsohn
  2003-04-11  4:11 ` Richard Henderson
  0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2003-04-09 19:34 UTC (permalink / raw)
  To: gcc-patches

	While investigating PowerPC performance, I have discovered that
the threshold levels used to test BRANCH_COST are not always correct for
PowerPC.  Instead of arguing to change the threshold, I propose allowing
the test to be overridden in the machine description, with the default
being the former BRANCH_COST-based test.

	If the patch below is approved, I will add the appropriate
documentation as well.  The motivation is:

Unmodified:
   200.sixtrack      1100       651       169*     1100       535      206*
   254.gap           1100       249       442*     1100       262      419*
   255.vortex        1900       283       672*     1900       275      691*

BRANCH_COST=1:
   200.sixtrack      1100      1492      73.7*     1100       743      148*
   254.gap           1100       248       444*     1100       239      460*
   255.vortex        1900       293       647*     1900       276      688*

Modified fold-const.c only:
   200.sixtrack      1100       649       169*     1100       675      163*
   254.gap           1100       281       391*     1100       249      442*
   255.vortex        1900       295       644*     1900       275      692*

Modified fold-const.c:fold_range_test() only:
   200.sixtrack      1100       964       114*     1100       529      208*
   254.gap           1100       245       449*     1100       243      452*
   255.vortex        1900       284       668*     1900       274      694*

Yes, BRANCH_COST=1 really does degrade 200.sixtrack that much -- it is
completely repeatable.

Thanks, David


	* fold-const.c (fold_range_test): Add new macro defaulting
	to BRANCH_COST.

Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.242
diff -c -p -r1.242 fold-const.c
*** fold-const.c	23 Mar 2003 22:57:25 -0000	1.242
--- fold-const.c	9 Apr 2003 19:25:26 -0000
*************** fold_range_test (exp)
*** 3449,3455 ****
    /* On machines where the branch cost is expensive, if this is a
       short-circuited branch and the underlying object on both sides
       is the same, make a non-short-circuit operation.  */
!   else if (BRANCH_COST >= 2
  	   && lhs != 0 && rhs != 0
  	   && (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
  	       || TREE_CODE (exp) == TRUTH_ORIF_EXPR)
--- 3449,3460 ----
    /* On machines where the branch cost is expensive, if this is a
       short-circuited branch and the underlying object on both sides
       is the same, make a non-short-circuit operation.  */
! 
! #ifndef RANGE_TEST_SHORT_CIRCUIT
! #define RANGE_TEST_SHORT_CIRCUIT (BRANCH_COST >= 2)
! #endif
! 
!   else if (RANGE_TEST_SHORT_CIRCUIT
  	   && lhs != 0 && rhs != 0
  	   && (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
  	       || TREE_CODE (exp) == TRUTH_ORIF_EXPR)

^ permalink raw reply	[flat|nested] 875+ messages in thread
* Fix a reload ICE on e500
@ 2007-08-14 20:00 Daniel Jacobowitz
  2007-08-20  7:38 ` Andrew Pinski
  0 siblings, 1 reply; 875+ messages in thread
From: Daniel Jacobowitz @ 2007-08-14 20:00 UTC (permalink / raw)
  To: gcc-patches

This patch fixes 20001012-1.c for powerpc-eabi with -mcpu=8548
-mfloat-gprs=double, on the 4.2 branch.  The problem is latent on
HEAD.

We start with this instruction:

(insn:HI 12 11 20 2 (set (subreg:DF (reg:DI 122) 0)
        (reg:DF 121)) 1103 {*frob_di_df_2} (nil)
    (expr_list:REG_DEAD (reg:DF 121)
        (nil)))

There's a register/register alternative for this instruction.
However, in 4.2 it can't be used because combine tried to create a
DImode subreg of (reg:DF 121); this leads to invalid_mode_change_p
refusing to let register 121 get assigned to a DFmode register.
It ends up in memory.

Rather than spilling it to the stack, reload uses the fact that this
register is known to be 1.0 to load that value from a constant pool.
This is a GOT-relative operation on PowerPC -fpic.  And the function
is a tiny leaf function which has not otherwise needed the GOT
pointer.  So emiting the reload makes the GOT pointer become suddenly
live, which changes the elimination offsets and eventually leads to
an ICE.

If I manually prod record_subregs_of_mode on mainline, the same ICE
occurs.  We now determine invalid mode changes as a dataflow problem,
so unsuccessful subregs from combine no longer affect them.

Most of this patch is fairly obvious once you know where to look.  The
same problem is already solved for non-SPE but the SPE case ignored
the calculation.  While I was looking at the condition, though, I
added the current_function_uses_const_pool.  I believe that the only
way that the GOT pointer can become live in the midst of reload is
this case, and current_function_uses_const_pool is how the MIPS
and i386 backends check for the same problem.

No regressions on powerpc-eabispe -mfloat-gprs=double for trunk.  Is
this OK to commit?  How about for the 4.2 branch?

-- 
Daniel Jacobowitz
CodeSourcery

2007-08-03  Daniel Jacobowitz  <dan@codesourcery.com>

	* config/rs6000/rs6000.c (rs6000_stack_info): Allocate space for the
	GOT pointer only if there is a constant pool.  Use the allocated space
	for SPE also.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 178068)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -13091,6 +13091,7 @@ rs6000_stack_info (void)
   int reg_size = TARGET_32BIT ? 4 : 8;
   int ehrd_size;
   int save_align;
+  int first_gp;
   HOST_WIDE_INT non_fixed_size;
 
   memset (&info, 0, sizeof (info));
@@ -13110,14 +13111,19 @@ rs6000_stack_info (void)
   /* Calculate which registers need to be saved & save area size.  */
   info_ptr->first_gp_reg_save = first_reg_to_save ();
   /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
-     even if it currently looks like we won't.  */
+     even if it currently looks like we won't.  Reload may need it to
+     get at a constant; if so, it will have already created a constant
+     pool entry for it.  */
   if (((TARGET_TOC && TARGET_MINIMAL_TOC)
        || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
        || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
+      && current_function_uses_const_pool
       && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
-    info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
+    first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
   else
-    info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save);
+    first_gp = info_ptr->first_gp_reg_save;
+
+  info_ptr->gp_size = reg_size * (32 - first_gp);
 
   /* For the SPE, we have an additional upper 32-bits on each GPR.
      Ideally we should save the entire 64-bits only when the upper
@@ -13205,7 +13211,7 @@ rs6000_stack_info (void)
 	    + info_ptr->parm_size);
 
   if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
-    info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
+    info_ptr->spe_gp_size = 8 * (32 - first_gp);
   else
     info_ptr->spe_gp_size = 0;
 

^ permalink raw reply	[flat|nested] 875+ messages in thread
* Mark PowerPC vector ABI in binary attributes
@ 2007-08-13 13:31 Daniel Jacobowitz
  0 siblings, 0 replies; 875+ messages in thread
From: Daniel Jacobowitz @ 2007-08-13 13:31 UTC (permalink / raw)
  To: gcc-patches; +Cc: Geoff Keating, David Edelsohn

I'm reposting this part separately from the -maltivec fixes, which are
more complicated.  This patch adds a marker to object files indicating
whether they were compiled with the generic vector ABI, AltiVec vector
ABI, or SPE vector ABI.  There's room for expansion should another
vector ABI be necessary later.

This patch will not have any other user-visible effect.  I will add
support to binutils to recognize and merge the attribute so that
linked executables are correctly marked, but not add a mismatch
warning yet; I think one is appropriate, but Andrew Pinski raised some
concerns and that discussion wasn't resolved.  Once I have binutils
support for merging the attribute, I will add GDB support for it; then
the AltiVec tests will start passing on powerpc-linux configurations.
We can decide what to do about warnings later.

Is this patch OK?

-- 
Daniel Jacobowitz
CodeSourcery

2007-08-07  Daniel Jacobowitz  <dan@codesourcery.com>

	* config/rs6000/rs6000.c (rs6000_file_start): Output a .gnu_attribute
	directive for the current vector ABI.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 127159)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -2316,8 +2316,14 @@ rs6000_file_start (void)
 
 #ifdef HAVE_AS_GNU_ATTRIBUTE
   if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
-    fprintf (file, "\t.gnu_attribute 4, %d\n",
-	     (TARGET_HARD_FLOAT && TARGET_FPRS) ? 1 : 2);
+    {
+      fprintf (file, "\t.gnu_attribute 4, %d\n",
+	       (TARGET_HARD_FLOAT && TARGET_FPRS) ? 1 : 2);
+      fprintf (file, "\t.gnu_attribute 8, %d\n",
+	       (TARGET_ALTIVEC_ABI ? 2
+		: TARGET_SPE_ABI ? 3
+		: 1));
+    }
 #endif
 
   if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [patch] set -mabi=altivec with -ftree-vectorize
@ 2007-07-31  8:20 Zdenek Dvorak
  2007-07-31 12:01 ` Daniel Jacobowitz
  0 siblings, 1 reply; 875+ messages in thread
From: Zdenek Dvorak @ 2007-07-31  8:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: dje

Hello,

using -O2 -maltivec -ftree-vectorize on ppc-linux leads to
misscompilations, as -mabi=altivec is not enabled there.
It would be somewhat annoying and error-prone to require a normal
user to know this and add the extra option.  As David Edelsohn
suggested, this patch makes us enable -mabi=altivec automatically
with -ftree-vectorize.

Bootstrapped & regtested on ppc-linux.

Zdenek

	* config/rs6000/rs6000.c (rs6000_override_options): Enable
	-mabi=altivec with -ftree-vectorize.
	* gcc.dg/pr32582-1.c: New test.

Index: testsuite/gcc.dg/pr32582-1.c
===================================================================
*** testsuite/gcc.dg/pr32582-1.c	(revision 0)
--- testsuite/gcc.dg/pr32582-1.c	(revision 0)
***************
*** 0 ****
--- 1,32 ----
+ /* { dg-do run { target { powerpc*-*-* && powerpc_altivec_ok } } } */
+ /* { dg-options "-O2 -ftree-vectorize -maltivec" } */
+ 
+ #include <stdlib.h>
+ #include <string.h>
+ 
+ char a[64];
+ 
+ void set (void)
+ {
+   int i;
+ 
+   for (i = 0; i < 64; i++)
+     a[i] = 'x';
+ }
+ 
+ void check (void)
+ {
+   int i;
+ 
+   for (i = 0; i < 64; i++)
+     if (a[i] != 0)
+       abort ();
+ }
+ 
+ int main (void)
+ {
+   set ();
+   memset (a, 0, sizeof a);
+   check ();
+   return 0;
+ }
Index: config/rs6000/rs6000.c
===================================================================
*** config/rs6000/rs6000.c	(revision 127065)
--- config/rs6000/rs6000.c	(working copy)
*************** rs6000_override_options (const char *def
*** 1537,1544 ****
      rs6000_ieeequad = 1;
  #endif
  
!   /* Set Altivec ABI as default for powerpc64 linux.  */
!   if (TARGET_ELF && TARGET_64BIT)
      {
        rs6000_altivec_abi = 1;
        TARGET_ALTIVEC_VRSAVE = 1;
--- 1537,1547 ----
      rs6000_ieeequad = 1;
  #endif
  
!   /* Set Altivec ABI as default for powerpc64 linux.  Also, if
!      autovectorization is run, enable Altivec ABI in order to
!      prevent misscompilations.  */
!   if ((TARGET_ELF && TARGET_64BIT)
!       || (TARGET_ALTIVEC && flag_tree_vectorize))
      {
        rs6000_altivec_abi = 1;
        TARGET_ALTIVEC_VRSAVE = 1;

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PATCH] Fix comments in PPC e500 code
@ 2006-08-09 12:49 Eric Botcazou
  2006-08-09 14:02 ` David Edelsohn
  0 siblings, 1 reply; 875+ messages in thread
From: Eric Botcazou @ 2006-08-09 12:49 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 823 bytes --]

Hi,

We were just bitten on the 3.4 branch by the GT/EQ bit ping-pong game in the 
implementation of the FP compare instructions on the PPC e500.  The final fix
  http://gcc.gnu.org/ml/gcc-patches/2005-03/msg00704.html
is only present on 3.4-e500-branch but not on the official 3.4 branch.

The perusal of the final code shows left-overs from the previous stages in 
some comments.  To avoid any more confusion we think it is important to have 
the comments exactly match the code.  Hence the attached patch.

Tested by building a cross to powerpc-eabispe.  OK for mainline?


2006-08-09  Eric Botcazou  <ebotcazou@adacore.com>

	* config/rs6000/rs6000.c (print_operand) <D>: Fix comment and adjust.
	(rs6000_generate_compare): Tweak comments.
	* config/rs6000/rs6000.md (UNSPEC_MV_CR_GT): Fix comment.


-- 
Eric Botcazou

[-- Attachment #2: f803-024-2_fsf.diff --]
[-- Type: text/x-diff, Size: 1995 bytes --]

Index: config/rs6000/rs6000.c
===================================================================
--- config/rs6000/rs6000.c	(revision 115944)
+++ config/rs6000/rs6000.c	(working copy)
@@ -10283,13 +10283,14 @@ print_operand (FILE *file, rtx x, int co
       return;
 
     case 'D':
-      /* Like 'J' but get to the EQ bit.  */
+      /* Like 'J' but get to the GT bit only.  */
       gcc_assert (GET_CODE (x) == REG);
 
-      /* Bit 1 is EQ bit.  */
-      i = 4 * (REGNO (x) - CR0_REGNO) + 2;
+      /* Bit 1 is GT bit.  */
+      i = 4 * (REGNO (x) - CR0_REGNO) + 1;
 
-      fprintf (file, "%d", i);
+      /* Add one for shift count in rlinm for scc.  */
+      fprintf (file, "%d", i+1);
       return;
 
     case 'E':
@@ -11086,7 +11087,7 @@ rs6000_generate_compare (enum rtx_code c
   /* First, the compare.  */
   compare_result = gen_reg_rtx (comp_mode);
 
-  /* SPE FP compare instructions on the GPRs.  Yuck!  */
+  /* E500 FP compare instructions on the GPRs.  Yuck!  */
   if ((TARGET_E500 && !TARGET_FPRS && TARGET_HARD_FLOAT)
       && rs6000_compare_fp_p)
     {
@@ -11096,8 +11097,8 @@ rs6000_generate_compare (enum rtx_code c
       if (op_mode == VOIDmode)
 	op_mode = GET_MODE (rs6000_compare_op1);
 
-      /* Note: The E500 comparison instructions set the GT bit (x +
-	 1), on success.  This explains the mess.  */
+      /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
+	 This explains the following mess.  */
 
       switch (code)
 	{
Index: config/rs6000/rs6000.md
===================================================================
--- config/rs6000/rs6000.md	(revision 115944)
+++ config/rs6000/rs6000.md	(working copy)
@@ -55,7 +55,7 @@ (define_constants
    (UNSPEC_TLSGOTTPREL		28)
    (UNSPEC_TLSTLS		29)
    (UNSPEC_FIX_TRUNC_TF		30)	; fadd, rounding towards zero
-   (UNSPEC_MV_CR_GT		31)	; move_from_CR_eq_bit
+   (UNSPEC_MV_CR_GT		31)	; move_from_CR_gt_bit
    (UNSPEC_STFIWX		32)
    (UNSPEC_POPCNTB		33)
    (UNSPEC_FRES			34)

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PATCH, committed] PR 28150 and PR 28170
@ 2006-07-06 19:53 David Edelsohn
  2006-07-07  3:07 ` Alan Modra
  0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2006-07-06 19:53 UTC (permalink / raw)
  To: gcc-patches

	These patches fix PR 28150 (TFmode PRE_INC) and PR 28170 (insv
with shift).  The insv function cleanups were incorporated from Alan
Modra's patch.

Bootstrapped and regression tested on powerpc-ibm-aix5.2.0.0 and
powerpc-linux. 

David

	PR target/28150
	* config/rs6000/rs6000.c (rs6000_legitimate_address): Do not allow
	PRE_{INC,DEC} of TFmode.

	PR target/28170
	* config/rs6000/rs6000.c (insvdi_rshift_rlwimi_p): Correct shiftop
	bounds. Simplify.

Index: rs6000.c
===================================================================
*** rs6000.c	(revision 115219)
--- rs6000.c	(working copy)
*************** rs6000_legitimate_address (enum machine_
*** 3522,3527 ****
--- 3522,3528 ----
    if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
        && !ALTIVEC_VECTOR_MODE (mode)
        && !SPE_VECTOR_MODE (mode)
+       && mode != TFmode
        /* Restrict addressing for DI because of our SUBREG hackery.  */
        && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == DImode))
        && TARGET_UPDATE
*************** effects of instruction do not correspond
*** 9799,9810 ****
  int
  insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
  {
!   if (INTVAL (startop) < 64
!       && INTVAL (startop) > 32
!       && (INTVAL (sizeop) + INTVAL (startop) < 64)
!       && (INTVAL (sizeop) + INTVAL (startop) > 33)
!       && (INTVAL (sizeop) + INTVAL (startop) + INTVAL (shiftop) < 96)
!       && (INTVAL (sizeop) + INTVAL (startop) + INTVAL (shiftop) >= 64)
        && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
      return 1;
  
--- 9800,9811 ----
  int
  insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
  {
!   if (INTVAL (startop) > 32
!       && INTVAL (startop) < 64
!       && INTVAL (sizeop) > 1
!       && INTVAL (sizeop) + INTVAL (startop) < 64
!       && INTVAL (shiftop) > 0
!       && INTVAL (sizeop) + INTVAL (shiftop) < 32
        && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
      return 1;
  

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PowerPC] Avoid ICE on DFmode subreg
@ 2006-04-12  0:50 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2006-04-12  0:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

This change should fix the AIX testcase failures caused by weird
subregs, by simply not generating them in the first place.

This testcase (-m32 -O2 -mcall-aixdesc -mxl-compat on linux)
  extern int g();
  void f (void) { g (0, 0.0, 0.0, 0.0, 0.0); }
ICEs since Dale's reg alloc changes when trying to handle the last
double arg stored partially in memory and partially in a gpr as well as
in a fpr.

Bootstrapped and regression tested powerpc-linux and powerpc64-linux.
OK mainline?

	* config/rs6000/rs6000.c (rs6000_mixed_function_arg): Update
	magic NULL_RTX comment.
	(function_arg): Store entire fp arg to mem if any part should go
	on stack.
	(rs6000_arg_partial_bytes): Adjust for above change.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 112849)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -5058,17 +5072,13 @@ rs6000_mixed_function_arg (enum machine_
   if (align_words + n_units > GP_ARG_NUM_REG)
     /* Not all of the arg fits in gprs.  Say that it goes in memory too,
        using a magic NULL_RTX component.
-       FIXME: This is not strictly correct.  Only some of the arg
-       belongs in memory, not all of it.  However, there isn't any way
-       to do this currently, apart from building rtx descriptions for
-       the pieces of memory we want stored.  Due to bugs in the generic
-       code we can't use the normal function_arg_partial_nregs scheme
-       with the PARALLEL arg description we emit here.
-       In any case, the code to store the whole arg to memory is often
-       more efficient than code to store pieces, and we know that space
-       is available in the right place for the whole arg.  */
-    /* FIXME: This should be fixed since the conversion to
-       TARGET_ARG_PARTIAL_BYTES.  */
+       This is not strictly correct.  Only some of the arg belongs in
+       memory, not all of it.  However, the normal scheme using
+       function_arg_partial_nregs can result in unusual subregs, eg.
+       (subreg:SI (reg:DF) 4), which are not handled well.  The code to
+       store the whole arg to memory is often more efficient than code
+       to store pieces, and we know that space is available in the right
+       place for the whole arg.  */
     rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
 
   i = 0;
@@ -5310,9 +5320,8 @@ function_arg (CUMULATIVE_ARGS *cum, enum
 			 include the portion actually in registers here.  */
 		      enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
 		      rtx off;
-		      int i=0;
-		      if (align_words + n_words > GP_ARG_NUM_REG
-			  && (TARGET_32BIT && TARGET_POWERPC64))
+		      int i = 0;
+		      if (align_words + n_words > GP_ARG_NUM_REG)
 			/* Not all of the arg fits in gprs.  Say that it
 			   goes in memory too, using a magic NULL_RTX
 			   component.  Also see comment in
@@ -5391,18 +5400,20 @@ rs6000_arg_partial_bytes (CUMULATIVE_ARG
 
   align_words = rs6000_parm_start (mode, type, cum->words);
 
-  if (USE_FP_FOR_ARG_P (cum, mode, type)
+  if (USE_FP_FOR_ARG_P (cum, mode, type))
+    {
       /* If we are passing this arg in the fixed parameter save area
 	 (gprs or memory) as well as fprs, then this function should
-	 return the number of bytes passed in the parameter save area
-	 rather than bytes passed in fprs.  */
-      && !(type
-	   && (cum->nargs_prototype <= 0
-	       || (DEFAULT_ABI == ABI_AIX
-		   && TARGET_XL_COMPAT
-		   && align_words >= GP_ARG_NUM_REG))))
-    {
-      if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3) > FP_ARG_MAX_REG + 1)
+	 return the number of partial bytes passed in the parameter
+	 save area rather than partial bytes passed in fprs.  */
+      if (type
+	  && (cum->nargs_prototype <= 0
+	      || (DEFAULT_ABI == ABI_AIX
+		  && TARGET_XL_COMPAT
+		  && align_words >= GP_ARG_NUM_REG)))
+	return 0;
+      else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
+	       > FP_ARG_MAX_REG + 1)
 	ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
       else if (cum->nargs_prototype >= 0)
 	return 0;

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [RFT/RFA] Fix AIX fallout from PR/19653 patch
@ 2006-04-04 16:21 Paolo Bonzini
  2006-04-04 17:52 ` David Edelsohn
  2006-04-05  2:20 ` Alan Modra
  0 siblings, 2 replies; 875+ messages in thread
From: Paolo Bonzini @ 2006-04-04 16:21 UTC (permalink / raw)
  To: GCC Patches; +Cc: David Edelsohn

[-- Attachment #1: Type: text/plain, Size: 1349 bytes --]

This patch fixes numerous failures that the PR/19653 patch introduced on 
AIX.  The failures could in principle be visible on other rs6000 
subtargets that have TOC, but looking at posted testresults these seem 
unaffected.

The problem is that constant_pool_expr_p returns true if a SYMBOL_REF is 
present in its argument; on the other hand, its users all call 
get_pool_constant on the same argument as if it was a SYMBOL_REF:

   ...
   else if (TARGET_TOC
           && constant_pool_expr_p (x)
           && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), 
Pmode))
   ...

This looks like a latent bug to me, but I have not yet investigate why, 
after the PR/19653 patch, we are requesting legitimization of a (const 
(plus (symbol_ref LC..0) (const_int 4))).  I think it is Dale's regclass 
changes, but I'm not sure.

Since constant_pool_expr_p calls ASM_OUTPUT_SPECIAL_POOL_ENTRY_P, but 
always with Pmode mode, my solution is to add an argument to 
constant_pool_expr_p so that it calls ASM_OUTPUT_SPECIAL_POOL_ENTRY_P 
with the correct mode.  This fixes the failing testcases I tried it on, 
but I am not familiar with these parts of the back-ends and I am not 
sure it is correct.  `svn annotate' has not been helpful in decyphering 
the history of these bits.

David, can you bootstrap this?  Ok for mainline if it works?

Paolo

[-- Attachment #2: fix-toc-bug.patch --]
[-- Type: text/plain, Size: 6225 bytes --]

This patch fixes numerous failures that the PR/19653 patch introduced on
AIX.  The failures could in principle be visible on other rs6000 subtargets
that have TOC, but looking at posted testresults these seem unaffected.

The problem is that constant_pool_expr_p returns true if a SYMBOL_REF
is present in its argument; on the other hand, its users all call
get_pool_constant on the same argument as if it was a SYMBOL_REF:

   ...
   else if (TARGET_TOC
           && constant_pool_expr_p (x)
           && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
   ...

This looks like a latent bug to me, but it may as well be a problem with
my reload changes (or Dale's regclass change -- could be as likely).

Since constant_pool_expr_p calls ASM_OUTPUT_SPECIAL_POOL_ENTRY_P, but always
with Pmode mode, my solution is to add an argument to constant_pool_expr_p
so that it calls ASM_OUTPUT_SPECIAL_POOL_ENTRY_P with the correct mode.
This fixes the failing testcases I tried it on, but I am not familiar with
these parts of the back-ends and I am not sure it is correct.  `svn
annotate' has not been helpful in decyphering the history of these bits.

David, can you bootstrap this?  Ok for mainline if it works?

Paolo

2006-04-04  Paolo Bonzini  <bonzini@gnu.org>

	* rs6000.c (constant_pool_expr_1): Add MODE parameter defaulting
	to the pool constant's mode.
	(constant_pool_expr_p): Add a MODE parameter, pass it.
	(toc_relative_expr_p): Adjust call.
	(legitimate_constant_pool_address_p, rs6000_legitimize_reload_address,
	rs6000_emit_move): Merge invocations of ASM_OUTPUT_SPECIAL_POOL_ENTRY_P
	with preceding calls to constant_pool_expr_p.

Index: rs6000.c
===================================================================
--- rs6000.c	(revision 112658)
+++ rs6000.c	(working copy)
@@ -588,8 +588,8 @@ static void rs6000_emit_allocate_stack (
 static unsigned rs6000_hash_constant (rtx);
 static unsigned toc_hash_function (const void *);
 static int toc_hash_eq (const void *, const void *);
-static int constant_pool_expr_1 (rtx, int *, int *);
-static bool constant_pool_expr_p (rtx);
+static int constant_pool_expr_1 (rtx, enum machine_mode, int *, int *);
+static bool constant_pool_expr_p (rtx, enum machine_mode);
 static bool legitimate_small_data_p (enum machine_mode, rtx);
 static bool legitimate_indexed_address_p (rtx, int);
 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
@@ -2642,7 +2642,8 @@ gpr_or_gpr_p (rtx op0, rtx op1)
 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address.  */
 
 static int
-constant_pool_expr_1 (rtx op, int *have_sym, int *have_toc)
+constant_pool_expr_1 (rtx op, enum machine_mode mode,
+		      int *have_sym, int *have_toc)
 {
   switch (GET_CODE (op))
     {
@@ -2651,7 +2652,9 @@ constant_pool_expr_1 (rtx op, int *have_
 	return 0;
       else if (CONSTANT_POOL_ADDRESS_P (op))
 	{
-	  if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
+	  if (mode == VOIDmode)
+	    mode = get_pool_mode (op);
+	  if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), mode))
 	    {
 	      *have_sym = 1;
 	      return 1;
@@ -2668,10 +2671,10 @@ constant_pool_expr_1 (rtx op, int *have_
 	return 0;
     case PLUS:
     case MINUS:
-      return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
-	      && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
+      return (constant_pool_expr_1 (XEXP (op, 0), mode, have_sym, have_toc)
+	      && constant_pool_expr_1 (XEXP (op, 1), mode, have_sym, have_toc));
     case CONST:
-      return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
+      return constant_pool_expr_1 (XEXP (op, 0), mode, have_sym, have_toc);
     case CONST_INT:
       return 1;
     default:
@@ -2680,11 +2683,11 @@ constant_pool_expr_1 (rtx op, int *have_
 }
 
 static bool
-constant_pool_expr_p (rtx op)
+constant_pool_expr_p (rtx op, enum machine_mode mode)
 {
   int have_sym = 0;
   int have_toc = 0;
-  return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
+  return constant_pool_expr_1 (op, mode, &have_sym, &have_toc) && have_sym;
 }
 
 bool
@@ -2692,7 +2695,7 @@ toc_relative_expr_p (rtx op)
 {
   int have_sym = 0;
   int have_toc = 0;
-  return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
+  return constant_pool_expr_1 (op, Pmode, &have_sym, &have_toc) && have_toc;
 }
 
 bool
@@ -2702,7 +2705,7 @@ legitimate_constant_pool_address_p (rtx 
 	  && GET_CODE (x) == PLUS
 	  && GET_CODE (XEXP (x, 0)) == REG
 	  && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
-	  && constant_pool_expr_p (XEXP (x, 1)));
+	  && constant_pool_expr_p (XEXP (x, 1), Pmode));
 }
 
 static bool
@@ -3005,8 +3008,7 @@ rs6000_legitimize_address (rtx x, rtx ol
       return gen_rtx_LO_SUM (Pmode, reg, x);
     }
   else if (TARGET_TOC
-	   && constant_pool_expr_p (x)
-	   && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
+	   && constant_pool_expr_p (x, Pmode))
     {
       return create_TOC_reference (x);
     }
@@ -3440,8 +3442,7 @@ rs6000_legitimize_reload_address (rtx x,
     }
 
   if (TARGET_TOC
-      && constant_pool_expr_p (x)
-      && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
+      && constant_pool_expr_p (x, mode))
     {
       (x) = create_TOC_reference (x);
       *win = 1;
@@ -4112,9 +4113,7 @@ rs6000_emit_move (rtx dest, rtx source, 
 	 reference to it.  */
       if (TARGET_TOC
 	  && GET_CODE (operands[1]) == SYMBOL_REF
-	  && constant_pool_expr_p (operands[1])
-	  && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
-					      get_pool_mode (operands[1])))
+	  && constant_pool_expr_p (operands[1], VOIDmode))
 	{
 	  operands[1] = create_TOC_reference (operands[1]);
 	}
@@ -4179,10 +4178,7 @@ rs6000_emit_move (rtx dest, rtx source, 
 	  operands[1] = force_const_mem (mode, operands[1]);
 
 	  if (TARGET_TOC
-	      && constant_pool_expr_p (XEXP (operands[1], 0))
-	      && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
-			get_pool_constant (XEXP (operands[1], 0)),
-			get_pool_mode (XEXP (operands[1], 0))))
+	      && constant_pool_expr_p (XEXP (operands[1], 0), VOIDmode))
 	    {
 	      operands[1]
 		= gen_const_mem (mode,

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PowerPC] PR26459 again
@ 2006-03-30 14:20 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2006-03-30 14:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

I believe this is a better fix for PR26459 than the one I installed,
which really didn't fix the root cause of the problem.  Apologies for
not analysing the problem sufficiently.  The problem with the existing
rs6000 CANNOT_CHANGE_MODE_CLASS is that when !TARGET_IEEEQUAD, the
DF->DI and DI->DF insns that are supposed to be caught by the
TARGET_E500_DOUBLE lines never get that far.  Instead, they match the
first test and return a zero.  Geoff added the first few lines of
CANNOT_CHANGE_MODE_CLASS with a changelog of
    PR target/11848
    * rs6000.h (CANNOT_CHANGE_MODE_CLASS): Allow change of mode
    in floating-point registers between TFmode and DImode.
so it seems to me that the following change will still do as Geoff
intended without the side effect of breaking linuxspe.

Bootstrapped and regression tested on 4.1 powerpc-linux and
powerpc64-linux.  Built powerpc-linux -> powerpc-linuxspe cross to test
pr26459, and i686-linux -> powerpc-darwin cross to test pr11848
testcase.  OK mainline and 4.1?  My previous patch won't do any harm
if it stays applied.

	PR target/26459
	* config/rs6000/rs6000.h (CANNOT_CHANGE_MODE_CLASS): Limit 2003-12-08
	change to FLOAT_REGS.

Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(revision 112399)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -1213,22 +1241,19 @@ enum reg_class
   ? 1                                                                   \
   : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
 
+/* Return nonzero if for CLASS a mode change from FROM to TO is invalid.  */
 
-/* Return a class of registers that cannot change FROM mode to TO mode.  */
-
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)			  \
-  (!TARGET_IEEEQUAD							  \
-   && GET_MODE_SIZE (FROM) >= 8 && GET_MODE_SIZE (TO) >= 8		  \
-   ? 0									  \
-   : GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)				  \
-   ? reg_classes_intersect_p (FLOAT_REGS, CLASS)			  \
-   : (TARGET_E500_DOUBLE && (((TO) == DFmode) + ((FROM) == DFmode)) == 1) \
-   ? reg_classes_intersect_p (GENERAL_REGS, CLASS)			  \
-   : (TARGET_E500_DOUBLE && (((TO) == DImode) + ((FROM) == DImode)) == 1) \
-   ? reg_classes_intersect_p (GENERAL_REGS, CLASS)			  \
-   : (TARGET_SPE && (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1) \
-   ? reg_classes_intersect_p (GENERAL_REGS, CLASS)			  \
-   : 0)
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)			\
+  (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)				\
+   ? ((GET_MODE_SIZE (FROM) < 8 || GET_MODE_SIZE (TO) < 8		\
+       || TARGET_IEEEQUAD)						\
+      && reg_classes_intersect_p (FLOAT_REGS, CLASS))			\
+   : (((TARGET_E500_DOUBLE						\
+	&& ((((TO) == DFmode) + ((FROM) == DFmode)) == 1		\
+	    || (((TO) == DImode) + ((FROM) == DImode)) == 1))		\
+       || (TARGET_SPE							\
+	   && (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1))	\
+      && reg_classes_intersect_p (GENERAL_REGS, CLASS)))
 
 /* Stack layout; function entry, exit and calling.  */
 

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PowerPC] linuxspe vs. ibm long double.
@ 2006-03-30  4:42 Alan Modra
  2006-03-30 12:51 ` Joseph S. Myers
  0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2006-03-30  4:42 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

This patch fixes a problem I noticed when fiddling with PR26459, namely,
that -mabi=ieeelongdouble or -mabi=ibmlongdouble stops the default
setting of rs6000_spe_abi.  Accomplished by only setting
rs6000_explicit_options.abi when -mabi=spe/no-spe/altivec is given,
and using a separate field in rs6000_explicit_options for
-mabi=ibmlongdouble/ieeelongdouble.  I figure that is reasonable to
separate the ieee/ibm long double selection from other abi selection.

I also select IEEE long double for linux spe by default, because the
E500 ABI doc quite clearly states that while other long double formats
may be used by the compiler that they must not be the default.  Whether
compatibilty with the ABI matters more than compatibility with the new
linux default is arguable, but I'm inclined to favour E500 ABI
compatibility over linux compatibility in this case.

Tested with a powerpc-linux -> powerpc-linuxspe cross build.  OK for
mainline?  4.1 too?

	* config/rs6000/rs6000.c (rs6000_explicit_options): Add ieee.
	(rs6000_override_options): Use it.
	(rs6000_handle_option): Set it.  Set rs6000_explicit_options.abi
	only for -mabi=spe/no-spe and -mabi=altivec.
	* config/rs6000/linuxspe.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Set
	rs6000_ieeequad when spe abi.

Index: gcc/config/rs6000/linuxspe.h
===================================================================
--- gcc/config/rs6000/linuxspe.h	(revision 112399)
+++ gcc/config/rs6000/linuxspe.h	(working copy)
@@ -49,6 +49,8 @@
     rs6000_cpu = PROCESSOR_PPC8540; \
   if (!rs6000_explicit_options.abi) \
     rs6000_spe_abi = 1; \
+  if (rs6000_spe_abi && !rs6000_explicit_options.ieee) \
+    rs6000_ieeequad = 1; \
   if (!rs6000_explicit_options.float_gprs) \
     rs6000_float_gprs = 1; \
   /* See note below.  */ \
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 112399)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -249,11 +249,12 @@ int rs6000_alignment_flags;
 struct {
   bool aix_struct_ret;		/* True if -maix-struct-ret was used.  */
   bool alignment;		/* True if -malign- was used.  */
-  bool abi;			/* True if -mabi= was used.  */
+  bool abi;			/* True if -mabi=spe/nospe was used.  */
   bool spe;			/* True if -mspe= was used.  */
   bool float_gprs;		/* True if -mfloat-gprs= was used.  */
   bool isel;			/* True if -misel was used. */
   bool long_double;	        /* True if -mlong-double- was used.  */
+  bool ieee;			/* True if -mabi=ieee/ibmlongdouble used.  */
 } rs6000_explicit_options;
 
 struct builtin_description
@@ -1292,7 +1293,7 @@ rs6000_override_options (const char *def
     rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
 
 #ifndef POWERPC_LINUX
-  if (!rs6000_explicit_options.abi)
+  if (!rs6000_explicit_options.ieee)
     rs6000_ieeequad = 1;
 #endif
 
@@ -1750,23 +1751,31 @@ rs6000_handle_option (size_t code, const
 #endif
 
     case OPT_mabi_:
-      rs6000_explicit_options.abi = true;
       if (!strcmp (arg, "altivec"))
 	{
+	  rs6000_explicit_options.abi = true;
 	  rs6000_altivec_abi = 1;
 	  rs6000_spe_abi = 0;
 	}
       else if (! strcmp (arg, "no-altivec"))
-	rs6000_altivec_abi = 0;
+	{
+	  /* ??? Don't set rs6000_explicit_options.abi here, to allow
+	     the default for rs6000_spe_abi to be chosen later.  */
+	  rs6000_altivec_abi = 0;
+	}
       else if (! strcmp (arg, "spe"))
 	{
+	  rs6000_explicit_options.abi = true;
 	  rs6000_spe_abi = 1;
 	  rs6000_altivec_abi = 0;
 	  if (!TARGET_SPE_ABI)
 	    error ("not configured for ABI: '%s'", arg);
 	}
       else if (! strcmp (arg, "no-spe"))
-	rs6000_spe_abi = 0;
+	{
+	  rs6000_explicit_options.abi = true;
+	  rs6000_spe_abi = 0;
+	}
 
       /* These are here for testing during development only, do not
 	 document in the manual please.  */
@@ -1783,11 +1792,13 @@ rs6000_handle_option (size_t code, const
 
       else if (! strcmp (arg, "ibmlongdouble"))
 	{
+	  rs6000_explicit_options.ieee = true;
 	  rs6000_ieeequad = 0;
 	  warning (0, "Using IBM extended precision long double");
 	}
       else if (! strcmp (arg, "ieeelongdouble"))
 	{
+	  rs6000_explicit_options.ieee = true;
 	  rs6000_ieeequad = 1;
 	  warning (0, "Using IEEE extended precision long double");
 	}

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PowerPC64] Fix 26453, segfault -m64 -mtraceback=full
@ 2006-02-24  2:22 Alan Modra
  2006-02-24  3:57 ` Mark Mitchell
  0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2006-02-24  2:22 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

Fixes a regression from gcc-3.3 introduced with r61058.  Bootstrapped
and regression tested powerpc64-linux.  OK mainline and active branches?

	PR target/26453
	* config/rs6000/rs6000.c (rs6000_output_function_epilogue): Don't
	output traceback table for thunks.  Localise rs6000_stack_info call.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 111347)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -15153,8 +15153,6 @@ static void
 rs6000_output_function_epilogue (FILE *file,
 				 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
 {
-  rs6000_stack_t *info = rs6000_stack_info ();
-
   if (! HAVE_epilogue)
     {
       rtx insn = get_last_insn ();
@@ -15225,13 +15223,14 @@ rs6000_output_function_epilogue (FILE *f
      System V.4 Powerpc's (and the embedded ABI derived from it) use a
      different traceback table.  */
   if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
-      && rs6000_traceback != traceback_none)
+      && rs6000_traceback != traceback_none && !current_function_is_thunk)
     {
       const char *fname = NULL;
       const char *language_string = lang_hooks.name;
       int fixed_parms = 0, float_parms = 0, parm_info = 0;
       int i;
       int optional_tbtab;
+      rs6000_stack_t *info = rs6000_stack_info ();
 
       if (rs6000_traceback == traceback_full)
 	optional_tbtab = 1;

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PowerPC] Fix PR25572, -mminimal-toc trashes r30
@ 2005-12-28 10:31 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2005-12-28 10:31 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

This patch updates regs_ever_live so that the prologue/epilogue code
knows about use of the TOC register created during reload.  Bootstrapped
and regression tested powerpc64-linux.  OK mainline?  OK for 4.1, 4.0
and 3.4 too, after I bootstrap there?

	PR target/25572
	* config/rs6000/rs6000.c (create_TOC_reference): Set regs_ever_live.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 109087)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -13499,6 +13499,8 @@ uses_TOC (void)
 rtx
 create_TOC_reference (rtx symbol)
 {
+  if (no_new_pseudos)
+    regs_ever_live[TOC_REGISTER] = 1;
   return gen_rtx_PLUS (Pmode,
 	   gen_rtx_REG (Pmode, TOC_REGISTER),
 	     gen_rtx_CONST (Pmode,

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PowerPC] Fix 25406, rs6000_special_round_type_align
@ 2005-12-14 14:56 Alan Modra
  2005-12-14 23:50 ` Alan Modra
  0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2005-12-14 14:56 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn, pinskia

This is obvious really, but I'm doing more than just fixing the bug so
I'll ask permission to commit.  Every place ROUND_TYPE_ALIGN is invoked,
the alignment values are unsigned int, so it makes sense for
rs6000_special_round_type_align to have unsigned int args.

Tested by running make "check-gcc" on powerpc64-linux with site.exp
supplying GCC_UNDER_TEST to use -malign-power, and with TYPE_MODE
in the patch below (and in ADJUST_FIELD_ALIGN) replaced with
MY_TYPE_MODE.

#define MY_TYPE_MODE(X) (!TYPE_P (X) ? abort (), SImode : TYPE_MODE (X))

ie. Effectively turning on rtl checking just here.  A full
powerpc64-linux bootstrap takes forever with --enable-checking=all.

	* config/rs6000/rs6000.c (rs6000_special_round_type_align): Handle
	error_mark_node.  Make alignment params unsigned.
	* config/rs6000/rs6000-protos.h
	(rs6000_special_round_type_align): Update prototype.
	(rs6000_machopic_legitimize_pic_address): Remove arg names.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 108499)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -2505,21 +2505,27 @@ invalid_e500_subreg (rtx op, enum machin
    field is an FP double while the FP fields remain word aligned.  */
 
 unsigned int
-rs6000_special_round_type_align (tree type, int computed, int specified)
+rs6000_special_round_type_align (tree type, unsigned int computed,
+				 unsigned int specified)
 {
+  unsigned int align = MAX (computed, specified);
   tree field = TYPE_FIELDS (type);
 
   /* Skip all non field decls */
   while (field != NULL && TREE_CODE (field) != FIELD_DECL)
     field = TREE_CHAIN (field);
 
-  if (field == NULL || field == type
-      || TYPE_MODE (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
-		    ? get_inner_array_type (field)
-		    : TREE_TYPE (field)) != DFmode)
-    return MAX (computed, specified);
+  if (field != NULL && field != type)
+    {
+      type = TREE_TYPE (field);
+      while (TREE_CODE (type) == ARRAY_TYPE)
+	type = TREE_TYPE (type);
+
+      if (type != error_mark_node && TYPE_MODE (type) == DFmode)
+	align = MAX (align, 64);
+    }
 
-  return MAX (MAX (computed, specified), 64);
+  return align;
 }
 
 /* Return 1 for an operand in small memory on V.4/eabi.  */
Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
--- gcc/config/rs6000/rs6000-protos.h	(revision 108499)
+++ gcc/config/rs6000/rs6000-protos.h	(working copy)
@@ -105,14 +105,13 @@ extern rtx rs6000_return_addr (int, rtx)
 extern void rs6000_output_symbol_ref (FILE*, rtx);
 extern HOST_WIDE_INT rs6000_initial_elimination_offset (int, int);
 
-extern rtx rs6000_machopic_legitimize_pic_address (rtx orig,
-						   enum machine_mode mode,
-						   rtx reg);
-
+extern rtx rs6000_machopic_legitimize_pic_address (rtx, enum machine_mode,
+						   rtx);
 #endif /* RTX_CODE */
 
 #ifdef TREE_CODE
-extern unsigned int rs6000_special_round_type_align (tree, int, int);
+extern unsigned int rs6000_special_round_type_align (tree, unsigned int,
+						     unsigned int);
 extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
 				  tree, int, int);
 extern int function_arg_boundary (enum machine_mode, tree);

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PowerPC] Default TARGET_ALIGN_NATURAL properly for target libs.
@ 2005-12-09  1:59 Alan Modra
  2005-12-09 16:15 ` Andrew Pinski
  0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2005-12-09  1:59 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

I noticed this when looking at PR25299.  Since powerpc64-linux now
defaults to natural alignment, we ought to compile target libs like
that.  Not that it really matters, because I don't think we have any
structs that start with a double.  Still..

Bootstrap in progress.  OK mainline?

	* config/rs6000/linux64.h (TARGET_ALIGN_NATURAL): Define.

Index: gcc/config/rs6000/linux64.h
===================================================================
--- gcc/config/rs6000/linux64.h	(revision 108256)
+++ gcc/config/rs6000/linux64.h	(working copy)
@@ -236,6 +239,12 @@ extern int dot_symbols;
    ? rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED)	\
    : MAX ((COMPUTED), (SPECIFIED)))
 
+/* Use the default for compiling target libs.  */
+#ifdef IN_TARGET_LIBS
+#undef TARGET_ALIGN_NATURAL
+#define TARGET_ALIGN_NATURAL 1
+#endif
+
 /* Indicate that jump tables go in the text section.  */
 #undef  JUMP_TABLES_IN_TEXT_SECTION
 #define JUMP_TABLES_IN_TEXT_SECTION TARGET_64BIT

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PowerPC] Fix pr25212, indexed address predicates
@ 2005-12-07  5:09 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2005-12-07  5:09 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

pr25212 is an ICE caused by attempting to reload an altivec indexed mem
address as an indirect address.  The resulting reload expression,
(set (reg) (and (plus (reg) (reg)) (const_int))), is too complex for any
rs6000 insn, and reload itself doesn't try to simplify it.

The root cause of this problem is that reload is tossing out a perfectly
good indexed address as invalid, because the rs6000 predicates are too
restrictive during reload:  legitimate_indexed_address_p only allows
valid base/index hard regs, or pseudos (and the PLUS I added for
pr24997).  In particular, they disallow invalid hard regs such as lr,
yet reload will arrange for an invalid reg to be reloaded into a valid
one.  All MEMs are processed by find_reloads_address early in
find_reloads.

So, as Ian Lance Taylor suggested, this patch simply relaxes the
predicate to accept more indexed addresses when !strict, trusting that
reload will ensure they match in the strict sense after reloading.  No
doubt other powerpc predicates could also be relaxed similarly, but I'll
leave that to later sometime when I feel like wrestling with reload
again.

As mentioned previously this also fixes INT_REG_OK_FOR_BASE_P, which can
return true for a pseudo reg that has reg_renumber[REGNO] == 0.

This has passed a "make quickstrap" followed by "make check" in gcc/,
ie. running gcc, g++, gfortran, objc testsuites without regressions on
both powerpc-linux and powerpc64-linux.  I'm running full bootstraps as
well, but these haven't completed.  OK for mainline and 4.1?

:ADDPATCH target:

	PR target/25212
	* config/rs6000/rs6000.c (legitimate_indexed_address_p): Relax
	tests further when !strict && reload_in_progress.
	(print_operand): Check that both operands of indexed address are regs.
	(print_operand_address): Likewise.
	* config/rs6000/rs6000.h (INT_REG_OK_FOR_INDEX_P): Simplify.
	(INT_REG_OK_FOR_BASE_P): Correct.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 108055)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -2726,23 +2726,19 @@ legitimate_indexed_address_p (rtx x, int
   op0 = XEXP (x, 0);
   op1 = XEXP (x, 1);
 
-  if (REG_P (op0) && REG_P (op1))
-    return ((INT_REG_OK_FOR_BASE_P (op0, strict)
-	     && INT_REG_OK_FOR_INDEX_P (op1, strict))
-	    || (INT_REG_OK_FOR_BASE_P (op1, strict)
-		&& INT_REG_OK_FOR_INDEX_P (op0, strict)));
-
   /* Recognize the rtl generated by reload which we know will later be
-     replaced by a base reg.  We rely on nothing but reload generating
-     this particular pattern, a reasonable assumption because it is not
-     canonical.  */
-  else if (reload_in_progress
-	   && GET_CODE (op0) == PLUS
-	   && REG_P (XEXP (op0, 0))
 -	   && GET_CODE (XEXP (op0, 1)) == CONST_INT
-	   && REG_P (op1))
-    return INT_REG_OK_FOR_INDEX_P (op1, strict);
-  return false;
+     replaced with proper base and index regs.  */
+  if (!strict
+      && reload_in_progress
+      && (REG_P (op0) || GET_CODE (op0) == PLUS)
+      && REG_P (op1))
+    return true;
+
+  return (REG_P (op0) && REG_P (op1)
+	  && ((INT_REG_OK_FOR_BASE_P (op0, strict)
+	       && INT_REG_OK_FOR_INDEX_P (op1, strict))
+	      || (INT_REG_OK_FOR_BASE_P (op1, strict)
+		  && INT_REG_OK_FOR_INDEX_P (op0, strict))));
 }
 
 inline bool
@@ -10667,7 +10677,8 @@ print_operand (FILE *file, rtx x, int co
 	else
 	  {
 	    gcc_assert (GET_CODE (tmp) == PLUS
-			&& GET_CODE (XEXP (tmp, 1)) == REG);
+			&& REG_P (XEXP (tmp, 0))
+			&& REG_P (XEXP (tmp, 1)));
 
 	    if (REGNO (XEXP (tmp, 0)) == 0)
 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
@@ -10727,6 +10738,7 @@ print_operand_address (FILE *file, rtx x
     }
   else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
     {
+      gcc_assert (REG_P (XEXP (x, 0)));
       if (REGNO (XEXP (x, 0)) == 0)
 	fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
 		 reg_names[ REGNO (XEXP (x, 0)) ]);
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(revision 108055)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -1723,17 +1751,14 @@ typedef struct rs6000_args
 /* Nonzero if X is a hard reg that can be used as an index
    or if it is a pseudo reg in the non-strict case.  */
 #define INT_REG_OK_FOR_INDEX_P(X, STRICT)			\
-  ((! (STRICT)							\
-    && (REGNO (X) <= 31						\
-	|| REGNO (X) == ARG_POINTER_REGNUM			\
-	|| REGNO (X) == FRAME_POINTER_REGNUM			\
-	|| REGNO (X) >= FIRST_PSEUDO_REGISTER))			\
-   || ((STRICT) && REGNO_OK_FOR_INDEX_P (REGNO (X))))
+  ((!(STRICT) && REGNO (X) >= FIRST_PSEUDO_REGISTER)		\
+   || REGNO_OK_FOR_INDEX_P (REGNO (X)))
 
 /* Nonzero if X is a hard reg that can be used as a base reg
    or if it is a pseudo reg in the non-strict case.  */
 #define INT_REG_OK_FOR_BASE_P(X, STRICT)			\
-  (REGNO (X) > 0 && INT_REG_OK_FOR_INDEX_P (X, (STRICT)))
+  ((!(STRICT) && REGNO (X) >= FIRST_PSEUDO_REGISTER)		\
+   || REGNO_OK_FOR_BASE_P (REGNO (X)))
 
 #define REG_OK_FOR_INDEX_P(X) INT_REG_OK_FOR_INDEX_P (X, REG_OK_STRICT_FLAG)
 #define REG_OK_FOR_BASE_P(X)  INT_REG_OK_FOR_BASE_P (X, REG_OK_STRICT_FLAG)

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PowerPC] PR24997: ICE with -ftree-vectorize
@ 2005-11-28  2:26 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2005-11-28  2:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

This patch fixes an ICE and also makes better use of indexed addressing
modes.  See http://gcc.gnu.org/ml/gcc/2005-11/msg01218.html.  While
making the necessary change to indexed_or_indirect_operand, I noticed
indexed_or_indirect_address and saw that it too should accept reloaded
indexed addresses, so I factored that code out.  Also, testing
address_operand after we have discarded address patterns we won't match
should speed the compiler a little.  address_operand calls
rs6000_legitimate_address which is reasonably complex.

Notes: 1) Using define_special_predicate for indexed_or_indirect_address
avoids relying on gen-preds noticing that it is special from the
address_operand call.  I originally put the address_operand call inside
the match_test, and managed to get an ICE due to gen-preds adding mode
tests that we don't want.  Calling address_operand via rtl lets
gen-preds see the call, so define_special_prediciate isn't necessary but
I figure it is safer to mark it so.
2) Removing memory_operand from indexed_or_indirect_operand doesn't lose
us anything.  We get the same tests via address_operand.

Bootstrapped and regression tested powerpc64-linux.  OK for 4.2 and 4.1?
Can this go on 4.0 too?  I believe that the same problem exists in 4.0,
but just isn't triggered with the pr24997 testcase.

	PR target/24997
	* config/rs6000/rs6000.c (legitimate_indexed_address_p): Allow pattern
	generated by reload.
	* config/rs6000/predicates.md (indexed_or_indirect_operand): Use
	indexed_or_indirect_address.
	(indexed_or_indirect_address): Don't test for base reg.  Call
	address_operand last.  Make explicit that this is a special predicate.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 107562)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -2731,13 +2730,23 @@ legitimate_indexed_address_p (rtx x, int
   op0 = XEXP (x, 0);
   op1 = XEXP (x, 1);
 
-  if (!REG_P (op0) || !REG_P (op1))
-    return false;
-
-  return ((INT_REG_OK_FOR_BASE_P (op0, strict)
-	   && INT_REG_OK_FOR_INDEX_P (op1, strict))
-	  || (INT_REG_OK_FOR_BASE_P (op1, strict)
-	      && INT_REG_OK_FOR_INDEX_P (op0, strict)));
+  if (REG_P (op0) && REG_P (op1))
+    return ((INT_REG_OK_FOR_BASE_P (op0, strict)
+	     && INT_REG_OK_FOR_INDEX_P (op1, strict))
+	    || (INT_REG_OK_FOR_BASE_P (op1, strict)
+		&& INT_REG_OK_FOR_INDEX_P (op0, strict)));
+
+  /* Recognize the rtl generated by reload which we know will later be
+     replaced by a base reg.  We rely on nothing but reload generating
+     this particular pattern, a reasonable assumption because it is not
+     canonical.  */
+  else if (reload_in_progress
+	   && GET_CODE (op0) == PLUS
+	   && REG_P (XEXP (op0, 0))
+	   && GET_CODE (XEXP (op0, 1)) == CONST_INT
+	   && REG_P (op1))
+    return INT_REG_OK_FOR_INDEX_P (op1, strict);
+  return false;
 }
 
 inline bool
Index: gcc/config/rs6000/predicates.md
===================================================================
--- gcc/config/rs6000/predicates.md	(revision 107562)
+++ gcc/config/rs6000/predicates.md	(working copy)
@@ -353,25 +353,6 @@
 					   || reload_in_progress,
 					   mode, XEXP (op, 0))")))
 
-;; Return 1 if the operand is an indexed or indirect memory operand.
-(define_predicate "indexed_or_indirect_operand"
-  (match_operand 0 "memory_operand")
-{
-  rtx tmp = XEXP (op, 0);
-
-  if (TARGET_ALTIVEC
-      && ALTIVEC_VECTOR_MODE (mode)
-      && GET_CODE (tmp) == AND
-      && GET_CODE (XEXP (tmp, 1)) == CONST_INT
-      && INTVAL (XEXP (tmp, 1)) == -16)
-    tmp = XEXP (tmp, 0);
-
-    return REG_P (tmp)
-		  || (GET_CODE (tmp) == PLUS
-		      && REG_P (XEXP (tmp, 0)) 
-		      && REG_P (XEXP (tmp, 1)));
-})
-
 ;; Return 1 if the operand is a memory operand with an address divisible by 4
 (define_predicate "word_offset_memref_operand"
   (and (match_operand 0 "memory_operand")
@@ -380,13 +361,28 @@
 		    || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT
 		    || INTVAL (XEXP (XEXP (op, 0), 1)) % 4 == 0")))
 
+;; Return 1 if the operand is an indexed or indirect memory operand.
+(define_predicate "indexed_or_indirect_operand"
+  (match_code "mem")
+{
+  op = XEXP (op, 0);
+  if (TARGET_ALTIVEC
+      && ALTIVEC_VECTOR_MODE (mode)
+      && GET_CODE (op) == AND
+      && GET_CODE (XEXP (op, 1)) == CONST_INT
+      && INTVAL (XEXP (op, 1)) == -16)
+    op = XEXP (op, 0);
+
+  return indexed_or_indirect_address (op, mode);
+})
+
 ;; Return 1 if the operand is an indexed or indirect address.
-(define_predicate "indexed_or_indirect_address"
-  (and (match_operand 0 "address_operand")
-       (match_test "REG_P (op)
+(define_special_predicate "indexed_or_indirect_address"
+  (and (match_test "REG_P (op)
 		    || (GET_CODE (op) == PLUS
-			&& REG_P (XEXP (op, 0)) 
-			&& REG_P (XEXP (op, 1)))")))
+			/* Omit testing REG_P (XEXP (op, 0)).  */
+			&& REG_P (XEXP (op, 1)))")
+       (match_operand 0 "address_operand")))
 
 ;; Used for the destination of the fix_truncdfsi2 expander.
 ;; If stfiwx will be used, the result goes to memory; otherwise,

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [RS6000] Add some more functions to ppc64-fp.c
@ 2005-11-25  4:49 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2005-11-25  4:49 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

This provides the extra ppc64 DImode functions corresponding to the
libgcc2 additions Joseph made in
http://gcc.gnu.org/ml/gcc-patches/2005-11/msg01538.html

	* config/rs6000/ppc64-fp.c (__floatunditf): New function.
	(__floatundidf, __floatundisf): Likewise.

Bootstrapped and regression tested powerpc64-linux.  OK to apply?

Index: gcc/config/rs6000/ppc64-fp.c
===================================================================
--- gcc/config/rs6000/ppc64-fp.c	(revision 107416)
+++ gcc/config/rs6000/ppc64-fp.c	(working copy)
@@ -39,8 +39,11 @@ extern DItype __fixsfdi (SFtype);
 extern USItype __fixunsdfsi (DFtype);
 extern USItype __fixunssfsi (SFtype);
 extern TFtype __floatditf (DItype);
+extern TFtype __floatunditf (UDItype);
 extern DFtype __floatdidf (DItype);
+extern DFtype __floatundidf (UDItype);
 extern SFtype __floatdisf (DItype);
+extern SFtype __floatundisf (UDItype);
 extern DItype __fixunstfdi (TFtype);
 
 static DItype local_fixunssfdi (SFtype);
@@ -100,6 +103,18 @@ __floatditf (DItype u)
   return (TFtype) dh + (TFtype) dl;
 }
 
+TFtype
+__floatunditf (UDItype u)
+{
+  DFtype dh, dl;
+
+  dh = (USItype) (u >> (sizeof (SItype) * 8));
+  dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
+  dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
+
+  return (TFtype) dh + (TFtype) dl;
+}
+
 DFtype
 __floatdidf (DItype u)
 {
@@ -112,6 +127,18 @@ __floatdidf (DItype u)
   return d;
 }
 
+DFtype
+__floatundidf (UDItype u)
+{
+  DFtype d;
+
+  d = (USItype) (u >> (sizeof (SItype) * 8));
+  d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
+  d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
+
+  return d;
+}
+
 SFtype
 __floatdisf (DItype u)
 {
@@ -137,6 +164,30 @@ __floatdisf (DItype u)
   return (SFtype) f;
 }
 
+SFtype
+__floatundisf (UDItype u)
+{
+  DFtype f;
+
+  if (53 < (sizeof (DItype) * 8)
+      && 53 > ((sizeof (DItype) * 8) - 53 + 24))
+    {
+      if (u >= ((UDItype) 1 << 53))
+        {
+          if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1))
+            {
+              u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1);
+              u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53));
+            }
+        }
+    }
+  f = (USItype) (u >> (sizeof (SItype) * 8));
+  f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
+  f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
+
+  return (SFtype) f;
+}
+
 DItype
 __fixunstfdi (TFtype a)
 {

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PATCH] volatile global register variable
@ 2005-11-09 16:28 David Edelsohn
  2005-11-09 18:13 ` Joseph S. Myers
  2005-11-09 18:41 ` Daniel Jacobowitz
  0 siblings, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2005-11-09 16:28 UTC (permalink / raw)
  To: gcc-patches; +Cc: Mark Mitchell, bergner

	GCC currently generates a warning when one declares a global
register variable as volatile.  The warning cannot be disabled and is
rather uninformative: "don't work as you wish".

	With the new Tree-SSA infrastructure, there now are times when one
needs to declare a variable associated with a global register as volatile.
This patch changes the warning to be protected by an option and disabled
by default.  The warning could be enabled with -Wall, if that is desired.

Okay for mainline?

Thanks, David


	PR 24644
	* common.opt (Wvolatile-register-var): New.
	* varasm.c (make_decl_rtl): Only emit warning when option
	specified.

Index: common.opt
===================================================================
*** common.opt	(revision 106675)
--- common.opt	(working copy)
*************** Wunused-variable
*** 173,178 ****
--- 173,182 ----
  Common Var(warn_unused_variable)
  Warn when a variable is unused
  
+ Wvolatile-register-var
+ Common
+ Warn when a register variable is declared volatile
+ 
  aux-info
  Common Separate
  -aux-info <file>	Emit declaration information into <file>
Index: varasm.c
===================================================================
*** varasm.c	(revision 106675)
--- varasm.c	(working copy)
*************** make_decl_rtl (tree decl)
*** 955,961 ****
  	      error ("global register variable has initial value");
  	    }
  	  if (TREE_THIS_VOLATILE (decl))
! 	    warning (0, "volatile register variables don%'t "
  		     "work as you might wish");
  
  	  /* If the user specified one of the eliminables registers here,
--- 955,962 ----
  	      error ("global register variable has initial value");
  	    }
  	  if (TREE_THIS_VOLATILE (decl))
! 	    warning (OPT_Wvolatile_register_var,
! 		     "volatile register variables don%'t "
  		     "work as you might wish");
  
  	  /* If the user specified one of the eliminables registers here,

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PowerPC] Fix PR23704, -m64 overrides prior -mno-powerpc-gfxopt
@ 2005-11-08  2:55 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2005-11-08  2:55 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

This fixes a testsuite failure rth found.  More commentary in the PR.
Bootstrapped etc. powerpc64-linux.  OK to apply?

	PR target/23704
	* config/rs6000/rs6000.c (rs6000_handle_option <OPT_m64>): Don't
	override prior explicit -mno-powerpc-gfxopt.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 106630)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -1624,9 +1624,9 @@
 #else
     case OPT_m64:
 #endif
-      target_flags |= MASK_POWERPC64 | MASK_POWERPC | MASK_PPC_GFXOPT;
-      target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC
-	| MASK_PPC_GFXOPT;
+      target_flags |= MASK_POWERPC64 | MASK_POWERPC;
+      target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
+      target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
       break;
 
 #ifdef TARGET_USES_AIX64_OPT

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PowerPC64] gcc.c-torture/compile/pr20928.c failure
@ 2005-11-02 23:22 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2005-11-02 23:22 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

gcc.c-torture/compile/pr20928.c fails on PowerPC64 with
Assembler messages:
Error: junk at end of line, first unrecognized character is `-'
The faulty assembler looks like
 .tc bar.N-2147483648[TC],bar+2147483648

This exposes two bugs in the rs6000 backend,
  a) assuming the offset fits in an int, and
  b) assuming that if offset < 0, then -offset > 0, which doesn't hold
     for the minimum integer.

	* config/rs6000/rs6000.c (output_toc): Don't assume "offset" fits
	in an int, use HOST_WIDE_INT and associated print macros.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 106403)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -15588,7 +15588,7 @@
   const char *name = buf;
   const char *real_name;
   rtx base = x;
-  int offset = 0;
+  HOST_WIDE_INT offset = 0;
 
   gcc_assert (!TARGET_NO_TOC);
 
@@ -15855,9 +15855,9 @@
       fprintf (file, "\t.tc %s", real_name);
 
       if (offset < 0)
-	fprintf (file, ".N%d", - offset);
+	fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
       else if (offset)
-	fprintf (file, ".P%d", offset);
+	fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
 
       fputs ("[TC],", file);
     }
@@ -15872,9 +15872,9 @@
     {
       RS6000_OUTPUT_BASENAME (file, name);
       if (offset < 0)
-	fprintf (file, "%d", offset);
+	fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
       else if (offset > 0)
-	fprintf (file, "+%d", offset);
+	fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
     }
   else
     output_addr_const (file, x);

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PowerPC] -msdata=data needless use of .sbss section
@ 2005-10-20 11:00 Alan Modra
  2005-10-20 16:28 ` David Edelsohn
  2005-11-27 23:21 ` Alan Modra
  0 siblings, 2 replies; 875+ messages in thread
From: Alan Modra @ 2005-10-20 11:00 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

This patch fixes an inconsistency between rs6000_elf_in_small_data_p and
ASM_OUTPUT_ALIGNED_LOCAL in the treatment of local items under
-msdata=data.  As the comment in rs6000_elf_in_small_data_p says:
	  /* If it's not public, and we're not going to reference it there,
	     there's no need to put it in the small data section.  */

So there isn't much point in having ASM_OUTPUT_ALIGNED_LOCAL place
static variables in .sbss when -msdata=data.  Bootstrapped and
regression tested powerpc-linux.  OK for 4.2?

	* config/rs6000/sysv4.h (ASM_OUTPUT_ALIGNED_LOCAL): Rename to..
	(ASM_OUTPUT_ALIGNED_DECL_LOCAL): ..this, adding extra parm.  Don't
	output locals to sbss when SDATA_DATA.
	(ASM_OUTPUT_ALIGNED_BSS): Adjust for above.
	* doc/invoke.texi (powerpc msdata-data): Static data doesn't gp in
	small data sections.

diff -urp -xCVS -x'*~' -xTAGS -x'*.info' -x'.#*' gcc-virgin/gcc/config/rs6000/sysv4.h gcc-current/gcc/config/rs6000/sysv4.h
--- gcc-virgin/gcc/config/rs6000/sysv4.h	2005-08-08 09:17:55.000000000 +0930
+++ gcc-current/gcc/config/rs6000/sysv4.h	2005-10-20 11:14:05.000000000 +0930
@@ -550,12 +550,12 @@ extern int rs6000_pic_labelno;
 
 #define	LCOMM_ASM_OP	"\t.lcomm\t"
 
-/* Override elfos.h definition.  */
-#undef	ASM_OUTPUT_ALIGNED_LOCAL
-#define	ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
+/* Describe how to emit uninitialized local items.  */
+#define	ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN)	\
 do {									\
-  if (rs6000_sdata != SDATA_NONE && (SIZE) > 0				\
-      && (SIZE) <= g_switch_value)					\
+  if (rs6000_sdata != SDATA_NONE					\
+      && (rs6000_sdata != SDATA_DATA || ((DECL) && TREE_PUBLIC (DECL)))	\
+      && (SIZE) > 0 && (SIZE) <= g_switch_value)			\
     {									\
       sbss_section ();							\
       ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT));	\
@@ -577,7 +577,7 @@ do {									\
 /* Describe how to emit uninitialized external linkage items.  */
 #define	ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN)		\
 do {									\
-  ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN);			\
+  ASM_OUTPUT_ALIGNED_DECL_LOCAL (FILE, DECL, NAME, SIZE, ALIGN);	\
 } while (0)
 
 #ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
diff -urp -xCVS -x'*~' -xTAGS -x'*.info' -x'.#*' gcc-virgin/gcc/doc/invoke.texi gcc-current/gcc/doc/invoke.texi
--- gcc-virgin/gcc/doc/invoke.texi	2005-10-20 10:14:26.000000000 +0930
+++ gcc-current/gcc/doc/invoke.texi	2005-10-20 18:07:50.000000000 +0930
@@ -11419,9 +11419,9 @@ same as @option{-msdata=sysv}.
 
 @item -msdata-data
 @opindex msdata-data
-On System V.4 and embedded PowerPC systems, put small global and static
-data in the @samp{.sdata} section.  Put small uninitialized global and
-static data in the @samp{.sbss} section.  Do not use register @code{r13}
+On System V.4 and embedded PowerPC systems, put small global
+data in the @samp{.sdata} section.  Put small uninitialized global
+data in the @samp{.sbss} section.  Do not use register @code{r13}
 to address small data however.  This is the default behavior unless
 other @option{-msdata} options are used.
 

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PowerPC] Fix PR23774 stack backchain broken
@ 2005-09-12  3:41 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2005-09-12  3:41 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

Bootstrapped and regression tested powerpc-linux and powerpc64-linux.
Relies on http://gcc.gnu.org/ml/gcc-patches/2005-09/msg00689.html being
applied.  OK for mainline and 4.0?

	PR target/23774
	* config/rs6000/rs6000.md (restore_stack_block): Write the backchain
	word before changing the stack pointer.  Use gen_frame_mem for MEMs.
	Use UNSPEC_TIE to prevent insn scheduling reordering the insns.
	(restore_stack_nonlocal): Likewise.
	(save_stack_nonlocal): Use template to emit insns, and gen_frame_mem.

--- rs6000.md	2005-09-01 20:15:50.000000000 +0930
+++ rs6000.md.tie-23774	2005-09-12 12:33:28.000000000 +0930
@@ -9348,50 +9348,53 @@
   "DONE;")
 
 (define_expand "restore_stack_block"
-  [(use (match_operand 0 "register_operand" ""))
-   (set (match_dup 2) (match_dup 3))
-   (set (match_dup 0) (match_operand 1 "register_operand" ""))
-   (set (match_dup 3) (match_dup 2))]
+  [(set (match_dup 2) (match_dup 3))
+   (set (match_dup 4) (match_dup 2))
+   (set (match_dup 5) (unspec:BLK [(match_dup 5)] UNSPEC_TIE))
+   (set (match_operand 0 "register_operand" "")
+	(match_operand 1 "register_operand" ""))]
   ""
   "
 {
   operands[2] = gen_reg_rtx (Pmode);
-  operands[3] = gen_rtx_MEM (Pmode, operands[0]);
+  operands[3] = gen_frame_mem (Pmode, operands[0]);
+  operands[4] = gen_frame_mem (Pmode, operands[1]);
+  operands[5] = gen_frame_mem (BLKmode, operands[0]);
 }")
 
 (define_expand "save_stack_nonlocal"
-  [(match_operand 0 "memory_operand" "")
-   (match_operand 1 "register_operand" "")]
+  [(set (match_dup 3) (match_dup 4))
+   (set (match_operand 0 "memory_operand" "") (match_dup 3))
+   (set (match_dup 2) (match_operand 1 "register_operand" ""))]
   ""
   "
 {
-  rtx temp = gen_reg_rtx (Pmode);
   int units_per_word = (TARGET_32BIT) ? 4 : 8;
 
   /* Copy the backchain to the first word, sp to the second.  */
-  emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
-  emit_move_insn (adjust_address_nv (operands[0], Pmode, 0), temp);
-  emit_move_insn (adjust_address_nv (operands[0], Pmode, units_per_word),
-		  operands[1]);
-  DONE;
+  operands[0] = adjust_address_nv (operands[0], Pmode, 0);
+  operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
+  operands[3] = gen_reg_rtx (Pmode);
+  operands[4] = gen_frame_mem (Pmode, operands[1]);
 }")
 
 (define_expand "restore_stack_nonlocal"
-  [(match_operand 0 "register_operand" "")
-   (match_operand 1 "memory_operand" "")]
+  [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
+   (set (match_dup 3) (match_dup 4))
+   (set (match_dup 5) (match_dup 2))
+   (set (match_dup 6) (unspec:BLK [(match_dup 6)] UNSPEC_TIE))
+   (set (match_operand 0 "register_operand" "") (match_dup 3))]
   ""
   "
 {
-  rtx temp = gen_reg_rtx (Pmode);
   int units_per_word = (TARGET_32BIT) ? 4 : 8;
 
-  /* Restore the backchain from the first word, sp from the second.  */
-  emit_move_insn (temp,
-		  adjust_address_nv (operands[1], Pmode, 0));
-  emit_move_insn (operands[0],
-		  adjust_address_nv (operands[1], Pmode, units_per_word));
-  emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp);
-  DONE;
+  operands[2] = gen_reg_rtx (Pmode);
+  operands[3] = gen_reg_rtx (Pmode);
+  operands[1] = adjust_address_nv (operands[1], Pmode, 0);
+  operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
+  operands[5] = gen_frame_mem (Pmode, operands[3]);
+  operands[6] = gen_frame_mem (BLKmode, operands[0]);
 }")
 \f
 ;; TOC register handling.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [RS6000] Nop-insertion fix
@ 2005-09-12  2:03 Alan Modra
  2005-09-12  7:23 ` Richard Henderson
  0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2005-09-12  2:03 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

This cleans up get_next_active_insn, using similar tests to those in
emit-rtl.c:next_active_insn to decide which insns are really active.  In
addition it excludes stack_tie, a fake insn that introduces dependency
between the stack pointer and stack memory, used in some function
prologues and epilogues.  This fake insn is seen by the insn grouping
pass as if it were real, resulting in nops being inserted to avoid
non-existent mem access stalls.
See also http://gcc.gnu.org/ml/gcc/2005-09/msg00272.html

	* config/rs6000/rs6000.c (get_next_active_insn): Rewrite using
	CALL_P, JUMP_P and NONJUMP_INSN_P, so that barriers and labels
	are omitted.  Exclude stack_tie insn too.

Bootstrapped and regression tested powerpc-linux.  OK for mainline and
4.0?

Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.866
diff -c -p -r1.866 rs6000.c
*** gcc/config/rs6000/rs6000.c	6 Sep 2005 02:04:59 -0000	1.866
--- gcc/config/rs6000/rs6000.c	12 Sep 2005 00:05:22 -0000
*************** rs6000_is_costly_dependence (rtx insn, r
*** 16622,16647 ****
  static rtx
  get_next_active_insn (rtx insn, rtx tail)
  {
!   rtx next_insn;
! 
!   if (!insn || insn == tail)
      return NULL_RTX;
  
!   next_insn = NEXT_INSN (insn);
! 
!   while (next_insn
!   	 && next_insn != tail
! 	 && (GET_CODE (next_insn) == NOTE
! 	     || GET_CODE (PATTERN (next_insn)) == USE
! 	     || GET_CODE (PATTERN (next_insn)) == CLOBBER))
      {
!       next_insn = NEXT_INSN (next_insn);
!     }
! 
!   if (!next_insn || next_insn == tail)
!     return NULL_RTX;
  
!   return next_insn;
  }
  
  /* Return whether the presence of INSN causes a dispatch group termination
--- 16636,16661 ----
  static rtx
  get_next_active_insn (rtx insn, rtx tail)
  {
!   if (insn == NULL_RTX || insn == tail)
      return NULL_RTX;
  
!   while (1)
      {
!       insn = NEXT_INSN (insn);
!       if (insn == NULL_RTX || insn == tail)
! 	return NULL_RTX;
  
!       if (CALL_P (insn)
! 	  || JUMP_P (insn)
! 	  || (NONJUMP_INSN_P (insn)
! 	      && GET_CODE (PATTERN (insn)) != USE
! 	      && GET_CODE (PATTERN (insn)) != CLOBBER
! 	      && !(GET_CODE (PATTERN (insn)) == SET
! 		   && GET_CODE (XEXP (PATTERN (insn), 1)) == UNSPEC
! 		   && XINT (XEXP (PATTERN (insn), 1), 1) == UNSPEC_TIE)))
! 	break;
!     }
!   return insn;
  }
  
  /* Return whether the presence of INSN causes a dispatch group termination

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PATCH, committed] PPC405 atomic support (PR target/21760)
@ 2005-06-23 13:33 David Edelsohn
  2005-06-23 13:51 ` Andreas Schwab
  0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2005-06-23 13:33 UTC (permalink / raw)
  To: gcc-patches

	This patch adds support for the PPC405CR atomic operation erratum.
The atomic operation correction needs to be applied to all GCC runtime
libraries, but a PPC405 multilib is not created.  Therefore this feature
only is enabled when GCC is configured using --with-cpu=405.

Bootstrapped and regression tested on powerpc-ibm-aix5.2.0.0

David


	PR target/21760
	* config/rs6000/rs6000.h (PPC405_ERRATUM77): New.
	* config/rs6000/rs6000.md: Move atomic instructions to ...
	* config/rs6000/sync.md: Here.
	Change sync_compare_and_swap<mode> to define_expand.  All stwcx
	patterns test PPC405_ERRATUM77.

Index: rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.370
diff -c -p -r1.370 rs6000.h
*** rs6000.h	12 Jun 2005 03:43:11 -0000	1.370
--- rs6000.h	21 Jun 2005 14:50:49 -0000
***************
*** 49,54 ****
--- 49,62 ----
  #define TARGET_CPU_DEFAULT ((char *)0)
  #endif
  
+ /* If configured for PPC405, support PPC405CR Erratum77.  */
+ #define PPC405_CPU_DEFAULT ("405")
+ #if #TARGET_CPU_DEFAULT == #PPC405_CPU_DEFAULT
+ #define PPC405_ERRATUM77 (rs6000_cpu == PROCESSOR_PPC405)
+ #else
+ #define PPC405_ERRATUM77 0
+ #endif
+ 
  /* Common ASM definitions used by ASM_SPEC among the various targets
     for handling -mcpu=xxx switches.  */
  #define ASM_CPU_SPEC \
*** /dev/null	Tue Jun 21 10:51:03 2005
--- sync.md	Mon Jun 20 11:08:00 2005
***************
*** 0 ****
--- 1,489 ----
+ ;; Machine description for PowerPC synchronization instructions.
+ ;; Copyright (C) 2005 Free Software Foundation, Inc.
+ ;; Contributed by Geoffrey Keating.
+ 
+ ;; This file is part of GCC.
+ 
+ ;; GCC is free software; you can redistribute it and/or modify it
+ ;; under the terms of the GNU General Public License as published
+ ;; by the Free Software Foundation; either version 2, or (at your
+ ;; option) any later version.
+ 
+ ;; GCC is distributed in the hope that it will be useful, but WITHOUT
+ ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+ ;; License for more details.
+ 
+ ;; You should have received a copy of the GNU General Public License
+ ;; along with GCC; see the file COPYING.  If not, write to the
+ ;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ ;; MA 02111-1307, USA.
+ 
+ (define_mode_attr larx [(SI "lwarx") (DI "ldarx")])
+ (define_mode_attr stcx [(SI "stwcx.") (DI "stdcx.")])
+ 
+ (define_insn "memory_barrier"
+   [(set (mem:BLK (match_scratch 0 "X"))
+ 	(unspec:BLK [(mem:BLK (match_scratch 1 "X"))] UNSPEC_SYNC))]
+   ""
+   "{ics|sync}")
+ 
+ (define_expand "sync_compare_and_swap<mode>"
+   [(parallel [(set (match_operand:GPR 1 "memory_operand" "")
+ 		   (unspec:GPR [(match_dup 1)
+ 				(match_operand:GPR 2 "reg_or_short_operand" "")
+ 				(match_operand:GPR 3 "gpc_reg_operand" "")]
+ 			       UNSPEC_SYNC_SWAP))
+ 	      (set (match_operand:GPR 0 "gpc_reg_operand" "") (match_dup 1))
+ 	      (set (mem:BLK (match_scratch 5 ""))
+ 		   (unspec:BLK [(mem:BLK (match_scratch 6 ""))] UNSPEC_SYNC))
+ 	      (clobber (match_scratch:CC 4 ""))])]
+   "TARGET_POWERPC")
+ 
+ (define_insn "sync_compare_and_swap<mode>_internal"
+   [(set (match_operand:GPR 1 "memory_operand" "+Z")
+ 	(unspec:GPR [(match_dup 1)
+ 		     (match_operand:GPR 2 "reg_or_short_operand" "rI")
+ 		     (match_operand:GPR 3 "gpc_reg_operand" "r")]
+ 		    UNSPEC_SYNC_SWAP))
+    (set (match_operand:GPR 0 "gpc_reg_operand" "=&r") (match_dup 1))
+    (set (mem:BLK (match_scratch 5 "X"))
+ 	(unspec:BLK [(mem:BLK (match_scratch 6 "X"))] UNSPEC_SYNC))
+    (clobber (match_scratch:CC 4 "=&x"))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "sync\n\t<larx> %0,%y1\n\tcmp<wd>%I2 %0,%2\n\tbne- $+12\n\t<stcx> %3,%y1\n\tbne- $-16\n\tisync"
+   [(set_attr "length" "28")])
+ 
+ (define_insn "sync_compare_and_swap<mode>_ppc405"
+   [(set (match_operand:GPR 1 "memory_operand" "+Z")
+ 	(unspec:GPR [(match_dup 1)
+ 		     (match_operand:GPR 2 "reg_or_short_operand" "rI")
+ 		     (match_operand:GPR 3 "gpc_reg_operand" "r")]
+ 		    UNSPEC_SYNC_SWAP))
+    (set (match_operand:GPR 0 "gpc_reg_operand" "=&r") (match_dup 1))
+    (set (mem:BLK (match_scratch 5 "X"))
+ 	(unspec:BLK [(mem:BLK (match_scratch 6 "X"))] UNSPEC_SYNC))
+    (clobber (match_scratch:CC 4 "=&x"))]
+   "TARGET_POWERPC && PPC405_ERRATUM77"
+   "sync\n\t<larx> %0,%y1\n\tcmp<wd>%I2 %0,%2\n\tbne- $+12\n\tsync\n\t<stcx> %3,%y1\n\tbne- $-16\n\tisync"
+   [(set_attr "length" "32")])
+ 
+ (define_expand "sync_add<mode>"
+   [(use (match_operand:INT1 0 "memory_operand" ""))
+    (use (match_operand:INT1 1 "add_operand" ""))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "
+ {
+   rs6000_emit_sync (PLUS, <MODE>mode, operands[0], operands[1], 
+ 		    NULL_RTX, NULL_RTX, true);
+   DONE;
+ }")
+ 
+ (define_expand "sync_sub<mode>"
+   [(use (match_operand:GPR 0 "memory_operand" ""))
+    (use (match_operand:GPR 1 "gpc_reg_operand" ""))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "
+ {
+   rs6000_emit_sync (MINUS, <MODE>mode, operands[0], operands[1], 
+ 		    NULL_RTX, NULL_RTX, true);
+   DONE;
+ }")
+ 
+ (define_expand "sync_ior<mode>"
+   [(use (match_operand:INT1 0 "memory_operand" ""))
+    (use (match_operand:INT1 1 "logical_operand" ""))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "
+ {
+   rs6000_emit_sync (IOR, <MODE>mode, operands[0], operands[1], 
+ 		    NULL_RTX, NULL_RTX, true);
+   DONE;
+ }")
+ 
+ (define_expand "sync_and<mode>"
+   [(use (match_operand:INT1 0 "memory_operand" ""))
+    (use (match_operand:INT1 1 "and_operand" ""))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "
+ {
+   rs6000_emit_sync (AND, <MODE>mode, operands[0], operands[1], 
+ 		    NULL_RTX, NULL_RTX, true);
+   DONE;
+ }")
+ 
+ (define_expand "sync_xor<mode>"
+   [(use (match_operand:INT1 0 "memory_operand" ""))
+    (use (match_operand:INT1 1 "logical_operand" ""))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "
+ {
+   rs6000_emit_sync (XOR, <MODE>mode, operands[0], operands[1], 
+ 		    NULL_RTX, NULL_RTX, true);
+   DONE;
+ }")
+ 
+ (define_expand "sync_nand<mode>"
+   [(use (match_operand:INT1 0 "memory_operand" ""))
+    (use (match_operand:INT1 1 "gpc_reg_operand" ""))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "
+ {
+   rs6000_emit_sync (AND, <MODE>mode, 
+ 		    gen_rtx_NOT (<MODE>mode, operands[0]),
+ 		    operands[1],
+ 		    NULL_RTX, NULL_RTX, true);
+   DONE;
+ }")
+ 
+ (define_expand "sync_old_add<mode>"
+   [(use (match_operand:INT1 0 "gpc_reg_operand" ""))
+    (use (match_operand:INT1 1 "memory_operand" ""))
+    (use (match_operand:INT1 2 "add_operand" ""))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "
+ {
+   rs6000_emit_sync (PLUS, <MODE>mode, operands[1], operands[2], 
+ 		    operands[0], NULL_RTX, true);
+   DONE;
+ }")
+ 
+ (define_expand "sync_old_sub<mode>"
+   [(use (match_operand:GPR 0 "gpc_reg_operand" ""))
+    (use (match_operand:GPR 1 "memory_operand" ""))
+    (use (match_operand:GPR 2 "gpc_reg_operand" ""))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "
+ {
+   rs6000_emit_sync (MINUS, <MODE>mode, operands[1], operands[2], 
+ 		    operands[0], NULL_RTX, true);
+   DONE;
+ }")
+ 
+ (define_expand "sync_old_ior<mode>"
+   [(use (match_operand:INT1 0 "gpc_reg_operand" ""))
+    (use (match_operand:INT1 1 "memory_operand" ""))
+    (use (match_operand:INT1 2 "logical_operand" ""))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "
+ {
+   rs6000_emit_sync (IOR, <MODE>mode, operands[1], operands[2], 
+ 		    operands[0], NULL_RTX, true);
+   DONE;
+ }")
+ 
+ (define_expand "sync_old_and<mode>"
+   [(use (match_operand:INT1 0 "gpc_reg_operand" ""))
+    (use (match_operand:INT1 1 "memory_operand" ""))
+    (use (match_operand:INT1 2 "and_operand" ""))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "
+ {
+   rs6000_emit_sync (AND, <MODE>mode, operands[1], operands[2], 
+ 		    operands[0], NULL_RTX, true);
+   DONE;
+ }")
+ 
+ (define_expand "sync_old_xor<mode>"
+   [(use (match_operand:INT1 0 "gpc_reg_operand" ""))
+    (use (match_operand:INT1 1 "memory_operand" ""))
+    (use (match_operand:INT1 2 "logical_operand" ""))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "
+ {
+   rs6000_emit_sync (XOR, <MODE>mode, operands[1], operands[2], 
+ 		    operands[0], NULL_RTX, true);
+   DONE;
+ }")
+ 
+ (define_expand "sync_old_nand<mode>"
+   [(use (match_operand:INT1 0 "gpc_reg_operand" ""))
+    (use (match_operand:INT1 1 "memory_operand" ""))
+    (use (match_operand:INT1 2 "gpc_reg_operand" ""))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "
+ {
+   rs6000_emit_sync (AND, <MODE>mode, 
+ 		    gen_rtx_NOT (<MODE>mode, operands[1]),
+ 		    operands[2],
+ 		    operands[0], NULL_RTX, true);
+   DONE;
+ }")
+ 
+ (define_expand "sync_new_add<mode>"
+   [(use (match_operand:INT1 0 "gpc_reg_operand" ""))
+    (use (match_operand:INT1 1 "memory_operand" ""))
+    (use (match_operand:INT1 2 "add_operand" ""))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "
+ {
+   rs6000_emit_sync (PLUS, <MODE>mode, operands[1], operands[2], 
+ 		    NULL_RTX, operands[0], true);
+   DONE;
+ }")
+ 
+ (define_expand "sync_new_sub<mode>"
+   [(use (match_operand:GPR 0 "gpc_reg_operand" ""))
+    (use (match_operand:GPR 1 "memory_operand" ""))
+    (use (match_operand:GPR 2 "gpc_reg_operand" ""))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "
+ {
+   rs6000_emit_sync (MINUS, <MODE>mode, operands[1], operands[2], 
+ 		    NULL_RTX, operands[0], true);
+   DONE;
+ }")
+ 
+ (define_expand "sync_new_ior<mode>"
+   [(use (match_operand:INT1 0 "gpc_reg_operand" ""))
+    (use (match_operand:INT1 1 "memory_operand" ""))
+    (use (match_operand:INT1 2 "logical_operand" ""))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "
+ {
+   rs6000_emit_sync (IOR, <MODE>mode, operands[1], operands[2], 
+ 		    NULL_RTX, operands[0], true);
+   DONE;
+ }")
+ 
+ (define_expand "sync_new_and<mode>"
+   [(use (match_operand:INT1 0 "gpc_reg_operand" ""))
+    (use (match_operand:INT1 1 "memory_operand" ""))
+    (use (match_operand:INT1 2 "and_operand" ""))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "
+ {
+   rs6000_emit_sync (AND, <MODE>mode, operands[1], operands[2], 
+ 		    NULL_RTX, operands[0], true);
+   DONE;
+ }")
+ 
+ (define_expand "sync_new_xor<mode>"
+   [(use (match_operand:INT1 0 "gpc_reg_operand" ""))
+    (use (match_operand:INT1 1 "memory_operand" ""))
+    (use (match_operand:INT1 2 "logical_operand" ""))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "
+ {
+   rs6000_emit_sync (XOR, <MODE>mode, operands[1], operands[2], 
+ 		    NULL_RTX, operands[0], true);
+   DONE;
+ }")
+ 
+ (define_expand "sync_new_nand<mode>"
+   [(use (match_operand:INT1 0 "gpc_reg_operand" ""))
+    (use (match_operand:INT1 1 "memory_operand" ""))
+    (use (match_operand:INT1 2 "gpc_reg_operand" ""))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "
+ {
+   rs6000_emit_sync (AND, <MODE>mode, 
+ 		    gen_rtx_NOT (<MODE>mode, operands[1]),
+ 		    operands[2],
+ 		    NULL_RTX, operands[0], true);
+   DONE;
+ }")
+ 
+ ; the sync_*_internal patterns all have these operands:
+ ; 0 - memory location
+ ; 1 - operand
+ ; 2 - value in memory after operation
+ ; 3 - value in memory immediately before operation
+ 
+ (define_insn "*sync_add<mode>_internal"
+   [(set (match_operand:GPR 2 "gpc_reg_operand" "=&r,&r")
+ 	(plus:GPR (match_operand:GPR 0 "memory_operand" "+Z,Z")
+ 		 (match_operand:GPR 1 "add_operand" "rI,L")))
+    (set (match_operand:GPR 3 "gpc_reg_operand" "=&b,&b") (match_dup 0))
+    (set (match_dup 0) 
+ 	(unspec:GPR [(plus:GPR (match_dup 0) (match_dup 1))]
+ 		   UNSPEC_SYNC_OP))
+    (clobber (match_scratch:CC 4 "=&x,&x"))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "@
+    <larx> %3,%y0\n\tadd%I1 %2,%3,%1\n\t<stcx> %2,%y0\n\tbne- $-12
+    <larx> %3,%y0\n\taddis %2,%3,%v1\n\t<stcx> %2,%y0\n\tbne- $-12"
+   [(set_attr "length" "16,16")])
+ 
+ (define_insn "*sync_addshort_internal"
+   [(set (match_operand:SI 2 "gpc_reg_operand" "=&r")
+ 	(ior:SI (and:SI (plus:SI (match_operand:SI 0 "memory_operand" "+Z")
+ 				 (match_operand:SI 1 "add_operand" "rI"))
+ 			(match_operand:SI 4 "gpc_reg_operand" "r"))
+ 		(and:SI (not:SI (match_dup 4)) (match_dup 0))))
+    (set (match_operand:SI 3 "gpc_reg_operand" "=&b") (match_dup 0))
+    (set (match_dup 0) 
+ 	(unspec:SI [(ior:SI (and:SI (plus:SI (match_dup 0) (match_dup 1))
+ 				    (match_dup 4))
+ 			    (and:SI (not:SI (match_dup 4)) (match_dup 0)))]
+ 		   UNSPEC_SYNC_OP))
+    (clobber (match_scratch:CC 5 "=&x"))
+    (clobber (match_scratch:SI 6 "=&r"))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "lwarx %3,%y0\n\tadd%I1 %2,%3,%1\n\tandc %6,%3,%4\n\tand %2,%2,%4\n\tor %2,%2,%6\n\tstwcx. %2,%y0\n\tbne- $-24"
+   [(set_attr "length" "28")])
+ 
+ (define_insn "*sync_sub<mode>_internal"
+   [(set (match_operand:GPR 2 "gpc_reg_operand" "=&r")
+ 	(minus:GPR (match_operand:GPR 0 "memory_operand" "+Z")
+ 		  (match_operand:GPR 1 "gpc_reg_operand" "r")))
+    (set (match_operand:GPR 3 "gpc_reg_operand" "=&b") (match_dup 0))
+    (set (match_dup 0) 
+ 	(unspec:GPR [(minus:GPR (match_dup 0) (match_dup 1))]
+ 		   UNSPEC_SYNC_OP))
+    (clobber (match_scratch:CC 4 "=&x"))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "<larx> %3,%y0\n\tsubf %2,%1,%3\n\t<stcx> %2,%y0\n\tbne- $-12"
+   [(set_attr "length" "16")])
+ 
+ (define_insn "*sync_andsi_internal"
+   [(set (match_operand:SI 2 "gpc_reg_operand" "=&r,&r,&r,&r")
+ 	(and:SI (match_operand:SI 0 "memory_operand" "+Z,Z,Z,Z")
+ 		(match_operand:SI 1 "and_operand" "r,T,K,L")))
+    (set (match_operand:SI 3 "gpc_reg_operand" "=&b,&b,&b,&b") (match_dup 0))
+    (set (match_dup 0) 
+ 	(unspec:SI [(and:SI (match_dup 0) (match_dup 1))]
+ 		   UNSPEC_SYNC_OP))
+    (clobber (match_scratch:CC 4 "=&x,&x,&x,&x"))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "@
+    lwarx %3,%y0\n\tand %2,%3,%1\n\tstwcx. %2,%y0\n\tbne- $-12
+    lwarx %3,%y0\n\trlwinm %2,%3,0,%m1,%M1\n\tstwcx. %2,%y0\n\tbne- $-12
+    lwarx %3,%y0\n\tandi. %2,%3,%b1\n\tstwcx. %2,%y0\n\tbne- $-12
+    lwarx %3,%y0\n\tandis. %2,%3,%u1\n\tstwcx. %2,%y0\n\tbne- $-12"
+   [(set_attr "length" "16,16,16,16")])
+ 
+ (define_insn "*sync_anddi_internal"
+   [(set (match_operand:DI 2 "gpc_reg_operand" "=&r,&r,&r,&r,&r")
+ 	(and:DI (match_operand:DI 0 "memory_operand" "+Z,Z,Z,Z,Z")
+ 		(match_operand:DI 1 "and_operand" "r,S,T,K,J")))
+    (set (match_operand:DI 3 "gpc_reg_operand" "=&b,&b,&b,&b,&b") (match_dup 0))
+    (set (match_dup 0) 
+ 	(unspec:DI [(and:DI (match_dup 0) (match_dup 1))]
+ 		   UNSPEC_SYNC_OP))
+    (clobber (match_scratch:CC 4 "=&x,&x,&x,&x,&x"))]
+   "TARGET_POWERPC64"
+   "@
+    ldarx %3,%y0\n\tand %2,%3,%1\n\tstdcx. %2,%y0\n\tbne- $-12
+    ldarx %3,%y0\n\trldic%B1 %2,%3,0,%S1\n\tstdcx. %2,%y0\n\tbne- $-12
+    ldarx %3,%y0\n\trlwinm %2,%3,0,%m1,%M1\n\tstdcx. %2,%y0\n\tbne- $-12
+    ldarx %3,%y0\n\tandi. %2,%3,%b1\n\tstdcx. %2,%y0\n\tbne- $-12
+    ldarx %3,%y0\n\tandis. %2,%3,%b1\n\tstdcx. %2,%y0\n\tbne- $-12"
+   [(set_attr "length" "16,16,16,16,16")])
+ 
+ (define_insn "*sync_boolsi_internal"
+   [(set (match_operand:SI 2 "gpc_reg_operand" "=&r,&r,&r")
+ 	(match_operator:SI 4 "boolean_or_operator"
+ 	 [(match_operand:SI 0 "memory_operand" "+Z,Z,Z")
+ 	  (match_operand:SI 1 "logical_operand" "r,K,L")]))
+    (set (match_operand:SI 3 "gpc_reg_operand" "=&b,&b,&b") (match_dup 0))
+    (set (match_dup 0) (unspec:SI [(match_dup 4)] UNSPEC_SYNC_OP))
+    (clobber (match_scratch:CC 5 "=&x,&x,&x"))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "@
+    lwarx %3,%y0\n\t%q4 %2,%3,%1\n\tstwcx. %2,%y0\n\tbne- $-12
+    lwarx %3,%y0\n\t%q4i %2,%3,%b1\n\tstwcx. %2,%y0\n\tbne- $-12
+    lwarx %3,%y0\n\t%q4is %2,%3,%u1\n\tstwcx. %2,%y0\n\tbne- $-12"
+   [(set_attr "length" "16,16,16")])
+ 
+ (define_insn "*sync_booldi_internal"
+   [(set (match_operand:DI 2 "gpc_reg_operand" "=&r,&r,&r")
+ 	(match_operator:DI 4 "boolean_or_operator"
+ 	 [(match_operand:DI 0 "memory_operand" "+Z,Z,Z")
+ 	  (match_operand:DI 1 "logical_operand" "r,K,JF")]))
+    (set (match_operand:DI 3 "gpc_reg_operand" "=&b,&b,&b") (match_dup 0))
+    (set (match_dup 0) (unspec:DI [(match_dup 4)] UNSPEC_SYNC_OP))
+    (clobber (match_scratch:CC 5 "=&x,&x,&x"))]
+   "TARGET_POWERPC64"
+   "@
+    ldarx %3,%y0\n\t%q4 %2,%3,%1\n\tstdcx. %2,%y0\n\tbne- $-12
+    ldarx %3,%y0\n\t%q4i %2,%3,%b1\n\tstdcx. %2,%y0\n\tbne- $-12
+    ldarx %3,%y0\n\t%q4is %2,%3,%u1\n\tstdcx. %2,%y0\n\tbne- $-12"
+   [(set_attr "length" "16,16,16")])
+ 
+ (define_insn "*sync_boolc<mode>_internal"
+   [(set (match_operand:GPR 2 "gpc_reg_operand" "=&r")
+ 	(match_operator:GPR 4 "boolean_operator"
+ 	 [(not:GPR (match_operand:GPR 0 "memory_operand" "+Z"))
+ 	  (match_operand:GPR 1 "gpc_reg_operand" "r")]))
+    (set (match_operand:GPR 3 "gpc_reg_operand" "=&b") (match_dup 0))
+    (set (match_dup 0) (unspec:GPR [(match_dup 4)] UNSPEC_SYNC_OP))
+    (clobber (match_scratch:CC 5 "=&x"))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "<larx> %3,%y0\n\t%q4 %2,%1,%3\n\t<stcx> %2,%y0\n\tbne- $-12"
+   [(set_attr "length" "16")])
+ 
+ ; This pattern could also take immediate values of operand 1,
+ ; since the non-NOT version of the operator is used; but this is not
+ ; very useful, since in practice operand 1 is a full 32-bit value.
+ ; Likewise, operand 5 is in practice either <= 2^16 or it is a register.
+ (define_insn "*sync_boolcshort_internal"
+   [(set (match_operand:SI 2 "gpc_reg_operand" "=&r")
+ 	(match_operator:SI 4 "boolean_operator"
+ 	 [(xor:SI (match_operand:SI 0 "memory_operand" "+Z")
+ 		  (match_operand:SI 5 "logical_operand" "rK"))
+ 	  (match_operand:SI 1 "gpc_reg_operand" "r")]))
+    (set (match_operand:SI 3 "gpc_reg_operand" "=&b") (match_dup 0))
+    (set (match_dup 0) (unspec:SI [(match_dup 4)] UNSPEC_SYNC_OP))
+    (clobber (match_scratch:CC 6 "=&x"))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "lwarx %3,%y0\n\txor%I2 %2,%3,%5\n\t%q4 %2,%2,%1\n\tstwcx. %2,%y0\n\tbne- $-16"
+   [(set_attr "length" "20")])
+ 
+ (define_insn "*sync_boolc<mode>_internal2"
+   [(set (match_operand:GPR 2 "gpc_reg_operand" "=&r")
+ 	(match_operator:GPR 4 "boolean_operator"
+ 	 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
+ 	  (match_operand:GPR 0 "memory_operand" "+Z")]))
+    (set (match_operand:GPR 3 "gpc_reg_operand" "=&b") (match_dup 0))
+    (set (match_dup 0) (unspec:GPR [(match_dup 4)] UNSPEC_SYNC_OP))
+    (clobber (match_scratch:CC 5 "=&x"))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "<larx> %3,%y0\n\t%q4 %2,%3,%1\n\t<stcx> %2,%y0\n\tbne- $-12"
+   [(set_attr "length" "16")])
+ 
+ (define_insn "*sync_boolcc<mode>_internal"
+   [(set (match_operand:GPR 2 "gpc_reg_operand" "=&r")
+ 	(match_operator:GPR 4 "boolean_operator"
+ 	 [(not:GPR (match_operand:GPR 0 "memory_operand" "+Z"))
+ 	  (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))]))
+    (set (match_operand:GPR 3 "gpc_reg_operand" "=&b") (match_dup 0))
+    (set (match_dup 0) (unspec:GPR [(match_dup 4)] UNSPEC_SYNC_OP))
+    (clobber (match_scratch:CC 5 "=&x"))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "<larx> %3,%y0\n\t%q4 %2,%1,%3\n\t<stcx> %2,%y0\n\tbne- $-12"
+   [(set_attr "length" "16")])
+ 
+ (define_insn "isync"
+   [(set (mem:BLK (match_scratch 0 "X"))
+         (unspec:BLK [(mem:BLK (match_scratch 1 "X"))] UNSPEC_ISYNC))]
+   "TARGET_POWERPC"
+   "isync")
+ 
+ (define_insn "sync_lock_test_and_set<mode>"
+   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
+ 	(match_operand:GPR 1 "memory_operand" "+Z"))
+    (set (match_dup 1) (unspec:GPR [(match_operand:GPR 2 "gpc_reg_operand" "r")] 
+ 				 UNSPEC_SYNC_OP))
+    (clobber (match_scratch:CC 3 "=&x"))
+    (set (mem:BLK (match_scratch 4 "X"))
+         (unspec:BLK [(mem:BLK (match_scratch 5 "X"))] UNSPEC_ISYNC))]
+   "TARGET_POWERPC && !PPC405_ERRATUM77"
+   "<larx> %0,%y1\n\t<stcx> %2,%y1\n\tbne- $-8\n\tisync"
+   [(set_attr "length" "16")])
+ 
+ (define_expand "sync_lock_release<mode>"
+   [(set (match_operand:INT 0 "memory_operand")
+ 	(match_operand:INT 1 "any_operand"))]
+   ""
+   "
+ {
+   emit_insn (gen_lwsync ());
+   emit_move_insn (operands[0], operands[1]);
+   DONE;
+ }")
+ 
+ ; Some AIX assemblers don't accept lwsync, so we use a .long.
+ (define_insn "lwsync"
+   [(set (mem:BLK (match_scratch 0 "X"))
+         (unspec:BLK [(mem:BLK (match_scratch 1 "X"))] UNSPEC_LWSYNC))]
+   ""
+   ".long 0x7c2004ac")
+ 

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PATCH] PowerPC SVR4 _mcount calls
@ 2005-06-10  1:09 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2005-06-10  1:09 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn, Steve Munroe

Linux has used glibc's _mcount forever, so there is no need for gcc to
allocate count vars for profiling.  I've also added a TARGET_SECURE_PLT
sequence to output_function_profiler in the event that some non-linux
svr4 ppc target wants to use it.

	* config/rs6000/linux.h (NO_PROFILE_COUNTERS): Define.
	* config/rs6000/linux64.h (NO_PROFILE_COUNTERS): Define as 1.
	* config/rs6000/rs6000.c (output_function_profiler): Obey
	NO_PROFILE_COUNTERS.  Handle TARGET_SECURE_PLT.  Use "bcl 20,31"
	for -fPIC.  Delete save_lr and substitute its value into strings.

Tested powerpc-linux.  OK to install mainline?

diff -urpN -xCVS -x'*~' -x'.#*' gcc-virgin/gcc/config/rs6000/linux.h gcc-current/gcc/config/rs6000/linux.h
--- gcc-virgin/gcc/config/rs6000/linux.h	2004-12-02 11:43:18.000000000 +1030
+++ gcc-current/gcc/config/rs6000/linux.h	2005-06-09 17:41:39.000000000 +0930
@@ -28,6 +28,9 @@
    process.  */
 #define OS_MISSING_POWERPC64 1
 
+/* We use glibc _mcount for profiling.  */
+#define NO_PROFILE_COUNTERS 1
+
 /* glibc has float and long double forms of math functions.  */
 #undef  TARGET_C99_FUNCTIONS
 #define TARGET_C99_FUNCTIONS 1
diff -urpN -xCVS -x'*~' -x'.#*' gcc-virgin/gcc/config/rs6000/linux64.h gcc-current/gcc/config/rs6000/linux64.h
--- gcc-virgin/gcc/config/rs6000/linux64.h	2005-05-06 23:34:42.000000000 +0930
+++ gcc-current/gcc/config/rs6000/linux64.h	2005-06-09 17:41:38.000000000 +0930
@@ -207,7 +210,7 @@ extern int dot_symbols;
 #endif
 
 /* We use glibc _mcount for profiling.  */
-#define NO_PROFILE_COUNTERS TARGET_64BIT
+#define NO_PROFILE_COUNTERS 1
 #define PROFILE_HOOK(LABEL) \
   do { if (TARGET_64BIT) output_profile_hook (LABEL); } while (0)
 
diff -urpN -xCVS -x'*~' -x'.#*' gcc-virgin/gcc/config/rs6000/rs6000.c gcc-current/gcc/config/rs6000/rs6000.c
--- gcc-virgin/gcc/config/rs6000/rs6000.c	2005-06-09 19:00:01.000000000 +0930
+++ gcc-current/gcc/config/rs6000/rs6000.c	2005-06-09 19:48:16.000000000 +0930
@@ -15428,7 +15477,6 @@ void
 output_function_profiler (FILE *file, int labelno)
 {
   char buf[100];
-  int save_lr = 8;
 
   switch (DEFAULT_ABI)
     {
@@ -15436,7 +15484,6 @@ output_function_profiler (FILE *file, in
       gcc_unreachable ();
 
     case ABI_V4:
-      save_lr = 4;
       if (!TARGET_32BIT)
 	{
 	  warning (0, "no profiling of 64-bit code for this ABI");
@@ -15444,11 +15491,28 @@ output_function_profiler (FILE *file, in
 	}
       ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
       fprintf (file, "\tmflr %s\n", reg_names[0]);
-      if (flag_pic == 1)
+      if (NO_PROFILE_COUNTERS)
+	{
+	  asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
+		       reg_names[0], reg_names[1]);
+	}
+      else if (TARGET_SECURE_PLT && flag_pic)
+	{
+	  asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
+		       reg_names[0], reg_names[1]);
+	  asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
+	  asm_fprintf (file, "\t{cau|addis} %s,%s,",
+		       reg_names[12], reg_names[12]);
+	  assemble_name (file, buf);
+	  asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
+	  assemble_name (file, buf);
+	  asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
+	}
+      else if (flag_pic == 1)
 	{
 	  fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
-	  asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
-		       reg_names[0], save_lr, reg_names[1]);
+	  asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
+		       reg_names[0], reg_names[1]);
 	  asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
 	  asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
 	  assemble_name (file, buf);
@@ -15456,10 +15520,10 @@ output_function_profiler (FILE *file, in
 	}
       else if (flag_pic > 1)
 	{
-	  asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
-		       reg_names[0], save_lr, reg_names[1]);
+	  asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
+		       reg_names[0], reg_names[1]);
 	  /* Now, we need to get the address of the label.  */
-	  fputs ("\tbl 1f\n\t.long ", file);
+	  fputs ("\tbcl 20,31,1f\n\t.long ", file);
 	  assemble_name (file, buf);
 	  fputs ("-.\n1:", file);
 	  asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
@@ -15473,8 +15537,8 @@ output_function_profiler (FILE *file, in
 	  asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
 	  assemble_name (file, buf);
 	  fputs ("@ha\n", file);
-	  asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
-		       reg_names[0], save_lr, reg_names[1]);
+	  asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
+		       reg_names[0], reg_names[1]);
 	  asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
 	  assemble_name (file, buf);
 	  asm_fprintf (file, "@l(%s)\n", reg_names[12]);

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* powerpc new PLT and GOT
@ 2005-05-12 16:05 Alan Modra
  2005-05-12 16:09 ` Andrew Pinski
                   ` (2 more replies)
  0 siblings, 3 replies; 875+ messages in thread
From: Alan Modra @ 2005-05-12 16:05 UTC (permalink / raw)
  To: gcc-patches

This is where I'm at with gcc support for the new powerpc-linux PLT/GOT
layout (see http://sources.redhat.com/ml/binutils/2005-05/msg00391.html).
I'm not asking for commit approval yet;  That ought to wait until I've
thrown together glibc support as well so this can all be tested properly,
but what I have here seems to do the right thing.  So I'm looking for
comments like "That's the Wrong Way.  You ought to ..."

Some things I know need attention:
a) Should the new -fpic PLT/GOT code support be enabled by default?  The
   linker  will continue to generate the old GOT/PLT layout until a new
   glibc is available, a consequence of a "bl got-4" used in the current
   crti.o.  This is fortunate, and means we don't need to do a configure
   test on glibc to figure whether the new PLT/GOT code is safe to use.
   However, the new GOT pointer load sequence is larger, (but might be
   quicker) and new PLT calls always need the GOT pointer, so code
   increases a little in size.
b) -fPIC should use the new GOT pointer load sequence too, as it is
   faster and smaller than the current -fPIC sequence.
c) The rtl generated by load_toc_v4_PIC_3c matches elf_low.  We get the
   right assembly though.

	* configure.ac (HAVE_AS_REL16): Test for R_PPC_REL16 relocs.
	* config/rs6000/sysv4.opt (mdata-plt, bss-plt): Add options.
	* config/rs6000/sysv4.h (SUBTARGET_OVERRIDE_OPTIONS): Error if
	-mdata-plt given without assembler support.
	* config/rs6000/rs6000.h (TARGET_DATA_PLT): Undef if not HAVE_AS_REL16.
	* config/rs6000/rs6000.c (rs6000_emit_load_toc_table): Handle
	TARGET_DATA_PLT got register load sequence.
	* config/rs6000/rs6000.md (load_toc_v4_PIC_1) Enable for
	TARGET_DATA_PLT.
	(load_toc_v4_PIC_3b, load_toc_v4_PIC_3c): New insns.
	(call, call_value): Mark pic_offset_table_rtx used for TARGET_DATA_PLT.
	* config.in: Regenerate.
	* configure: Regenerate.

diff -urp -xCVS -x'*~' -x'.#*' gcc-virgin/gcc/configure.ac gcc-current/gcc/configure.ac
--- gcc-virgin/gcc/configure.ac	2005-05-09 20:03:03.000000000 +0930
+++ gcc-current/gcc/configure.ac	2005-05-12 18:31:15.000000000 +0930
@@ -2828,6 +2828,24 @@ foo:	nop
       [AC_DEFINE(HAVE_AS_POPCNTB, 1,
 	  [Define if your assembler supports popcntb field.])])
 
+    case $target in
+      *-*-aix*) conftest_s='	.csect .text[[PR]]
+LCF..0:
+	addis 11,30,_GLOBAL_OFFSET_TABLE_-LCF..0@ha';;
+      *-*-darwin*)
+	conftest_s='	.text
+LCF0:
+	addis r11,r30,_GLOBAL_OFFSET_TABLE_-LCF0@ha';;
+      *) conftest_s='	.text
+.LCF0:
+	addis 11,30,_GLOBAL_OFFSET_TABLE_-.LCF0@ha';;
+    esac
+
+    gcc_GAS_CHECK_FEATURE([rel16 relocs],
+      gcc_cv_as_powerpc_rel16, [2,17,0],,
+      [$conftest_s],,
+      [AC_DEFINE(HAVE_AS_REL16, 1,
+	  [Define if your assembler supports R_PPC_REL16 relocs.])])
     ;;
 
   mips*-*-*)
diff -urp -xCVS -x'*~' -x'.#*' gcc-virgin/gcc/config/rs6000/sysv4.opt gcc-current/gcc/config/rs6000/sysv4.opt
--- gcc-virgin/gcc/config/rs6000/sysv4.opt	2005-05-07 17:51:46.000000000 +0930
+++ gcc-current/gcc/config/rs6000/sysv4.opt	2005-05-12 20:27:22.000000000 +0930
@@ -140,3 +140,11 @@ Generate 32-bit code
 mnewlib
 Target RejectNegative
 no description yet
+
+mdata-plt
+Target Report RejectNegative Mask(DATA_PLT)
+Generate code to use a non-exec PLT and GOT
+
+mbss-plt
+Target Report RejectNegative InverseMask(DATA_PLT)
+Generate code for old exec BSS PLT
diff -urp -xCVS -x'*~' -x'.#*' gcc-virgin/gcc/config/rs6000/sysv4.h gcc-current/gcc/config/rs6000/sysv4.h
--- gcc-virgin/gcc/config/rs6000/sysv4.h	2005-05-06 23:34:43.000000000 +0930
+++ gcc-current/gcc/config/rs6000/sysv4.h	2005-05-12 19:41:09.000000000 +0930
@@ -205,6 +205,11 @@ do {									\
       error ("-mcall-aixdesc must be big endian");			\
     }									\
 									\
+  if (TARGET_DATA_PLT != ((target_flags & MASK_DATA_PLT) != 0))		\
+    {									\
+      error ("-mdata-plt not supported by your assembler");		\
+    }									\
+									\
   /* Treat -fPIC the same as -mrelocatable.  */				\
   if (flag_pic > 1 && DEFAULT_ABI != ABI_AIX)				\
     target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC; \
diff -urp -xCVS -x'*~' -x'.#*' gcc-virgin/gcc/config/rs6000/rs6000.c gcc-current/gcc/config/rs6000/rs6000.c
--- gcc-virgin/gcc/config/rs6000/rs6000.c	2005-05-09 20:03:12.000000000 +0930
+++ gcc-current/gcc/config/rs6000/rs6000.c	2005-05-12 18:45:53.000000000 +0930
@@ -12547,15 +12596,46 @@ rs6000_emit_load_toc_table (int fromprol
 
   if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
     {
-      rtx temp = (fromprolog
-		  ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
-		  : gen_reg_rtx (Pmode));
-      insn = emit_insn (gen_load_toc_v4_pic_si (temp));
-      if (fromprolog)
-	rs6000_maybe_dead (insn);
-      insn = emit_move_insn (dest, temp);
-      if (fromprolog)
-	rs6000_maybe_dead (insn);
+      rtx tempLR = (fromprolog
+		    ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
+		    : gen_reg_rtx (Pmode));
+
+      if (TARGET_DATA_PLT)
+	{
+	  char buf[30];
+	  rtx lab, tmp1, tmp2, got;
+
+	  ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
+	  lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
+	  got = rs6000_got_sym ();
+	  tmp1 = tmp2 = dest;
+	  if (!fromprolog)
+	    {
+	      tmp1 = gen_reg_rtx (Pmode);
+	      tmp2 = gen_reg_rtx (Pmode);
+	    }
+	  insn = emit_insn (gen_load_toc_v4_PIC_1 (tempLR, lab));
+	  if (fromprolog)
+	    rs6000_maybe_dead (insn);
+	  insn = emit_move_insn (tmp1, tempLR);
+	  if (fromprolog)
+	    rs6000_maybe_dead (insn);
+	  insn = emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
+	  if (fromprolog)
+	    rs6000_maybe_dead (insn);
+	  insn = emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
+	  if (fromprolog)
+	    rs6000_maybe_dead (insn);
+	}
+      else
+	{
+	  insn = emit_insn (gen_load_toc_v4_pic_si (tempLR));
+	  if (fromprolog)
+	    rs6000_maybe_dead (insn);
+	  insn = emit_move_insn (dest, tempLR);
+	  if (fromprolog)
+	    rs6000_maybe_dead (insn);
+	}
     }
   else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
     {
diff -urp -xCVS -x'*~' -x'.#*' gcc-virgin/gcc/config/rs6000/rs6000.h gcc-current/gcc/config/rs6000/rs6000.h
--- gcc-virgin/gcc/config/rs6000/rs6000.h	2005-05-09 20:03:12.000000000 +0930
+++ gcc-current/gcc/config/rs6000/rs6000.h	2005-05-12 18:45:55.000000000 +0930
@@ -144,6 +144,11 @@
 #define TARGET_POPCNTB 0
 #endif
 
+#ifndef HAVE_AS_REL16
+#undef  TARGET_DATA_PLT
+#define TARGET_DATA_PLT 0
+#endif
+
 #define TARGET_32BIT		(! TARGET_64BIT)
 
 /* Emit a dtp-relative reference to a TLS variable.  */
diff -urp -xCVS -x'*~' -x'.#*' gcc-virgin/gcc/config/rs6000/rs6000.md gcc-current/gcc/config/rs6000/rs6000.md
--- gcc-virgin/gcc/config/rs6000/rs6000.md	2005-05-12 12:45:31.000000000 +0930
+++ gcc-current/gcc/config/rs6000/rs6000.md	2005-05-12 18:39:45.000000000 +0930
@@ -9812,7 +9810,8 @@
   [(set (match_operand:SI 0 "register_operand" "=l")
 	(match_operand:SI 1 "immediate_operand" "s"))
    (use (unspec [(match_dup 1)] UNSPEC_TOC))]
-  "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
+  "TARGET_ELF && DEFAULT_ABI != ABI_AIX
+   && (flag_pic == 2 || (flag_pic && TARGET_DATA_PLT))"
   "bcl 20,31,%1\\n%1:"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
@@ -9835,6 +9834,22 @@
   "{l|lwz} %0,%2-%3(%1)"
   [(set_attr "type" "load")])
 
+(define_insn "load_toc_v4_PIC_3b"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
+	(plus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+		 (high:SI
+		   (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
+			     (match_operand:SI 3 "symbol_ref_operand" "s")))))]
+  "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_DATA_PLT"
+  "{cau|addis} %0,%1,%2-%3@ha")
+
+(define_insn "load_toc_v4_PIC_3c"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
+		   (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
+			     (match_operand:SI 3 "symbol_ref_operand" "s"))))]
+  "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_DATA_PLT"
+  "{cal|addi} %0,%1,%2-%3@l")
 
 ;; If the TOC is shared over a translation unit, as happens with all
 ;; the kinds of PIC that we support, we need to restore the TOC
@@ -9985,6 +10000,25 @@
 
   operands[0] = XEXP (operands[0], 0);
 
+  if (DEFAULT_ABI == ABI_V4 && TARGET_DATA_PLT
+      && flag_pic
+      && GET_CODE (operands[0]) == SYMBOL_REF
+      && !SYMBOL_REF_LOCAL_P (operands[0]))
+    {
+      rtx call;
+      rtvec tmp;
+
+      tmp = gen_rtvec (3,
+		       gen_rtx_CALL (VOIDmode,
+				     gen_rtx_MEM (SImode, operands[0]),
+				     operands[1]),
+		       gen_rtx_USE (VOIDmode, operands[2]),
+		       gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
+      call = emit_call_insn (gen_rtx_PARALLEL (VOIDmode, tmp));
+      use_reg (&CALL_INSN_FUNCTION_USAGE (call), pic_offset_table_rtx);
+      DONE;
+    }
+
   if (GET_CODE (operands[0]) != SYMBOL_REF
       || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[0]))
       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
@@ -10036,6 +10070,28 @@
 
   operands[1] = XEXP (operands[1], 0);
 
+  if (DEFAULT_ABI == ABI_V4 && TARGET_DATA_PLT
+      && flag_pic
+      && GET_CODE (operands[1]) == SYMBOL_REF
+      && !SYMBOL_REF_LOCAL_P (operands[1]))
+    {
+      rtx call;
+      rtvec tmp;
+
+      tmp = gen_rtvec (3,
+		       gen_rtx_SET (VOIDmode,
+				    operands[0],
+				    gen_rtx_CALL (VOIDmode,
+						  gen_rtx_MEM (SImode,
+							       operands[1]),
+						  operands[2])),
+		       gen_rtx_USE (VOIDmode, operands[3]),
+		       gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
+      call = emit_call_insn (gen_rtx_PARALLEL (VOIDmode, tmp));
+      use_reg (&CALL_INSN_FUNCTION_USAGE (call), pic_offset_table_rtx);
+      DONE;
+    }
+
   if (GET_CODE (operands[1]) != SYMBOL_REF
       || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[1]))
       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* Patch ping! (4.1 projects, stage 1.2)  Hot/cold partitioning fixes
@ 2005-03-30 20:02 Caroline Tice
  2005-03-30 23:14 ` Geoffrey Keating
  2005-04-01 13:55 ` AIX bootstrap failure (was Re: Hot/cold partitioning fixes) David Edelsohn
  0 siblings, 2 replies; 875+ messages in thread
From: Caroline Tice @ 2005-03-30 20:02 UTC (permalink / raw)
  To: gcc-patches@gcc.gnu.org Patches; +Cc: Caroline Tice


Fix current problems with hot/cold partitioning optimization
http://gcc.gnu.org/ml/gcc-patches/2005-03/msg02230.html


Since stage 1.2 projects are supposed to be committed by this Friday,
I would appreciate someone taking a look at this soon.  Thanks!

-- Caroline Tice
ctice@apple.com

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [RS6000] Fix PR20611, duplicate label for inlined function referencing TLS
@ 2005-03-30  3:38 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2005-03-30  3:38 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

This patch avoids the duplicate label by simply not emitting a label for
load_toc_v4_PIC_1b.  I don't believe there is any need for the label on
this insn.  Removing the (use (unspec ..)) on the pattern doesn't affect
uses_TOC() because this particular unspec doesn't match anyway (nor
should it, the toc use here doesn't require the word emitted when
uses_TOC() is true).  Also, I think that changing the (set (reg) (symref))
to (set (reg) (unspec)) won't affect any of the places in rs6000.c that
recognize symbol_refs;  The symbol_ref in the set was previously a code
label, not one of the interesting symbol_refs to a variable or somesuch.

	PR target/20611
	* config/rs6000/rs6000.md (load_toc_v4_PIC_1b): Remove inline
	label operand.  Remove (use (unspec..)).  Don't emit a label on
	the offset word.
	* config/rs6000/rs6000.c (rs6000_legitimize_tls_address): Don't
	generate inline label for load_toc_v4_PIC_1b.
	(rs6000_emit_load_toc_table): Likewise.

Bootstrap and regression test powerpc-linux in progress.  I'd like to
apply this mainline, 4.0, and 3.4.  OK?

Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.798
diff -u -p -r1.798 rs6000.c
--- gcc/config/rs6000/rs6000.c	29 Mar 2005 16:10:06 -0000	1.798
+++ gcc/config/rs6000/rs6000.c	30 Mar 2005 01:54:10 -0000
@@ -2809,21 +2809,16 @@ rs6000_legitimize_tls_address (rtx addr,
 		rs6000_emit_move (got, gsym, Pmode);
 	      else
 		{
-		  char buf[30];
-		  static int tls_got_labelno = 0;
-		  rtx tempLR, lab, tmp3, mem;
+		  rtx tempLR, tmp3, mem;
 		  rtx first, last;
 
-		  ASM_GENERATE_INTERNAL_LABEL (buf, "LTLS", tls_got_labelno++);
-		  lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
 		  tempLR = gen_reg_rtx (Pmode);
 		  tmp1 = gen_reg_rtx (Pmode);
 		  tmp2 = gen_reg_rtx (Pmode);
 		  tmp3 = gen_reg_rtx (Pmode);
 		  mem = gen_const_mem (Pmode, tmp1);
 
-		  first = emit_insn (gen_load_toc_v4_PIC_1b (tempLR, lab,
-							     gsym));
+		  first = emit_insn (gen_load_toc_v4_PIC_1b (tempLR, gsym));
 		  emit_move_insn (tmp1, tempLR);
 		  emit_move_insn (tmp2, mem);
 		  emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
@@ -12023,11 +12018,10 @@ rs6000_emit_load_toc_table (int fromprol
       rtx temp0 = (fromprolog
 		   ? gen_rtx_REG (Pmode, 0)
 		   : gen_reg_rtx (Pmode));
-      rtx symF;
 
       if (fromprolog)
 	{
-	  rtx symL;
+	  rtx symF, symL;
 
 	  ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
 	  symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
@@ -12045,14 +12039,9 @@ rs6000_emit_load_toc_table (int fromprol
       else
 	{
 	  rtx tocsym;
-	  static int reload_toc_labelno = 0;
 
 	  tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
-
-	  ASM_GENERATE_INTERNAL_LABEL (buf, "LCG", reload_toc_labelno++);
-	  symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
-
-	  emit_insn (gen_load_toc_v4_PIC_1b (tempLR, symF, tocsym));
+	  emit_insn (gen_load_toc_v4_PIC_1b (tempLR, tocsym));
 	  emit_move_insn (dest, tempLR);
 	  emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
 	}
Index: gcc/config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.357
diff -u -p -r1.357 rs6000.md
--- gcc/config/rs6000/rs6000.md	26 Mar 2005 17:35:41 -0000	1.357
+++ gcc/config/rs6000/rs6000.md	30 Mar 2005 01:54:12 -0000
@@ -10146,11 +10146,10 @@
 
 (define_insn "load_toc_v4_PIC_1b"
   [(set (match_operand:SI 0 "register_operand" "=l")
-	(match_operand:SI 1 "immediate_operand" "s"))
-   (use (unspec [(match_dup 1) (match_operand 2 "immediate_operand" "s")]
+	(unspec [(match_operand 1 "immediate_operand" "s")]
 		UNSPEC_TOCPTR))]
   "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
-  "bcl 20,31,%1+4\\n%1:\\n\\t.long %2-%1"
+  "bcl 20,31,$+8\\n\\t.long %1-$"
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
 

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* powerpc-linux unwinder fix for 3.4
@ 2005-03-17  0:27 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2005-03-17  0:27 UTC (permalink / raw)
  To: David Edelsohn; +Cc: gcc-patches

Hi David,
  In http://gcc.gnu.org/ml/gcc-patches/2005-01/msg02170.html, I fixed
a number of problems with the dwarf2 unwinder and mentioned that I'd
tested code on the 3.4 branch, but didn't ask permission to apply
there.  Now people want to use vdso enabled kernels with 3.4 libgcc,
so I'd like to apply the changes to the branch too.  OK?

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PATCH] PowerPC function arg alignment tidy
@ 2005-03-14 12:58 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2005-03-14 12:58 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

This tidies the alignment calculations for function arg passing.  One
function that calculates alignment padding correctly for all possible
alignment values is better than three different calculations, each
making use of local knowledge about the restricted set of alignments
to optimize the code a little.

It takes a little thought to see that this patch doesn't change
anything, especially for rs6000_arg_partial_bytes.  You need to know
that function_arg_boundary()/PARM_BOUNDARY-1 can only be 0, 1 or 3 for
32-bit, and 0 or 1 for 64-bit.  Then it's not hard to see that changing
from
  ((TARGET_32BIT ? 2 : 0) - x) & align
to
  -((ABI_V4 ? 2 : 6) + x) & align
doesn't alter the padding.

	* config/rs6000/rs6000.c (rs6000_parm_start): New function.
	(function_arg_advance): Use rs6000_parm_start.
	(function_arg, rs6000_arg_partial_bytes): Likewise.

Bootstrapped and regression tested powerpc-linux.  OK for mainline?

Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.794
diff -u -p -r1.794 rs6000.c
--- gcc/config/rs6000/rs6000.c	14 Mar 2005 07:24:25 -0000	1.794
+++ gcc/config/rs6000/rs6000.c	14 Mar 2005 09:50:53 -0000
@@ -4060,6 +4060,20 @@ function_arg_boundary (enum machine_mode
     return PARM_BOUNDARY;
 }
 
+/* For a function parm of MODE and TYPE, return the starting word in
+   the parameter area.  NWORDS of the parameter area are already used.  */
+
+static unsigned int
+rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
+{
+  unsigned int align;
+  unsigned int parm_offset;
+
+  align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
+  parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
+  return nwords + (-(parm_offset + nwords) & align);
+}
+
 /* Compute the size (in words) of a function argument.  */
 
 static unsigned long
@@ -4314,15 +4328,10 @@ function_arg_advance (CUMULATIVE_ARGS *c
   else
     {
       int n_words = rs6000_arg_size (mode, type);
-      int align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
+      int start_words = cum->words;
+      int align_words = rs6000_parm_start (mode, type, start_words);
 
-      /* The simple alignment calculation here works because
-	 function_arg_boundary / PARM_BOUNDARY will only be 1 or 2.
-	 If we ever want to handle alignments larger than 8 bytes for
-	 32-bit or 16 bytes for 64-bit, then we'll need to take into
-	 account the offset to the start of the parm save area.  */
-      align &= cum->words;
-      cum->words += align + n_words;
+      cum->words = align_words + n_words;
 
       if (GET_MODE_CLASS (mode) == MODE_FLOAT
 	  && TARGET_HARD_FLOAT && TARGET_FPRS)
@@ -4335,7 +4344,7 @@ function_arg_advance (CUMULATIVE_ARGS *c
 	  fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
 		   cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
 	  fprintf (stderr, "named = %d, align = %d, depth = %d\n",
-		   named, align, depth);
+		   named, align_words - start_words, depth);
 	}
     }
 }
@@ -4826,8 +4835,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum
     }
   else
     {
-      int align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
-      int align_words = cum->words + (cum->words & align);
+      int align_words = rs6000_parm_start (mode, type, cum->words);
 
       if (USE_FP_FOR_ARG_P (cum, mode, type))
 	{
@@ -4940,8 +4948,6 @@ rs6000_arg_partial_bytes (CUMULATIVE_ARG
 			  tree type, bool named)
 {
   int ret = 0;
-  int align;
-  int parm_offset;
   int align_words;
 
   if (DEFAULT_ABI == ABI_V4)
@@ -4957,9 +4963,7 @@ rs6000_arg_partial_bytes (CUMULATIVE_ARG
       && int_size_in_bytes (type) > 0)
     return 0;
 
-  align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
-  parm_offset = TARGET_32BIT ? 2 : 0;
-  align_words = cum->words + ((parm_offset - cum->words) & align);
+  align_words = rs6000_parm_start (mode, type, cum->words);
 
   if (USE_FP_FOR_ARG_P (cum, mode, type)
       /* If we are passing this arg in gprs as well, then this function

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
[parent not found: <1109545242.14992.234.camel@gaston>]
* [RFC] PowerPC 128 bit long double compatibility (PR target/19019)
@ 2005-02-15  2:20 David Edelsohn
  2005-02-15  2:22 ` Geoffrey Keating
  2005-02-15  2:53 ` Richard Henderson
  0 siblings, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2005-02-15  2:20 UTC (permalink / raw)
  To: Geoff Keating; +Cc: gcc-patches

	The GCC and IBM XLC semantics of the 128-bit long double differ
and do not interoperate completely.  This patch renames the support
functions to unique names so that the compilers do not try to use each
other's support functions.

	This will need to be pushed back into GCC 3.4 and Linux distros
using GCC 3.4 as well.

David

	* config/rs6000/darwin-ldouble.c (_xlqadd): Rename to __gcc_qadd.
	(_xlqsub): Rename to __gcc_qsub.
	(_xlqmul): Rename to __gcc_qmul.
	(_xlqdiv): Rename to __gcc_qdiv.
	* config/rs6000/libgcc-ppc64.ver: Rename symbols.
	* config/rs6000/rs6000.c (rs6000_init_libfuncs): Rename symbols.
	* config/rs6000/t-aix43 (LIB2FUNCS_EXTRA): New.
	* config/rs6000/t-aix52 (LIB2FUNCS_EXTRA): New.
	* config/rs6000/t-newas (LIB2FUNCS_EXTRA): New.

Index: darwin-ldouble.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/darwin-ldouble.c,v
retrieving revision 1.8
diff -c -p -r1.8 darwin-ldouble.c
*** darwin-ldouble.c	31 Jul 2004 01:40:16 -0000	1.8
--- darwin-ldouble.c	14 Feb 2005 22:08:49 -0000
*************** Software Foundation, 59 Temple Place - S
*** 30,41 ****
  /* Implementations of floating-point long double basic arithmetic
     functions called by the IBM C compiler when generating code for
     PowerPC platforms.  In particular, the following functions are
!    implemented: _xlqadd, _xlqsub, _xlqmul, and _xlqdiv.  Double-double
!    algorithms are based on the paper "Doubled-Precision IEEE Standard
!    754 Floating-Point Arithmetic" by W. Kahan, February 26, 1987.  An
!    alternative published reference is "Software for Doubled-Precision
!    Floating-Point Computations", by Seppo Linnainmaa, ACM TOMS vol 7
!    no 3, September 1981, pages 272-283.  */
  
  /* Each long double is made up of two IEEE doubles.  The value of the
     long double is the sum of the values of the two parts.  The most
--- 30,41 ----
  /* Implementations of floating-point long double basic arithmetic
     functions called by the IBM C compiler when generating code for
     PowerPC platforms.  In particular, the following functions are
!    implemented: __gcc_qadd, __gcc_qsub, __gcc_qmul, and __gcc_qdiv.
!    Double-double algorithms are based on the paper "Doubled-Precision
!    IEEE Standard 754 Floating-Point Arithmetic" by W. Kahan, February 26,
!    1987.  An alternative published reference is "Software for
!    Doubled-Precision Floating-Point Computations", by Seppo Linnainmaa,
!    ACM TOMS vol 7 no 3, September 1981, pages 272-283.  */
  
  /* Each long double is made up of two IEEE doubles.  The value of the
     long double is the sum of the values of the two parts.  The most
*************** Software Foundation, 59 Temple Place - S
*** 48,54 ****
  
     This code currently assumes big-endian.  */
  
! #if !_SOFT_FLOAT && (defined (__MACH__) || defined (__powerpc64__))
  
  #define fabs(x) __builtin_fabs(x)
  #define isless(x, y) __builtin_isless (x, y)
--- 48,54 ----
  
     This code currently assumes big-endian.  */
  
! #if !_SOFT_FLOAT && (defined (__MACH__) || defined (__powerpc64__) || defined (_AIX))
  
  #define fabs(x) __builtin_fabs(x)
  #define isless(x, y) __builtin_isless (x, y)
*************** Software Foundation, 59 Temple Place - S
*** 62,71 ****
     but GCC currently generates poor code when a union is used to turn
     a long double into a pair of doubles.  */
  
! extern long double _xlqadd (double, double, double, double);
! extern long double _xlqsub (double, double, double, double);
! extern long double _xlqmul (double, double, double, double);
! extern long double _xlqdiv (double, double, double, double);
  
  typedef union
  {
--- 62,71 ----
     but GCC currently generates poor code when a union is used to turn
     a long double into a pair of doubles.  */
  
! extern long double __gcc_qadd (double, double, double, double);
! extern long double __gcc_qsub (double, double, double, double);
! extern long double __gcc_qmul (double, double, double, double);
! extern long double __gcc_qdiv (double, double, double, double);
  
  typedef union
  {
*************** typedef union
*** 75,81 ****
  
  /* Add two 'long double' values and return the result.	*/
  long double
! _xlqadd (double a, double aa, double c, double cc)
  {
    longDblUnion x;
    double z, q, zz, xh;
--- 75,81 ----
  
  /* Add two 'long double' values and return the result.	*/
  long double
! __gcc_qadd (double a, double aa, double c, double cc)
  {
    longDblUnion x;
    double z, q, zz, xh;
*************** _xlqadd (double a, double aa, double c, 
*** 110,122 ****
  }
  
  long double
! _xlqsub (double a, double b, double c, double d)
  {
!   return _xlqadd (a, b, -c, -d);
  }
  
  long double
! _xlqmul (double a, double b, double c, double d)
  {
    longDblUnion z;
    double t, tau, u, v, w;
--- 110,122 ----
  }
  
  long double
! __gcc_qsub (double a, double b, double c, double d)
  {
!   return __gcc_qadd (a, b, -c, -d);
  }
  
  long double
! __gcc_qmul (double a, double b, double c, double d)
  {
    longDblUnion z;
    double t, tau, u, v, w;
*************** _xlqmul (double a, double b, double c, d
*** 145,151 ****
  }
  
  long double
! _xlqdiv (double a, double b, double c, double d)
  {
    longDblUnion z;
    double s, sigma, t, tau, u, v, w;
--- 145,151 ----
  }
  
  long double
! __gcc_qdiv (double a, double b, double c, double d)
  {
    longDblUnion z;
    double s, sigma, t, tau, u, v, w;
Index: libgcc-ppc64.ver
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/libgcc-ppc64.ver,v
retrieving revision 1.2
diff -c -p -r1.2 libgcc-ppc64.ver
*** libgcc-ppc64.ver	7 Feb 2004 03:06:46 -0000	1.2
--- libgcc-ppc64.ver	14 Feb 2005 22:08:49 -0000
***************
*** 1,7 ****
  GCC_3.4 {
    # long double support
!   _xlqadd
!   _xlqsub
!   _xlqmul
!   _xlqdiv
  }
--- 1,7 ----
  GCC_3.4 {
    # long double support
!   __gcc_qadd
!   __gcc_qsub
!   __gcc_qmul
!   __gcc_qdiv
  }
Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.785
diff -c -p -r1.785 rs6000.c
*** rs6000.c	13 Feb 2005 21:31:25 -0000	1.785
--- rs6000.c	14 Feb 2005 22:08:49 -0000
*************** rs6000_init_libfuncs (void)
*** 8871,8880 ****
  	}
  
        /* Standard AIX/Darwin/64-bit SVR4 quad floating point routines.  */
!       set_optab_libfunc (add_optab, TFmode, "_xlqadd");
!       set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
!       set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
!       set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
      }
    else
      {
--- 8871,8880 ----
  	}
  
        /* Standard AIX/Darwin/64-bit SVR4 quad floating point routines.  */
!       set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
!       set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
!       set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
!       set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
      }
    else
      {
Index: t-aix43
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/t-aix43,v
retrieving revision 1.22
diff -c -p -r1.22 t-aix43
*** t-aix43	10 Jan 2005 15:10:05 -0000	1.22
--- t-aix43	14 Feb 2005 22:08:49 -0000
*************** SHLIB_MKMAP = $(srcdir)/mkmap-flat.awk
*** 61,66 ****
--- 61,69 ----
  SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver
  SHLIB_NM_FLAGS = -Bpg -X32_64
  
+ # GCC 128-bit long double support routines.
+ LIB2FUNCS_EXTRA = $(srcdir)/config/rs6000/darwin-ldouble.c
+ 
  # Either 32-bit and 64-bit objects in archives.
  AR_FLAGS_FOR_TARGET = -X32_64
  
Index: t-aix52
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/t-aix52,v
retrieving revision 1.5
diff -c -p -r1.5 t-aix52
*** t-aix52	7 Dec 2004 18:44:31 -0000	1.5
--- t-aix52	14 Feb 2005 22:08:49 -0000
*************** SHLIB_MKMAP = $(srcdir)/mkmap-flat.awk
*** 42,47 ****
--- 42,50 ----
  SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver
  SHLIB_NM_FLAGS = -Bpg -X32_64
  
+ # GCC 128-bit long double support routines.
+ LIB2FUNCS_EXTRA = $(srcdir)/config/rs6000/darwin-ldouble.c
+ 
  # Either 32-bit and 64-bit objects in archives.
  AR_FLAGS_FOR_TARGET = -X32_64
  
Index: t-newas
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/t-newas,v
retrieving revision 1.6
diff -c -p -r1.6 t-newas
*** t-newas	18 Dec 2002 22:45:35 -0000	1.6
--- t-newas	14 Feb 2005 22:08:49 -0000
*************** MULTILIB_MATCHES	= $(MULTILIB_MATCHES_FL
*** 27,32 ****
--- 27,35 ----
  			  mcpu?powerpc=mpowerpc-gpopt \
  			  mcpu?powerpc=mpowerpc-gfxopt
  
+ # GCC 128-bit long double support routines.
+ LIB2FUNCS_EXTRA = $(srcdir)/config/rs6000/darwin-ldouble.c
+ 
  # Aix 3.2.x needs milli.exp for -mcpu=common
  EXTRA_PARTS = milli.exp
  milli.exp: $(srcdir)/config/rs6000/milli.exp

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PATCH] powerpc dwarf2 unwinder fallback
@ 2005-01-29  7:47 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2005-01-29  7:47 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

This patch corrects some problems with the unwind fallback code on
powerpc-linux and powerpc64-linux.

1) Floating point and vector registers were not being restored.  OK, so
who uses fprs and vmx inside signal handlers?  It can't be very common
to have explicit use, but gcc generates code that uses fp and vector
regs to move blocks of memory around.

2) The 64-bit rt_sigreturn code used to access saved registers by an
offset from pc.  This works when the trampoline is on the stack, but new
linux kernels will use a vdso with the trampoline no longer on the
stack.  I think the only reason that an offset from pc was used was to
support linux-2.4.19 and linux-2.4.20, the first two released linux
kernels that supported ppc64.  These kernels used a different stack
layout than later kernels.  Since people might still be running these
old kernels, I've kept code to support them, and added extra code to
support the vdso.

3) I've removed gcc_sigcontext because it only bore a passing semblance
to the real structure, and merged it with gcc_ucontext.  get_sigcontext
becomes get_regs too, because we are really only interested in regs.

Tested with powerpc-linux and powerpc64-linux bootstrap and regression
check.  Also glibc "make check" both with and without vdso (but using
the equivalent code with a gcc-3.4 branch compiler to avoid glibc build
problems with gcc-4.0).  OK to install?

	* config/rs6000/linux-unwind.h (struct gcc_vregs): New.
	(struct gcc_regs): Rename from gcc_pt_regs.  Add more regs.
	(struct gcc_sigcontext): Delete.  Merge contents to..
	(struct gcc_ucontext): ..here.
	(get_sigcontext): Delete.
	(get_regs): New function, like get_sigcontext but return regs ptr.
	64-bit version finds regs from r1 to support vdso.
	(ppc_linux_aux_vector): New function.
	(ppc_fallback_frame_state): Modify for get_regs.  Restore fprs
	and vector regs.

Index: gcc/config/rs6000/linux-unwind.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/linux-unwind.h,v
retrieving revision 1.2
diff -u -p -r1.2 linux-unwind.h
--- gcc/config/rs6000/linux-unwind.h	15 Sep 2004 11:43:31 -0000	1.2
+++ gcc/config/rs6000/linux-unwind.h	29 Jan 2005 07:17:56 -0000
@@ -24,7 +24,22 @@
    these structs elsewhere;  Many fields are missing, particularly
    from the end of the structures.  */
 
-struct gcc_pt_regs
+struct gcc_vregs
+{
+  __attribute__ ((vector_size (16))) int vr[32];
+#ifdef __powerpc64__
+  unsigned int pad1[3];
+  unsigned int vscr;
+  unsigned int vsave;
+  unsigned int pad2[3];
+#else
+  unsigned int vsave;
+  unsigned int pad[2];
+  unsigned int vscr;
+#endif
+};
+
+struct gcc_regs
 {
   unsigned long gpr[32];
   unsigned long nip;
@@ -34,22 +49,32 @@ struct gcc_pt_regs
   unsigned long link;
   unsigned long xer;
   unsigned long ccr;
-};
-
-struct gcc_sigcontext
-{
-  unsigned long	pad[7];
-  struct gcc_pt_regs *regs;
+  unsigned long softe;
+  unsigned long trap;
+  unsigned long dar;
+  unsigned long dsisr;
+  unsigned long result;
+  unsigned long pad1[4];
+  double fpr[32];
+  unsigned int pad2;
+  unsigned int fpscr;
+#ifdef __powerpc64__
+  struct gcc_vregs *vp;
+#else
+  unsigned int pad3[2];
+#endif
+  struct gcc_vregs vregs;
 };
 
 struct gcc_ucontext
 {
 #ifdef __powerpc64__
-  unsigned long pad[21];
+  unsigned long pad[28];
 #else
-  unsigned long pad[5];
+  unsigned long pad[12];
 #endif
-  struct gcc_sigcontext uc_mcontext;
+  struct gcc_regs *regs;
+  struct gcc_regs rsave;
 };
 
 #ifdef __powerpc64__
@@ -77,34 +102,54 @@ frob_update_context (struct _Unwind_Cont
 }
 
 /* If PC is at a sigreturn trampoline, return a pointer to the
-   sigcontext.  Otherwise return NULL.  */
+   regs.  Otherwise return NULL.  */
 
-static struct gcc_sigcontext *
-get_sigcontext (struct _Unwind_Context *context)
+static struct gcc_regs *
+get_regs (struct _Unwind_Context *context)
 {
   const unsigned char *pc = context->ra;
 
   /* addi r1, r1, 128; li r0, 0x0077; sc  (sigreturn) */
   /* addi r1, r1, 128; li r0, 0x00AC; sc  (rt_sigreturn) */
-  if (*(unsigned int *) (pc+0) != 0x38210000 + SIGNAL_FRAMESIZE
-      || *(unsigned int *) (pc+8) != 0x44000002)
+  if (*(unsigned int *) (pc + 0) != 0x38210000 + SIGNAL_FRAMESIZE
+      || *(unsigned int *) (pc + 8) != 0x44000002)
     return NULL;
-  if (*(unsigned int *) (pc+4) == 0x38000077)
+  if (*(unsigned int *) (pc + 4) == 0x38000077)
     {
       struct sigframe {
 	char gap[SIGNAL_FRAMESIZE];
-	struct gcc_sigcontext sigctx;
-      } *rt_ = context->cfa;
-      return &rt_->sigctx;
+	unsigned long pad[7];
+	struct gcc_regs *regs;
+      } *frame = (struct sigframe *) context->cfa;
+      return frame->regs;
     }
-  else if (*(unsigned int *) (pc+4) == 0x380000AC)
+  else if (*(unsigned int *) (pc + 4) == 0x380000AC)
     {
-      struct rt_sigframe {
+      /* This works for 2.4 kernels, but not for 2.6 kernels with vdso
+	 because pc isn't pointing into the stack.  Can be removed when
+	 no one is running 2.4.19 or 2.4.20, the first two ppc64
+	 kernels released.  */
+      struct rt_sigframe_24 {
 	int tramp[6];
 	void *pinfo;
 	struct gcc_ucontext *puc;
-      } *rt_ = (struct rt_sigframe *) pc;
-      return &rt_->puc->uc_mcontext;
+      } *frame24 = (struct rt_sigframe_24 *) pc;
+
+      /* Test for magic value in *puc of vdso.  */
+      if ((long) frame24->puc != -21 * 8)
+	return frame24->puc->regs;
+      else
+	{
+	  struct rt_sigframe {
+	    char gap[SIGNAL_FRAMESIZE];
+	    struct gcc_ucontext uc;
+	    unsigned long pad[2];
+	    int tramp[6];
+	    void *pinfo;
+	    struct gcc_ucontext *puc;
+	  } *frame = (struct rt_sigframe *) context->cfa;
+	  return frame->uc.regs;
+	}
     }
   return NULL;
 }
@@ -113,8 +158,8 @@ get_sigcontext (struct _Unwind_Context *
 
 enum { SIGNAL_FRAMESIZE = 64 };
 
-static struct gcc_sigcontext *
-get_sigcontext (struct _Unwind_Context *context)
+static struct gcc_regs *
+get_regs (struct _Unwind_Context *context)
 {
   const unsigned char *pc = context->ra;
 
@@ -122,31 +167,64 @@ get_sigcontext (struct _Unwind_Context *
   /* li r0, 0x0077; sc  (sigreturn new)  */
   /* li r0, 0x6666; sc  (rt_sigreturn old)  */
   /* li r0, 0x00AC; sc  (rt_sigreturn new)  */
-  if (*(unsigned int *) (pc+4) != 0x44000002)
+  if (*(unsigned int *) (pc + 4) != 0x44000002)
     return NULL;
-  if (*(unsigned int *) (pc+0) == 0x38007777
-      || *(unsigned int *) (pc+0) == 0x38000077)
+  if (*(unsigned int *) (pc + 0) == 0x38007777
+      || *(unsigned int *) (pc + 0) == 0x38000077)
     {
       struct sigframe {
 	char gap[SIGNAL_FRAMESIZE];
-	struct gcc_sigcontext sigctx;
-      } *rt_ = context->cfa;
-      return &rt_->sigctx;
+	unsigned long pad[7];
+	struct gcc_regs *regs;
+      } *frame = (struct sigframe *) context->cfa;
+      return frame->regs;
     }
-  else if (*(unsigned int *) (pc+0) == 0x38006666
-	   || *(unsigned int *) (pc+0) == 0x380000AC)
+  else if (*(unsigned int *) (pc + 0) == 0x38006666
+	   || *(unsigned int *) (pc + 0) == 0x380000AC)
     {
       struct rt_sigframe {
 	char gap[SIGNAL_FRAMESIZE + 16];
 	char siginfo[128];
 	struct gcc_ucontext uc;
-      } *rt_ = context->cfa;
-      return &rt_->uc.uc_mcontext;
+      } *frame = (struct rt_sigframe *) context->cfa;
+      return frame->uc.regs;
     }
   return NULL;
 }
 #endif
 
+/* Find an entry in the process auxilliary vector.  The canonical way to
+   test for VMX is to look at AT_HWCAP.  */
+
+static long
+ppc_linux_aux_vector (long which)
+{
+  /* __libc_stack_end holds the original stack passed to a process.  */
+  extern long *__libc_stack_end;
+  long argc;
+  char **argv;
+  char **envp;
+  struct auxv
+  {
+    long a_type;
+    long a_val;
+  } *auxp;
+
+  /* The Linux kernel puts argc first on the stack.  */
+  argc = __libc_stack_end[0];
+  /* Followed by argv, NULL terminated.  */
+  argv = (char **) __libc_stack_end + 1;
+  /* Followed by environment string pointers, NULL terminated. */
+  envp = argv + argc + 1;
+  while (*envp++)
+    continue;
+  /* Followed by the aux vector, zero terminated.  */
+  for (auxp = (struct auxv *) envp; auxp->a_type != 0; ++auxp)
+    if (auxp->a_type == which)
+      return auxp->a_val;
+  return 0;
+}
+
 /* Do code reading to identify a signal frame, and set the frame
    state data appropriately.  See unwind-dw2.c for the structs.  */
 
@@ -156,14 +234,15 @@ static _Unwind_Reason_Code
 ppc_fallback_frame_state (struct _Unwind_Context *context,
 			  _Unwind_FrameState *fs)
 {
-  struct gcc_sigcontext *sc = get_sigcontext (context);
+  static long hwcap = 0;
+  struct gcc_regs *regs = get_regs (context);
   long new_cfa;
   int i;
 
-  if (sc == NULL)
+  if (regs == NULL)
     return _URC_END_OF_STACK;
 
-  new_cfa = sc->regs->gpr[STACK_POINTER_REGNUM];
+  new_cfa = regs->gpr[STACK_POINTER_REGNUM];
   fs->cfa_how = CFA_REG_OFFSET;
   fs->cfa_reg = STACK_POINTER_REGNUM;
   fs->cfa_offset = new_cfa - (long) context->cfa;
@@ -172,21 +251,65 @@ ppc_fallback_frame_state (struct _Unwind
     if (i != STACK_POINTER_REGNUM)
       {
 	fs->regs.reg[i].how = REG_SAVED_OFFSET;
-	fs->regs.reg[i].loc.offset
-	  = (long)&(sc->regs->gpr[i]) - new_cfa;
+	fs->regs.reg[i].loc.offset = (long) &regs->gpr[i] - new_cfa;
       }
 
   fs->regs.reg[CR2_REGNO].how = REG_SAVED_OFFSET;
-  fs->regs.reg[CR2_REGNO].loc.offset
-    = (long)&(sc->regs->ccr) - new_cfa;
+  fs->regs.reg[CR2_REGNO].loc.offset = (long) &regs->ccr - new_cfa;
 
   fs->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET;
-  fs->regs.reg[LINK_REGISTER_REGNUM].loc.offset
-    = (long)&(sc->regs->link) - new_cfa;
+  fs->regs.reg[LINK_REGISTER_REGNUM].loc.offset = (long) &regs->link - new_cfa;
 
   fs->regs.reg[ARG_POINTER_REGNUM].how = REG_SAVED_OFFSET;
-  fs->regs.reg[ARG_POINTER_REGNUM].loc.offset
-    = (long)&(sc->regs->nip) - new_cfa;
+  fs->regs.reg[ARG_POINTER_REGNUM].loc.offset = (long) &regs->nip - new_cfa;
   fs->retaddr_column = ARG_POINTER_REGNUM;
+
+  if (hwcap == 0)
+    {
+      hwcap = ppc_linux_aux_vector (16);
+      /* These will already be set if we found AT_HWCAP.  A non-zero
+	 value stops us looking again if for some reason we couldn't
+	 find AT_HWCAP.  */
+#ifdef __powerpc64__
+      hwcap |= 0xc0000000;
+#else
+      hwcap |= 0x80000000;
+#endif
+    }
+
+  /* If we have a FPU...  */
+  if (hwcap & 0x08000000)
+    for (i = 0; i < 32; i++)
+      {
+	fs->regs.reg[i + 32].how = REG_SAVED_OFFSET;
+	fs->regs.reg[i + 32].loc.offset = (long) &regs->fpr[i] - new_cfa;
+      }
+
+  /* If we have a VMX unit...  */
+  if (hwcap & 0x10000000)
+    {
+      struct gcc_vregs *vregs;
+#ifdef __powerpc64__
+      vregs = regs->vp;
+#else
+      vregs = &regs->vregs;
+#endif
+      if (regs->msr & (1 << 25))
+	{
+	  for (i = 0; i < 32; i++)
+	    {
+	      fs->regs.reg[i + FIRST_ALTIVEC_REGNO].how = REG_SAVED_OFFSET;
+	      fs->regs.reg[i + FIRST_ALTIVEC_REGNO].loc.offset
+		= (long) &vregs[i] - new_cfa;
+	    }
+
+	  fs->regs.reg[VSCR_REGNO].how = REG_SAVED_OFFSET;
+	  fs->regs.reg[VSCR_REGNO].loc.offset = (long) &vregs->vscr - new_cfa;
+	}
+
+      fs->regs.reg[VRSAVE_REGNO].how = REG_SAVED_OFFSET;
+      fs->regs.reg[VRSAVE_REGNO].loc.offset = (long) &vregs->vsave - new_cfa;
+    }
+
   return _URC_NO_REASON;
 }

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PATCH] PR target/19389 Odd gpr mem load unrecognizable insn
@ 2005-01-12  5:02 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2005-01-12  5:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

This patch constrains addresses accepted by movtf so that gpr loads and
stores to memory must satisfy word_offset_memref_operand, similarly to
the way movdf constrains gpr loads and stores.  This allows David's
recent rs6000_legitimize_reload_address fix to trigger for TFmode.

	PR target/19389
	* config/rs6000/rs6000.md (movtf_internal): Replace r->o and m->r
	with r->Y and Y->r.

Bootstrap etc. in progress.  OK for mainline?

Index: gcc/config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.339
diff -u -p -r1.339 rs6000.md
--- gcc/config/rs6000/rs6000.md	25 Dec 2004 12:41:02 -0000	1.339
+++ gcc/config/rs6000/rs6000.md	12 Jan 2005 04:50:12 -0000
@@ -8234,10 +8234,10 @@
 
 ; It's important to list the o->f and f->o moves before f->f because
 ; otherwise reload, given m->f, will try to pick f->f and reload it,
-; which doesn't make progress.  Likewise r->o<> must be before r->r.
+; which doesn't make progress.  Likewise r->Y must be before r->r.
 (define_insn_and_split "*movtf_internal"
-  [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,f,r,o<>,r")
-	(match_operand:TF 1 "input_operand"         "f,o,f,mGHF,r,r"))]
+  [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,f,r,Y,r")
+	(match_operand:TF 1 "input_operand"         "f,o,f,YGHF,r,r"))]
   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
    && (gpc_reg_operand (operands[0], TFmode)

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PATCH] Fix target/19147: invalid rlwinm patterns
@ 2004-12-24 13:47 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2004-12-24 13:47 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

gcc.c-torture/execute/930718-1.c has been failing on powerpc64-linux
since somewhere in the latter half of September, and I hadn't got around
to investigating the reason.  It turns out that this failure is due to a
problem with andsi3_internal7 and andsi3_internal8, two patterns dealing
with wrapping rlwinm masks (ie. mb > me) I added to rs6000.md on
2002-07-24.  Fariborz Jahanian made a fix for one failure mode of
andsi3_internal8 on 2004-10-26, and at the time I commented that LT and
GT condition bits might be wrong before his patch.

Well, they're still wrong.  To get LT right, you must have a mask that
wraps over the high bits, but we go out of our way to ensure that the
mask doesn't wrap (to make EQ right).  A wrapping mask won't do for EQ
because "rlwinm." works by duplicating the 32-bit input to both high and
low word of a 64-bit value, rotating by 0 to 31 bits, then masking with
a pattern consisting of 1's between two given bits in the low word and
0's elsewhere.  The trickiness is that if the start bit of the mask is
less signifigant than the end bit, then the mask wraps around.  If the
mask wraps then the high word of the mask will be 1's, which will result
in EQ false if any bit of the input is set.  On the other hand, without
a wrapping mask LT will always be false regardless of input.

One solution to this dilemma is to rotate the input so that we can use
a non-wrapping mask to clear bits, then rotate back and use a wrapping
mask of all 1's to generate the condition bits.  That gets EQ, LT and
GT correct.  Unfortunately, if the output is wanted we've just
duplicated the low word to the high word, and I think GCC "knows" that
an andsi operation doesn't set bits willy nilly in the high word.  (See
rtlanal.c:nonzero_bits).

So..

	PR target/19147
	* config/rs6000/rs6000.md (andsi3_internal7, andsi3_internal8): Delete.

OK mainline, 3.4 and 3.3?

Index: gcc/config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.337
diff -u -p -r1.337 rs6000.md
--- gcc/config/rs6000/rs6000.md	11 Dec 2004 17:37:25 -0000	1.337
+++ gcc/config/rs6000/rs6000.md	24 Dec 2004 13:42:00 -0000
@@ -2411,60 +2411,6 @@
 }"
   [(set_attr "length" "8")])
 
-(define_insn_and_split "*andsi3_internal7"
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
-	(compare:CC (and:SI (match_operand:SI 0 "gpc_reg_operand" "r,r")
-			    (match_operand:SI 1 "mask_operand_wrap" "i,i"))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r"))]
-  "TARGET_POWERPC64"
-  "#"
-  "TARGET_POWERPC64"
-  [(parallel [(set (match_dup 2)
-		   (compare:CC (and:SI (rotate:SI (match_dup 0) (match_dup 4))
-				       (match_dup 5))
-			       (const_int 0)))
-	      (clobber (match_dup 3))])]
-  "
-{
-  int mb = extract_MB (operands[1]);
-  int me = extract_ME (operands[1]);
-  operands[4] = GEN_INT (me + 1);
-  operands[5] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb)));
-}"
-  [(set_attr "type" "delayed_compare,compare")
-   (set_attr "length" "4,8")])
-
-(define_insn_and_split "*andsi3_internal8"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
-	(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-			    (match_operand:SI 2 "mask_operand_wrap" "i,i"))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(and:SI (match_dup 1)
-		(match_dup 2)))]
-  "TARGET_POWERPC64"
-  "#"
-  "TARGET_POWERPC64"
-  [(set (match_dup 0)
-		   (and:SI (rotate:SI (match_dup 1) (match_dup 4))
-			   (match_dup 5)))
-   (parallel [(set (match_dup 3)
-	           (compare:CC (rotate:SI (match_dup 0) (match_dup 6))
-			       (const_int 0)))
-              (set (match_dup 0)
-	           (rotate:SI (match_dup 0) (match_dup 6)))])]
-  "
-{
-  int mb = extract_MB (operands[2]);
-  int me = extract_ME (operands[2]);
-  operands[4] = GEN_INT (me + 1);
-  operands[6] = GEN_INT (32 - (me + 1));
-  operands[5] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb)));
-}"
-  [(set_attr "type" "delayed_compare,compare")
-   (set_attr "length" "8,12")])
-
 (define_expand "iorsi3"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
 	(ior:SI (match_operand:SI 1 "gpc_reg_operand" "")

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PATCH] PR target/19137: ICE with load of TImode constant
@ 2004-12-23 14:57 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2004-12-23 14:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

This fixes an ICE on powerpc-linux, found running the gcc testsuite.
The problem being that rs6000.md has no TImode move pattern handling
constants (*), and the existing splitter doesn't do anything until after
reload.  This ICE happens in regclass.

*) The movti_string pattern that might seem to be available for
powerpc-linux has a too restrictive operand predicate.
reg_or_mem_operand won't match a constant.  An alternative fix is to
relax this predicate to "input_operand".  That unfortunately results in
reload forcing the zero to memory, so generated code is poor.  OK, you
could add an "n" alternative..  See below for a patch to do that.

Here's my first attempt at a fix.

	PR target/19137
	* config/rs6000/rs6000.c (rs6000_emit_move): Split TImode constant
	loads.

diff -u6rp -xCVS -x'*~' -x'.#*' gcc-virgin/gcc/config/rs6000/rs6000.c gcc-current/gcc/config/rs6000/rs6000.c
--- gcc-virgin/gcc/config/rs6000/rs6000.c	2004-12-23 17:46:27.419162669 +1030
+++ gcc-current/gcc/config/rs6000/rs6000.c	2004-12-23 20:05:46.989764716 +1030
@@ -4334,16 +4334,17 @@ rs6000_emit_move (rtx dest, rtx source, 
   if (reload_in_progress && mode == Pmode
       && (! general_operand (operands[1], mode)
 	  || ! nonimmediate_operand (operands[0], mode)))
     goto emit_set;
 
   /* 128-bit constant floating-point values on Darwin should really be
-     loaded as two parts.  */
-  if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
-      && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
-      && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
+     loaded as two parts.  Similarly, split TImode constants.  */
+  if (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+       && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
+       && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
+      || (mode == TImode && GET_CODE (operands[1]) == CONST_INT))
     {
       /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
 	 know how to get a DFmode SUBREG of a TFmode.  */
       rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode, 0),
 			simplify_gen_subreg (DImode, operands[1], mode, 0),
 			DImode);


Alternative fix.  I'm inclined to think this one is better because it
delays splitting, which means less rtl to process in earlier passes.

	PR target/19137
	* config/rs6000/rs6000.md (movti_power, movti_string): Relax
	operand[1] predicate to input_operand, and add r<-n alternative.

powerpc-linux bootstrap and regression test in progress.  OK mainline?

diff -urp -xCVS -x'*~' -x'.#*' gcc-virgin/gcc/config/rs6000/rs6000.md gcc-current/gcc/config/rs6000/rs6000.md
--- gcc-virgin/gcc/config/rs6000/rs6000.md	2004-12-18 20:17:55.000000000 +1030
+++ gcc-current/gcc/config/rs6000/rs6000.md	2004-12-24 00:53:07.155150191 +1030
@@ -8692,8 +8695,8 @@
 ;; giving the SCRATCH mq.
 
 (define_insn "*movti_power"
-  [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
-	(match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
+  [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r,r")
+	(match_operand:TI 1 "input_operand" "r,r,r,Q,m,n"))
    (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
   "TARGET_POWER && ! TARGET_POWERPC64
    && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
@@ -8718,14 +8721,15 @@
 	return \"{lsi|lswi} %0,%P1,16\";
       /* ... fall through ...  */
     case 4:
+    case 5:
       return \"#\";
     }
 }"
-  [(set_attr "type" "store,store,*,load,load")])
+  [(set_attr "type" "store,store,*,load,load,*")])
 
 (define_insn "*movti_string"
-  [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,o<>,????r,????r,????r")
-	(match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))]
+  [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,o<>,????r,????r,????r,r")
+	(match_operand:TI 1 "input_operand" "r,r,r,Q,m,n"))]
   "! TARGET_POWER && ! TARGET_POWERPC64
    && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
   "*
@@ -8748,10 +8752,11 @@
 	return \"{lsi|lswi} %0,%P1,16\";
       /* ... fall through ...  */
     case 4:
+    case 5:
       return \"#\";
     }
 }"
-  [(set_attr "type" "store,store,*,load,load")])
+  [(set_attr "type" "store,store,*,load,load,*")])
 
 (define_insn "*movti_ppc64"
   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o<>,r")

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* mklibgcc fallout
@ 2004-12-02 12:13 Alan Modra
  2004-12-02 17:12 ` Zack Weinberg
  0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2004-12-02 12:13 UTC (permalink / raw)
  To: gcc-patches; +Cc: zack

This fixes one problem with Zack's recent mklibgcc changes.  On a native
powerpc64-linux build, I was seeing

checking for sin in -lm... configure: error: Link tests are not allowed after GCC_NO_EXECUTABLES.
make[1]: *** [configure-target-libstdc++-v3] Error 1

when building multilibs.  This turned out to be due to a bad symlink in
gcc/32,
  libgcc_s_32.so -> 32/libgcc_s.so.1
which should be
  libgcc_s_32.so -> libgcc_s.so.1.

	* mklibgcc.in: Trim directory when substituting shlib_base_name.

See config/t-slibgcc-elf-ver for where shlib_base_name is used.
Tested powerpc64-linux.

--- gcc-virgin/gcc/mklibgcc.in	2004-12-01 08:25:51.000000000 +1030
+++ gcc-current/gcc/mklibgcc.in	2004-12-02 21:41:44.682588912 +1030
@@ -755,13 +755,14 @@
 
   # Shared libraries.
   if [ "$libgcc_s_so" ]; then
+    shlib_base_name=`echo $libgcc_s_so_base | sed 's,.*/,,'`
     echo ""
     echo "$libgcc_s_so: stmp-dirs $libunwind_so"
     echo "	$SHLIB_LINK" \
 	 | sed -e "s%@multilib_flags@%$flags%g" \
 	       -e "s%@multilib_dir@%$dir%g" \
 	       -e "s%@shlib_objs@%\$(filter-out $libgcc_s_so_extra,\$(objects))%g" \
-	       -e "s%@shlib_base_name@%$libgcc_s_so_base%g" \
+	       -e "s%@shlib_base_name@%$shlib_base_name%g" \
 	       -e "s%@shlib_so_name@%$libgcc_s_soname%g" \
 	       -e "s%@shlib_map_file@%$mapfile%g" \
 	       -e "s%@shlib_dir@%$shlib_dir%g" \
@@ -770,13 +771,14 @@
   fi
 
   if [ "$libunwind_so" ]; then
+    shlib_base_name=`echo $libunwind_so_base | sed 's,.*/,,'`
     echo ""
     echo "$libunwind_so: stmp-dirs"
     echo "	$SHLIBUNWIND_LINK" \
 	   | sed -e "s%@multilib_flags@%$flags%g" \
 		 -e "s%@multilib_dir@%$dir%g" \
 		 -e "s%@shlib_objs@%\$(filter-out $libunwind_so_extra,\$(objects))%g" \
-		 -e "s%@shlib_base_name@%$libunwind_so_base%g" \
+		 -e "s%@shlib_base_name@%$shlib_base_name%g" \
 		 -e "s%@shlib_so_name@%$libunwind_soname%g" \
 		 -e "s%@shlib_dir@%$shlib_dir%g" \
 		 -e "s%@shlib_slibdir_qual@%$shlib_dir_qual%g"
-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [RS6000] Fix PR12817
@ 2004-11-26 10:32 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2004-11-26 10:32 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

The comment below says it all.  I've added a testcase to the pr.

	PR target/12817
	* config/rs6000/rs6000.c (rs6000_emit_prologue): Use r11 for vrsave.

Bootstrap and regression test powerpc-linux in progress.  This ought to
count as obvious, but I'll ask.  OK to install?  gcc-3.4 and gcc-3.3
too?

diff -urp -xCVS -x'*~' gcc-virgin/gcc/config/rs6000/rs6000.c gcc-current/gcc/config/rs6000/rs6000.c
--- gcc-virgin/gcc/config/rs6000/rs6000.c	2004-11-26 14:48:20.163051172 +1030
+++ gcc-current/gcc/config/rs6000/rs6000.c	2004-11-26 19:45:39.482476440 +1030
@@ -14026,8 +14042,9 @@ rs6000_emit_prologue (void)
       rtx reg, mem, vrsave;
       int offset;
 
-      /* Get VRSAVE onto a GPR.  */
-      reg = gen_rtx_REG (SImode, 12);
+      /* Get VRSAVE onto a GPR.  Note that ABI_V4 might be using r12
+	 as frame_reg_rtx.  */
+      reg = gen_rtx_REG (SImode, 11);
       vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
       if (TARGET_MACHO)
 	emit_insn (gen_get_vrsave_internal (reg));

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PATCH] Fix PR16356
@ 2004-11-26  2:32 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2004-11-26  2:32 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

This fixes PR 16356, a regression caused by floatdisf2_internal2
manipulating its input register rather than copying to a new output reg.
While I was poking at this problem, I noticed we can get rid of one of
the branches in this expander by using the following trick:

  if (x & 2047)
    {
      x &= ~2047;
      x |= 2048;
    }

can be implemented as

  tmp = x & 2047;
  tmp += 2047;
  x |= tmp;
  x &= ~2047;

Removing the branch allows floatdisf2_internal2 to be used when
TARGET_POWERPC64, because the old branch condition was the only reason
that this insn needed to be TARGET_64BIT.

	PR rtl-optimization/16356
	* config/rs6000/rs6000.md (floatdisf2_internal2): Rewrite with
	separate output register and one less jump.  Enable for powerpc64.
	(floatdisf2): Adjust for above.

Bootstrapped and regression tested powerpc64-linux.  Also tested that
a few G random long values convert to exactly the same floats as older
compilers give.  OK to apply?  3.4 too?

--- gcc-virgin/gcc/config/rs6000/rs6000.md	2004-11-15 17:05:37.000000000 +1030
+++ gcc-current/gcc/config/rs6000/rs6000.md	2004-11-26 08:48:09.671759913 +1030
@@ -5402,16 +5402,18 @@
 (define_expand "floatdisf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
-  "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
   "
 {
+  rtx val = operands[1];
   if (!flag_unsafe_math_optimizations)
     {
       rtx label = gen_label_rtx ();
-      emit_insn (gen_floatdisf2_internal2 (operands[1], label));
+      val = gen_reg_rtx (DImode);
+      emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
       emit_label (label);
     }
-  emit_insn (gen_floatdisf2_internal1 (operands[0], operands[1]));
+  emit_insn (gen_floatdisf2_internal1 (operands[0], val));
   DONE;
 }")
 
@@ -5436,30 +5438,31 @@
 ;; by a bit that won't be lost at that stage, but is below the SFmode
 ;; rounding position.
 (define_expand "floatdisf2_internal2"
-  [(parallel [(set (match_dup 4)
-		   (compare:CC (and:DI (match_operand:DI 0 "" "")
-				       (const_int 2047))
-			       (const_int 0)))
-	      (set (match_dup 2) (and:DI (match_dup 0) (const_int 2047)))
-	      (clobber (match_scratch:CC 7 ""))])
-   (set (match_dup 3) (ashiftrt:DI (match_dup 0) (const_int 53)))
-   (set (match_dup 3) (plus:DI (match_dup 3) (const_int 1)))
-   (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
-			   (label_ref (match_operand:DI 1 "" ""))
-			   (pc)))
-   (set (match_dup 5) (compare:CCUNS (match_dup 3) (const_int 2)))
-   (set (pc) (if_then_else (ltu (match_dup 5) (const_int 0))
-			   (label_ref (match_dup 1))
+  [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
+				   (const_int 53)))
+   (parallel [(set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
+						      (const_int 2047)))
+	      (clobber (scratch:CC))])
+   (set (match_dup 3) (plus:DI (match_dup 3)
+			       (const_int 1)))
+   (set (match_dup 0) (plus:DI (match_dup 0)
+			       (const_int 2047)))
+   (set (match_dup 4) (compare:CCUNS (match_dup 3)
+				     (const_int 3)))
+   (set (match_dup 0) (ior:DI (match_dup 0)
+			      (match_dup 1)))
+   (parallel [(set (match_dup 0) (and:DI (match_dup 0)
+					 (const_int -2048)))
+	      (clobber (scratch:CC))])
+   (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
+			   (label_ref (match_operand:DI 2 "" ""))
 			   (pc)))
-   (set (match_dup 0) (xor:DI (match_dup 0) (match_dup 2)))
-   (set (match_dup 0) (ior:DI (match_dup 0) (const_int 2048)))]
-  "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_FPRS"
+   (set (match_dup 0) (match_dup 1))]
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
   "
 {
-  operands[2] = gen_reg_rtx (DImode);
   operands[3] = gen_reg_rtx (DImode);
-  operands[4] = gen_reg_rtx (CCmode);
-  operands[5] = gen_reg_rtx (CCUNSmode);
+  operands[4] = gen_reg_rtx (CCUNSmode);
 }")
 \f
 ;; Define the DImode operations that can be done in a small number

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* fix pr 16480 on gcc-3.4
@ 2004-11-10  2:36 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2004-11-10  2:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

This is a backport of my PR 16480 fix, along with one of Geoff's
obviously correct fixes, for gcc-3.4.  Regression tested powerpc-linux.
OK to apply?

	PR target/16480
	2004-08-26  Alan Modra  <amodra@bigpond.net.au>
	* config/rs6000/rs6000.c (rs6000_split_multireg_move): Don't abort
	on "(mem (symbol_ref ..))" rtl.  Look at LO_SUM base regs as well
	as PLUS base regs.
	2004-08-01  Geoffrey Keating  <geoffk@apple.com>
	* config/rs6000/rs6000.c (rs6000_split_multireg_move): Just abort
	if trying to *store* to a non-offsettable address.
	2004-07-30  Geoffrey Keating  <geoffk@apple.com>
	* config/rs6000/rs6000.c (rs6000_split_multireg_move): Cope with
	non-offsettable addresses being moved into multiple GPRs.

diff -urp -xCVS -x'*~' -x'.#*' gcc-3.4-virgin/gcc/config/rs6000/rs6000.c gcc-3.4-pr16480/gcc/config/rs6000/rs6000.c
--- gcc-3.4-virgin/gcc/config/rs6000/rs6000.c	2004-10-23 19:26:49.000000000 +0930
+++ gcc-3.4-pr16480/gcc/config/rs6000/rs6000.c	2004-11-10 11:43:22.302029284 +1030
@@ -10526,22 +10526,27 @@ rs6000_split_multireg_move (rtx dst, rtx
 			 : gen_adddi3 (breg, breg, delta_rtx));
 	      src = gen_rtx_MEM (mode, breg);
 	    }
+	  else if (! offsettable_memref_p (src))
+	    {
+	      rtx newsrc, basereg;
+	      basereg = gen_rtx_REG (Pmode, reg);
+	      emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
+	      newsrc = gen_rtx_MEM (GET_MODE (src), basereg);
+	      MEM_COPY_ATTRIBUTES (newsrc, src);
+	      src = newsrc;
+	    }
 
-	  /* We have now address involving an base register only.
-	     If we use one of the registers to address memory, 
-	     we have change that register last.  */
-
-	  breg = (GET_CODE (XEXP (src, 0)) == PLUS
-		  ? XEXP (XEXP (src, 0), 0)
-		  : XEXP (src, 0));
-
-	  if (!REG_P (breg))
-	      abort();
-
-	  if (REGNO (breg) >= REGNO (dst) 
+	  breg = XEXP (src, 0);
+	  if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
+	    breg = XEXP (breg, 0);
+
+	  /* If the base register we are using to address memory is
+	     also a destination reg, then change that register last.  */
+	  if (REG_P (breg)
+	      && REGNO (breg) >= REGNO (dst)
 	      && REGNO (breg) < REGNO (dst) + nregs)
 	    j = REGNO (breg) - REGNO (dst);
-        }
+	}
 
       if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
 	{
@@ -10573,6 +10578,8 @@ rs6000_split_multireg_move (rtx dst, rtx
 			   : gen_adddi3 (breg, breg, delta_rtx));
 	      dst = gen_rtx_MEM (mode, breg);
 	    }
+	  else if (! offsettable_memref_p (dst))
+	    abort ();
 	}
 
       for (i = 0; i < nregs; i++)

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [RFC] PowerPC sCC patterns
@ 2004-11-08 23:07 David Edelsohn
  2004-11-24 11:40 ` Alan Modra
  0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2004-11-08 23:07 UTC (permalink / raw)
  To: gcc-patches

	This patch creates splitters for sCC patterns whose final step
does not use the carry bit, namely GTU and LTU.  This gives the scheduler
a little more information and a little more freedom.

	While testing, I discovered that combine did not choose the best
patterns because rtx_costs did not model those instruction, so this patch
improves the cost model as well.

	If anyone notices any mistakes, let me know.

David


	* config/rs6000/rs6000.c (rs6000_rtx_costs): Add EQ, GTU, and LTU.
	* config/rs6000/rs6000.md (sCC): Split GTU and LTU patterns.

Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.737
diff -c -p -r1.737 rs6000.c
*** rs6000.c	8 Nov 2004 04:42:35 -0000	1.737
--- rs6000.c	8 Nov 2004 22:54:52 -0000
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 17984,17992 ****
  	  *total = rs6000_cost->fp;
  	  return false;
  	}
- 
        break;
  
      default:
        break;
      }
--- 17984,18015 ----
  	  *total = rs6000_cost->fp;
  	  return false;
  	}
        break;
  
+     case EQ:
+     case GTU:
+     case LTU:
+       if (mode == Pmode)
+ 	{
+ 	  switch (outer_code)
+ 	    {
+ 	    case PLUS:
+ 	    case NEG:
+ 	      /* PLUS or NEG already counted so only add one more.  */
+ 	      *total = COSTS_N_INSNS (1);
+ 	      break;
+ 	    case SET:
+ 	      *total = COSTS_N_INSNS (3);
+ 	      break;
+ 	    case COMPARE:
+ 	      *total = 0;
+ 	      return true;
+ 	    default:
+ 	      break;
+ 	    }
+ 	  return false;
+ 	}
+ 
      default:
        break;
      }
Index: rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.329
diff -c -p -r1.329 rs6000.md
*** rs6000.md	8 Nov 2004 04:42:36 -0000	1.329
--- rs6000.md	8 Nov 2004 22:54:53 -0000
***************
*** 12460,12474 ****
    "doz%I2 %0,%1,%2\;nabs %0,%0\;{srai|srawi} %0,%0,31"
    [(set_attr "length" "12")])
  
! (define_insn ""
    [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
  	(ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
  		(match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
    "TARGET_32BIT"
!   "@
!    {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0
!    {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
!   [(set_attr "length" "12")])
  
  (define_insn ""
    [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
--- 12460,12486 ----
    "doz%I2 %0,%1,%2\;nabs %0,%0\;{srai|srawi} %0,%0,31"
    [(set_attr "length" "12")])
  
! (define_insn_and_split ""
    [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
  	(ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
  		(match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
    "TARGET_32BIT"
!   "#"
!   "TARGET_32BIT"
!   [(set (match_dup 0) (neg:SI (ltu:SI (match_dup 1) (match_dup 2))))
!    (set (match_dup 0) (neg:SI (match_dup 0)))]
!   "")
! 
! (define_insn_and_split ""
!   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
! 	(ltu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
! 		(match_operand:DI 2 "reg_or_neg_short_operand" "r,P")))]
!   "TARGET_64BIT"
!   "#"
!   "TARGET_64BIT"
!   [(set (match_dup 0) (neg:DI (ltu:DI (match_dup 1) (match_dup 2))))
!    (set (match_dup 0) (neg:DI (match_dup 0)))]
!   "")
  
  (define_insn ""
    [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
***************
*** 12503,12520 ****
  		    (const_int 0)))]
    "")
  
! (define_insn ""
!   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
! 	(plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
! 			 (match_operand:SI 2 "reg_or_neg_short_operand" "r,r,P,P"))
! 		 (match_operand:SI 3 "reg_or_short_operand" "r,I,r,I")))]
    "TARGET_32BIT"
!   "@
!   {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;{sf|subf} %0,%0,%3
!   {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;{sfi|subfic} %0,%0,%3
!   {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;{sf|subf} %0,%0,%3
!   {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;{sfi|subfic} %0,%0,%3"
!  [(set_attr "length" "12")])
  
  (define_insn ""
    [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
--- 12515,12543 ----
  		    (const_int 0)))]
    "")
  
! (define_insn_and_split ""
!   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
! 	(plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
! 			 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
! 		 (match_operand:SI 3 "reg_or_short_operand" "rI,rI")))]
    "TARGET_32BIT"
!   "#"
!   "TARGET_32BIT"
!   [(set (match_dup 0) (neg:SI (ltu:SI (match_dup 1) (match_dup 2))))
!    (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 0)))]
!   "")
! 
! (define_insn_and_split ""
!   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
! 	(plus:DI (ltu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
! 			 (match_operand:DI 2 "reg_or_neg_short_operand" "r,P"))
! 		 (match_operand:DI 3 "reg_or_short_operand" "rI,rI")))]
!   "TARGET_64BIT"
!   "#"
!   "TARGET_64BIT"
!   [(set (match_dup 0) (neg:DI (ltu:DI (match_dup 1) (match_dup 2))))
!    (set (match_dup 0) (minus:DI (match_dup 3) (match_dup 0)))]
!   "")
  
  (define_insn ""
    [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
***************
*** 12596,12601 ****
--- 12619,12634 ----
    [(set_attr "length" "8")])
  
  (define_insn ""
+   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+ 	(neg:DI (ltu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+ 			(match_operand:DI 2 "reg_or_neg_short_operand" "r,P"))))]
+   "TARGET_64BIT"
+   "@
+    {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0
+    {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0"
+   [(set_attr "length" "8")])
+ 
+ (define_insn ""
    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
  	(ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
  	       (match_operand:SI 2 "reg_or_short_operand" "rI")))
***************
*** 13343,13363 ****
    "doz %0,%2,%1\;nabs %0,%0\;{srai|srawi} %0,%0,31"
    [(set_attr "length" "12")])
  
! (define_insn ""
    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
! 	(gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
! 		(match_operand:SI 2 "reg_or_short_operand" "rI")))]
    "TARGET_32BIT"
!   "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
!   [(set_attr "length" "12")])
  
! (define_insn ""
    [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
! 	(gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
! 		(match_operand:DI 2 "reg_or_short_operand" "rI")))]
    "TARGET_64BIT"
!   "subf%I2c %0,%1,%2\;subfe %0,%0,%0\;neg %0,%0"
!   [(set_attr "length" "12")])
  
  (define_insn ""
    [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
--- 13376,13402 ----
    "doz %0,%2,%1\;nabs %0,%0\;{srai|srawi} %0,%0,31"
    [(set_attr "length" "12")])
  
! (define_insn_and_split ""
    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
!         (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
!                 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
    "TARGET_32BIT"
!   "#"
!   "TARGET_32BIT"
!   [(set (match_dup 0) (neg:SI (gtu:SI (match_dup 1) (match_dup 2))))
!    (set (match_dup 0) (neg:SI (match_dup 0)))]
!   "")
  
! (define_insn_and_split ""
    [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
!         (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
!                 (match_operand:DI 2 "reg_or_short_operand" "rI")))]
    "TARGET_64BIT"
!   "#"
!   "TARGET_64BIT"
!   [(set (match_dup 0) (neg:DI (gtu:DI (match_dup 1) (match_dup 2))))
!    (set (match_dup 0) (neg:DI (match_dup 0)))]
!   "")
  
  (define_insn ""
    [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
***************
*** 13421,13449 ****
  		    (const_int 0)))]
    "")
  
! (define_insn ""
!   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r")
! 	(plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
! 			 (match_operand:SI 2 "reg_or_short_operand" "I,rI,rI"))
! 		 (match_operand:SI 3 "reg_or_short_operand" "r,r,I")))]
    "TARGET_32BIT"
!   "@
!    {ai|addic} %0,%1,%k2\;{aze|addze} %0,%3
!    {sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;{sf|subf} %0,%0,%3
!    {sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;{sfi|subfic} %0,%0,%3"
!   [(set_attr "length" "8,12,12")])
  
! (define_insn ""
!   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,&r")
! 	(plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r")
! 			 (match_operand:DI 2 "reg_or_short_operand" "I,rI,rI"))
! 		 (match_operand:DI 3 "reg_or_short_operand" "r,r,I")))]
    "TARGET_64BIT"
!   "@
!    addic %0,%1,%k2\;addze %0,%3
!    subf%I2c %0,%1,%2\;subfe %0,%0,%0\;subf %0,%0,%3
!    subf%I2c %0,%1,%2\;subfe %0,%0,%0\;subfic %0,%0,%3"
!   [(set_attr "length" "8,12,12")])
  
  (define_insn ""
    [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
--- 13460,13488 ----
  		    (const_int 0)))]
    "")
  
! (define_insn_and_split ""
!   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
!         (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
!                          (match_operand:SI 2 "reg_or_short_operand" "rI"))
!                  (match_operand:SI 3 "reg_or_short_operand" "rI")))]
    "TARGET_32BIT"
!   "#"
!   "TARGET_32BIT"
!   [(set (match_dup 0) (neg:SI (gtu:SI (match_dup 1) (match_dup 2))))
!    (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 0)))]
!   "")
  
! (define_insn_and_split ""
!   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
!         (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
!                          (match_operand:DI 2 "reg_or_short_operand" "rI"))
!                  (match_operand:DI 3 "reg_or_short_operand" "rI")))]
    "TARGET_64BIT"
!   "#"
!   "TARGET_64BIT"
!   [(set (match_dup 0) (neg:DI (gtu:DI (match_dup 1) (match_dup 2))))
!    (set (match_dup 0) (minus:DI (match_dup 3) (match_dup 0)))]
!   "")
  
  (define_insn ""
    [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")

^ permalink raw reply	[flat|nested] 875+ messages in thread
* Release RTL bodies after compilation (sometimes)
@ 2004-09-02 18:53 Jan Hubicka
  2004-09-02 18:56 ` Jakub Jelinek
                   ` (2 more replies)
  0 siblings, 3 replies; 875+ messages in thread
From: Jan Hubicka @ 2004-09-02 18:53 UTC (permalink / raw)
  To: gcc-patches, rth



Hi,

This patch save about 3MB of garbage on -O0 combine.c compilation by
explicitely freeing some and annotations CFG edges.  Additionally it
makes RTL function bodies to be released again in majority of cases
after compilation.  This reduce peak memory usage from 9MB to 5MB on
Gerald testcase I get from 21 garbage collection runs to 18.  This can
still be significantly improved by followup patches I broke out as they
are slightly more controversal.

On gcc modules compilation test I didn't measured any actual performance
differences but for Gerald's testcase it is about 6%.

Bootstraped/regtested on i686-pc-gnu-linux, OK?

Honza
2004-09-01  Jan Hubicka  <jh@suse.cz>
	* cfg.c (fre_edge): Use ggc_free.
	(expunge_block): Use ggc_free.
	* cfglayout.c (cfg_layout_initialize): Free RBI info.
	* tree-ssa-dce.c (remove_dead_stmt): Free STMT annotation.
	* tree-ssa.c (delete_tree_ssa): Free annotations.
Index: gcc/cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfg.c,v
retrieving revision 1.63
diff -c -3 -p -r1.63 cfg.c
*** gcc/cfg.c	25 Aug 2004 07:25:06 -0000	1.63
--- gcc/cfg.c	2 Sep 2004 18:25:04 -0000
*************** static void
*** 134,140 ****
  free_edge (edge e ATTRIBUTE_UNUSED)
  {
    n_edges--;
!   /* ggc_free (e);  */
  }
  
  /* Free the memory associated with the edge structures.  */
--- 134,140 ----
  free_edge (edge e ATTRIBUTE_UNUSED)
  {
    n_edges--;
!   ggc_free (e);
  }
  
  /* Free the memory associated with the edge structures.  */
*************** expunge_block (basic_block b)
*** 269,275 ****
    unlink_block (b);
    BASIC_BLOCK (b->index) = NULL;
    n_basic_blocks--;
!   /* ggc_free (b); */
  }
  \f
  /* Create an edge connecting SRC and DEST with flags FLAGS.  Return newly
--- 269,275 ----
    unlink_block (b);
    BASIC_BLOCK (b->index) = NULL;
    n_basic_blocks--;
!   ggc_free (b);
  }
  \f
  /* Create an edge connecting SRC and DEST with flags FLAGS.  Return newly
Index: gcc/passes.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/passes.c,v
retrieving revision 2.41
diff -c -3 -p -r2.41 passes.c
*** gcc/passes.c	1 Sep 2004 20:58:52 -0000	2.41
--- gcc/passes.c	2 Sep 2004 18:25:04 -0000
*************** rest_of_clean_state (void)
*** 1685,1690 ****
--- 1685,1691 ----
  
    /* We're done with this function.  Free up memory if we can.  */
    free_after_parsing (cfun);
+   free_after_compilation (cfun);
  }
  \f
  
Index: gcc/tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa.c,v
retrieving revision 2.30
diff -c -3 -p -r2.30 tree-ssa.c
*** gcc/tree-ssa.c	1 Sep 2004 22:06:20 -0000	2.30
--- gcc/tree-ssa.c	2 Sep 2004 18:25:05 -0000
*************** delete_tree_ssa (void)
*** 641,653 ****
    /* Remove annotations from every tree in the function.  */
    FOR_EACH_BB (bb)
      for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
!       bsi_stmt (bsi)->common.ann = NULL;
  
    /* Remove annotations from every referenced variable.  */
    if (referenced_vars)
      {
        for (i = 0; i < num_referenced_vars; i++)
! 	referenced_var (i)->common.ann = NULL;
        referenced_vars = NULL;
      }
  
--- 641,662 ----
    /* Remove annotations from every tree in the function.  */
    FOR_EACH_BB (bb)
      for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
!       {
! 	tree stmt = bsi_stmt (bsi);
!         release_defs (stmt);
! 	ggc_free (stmt->common.ann);
! 	stmt->common.ann = NULL;
!       }
  
    /* Remove annotations from every referenced variable.  */
    if (referenced_vars)
      {
        for (i = 0; i < num_referenced_vars; i++)
! 	{
! 	  tree var = referenced_var (i);
! 	  ggc_free (var->common.ann);
! 	  var->common.ann = NULL;
! 	}
        referenced_vars = NULL;
      }
  
Index: gcc/tree-ssanames.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssanames.c,v
retrieving revision 2.8
diff -c -3 -p -r2.8 tree-ssanames.c
*** gcc/tree-ssanames.c	25 Aug 2004 21:21:19 -0000	2.8
--- gcc/tree-ssanames.c	2 Sep 2004 18:25:05 -0000
*************** release_defs (tree stmt)
*** 300,306 ****
    ssa_op_iter iter;
  
    FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
!     release_ssa_name (def);
  }
  
  
--- 300,307 ----
    ssa_op_iter iter;
  
    FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
!     if (TREE_CODE (def) == SSA_NAME)
!       release_ssa_name (def);
  }
  
  

^ permalink raw reply	[flat|nested] 875+ messages in thread
* RS6000 fix pr16480
@ 2004-08-25 14:28 Alan Modra
  2004-08-25 15:45 ` David Edelsohn
  0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2004-08-25 14:28 UTC (permalink / raw)
  To: gcc-patches

This fixes an abort on a memory address that rs6000_split_multireg_move
wasn't expecting, a (mem/i:DI (symbol_ref ..)), which is allowed by
legitimate_small_data_p.  In looking over other addresses allowed by
rs6000_legitimate_address, I think we also need to look inside a LO_SUM
for a clash with the destination reg.

	PR target/16480
	* config/rs6000/rs6000.c (rs6000_split_multireg_move): Don't abort
	on "(mem (symbol_ref ..))" rtl.  Look at LO_SUM base regs as well
	as PLUS base regs.

Bootstrap and regression test on powerpc-linux in progress.  To fix this
properly on gcc-3.4, I think we also should back-port the
offsettable_memref_p change to rs6000_split_multireg_move.

diff -urp -xCVS -x'*~' gcc-virgin/gcc/config/rs6000/rs6000.c gcc-current/gcc/config/rs6000/rs6000.c
--- gcc-virgin/gcc/config/rs6000/rs6000.c	2004-08-25 13:08:14.909251153 +0930
+++ gcc-current/gcc/config/rs6000/rs6000.c	2004-08-25 21:13:33.405845840 +0930
@@ -11352,18 +11353,14 @@ rs6000_split_multireg_move (rtx dst, rtx
 	      src = newsrc;
 	    }
 
-	  /* We have now address involving an base register only.
-	     If we use one of the registers to address memory,
-	     we have change that register last.  */
-
-	  breg = (GET_CODE (XEXP (src, 0)) == PLUS
-		  ? XEXP (XEXP (src, 0), 0)
-		  : XEXP (src, 0));
-
-	  if (!REG_P (breg))
-	      abort();
-
-	  if (REGNO (breg) >= REGNO (dst)
+	  breg = XEXP (src, 0);
+	  if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
+	    breg = XEXP (breg, 0);
+
+	  /* If the base register we are using to address memory is
+	     also a destination reg, then change that register last.  */
+	  if (REG_P (breg)
+	      && REGNO (breg) >= REGNO (dst)
 	      && REGNO (breg) < REGNO (dst) + nregs)
 	    j = REGNO (breg) - REGNO (dst);
         }

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* powerpc64 fixes missing from 3.4 branch
@ 2004-08-11 11:13 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2004-08-11 11:13 UTC (permalink / raw)
  To: David Edelsohn; +Cc: gcc-patches

Hi David,
  http://gcc.gnu.org/ml/gcc-patches/2004-06/msg02298.html hasn't been
applied to the gcc-3.4 branch, probably because it was okayed too close
to the 3.4.1 release.  OK to apply?  Bootstrapped etc. powerpc64-linux.
See http://gcc.gnu.org/ml/gcc-patches/2004-05/msg00665.html for blurb on
what it does.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* powerpc64 linux dot symbols
@ 2004-08-10 11:55 Alan Modra
  2004-08-10 12:37 ` Joseph S. Myers
                   ` (2 more replies)
  0 siblings, 3 replies; 875+ messages in thread
From: Alan Modra @ 2004-08-10 11:55 UTC (permalink / raw)
  To: gcc-patches; +Cc: dje, mendell, sjmunroe, gilliam, yaari, klausner

This is the gcc part of my patch to binutils+gcc to remove use of "dot"
symbols on PowerPC64 Linux function entry points.  The main reason for
making this change is to remove a user visible PowerPC64 ELF wart:
Functions called names like "data" and "dynamic" won't compile, since
the associated dot symbols, ".data" and ".dynamic" clash with ELF
section names.  A secondary reason is that reducing the number of global
symbols speeds application load time, because ld.so's symbol table is
somewhat smaller.


So, what's different?

Old

function call:		bl .foo
descriptor sym:		foo, type=object, size=24
entry sym:		.foo, type=function, size=<function code size>
descriptor:		.quad .foo, .TOC.@tocbase, 0

New

function call:		bl foo
descriptor sym:		foo, type=function, size=<function code size>
entry sym:		.LEfoo local sym (won't appear in object)
descriptor:		.quad .LEfoo, .TOC.@tocbase, 0

Note that old descriptor syms have been given type "function" by the
linker in executables and dynamic libraries for quite some time.
(see http://sources.redhat.com/ml/binutils/2004-03/msg00550.html)
So for tools like FDPR that process binaries, the net change in
executables is that dot symbols are missing, and function size is
attached to a different symbol.

Of course, this change has implications in other parts of the
toolchain.  For instance, I need to make some changes to objdump,
as .text tends to be one large block of code without any symbols.
gdb likely needs some work too, as it will need to look up function
descriptors to find code addresses.  glibc is probably OK, although I
haven't yet compiled it with the new compiler.  One very fortunate
property of old dynamic libraries is that they don't make references
to external dot symbols, so there shouldn't be any change needed in
ld.so.


Testing of the following patch against mainline hasn't completed yet,
but a virtually identical patch against 3.4 has survived bootstrap and
regression testing on powerpc64-linux, with both old and new linkers.

	* config/rs6000/linux64.h (DOT_SYMBOLS): Define.
	(CRT_CALL_STATIC_FUNCTION): Define !DOT_SYMBOLS version.
	(ASM_DECLARE_FUNCTION_SIZE): Modify for !DOT_SYMBOLS.
	(ASM_OUTPUT_SOURCE_LINE, DBX_OUTPUT_BRAC, DBX_OUTPUT_NFUN): Likewise.
	* config/rs6000/rs6000-protos.h (rs6000_output_function_entry): Decl.
	* config/rs6000/rs6000.c (rs6000_output_function_entry): New function,
	modified for !DOT_SYMBOLS..
	(print_operand <case 'z'>): ..extracted from here.
	(rs6000_assemble_visibility): Modify for !DOT_SYMBOLS.
	(rs6000_output_function_epilogue): Likewise.
	(rs6000_elf_declare_function_name): Likewise.
	* config/rs6000/rs6000.h (DOT_SYMBOLS): Define.
	(ASM_WEAKEN_DECL, ASM_OUTPUT_DEF_FROM_DECLS): Modify for !DOT_SYMBOLS.
	* configure.ac (HAVE_LD_NO_DOT_SYMS): Add new AC_DEFINE.
	* configure: Regenerate.
	* config.in: Regenerate.

Index: gcc/configure.ac
===================================================================
RCS file: /cvs/gcc/gcc/gcc/configure.ac,v
retrieving revision 2.50
diff -u -p -r2.50 configure.ac
--- gcc/configure.ac	23 Jul 2004 06:59:34 -0000	2.50
+++ gcc/configure.ac	9 Aug 2004 23:52:02 -0000
@@ -2857,6 +2857,47 @@ if test x"$gcc_cv_ld_as_needed" = xyes; 
 [Define if your linker supports --as-needed and --no-as-needed options.])
 fi
 
+case "$target" in
+  powerpc64*-*-linux*)
+    AC_CACHE_CHECK(linker support for omitting dot symbols,
+    gcc_cv_ld_no_dot_syms,
+    [gcc_cv_ld_no_dot_syms=no
+    if test $in_tree_ld = yes ; then
+      if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2; then
+        gcc_cv_ld_no_dot_syms=yes
+      fi
+    elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x ; then
+      cat > conftest1.s <<EOF
+	.text
+	bl foo
+EOF
+      cat > conftest2.s <<EOF
+	.section ".opd","aw"
+	.align 3
+	.globl foo
+	.type foo,@function
+foo:
+	.quad .LEfoo,.TOC.@tocbase,0
+	.text
+.LEfoo:
+	blr
+	.size foo,.-.LEfoo
+EOF
+      if $gcc_cv_as -o conftest1.o conftest1.s > /dev/null 2>&1 \
+         && $gcc_cv_as -o conftest2.o conftest2.s > /dev/null 2>&1 \
+         && $gcc_cv_ld -o conftest conftest1.o conftest2.o > /dev/null 2>&1; then
+        gcc_cv_ld_no_dot_syms=yes
+      fi
+      rm -f conftest conftest1.o conftest2.o conftest1.s conftest2.s
+    fi
+    ])
+    if test x"$gcc_cv_ld_no_dot_syms" = xyes; then
+      AC_DEFINE(HAVE_LD_NO_DOT_SYMS, 1,
+    [Define if your PowerPC64 linker only needs function descriptor syms.])
+    fi
+    ;;
+esac
+
 if test x$with_sysroot = x && test x$host = x$target \
    && test "$prefix" != "/usr" && test "x$prefix" != "x$local_prefix" ; then
   AC_DEFINE_UNQUOTED(PREFIX_INCLUDE_DIR, "$prefix/include",
Index: gcc/config/rs6000/linux64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/linux64.h,v
retrieving revision 1.62
diff -u -p -r1.62 linux64.h
--- gcc/config/rs6000/linux64.h	13 Jul 2004 07:45:04 -0000	1.62
+++ gcc/config/rs6000/linux64.h	9 Aug 2004 23:52:06 -0000
@@ -50,6 +50,12 @@
 #undef	TARGET_AIX
 #define	TARGET_AIX TARGET_64BIT
 
+#ifdef HAVE_LD_NO_DOT_SYMS
+/* New ABI uses a local sym for the function entry point.  */
+#undef DOT_SYMBOLS
+#define DOT_SYMBOLS 0
+#endif
+
 #undef PROCESSOR_DEFAULT64
 #define PROCESSOR_DEFAULT64 PROCESSOR_PPC630
 
@@ -386,11 +398,19 @@
    object files, each potentially with a different TOC pointer.  For
    that reason, place a nop after the call so that the linker can
    restore the TOC pointer if a TOC adjusting call stub is needed.  */
+#if DOT_SYMBOLS
 #define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC)	\
   asm (SECTION_OP "\n"					\
 "	bl ." #FUNC "\n"				\
 "	nop\n"						\
 "	.previous");
+#else
+#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC)	\
+  asm (SECTION_OP "\n"					\
+"	bl " #FUNC "\n"					\
+"	nop\n"						\
+"	.previous");
+#endif
 #endif
 
 /* FP save and restore routines.  */
@@ -415,13 +435,11 @@
       if (!flag_inhibit_size_directive)					\
 	{								\
 	  fputs ("\t.size\t", (FILE));					\
-	  if (TARGET_64BIT)						\
+	  if (TARGET_64BIT && DOT_SYMBOLS)				\
 	    putc ('.', (FILE));						\
 	  assemble_name ((FILE), (FNAME));				\
 	  fputs (",.-", (FILE));					\
-	  if (TARGET_64BIT)						\
-	    putc ('.', (FILE));						\
-	  assemble_name ((FILE), (FNAME));				\
+	  rs6000_output_function_entry (FILE, FNAME);			\
 	  putc ('\n', (FILE));						\
 	}								\
     }									\
@@ -465,14 +483,13 @@
 do									\
   {									\
     char temp[256];							\
+    const char *s;							\
     ASM_GENERATE_INTERNAL_LABEL (temp, "LM", COUNTER);			\
     fprintf (FILE, "\t.stabn 68,0,%d,", LINE);				\
     assemble_name (FILE, temp);						\
     putc ('-', FILE);							\
-    if (TARGET_64BIT)							\
-      putc ('.', FILE);							\
-    assemble_name (FILE,						\
-		   XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
+    s = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);		\
+    rs6000_output_function_entry (FILE, s);				\
     putc ('\n', FILE);							\
     (*targetm.asm_out.internal_label) (FILE, "LM", COUNTER);		\
   }									\
@@ -482,19 +499,20 @@ while (0)
 #define DBX_OUTPUT_BRAC(FILE, NAME, BRAC) \
   do									\
     {									\
-      const char *flab;							\
+      const char *s;							\
       fprintf (FILE, "%s%d,0,0,", ASM_STABN_OP, BRAC);			\
       assemble_name (FILE, NAME);					\
       putc ('-', FILE);							\
       if (current_function_func_begin_label != NULL_TREE)		\
-	flab = IDENTIFIER_POINTER (current_function_func_begin_label);	\
+	{								\
+	  s = IDENTIFIER_POINTER (current_function_func_begin_label);	\
+	  assemble_name (FILE, s);					\
+	}								\
       else								\
 	{								\
-	  if (TARGET_64BIT)						\
-	    putc ('.', FILE);						\
-	  flab = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);	\
+	  s = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);	\
+	  rs6000_output_function_entry (FILE, s);			\
 	}								\
-      assemble_name (FILE, flab);					\
       putc ('\n', FILE);						\
     }									\
   while (0)
@@ -506,12 +524,12 @@ while (0)
 #define	DBX_OUTPUT_NFUN(FILE, LSCOPE, DECL)				\
   do									\
     {									\
+      const char *s;							\
       fprintf (FILE, "%s\"\",%d,0,0,", ASM_STABS_OP, N_FUN);		\
       assemble_name (FILE, LSCOPE);					\
       putc ('-', FILE);							\
-      if (TARGET_64BIT)							\
-        putc ('.', FILE);						\
-      assemble_name (FILE, XSTR (XEXP (DECL_RTL (DECL), 0), 0));	\
+      s = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);		\
+      rs6000_output_function_entry (FILE, s);				\
       putc ('\n', FILE);						\
     }									\
   while (0)
Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000-protos.h,v
retrieving revision 1.85
diff -u -p -r1.85 rs6000-protos.h
--- gcc/config/rs6000/rs6000-protos.h	28 Jul 2004 12:13:13 -0000	1.85
+++ gcc/config/rs6000/rs6000-protos.h	9 Aug 2004 23:52:06 -0000
@@ -110,6 +110,7 @@ extern enum reg_class secondary_reload_c
 extern int ccr_bit (rtx, int);
 extern int extract_MB (rtx);
 extern int extract_ME (rtx);
+extern void rs6000_output_function_entry (FILE *, const char *);
 extern void print_operand (FILE *, rtx, int);
 extern void print_operand_address (FILE *, rtx);
 extern enum rtx_code rs6000_reverse_condition (enum machine_mode,
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.675
diff -u -p -r1.675 rs6000.c
--- gcc/config/rs6000/rs6000.c	2 Aug 2004 01:46:39 -0000	1.675
+++ gcc/config/rs6000/rs6000.c	9 Aug 2004 23:52:15 -0000
@@ -9543,6 +9539,36 @@ rs6000_get_some_local_dynamic_name_1 (rt
   return 0;
 }
 
+/* Write out a function code label.  */
+
+void
+rs6000_output_function_entry (FILE *file, const char *fname)
+{
+  if (fname[0] != '.')
+    {
+      switch (DEFAULT_ABI)
+	{
+	default:
+	  abort ();
+
+	case ABI_AIX:
+	  if (DOT_SYMBOLS)
+	    putc ('.', file);
+	  else
+	    ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LE");
+	  break;
+
+	case ABI_V4:
+	case ABI_DARWIN:
+	  break;
+	}
+    }
+  if (TARGET_AIX)
+    RS6000_OUTPUT_BASENAME (file, fname);
+  else
+    assemble_name (file, fname);
+}
+
 /* Print an operand.  Recognize special options, documented below.  */
 
 #if TARGET_ELF
@@ -10075,23 +10101,7 @@ print_operand (FILE *file, rtx x, int co
       if (SYMBOL_REF_DECL (x))
         mark_decl_referenced (SYMBOL_REF_DECL (x));
 
-      if (XSTR (x, 0)[0] != '.')
-	{
-	  switch (DEFAULT_ABI)
-	    {
-	    default:
-	      abort ();
-
-	    case ABI_AIX:
-	      putc ('.', file);
-	      break;
-
-	    case ABI_V4:
-	    case ABI_DARWIN:
-	      break;
-	    }
-	}
-      /* For macho, we need to check it see if we need a stub.  */
+      /* For macho, check to see if we need a stub.  */
       if (TARGET_MACHO)
 	{
 	  const char *name = XSTR (x, 0);
@@ -10102,10 +10112,10 @@ print_operand (FILE *file, rtx x, int co
 #endif
 	  assemble_name (file, name);
 	}
-     else if (TARGET_AIX)
-	RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
-      else
+      else if (!DOT_SYMBOLS)
 	assemble_name (file, XSTR (x, 0));
+      else
+	rs6000_output_function_entry (file, XSTR (x, 0));
       return;
 
     case 'Z':
@@ -10361,7 +10371,9 @@ rs6000_assemble_visibility (tree decl, i
 {
   /* Functions need to have their entry point symbol visibility set as
      well as their descriptor symbol visibility.  */
-  if (DEFAULT_ABI == ABI_AIX && TREE_CODE (decl) == FUNCTION_DECL)
+  if (DEFAULT_ABI == ABI_AIX
+      && DOT_SYMBOLS
+      && TREE_CODE (decl) == FUNCTION_DECL)
     {
       static const char * const visibility_types[] = {
         NULL, "internal", "hidden", "protected"
@@ -13686,17 +13698,12 @@ rs6000_output_function_epilogue (FILE *f
       /* Offset from start of code to tb table.  */
       fputs ("\t.long ", file);
       ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
-#if TARGET_AIX
-      RS6000_OUTPUT_BASENAME (file, fname);
-#else
-      assemble_name (file, fname);
-#endif
-      fputs ("-.", file);
-#if TARGET_AIX
-      RS6000_OUTPUT_BASENAME (file, fname);
-#else
-      assemble_name (file, fname);
-#endif
+      if (TARGET_AIX)
+	RS6000_OUTPUT_BASENAME (file, fname);
+      else
+	assemble_name (file, fname);
+      putc ('-', file);
+      rs6000_output_function_entry (file, fname);
       putc ('\n', file);
 
       /* Interrupt handler mask.  */
@@ -16262,22 +16269,27 @@ rs6000_elf_declare_function_name (FILE *
       fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
       ASM_OUTPUT_LABEL (file, name);
       fputs (DOUBLE_INT_ASM_OP, file);
-      putc ('.', file);
-      assemble_name (file, name);
-      fputs (",.TOC.@tocbase,0\n\t.previous\n\t.size\t", file);
-      assemble_name (file, name);
-      fputs (",24\n\t.type\t.", file);
-      assemble_name (file, name);
-      fputs (",@function\n", file);
-      if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
+      rs6000_output_function_entry (file, name);
+      fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
+      if (DOT_SYMBOLS)
 	{
-	  fputs ("\t.globl\t.", file);
+	  fputs ("\t.size\t", file);
 	  assemble_name (file, name);
-	  putc ('\n', file);
+	  fputs (",24\n\t.type\t.", file);
+	  assemble_name (file, name);
+	  fputs (",@function\n", file);
+	  if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
+	    {
+	      fputs ("\t.globl\t.", file);
+	      assemble_name (file, name);
+	      putc ('\n', file);
+	    }
 	}
+      else
+	ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
       ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
-      putc ('.', file);
-      ASM_OUTPUT_LABEL (file, name);
+      rs6000_output_function_entry (file, name);
+      fputs (":\n", file);
       return;
     }
 
Index: gcc/config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.329
diff -u -p -r1.329 rs6000.h
--- gcc/config/rs6000/rs6000.h	16 Jul 2004 23:25:47 -0000	1.329
+++ gcc/config/rs6000/rs6000.h	9 Aug 2004 23:52:17 -0000
@@ -40,6 +40,10 @@
 #define TARGET_AIX 0
 #endif
 
+/* Control whether function entry points use a "dot" symbol when
+   ABI_AIX.  */
+#define DOT_SYMBOLS 1
+
 /* Default string to use for cpu if not specified.  */
 #ifndef TARGET_CPU_DEFAULT
 #define TARGET_CPU_DEFAULT ((char *)0)
@@ -2233,9 +2237,9 @@ extern int toc_initialized;
   do									\
     {									\
       fputs ("\t.weak\t", (FILE));					\
-      RS6000_OUTPUT_BASENAME ((FILE), (NAME)); 			\
+      RS6000_OUTPUT_BASENAME ((FILE), (NAME)); 				\
       if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL			\
-	  && DEFAULT_ABI == ABI_AIX)					\
+	  && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS)			\
 	{								\
 	  if (TARGET_XCOFF)						\
 	    fputs ("[DS]", (FILE));					\
@@ -2247,7 +2251,7 @@ extern int toc_initialized;
 	{								\
 	  ASM_OUTPUT_DEF ((FILE), (NAME), (VAL));			\
 	  if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL		\
-	      && DEFAULT_ABI == ABI_AIX)				\
+	      && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS)			\
 	    {								\
 	      fputs ("\t.set\t.", (FILE));				\
 	      RS6000_OUTPUT_BASENAME ((FILE), (NAME));			\
@@ -2268,7 +2272,7 @@ extern int toc_initialized;
       const char *alias = XSTR (XEXP (DECL_RTL (DECL), 0), 0);		\
       const char *name = IDENTIFIER_POINTER (TARGET);			\
       if (TREE_CODE (DECL) == FUNCTION_DECL				\
-	  && DEFAULT_ABI == ABI_AIX)					\
+	  && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS)			\
 	{								\
 	  if (TREE_PUBLIC (DECL))					\
 	    {								\

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PATCH, committed] SFmode arg padding and va_arg cleanup
@ 2004-07-14 21:21 David Edelsohn
  2004-07-26 20:30 ` Alan Modra
  0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2004-07-14 21:21 UTC (permalink / raw)
  To: gcc-patches

	SFmode should not be padded when passed in stack in 64-bit mode.

	Update rs6000_gimplify_va_arg to use size_int().

David


	* config/rs6000/rs6000.c (function_arg_padding): Do not pad SFmode
	for TARGET_64BIT.
	(rs6000_gimplify_va_arg): Use size_int instead of build_int_2.

Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.665
diff -c -p -u -r1.665 rs6000.c
--- rs6000.c	13 Jul 2004 07:45:04 -0000	1.665
+++ rs6000.c	14 Jul 2004 13:59:47 -0000
@@ -4593,6 +4593,10 @@ function_arg_padding (enum machine_mode 
 	return upward;
     }
 
+  /* SFmode parameters are not padded.  */
+  if (TARGET_64BIT && mode == SFmode)
+    return none;
+
   /* Fall back to the default.  */
   return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
 }
@@ -5459,7 +5463,7 @@ rs6000_gimplify_va_arg (tree valist, tre
 	{
 	  /* Args grow upward.  */
 	  t = build2 (POSTINCREMENT_EXPR, TREE_TYPE (valist), valist,
-		      build_int_2 (POINTER_SIZE / BITS_PER_UNIT, 0));
+		      size_int (POINTER_SIZE / BITS_PER_UNIT));
 	  t = build1 (NOP_EXPR, build_pointer_type (ptrtype), t);
 	  t = build_fold_indirect_ref (t);
 	  return build_fold_indirect_ref (t);
@@ -5568,12 +5572,11 @@ rs6000_gimplify_va_arg (tree valist, tre
       if (n_reg == 2)
 	{
 	  u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), reg,
-		     build_int_2 (n_reg - 1, 0));
+		     size_int (n_reg - 1));
 	  u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, u);
 	}
 
-      t = build_int_2 (8 - n_reg + 1, 0);
-      TREE_TYPE (t) = TREE_TYPE (reg);
+      t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
       t = build2 (GE_EXPR, boolean_type_node, u, t);
       u = build1 (GOTO_EXPR, void_type_node, lab_false);
       t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
@@ -5581,12 +5584,11 @@ rs6000_gimplify_va_arg (tree valist, tre
 
       t = sav;
       if (sav_ofs)
-	t = build2 (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
+	t = build2 (PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
 
-      u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
-		 build_int_2 (n_reg, 0));
+      u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, size_int (n_reg));
       u = build1 (CONVERT_EXPR, integer_type_node, u);
-      u = build2 (MULT_EXPR, integer_type_node, u, build_int_2 (sav_scale, 0));
+      u = build2 (MULT_EXPR, integer_type_node, u, size_int (sav_scale));
       t = build2 (PLUS_EXPR, ptr_type_node, t, u);
 
       t = build2 (MODIFY_EXPR, void_type_node, addr, t);
@@ -5602,7 +5604,7 @@ rs6000_gimplify_va_arg (tree valist, tre
 	{
 	  /* Ensure that we don't find any more args in regs.
 	     Alignment has taken care of the n_reg == 2 case.  */
-	  t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
+	  t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, size_int (8));
 	  gimplify_and_add (t, pre_p);
 	}
     }
@@ -5613,7 +5615,7 @@ rs6000_gimplify_va_arg (tree valist, tre
   t = ovf;
   if (align != 1)
     {
-      t = build2 (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (align - 1, 0));
+      t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
       t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align, -1));
     }
   gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
@@ -5621,7 +5623,7 @@ rs6000_gimplify_va_arg (tree valist, tre
   u = build2 (MODIFY_EXPR, void_type_node, addr, t);
   gimplify_and_add (u, pre_p);
 
-  t = build2 (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0));
+  t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
   t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
   gimplify_and_add (t, pre_p);
 

^ permalink raw reply	[flat|nested] 875+ messages in thread
* rs6000 mainline patch for pr 14478
@ 2004-05-26 17:31 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2004-05-26 17:31 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

Insurance that const zero never makes it to these patterns.
http://gcc.gnu.org/ml/gcc-patches/2004-03/msg00696.html
Bootstrapped, etc. powerpc64-linux.  OK mainline?  I'd like to apply
either this patch or the one referenced above to the 3.4 branch too.

	PR target/14478
	* config/rs6000/rs6000.c (reg_or_short_operand): Don't allow zero.

diff -urp -xCVS -x'*~' gcc-virgin/gcc/config/rs6000/rs6000.c gcc-mainline/gcc/config/rs6000/rs6000.c
--- gcc-virgin/gcc/config/rs6000/rs6000.c	2004-05-21 11:00:09.000000000 +0930
+++ gcc-mainline/gcc/config/rs6000/rs6000.c	2004-05-26 10:52:34.000000000 +0930
@@ -1406,13 +1406,16 @@ reg_or_short_operand (rtx op, enum machi
 }
 
 /* Similar, except check if the negation of the constant would be
-   valid for a D-field.  */
+   valid for a D-field.  Don't allow a constant zero, since all the
+   patterns that call this predicate use "addic r1,r2,-constant" on
+   a constant value to set a carry when r2 is greater or equal to
+   "constant".  That doesn't work for zero.  */
 
 int
 reg_or_neg_short_operand (rtx op, enum machine_mode mode)
 {
   if (GET_CODE (op) == CONST_INT)
-    return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P');
+    return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P') && INTVAL (op) != 0;
 
   return gpc_reg_operand (op, mode);
 }

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* Fixes for powerpc-linux param passing
@ 2004-05-08 15:54 Alan Modra
  2004-05-08 15:54 ` Aldy Hernandez
                   ` (2 more replies)
  0 siblings, 3 replies; 875+ messages in thread
From: Alan Modra @ 2004-05-08 15:54 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn, Aldy Hernandez, Hartmut Penner, Janis Johnson

This patch cures a number of powerpc-linux parameter passing problems.

1) rs6000_va_arg disagreed with function_arg on where floating point
   types live, apart from SFmode, DFmode and TFmode.  function_arg
   passes other floating point types, including all complex floats, in
   gprs, whereas rs6000_va_arg expected them in fp regs.

2) rs6000_va_arg disagreed with function_arg on arg alignment.
   function_arg/function_arg_advance aligned to an even word for DFmode
   and when exactly 2 gprs were needed for args.  rs6000_va_arg aligned
   when more than one word was needed for args, a mismatch on something
   like complex long long.

3) function_arg_boundary disagreed with function_arg_advance on
   alignment for two word args that didn't happen to be either DImode,
   DFmode or a SPE vector.  This doesn't cause a problem until you
   exhaust gprs for arg passing, at which point the generic function
   calling code lays out the stack according to function_arg_boundary,
   but the rs6000 backend assumes larger alignment.  Only causes a
   problem with variable argument functions with a large number of
   fixed arguments.  Presumably such functions are rare.

4) No accounting for stack space used by AltiVec args when -mabi=altivec
   and we run out of AltiVec registers.  Again, only causes a problem
   with variable argument functions with a large number of fixed vector
   arguments.

5) Passing vectors when -maltivec and -mabi=no-altivec was broken for
   reasons detailed in http://gcc.gnu.org/ml/gcc/2004-04/msg01316.html
   Vectors need to be aligned.  Also, -maltivec shouldn't change the
   function passing mechanism, which means both
   "-mabi=no-altivec -mno-altivec" and "-mabi=no-altivec -maltivec" need
   to change.  In this patch, I've chosen to pass altivec vectors by
   reference.  If passing by value, alignment constraints allow only one
   vector to be passed in regs, in r5,r6,r7,r8.

My fix for (5) does mean an ABI change, unfortunately.  I'm not sure how
to go about implementing altivec loads and stores to unaligned
locations.  The hardware can do it using multiple instructions and a
few temp vector regs.  I did try adding the following to rs6000_emit_move
to see whether the idea is feasible:

@@ -3573,7 +3573,25 @@ rs6000_emit_move (rtx dest, rtx source, 
       return;
     }
 
+  if (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode))
+    {
+      /* Loads and stores using AltiVec instructions must be 16 byte
+	 aligned, at least when transferring full vectors.  */
+      if (GET_CODE (operands[0]) == MEM
+	  && MEM_ALIGN (operands[0]) < 128)
+	{
+	  debug_rtx (operands[0]);
+	  abort ();
+	}
+      if (GET_CODE (operands[1]) == MEM
+	  && MEM_ALIGN (operands[1]) < 128)
+	{
+	  debug_rtx (operands[1]);
+	  abort ();
+	}
+    }
+
   if (!no_new_pseudos)
     {
       if (GET_CODE (operands[1]) == MEM && optimize > 0

This resulted in
(mem:V4SI (reg:SI 126) [0 S16 A8])
.../gcc.dg/altivec-varargs-1.c: In function `foo':
.../gcc.dg/altivec-varargs-1.c:25: internal compiler error: in rs6000_emit_move
We're looking at the result of a MEM returned from expand_builtin_va_arg,
so that's the first thing that would need fixing..


Anyhow, the following was tested powerpc-linux and powerpc64-linux, on
both altivec and non-altivec hardware, no regressions.  Fixes the
following failures:

FAIL: gcc.c-torture/execute/va-arg-25.c execution,  -O0 
FAIL: gcc.c-torture/execute/va-arg-25.c execution,  -O1 
FAIL: gcc.c-torture/execute/va-arg-25.c execution,  -O2 
FAIL: gcc.c-torture/execute/va-arg-25.c execution,  -O3 -fomit-frame-pointer 
FAIL: gcc.c-torture/execute/va-arg-25.c execution,  -O3 -g 
FAIL: gcc.c-torture/execute/va-arg-25.c execution,  -Os 
FAIL: gcc.dg/compat/scalar-by-value-3 c_compat_x_tst.o-c_compat_y_tst.o execute
FAIL: gcc.dg/compat/scalar-return-3 c_compat_x_tst.o-c_compat_y_tst.o execute
FAIL: gcc.dg/complex-1.c execution test
FAIL: g++.dg/ext/altivec-3.C execution test

	* config/rs6000/rs6000.c (function_arg_boundary): Align for ABI_V4
	when size is 8 bytes.
	(function_arg_advance): Account for stack space used by AltiVec
	args when -mabi=altivec.  Simplify alignment calculations.  For 
	ABI_V4, pass AltiVec vectors by reference when -mabi=no-altivec.
	(function_arg): Similarly.
	(function_arg_pass_by_reference): True for ABI_V4 AltiVec when
	not AltiVec ABI.
	(rs6000_va_arg): Correct fp arg test.  Adjust for AltiVec change.
	Correct alignment, and align before testing reg count.  Remove
	TREE_THIS_VOLATILE from reg.  Don't emit unused labels.
	(rs6000_complex_function_value): Check TARGET_HARD_FLOAT and
	TARGET_FPRS here..
	(rs6000_function_value): .. not here before call.

Some notes on the patch:
- Aldy added TREE_THIS_VOLATILE in
  http://gcc.gnu.org/ml/gcc-patches/2002-03/msg00409.html without any
  explanation.  I think it is no longer needed.  Not surprisingly, it
  pessimises the code.
- Aligning reg before comparing in rs6000_va_arg isn't a bug fix.  I
  just think it's neater that way as you then don't need the code that
  later sets reg to 8.

OK to install mainline?  Failing that, OK to install without the changes
to pass AltiVec by refernce?


--- gcc-virgin/gcc/config/rs6000/rs6000.c	2004-05-06 15:10:07.000000000 +0930
+++ gcc-mainline/gcc/config/rs6000/rs6000.c	2004-05-08 22:20:52.000000000 +0930
@@ -4065,10 +4083,10 @@ function_arg_padding (enum machine_mode 
 int
 function_arg_boundary (enum machine_mode mode, tree type ATTRIBUTE_UNUSED)
 {
-  if (DEFAULT_ABI == ABI_V4 && (mode == DImode || mode == DFmode))
+  if (DEFAULT_ABI == ABI_V4 && GET_MODE_SIZE (mode) == 8)
+    return 64;
+  else if (SPE_VECTOR_MODE (mode))
     return 64;
-   else if (SPE_VECTOR_MODE (mode))
-     return 64;
   else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
     return 128;
   else
@@ -4105,6 +4123,8 @@ function_arg_advance (CUMULATIVE_ARGS *c
 
   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
     {
+      bool stack = false;
+
       if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
         {
 	  cum->vregno++;
@@ -4112,12 +4132,18 @@ function_arg_advance (CUMULATIVE_ARGS *c
 	    error ("Cannot pass argument in vector register because"
 		   " altivec instructions are disabled, use -maltivec"
 		   " to enable them.");
+
+	  /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
+	     even if it is going to be passed in a vector register.  
+	     Darwin does the same for variable-argument functions.  */
+	  if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
+	      || (cum->stdarg && DEFAULT_ABI != ABI_V4))
+	    stack = true;
 	}
-      /* PowerPC64 Linux and AIX allocates GPRs for a vector argument
-	 even if it is going to be passed in a vector register.  
-	 Darwin does the same for variable-argument functions.  */
-      if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
-		   || (cum->stdarg && DEFAULT_ABI != ABI_V4))
+      else
+	stack = true;
+
+      if (stack)
         {
 	  int align;
 	  
@@ -4129,7 +4155,7 @@ function_arg_advance (CUMULATIVE_ARGS *c
 	     aligned.  Space for GPRs is reserved even if the argument
 	     will be passed in memory.  */
 	  if (TARGET_32BIT)
-	    align = ((6 - (cum->words & 3)) & 3);
+	    align = (2 - cum->words) & 3;
 	  else
 	    align = cum->words & 1;
 	  cum->words += align + rs6000_arg_size (mode, type);
@@ -4167,22 +4193,27 @@ function_arg_advance (CUMULATIVE_ARGS *c
 	  int n_words;
 	  int gregno = cum->sysv_gregno;
 
-	  /* Aggregates and IEEE quad get passed by reference.  */
+	  /* Aggregates, IEEE quad, and AltiVec vectors get passed by
+	     reference.  */
 	  if ((type && AGGREGATE_TYPE_P (type))
-	      || mode == TFmode)
+	      || mode == TFmode
+	      || ALTIVEC_VECTOR_MODE (mode))
 	    n_words = 1;
 	  else 
 	    n_words = rs6000_arg_size (mode, type);
 
-	  /* Long long and SPE vectors are put in odd registers.  */
-	  if (n_words == 2 && (gregno & 1) == 0)
-	    gregno += 1;
+	  /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
+	     (r7,r8) or (r9,r10).  As does any other 2 word item such
+	     as complex int due to a historical mistake.  */
+	  if (n_words == 2)
+	    gregno += (1 - gregno) & 1;
 
-	  /* Long long and SPE vectors are not split between registers
-	     and stack.  */
+	  /* Multi-reg args are not split between registers and stack.  */
 	  if (gregno + n_words - 1 > GP_ARG_MAX_REG)
 	    {
-	      /* Long long is aligned on the stack.  */
+	      /* Long long and SPE vectors are aligned on the stack.
+		 So are other 2 word items such as complex int due to
+		 a historical mistake.  */
 	      if (n_words == 2)
 		cum->words += cum->words & 1;
 	      cum->words += n_words;
@@ -4465,7 +4496,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum
 	     they just have to start on an even word, since the parameter
 	     save area is 16-byte aligned.  */
 	  if (TARGET_32BIT)
-	    align = ((6 - (cum->words & 3)) & 3);
+	    align = (2 - cum->words) & 3;
 	  else
 	    align = cum->words & 1;
 	  align_words = cum->words + align;
@@ -4502,18 +4533,22 @@ function_arg (CUMULATIVE_ARGS *cum, enum
 	  int n_words;
 	  int gregno = cum->sysv_gregno;
 
-	  /* Aggregates and IEEE quad get passed by reference.  */
+	  /* Aggregates, IEEE quad, and AltiVec vectors get passed by
+	     reference.  */
 	  if ((type && AGGREGATE_TYPE_P (type))
-	      || mode == TFmode)
+	      || mode == TFmode
+	      || ALTIVEC_VECTOR_MODE (mode))
 	    n_words = 1;
 	  else 
 	    n_words = rs6000_arg_size (mode, type);
 
-	  /* Long long and SPE vectors are put in odd registers.  */
-	  if (n_words == 2 && (gregno & 1) == 0)
-	    gregno += 1;
+	  /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
+	     (r7,r8) or (r9,r10).  As does any other 2 word item such
+	     as complex int due to a historical mistake.  */
+	  if (n_words == 2)
+	    gregno += (1 - gregno) & 1;
 
-	  /* Long long does not split between registers and stack.  */
+	  /* Multi-reg args are not split between registers and stack.  */
 	  if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
 	    return gen_rtx_REG (mode, gregno);
 	  else
@@ -4659,7 +4694,8 @@ function_arg_pass_by_reference (CUMULATI
 {
   if (DEFAULT_ABI == ABI_V4
       && ((type && AGGREGATE_TYPE_P (type))
-	  || mode == TFmode))
+	  || mode == TFmode
+	  || (!TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))))
     {
       if (TARGET_DEBUG_ARG)
 	fprintf (stderr, "function_arg_pass_by_reference: aggregate\n");
@@ -4913,6 +4948,7 @@ rs6000_va_arg (tree valist, tree type)
   tree gpr, fpr, ovf, sav, reg, t, u;
   int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
   rtx lab_false, lab_over, addr_rtx, r;
+  int align;
 
   if (DEFAULT_ABI != ABI_V4)
     {
@@ -4986,10 +5022,14 @@ rs6000_va_arg (tree valist, tree type)
 
   size = int_size_in_bytes (type);
   rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+  align = 1;
 
-  if (AGGREGATE_TYPE_P (type) || TYPE_MODE (type) == TFmode)
+  if (AGGREGATE_TYPE_P (type)
+      || TYPE_MODE (type) == TFmode
+      || (!TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type))))
     {
-      /* Aggregates and long doubles are passed by reference.  */
+      /* Aggregates, long doubles, and AltiVec vectors are passed by
+	 reference.  */
       indirect_p = 1;
       reg = gpr;
       n_reg = 1;
@@ -4998,7 +5038,8 @@ rs6000_va_arg (tree valist, tree type)
       size = UNITS_PER_WORD;
       rsize = 1;
     }
-  else if (FLOAT_TYPE_P (type) && TARGET_HARD_FLOAT && TARGET_FPRS)
+  else if (TARGET_HARD_FLOAT && TARGET_FPRS
+	   && (TYPE_MODE (type) == SFmode || TYPE_MODE (type) == DFmode))
     {
       /* FP args go in FP registers, if present.  */
       indirect_p = 0;
@@ -5006,6 +5047,8 @@ rs6000_va_arg (tree valist, tree type)
       n_reg = 1;
       sav_ofs = 8*4;
       sav_scale = 8;
+      if (TYPE_MODE (type) == DFmode)
+	align = 8;
     }
   else
     {
@@ -5015,38 +5058,43 @@ rs6000_va_arg (tree valist, tree type)
       n_reg = rsize;
       sav_ofs = 0;
       sav_scale = 4;
+      if (n_reg == 2)
+	align = 8;
     }
 
   /* Pull the value out of the saved registers....  */
 
-  lab_false = gen_label_rtx ();
-  lab_over = gen_label_rtx ();
+  lab_over = NULL_RTX;
   addr_rtx = gen_reg_rtx (Pmode);
 
-  /*  AltiVec vectors never go in registers.  */
-  if (!TARGET_ALTIVEC || TREE_CODE (type) != VECTOR_TYPE)
+  /*  AltiVec vectors never go in registers when -mabi=altivec.  */
+  if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
+    align = 16;
+  else
     {
-      TREE_THIS_VOLATILE (reg) = 1;
-      emit_cmp_and_jump_insns
-	(expand_expr (reg, NULL_RTX, QImode, EXPAND_NORMAL),
-	 GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
-	 lab_false);
-
-      /* Long long is aligned in the registers.  */
-      if (n_reg > 1)
+      lab_false = gen_label_rtx ();
+      lab_over = gen_label_rtx ();
+
+      /* Long long and SPE vectors are aligned in the registers.
+	 As are any other 2 gpr item such as complex int due to a
+	 historical mistake.  */
+      u = reg;
+      if (n_reg == 2)
 	{
 	  u = build (BIT_AND_EXPR, TREE_TYPE (reg), reg,
 		     build_int_2 (n_reg - 1, 0));
-	  u = build (PLUS_EXPR, TREE_TYPE (reg), reg, u);
-	  u = build (MODIFY_EXPR, TREE_TYPE (reg), reg, u);
+	  u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, u);
 	  TREE_SIDE_EFFECTS (u) = 1;
-	  expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
 	}
 
+      emit_cmp_and_jump_insns
+	(expand_expr (u, NULL_RTX, QImode, EXPAND_NORMAL),
+	 GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
+	 lab_false);
+
+      t = sav;
       if (sav_ofs)
 	t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
-      else
-	t = sav;
 
       u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
 		 build_int_2 (n_reg, 0));
@@ -5067,40 +5115,18 @@ rs6000_va_arg (tree valist, tree type)
 
       emit_jump_insn (gen_jump (lab_over));
       emit_barrier ();
-    }
 
-  emit_label (lab_false);
+      emit_label (lab_false);
+    }
 
   /* ... otherwise out of the overflow area.  */
 
-  /* Make sure we don't find reg 7 for the next int arg.
-
-     All AltiVec vectors go in the overflow area.  So in the AltiVec
-     case we need to get the vectors from the overflow area, but
-     remember where the GPRs and FPRs are.  */
-  if (n_reg > 1 && (TREE_CODE (type) != VECTOR_TYPE
-		    || !TARGET_ALTIVEC))
-    {
-      t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
-      TREE_SIDE_EFFECTS (t) = 1;
-      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
-    }
-
   /* Care for on-stack alignment if needed.  */
-  if (rsize <= 1)
-    t = ovf;
-  else
+  t = ovf;
+  if (align != 1)
     {
-      int align;
-
-      /* AltiVec vectors are 16 byte aligned.  */
-      if (TARGET_ALTIVEC && TREE_CODE (type) == VECTOR_TYPE)
-	align = 15;
-      else
-	align = 7;
-
-      t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align, 0));
-      t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align-1, -1));
+      t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (align - 1, 0));
+      t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align, -1));
     }
   t = save_expr (t);
 
@@ -5113,7 +5139,8 @@ rs6000_va_arg (tree valist, tree type)
   TREE_SIDE_EFFECTS (t) = 1;
   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
 
-  emit_label (lab_over);
+  if (lab_over)
+    emit_label (lab_over);
 
   if (indirect_p)
     {
@@ -16199,7 +16226,7 @@ rs6000_complex_function_value (enum mach
   enum machine_mode inner = GET_MODE_INNER (mode);
   unsigned int inner_bytes = GET_MODE_SIZE (inner);
 
-  if (FLOAT_MODE_P (mode))
+  if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
     regno = FP_ARG_RETURN;
   else
     {
@@ -16257,10 +16284,9 @@ rs6000_function_value (tree valtype, tre
   else
     mode = TYPE_MODE (valtype);
 
-  if (TREE_CODE (valtype) == REAL_TYPE && TARGET_HARD_FLOAT && TARGET_FPRS)
+  if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
     regno = FP_ARG_RETURN;
   else if (TREE_CODE (valtype) == COMPLEX_TYPE
-	   && TARGET_HARD_FLOAT
 	   && targetm.calls.split_complex_arg)
     return rs6000_complex_function_value (mode);
   else if (TREE_CODE (valtype) == VECTOR_TYPE

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* rs6000 stack boundary
@ 2004-04-30 14:46 Alan Modra
  2004-04-30 22:26 ` Geoff Keating
  0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2004-04-30 14:46 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

Fixes some problems with STACK_BOUNDARY.  Altivec needs 16 byte
alignment whether or no -mabi=altivec is given, and PowerPC64 Linux
always has a 16 byte aligned stack.  On PowerPC64 Linux, the sysv4.h
definition unfortunately overrode the rs6000.h one.

	* config/rs6000/rs6000.h (STACK_BOUNDARY): Use 128 bit for either
	TARGET_ALTIVEC or TARGET_ALTIVEC_ABI.
	* config/rs6000/sysv4.h (ABI_STACK_BOUNDARY): Likewise.
	(STACK_BOUNDARY): Delete.

Regression tested powerpc64-linux.  OK for mainline?

Index: gcc/config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.320
diff -u -p -r1.320 rs6000.h
--- gcc/config/rs6000/rs6000.h	24 Apr 2004 06:37:19 -0000	1.320
+++ gcc/config/rs6000/rs6000.h	30 Apr 2004 14:29:35 -0000
@@ -718,7 +718,8 @@ extern const char *rs6000_warn_altivec_l
 #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
 
 /* Boundary (in *bits*) on which stack pointer should be aligned.  */
-#define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
+#define STACK_BOUNDARY \
+  ((TARGET_32BIT && !TARGET_ALTIVEC && !TARGET_ALTIVEC_ABI) ? 64 : 128)
 
 /* Allocation boundary (in *bits*) for the code of a function.  */
 #define FUNCTION_BOUNDARY 32
Index: gcc/config/rs6000/sysv4.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/sysv4.h,v
retrieving revision 1.148
diff -u -p -r1.148 sysv4.h
--- gcc/config/rs6000/sysv4.h	11 Apr 2004 06:21:05 -0000	1.148
+++ gcc/config/rs6000/sysv4.h	30 Apr 2004 14:29:36 -0000
@@ -385,12 +385,6 @@ do {									\
 #undef	STRICT_ALIGNMENT
 #define	STRICT_ALIGNMENT (TARGET_STRICT_ALIGN)
 
-/* Alignment in bits of the stack boundary.  Note, in order to allow building
-   one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
-   versions, just use 64 as the stack boundary.  */
-#undef	STACK_BOUNDARY
-#define	STACK_BOUNDARY	(TARGET_ALTIVEC_ABI ? 128 : 64)
-
 /* Define this macro if you wish to preserve a certain alignment for
    the stack pointer, greater than what the hardware enforces.  The
    definition is a C expression for the desired alignment (measured
@@ -407,7 +401,8 @@ do {									\
 #define PREFERRED_STACK_BOUNDARY 128
 
 /* Real stack boundary as mandated by the appropriate ABI.  */
-#define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
+#define ABI_STACK_BOUNDARY \
+  ((TARGET_EABI && !TARGET_ALTIVEC && !TARGET_ALTIVEC_ABI) ? 64 : 128)
 
 /* An expression for the alignment of a structure field FIELD if the
    alignment computed in the usual way is COMPUTED.  */

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [lno] PATCH rs6000.md fix
@ 2004-03-30 14:55 Mostafa Hagog
  2004-03-30 15:36 ` David Edelsohn
  2004-04-01 12:43 ` Dorit Naishlos
  0 siblings, 2 replies; 875+ messages in thread
From: Mostafa Hagog @ 2004-03-30 14:55 UTC (permalink / raw)
  To: gcc-patches; +Cc: dje, geoffk

The following patch fixes an inconsistency in doloop related patterns of
rs6000.md.
Dorit Naishlos has pointed out to me that the gap benchmark fails on the
lno branch when
gcse-after-reload is specified. It turned that this is due to the same
problem that appeared
in s390 port (http://gcc.gnu.org/ml/gcc-patches/2004-03/msg01803.html).

Bootstraps on powerpc-apple-darwin7.2.0, no new regressions. Ok to commit
to lno?
IMO this should go also to mainline.

2004-03-28 Mostafa Hagog  <mustafa@il.ibm.com>

      * config/rs6000/rs6000.md ("*ctrsi_internal1", "*ctrsi_internal2",
      "*ctrdi_internal1", "*ctrdi_internal2", "*ctrsi_internal3",
      "*ctrsi_internal4", "*ctrdi_internal3", "*ctrdi_internal4",
      "*ctrsi_internal5", "*ctrsi_internal6", "*ctrdi_internal5",
      "*ctrdi_internal6"): Replace register_operand with
nonimmediate_operand


Index: rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.190.2.35.2.3
diff -c -p -r1.190.2.35.2.3 rs6000.md
*** rs6000.md     21 Mar 2004 03:21:23 -0000    1.190.2.35.2.3
--- rs6000.md     28 Mar 2004 09:20:59 -0000
***************
*** 13900,13906 ****
                    (const_int 1))
                  (label_ref (match_operand 0 "" ""))
                  (pc)))
!    (set (match_operand:SI 2 "register_operand" "=1,*r,m,*q*c*l")
      (plus:SI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
--- 13900,13906 ----
                    (const_int 1))
                  (label_ref (match_operand 0 "" ""))
                  (pc)))
!    (set (match_operand:SI 2 "nonimmediate_operand" "=1,*r,m,*q*c*l")
      (plus:SI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
***************
*** 13924,13930 ****
                    (const_int 1))
                  (pc)
                  (label_ref (match_operand 0 "" ""))))
!    (set (match_operand:SI 2 "register_operand" "=1,*r,m,*q*c*l")
      (plus:SI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
--- 13924,13930 ----
                    (const_int 1))
                  (pc)
                  (label_ref (match_operand 0 "" ""))))
!    (set (match_operand:SI 2 "nonimmediate_operand" "=1,*r,m,*q*c*l")
      (plus:SI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
***************
*** 13948,13954 ****
                    (const_int 1))
                  (label_ref (match_operand 0 "" ""))
                  (pc)))
!    (set (match_operand:DI 2 "register_operand" "=1,*r,m,*c*l")
      (plus:DI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
--- 13948,13954 ----
                    (const_int 1))
                  (label_ref (match_operand 0 "" ""))
                  (pc)))
!    (set (match_operand:DI 2 "nonimmediate_operand" "=1,*r,m,*c*l")
      (plus:DI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
***************
*** 13972,13978 ****
                    (const_int 1))
                  (pc)
                  (label_ref (match_operand 0 "" ""))))
!    (set (match_operand:DI 2 "register_operand" "=1,*r,m,*c*l")
      (plus:DI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
--- 13972,13978 ----
                    (const_int 1))
                  (pc)
                  (label_ref (match_operand 0 "" ""))))
!    (set (match_operand:DI 2 "nonimmediate_operand" "=1,*r,m,*c*l")
      (plus:DI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
***************
*** 13998,14004 ****
                    (const_int 0))
                  (label_ref (match_operand 0 "" ""))
                  (pc)))
!    (set (match_operand:SI 2 "register_operand" "=1,*r,m,*q*c*l")
      (plus:SI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
--- 13998,14004 ----
                    (const_int 0))
                  (label_ref (match_operand 0 "" ""))
                  (pc)))
!    (set (match_operand:SI 2 "nonimmediate_operand" "=1,*r,m,*q*c*l")
      (plus:SI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
***************
*** 14022,14028 ****
                    (const_int 0))
                  (pc)
                  (label_ref (match_operand 0 "" ""))))
!    (set (match_operand:SI 2 "register_operand" "=1,*r,m,*q*c*l")
      (plus:SI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
--- 14022,14028 ----
                    (const_int 0))
                  (pc)
                  (label_ref (match_operand 0 "" ""))))
!    (set (match_operand:SI 2 "nonimmediate_operand" "=1,*r,m,*q*c*l")
      (plus:SI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
***************
*** 14046,14052 ****
                    (const_int 0))
                  (label_ref (match_operand 0 "" ""))
                  (pc)))
!    (set (match_operand:DI 2 "register_operand" "=1,*r,m,*c*l")
      (plus:DI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
--- 14046,14052 ----
                    (const_int 0))
                  (label_ref (match_operand 0 "" ""))
                  (pc)))
!    (set (match_operand:DI 2 "nonimmediate_operand" "=1,*r,m,*c*l")
      (plus:DI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
***************
*** 14070,14076 ****
                    (const_int 0))
                  (pc)
                  (label_ref (match_operand 0 "" ""))))
!    (set (match_operand:DI 2 "register_operand" "=1,*r,m,*c*l")
      (plus:DI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
--- 14070,14076 ----
                    (const_int 0))
                  (pc)
                  (label_ref (match_operand 0 "" ""))))
!    (set (match_operand:DI 2 "nonimmediate_operand" "=1,*r,m,*c*l")
      (plus:DI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
***************
*** 14096,14102 ****
                    (const_int 1))
                  (label_ref (match_operand 0 "" ""))
                  (pc)))
!    (set (match_operand:SI 2 "register_operand" "=1,*r,m,*q*c*l")
      (plus:SI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
--- 14096,14102 ----
                    (const_int 1))
                  (label_ref (match_operand 0 "" ""))
                  (pc)))
!    (set (match_operand:SI 2 "nonimmediate_operand" "=1,*r,m,*q*c*l")
      (plus:SI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
***************
*** 14120,14126 ****
                    (const_int 1))
                  (pc)
                  (label_ref (match_operand 0 "" ""))))
!    (set (match_operand:SI 2 "register_operand" "=1,*r,m,*q*c*l")
      (plus:SI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
--- 14120,14126 ----
                    (const_int 1))
                  (pc)
                  (label_ref (match_operand 0 "" ""))))
!    (set (match_operand:SI 2 "nonimmediate_operand" "=1,*r,m,*q*c*l")
      (plus:SI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
***************
*** 14144,14150 ****
                    (const_int 1))
                  (label_ref (match_operand 0 "" ""))
                  (pc)))
!    (set (match_operand:DI 2 "register_operand" "=1,*r,m,*c*l")
      (plus:DI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
--- 14144,14150 ----
                    (const_int 1))
                  (label_ref (match_operand 0 "" ""))
                  (pc)))
!    (set (match_operand:DI 2 "nonimmediate_operand" "=1,*r,m,*c*l")
      (plus:DI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
***************
*** 14168,14174 ****
                    (const_int 1))
                  (pc)
                  (label_ref (match_operand 0 "" ""))))
!    (set (match_operand:DI 2 "register_operand" "=1,*r,m,*c*l")
      (plus:DI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
--- 14168,14174 ----
                    (const_int 1))
                  (pc)
                  (label_ref (match_operand 0 "" ""))))
!    (set (match_operand:DI 2 "nonimmediate_operand" "=1,*r,m,*c*l")
      (plus:DI (match_dup 1)
             (const_int -1)))
     (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))



^ permalink raw reply	[flat|nested] 875+ messages in thread
* [csl-arm,  HEAD] ARM PATCH - fix QImode addressing on ARMv4
@ 2004-03-13 11:43 Richard Earnshaw
  2004-03-13 13:01 ` Richard Earnshaw
  2004-03-19  8:14 ` Richard Earnshaw
  0 siblings, 2 replies; 875+ messages in thread
From: Richard Earnshaw @ 2004-03-13 11:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: Richard.Earnshaw

[-- Attachment #1: Type: text/plain, Size: 2290 bytes --]

This patch fixes the way that we manage QImode indexes when compiling for
ARM Architecture v4 or later.  In v4 we have a ldrsb instruction that can
sign-extend a byte load (ldrb zero-extends).  Unfortunately the indexing
capabilities of this insn are less flexible than its unsigned counterpart.
In the past we have restricted (mostly) the indexing range of ldrb to that
of its poorer cousin: that generates correct code, but at the expense of
wasting instructions when the indexing exceeds the capabilities of ldrsb.

The patch below addresses all this by introducing a new memory predicate
arm_extendqisi_mem_op which can validate a ldrsb address index distinctly
from an ldrb address index (it does so by calling arm_legitimate_address_p
with a new argument, the 'outer' code in much the same way as the RTX_COST
macros do.

Measurements on CSiBE code show about 0.1% code size reduction with this
change.

Built and regress tested for arm-unknown-elf on the csl-arm-branch and
HEAD, and fully bootstrapped on armv4-linux-gnu on HEAD.

Committed to csl-arm and HEAD.

2004-03-13  Richard Earnshaw  <rearnsha@arm.com>

	* arm.c (arm_legitimate_address_p): New argument, OUTER.  Pass through
	to arm_legitimate_index_p.  Update all callers with SET as default
	value.
	(arm_legitimate_index_p): New argument, OUTER.  Restrict the index
	range if OUTER is a sign-extend operation on QImode.  Correctly
	reject shift operations on sign-extended QImode addresses.
	(bad_signed_byte_operand): Delete.
	(arm_extendqisi_mem_op): New function.
	* arm.h (EXTRA_CONSTRAINT_ARM): Delete.  Replace with...
	(EXTRA_CONSTRAINT_STR_ARM): ... this.  Handle extended address
	constraints.
	(CONSTRAINT_LEN): New.
	(EXTRA_CONSTRAINT): Delete.  Replace with...
	(EXTRA_CONSTRAINT_STR): ... this.
	(PREDICATE_CODES): Remove bad_signed_byte_operand.
	* arm.md (extendqihi_insn): Use new constraint Uq.  Rework.  Length
	is now always default.
	(define_splits for bad sign-extend loads): Delete.
	(arm_extendqisi, arm_extendqisi_v5): Likewise.
	* arm/vfp.md (arm_movsi_vfp, arm_movdi_vfp, movsf_vfp, movdf_vfp):
	Rework 'U' constraint to 'Uv'.
	* arm-protos.h: Remove bad_signed_byte_operand.  Add
	arm_extendqisi_mem_op.
	* doc/md.texi (ARM constraints): Rename VFP constraint (now Uv).
	Add Uq constraint.



[-- Attachment #2: extendqisi-addr.patch --]
[-- Type: text/plain , Size: 26031 bytes --]

Index: config/arm/arm-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm-protos.h,v
retrieving revision 1.60.4.6
diff -p -p -r1.60.4.6 arm-protos.h
*** config/arm/arm-protos.h	30 Jan 2004 16:14:21 -0000	1.60.4.6
--- config/arm/arm-protos.h	11 Mar 2004 07:15:25 -0000
*************** extern int arm_split_constant (RTX_CODE,
*** 50,56 ****
  extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, rtx *);
  extern int legitimate_pic_operand_p (rtx);
  extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
! extern int arm_legitimate_address_p  (enum machine_mode, rtx, int);
  extern int thumb_legitimate_address_p (enum machine_mode, rtx, int);
  extern int thumb_legitimate_offset_p (enum machine_mode, HOST_WIDE_INT);
  extern rtx arm_legitimize_address (rtx, rtx, enum machine_mode);
--- 50,56 ----
  extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, rtx *);
  extern int legitimate_pic_operand_p (rtx);
  extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
! extern int arm_legitimate_address_p  (enum machine_mode, rtx, RTX_CODE, int);
  extern int thumb_legitimate_address_p (enum machine_mode, rtx, int);
  extern int thumb_legitimate_offset_p (enum machine_mode, HOST_WIDE_INT);
  extern rtx arm_legitimize_address (rtx, rtx, enum machine_mode);
*************** extern int arm_rhsm_operand (rtx, enum m
*** 70,78 ****
  extern int arm_add_operand (rtx, enum machine_mode);
  extern int arm_addimm_operand (rtx, enum machine_mode);
  extern int arm_not_operand (rtx, enum machine_mode);
  extern int offsettable_memory_operand (rtx, enum machine_mode);
  extern int alignable_memory_operand (rtx, enum machine_mode);
- extern int bad_signed_byte_operand (rtx, enum machine_mode);
  extern int arm_float_rhs_operand (rtx, enum machine_mode);
  extern int arm_float_add_operand (rtx, enum machine_mode);
  extern int power_of_two_operand (rtx, enum machine_mode);
--- 70,78 ----
  extern int arm_add_operand (rtx, enum machine_mode);
  extern int arm_addimm_operand (rtx, enum machine_mode);
  extern int arm_not_operand (rtx, enum machine_mode);
+ extern int arm_extendqisi_mem_op (rtx, enum machine_mode);
  extern int offsettable_memory_operand (rtx, enum machine_mode);
  extern int alignable_memory_operand (rtx, enum machine_mode);
  extern int arm_float_rhs_operand (rtx, enum machine_mode);
  extern int arm_float_add_operand (rtx, enum machine_mode);
  extern int power_of_two_operand (rtx, enum machine_mode);
Index: config/arm/arm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.303.2.17
diff -p -p -r1.303.2.17 arm.c
*** config/arm/arm.c	3 Mar 2004 16:03:31 -0000	1.303.2.17
--- config/arm/arm.c	11 Mar 2004 07:15:57 -0000
*************** static int arm_gen_constant (enum rtx_co
*** 64,70 ****
  			     rtx, rtx, int, int);
  static unsigned bit_count (unsigned long);
  static int arm_address_register_rtx_p (rtx, int);
! static int arm_legitimate_index_p (enum machine_mode, rtx, int);
  static int thumb_base_register_rtx_p (rtx, enum machine_mode, int);
  inline static int thumb_index_register_rtx_p (rtx, int);
  static int const_ok_for_op (HOST_WIDE_INT, enum rtx_code);
--- 64,70 ----
  			     rtx, rtx, int, int);
  static unsigned bit_count (unsigned long);
  static int arm_address_register_rtx_p (rtx, int);
! static int arm_legitimate_index_p (enum machine_mode, rtx, RTX_CODE, int);
  static int thumb_base_register_rtx_p (rtx, enum machine_mode, int);
  inline static int thumb_index_register_rtx_p (rtx, int);
  static int const_ok_for_op (HOST_WIDE_INT, enum rtx_code);
*************** legitimize_pic_address (rtx orig, enum m
*** 2708,2714 ****
  	{
  	  /* The base register doesn't really matter, we only want to
  	     test the index for the appropriate mode.  */
! 	  if (!arm_legitimate_index_p (mode, offset, 0))
  	    {
  	      if (!no_new_pseudos)
  		offset = force_reg (Pmode, offset);
--- 2708,2714 ----
  	{
  	  /* The base register doesn't really matter, we only want to
  	     test the index for the appropriate mode.  */
! 	  if (!arm_legitimate_index_p (mode, offset, SET, 0))
  	    {
  	      if (!no_new_pseudos)
  		offset = force_reg (Pmode, offset);
*************** arm_address_register_rtx_p (rtx x, int s
*** 2813,2819 ****
  
  /* Return nonzero if X is a valid ARM state address operand.  */
  int
! arm_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p)
  {
    if (arm_address_register_rtx_p (x, strict_p))
      return 1;
--- 2813,2820 ----
  
  /* Return nonzero if X is a valid ARM state address operand.  */
  int
! arm_legitimate_address_p (enum machine_mode mode, rtx x, RTX_CODE outer,
! 			  int strict_p)
  {
    if (arm_address_register_rtx_p (x, strict_p))
      return 1;
*************** arm_legitimate_address_p (enum machine_m
*** 2826,2832 ****
  	   && arm_address_register_rtx_p (XEXP (x, 0), strict_p)
  	   && GET_CODE (XEXP (x, 1)) == PLUS
  	   && XEXP (XEXP (x, 1), 0) == XEXP (x, 0))
!     return arm_legitimate_index_p (mode, XEXP (XEXP (x, 1), 1), strict_p);
  
    /* After reload constants split into minipools will have addresses
       from a LABEL_REF.  */
--- 2827,2834 ----
  	   && arm_address_register_rtx_p (XEXP (x, 0), strict_p)
  	   && GET_CODE (XEXP (x, 1)) == PLUS
  	   && XEXP (XEXP (x, 1), 0) == XEXP (x, 0))
!     return arm_legitimate_index_p (mode, XEXP (XEXP (x, 1), 1), outer,
! 				   strict_p);
  
    /* After reload constants split into minipools will have addresses
       from a LABEL_REF.  */
*************** arm_legitimate_address_p (enum machine_m
*** 2878,2886 ****
        rtx xop1 = XEXP (x, 1);
  
        return ((arm_address_register_rtx_p (xop0, strict_p)
! 	       && arm_legitimate_index_p (mode, xop1, strict_p))
  	      || (arm_address_register_rtx_p (xop1, strict_p)
! 		  && arm_legitimate_index_p (mode, xop0, strict_p)));
      }
  
  #if 0
--- 2880,2888 ----
        rtx xop1 = XEXP (x, 1);
  
        return ((arm_address_register_rtx_p (xop0, strict_p)
! 	       && arm_legitimate_index_p (mode, xop1, outer, strict_p))
  	      || (arm_address_register_rtx_p (xop1, strict_p)
! 		  && arm_legitimate_index_p (mode, xop0, outer, strict_p)));
      }
  
  #if 0
*************** arm_legitimate_address_p (enum machine_m
*** 2891,2897 ****
        rtx xop1 = XEXP (x, 1);
  
        return (arm_address_register_rtx_p (xop0, strict_p)
! 	      && arm_legitimate_index_p (mode, xop1, strict_p));
      }
  #endif
  
--- 2893,2899 ----
        rtx xop1 = XEXP (x, 1);
  
        return (arm_address_register_rtx_p (xop0, strict_p)
! 	      && arm_legitimate_index_p (mode, xop1, outer, strict_p));
      }
  #endif
  
*************** arm_legitimate_address_p (enum machine_m
*** 2913,2919 ****
  /* Return nonzero if INDEX is valid for an address index operand in
     ARM state.  */
  static int
! arm_legitimate_index_p (enum machine_mode mode, rtx index, int strict_p)
  {
    HOST_WIDE_INT range;
    enum rtx_code code = GET_CODE (index);
--- 2915,2922 ----
  /* Return nonzero if INDEX is valid for an address index operand in
     ARM state.  */
  static int
! arm_legitimate_index_p (enum machine_mode mode, rtx index, RTX_CODE outer,
! 			int strict_p)
  {
    HOST_WIDE_INT range;
    enum rtx_code code = GET_CODE (index);
*************** arm_legitimate_index_p (enum machine_mod
*** 2938,2975 ****
  	    && INTVAL (index) < 256
  	    && INTVAL (index) > -256);
  
!   /* XXX What about ldrsb?  */
!   if (GET_MODE_SIZE (mode) <= 4  && code == MULT
!       && (!arm_arch4 || (mode) != HImode))
!     {
!       rtx xiop0 = XEXP (index, 0);
!       rtx xiop1 = XEXP (index, 1);
! 
!       return ((arm_address_register_rtx_p (xiop0, strict_p)
! 	       && power_of_two_operand (xiop1, SImode))
! 	      || (arm_address_register_rtx_p (xiop1, strict_p)
! 		  && power_of_two_operand (xiop0, SImode)));
      }
  
!   if (GET_MODE_SIZE (mode) <= 4
!       && (code == LSHIFTRT || code == ASHIFTRT
! 	  || code == ASHIFT || code == ROTATERT)
!       && (!arm_arch4 || (mode) != HImode))
!     {
!       rtx op = XEXP (index, 1);
! 
!       return (arm_address_register_rtx_p (XEXP (index, 0), strict_p)
! 	      && GET_CODE (op) == CONST_INT
! 	      && INTVAL (op) > 0
! 	      && INTVAL (op) <= 31);
!     }
! 
!   /* XXX For ARM v4 we may be doing a sign-extend operation during the
!      load, but that has a restricted addressing range and we are unable
!      to tell here whether that is the case.  To be safe we restrict all
!      loads to that range.  */
    if (arm_arch4)
!     range = (mode == HImode || mode == QImode) ? 256 : 4096;
    else
      range = (mode == HImode) ? 4095 : 4096;
  
--- 2941,2982 ----
  	    && INTVAL (index) < 256
  	    && INTVAL (index) > -256);
  
!   if (GET_MODE_SIZE (mode) <= 4
!       && ! (arm_arch4
! 	    && (mode == HImode
! 		|| (mode == QImode && outer == SIGN_EXTEND))))
!     {
!       if (code == MULT)
! 	{
! 	  rtx xiop0 = XEXP (index, 0);
! 	  rtx xiop1 = XEXP (index, 1);
! 
! 	  return ((arm_address_register_rtx_p (xiop0, strict_p)
! 		   && power_of_two_operand (xiop1, SImode))
! 		  || (arm_address_register_rtx_p (xiop1, strict_p)
! 		      && power_of_two_operand (xiop0, SImode)));
! 	}
!       else if (code == LSHIFTRT || code == ASHIFTRT
! 	       || code == ASHIFT || code == ROTATERT)
! 	{
! 	  rtx op = XEXP (index, 1);
! 
! 	  return (arm_address_register_rtx_p (XEXP (index, 0), strict_p)
! 		  && GET_CODE (op) == CONST_INT
! 		  && INTVAL (op) > 0
! 		  && INTVAL (op) <= 31);
! 	}
      }
  
!   /* For ARM v4 we may be doing a sign-extend operation during the
!      load.  */
    if (arm_arch4)
!     {
!       if (mode == HImode || (outer == SIGN_EXTEND && mode == QImode))
! 	range = 256;
!       else
! 	range = 4096;
!     }
    else
      range = (mode == HImode) ? 4095 : 4096;
  
*************** arm_reload_memory_operand (rtx op, enum 
*** 4135,4171 ****
  		  && REGNO (op) >= FIRST_PSEUDO_REGISTER)));
  }
  
- /* Return 1 if OP is a valid memory address, but not valid for a signed byte
-    memory access (architecture V4).
-    MODE is QImode if called when computing constraints, or VOIDmode when
-    emitting patterns.  In this latter case we cannot use memory_operand()
-    because it will fail on badly formed MEMs, which is precisely what we are
-    trying to catch.  */
- int
- bad_signed_byte_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
- {
-   if (GET_CODE (op) != MEM)
-     return 0;
- 
-   op = XEXP (op, 0);
- 
-   /* A sum of anything more complex than reg + reg or reg + const is bad.  */
-   if ((GET_CODE (op) == PLUS || GET_CODE (op) == MINUS)
-       && (!s_register_operand (XEXP (op, 0), VOIDmode)
- 	  || (!s_register_operand (XEXP (op, 1), VOIDmode)
- 	      && GET_CODE (XEXP (op, 1)) != CONST_INT)))
-     return 1;
- 
-   /* Big constants are also bad.  */
-   if (GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT
-       && (INTVAL (XEXP (op, 1)) > 0xff
- 	  || -INTVAL (XEXP (op, 1)) > 0xff))
-     return 1;
- 
-   /* Everything else is good, or can will automatically be made so.  */
-   return 0;
- }
- 
  /* Return TRUE for valid operands for the rhs of an ARM instruction.  */
  int
  arm_rhs_operand (rtx op, enum machine_mode mode)
--- 4142,4147 ----
*************** cirrus_memory_offset (rtx op)
*** 4356,4361 ****
--- 4332,4346 ----
      }
  
    return 0;
+ }
+ 
+ int
+ arm_extendqisi_mem_op (rtx op, enum machine_mode mode)
+ {
+   if (!memory_operand (op, mode))
+     return 0;
+ 
+   return arm_legitimate_address_p (mode, XEXP (op, 0), SIGN_EXTEND, 0);
  }
  
  /* Return nonzero if OP is a Cirrus or general register.  */
Index: config/arm/arm.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.h,v
retrieving revision 1.210.2.19
diff -p -p -r1.210.2.19 arm.h
*** config/arm/arm.h	5 Mar 2004 17:32:17 -0000	1.210.2.19
--- config/arm/arm.h	11 Mar 2004 07:16:07 -0000
*************** enum reg_class
*** 1486,1508 ****
     accessed without using a load.
     'U' is an address valid for VFP load/store insns.  */
  
! #define EXTRA_CONSTRAINT_ARM(OP, C)					    \
!   ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG :    \
!    (C) == 'R' ? (GET_CODE (OP) == MEM					    \
! 		 && GET_CODE (XEXP (OP, 0)) == SYMBOL_REF		    \
! 		 && CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) :		    \
!    (C) == 'S' ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) :		    \
!    (C) == 'T' ? cirrus_memory_offset (OP) : 		    		    \
!    (C) == 'U' ? vfp_mem_operand (OP) :					    \
!    0)
  
  #define EXTRA_CONSTRAINT_THUMB(X, C)					\
    ((C) == 'Q' ? (GET_CODE (X) == MEM					\
  		 && GET_CODE (XEXP (X, 0)) == LABEL_REF) : 0)
  
! #define EXTRA_CONSTRAINT(X, C)						\
!   (TARGET_ARM ?								\
!    EXTRA_CONSTRAINT_ARM (X, C) : EXTRA_CONSTRAINT_THUMB (X, C))
  
  #define EXTRA_MEMORY_CONSTRAINT(C, STR) ((C) == 'U')
  
--- 1486,1515 ----
     accessed without using a load.
     'U' is an address valid for VFP load/store insns.  */
  
! #define EXTRA_CONSTRAINT_STR_ARM(OP, C, STR)			\
!   (((C) == 'Q') ? (GET_CODE (OP) == MEM				\
! 		 && GET_CODE (XEXP (OP, 0)) == REG) :		\
!    ((C) == 'R') ? (GET_CODE (OP) == MEM				\
! 		   && GET_CODE (XEXP (OP, 0)) == SYMBOL_REF	\
! 		   && CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) :	\
!    ((C) == 'S') ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) :	\
!    ((C) == 'T') ? cirrus_memory_offset (OP) :			\
!    ((C) == 'U' && (STR)[1] == 'v') ? vfp_mem_operand (OP) :	\
!    ((C) == 'U' && (STR)[1] == 'q')				\
!     ? arm_extendqisi_mem_op (OP, GET_MODE (OP))			\
!       : 0)
! 
! #define CONSTRAINT_LEN(C,STR)				\
!   ((C) == 'U' ? 2 : DEFAULT_CONSTRAINT_LEN (C, STR))
  
  #define EXTRA_CONSTRAINT_THUMB(X, C)					\
    ((C) == 'Q' ? (GET_CODE (X) == MEM					\
  		 && GET_CODE (XEXP (X, 0)) == LABEL_REF) : 0)
  
! #define EXTRA_CONSTRAINT_STR(X, C, STR)		\
!   (TARGET_ARM					\
!    ? EXTRA_CONSTRAINT_STR_ARM (X, C, STR)	\
!    : EXTRA_CONSTRAINT_THUMB (X, C))
  
  #define EXTRA_MEMORY_CONSTRAINT(C, STR) ((C) == 'U')
  
*************** typedef struct
*** 2371,2377 ****
  
  #define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE,X,WIN)		\
    {								\
!     if (arm_legitimate_address_p (MODE, X, REG_STRICT_P))	\
        goto WIN;							\
    }
  
--- 2378,2384 ----
  
  #define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE,X,WIN)		\
    {								\
!     if (arm_legitimate_address_p (MODE, X, SET, REG_STRICT_P))	\
        goto WIN;							\
    }
  
*************** extern int making_const_table;
*** 2862,2868 ****
    {"thumb_cmpneg_operand", {CONST_INT}},				\
    {"thumb_cbrch_target_operand", {SUBREG, REG, MEM}},			\
    {"offsettable_memory_operand", {MEM}},				\
-   {"bad_signed_byte_operand", {MEM}},					\
    {"alignable_memory_operand", {MEM}},					\
    {"shiftable_operator", {PLUS, MINUS, AND, IOR, XOR}},			\
    {"minmax_operator", {SMIN, SMAX, UMIN, UMAX}},			\
--- 2869,2874 ----
Index: config/arm/arm.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.md,v
retrieving revision 1.145.2.14
diff -p -p -r1.145.2.14 arm.md
*** config/arm/arm.md	3 Mar 2004 16:03:32 -0000	1.145.2.14
--- config/arm/arm.md	11 Mar 2004 07:16:25 -0000
***************
*** 3746,3804 ****
    }"
  )
  
- ; Rather than restricting all byte accesses to memory addresses that ldrsb
- ; can handle, we fix up the ones that ldrsb can't grok with a split.
  (define_insn "*extendqihi_insn"
!   [(set (match_operand:HI                 0 "s_register_operand" "=r")
! 	(sign_extend:HI (match_operand:QI 1 "memory_operand"      "m")))]
    "TARGET_ARM && arm_arch4"
!   "*
!   /* If the address is invalid, this will split the instruction into two.  */
!   if (bad_signed_byte_operand (operands[1], VOIDmode))
!     return \"#\";
!   return \"ldr%?sb\\t%0, %1\";
!   "
    [(set_attr "type" "load_byte")
     (set_attr "predicable" "yes")
-    (set_attr "length" "8")
     (set_attr "pool_range" "256")
     (set_attr "neg_pool_range" "244")]
  )
  
- (define_split
-   [(set (match_operand:HI 0 "s_register_operand" "")
- 	(sign_extend:HI (match_operand:QI 1 "bad_signed_byte_operand" "")))]
-   "TARGET_ARM && arm_arch4 && reload_completed"
-   [(set (match_dup 3) (match_dup 1))
-    (set (match_dup 0) (sign_extend:HI (match_dup 2)))]
-   "
-   {
-     HOST_WIDE_INT offset;
- 
-     operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
-     operands[2] = gen_rtx_MEM (QImode, operands[3]);
-     MEM_COPY_ATTRIBUTES (operands[2], operands[1]);
-     operands[1] = XEXP (operands[1], 0);
-     if (GET_CODE (operands[1]) == PLUS
- 	&& GET_CODE (XEXP (operands[1], 1)) == CONST_INT
- 	&& !(const_ok_for_arm (offset = INTVAL (XEXP (operands[1], 1)))
- 	     || const_ok_for_arm (-offset)))
-       {
- 	HOST_WIDE_INT low = (offset > 0
- 			     ? (offset & 0xff) : -((-offset) & 0xff));
- 	XEXP (operands[2], 0) = plus_constant (operands[3], low);
- 	operands[1] = plus_constant (XEXP (operands[1], 0), offset - low);
-       }
-     /* Ensure the sum is in correct canonical form.  */
-     else if (GET_CODE (operands[1]) == PLUS
- 	     && GET_CODE (XEXP (operands[1], 1)) != CONST_INT
- 	     && !s_register_operand (XEXP (operands[1], 1), VOIDmode))
-       operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]),
- 					   XEXP (operands[1], 1),
- 					   XEXP (operands[1], 0));
-   }"
- )
- 
  (define_expand "extendqisi2"
    [(set (match_dup 2)
  	(ashift:SI (match_operand:QI 1 "general_operand" "")
--- 3746,3762 ----
    }"
  )
  
  (define_insn "*extendqihi_insn"
!   [(set (match_operand:HI 0 "s_register_operand" "=r")
! 	(sign_extend:HI (match_operand:QI 1 "memory_operand" "Uq")))]
    "TARGET_ARM && arm_arch4"
!   "ldr%?sb\\t%0, %1"
    [(set_attr "type" "load_byte")
     (set_attr "predicable" "yes")
     (set_attr "pool_range" "256")
     (set_attr "neg_pool_range" "244")]
  )
  
  (define_expand "extendqisi2"
    [(set (match_dup 2)
  	(ashift:SI (match_operand:QI 1 "general_operand" "")
***************
*** 3831,3872 ****
    }"
  )
  
- ; Rather than restricting all byte accesses to memory addresses that ldrsb
- ; can handle, we fix up the ones that ldrsb can't grok with a split.
  (define_insn "*arm_extendqisi"
    [(set (match_operand:SI 0 "s_register_operand" "=r")
! 	(sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
    "TARGET_ARM && arm_arch4 && !arm_arch6"
!   "*
!   /* If the address is invalid, this will split the instruction into two.  */
!   if (bad_signed_byte_operand (operands[1], VOIDmode))
!     return \"#\";
!   return \"ldr%?sb\\t%0, %1\";
!   "
    [(set_attr "type" "load_byte")
     (set_attr "predicable" "yes")
-    (set_attr "length" "8")
     (set_attr "pool_range" "256")
     (set_attr "neg_pool_range" "244")]
  )
  
  (define_insn "*arm_extendqisi_v6"
    [(set (match_operand:SI 0 "s_register_operand" "=r,r")
! 	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
    "TARGET_ARM && arm_arch6"
!   "*
!   if (which_alternative == 0)
!     return \"sxtb%?\\t%0, %1\";
! 
!   /* If the address is invalid, this will split the instruction into two.  */
!   if (bad_signed_byte_operand (operands[1], VOIDmode))
!     return \"#\";
! 
!   return \"ldr%?sb\\t%0, %1\";
!   "
    [(set_attr "type" "alu_shift,load_byte")
     (set_attr "predicable" "yes")
-    (set_attr "length" "4,8")
     (set_attr "pool_range" "*,256")
     (set_attr "neg_pool_range" "*,244")]
  )
--- 3789,3814 ----
    }"
  )
  
  (define_insn "*arm_extendqisi"
    [(set (match_operand:SI 0 "s_register_operand" "=r")
! 	(sign_extend:SI (match_operand:QI 1 "memory_operand" "Uq")))]
    "TARGET_ARM && arm_arch4 && !arm_arch6"
!   "ldr%?sb\\t%0, %1"
    [(set_attr "type" "load_byte")
     (set_attr "predicable" "yes")
     (set_attr "pool_range" "256")
     (set_attr "neg_pool_range" "244")]
  )
  
  (define_insn "*arm_extendqisi_v6"
    [(set (match_operand:SI 0 "s_register_operand" "=r,r")
! 	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uq")))]
    "TARGET_ARM && arm_arch6"
!   "@
!    sxtb%?\\t%0, %1
!    ldr%?sb\\t%0, %1"
    [(set_attr "type" "alu_shift,load_byte")
     (set_attr "predicable" "yes")
     (set_attr "pool_range" "*,256")
     (set_attr "neg_pool_range" "*,244")]
  )
***************
*** 3879,3917 ****
    "sxtab%?\\t%0, %2, %1"
    [(set_attr "type" "alu_shift")
     (set_attr "predicable" "yes")]
- )
- 
- (define_split
-   [(set (match_operand:SI 0 "s_register_operand" "")
- 	(sign_extend:SI (match_operand:QI 1 "bad_signed_byte_operand" "")))]
-   "TARGET_ARM && arm_arch4 && reload_completed"
-   [(set (match_dup 0) (match_dup 1))
-    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
-   "
-   {
-     HOST_WIDE_INT offset;
- 
-     operands[2] = gen_rtx_MEM (QImode, operands[0]);
-     MEM_COPY_ATTRIBUTES (operands[2], operands[1]);
-     operands[1] = XEXP (operands[1], 0);
-     if (GET_CODE (operands[1]) == PLUS
- 	&& GET_CODE (XEXP (operands[1], 1)) == CONST_INT
- 	&& !(const_ok_for_arm (offset = INTVAL (XEXP (operands[1], 1)))
- 	     || const_ok_for_arm (-offset)))
-       {
- 	HOST_WIDE_INT low = (offset > 0
- 			     ? (offset & 0xff) : -((-offset) & 0xff));
- 	XEXP (operands[2], 0) = plus_constant (operands[0], low);
- 	operands[1] = plus_constant (XEXP (operands[1], 0), offset - low);
-       }
-     /* Ensure the sum is in correct canonical form.  */
-     else if (GET_CODE (operands[1]) == PLUS
- 	     && GET_CODE (XEXP (operands[1], 1)) != CONST_INT
- 	     && !s_register_operand (XEXP (operands[1], 1), VOIDmode))
-       operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]),
- 					   XEXP (operands[1], 1),
- 					   XEXP (operands[1], 0));
-   }"
  )
  
  (define_insn "*thumb_extendqisi2"
--- 3821,3826 ----
Index: config/arm/vfp.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/vfp.md,v
retrieving revision 1.1.2.1
diff -p -p -r1.1.2.1 vfp.md
*** config/arm/vfp.md	30 Jan 2004 16:15:19 -0000	1.1.2.1
--- config/arm/vfp.md	11 Mar 2004 07:16:25 -0000
***************
*** 111,118 ****
  ;; ??? For now do not allow loading constants into vfp regs.  This causes
  ;; problems because small sonstants get converted into adds.
  (define_insn "*arm_movsi_vfp"
!   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,m,!w,r,!w,!w, U")
!       (match_operand:SI 1 "general_operand"	   "rI,K,mi,r,r,!w,!w,Ui,!w"))]
    "TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT
     && (   s_register_operand (operands[0], SImode)
         || s_register_operand (operands[1], SImode))"
--- 111,118 ----
  ;; ??? For now do not allow loading constants into vfp regs.  This causes
  ;; problems because small sonstants get converted into adds.
  (define_insn "*arm_movsi_vfp"
!   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,m,!w,r,!w,!w,  Uv")
!       (match_operand:SI 1 "general_operand"	   "rI,K,mi,r,r,!w,!w,Uvi,!w"))]
    "TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT
     && (   s_register_operand (operands[0], SImode)
         || s_register_operand (operands[1], SImode))"
***************
*** 136,143 ****
  ;; DImode moves
  
  (define_insn "*arm_movdi_vfp"
!   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,o<>,w,r,w,w ,U")
! 	(match_operand:DI 1 "di_operand"              "rIK,mi,r ,r,w,w,Ui,w"))]
    "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
    "*
    switch (which_alternative)
--- 136,143 ----
  ;; DImode moves
  
  (define_insn "*arm_movdi_vfp"
!   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,o<>,w,r,w,w  ,Uv")
! 	(match_operand:DI 1 "di_operand"              "rIK,mi,r ,r,w,w,Uvi,w"))]
    "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
    "*
    switch (which_alternative)
***************
*** 168,175 ****
  ;; SFmode moves
  
  (define_insn "*movsf_vfp"
!   [(set (match_operand:SF 0 "nonimmediate_operand" "=w,r,w ,U,r ,m,w,r")
! 	(match_operand:SF 1 "general_operand"	   " r,w,UE,w,mE,r,w,r"))]
    "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
     && (   s_register_operand (operands[0], SFmode)
         || s_register_operand (operands[1], SFmode))"
--- 168,175 ----
  ;; SFmode moves
  
  (define_insn "*movsf_vfp"
!   [(set (match_operand:SF 0 "nonimmediate_operand" "=w,r,w  ,Uv,r ,m,w,r")
! 	(match_operand:SF 1 "general_operand"	   " r,w,UvE,w, mE,r,w,r"))]
    "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
     && (   s_register_operand (operands[0], SFmode)
         || s_register_operand (operands[1], SFmode))"
***************
*** 192,199 ****
  ;; DFmode moves
  
  (define_insn "*movdf_vfp"
!   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,r,r, m,w ,U,w,r")
! 	(match_operand:DF 1 "soft_df_operand"		   " r,w,mF,r,UF,w,w,r"))]
    "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
    "*
    {
--- 192,199 ----
  ;; DFmode moves
  
  (define_insn "*movdf_vfp"
!   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,r,r, m,w  ,Uv,w,r")
! 	(match_operand:DF 1 "soft_df_operand"		   " r,w,mF,r,UvF,w, w,r"))]
    "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
    "*
    {
Index: doc/md.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/md.texi,v
retrieving revision 1.79.4.4
diff -p -p -r1.79.4.4 md.texi
*** doc/md.texi	3 Mar 2004 16:04:37 -0000	1.79.4.4
--- doc/md.texi	11 Mar 2004 07:17:10 -0000
*************** An item in the constant pool
*** 1379,1386 ****
  A symbol in the text segment of the current file
  @end table
  
! @item U
  A memory reference suitable for VFP load/store insns (reg+constant offset)
  
  @item AVR family---@file{avr.h}
  @table @code
--- 1379,1389 ----
  A symbol in the text segment of the current file
  @end table
  
! @item Uv
  A memory reference suitable for VFP load/store insns (reg+constant offset)
+ 
+ @item Uq
+ A memory reference suitable for for the ARMv4 ldrsb instruction.
  
  @item AVR family---@file{avr.h}
  @table @code

^ permalink raw reply	[flat|nested] 875+ messages in thread
[parent not found: <40491948.2010900@us.ibm.com>]
* Fix PR 14406 (rs6000 abstf2)
@ 2004-03-03 15:14 Alan Modra
  2004-03-19  8:14 ` Alan Modra
  0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2004-03-03 15:14 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

Replaces the bogus abstf2 pattern with one that works.  Details in the
PR.

	PR target/14406
	* config/rs6000/rs6000.md (abstf2, abstf2+1): Delete define_insn.
	(abstf2, abstf2_internal): New define_expand.

powerpc64-linux bootstrap and regression test in progress.

Index: gcc/config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.296
diff -c -p -r1.296 rs6000.md
*** gcc/config/rs6000/rs6000.md	27 Feb 2004 02:13:59 -0000	1.296
--- gcc/config/rs6000/rs6000.md	3 Mar 2004 15:04:29 -0000
***************
*** 8375,8409 ****
    [(set_attr "type" "fp")
     (set_attr "length" "8")])
  
! (define_insn "abstf2"
    [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
  	(abs:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
    "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
!   "*
  {
!   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
!     return \"fabs %L0,%L1\;fabs %0,%1\";
!   else
!     return \"fabs %0,%1\;fabs %L0,%L1\";
! }"
!   [(set_attr "type" "fp")
!    (set_attr "length" "8")])
  
! (define_insn ""
    [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
! 	(neg:TF (abs:TF (match_operand:TF 1 "gpc_reg_operand" "f"))))]
    "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
!   "*
  {
!   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
!     return \"fnabs %L0,%L1\;fnabs %0,%1\";
!   else
!     return \"fnabs %0,%1\;fnabs %L0,%L1\";
! }"
!   [(set_attr "type" "fp")
!    (set_attr "length" "8")])
  \f
  ;; Next come the multi-word integer load and store and the load and store
  ;; multiple insns.
--- 8376,8415 ----
    [(set_attr "type" "fp")
     (set_attr "length" "8")])
  
! (define_expand "abstf2"
    [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
  	(abs:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
    "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
!   "
  {
!   rtx label = gen_label_rtx ();
!   emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
!   emit_label (label);
!   DONE;
! }")
  
! (define_expand "abstf2_internal"
    [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
! 	(match_operand:TF 1 "gpc_reg_operand" "f"))
!    (set (match_dup 3) (abs:DF (match_dup 5)))
!    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
!    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
! 			   (label_ref (match_operand 2 "" ""))
! 			   (pc)))
!    (set (match_dup 5) (abs:DF (match_dup 5)))
!    (set (match_dup 6) (neg:DF (match_dup 6)))]
    "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
     && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
!   "
  {
!   const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
!   const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
!   operands[3] = gen_reg_rtx (DFmode);
!   operands[4] = gen_reg_rtx (CCFPmode);
!   operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
!   operands[6] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word);
! }")
  \f
  ;; Next come the multi-word integer load and store and the load and store
  ;; multiple insns.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
* Fix libjava failure on powerpc64-linux
@ 2004-02-10 11:42 Alan Modra
  2004-02-10 12:34 ` Andrew Haley
  2004-02-21 13:45 ` Alan Modra
  0 siblings, 2 replies; 875+ messages in thread
From: Alan Modra @ 2004-02-10 11:42 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Haley, David Edelsohn

I finally found out why powerpc64 libjava tests were failing (See
http://gcc.gnu.org/ml/gcc-patches/2004-01/msg02462.html), and would have
a lot sooner if the sigaction syscall return value had been checked.
The powerpc64 linux kernel only provides a sigaction call for 32 bit
processes, something I wasn't aware of.  64 bit processes are supposed
to use rt_sigaction, so the syscall didn't manage to install a handler.

gcc/ChangeLog
	* config/rs6000/linux64.h (MD_FALLBACK_FRAME_STATE_FOR): Don't
	bump retaddr here.

libjava/ChangeLog
	* include/powerpc-signal.h: Revert 2004-01-21 change.
	(INIT_SEGV, INIT_FPE): Provide powerpc64 versions.  Check return
	from syscall for ppc32 versions.

I used an illegal instruction to bomb on syscall failure rather than
an abort, because abort in libjava doesn't do anything fancy, just
prints "Aborted" and exits.  I like sigill because core dumps from a
sigill give you the reg set at the point of failure, instead of having
to look back up the call stack, which can be tedious when gdb doesn't
happen to work too well on your target.  Maybe I should use _Jv_abort
here?

Regtested powerpc64-linux.  OK mainline and 3.4?

Index: gcc/config/rs6000/linux64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/linux64.h,v
retrieving revision 1.57
diff -u -p -r1.57 linux64.h
--- gcc/config/rs6000/linux64.h	3 Feb 2004 00:40:26 -0000	1.57
+++ gcc/config/rs6000/linux64.h	10 Feb 2004 10:22:36 -0000
@@ -643,15 +649,9 @@ enum { SIGNAL_FRAMESIZE = 64 };
     (FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset 			\
       = (long)&(sc_->regs->link) - new_cfa_;				\
 									\
-    /* The unwinder expects the IP to point to the following insn,	\
-       whereas the kernel returns the address of the actual		\
-       faulting insn. We store NIP+4 in an unused register slot to	\
-       get the same result for multiple evaluation of the same signal	\
-       frame.  */							\
-    sc_->regs->gpr[47] = sc_->regs->nip + 4;  				\
     (FS)->regs.reg[ARG_POINTER_REGNUM].how = REG_SAVED_OFFSET;		\
     (FS)->regs.reg[ARG_POINTER_REGNUM].loc.offset 			\
-      = (long)&(sc_->regs->gpr[47]) - new_cfa_;				\
+      = (long)&(sc_->regs->nip) - new_cfa_;				\
     (FS)->retaddr_column = ARG_POINTER_REGNUM;				\
     goto SUCCESS;							\
   } while (0)
Index: libjava/include/powerpc-signal.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/include/powerpc-signal.h,v
retrieving revision 1.3
diff -u -p -w -r1.3 powerpc-signal.h
--- libjava/include/powerpc-signal.h	23 Jan 2004 17:32:16 -0000	1.3
+++ libjava/include/powerpc-signal.h	10 Feb 2004 10:41:45 -0000
@@ -13,8 +13,6 @@ details.  */
 #ifndef JAVA_SIGNAL_H
 # define JAVA_SIGNAL_H 1
 
-# ifndef __powerpc64__
-
 #  include <signal.h>
 #  include <sys/syscall.h>
 
@@ -53,6 +51,7 @@ while (0)
    compatibility hacks in MAKE_THROW_FRAME, as the ucontext layout
    on PPC changed during the 2.5 kernel series.  */
 
+#ifndef __powerpc64__
 struct kernel_old_sigaction {
   void (*k_sa_handler) (int, struct sigcontext *);
   unsigned long k_sa_mask;
@@ -67,7 +66,8 @@ do									\
     kact.k_sa_handler = catch_segv;					\
     kact.k_sa_mask = 0;							\
     kact.k_sa_flags = 0;						\
-    syscall (SYS_sigaction, SIGSEGV, &kact, NULL);			\
+    if (syscall (SYS_sigaction, SIGSEGV, &kact, NULL) != 0)		\
+      __asm__ __volatile__ (".long 0");					\
   }									\
 while (0)  
 
@@ -78,17 +78,42 @@ do									\
     kact.k_sa_handler = catch_fpe;					\
     kact.k_sa_mask = 0;							\
     kact.k_sa_flags = 0;						\
-    syscall (SYS_sigaction, SIGFPE, &kact, NULL);			\
+    if (syscall (SYS_sigaction, SIGFPE, &kact, NULL) != 0)		\
+      __asm__ __volatile__ (".long 0");					\
   }									\
 while (0)
 
-# else
+#else /* powerpc64 */
 
-#  undef HANDLE_SEGV
-#  undef HANDLE_FPE
+struct kernel_sigaction
+{
+  void (*k_sa_handler) (int, struct sigcontext *);
+  unsigned long k_sa_flags;
+  void (*k_sa_restorer)(void);
+  unsigned long k_sa_mask;
+};
+
+#define INIT_SEGV							\
+do									\
+  {									\
+    struct kernel_sigaction kact;					\
+    memset (&kact, 0, sizeof (kact));					\
+    kact.k_sa_handler = catch_segv;					\
+    if (syscall (SYS_rt_sigaction, SIGSEGV, &kact, NULL, 8) != 0)	\
+      __asm__ __volatile__ (".long 0");					\
+  }									\
+while (0)  
 
-#  define INIT_SEGV   do {} while (0)
-#  define INIT_FPE   do {} while (0)
+#define INIT_FPE							\
+do									\
+  {									\
+    struct kernel_sigaction kact;					\
+    memset (&kact, 0, sizeof (kact));					\
+    kact.k_sa_handler = catch_fpe;					\
+    if (syscall (SYS_rt_sigaction, SIGFPE, &kact, NULL, 8) != 0)	\
+      __asm__ __volatile__ (".long 0");					\
+  }									\
+while (0)
 # endif
 
 #endif /* JAVA_SIGNAL_H */

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
[parent not found: <20040108000828.GQ2533@bubble.modra.org>]
[parent not found: <OFEA5CA921.302AEEB5-ON41256E00.005FB141@de.ibm.com>]
* Re: [PATCH] - Use of powerpc 64bit instructions in 32bit ABI
@ 2003-10-24 13:52 Ulrich Weigand
  2003-10-24 17:32 ` David Edelsohn
  0 siblings, 1 reply; 875+ messages in thread
From: Ulrich Weigand @ 2003-10-24 13:52 UTC (permalink / raw)
  To: Fariborz Jahanian
  Cc: David Edelsohn, Richard Henderson, ian, davem, gcc-patches


Fariborz Jahanian wrote:

>Yes. The very early apple's implementation assumed word_mode == DImode
>and emit_group{load/store} just work by
>using PARALLEL for function arguments/return values to register pairs.
>Problem started arising in other parts of
>the compiler;  which uses word_mode==DImode to figure out, for example,
>number of registers used in passing
>structure-by-value; with register size remaining 32-bit.

Could you elaborate what the problem with struct-by-value was?
This appears to work fine for me by returning false from
FUNCTION_ARG_PASS_BY_REFERENCE and then returning a PARALLEL
from FUNCTION_ARG for that struct parameter.



Mit freundlichen Gruessen / Best Regards

Ulrich Weigand

--
  Dr. Ulrich Weigand
  Linux for S/390 Design & Development
  IBM Deutschland Entwicklung GmbH, Schoenaicher Str. 220, 71032 Boeblingen
  Phone: +49-7031/16-3727   ---   Email: Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 875+ messages in thread
[parent not found: <20030911193937.GD16280@redhat.com>]
[parent not found: <20030612184851.E41510@forte.austin.ibm.com>]
* [PATCH] powerpc64-linux bi-arch support
@ 2003-05-27 11:58 Jakub Jelinek
  2003-05-27 14:57 ` David Edelsohn
                   ` (3 more replies)
  0 siblings, 4 replies; 875+ messages in thread
From: Jakub Jelinek @ 2003-05-27 11:58 UTC (permalink / raw)
  To: David Edelsohn, Alan Modra, Janis Johnson; +Cc: gcc-patches

Hi!

Below is a forward port of the ppc64-linux bi-arch support.
Similar patch got lots of testing on gcc-3_2-rhl8-branch and some on
gcc-3_3-rhl-branch.
GCC can be configured to support just 32-bit target (configuring for
powerpc-*-linux*), 32-bit and 64-bit target defaulting to 32-bit
(--target powerpc64-*-linux* --with-cpu=default32 (or some specific 32-bit
CPU)) or 32-bit and 64-bit target defaulting to 64-bit
(--target powerpc64-*-linux*).

2003-05-27  Jakub Jelinek  <jakub@redhat.com>
	    Alan Modra  <amodra@bigpond.net.au>

	* config/i386/linux.h (NO_PROFILE_COUNTERS): Define to 1.
	* config/i386/freebsd.h (NO_PROFILE_COUNTERS): Likewise.
	* config/i386/netbsd-elf.h (NO_PROFILE_COUNTERS): Likewise.
	* config/xtensa/xtensa.h (NO_PROFILE_COUTNERS): Likewise.
	* config/darwin.h (NO_PROFILE_COUNTERS): Likewise.
	* final.c (NO_PROFILE_COUNTERS): Define to 0 if not defined.
	(profile_function): Allow NO_PROFILE_COUNTERS to be non-constant.
	* config/rs6000/rs6000.c (output_profile_hook): Likewise.

	* configure.in (powerpc*-*, s390*-*): Set tls_as_opt.
	Pass it to $gcc_cv_as.
	* configure: Rebuilt.

	* config/rs6000/rs6000.c (rs6000_abi_name): Remove initializer.
	(print_operand): Allow TARGET_AIX to be non-constant.
	(rs6000_aix_emit_builtin_unwind_init, rs6000_emit_eh_toc_restore):
	Define unconditionally.
	(rs6000_elf_declare_function_name): New function.
	* config/rs6000/rs6000.md (eh_return): Allow TARGET_AIX to be
	non-constant.
	* config/rs6000/linux64.h [!RS6000_BI_ARCH] (TARGET_64BIT): Define
	to 1.
	(DEFAULT_ARCH64_P, RS6000_BI_ARCH_P): Define.
	[IN_LIBGCC2] (TARGET_64BIT): Define based on whether __powerpc64__
	is defined.
	(TARGET_AIX): Define to 1 if TARGET_64BIT.
	(PROCESSOR_DEFAULT): Remove.
	(TARGET_RELOCATABLE, RS6000_ABI_NAME, INVALID_64BIT,
	INVALID_32BIT, SUBSUBTARGET_OVERRIDE_OPTIONS): Define.
	[RS6000_BI_ARCH] (OVERRIDE_OPTIONS, ASM_FILE_START): Define.
	(ASM_DEFAULT_SPEC, ASM_SPEC, LINK_OS_LINUX_SPEC): Define for both
	-m32 and -m64.
	(MULTILIB_DEFAULTS): Define.
	(SUBSUBTARGET_EXTRA_SPECS): Define.
	(ASM_SPEC32, ASM_SPEC64, ASM_SPEC_COMMON): Define.
	(TARGET_TOC): Define only if !RS6000_BI_ARCH.
	(TARGET_NO_TOC): Remove.
	[!RS6000_BI_ARCH] (TARGET_RELOCATABLE, TARGET_EABI,
	TARGET_PROTOTYPE): Define to 0.
	(NO_PROFILE_COUNTERS): Define to TARGET_64BIT.
	(PROFILE_HOOK): Only call output_profile_hook if TARGET_64BIT.
	(ADJUST_FIELD_ALIGN, ROUND_TYPE_ALIGN): Adjust to work properly
	if !TARGET_64BIT.
	(USER_LABEL_PREFIX): Remove.
	(JUMP_TABLES_IN_TEXT_SECTION): Define to TARGET_64BIT.
	(SETUP_FRAME_ADDRESSES): Only call rs6000_aix_emit_builtin_unwind_init
	if TARGET_64BIT.
	(TARGET_OS_CPP_BUILTINS): Handle both -m32 and -m64.
	(LINK_OS_LINUX_SPEC32, LINK_OS_LINUX_SPEC64): Define.
	(STARTFILE_LINUX_SPEC, ENDFILE_LINUX_SPEC): Remove.
	(TOC_SECTION_ASM_OP): Define depending on TARGET_64BIT.
	(MINIMAL_TOC_SECTION_ASM_OP): Likewise.
	(SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE): Define depending on
	TARGET_64BIT.
	(RS6000_CALL_GLUE): Likewise.
	(SAVE_FP_PREFIX, SAVE_FP_SUFFIX, RESTORE_FP_PREFIX,
	RESTORE_FP_SUFFIX): Likewise.
	(ASM_DECLARE_FUNCTION_NAME): Remove.
	(ASM_DECLARE_FUNCTION_SIZE, ASM_OUTPUT_SOURCE_LINE,
	DBX_OUTPUT_BRAC, DBX_OUTPUT_NFUN): Only output dot before function
	name if TARGET_64BIT.
	(ASM_OUTPUT_SPECIAL_POOL_ENTRY_P): Handle both TARGET_64BIT and
	!TARGET_64BIT.
	(ASM_OUTPUT_REG_PUSH, ASM_OUTPUT_REG_POP): Remove undefs.
	(ASM_PREFERRED_EH_DATA_FORMAT): Take TARGET_64BIT into account.
	(DRAFT_V4_STRUCT_RET): Define.
	(SIGNAL_FRAMESIZE): New enum value.
	(MD_FALLBACK_FRAME_STATE_FOR): Define.
	* config/rs6000/default64.h: New file.
	* config/rs6000/sysv4.h (SUBTARGET_SWITCHES): Add -m32 and -m64
	options.
	(SUBTARGET_OVERRIDE_OPTIONS): If rs6000_abi_name is NULL, set it
	to RS6000_ABI_NAME.  Only disallow mixing of -fPIC with -mcall-aixdesc
	if !TARGET_64BIT.
	[!RS6000_BI_ARCH] (SUBSUBTARGET_OVERRIDE_OPTIONS): Define.
	(ASM_DECLARE_FUNCTION_NAME): Use rs6000_elf_declare_function_name
	function.
	(TARGET_OS_SYSV_CPP_BUILTINS): Define.
	(TARGET_OS_CPP_BUILTINS): Use it.
	(CPP_SYSV_SPEC): Remove.
	(CPP_SPEC): Remove cpp_sysv.
	(SUBTARGET_EXTRA_SPECS): Remove cpp_sysv.
	Add SUBSUBTARGET_EXTRA_SPECS.
	(SUBSUBTARGET_EXTRA_SPECS): Define.
	* config/rs6000/biarch64.h: New file.
	* config/rs6000/rs6000-protos.h (rs6000_elf_declare_function_name):
	New prototype.
	* config/rs6000/x-linux64: New file.
	* config/rs6000/t-linux64: Build -m64, -m32 and -m32 -msoft-float
	multilibs.
	* config/rs6000/eabi-ci.asm: Protect with #ifndef __powerpc64__.
	* config/rs6000/eabi-cn.asm: Likewise.
	* config/rs6000/tramp.asm: Likewise.
	* config/rs6000/sol-ci.asm: Likewise.
	* config/rs6000/sol-cn.asm: Likewise.
	* config/rs6000/linux.h (TARGET_64BIT): Define to 0.
	(TARGET_OS_CPP_BUILTINS): Use TARGET_OS_SYSV_CPP_BUILTINS.
	* config/rs6000/ppc-asm.h: Move __powerpc64__ section before
	_CALL_AIXDESC section.
	* config.gcc (powerpc64-*-linux*): Configure a bi-arch compiler,
	defaulting to -m64 unless --with-cpu= is one of the 32-bit CPUs
	or default32.

--- gcc/config/darwin.h.jj	2003-05-26 17:20:11.000000000 -0400
+++ gcc/config/darwin.h	2003-05-26 19:17:04.000000000 -0400
@@ -310,7 +310,7 @@ do { text_section ();							\
 
 /* Our profiling scheme doesn't LP labels and counter words.  */
 
-#define NO_PROFILE_COUNTERS
+#define NO_PROFILE_COUNTERS	1
 
 #undef	INIT_SECTION_ASM_OP
 #define INIT_SECTION_ASM_OP
--- gcc/config/i386/linux.h.jj	2003-05-26 17:20:11.000000000 -0400
+++ gcc/config/i386/linux.h	2003-05-26 19:17:04.000000000 -0400
@@ -51,7 +51,7 @@ Boston, MA 02111-1307, USA.  */
    To the best of my knowledge, no Linux libc has required the label
    argument to mcount.  */
 
-#define NO_PROFILE_COUNTERS
+#define NO_PROFILE_COUNTERS	1
 
 #undef MCOUNT_NAME
 #define MCOUNT_NAME "mcount"
--- gcc/config/i386/freebsd.h.jj	2003-05-26 17:20:11.000000000 -0400
+++ gcc/config/i386/freebsd.h	2003-05-26 19:17:04.000000000 -0400
@@ -43,7 +43,7 @@ Boston, MA 02111-1307, USA.  */
   (TARGET_64BIT ? dbx64_register_map[n] : svr4_dbx_register_map[n])
 
 #undef  NO_PROFILE_COUNTERS
-#define NO_PROFILE_COUNTERS
+#define NO_PROFILE_COUNTERS	1
 
 /* Tell final.c that we don't need a label passed to mcount.  */
 
--- gcc/config/i386/netbsd-elf.h.jj	2003-05-26 17:20:11.000000000 -0400
+++ gcc/config/i386/netbsd-elf.h	2003-05-26 19:17:04.000000000 -0400
@@ -76,7 +76,7 @@ Boston, MA 02111-1307, USA.  */
 /* Output assembler code to FILE to call the profiler.  */
 
 #undef NO_PROFILE_COUNTERS
-#define NO_PROFILE_COUNTERS
+#define NO_PROFILE_COUNTERS	1
 
 #undef FUNCTION_PROFILER
 #define FUNCTION_PROFILER(FILE, LABELNO)				\
--- gcc/config/rs6000/rs6000.c.jj	2003-05-26 17:20:11.000000000 -0400
+++ gcc/config/rs6000/rs6000.c	2003-05-26 19:17:05.000000000 -0400
@@ -124,7 +124,7 @@ int rs6000_pic_labelno;
 
 #ifdef USING_ELFOS_H
 /* Which abi to adhere to */
-const char *rs6000_abi_name = RS6000_ABI_NAME;
+const char *rs6000_abi_name;
 
 /* Semantics of the small data area */
 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
@@ -8660,11 +8660,10 @@ print_operand (file, x, code)
 	      break;
 	    }
 	}
-#if TARGET_AIX
-      RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
-#else
-      assemble_name (file, XSTR (x, 0));
-#endif
+      if (TARGET_AIX)
+	RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
+      else
+	assemble_name (file, XSTR (x, 0));
       return;
 
     case 'Z':
@@ -10565,7 +10564,6 @@ create_TOC_reference (symbol) 
 		 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
 }
 
-#if TARGET_AIX
 /* __throw will restore its own return address to be the same as the
    return address of the function that the throw is being made to.
    This is unfortunate, because we want to check the original
@@ -10693,7 +10691,6 @@ rs6000_emit_eh_toc_restore (stacksize)
   emit_note (NULL, NOTE_INSN_LOOP_END);
   emit_label (loop_exit);
 }
-#endif /* TARGET_AIX */
 \f
 /* This ties together stack memory (MEM with an alias set of
    rs6000_sr_alias_set) and the change to the stack pointer.  */
@@ -12884,20 +12881,24 @@ output_profile_hook (labelno)
 
   if (DEFAULT_ABI == ABI_AIX)
     {
-#ifdef NO_PROFILE_COUNTERS
-      emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
-#else
-      char buf[30];
-      const char *label_name;
-      rtx fun;
+#ifndef NO_PROFILE_COUNTERS
+# define NO_PROFILE_COUNTERS 0
+#endif
+      if (NO_PROFILE_COUNTERS)  
+	emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
+      else
+	{
+	  char buf[30];
+	  const char *label_name;
+	  rtx fun;
 
-      ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
-      label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
-      fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
+	  ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
+	  label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
+	  fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
 
-      emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
-                         fun, Pmode);
-#endif
+	  emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
+			     fun, Pmode);
+	}
     }
   else if (DEFAULT_ABI == ABI_DARWIN)
     {
@@ -13933,6 +13934,79 @@ rs6000_elf_asm_out_destructor (symbol, p
   else
     assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
 }
+
+void
+rs6000_elf_declare_function_name (file, name, decl)
+     FILE *file;
+     const char *name;
+     tree decl;
+{
+  if (TARGET_64BIT)
+    {
+      fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
+      ASM_OUTPUT_LABEL (file, name);
+      fputs (DOUBLE_INT_ASM_OP, file);
+      putc ('.', file);
+      assemble_name (file, name);
+      fputs (",.TOC.@tocbase,0\n\t.previous\n\t.size\t", file);
+      assemble_name (file, name);
+      fputs (",24\n\t.type\t.", file);
+      assemble_name (file, name);
+      fputs (",@function\n", file);
+      if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
+	{
+	  fputs ("\t.globl\t.", file);
+	  assemble_name (file, name);
+	  putc ('\n', file);
+	}
+      ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
+      putc ('.', file);
+      ASM_OUTPUT_LABEL (file, name);
+      return;
+    }
+
+  if (TARGET_RELOCATABLE
+      && (get_pool_size () != 0 || current_function_profile)
+      && uses_TOC())
+    {
+      char buf[256];
+
+      (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
+
+      ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
+      fprintf (file, "\t.long ");
+      assemble_name (file, buf);
+      putc ('-', file);
+      ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
+      assemble_name (file, buf);
+      putc ('\n', file);
+    }
+
+  ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
+  ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
+
+  if (DEFAULT_ABI == ABI_AIX)
+    {
+      const char *desc_name, *orig_name;
+
+      orig_name = (*targetm.strip_name_encoding) (name);
+      desc_name = orig_name;
+      while (*desc_name == '.')
+	desc_name++;
+
+      if (TREE_PUBLIC (decl))
+	fprintf (file, "\t.globl %s\n", desc_name);
+
+      fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
+      fprintf (file, "%s:\n", desc_name);
+      fprintf (file, "\t.long %s\n", orig_name);
+      fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
+      if (DEFAULT_ABI == ABI_AIX)
+	fputs ("\t.long 0\n", file);
+      fprintf (file, "\t.previous\n");
+    }
+  ASM_OUTPUT_LABEL (file, name);
+}
 #endif
 
 #if TARGET_XCOFF
--- gcc/config/rs6000/linux64.h.jj	2003-05-26 17:20:11.000000000 -0400
+++ gcc/config/rs6000/linux64.h	2003-05-26 19:17:56.000000000 -0400
@@ -19,43 +19,163 @@
    Free Software Foundation, 59 Temple Place - Suite 330, Boston,
    MA 02111-1307, USA.  */
 
-/* Yes!  We are AIX! Err. Wait. We're Linux!. No, wait, we're a
-  combo of both!*/
-#undef  DEFAULT_ABI
-#define DEFAULT_ABI ABI_AIX
-
-#undef  TARGET_AIX
-#define TARGET_AIX 1
-
-#undef  TARGET_DEFAULT
-#define TARGET_DEFAULT \
-  (MASK_POWERPC | MASK_POWERPC64 | MASK_64BIT | MASK_NEW_MNEMONICS)
-
-#undef  PROCESSOR_DEFAULT
-#define PROCESSOR_DEFAULT PROCESSOR_PPC630
-#undef  PROCESSOR_DEFAULT64
+#ifndef RS6000_BI_ARCH
+
+#undef	DEFAULT_ABI
+#define	DEFAULT_ABI ABI_AIX
+
+#undef	TARGET_64BIT
+#define	TARGET_64BIT 1
+
+#define	DEFAULT_ARCH64_P 1
+#define	RS6000_BI_ARCH_P 0
+
+#else
+
+#define	DEFAULT_ARCH64_P (TARGET_DEFAULT & MASK_64BIT)
+#define	RS6000_BI_ARCH_P 1
+
+#endif
+
+#ifdef IN_LIBGCC2
+#undef TARGET_64BIT
+#ifdef __powerpc64__
+#define TARGET_64BIT 1
+#else
+#define TARGET_64BIT 0
+#endif
+#endif
+
+#undef	TARGET_AIX
+#define	TARGET_AIX TARGET_64BIT
+
+#undef PROCESSOR_DEFAULT64
 #define PROCESSOR_DEFAULT64 PROCESSOR_PPC630
 
-#undef  ASM_DEFAULT_SPEC
-#define ASM_DEFAULT_SPEC "-mppc64"
+#undef	TARGET_RELOCATABLE
+#define	TARGET_RELOCATABLE (!TARGET_64BIT && (target_flags & MASK_RELOCATABLE))
+
+#undef	RS6000_ABI_NAME
+#define	RS6000_ABI_NAME (TARGET_64BIT ? "aixdesc" : "sysv")
 
+#define INVALID_64BIT "-m%s not supported in this configuration"
+#define INVALID_32BIT INVALID_64BIT
+
+#undef	SUBSUBTARGET_OVERRIDE_OPTIONS
+#define	SUBSUBTARGET_OVERRIDE_OPTIONS				\
+  do								\
+    {								\
+      if (TARGET_64BIT)						\
+	{							\
+	  if (DEFAULT_ABI != ABI_AIX)				\
+	    {							\
+	      DEFAULT_ABI = ABI_AIX;				\
+	      error (INVALID_64BIT, "call");			\
+	    }							\
+	  if (TARGET_RELOCATABLE)				\
+	    {							\
+	      target_flags &= ~MASK_RELOCATABLE;		\
+	      error (INVALID_64BIT, "relocatable");		\
+	    }							\
+	  if (TARGET_EABI)					\
+	    {							\
+	      target_flags &= ~MASK_EABI;			\
+	      error (INVALID_64BIT, "eabi");			\
+	    }							\
+	  if (TARGET_PROTOTYPE)					\
+	    {							\
+	      target_flags &= ~MASK_PROTOTYPE;			\
+	      error (INVALID_64BIT, "prototype");		\
+	    }							\
+	}							\
+      else							\
+	{							\
+	  if (!RS6000_BI_ARCH_P)				\
+	    error (INVALID_32BIT, "32");			\
+	}							\
+    }								\
+  while (0)
+
+#ifdef	RS6000_BI_ARCH
+
+#undef	OVERRIDE_OPTIONS
+#define	OVERRIDE_OPTIONS \
+  rs6000_override_options (((TARGET_DEFAULT ^ target_flags) & MASK_64BIT) \
+			   ? (char *) 0 : TARGET_CPU_DEFAULT)
+
+#undef	ASM_FILE_START
+#define	ASM_FILE_START(FILE)						    \
+  do									    \
+    {                                                                       \
+      output_file_directive ((FILE), main_input_filename);		    \
+      rs6000_file_start (FILE, (((TARGET_DEFAULT ^ target_flags)	    \
+				 & MASK_64BIT)				    \
+				? (char *) 0 : TARGET_CPU_DEFAULT));	    \
+    }									    \
+  while (0)
+
+#endif
+
+#undef	ASM_DEFAULT_SPEC
 #undef	ASM_SPEC
-#define	ASM_SPEC "%{.s: %{mregnames} %{mno-regnames}} \
-%{.S: %{mregnames} %{mno-regnames}} \
-%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian} \
-%{v:-V} %{Qy:} %{!Qn:-Qy} -a64 %(asm_cpu) %{Wa,*:%*}"
+#undef	LINK_OS_LINUX_SPEC
 
-/* This is always a 64 bit compiler.  */
-#undef	TARGET_64BIT
-#define	TARGET_64BIT		1
+#ifndef	RS6000_BI_ARCH
+#define	ASM_DEFAULT_SPEC "-mppc64"
+#define	ASM_SPEC         "%(asm_spec64) %(asm_spec_common)"
+#define	LINK_OS_LINUX_SPEC "%(link_os_linux_spec64)"
+#else
+#if DEFAULT_ARCH64_P
+#define	ASM_DEFAULT_SPEC "-mppc%{!m32:64}"
+#define	ASM_SPEC         "%{m32:%(asm_spec32)}%{!m32:%(asm_spec64)} %(asm_spec_common)"
+#define	LINK_OS_LINUX_SPEC "%{m32:%(link_os_linux_spec32)}%{!m32:%(link_os_linux_spec64)}"
+#else
+#define	ASM_DEFAULT_SPEC "-mppc%{m64:64}"
+#define	ASM_SPEC         "%{!m64:%(asm_spec32)}%{m64:%(asm_spec64)} %(asm_spec_common)"
+#define	LINK_OS_LINUX_SPEC "%{!m64:%(link_os_linux_spec32)}%{m64:%(link_os_linux_spec64)}"
+#endif
+#endif
+
+#define ASM_SPEC32 "-a32 %{n} %{T} %{Ym,*} %{Yd,*} \
+%{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} \
+%{memb} %{!memb: %{msdata: -memb} %{msdata=eabi: -memb}} \
+%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
+    %{mcall-freebsd: -mbig} \
+    %{mcall-i960-old: -mlittle} \
+    %{mcall-linux: -mbig} \
+    %{mcall-gnu: -mbig} \
+    %{mcall-netbsd: -mbig} \
+}}}}"
+
+#define ASM_SPEC64 "-a64"
+
+#define ASM_SPEC_COMMON "%(asm_cpu) \
+%{.s: %{mregnames} %{mno-regnames}} %{.S: %{mregnames} %{mno-regnames}} \
+%{v:-V} %{Qy:} %{!Qn:-Qy} %{Wa,*:%*} \
+%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian}"
+
+#undef	SUBSUBTARGET_EXTRA_SPECS
+#define SUBSUBTARGET_EXTRA_SPECS \
+  { "asm_spec_common",		ASM_SPEC_COMMON },			\
+  { "asm_spec32",		ASM_SPEC32 },				\
+  { "asm_spec64",		ASM_SPEC64 },				\
+  { "link_os_linux_spec32",	LINK_OS_LINUX_SPEC32 },			\
+  { "link_os_linux_spec64",	LINK_OS_LINUX_SPEC64 },
+
+#undef	MULTILIB_DEFAULTS
+#if DEFAULT_ARCH64_P
+#define MULTILIB_DEFAULTS { "m64" }
+#else
+#define MULTILIB_DEFAULTS { "m32" }
+#endif
+
+#ifndef RS6000_BI_ARCH
 
 /* 64-bit PowerPC Linux always has a TOC.  */
-#undef  TARGET_NO_TOC
-#define TARGET_NO_TOC		0
 #undef  TARGET_TOC
 #define	TARGET_TOC		1
 
-/* Some things from sysv4.h we don't do.  */
+/* Some things from sysv4.h we don't do when 64 bit.  */
 #undef	TARGET_RELOCATABLE
 #define	TARGET_RELOCATABLE	0
 #undef	TARGET_EABI
@@ -63,8 +183,9 @@
 #undef	TARGET_PROTOTYPE
 #define	TARGET_PROTOTYPE	0
 
-/* Reuse sysv4 mask bits we made available above.  */
-#define	MASK_PROFILE_KERNEL	0x08000000
+#endif
+
+#define	MASK_PROFILE_KERNEL	0x00080000
 
 /* Non-standard profiling for kernels, which just saves LR then calls
    _mcount without worrying about arg saves.  The idea is to change
@@ -73,88 +194,62 @@
 #define TARGET_PROFILE_KERNEL	(target_flags & MASK_PROFILE_KERNEL)
 
 /* Override sysv4.h.  */
-#undef	SUBTARGET_SWITCHES
-#define SUBTARGET_SWITCHES						\
-  {"bit-align",	-MASK_NO_BITFIELD_TYPE,					\
-    N_("Align to the base type of the bit-field") },			\
-  {"no-bit-align",	 MASK_NO_BITFIELD_TYPE,				\
-    N_("Don't align to the base type of the bit-field") },		\
-  {"strict-align",	 MASK_STRICT_ALIGN,				\
-    N_("Don't assume that unaligned accesses are handled by the system") }, \
-  {"no-strict-align",	-MASK_STRICT_ALIGN,				\
-    N_("Assume that unaligned accesses are handled by the system") },	\
-  {"little-endian",	 MASK_LITTLE_ENDIAN,				\
-    N_("Produce little endian code") },					\
-  {"little",		 MASK_LITTLE_ENDIAN,				\
-    N_("Produce little endian code") },					\
-  {"big-endian",	-MASK_LITTLE_ENDIAN,				\
-    N_("Produce big endian code") },					\
-  {"big",		-MASK_LITTLE_ENDIAN,				\
-    N_("Produce big endian code") },					\
-  {"bit-word",		-MASK_NO_BITFIELD_WORD,				\
-    N_("Allow bit-fields to cross word boundaries") },			\
-  {"no-bit-word",	 MASK_NO_BITFIELD_WORD,				\
-    N_("Do not allow bit-fields to cross word boundaries") },		\
-  {"regnames",		 MASK_REGNAMES,					\
-    N_("Use alternate register names") },				\
-  {"no-regnames",	-MASK_REGNAMES,					\
-    N_("Don't use alternate register names") },				\
+#undef	EXTRA_SUBTARGET_SWITCHES
+#define EXTRA_SUBTARGET_SWITCHES					\
   {"profile-kernel",	 MASK_PROFILE_KERNEL,				\
    N_("Call mcount for profiling before a function prologue") },	\
   {"no-profile-kernel",	-MASK_PROFILE_KERNEL,				\
    N_("Call mcount for profiling after a function prologue") },
 
-#undef	SUBTARGET_OPTIONS
-#define	SUBTARGET_OPTIONS
-
-#undef	SUBTARGET_OVERRIDE_OPTIONS
-#define	SUBTARGET_OVERRIDE_OPTIONS {}
-
 /* We use glibc _mcount for profiling.  */
-#define NO_PROFILE_COUNTERS 1
-#define PROFILE_HOOK(LABEL) output_profile_hook (LABEL)
+#define NO_PROFILE_COUNTERS TARGET_64BIT
+#define PROFILE_HOOK(LABEL) \
+  do { if (TARGET_64BIT) output_profile_hook (LABEL); } while (0)
 
 /* We don't need to generate entries in .fixup.  */
 #undef RELOCATABLE_NEEDS_FIXUP
 
-#define USER_LABEL_PREFIX  ""
-
 /* This now supports a natural alignment mode. */
 /* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints.  */
 #undef  ADJUST_FIELD_ALIGN
 #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
-  (TARGET_ALIGN_NATURAL ? (COMPUTED) : \
-  (TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
-	      ? get_inner_array_type (FIELD) \
-	      : TREE_TYPE (FIELD)) == DFmode \
-   ? MIN ((COMPUTED), 32) : (COMPUTED)))
+  ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE)	\
+   ? 128								\
+   : (TARGET_64BIT							\
+      && TARGET_ALIGN_NATURAL == 0					\
+      && TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE		\
+		    ? get_inner_array_type (FIELD)			\
+		    : TREE_TYPE (FIELD)) == DFmode)			\
+   ? MIN ((COMPUTED), 32)						\
+   : (COMPUTED))
 
 /* AIX increases natural record alignment to doubleword if the first
    field is an FP double while the FP fields remain word aligned.  */
 #undef  ROUND_TYPE_ALIGN
-#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED)	\
-  ((TREE_CODE (STRUCT) == RECORD_TYPE			\
-    || TREE_CODE (STRUCT) == UNION_TYPE			\
-    || TREE_CODE (STRUCT) == QUAL_UNION_TYPE)		\
-   && TYPE_FIELDS (STRUCT) != 0				\
-   && TARGET_ALIGN_NATURAL == 0                         \
-   && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode	\
-   ? MAX (MAX ((COMPUTED), (SPECIFIED)), 64)		\
+#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED)		\
+  ((TARGET_ALTIVEC && TREE_CODE (STRUCT) == VECTOR_TYPE)	\
+   ? MAX (MAX ((COMPUTED), (SPECIFIED)), 128)			\
+   : (TARGET_64BIT						\
+      && (TREE_CODE (STRUCT) == RECORD_TYPE			\
+	  || TREE_CODE (STRUCT) == UNION_TYPE			\
+	  || TREE_CODE (STRUCT) == QUAL_UNION_TYPE)		\
+      && TYPE_FIELDS (STRUCT) != 0				\
+      && TARGET_ALIGN_NATURAL == 0				\
+      && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode)		\
+   ? MAX (MAX ((COMPUTED), (SPECIFIED)), 64)			\
    : MAX ((COMPUTED), (SPECIFIED)))
 
 /* Indicate that jump tables go in the text section.  */
 #undef  JUMP_TABLES_IN_TEXT_SECTION
-#define JUMP_TABLES_IN_TEXT_SECTION 1
-
-/* 64-bit PowerPC Linux always has GPR13 fixed.  */
-#define FIXED_R13		1
+#define JUMP_TABLES_IN_TEXT_SECTION TARGET_64BIT
 
 /* __throw will restore its own return address to be the same as the
    return address of the function that the throw is being made to.
    This is unfortunate, because we want to check the original
    return address to see if we need to restore the TOC.
    So we have to squirrel it away with this.  */
-#define SETUP_FRAME_ADDRESSES() rs6000_aix_emit_builtin_unwind_init ()
+#define SETUP_FRAME_ADDRESSES() \
+  do { if (TARGET_64BIT) rs6000_aix_emit_builtin_unwind_init (); } while (0)
 
 /* Override svr4.h  */
 #undef MD_EXEC_PREFIX
@@ -165,17 +260,28 @@
 #define	CPP_SYSV_SPEC ""
 
 #undef  TARGET_OS_CPP_BUILTINS
-#define TARGET_OS_CPP_BUILTINS()            \
-  do                                        \
-    {                                       \
-      builtin_define ("__PPC__");           \
-      builtin_define ("__PPC64__");         \
-      builtin_define ("__powerpc__");       \
-      builtin_define ("__powerpc64__");     \
-      builtin_define ("__PIC__");           \
-      builtin_assert ("cpu=powerpc64");     \
-      builtin_assert ("machine=powerpc64"); \
-    }                                       \
+#define TARGET_OS_CPP_BUILTINS()            		\
+  do							\
+    {							\
+      if (TARGET_64BIT)					\
+	{						\
+	  builtin_define ("__PPC__");			\
+	  builtin_define ("__PPC64__");			\
+	  builtin_define ("__powerpc__");		\
+	  builtin_define ("__powerpc64__");		\
+	  builtin_define ("__PIC__");			\
+	  builtin_assert ("cpu=powerpc64");		\
+	  builtin_assert ("machine=powerpc64");		\
+	}						\
+      else						\
+	{						\
+	  builtin_define_std ("PPC");			\
+	  builtin_define_std ("powerpc");		\
+	  builtin_assert ("cpu=powerpc");		\
+	  builtin_assert ("machine=powerpc");		\
+	  TARGET_OS_SYSV_CPP_BUILTINS ();		\
+	}						\
+    }							\
   while (0)
 
 #undef  CPP_OS_DEFAULT_SPEC
@@ -205,43 +311,40 @@
 #undef	LINK_OS_DEFAULT_SPEC
 #define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
 
-#undef  LINK_OS_LINUX_SPEC
-#define LINK_OS_LINUX_SPEC "-m elf64ppc %{!shared: %{!static: \
+#define LINK_OS_LINUX_SPEC32 "-m elf32ppclinux %{!shared: %{!static: \
   %{rdynamic:-export-dynamic} \
-  %{!dynamic-linker:-dynamic-linker /lib64/ld64.so.1}}}"
+  %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}}}"
 
-#ifdef NATIVE_CROSS
-#define STARTFILE_PREFIX_SPEC "/usr/local/lib64/ /lib64/ /usr/lib64/"
-#endif
-
-#undef  STARTFILE_LINUX_SPEC
-#define STARTFILE_LINUX_SPEC "\
-%{!shared: %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}} crti.o%s \
-%{static:crtbeginT.o%s} \
-%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
-
-#undef  ENDFILE_LINUX_SPEC
-#define ENDFILE_LINUX_SPEC "\
-%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
+#define LINK_OS_LINUX_SPEC64 "-m elf64ppc %{!shared: %{!static: \
+  %{rdynamic:-export-dynamic} \
+  %{!dynamic-linker:-dynamic-linker /lib64/ld64.so.1}}}"
 
 #undef  TOC_SECTION_ASM_OP
-#define TOC_SECTION_ASM_OP "\t.section\t\".toc\",\"aw\""
+#define TOC_SECTION_ASM_OP \
+  (TARGET_64BIT						\
+   ? "\t.section\t\".toc\",\"aw\""			\
+   : "\t.section\t\".got\",\"aw\"")
 
 #undef  MINIMAL_TOC_SECTION_ASM_OP
-#define MINIMAL_TOC_SECTION_ASM_OP "\t.section\t\".toc1\",\"aw\""
+#define MINIMAL_TOC_SECTION_ASM_OP \
+  (TARGET_64BIT						\
+   ? "\t.section\t\".toc1\",\"aw\""			\
+   : ((TARGET_RELOCATABLE || flag_pic)			\
+      ? "\t.section\t\".got2\",\"aw\""			\
+      : "\t.section\t\".got1\",\"aw\""))
 
 #undef  TARGET_VERSION
 #define TARGET_VERSION fprintf (stderr, " (PowerPC64 GNU/Linux)");
 
 /* Must be at least as big as our pointer type.  */
-#undef  SIZE_TYPE
-#define SIZE_TYPE "long unsigned int"
+#undef	SIZE_TYPE
+#define	SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")
 
-#undef  PTRDIFF_TYPE
-#define PTRDIFF_TYPE "long int"
-
-#undef  WCHAR_TYPE
-#define WCHAR_TYPE "int"
+#undef	PTRDIFF_TYPE
+#define	PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
+  
+#undef	WCHAR_TYPE
+#define	WCHAR_TYPE (TARGET_64BIT ? "int" : "long int")
 #undef  WCHAR_TYPE_SIZE
 #define WCHAR_TYPE_SIZE 32
 
@@ -255,51 +358,25 @@
 
 /* PowerPC no-op instruction.  */
 #undef  RS6000_CALL_GLUE
-#define RS6000_CALL_GLUE "nop"
+#define RS6000_CALL_GLUE (TARGET_64BIT ? "nop" : "cror 31,31,31")
 
 #undef  RS6000_MCOUNT
 #define RS6000_MCOUNT "_mcount"
 
 /* FP save and restore routines.  */
 #undef  SAVE_FP_PREFIX
-#define SAVE_FP_PREFIX "._savef"
+#define SAVE_FP_PREFIX (TARGET_64BIT ? "._savef" : "_savefpr_")
 #undef  SAVE_FP_SUFFIX
-#define SAVE_FP_SUFFIX ""
+#define SAVE_FP_SUFFIX (TARGET_64BIT ? "" : "_l")
 #undef  RESTORE_FP_PREFIX
-#define RESTORE_FP_PREFIX "._restf"
+#define RESTORE_FP_PREFIX (TARGET_64BIT ? "._restf" : "_restfpr_")
 #undef  RESTORE_FP_SUFFIX
-#define RESTORE_FP_SUFFIX ""
+#define RESTORE_FP_SUFFIX (TARGET_64BIT ? "" : "_l")
 
 /* Dwarf2 debugging.  */
 #undef  PREFERRED_DEBUGGING_TYPE
 #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
 
-#undef  ASM_DECLARE_FUNCTION_NAME
-#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)			\
-  do									\
-    {									\
-      fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", (FILE));	\
-      ASM_OUTPUT_LABEL ((FILE), (NAME));				\
-      fputs (DOUBLE_INT_ASM_OP, (FILE));				\
-      putc ('.', (FILE));						\
-      assemble_name ((FILE), (NAME));					\
-      fputs (",.TOC.@tocbase,0\n\t.previous\n\t.size\t", (FILE));	\
-      assemble_name ((FILE), (NAME));					\
-      fputs (",24\n\t.type\t.", (FILE));				\
-      assemble_name ((FILE), (NAME));					\
-      fputs (",@function\n", (FILE));					\
-      if (TREE_PUBLIC (DECL) && ! DECL_WEAK (DECL))			\
-        {								\
-	  fputs ("\t.globl\t.", (FILE));				\
-	  assemble_name ((FILE), (NAME));				\
-	  putc ('\n', (FILE));						\
-        }								\
-      ASM_DECLARE_RESULT ((FILE), DECL_RESULT (DECL));			\
-      putc ('.', (FILE));						\
-      ASM_OUTPUT_LABEL ((FILE), (NAME));				\
-    }									\
-  while (0)
-
 /* This is how to declare the size of a function.  */
 #undef	ASM_DECLARE_FUNCTION_SIZE
 #define	ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)			\
@@ -307,9 +384,13 @@
     {									\
       if (!flag_inhibit_size_directive)					\
 	{								\
-	  fputs ("\t.size\t.", (FILE));					\
+	  fputs ("\t.size\t", (FILE));					\
+	  if (TARGET_64BIT)						\
+	    putc ('.', (FILE));						\
 	  assemble_name ((FILE), (FNAME));				\
-	  fputs (",.-.", (FILE));					\
+	  fputs (",.-", (FILE));					\
+	  if (TARGET_64BIT)						\
+	    putc ('.', (FILE));						\
 	  assemble_name ((FILE), (FNAME));				\
 	  putc ('\n', (FILE));						\
 	}								\
@@ -336,10 +417,16 @@
        || (GET_CODE (X) == CONST_INT 					\
 	   && GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode))	\
        || (GET_CODE (X) == CONST_DOUBLE					\
-	   && (TARGET_POWERPC64						\
-	       || TARGET_MINIMAL_TOC					\
-	       || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT		\
-		   && ! TARGET_NO_FP_IN_TOC)))))
+	   && ((TARGET_64BIT						\
+		&& (TARGET_POWERPC64					\
+		    || TARGET_MINIMAL_TOC				\
+		    || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT	\
+			&& ! TARGET_NO_FP_IN_TOC)))			\
+	       || (!TARGET_64BIT					\
+		   && !TARGET_NO_FP_IN_TOC				\
+		   && !TARGET_RELOCATABLE				\
+		   && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT	\
+		   && BITS_PER_WORD == HOST_BITS_PER_INT)))))
 
 /* This is the same as the dbxelf.h version, except that we need to
    use the function code label, not the function descriptor.  */
@@ -352,7 +439,9 @@ do									\
     ASM_GENERATE_INTERNAL_LABEL (temp, "LM", sym_lineno);		\
     fprintf (FILE, "\t.stabn 68,0,%d,", LINE);				\
     assemble_name (FILE, temp);						\
-    fputs ("-.", FILE);							\
+    putc ('-', FILE);							\
+    if (TARGET_64BIT)							\
+      putc ('.', FILE);							\
     assemble_name (FILE,						\
 		   XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
     putc ('\n', FILE);							\
@@ -373,7 +462,8 @@ while (0)
 	flab = IDENTIFIER_POINTER (current_function_func_begin_label);	\
       else								\
 	{								\
-	  putc ('.', FILE);						\
+	  if (TARGET_64BIT)						\
+	    putc ('.', FILE);						\
 	  flab = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);	\
 	}								\
       assemble_name (FILE, flab);					\
@@ -390,19 +480,175 @@ while (0)
     {									\
       fprintf (FILE, "%s\"\",%d,0,0,", ASM_STABS_OP, N_FUN);		\
       assemble_name (FILE, LSCOPE);					\
-      fputs ("-.", FILE);						\
+      putc ('-', FILE);							\
+      if (TARGET_64BIT)							\
+        putc ('.', FILE);						\
       assemble_name (FILE, XSTR (XEXP (DECL_RTL (DECL), 0), 0));	\
       putc ('\n', FILE);						\
     }									\
   while (0)
 
-/* Override sysv4.h as these are ABI_V4 only.  */
-#undef	ASM_OUTPUT_REG_PUSH
-#undef	ASM_OUTPUT_REG_POP
-
 /* Select a format to encode pointers in exception handling data.  CODE
    is 0 for data, 1 for code labels, 2 for function pointers.  GLOBAL is
    true if the symbol may be affected by dynamic relocations.  */
 #undef	ASM_PREFERRED_EH_DATA_FORMAT
 #define	ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
-  (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_udata8)
+  ((TARGET_64BIT || flag_pic || TARGET_RELOCATABLE)			\
+   ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel		\
+      | (TARGET_64BIT ? DW_EH_PE_udata8 : DW_EH_PE_sdata4))		\
+   : DW_EH_PE_absptr)
+
+/* For backward compatibility, we must continue to use the AIX
+   structure return convention.  */
+#undef DRAFT_V4_STRUCT_RET
+#define DRAFT_V4_STRUCT_RET (!TARGET_64BIT)
+
+/* Do code reading to identify a signal frame, and set the frame
+   state data appropriately.  See unwind-dw2.c for the structs.  */
+
+#ifdef IN_LIBGCC2
+#include <signal.h>
+#include <sys/ucontext.h>
+
+#ifdef __powerpc64__
+enum { SIGNAL_FRAMESIZE = 128 };
+#else
+enum { SIGNAL_FRAMESIZE = 64 };
+#endif
+#endif
+
+#ifdef __powerpc64__
+
+#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
+  do {									\
+    unsigned char *pc_ = (CONTEXT)->ra;					\
+    struct sigcontext *sc_;						\
+    long new_cfa_;							\
+    int i_;								\
+									\
+    /* addi r1, r1, 128; li r0, 0x0077; sc  (sigreturn) */		\
+    /* addi r1, r1, 128; li r0, 0x00AC; sc  (rt_sigreturn) */		\
+    if (*(unsigned int *) (pc_+0) != 0x38210000 + SIGNAL_FRAMESIZE	\
+	|| *(unsigned int *) (pc_+8) != 0x44000002)			\
+      break;								\
+    if (*(unsigned int *) (pc_+4) == 0x38000077)			\
+      {									\
+	struct sigframe {						\
+	  char gap[SIGNAL_FRAMESIZE];					\
+	  struct sigcontext sigctx;					\
+	} *rt_ = (CONTEXT)->cfa;					\
+	sc_ = &rt_->sigctx;						\
+      }									\
+    else if (*(unsigned int *) (pc_+4) == 0x380000AC)			\
+      {									\
+	struct rt_sigframe {						\
+	  int tramp[6];							\
+	  struct siginfo *pinfo;					\
+	  struct ucontext *puc;						\
+	} *rt_ = (struct rt_sigframe *) pc_;				\
+	sc_ = &rt_->puc->uc_mcontext;					\
+      }									\
+    else								\
+      break;								\
+    									\
+    new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM];			\
+    (FS)->cfa_how = CFA_REG_OFFSET;					\
+    (FS)->cfa_reg = STACK_POINTER_REGNUM;				\
+    (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa;		\
+    									\
+    for (i_ = 0; i_ < 32; i_++)						\
+      if (i_ != STACK_POINTER_REGNUM)					\
+	{	    							\
+	  (FS)->regs.reg[i_].how = REG_SAVED_OFFSET;			\
+	  (FS)->regs.reg[i_].loc.offset 				\
+	    = (long)&(sc_->regs->gpr[i_]) - new_cfa_;			\
+	}								\
+									\
+    (FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET;	\
+    (FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset 			\
+      = (long)&(sc_->regs->link) - new_cfa_;				\
+									\
+    /* The unwinder expects the IP to point to the following insn,	\
+       whereas the kernel returns the address of the actual		\
+       faulting insn. We store NIP+4 in an unused register slot to	\
+       get the same result for multiple evaluation of the same signal	\
+       frame.  */							\
+    sc_->regs->gpr[47] = sc_->regs->nip + 4;  				\
+    (FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET;			\
+    (FS)->regs.reg[CR0_REGNO].loc.offset 				\
+      = (long)&(sc_->regs->gpr[47]) - new_cfa_;				\
+    (FS)->retaddr_column = CR0_REGNO;					\
+    goto SUCCESS;							\
+  } while (0)
+
+#else
+
+#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
+  do {									\
+    unsigned char *pc_ = (CONTEXT)->ra;					\
+    struct sigcontext *sc_;						\
+    long new_cfa_;							\
+    int i_;								\
+									\
+    /* li r0, 0x7777; sc  (sigreturn old)  */				\
+    /* li r0, 0x0077; sc  (sigreturn new)  */				\
+    /* li r0, 0x6666; sc  (rt_sigreturn old)  */			\
+    /* li r0, 0x00AC; sc  (rt_sigreturn new)  */			\
+    if (*(unsigned int *) (pc_+4) != 0x44000002)			\
+      break;								\
+    if (*(unsigned int *) (pc_+0) == 0x38007777				\
+	|| *(unsigned int *) (pc_+0) == 0x38000077)			\
+      {									\
+	struct sigframe {						\
+	  char gap[SIGNAL_FRAMESIZE];					\
+	  struct sigcontext sigctx;					\
+	} *rt_ = (CONTEXT)->cfa;					\
+	sc_ = &rt_->sigctx;						\
+      }									\
+    else if (*(unsigned int *) (pc_+0) == 0x38006666			\
+	     || *(unsigned int *) (pc_+0) == 0x380000AC)		\
+      {									\
+	struct rt_sigframe {						\
+	  char gap[SIGNAL_FRAMESIZE];					\
+	  unsigned long _unused[2];					\
+	  struct siginfo *pinfo;					\
+	  void *puc;							\
+	  struct siginfo info;						\
+	  struct ucontext uc;						\
+	} *rt_ = (CONTEXT)->cfa;					\
+	sc_ = &rt_->uc.uc_mcontext;					\
+      }									\
+    else								\
+      break;								\
+    									\
+    new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM];			\
+    (FS)->cfa_how = CFA_REG_OFFSET;					\
+    (FS)->cfa_reg = STACK_POINTER_REGNUM;				\
+    (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa;		\
+    									\
+    for (i_ = 0; i_ < 32; i_++)						\
+      if (i_ != STACK_POINTER_REGNUM)					\
+	{	    							\
+	  (FS)->regs.reg[i_].how = REG_SAVED_OFFSET;			\
+	  (FS)->regs.reg[i_].loc.offset 				\
+	    = (long)&(sc_->regs->gpr[i_]) - new_cfa_;			\
+	}								\
+									\
+    (FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET;	\
+    (FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset 			\
+      = (long)&(sc_->regs->link) - new_cfa_;				\
+									\
+    /* The unwinder expects the IP to point to the following insn,	\
+       whereas the kernel returns the address of the actual		\
+       faulting insn. We store NIP+4 in an unused register slot to	\
+       get the same result for multiple evaluation of the same signal	\
+       frame.  */							\
+    sc_->regs->gpr[47] = sc_->regs->nip + 4;  				\
+    (FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET;			\
+    (FS)->regs.reg[CR0_REGNO].loc.offset 				\
+      = (long)&(sc_->regs->gpr[47]) - new_cfa_;				\
+    (FS)->retaddr_column = CR0_REGNO;					\
+    goto SUCCESS;							\
+  } while (0)
+
+#endif
--- gcc/config/rs6000/rs6000.md.jj	2003-05-26 17:20:12.000000000 -0400
+++ gcc/config/rs6000/rs6000.md	2003-05-26 19:17:05.000000000 -0400
@@ -14581,9 +14581,8 @@
   ""
   "
 {
-#if TARGET_AIX
-  rs6000_emit_eh_toc_restore (EH_RETURN_STACKADJ_RTX);
-#endif
+  if (TARGET_AIX)
+    rs6000_emit_eh_toc_restore (EH_RETURN_STACKADJ_RTX);
   if (TARGET_32BIT)
     emit_insn (gen_eh_set_lr_si (operands[0]));
   else
--- gcc/config/rs6000/default64.h.jj	2003-05-26 19:17:05.000000000 -0400
+++ gcc/config/rs6000/default64.h	2003-05-26 19:17:05.000000000 -0400
@@ -0,0 +1,24 @@
+/* Definitions of target machine for GNU compiler,
+   for 64 bit powerpc linux defaulting to -m64.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT \
+  (MASK_POWERPC | MASK_POWERPC64 | MASK_64BIT | MASK_NEW_MNEMONICS)
--- gcc/config/rs6000/sysv4.h.jj	2003-05-26 17:20:12.000000000 -0400
+++ gcc/config/rs6000/sysv4.h	2003-05-26 19:17:05.000000000 -0400
@@ -149,6 +149,10 @@ extern const char *rs6000_tls_size_strin
     N_("Set the PPC_EMB bit in the ELF flags header") },		\
   { "windiss",           0, N_("Use the WindISS simulator") },          \
   { "shlib",		 0, N_("no description yet") },			\
+  { "64",		 MASK_64BIT | MASK_POWERPC64 | MASK_POWERPC,	\
+			 N_("Generate 64-bit code") },			\
+  { "32",		 - (MASK_64BIT | MASK_POWERPC64),		\
+			 N_("Generate 32-bit code") },			\
   EXTRA_SUBTARGET_SWITCHES						\
   { "newlib",		 0, N_("no description yet") },
 
@@ -172,6 +176,9 @@ do {									\
   if (!g_switch_set)							\
     g_switch_value = SDATA_DEFAULT_SIZE;				\
 									\
+  if (rs6000_abi_name == NULL)						\
+    rs6000_abi_name = RS6000_ABI_NAME;					\
+									\
   if (!strcmp (rs6000_abi_name, "sysv"))				\
     rs6000_current_abi = ABI_V4;					\
   else if (!strcmp (rs6000_abi_name, "sysv-noeabi"))			\
@@ -274,7 +281,7 @@ do {									\
 	     rs6000_abi_name);						\
     }									\
 									\
-  if (flag_pic > 1 && rs6000_current_abi == ABI_AIX)			\
+  if (!TARGET_64BIT && flag_pic > 1 && rs6000_current_abi == ABI_AIX)	\
     {									\
       flag_pic = 0;							\
       error ("-fPIC and -mcall-%s are incompatible",			\
@@ -293,9 +300,16 @@ do {									\
 									\
   else if (TARGET_RELOCATABLE)						\
     flag_pic = 2;							\
-									\
 } while (0)
 
+#ifndef RS6000_BI_ARCH
+# define SUBSUBTARGET_OVERRIDE_OPTIONS					\
+do {									\
+  if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)			\
+    error ("-m%s not supported in this configuration",			\
+	   (target_flags & MASK_64BIT) ? "64" : "32");			\
+} while (0)
+#endif
 
 /* Override rs6000.h definition.  */
 #undef	TARGET_DEFAULT
@@ -590,51 +604,7 @@ extern int rs6000_pic_labelno;
 /* Override elfos.h definition.  */
 #undef	ASM_DECLARE_FUNCTION_NAME
 #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)			\
-  do {									\
-    const char *const init_ptr = (TARGET_64BIT) ? ".quad" : ".long";	\
-									\
-    if (TARGET_RELOCATABLE 						\
-	&& (get_pool_size () != 0 || current_function_profile)		\
-	&& uses_TOC())							\
-      {									\
-	char buf[256];							\
-									\
-	(*targetm.asm_out.internal_label) (FILE, "LCL", rs6000_pic_labelno); \
-									\
-	ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);			\
-	fprintf (FILE, "\t%s ", init_ptr);				\
-	assemble_name (FILE, buf);					\
-	putc ('-', FILE);						\
-	ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);	\
-	assemble_name (FILE, buf);					\
-	putc ('\n', FILE);						\
-      }									\
-									\
-    ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function");			\
-    ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL));			\
-									\
-    if (DEFAULT_ABI == ABI_AIX)						\
-      {									\
-	const char *desc_name, *orig_name;				\
-									\
-        orig_name = (*targetm.strip_name_encoding) (NAME);		\
-        desc_name = orig_name;						\
-	while (*desc_name == '.')					\
-	  desc_name++;							\
-									\
-	if (TREE_PUBLIC (DECL))						\
-	  fprintf (FILE, "\t.globl %s\n", desc_name);			\
-									\
-	fprintf (FILE, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);		\
-	fprintf (FILE, "%s:\n", desc_name);				\
-	fprintf (FILE, "\t%s %s\n", init_ptr, orig_name);		\
-	fprintf (FILE, "\t%s _GLOBAL_OFFSET_TABLE_\n", init_ptr);	\
-	if (DEFAULT_ABI == ABI_AIX)					\
-	  fprintf (FILE, "\t%s 0\n", init_ptr);				\
-	fprintf (FILE, "\t.previous\n");				\
-      }									\
-    ASM_OUTPUT_LABEL (FILE, NAME);					\
-  } while (0)
+  rs6000_elf_declare_function_name ((FILE), (NAME), (DECL))
 
 /* The USER_LABEL_PREFIX stuff is affected by the -fleading-underscore
    flag.  The LOCAL_LABEL_PREFIX variable is used by dbxelf.h.  */
@@ -789,6 +759,25 @@ extern int fixuplabelno;
 #define	TARGET_VERSION fprintf (stderr, " (PowerPC System V.4)");
 #endif
 \f
+#define TARGET_OS_SYSV_CPP_BUILTINS()	  \
+  do                                      \
+    {                                     \
+      if (flag_pic == 1)		  \
+        {				  \
+	  builtin_define ("__pic__=1");	  \
+	  builtin_define ("__PIC__=1");	  \
+        }				  \
+      else if (flag_pic == 2)		  \
+        {				  \
+	  builtin_define ("__pic__=2");	  \
+	  builtin_define ("__PIC__=2");	  \
+        }				  \
+      if (target_flags_explicit		  \
+	  & MASK_RELOCATABLE)		  \
+	builtin_define ("_RELOCATABLE");  \
+    }                                     \
+  while (0)
+
 #ifndef	TARGET_OS_CPP_BUILTINS
 #define TARGET_OS_CPP_BUILTINS()          \
   do                                      \
@@ -800,6 +789,7 @@ extern int fixuplabelno;
       builtin_assert ("system=svr4");     \
       builtin_assert ("cpu=powerpc");     \
       builtin_assert ("machine=powerpc"); \
+      TARGET_OS_SYSV_CPP_BUILTINS ();	  \
     }                                     \
   while (0)
 #endif
@@ -945,14 +935,9 @@ extern int fixuplabelno;
 
 #define LINK_OS_DEFAULT_SPEC ""
 
-#define CPP_SYSV_SPEC \
-"%{mrelocatable*: -D_RELOCATABLE} \
-%{fpic: -D__PIC__=1 -D__pic__=1} \
-%{!fpic: %{fPIC: -D__PIC__=2 -D__pic__=2}}"
-
 /* Override rs6000.h definition.  */
 #undef	CPP_SPEC
-#define	CPP_SPEC "%{posix: -D_POSIX_SOURCE} %(cpp_sysv) \
+#define	CPP_SPEC "%{posix: -D_POSIX_SOURCE} \
 %{mads         : %(cpp_os_ads)         ; \
   myellowknife : %(cpp_os_yellowknife) ; \
   mmvme        : %(cpp_os_mvme)        ; \
@@ -1215,7 +1200,6 @@ ncrtn.o%s"
 /* Override rs6000.h definition.  */
 #undef	SUBTARGET_EXTRA_SPECS
 #define	SUBTARGET_EXTRA_SPECS						\
-  { "cpp_sysv",			CPP_SYSV_SPEC },			\
   { "crtsavres_default",        CRTSAVRES_DEFAULT_SPEC },              \
   { "lib_ads",			LIB_ADS_SPEC },				\
   { "lib_yellowknife",		LIB_YELLOWKNIFE_SPEC },			\
@@ -1284,7 +1268,10 @@ ncrtn.o%s"
   { "cpp_os_linux",		CPP_OS_LINUX_SPEC },			\
   { "cpp_os_netbsd",		CPP_OS_NETBSD_SPEC },			\
   { "cpp_os_windiss",           CPP_OS_WINDISS_SPEC },                  \
-  { "cpp_os_default",		CPP_OS_DEFAULT_SPEC },
+  { "cpp_os_default",		CPP_OS_DEFAULT_SPEC },			\
+  SUBSUBTARGET_EXTRA_SPECS
+
+#define	SUBSUBTARGET_EXTRA_SPECS
 
 /* Define this macro as a C expression for the initializer of an
    array of string to tell the driver program which options are
--- gcc/config/rs6000/biarch64.h.jj	2003-05-26 19:17:05.000000000 -0400
+++ gcc/config/rs6000/biarch64.h	2003-05-26 19:17:05.000000000 -0400
@@ -0,0 +1,22 @@
+/* Definitions of target machine for GNU compiler, for 32/64 bit powerpc.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Specify this in a cover file to provide bi-architecture (32/64) support.  */
+#define RS6000_BI_ARCH 1
--- gcc/config/rs6000/rs6000-protos.h.jj	2003-05-26 17:20:11.000000000 -0400
+++ gcc/config/rs6000/rs6000-protos.h	2003-05-26 19:17:05.000000000 -0400
@@ -155,6 +155,8 @@ extern void setup_incoming_varargs PARAM
 extern rtx rs6000_function_value (tree, tree);
 extern struct rtx_def *rs6000_va_arg PARAMS ((tree, tree));
 extern int function_ok_for_sibcall PARAMS ((tree));
+extern void rs6000_elf_declare_function_name
+  PARAMS ((FILE *, const char *, tree));
 #ifdef ARGS_SIZE_RTX
 /* expr.h defines ARGS_SIZE_RTX and `enum direction' */
 extern enum direction function_arg_padding PARAMS ((enum machine_mode, tree));
--- gcc/config/rs6000/x-linux64.jj	2003-05-26 19:17:05.000000000 -0400
+++ gcc/config/rs6000/x-linux64	2003-05-26 19:17:05.000000000 -0400
@@ -0,0 +1,2 @@
+# parts of gcc need more than a 64k TOC.
+X_CFLAGS = -mminimal-toc
--- gcc/config/rs6000/t-linux64.jj	2003-05-26 17:20:12.000000000 -0400
+++ gcc/config/rs6000/t-linux64	2003-05-26 19:17:05.000000000 -0400
@@ -1,19 +1,32 @@
-# Override t-linux.  We don't want -fPIC.
-CRTSTUFF_T_CFLAGS_S =
-TARGET_LIBGCC2_CFLAGS =
+# These functions are needed for soft-float on powerpc64-linux.
+LIB2FUNCS_EXTRA = tramp.S $(srcdir)/config/rs6000/ppc64-fp.c
 
-EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o \
-			crtsavres.o
+# Modify the shared lib version file
+SHLIB_MKMAP_OPTS = -v dotsyms=1
 
-# These functions are needed for soft-float on powerpc64-linux.
-LIB2FUNCS_EXTRA = $(srcdir)/config/rs6000/ppc64-fp.c
+MULTILIB_OPTIONS        = m64/m32 msoft-float
+MULTILIB_DIRNAMES       = 64 32 nof
+MULTILIB_EXTRA_OPTS     = fPIC mstrict-align
+MULTILIB_EXCEPTIONS     = m64/msoft-float
+MULTILIB_EXCLUSIONS     = m64/!m32/msoft-float
+MULTILIB_OSDIRNAMES	= ../lib64 ../lib nof
+MULTILIB_MATCHES        = $(MULTILIB_MATCHES_FLOAT)
 
-# ld provides these functions as needed.
-crtsavres.S:
-	echo >crtsavres.S
+TARGET_LIBGCC2_CFLAGS = -mno-minimal-toc -fPIC
 
-$(T)crtsavres.o: crtsavres.S
-	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtsavres.S -o $(T)crtsavres.o
+# We want fine grained libraries, so use the new code to build the
+# floating point emulation libraries.
+# fp-bit is only to be used by 32-bit multilibs
+FPBIT = fp-bit32.c
+DPBIT = dp-bit32.c
 
-# Modify the shared lib version file
-SHLIB_MKMAP_OPTS = -v dotsyms=1
+dp-bit32.c: $(srcdir)/config/fp-bit.c
+	( echo '#ifndef __powerpc64__'; \
+	  cat $(srcdir)/config/fp-bit.c; \
+	  echo '#endif' ) > dp-bit32.c
+
+fp-bit32.c: $(srcdir)/config/fp-bit.c
+	( echo '#ifndef __powerpc64__'; \
+	  echo '#define FLOAT'; \
+	  cat $(srcdir)/config/fp-bit.c; \
+	  echo '#endif' ) > fp-bit32.c
--- gcc/config/rs6000/eabi-ci.asm.jj	2003-05-26 17:20:11.000000000 -0400
+++ gcc/config/rs6000/eabi-ci.asm	2003-05-26 19:17:05.000000000 -0400
@@ -41,6 +41,7 @@ Boston, MA 02111-1307, USA.
 
 #include <ppc-asm.h>
 
+#ifndef __powerpc64__
 	.section ".got","aw"
 	.globl	__GOT_START__
 	.type	__GOT_START__,@object
@@ -122,3 +123,4 @@ FUNC_START(__fini)
 	stwu 1,-16(1)
 	mflr 0
 	stw 0,20(1)
+#endif
--- gcc/config/rs6000/linux.h.jj	2003-05-26 17:20:11.000000000 -0400
+++ gcc/config/rs6000/linux.h	2003-05-26 19:17:05.000000000 -0400
@@ -32,6 +32,7 @@
       builtin_define_std ("powerpc");     \
       builtin_assert ("cpu=powerpc");     \
       builtin_assert ("machine=powerpc"); \
+      TARGET_OS_SYSV_CPP_BUILTINS ();	  \
     }                                     \
   while (0)
 
@@ -78,6 +79,13 @@
 #undef  DRAFT_V4_STRUCT_RET
 #define DRAFT_V4_STRUCT_RET 1
 
+/* We are 32-bit all the time, so optimize a little.  */
+#undef TARGET_64BIT
+#define TARGET_64BIT 0
+ 
+/* We don't need to generate entries in .fixup.  */
+#undef RELOCATABLE_NEEDS_FIXUP
+
 /* Do code reading to identify a signal frame, and set the frame
    state data appropriately.  See unwind-dw2.c for the structs.  */
 
--- gcc/config/rs6000/eabi-cn.asm.jj	2003-05-26 17:20:11.000000000 -0400
+++ gcc/config/rs6000/eabi-cn.asm	2003-05-26 19:17:05.000000000 -0400
@@ -39,6 +39,7 @@ Boston, MA 02111-1307, USA.
 	.file	"crtn.s"
 	.ident	"GNU C crtn.s"
 
+#ifndef __powerpc64__
 	.section ".got","aw"
 	.globl	__GOT_END__
 	.type	__GOT_END__,@object
@@ -113,3 +114,4 @@ __EH_FRAME_END__:
 	mtlr 0
 	addi 1,1,16
 	blr
+#endif
--- gcc/config/rs6000/tramp.asm.jj	2003-05-26 17:20:12.000000000 -0400
+++ gcc/config/rs6000/tramp.asm	2003-05-26 19:17:05.000000000 -0400
@@ -39,6 +39,7 @@
 	.section ".text"
 	#include "ppc-asm.h"
 
+#ifndef __powerpc64__
 	.type	trampoline_initial,@object
 	.align	2
 trampoline_initial:
@@ -107,3 +108,4 @@ FUNC_START(__trampoline_setup)
 	bl	JUMP_TARGET(abort)
 FUNC_END(__trampoline_setup)
 
+#endif
--- gcc/config/rs6000/sol-ci.asm.jj	2003-05-26 17:20:12.000000000 -0400
+++ gcc/config/rs6000/sol-ci.asm	2003-05-26 19:17:05.000000000 -0400
@@ -39,6 +39,7 @@
 	.file	"scrti.s"
 	.ident	"GNU C scrti.s"
 
+#ifndef __powerpc64__
 # Start of .text
 	.section ".text"
 	.globl	_ex_text0
@@ -102,3 +103,4 @@ _fini:	stwu	%r1,-16(%r1)
 	.space 4
 	.weak	environ
 	.set	environ,_environ
+#endif
--- gcc/config/rs6000/sol-cn.asm.jj	2003-05-26 17:20:12.000000000 -0400
+++ gcc/config/rs6000/sol-cn.asm	2003-05-26 19:17:05.000000000 -0400
@@ -39,6 +39,7 @@
 	.file	"scrtn.s"
 	.ident	"GNU C scrtn.s"
 
+#ifndef __powerpc64__
 # Default versions of exception handling register/deregister
 	.weak	_ex_register
 	.weak	_ex_deregister
@@ -80,3 +81,4 @@ _ex_range1:
 	mtlr	%r0
 	addi	%r1,%r1,16
 	blr
+#endif
--- gcc/config/rs6000/ppc-asm.h.jj	2003-05-26 17:20:11.000000000 -0400
+++ gcc/config/rs6000/ppc-asm.h	2003-05-26 19:17:05.000000000 -0400
@@ -95,21 +95,15 @@
  * the real function with one or two leading periods respectively.
  */
 
-#ifdef _RELOCATABLE
-#define DESC_SECTION ".got2"
-#else
-#define DESC_SECTION ".got1"
-#endif
-
-#if defined(_CALL_AIXDESC)
+#if defined (__powerpc64__)
 #define FUNC_NAME(name) GLUE(.,name)
 #define JUMP_TARGET(name) FUNC_NAME(name)
 #define FUNC_START(name) \
-	.section DESC_SECTION,"aw"; \
+	.section ".opd","aw"; \
 name: \
-	.long GLUE(.,name); \
-	.long _GLOBAL_OFFSET_TABLE_; \
-	.long 0; \
+	.quad GLUE(.,name); \
+	.quad .TOC.@tocbase; \
+	.quad 0; \
 	.previous; \
 	.type GLUE(.,name),@function; \
 	.globl name; \
@@ -120,15 +114,22 @@ GLUE(.,name):
 GLUE(.L,name): \
 	.size GLUE(.,name),GLUE(.L,name)-GLUE(.,name)
 
-#elif defined (__powerpc64__)
+#elif defined(_CALL_AIXDESC)
+
+#ifdef _RELOCATABLE
+#define DESC_SECTION ".got2"
+#else
+#define DESC_SECTION ".got1"
+#endif
+
 #define FUNC_NAME(name) GLUE(.,name)
 #define JUMP_TARGET(name) FUNC_NAME(name)
 #define FUNC_START(name) \
-	.section ".opd","aw"; \
+	.section DESC_SECTION,"aw"; \
 name: \
-	.quad GLUE(.,name); \
-	.quad .TOC.@tocbase; \
-	.quad 0; \
+	.long GLUE(.,name); \
+	.long _GLOBAL_OFFSET_TABLE_; \
+	.long 0; \
 	.previous; \
 	.type GLUE(.,name),@function; \
 	.globl name; \
@@ -140,6 +141,7 @@ GLUE(.L,name): \
 	.size GLUE(.,name),GLUE(.L,name)-GLUE(.,name)
 
 #else
+
 #define FUNC_NAME(name) GLUE(__USER_LABEL_PREFIX__,name)
 #if defined __PIC__ || defined __pic__
 #define JUMP_TARGET(name) FUNC_NAME(name@plt)
@@ -155,4 +157,3 @@ FUNC_NAME(name):
 GLUE(.L,name): \
 	.size FUNC_NAME(name),GLUE(.L,name)-FUNC_NAME(name)
 #endif
-
--- gcc/config/xtensa/xtensa.h.jj	2003-05-26 17:20:12.000000000 -0400
+++ gcc/config/xtensa/xtensa.h	2003-05-26 19:17:05.000000000 -0400
@@ -944,7 +944,7 @@ typedef struct xtensa_args {
    _mcount uses a window size of 8 to make sure that it doesn't clobber
    any incoming argument values. */
 
-#define NO_PROFILE_COUNTERS
+#define NO_PROFILE_COUNTERS	1
 
 #define FUNCTION_PROFILER(FILE, LABELNO) \
   do {									\
--- gcc/config.gcc.jj	2003-05-26 17:20:10.000000000 -0400
+++ gcc/config.gcc	2003-05-26 19:17:05.000000000 -0400
@@ -1566,8 +1566,12 @@ powerpc-*-openbsd*)
 	extra_headers=
 	;;
 powerpc64-*-linux*)
-	tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux64.h"
-	tmake_file="rs6000/t-fprules t-slibgcc-elf-ver t-linux rs6000/t-linux64"
+	tm_file="rs6000/biarch64.h ${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h"
+	case x$with_cpu in
+	x|xpowerpc64|xdefault64) tm_file="${tm_file} rs6000/default64.h";;
+	esac
+	tm_file="${tm_file} rs6000/linux64.h"
+	tmake_file="rs6000/t-fprules t-slibgcc-elf-ver t-linux rs6000/t-ppccomm rs6000/t-linux64"
 	;;
 powerpc64-*-gnu*)
 	tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux64.h rs6000/gnu.h"
@@ -1698,14 +1702,14 @@ rs6000-ibm-aix4.[12]* | powerpc-ibm-aix4
 	extra_headers=
 	;;
 rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*)
-	tm_file="${tm_file} rs6000/aix.h rs6000/aix43.h rs6000/xcoff.h"
+	tm_file="rs6000/biarch64.h ${tm_file} rs6000/aix.h rs6000/aix43.h rs6000/xcoff.h"
 	tmake_file=rs6000/t-aix43
 	use_collect2=yes
 	thread_file='aix'
 	extra_headers=
 	;;
 rs6000-ibm-aix5.1.* | powerpc-ibm-aix5.1.*)
-	tm_file="${tm_file} rs6000/aix.h rs6000/aix51.h rs6000/xcoff.h"
+	tm_file="rs6000/biarch64.h ${tm_file} rs6000/aix.h rs6000/aix51.h rs6000/xcoff.h"
 	tmake_file=rs6000/t-aix43
 	use_collect2=yes
 	thread_file='aix'
@@ -2291,7 +2295,7 @@ powerpc*-*-* | rs6000-*-*)
                 tm_file="$tm_file rs6000/altivec-defs.h"
         fi
 	case "x$with_cpu" in
-		x)
+		x | xdefault32 | xdefault64)
 			;;
 
 		xcommon | xpowerpc | xpowerpc64 \
--- gcc/final.c.jj	2003-05-26 17:20:11.000000000 -0400
+++ gcc/final.c	2003-05-26 19:17:05.000000000 -0400
@@ -1426,7 +1426,7 @@ profile_function (file)
      FILE *file ATTRIBUTE_UNUSED;
 {
 #ifndef NO_PROFILE_COUNTERS
-  int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
+# define NO_PROFILE_COUNTERS	0
 #endif
 #if defined(ASM_OUTPUT_REG_PUSH)
 #if defined(STRUCT_VALUE_INCOMING_REGNUM) || defined(STRUCT_VALUE_REGNUM)
@@ -1437,12 +1437,14 @@ profile_function (file)
 #endif
 #endif /* ASM_OUTPUT_REG_PUSH */
 
-#ifndef NO_PROFILE_COUNTERS
-  data_section ();
-  ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
-  (*targetm.asm_out.internal_label) (file, "LP", current_function_funcdef_no);
-  assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
-#endif
+  if (! NO_PROFILE_COUNTERS)
+    {
+      int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
+      data_section ();
+      ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
+      (*targetm.asm_out.internal_label) (file, "LP", current_function_funcdef_no);
+      assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
+    }
 
   function_section (current_function_decl);
 
--- gcc/configure.in.jj	2003-05-26 17:20:10.000000000 -0400
+++ gcc/configure.in	2003-05-26 19:17:05.000000000 -0400
@@ -2048,6 +2048,7 @@ gcc_cv_as_tls=no
 conftest_s=
 tls_first_major=
 tls_first_minor=
+tls_as_opt=
 case "$target" in
 changequote(,)dnl
   alpha*-*-*)
@@ -2147,6 +2148,7 @@ x3:	.space 4
 	addi 9,9,x2@tprel@l'
 	tls_first_major=2
 	tls_first_minor=14
+	tls_as_opt=-a32
 	;;
   powerpc64-*-*)
     conftest_s='
@@ -2180,6 +2182,7 @@ x3:	.space 8
 	nop'
 	tls_first_major=2
 	tls_first_minor=14
+	tls_as_opt=-a64
 	;;
   s390-*-*)
     conftest_s='
@@ -2198,6 +2201,7 @@ foo:	.long	25
 	bas	%r14,0(%r1,%r13):tls_ldcall:foo'
 	tls_first_major=2
 	tls_first_minor=14
+	tls_as_opt=-m31
 	;;
   s390x-*-*)
     conftest_s='
@@ -2215,6 +2219,7 @@ foo:	.long	25
 	brasl	%r14,__tls_get_offset@PLT:tls_ldcall:foo'
 	tls_first_major=2
 	tls_first_minor=14
+	tls_as_opt="-m64 -Aesame"
 	;;
 esac
 if test -z "$tls_first_major"; then
@@ -2225,7 +2230,7 @@ elif test $in_tree_gas = yes ; then
   ])
 elif test x$gcc_cv_as != x; then
   echo "$conftest_s" > conftest.s
-  if $gcc_cv_as --fatal-warnings -o conftest.o conftest.s > /dev/null 2>&1
+  if $gcc_cv_as $tls_as_opt --fatal-warnings -o conftest.o conftest.s > /dev/null 2>&1
   then
     gcc_cv_as_tls=yes
   fi
--- gcc/configure.jj	2003-05-26 17:20:10.000000000 -0400
+++ gcc/configure	2003-05-26 19:17:05.000000000 -0400
@@ -8123,6 +8123,7 @@ gcc_cv_as_tls=no
 conftest_s=
 tls_first_major=
 tls_first_minor=
+tls_as_opt=
 case "$target" in
   alpha*-*-*)
     conftest_s='
@@ -8220,6 +8221,7 @@ x3:	.space 4
 	addi 9,9,x2@tprel@l'
 	tls_first_major=2
 	tls_first_minor=14
+	tls_as_opt=-a32
 	;;
   powerpc64-*-*)
     conftest_s='
@@ -8253,6 +8255,7 @@ x3:	.space 8
 	nop'
 	tls_first_major=2
 	tls_first_minor=14
+	tls_as_opt=-a64
 	;;
   s390-*-*)
     conftest_s='
@@ -8271,6 +8274,7 @@ foo:	.long	25
 	bas	%r14,0(%r1,%r13):tls_ldcall:foo'
 	tls_first_major=2
 	tls_first_minor=14
+	tls_as_opt=-m31
 	;;
   s390x-*-*)
     conftest_s='
@@ -8288,6 +8292,7 @@ foo:	.long	25
 	brasl	%r14,__tls_get_offset@PLT:tls_ldcall:foo'
 	tls_first_major=2
 	tls_first_minor=14
+	tls_as_opt="-m64 -Aesame"
 	;;
 esac
 if test -z "$tls_first_major"; then
@@ -8305,7 +8310,7 @@ fi
 
 elif test x$gcc_cv_as != x; then
   echo "$conftest_s" > conftest.s
-  if $gcc_cv_as --fatal-warnings -o conftest.o conftest.s > /dev/null 2>&1
+  if $gcc_cv_as $tls_as_opt --fatal-warnings -o conftest.o conftest.s > /dev/null 2>&1
   then
     gcc_cv_as_tls=yes
   fi

	Jakub

^ permalink raw reply	[flat|nested] 875+ messages in thread
* powerpc-unknown-linux-gnu bootstrap fix
@ 2003-05-14 16:25 Matt Kraai
  2003-05-14 17:12 ` David Edelsohn
  0 siblings, 1 reply; 875+ messages in thread
From: Matt Kraai @ 2003-05-14 16:25 UTC (permalink / raw)
  To: gcc-patches

Howdy,

Bootstrap on my powerpc-unknown-linux-gnu failed with the
following output:

 stage1/xgcc -Bstage1/ -B/home/kraai/dev/gcc/inst/powerpc-unknown-linux-gnu/bin/ -c   -g -O2 -DIN_GCC   -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -pedantic -Wno-long-long -Werror -fno-common   -DHAVE_CONFIG_H    -I. -I. -I../../gcc/gcc -I../../gcc/gcc/. -I../../gcc/gcc/config -I../../gcc/gcc/../include ../../gcc/gcc/varasm.c -o varasm.o
 ../../gcc/gcc/varasm.c: In function `asm_emit_uninitialised':
 ../../gcc/gcc/varasm.c:1375: warning: comparison between signed and unsigned
 ../../gcc/gcc/varasm.c:1382: warning: comparison between signed and unsigned
 ../../gcc/gcc/varasm.c: In function `assemble_static_space':
 ../../gcc/gcc/varasm.c:1783: warning: comparison between signed and unsigned
 make[2]: *** [varasm.o] Error 1
 make[2]: Leaving directory `/home/kraai/dev/gcc/bld/gcc'
 make[1]: *** [stage2_build] Error 2
 make[1]: Leaving directory `/home/kraai/dev/gcc/bld/gcc'
 make: *** [bootstrap] Error 2

Applying the appended patch allowed it to proceed.  OK?

-- 
Matt Kraai <kraai@alumni.cmu.edu>
Debian GNU/Linux Peon

       * config/rs6000/sysv4.h (ASM_OUTPUT_ALIGNED_LOCAL): Cast
       g_switch_value to unsigned HOST_WIDE_INT.

*** sysv4.h.~1.126.~	Tue May 13 21:43:03 2003
--- sysv4.h	Wed May 14 07:35:47 2003
***************
*** 666,672 ****
  #define	ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
  do {									\
    if (rs6000_sdata != SDATA_NONE && (SIZE) > 0				\
!       && (SIZE) <= g_switch_value)					\
      {									\
        sbss_section ();							\
        ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT));	\
--- 666,672 ----
  #define	ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
  do {									\
    if (rs6000_sdata != SDATA_NONE && (SIZE) > 0				\
!       && (SIZE) <= (unsigned HOST_WIDE_INT)g_switch_value)		\
      {									\
        sbss_section ();							\
        ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT));	\

^ permalink raw reply	[flat|nested] 875+ messages in thread
* function parms in regs, patch 3 of 3
@ 2003-04-24 15:34 Alan Modra
  0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2003-04-24 15:34 UTC (permalink / raw)
  To: gcc-patches

This patch defines a new macro, BLOCK_REG_PADDING, and uses it to
determine what to do with odd-sized struct pieces in regs.  I wanted
to make use of FUNCTION_ARG_PADDING in its default definition, so
that meant passing TYPE to emit_group_{load,store}.  Anyway, what
this does is allow powerpc64 to pad structs upward, downward and
every which way to our heart's content, in registers, without using
the PARALLELs invented for Irix support.  All controlled in one place,
rs6000.c:function_arg_padding.  Hmm.  It might be a good idea to make
the default PAD_VARARGS_DOWN use FUNCTION_ARG_PADDING too.

The rs6000 code has been tested using AGGREGATE_PADDING_FIXED == 0,
AGGREGATE_PADDING_FIXED == 1 and AGGREGATES_PAD_UPWARD_ALWAYS == 0,
AGGREGATE_PADDING_FIXED == 1 and AGGREGATES_PAD_UPWARD_ALWAYS == 1,
with and without MUST_PASS_IN_STACK redefined.  All seems well.
Of course, redefining MUST_PASS_IN_STACK means that code compiled
with previous versions of gcc might not be compatible with a new
gcc, but I think we need to suffer the pain now so that we're
compliant with the ABI.

	* expr.h (struct locate_and_pad_arg_data): Add where_pad.
	(BLOCK_REG_PADDING): Define.
	(emit_group_load, emit_group_store): Adjust declarations.
	* expr.c (emit_group_load): Add "type" param, and use
	BLOCK_REG_PADDING to determine need for a shift.  Optimize non-
	aligned accesses if !SLOW_UNALIGNED_ACCESS.
	(emit_group_store): Likewise.
	(emit_push_insn, expand_assignment, store_expr, expand_expr): Adjust
	emit_group_load and emit_group_store calls.
	* calls.c (store_unaligned_arguments_into_pseudos): Tidy.  Use
	BLOCK_REG_PADDING to determine whether we need endian_correction.
	(load_register_parameters): Localize vars.  Handle shifting of
	small values to the correct end of regs.  Adjust emit_group_load
	call.
	(expand_call, emit_library_call_value_1): Adjust emit_group_load
	and emit_group_store calls.
	* function.c (assign_parms): Set mem alignment for stack slots.
	Adjust emit_group_store call.  Store values at the "wrong" end
	of regs to the stack.  Use BLOCK_REG_PADDING.
	(locate_and_pad_parm): Save where_pad.
	(expand_function_end): Adjust emit_group_load call.
	* stmt.c (expand_value_return): Adjust emit_group_load call.
	* Makefile.in (calls.o): Depend on $(OPTABS_H).

	* config/rs6000/linux64.h (TARGET_BIG_ENDIAN): Redefine as 1.
	(FIXED_R13): Delete.
	(AGGREGATE_PADDING_FIXED): Define.
	(MUST_PASS_IN_STACK): Define.
	* config/rs6000/rs6000.h (struct rs6000_args): Remove orig_nargs.
	(PAD_VARARGS_DOWN): Define in terms of FUNCTION_ARG_PADDING.
	* config/rs6000/rs6000.c (init_cumulative_args): Don't set orig_nargs.
	(function_arg_padding): !AGGREGATE_PADDING_FIXED compatibility code.
	Act on AGGREGATES_PAD_UPWARD_ALWAYS.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

diff -urp gcc2/gcc/expr.h gcc3/gcc/expr.h
--- gcc2/gcc/expr.h	2003-04-24 15:31:56.000000000 +0930
+++ gcc3/gcc/expr.h	2003-04-24 21:07:17.000000000 +0930
@@ -93,6 +93,8 @@ struct locate_and_pad_arg_data
   /* The amount that the stack pointer needs to be adjusted to
      force alignment for the next argument.  */
   struct args_size alignment_pad;
+  /* Which way we should pad this arg.  */
+  enum direction where_pad;
 };
 #endif
 
@@ -150,6 +152,14 @@ do {							\
       ? downward : upward))
 #endif
 
+/* Specify padding for the last element of a block move between
+   registers and memory.  FIRST is non-zero if this is the only
+   element.  */
+#ifndef BLOCK_REG_PADDING
+#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
+  (!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
+#endif
+
 /* Supply a default definition for FUNCTION_ARG_BOUNDARY.  Normally, we let
    FUNCTION_ARG_PADDING, which also pads the length, handle any needed
    alignment.  */
@@ -416,19 +426,21 @@ extern void move_block_from_reg PARAMS (
 /* Generate a non-consecutive group of registers represented by a PARALLEL.  */
 extern rtx gen_group_rtx PARAMS ((rtx));
 
+#ifdef TREE_CODE
 /* Load a BLKmode value into non-consecutive registers represented by a
    PARALLEL.  */
-extern void emit_group_load PARAMS ((rtx, rtx, int));
+extern void emit_group_load PARAMS ((rtx, rtx, tree, int));
+#endif
 
 /* Move a non-consecutive group of registers represented by a PARALLEL into
    a non-consecutive group of registers represented by a PARALLEL.  */
 extern void emit_group_move PARAMS ((rtx, rtx));
 
+#ifdef TREE_CODE
 /* Store a BLKmode value from non-consecutive registers represented by a
    PARALLEL.  */
-extern void emit_group_store PARAMS ((rtx, rtx, int));
+extern void emit_group_store PARAMS ((rtx, rtx, tree, int));
 
-#ifdef TREE_CODE
 /* Copy BLKmode object from a set of registers.  */
 extern rtx copy_blkmode_from_reg PARAMS ((rtx, rtx, tree));
 #endif
diff -urp gcc2/gcc/expr.c gcc3/gcc/expr.c
--- gcc2/gcc/expr.c	2003-04-24 14:46:04.000000000 +0930
+++ gcc3/gcc/expr.c	2003-04-24 21:07:17.000000000 +0930
@@ -2212,19 +2212,15 @@ gen_group_rtx (orig)
   return gen_rtx_PARALLEL (GET_MODE (orig), gen_rtvec_v (length, tmps));
 }
 
-/* Emit code to move a block SRC to a block DST, where DST is non-consecutive
-   registers represented by a PARALLEL.  SSIZE represents the total size of
-   block SRC in bytes, or -1 if not known.  */
-/* ??? If SSIZE % UNITS_PER_WORD != 0, we make the blatant assumption that
-   the balance will be in what would be the low-order memory addresses, i.e.
-   left justified for big endian, right justified for little endian.  This
-   happens to be true for the targets currently using this support.  If this
-   ever changes, a new target macro along the lines of FUNCTION_ARG_PADDING
-   would be needed.  */
+/* Emit code to move a block ORIG_SRC of type TYPE to a block DST,
+   where DST is non-consecutive registers represented by a PARALLEL.
+   SSIZE represents the total size of block ORIG_SRC in bytes, or -1
+   if not known.  */ 
 
 void
-emit_group_load (dst, orig_src, ssize)
+emit_group_load (dst, orig_src, type, ssize)
      rtx dst, orig_src;
+     tree type;
      int ssize;
 {
   rtx *tmps, src;
@@ -2253,7 +2249,11 @@ emit_group_load (dst, orig_src, ssize)
       /* Handle trailing fragments that run over the size of the struct.  */
       if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
 	{
-	  shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
+	  /* Arrange to shift the fragment to where it belongs.
+	     extract_bit_field loads to the lsb of the reg.  */
+	  if (BLOCK_REG_PADDING (GET_MODE (orig_src), type, i == start)
+	      == (BYTES_BIG_ENDIAN ? upward : downward))
+	    shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
 	  bytelen = ssize - bytepos;
 	  if (bytelen <= 0)
 	    abort ();
@@ -2278,7 +2278,8 @@ emit_group_load (dst, orig_src, ssize)
 
       /* Optimize the access just a bit.  */
       if (GET_CODE (src) == MEM
-	  && MEM_ALIGN (src) >= GET_MODE_ALIGNMENT (mode)
+	  && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (src))
+	      || MEM_ALIGN (src) >= GET_MODE_ALIGNMENT (mode))
 	  && bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
 	  && bytelen == GET_MODE_SIZE (mode))
 	{
@@ -2321,7 +2322,7 @@ emit_group_load (dst, orig_src, ssize)
 				     bytepos * BITS_PER_UNIT, 1, NULL_RTX,
 				     mode, mode, ssize);
 
-      if (BYTES_BIG_ENDIAN && shift)
+      if (shift)
 	expand_binop (mode, ashl_optab, tmps[i], GEN_INT (shift),
 		      tmps[i], 0, OPTAB_WIDEN);
     }
@@ -2353,13 +2354,16 @@ emit_group_move (dst, src)
 		    XEXP (XVECEXP (src, 0, i), 0));
 }
 
-/* Emit code to move a block SRC to a block DST, where SRC is non-consecutive
-   registers represented by a PARALLEL.  SSIZE represents the total size of
-   block DST, or -1 if not known.  */
+/* Emit code to move a block SRC to a block ORIG_DST of type TYPE,
+   where SRC is non-consecutive registers represented by a PARALLEL.
+   SSIZE represents the total size of block ORIG_DST, or -1 if not
+   known.  */
 
 void
-emit_group_store (orig_dst, src, ssize)
-     rtx orig_dst, src;
+emit_group_store (orig_dst, src, type, ssize)
+     rtx orig_dst;
+     rtx src;
+     tree type ATTRIBUTE_UNUSED;
      int ssize;
 {
   rtx *tmps, dst;
@@ -2404,8 +2408,8 @@ emit_group_store (orig_dst, src, ssize)
 	 the temporary.  */
 
       temp = assign_stack_temp (GET_MODE (dst), ssize, 0);
-      emit_group_store (temp, src, ssize);
-      emit_group_load (dst, temp, ssize);
+      emit_group_store (temp, src, type, ssize);
+      emit_group_load (dst, temp, type, ssize);
       return;
     }
   else if (GET_CODE (dst) != MEM && GET_CODE (dst) != CONCAT)
@@ -2426,7 +2430,10 @@ emit_group_store (orig_dst, src, ssize)
       /* Handle trailing fragments that run over the size of the struct.  */
       if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
 	{
-	  if (BYTES_BIG_ENDIAN)
+	  /* store_bit_field always takes its value from the lsb.
+	     Move the fragment to the lsb if it's not already there.  */
+	  if (BLOCK_REG_PADDING (GET_MODE (orig_dst), type, i == start)
+	      == (BYTES_BIG_ENDIAN ? upward : downward))
 	    {
 	      int shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
 	      expand_binop (mode, ashr_optab, tmps[i], GEN_INT (shift),
@@ -2459,7 +2466,8 @@ emit_group_store (orig_dst, src, ssize)
 
       /* Optimize the access just a bit.  */
       if (GET_CODE (dest) == MEM
-	  && MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode)
+	  && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (dest))
+	      || MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode))
 	  && bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
 	  && bytelen == GET_MODE_SIZE (mode))
 	emit_move_insn (adjust_address (dest, mode, bytepos), tmps[i]);
@@ -3991,7 +3999,7 @@ emit_push_insn (x, mode, type, size, ali
       /* Handle calls that pass values in multiple non-contiguous locations.
 	 The Irix 6 ABI has examples of this.  */
       if (GET_CODE (reg) == PARALLEL)
-	emit_group_load (reg, x, -1);  /* ??? size? */
+	emit_group_load (reg, x, type, -1);
       else
 	move_block_to_reg (REGNO (reg), x, partial, mode);
     }
@@ -4194,7 +4202,8 @@ expand_assignment (to, from, want_value,
       /* Handle calls that return values in multiple non-contiguous locations.
 	 The Irix 6 ABI has examples of this.  */
       if (GET_CODE (to_rtx) == PARALLEL)
-	emit_group_load (to_rtx, value, int_size_in_bytes (TREE_TYPE (from)));
+	emit_group_load (to_rtx, value, TREE_TYPE (from),
+			 int_size_in_bytes (TREE_TYPE (from)));
       else if (GET_MODE (to_rtx) == BLKmode)
 	emit_block_move (to_rtx, value, expr_size (from), BLOCK_OP_NORMAL);
       else
@@ -4228,7 +4237,8 @@ expand_assignment (to, from, want_value,
       temp = expand_expr (from, 0, GET_MODE (to_rtx), 0);
 
       if (GET_CODE (to_rtx) == PARALLEL)
-	emit_group_load (to_rtx, temp, int_size_in_bytes (TREE_TYPE (from)));
+	emit_group_load (to_rtx, temp, TREE_TYPE (from),
+			 int_size_in_bytes (TREE_TYPE (from)));
       else
 	emit_move_insn (to_rtx, temp);
 
@@ -4641,7 +4651,8 @@ store_expr (exp, target, want_value)
       /* Handle calls that return values in multiple non-contiguous locations.
 	 The Irix 6 ABI has examples of this.  */
       else if (GET_CODE (target) == PARALLEL)
-	emit_group_load (target, temp, int_size_in_bytes (TREE_TYPE (exp)));
+	emit_group_load (target, temp, TREE_TYPE (exp),
+			 int_size_in_bytes (TREE_TYPE (exp)));
       else if (GET_MODE (temp) == BLKmode)
 	emit_block_move (target, temp, expr_size (exp),
 			 (want_value & 2
@@ -9182,7 +9193,7 @@ expand_expr (exp, target, tmode, modifie
 		    /* Handle calls that pass values in multiple
 		       non-contiguous locations.  The Irix 6 ABI has examples
 		       of this.  */
-		    emit_group_store (memloc, op0,
+		    emit_group_store (memloc, op0, inner_type,
 				      int_size_in_bytes (inner_type));
 		  else
 		    emit_move_insn (memloc, op0);
diff -urp gcc2/gcc/calls.c gcc3/gcc/calls.c
--- gcc2/gcc/calls.c	2003-04-24 11:25:45.000000000 +0930
+++ gcc3/gcc/calls.c	2003-04-24 21:07:17.000000000 +0930
@@ -27,6 +27,7 @@ Software Foundation, 59 Temple Place - S
 #include "tree.h"
 #include "flags.h"
 #include "expr.h"
+#include "optabs.h"
 #include "libfuncs.h"
 #include "function.h"
 #include "regs.h"
@@ -1015,22 +1016,22 @@ store_unaligned_arguments_into_pseudos (
 	    < (unsigned int) MIN (BIGGEST_ALIGNMENT, BITS_PER_WORD)))
       {
 	int bytes = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
-	int big_endian_correction = 0;
-
-	args[i].n_aligned_regs
-	  = args[i].partial ? args[i].partial
-	    : (bytes + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
+	int nregs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+	int endian_correction = 0;
 
+	args[i].n_aligned_regs = args[i].partial ? args[i].partial : nregs;
 	args[i].aligned_regs = (rtx *) xmalloc (sizeof (rtx)
 						* args[i].n_aligned_regs);
 
-	/* Structures smaller than a word are aligned to the least
-	   significant byte (to the right).  On a BYTES_BIG_ENDIAN machine,
+	/* Structures smaller than a word are normally aligned to the
+	   least significant byte.  On a BYTES_BIG_ENDIAN machine,
 	   this means we must skip the empty high order bytes when
 	   calculating the bit offset.  */
-	if (BYTES_BIG_ENDIAN
-	    && bytes < UNITS_PER_WORD)
-	  big_endian_correction = (BITS_PER_WORD  - (bytes * BITS_PER_UNIT));
+	if (bytes < UNITS_PER_WORD
+	    && (BLOCK_REG_PADDING (args[i].mode,
+				   TREE_TYPE (args[i].tree_value), 1)
+		== downward))
+	  endian_correction = BITS_PER_WORD - bytes * BITS_PER_UNIT;
 
 	for (j = 0; j < args[i].n_aligned_regs; j++)
 	  {
@@ -1039,6 +1040,8 @@ store_unaligned_arguments_into_pseudos (
 	    int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD);
 
 	    args[i].aligned_regs[j] = reg;
+	    word = extract_bit_field (word, bitsize, 0, 1, NULL_RTX,
+				      word_mode, word_mode, BITS_PER_WORD);
 
 	    /* There is no need to restrict this code to loading items
 	       in TYPE_ALIGN sized hunks.  The bitfield instructions can
@@ -1054,11 +1057,8 @@ store_unaligned_arguments_into_pseudos (
 	    emit_move_insn (reg, const0_rtx);
 
 	    bytes -= bitsize / BITS_PER_UNIT;
-	    store_bit_field (reg, bitsize, big_endian_correction, word_mode,
-			     extract_bit_field (word, bitsize, 0, 1, NULL_RTX,
-						word_mode, word_mode,
-						BITS_PER_WORD),
-			     BITS_PER_WORD);
+	    store_bit_field (reg, bitsize, endian_correction, word_mode,
+			     word, BITS_PER_WORD);
 	  }
       }
 }
@@ -1689,34 +1689,45 @@ load_register_parameters (args, num_actu
     {
       rtx reg = ((flags & ECF_SIBCALL)
 		 ? args[i].tail_call_reg : args[i].reg);
-      int partial = args[i].partial;
-      int nregs;
-
       if (reg)
 	{
+	  int partial = args[i].partial;
+	  int nregs;
+	  int size = 0;
 	  rtx before_arg = get_last_insn ();
 	  /* Set to non-negative if must move a word at a time, even if just
 	     one word (e.g, partial == 1 && mode == DFmode).  Set to -1 if
 	     we just use a normal move insn.  This value can be zero if the
 	     argument is a zero size structure with no fields.  */
-	  nregs = (partial ? partial
-		   : (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode
-		      ? ((int_size_in_bytes (TREE_TYPE (args[i].tree_value))
-			  + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
-		      : -1));
+	  nregs = -1;
+	  if (partial)
+	    nregs = partial;
+	  else if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode)
+	    {
+	      size = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
+	      nregs = (size + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
+	    }
+	  else
+	    size = GET_MODE_SIZE (args[i].mode);
 
 	  /* Handle calls that pass values in multiple non-contiguous
 	     locations.  The Irix 6 ABI has examples of this.  */
 
 	  if (GET_CODE (reg) == PARALLEL)
-	    emit_group_load (reg, args[i].value,
-			     int_size_in_bytes (TREE_TYPE (args[i].tree_value)));
+	    {
+	      tree type = TREE_TYPE (args[i].tree_value);
+	      emit_group_load (reg, args[i].value, type,
+			       int_size_in_bytes (type));
+	    }
 
 	  /* If simple case, just do move.  If normal partial, store_one_arg
 	     has already loaded the register for us.  In all other cases,
 	     load the register(s) from memory.  */
 
-	  else if (nregs == -1)
+	  else if (nregs == -1
+		   && !(size < UNITS_PER_WORD
+			&& (args[i].locate.where_pad
+			    == (BYTES_BIG_ENDIAN ? upward : downward))))
 	    emit_move_insn (reg, args[i].value);
 
 	  /* If we have pre-computed the values to put in the registers in
@@ -1728,9 +1739,42 @@ load_register_parameters (args, num_actu
 			      args[i].aligned_regs[j]);
 
 	  else if (partial == 0 || args[i].pass_on_stack)
-	    move_block_to_reg (REGNO (reg),
-			       validize_mem (args[i].value), nregs,
-			       args[i].mode);
+	    {
+	      rtx mem = validize_mem (args[i].value);
+
+	      /* Handle case where we have a value that needs shifting
+		 up to the msb.  eg. a QImode value and we're padding
+		 upward on a BYTES_BIG_ENDIAN machine.  */
+	      if (nregs == -1)
+		{
+		  rtx ri = gen_rtx_REG (word_mode, REGNO (reg));
+		  rtx x;
+		  int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
+		  x = expand_binop (word_mode, ashl_optab, mem,
+				    GEN_INT (shift), ri, 1, OPTAB_WIDEN);
+		  if (x != ri)
+		    emit_move_insn (ri, x);
+		}
+
+	      /* Handle a BLKmode that needs shifting.  */
+	      else if (nregs == 1 && size < UNITS_PER_WORD
+		       && args[i].locate.where_pad == downward)
+		{
+		  rtx tem = operand_subword_force (mem, 0, args[i].mode);
+		  rtx ri = gen_rtx_REG (word_mode, REGNO (reg));
+		  rtx x = gen_reg_rtx (word_mode);
+		  int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
+		  optab dir = BYTES_BIG_ENDIAN ? lshr_optab : ashl_optab;
+
+		  emit_move_insn (x, tem);
+		  x = expand_binop (word_mode, dir, x, GEN_INT (shift),
+				    ri, 1, OPTAB_WIDEN);
+		  if (x != ri)
+		    emit_move_insn (ri, x);
+		}
+	      else
+		move_block_to_reg (REGNO (reg), mem, nregs, args[i].mode);
+	    }
 
 	  /* When a parameter is a block, and perhaps in other cases, it is
 	     possible that it did a load from an argument slot that was
@@ -3225,7 +3269,7 @@ expand_call (exp, target, ignore)
 	    }
 
 	  if (! rtx_equal_p (target, valreg))
-	    emit_group_store (target, valreg,
+	    emit_group_store (target, valreg, TREE_TYPE (exp),
 			      int_size_in_bytes (TREE_TYPE (exp)));
 
 	  /* We can not support sibling calls for this case.  */
@@ -3976,7 +4020,7 @@ emit_library_call_value_1 (retval, orgfu
       /* Handle calls that pass values in multiple non-contiguous
 	 locations.  The PA64 has examples of this for library calls.  */
       if (reg != 0 && GET_CODE (reg) == PARALLEL)
-	emit_group_load (reg, val, GET_MODE_SIZE (GET_MODE (val)));
+	emit_group_load (reg, val, NULL_TREE, GET_MODE_SIZE (GET_MODE (val)));
       else if (reg != 0 && partial == 0)
 	emit_move_insn (reg, val);
 
@@ -4080,7 +4124,7 @@ emit_library_call_value_1 (retval, orgfu
 	  if (GET_CODE (valreg) == PARALLEL)
 	    {
 	      temp = gen_reg_rtx (outmode);
-	      emit_group_store (temp, valreg, outmode);
+	      emit_group_store (temp, valreg, NULL_TREE, outmode);
 	      valreg = temp;
 	    }
 
@@ -4123,7 +4167,7 @@ emit_library_call_value_1 (retval, orgfu
 	{
 	  if (value == 0)
 	    value = gen_reg_rtx (outmode);
-	  emit_group_store (value, valreg, outmode);
+	  emit_group_store (value, valreg, NULL_TREE, outmode);
 	}
       else if (value != 0)
 	emit_move_insn (value, valreg);
diff -urp gcc2/gcc/function.c gcc3/gcc/function.c
--- gcc2/gcc/function.c	2003-04-24 17:52:45.000000000 +0930
+++ gcc3/gcc/function.c	2003-04-24 21:07:17.000000000 +0930
@@ -4623,6 +4623,8 @@ assign_parms (fndecl)
 						  offset_rtx));
 
 	set_mem_attributes (stack_parm, parm, 1);
+	if (entry_parm && MEM_ATTRS (stack_parm)->align < PARM_BOUNDARY)
+	  set_mem_align (stack_parm, PARM_BOUNDARY);
 
 	/* Set also REG_ATTRS if parameter was passed in a register.  */
 	if (entry_parm)
@@ -4654,6 +4656,7 @@ assign_parms (fndecl)
 	     locations.  The Irix 6 ABI has examples of this.  */
 	  if (GET_CODE (entry_parm) == PARALLEL)
 	    emit_group_store (validize_mem (stack_parm), entry_parm,
+			      TREE_TYPE (parm),
 			      int_size_in_bytes (TREE_TYPE (parm)));
 
 	  else
@@ -4757,7 +4760,10 @@ assign_parms (fndecl)
 
 	 Set DECL_RTL to that place.  */
 
-      if (nominal_mode == BLKmode || GET_CODE (entry_parm) == PARALLEL)
+      if (nominal_mode == BLKmode
+	  || (locate.where_pad == (BYTES_BIG_ENDIAN ? upward : downward)
+	      && GET_MODE_SIZE (promoted_mode) < UNITS_PER_WORD)
+	  || GET_CODE (entry_parm) == PARALLEL)
 	{
 	  /* If a BLKmode arrives in registers, copy it to a stack slot.
 	     Handle calls that pass values in multiple non-contiguous
@@ -4793,7 +4799,7 @@ assign_parms (fndecl)
 	      /* Handle calls that pass values in multiple non-contiguous
 		 locations.  The Irix 6 ABI has examples of this.  */
 	      if (GET_CODE (entry_parm) == PARALLEL)
-		emit_group_store (mem, entry_parm, size);
+		emit_group_store (mem, entry_parm, TREE_TYPE (parm), size);
 
 	      /* If SIZE is that of a mode no bigger than a word, just use
 		 that mode's store operation.  */
@@ -4802,7 +4808,10 @@ assign_parms (fndecl)
 		  enum machine_mode mode
 		    = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
 
-		  if (mode != BLKmode)
+		  if (mode != BLKmode
+		      && (size == UNITS_PER_WORD
+			  || (BLOCK_REG_PADDING (mode, TREE_TYPE (parm), 1)
+			      != (BYTES_BIG_ENDIAN ? upward : downward))))
 		    {
 		      rtx reg = gen_rtx_REG (mode, REGNO (entry_parm));
 		      emit_move_insn (change_address (mem, mode, 0), reg);
@@ -4813,7 +4822,8 @@ assign_parms (fndecl)
 		     to memory.  Note that the previous test doesn't
 		     handle all cases (e.g. SIZE == 3).  */
 		  else if (size != UNITS_PER_WORD
-			   && BYTES_BIG_ENDIAN)
+			   && (BLOCK_REG_PADDING (mode, TREE_TYPE (parm), 1)
+			       == downward))
 		    {
 		      rtx tem, x;
 		      int by = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
@@ -5411,6 +5421,7 @@ locate_and_pad_parm (passed_mode, type, 
     = type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
   where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
   boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
+  locate->where_pad = where_pad;
 
 #ifdef ARGS_GROW_DOWNWARD
   locate->slot_offset.constant = -initial_offset_ptr->constant;
@@ -7142,6 +7153,7 @@ expand_function_end (filename, line, end
 		emit_group_move (real_decl_rtl, decl_rtl);
 	      else
 		emit_group_load (real_decl_rtl, decl_rtl,
+				 TREE_TYPE (decl_result),
 				 int_size_in_bytes (TREE_TYPE (decl_result)));
 	    }
 	  else
diff -urp gcc2/gcc/stmt.c gcc3/gcc/stmt.c
--- gcc2/gcc/stmt.c	2003-04-22 18:55:34.000000000 +0930
+++ gcc3/gcc/stmt.c	2003-04-24 21:07:18.000000000 +0930
@@ -3008,7 +3008,7 @@ expand_value_return (val)
 	val = convert_modes (mode, old_mode, val, unsignedp);
 #endif
       if (GET_CODE (return_reg) == PARALLEL)
-	emit_group_load (return_reg, val, int_size_in_bytes (type));
+	emit_group_load (return_reg, val, type, int_size_in_bytes (type));
       else
 	emit_move_insn (return_reg, val);
     }
diff -urp gcc2/gcc/Makefile.in gcc3/gcc/Makefile.in
--- gcc2/gcc/Makefile.in	2003-04-24 15:47:39.000000000 +0930
+++ gcc3/gcc/Makefile.in	2003-04-24 21:14:33.000000000 +0930
@@ -1531,7 +1531,7 @@ builtins.o : builtins.c $(CONFIG_H) $(SY
    $(RECOG_H) output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h \
    except.h $(TM_P_H) $(PREDICT_H) libfuncs.h real.h langhooks.h
 calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) flags.h \
-   $(EXPR_H) langhooks.h $(TARGET_H) \
+   $(EXPR_H) $(OPTABS_H) langhooks.h $(TARGET_H) \
    libfuncs.h $(REGS_H) toplev.h output.h function.h $(TIMEVAR_H) $(TM_P_H) cgraph.h except.h
 expmed.o : expmed.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
    flags.h insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) real.h \
diff -urp gcc2/gcc/config/rs6000/linux64.h gcc3/gcc/config/rs6000/linux64.h
--- gcc2/gcc/config/rs6000/linux64.h	2003-04-22 18:55:34.000000000 +0930
+++ gcc3/gcc/config/rs6000/linux64.h	2003-04-24 21:07:17.000000000 +0930
@@ -49,6 +49,10 @@
 #undef	TARGET_64BIT
 #define	TARGET_64BIT		1
 
+/* And we're always big-endian.  */
+#undef	TARGET_BIG_ENDIAN
+#define TARGET_BIG_ENDIAN 1
+
 /* 64-bit PowerPC Linux always has a TOC.  */
 #undef  TARGET_NO_TOC
 #define TARGET_NO_TOC		0
@@ -143,8 +147,25 @@
 #undef  JUMP_TABLES_IN_TEXT_SECTION
 #define JUMP_TABLES_IN_TEXT_SECTION 1
 
-/* 64-bit PowerPC Linux always has GPR13 fixed.  */
-#define FIXED_R13		1
+/* The linux ppc64 ABI isn't explicit on whether aggregates smaller
+   than a doubleword should be padded upward or downward.  You could
+   reasonably assume that they follow the normal rules for structure
+   layout treating the parameter area as any other block of memory,
+   then map the reg param area to registers.  ie. pad updard.
+   Setting both of the following defines results in this behaviour.
+   Setting just the first one will result in aggregates that fit in a
+   doubleword being padded downward, and others being padded upward.
+   Not a bad idea as this results in struct { int x; } being passed
+   the same way as an int.  */
+#define AGGREGATE_PADDING_FIXED 1
+/* #define AGGREGATES_PAD_UPWARD_ALWAYS 1 */
+
+/* We don't want anything in the reg parm area being passed on the
+   stack.  */
+#define MUST_PASS_IN_STACK(MODE, TYPE)				\
+  ((TYPE) != 0							\
+   && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST		\
+       || TREE_ADDRESSABLE (TYPE)))
 
 /* __throw will restore its own return address to be the same as the
    return address of the function that the throw is being made to.
diff -urp gcc2/gcc/config/rs6000/rs6000.h gcc3/gcc/config/rs6000/rs6000.h
--- gcc2/gcc/config/rs6000/rs6000.h	2003-04-23 11:29:04.000000000 +0930
+++ gcc3/gcc/config/rs6000/rs6000.h	2003-04-24 21:07:17.000000000 +0930
@@ -1701,7 +1701,6 @@ typedef struct rs6000_args
   int fregno;			/* next available FP register */
   int vregno;			/* next available AltiVec register */
   int nargs_prototype;		/* # args left in the current prototype */
-  int orig_nargs;		/* Original value of nargs_prototype */
   int prototype;		/* Whether a prototype was defined */
   int call_cookie;		/* Do special things for this call */
   int sysv_gregno;		/* next available GP register */
@@ -1832,13 +1831,8 @@ typedef struct rs6000_args
 #define EXPAND_BUILTIN_VA_ARG(valist, type) \
   rs6000_va_arg (valist, type)
 
-/* For AIX, the rule is that structures are passed left-aligned in
-   their stack slot.  However, GCC does not presently do this:
-   structures which are the same size as integer types are passed
-   right-aligned, as if they were in fact integers.  This only
-   matters for structures of size 1 or 2, or 4 when TARGET_64BIT.
-   ABI_V4 does not use std_expand_builtin_va_arg.  */
-#define PAD_VARARGS_DOWN (TYPE_MODE (type) != BLKmode)
+#define PAD_VARARGS_DOWN \
+   (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
 
 /* Define this macro to be a nonzero value if the location where a function
    argument is passed depends on whether or not it is a named argument.  */
diff -urp gcc2/gcc/config/rs6000/rs6000.c gcc3/gcc/config/rs6000/rs6000.c
--- gcc2/gcc/config/rs6000/rs6000.c	2003-04-24 14:46:04.000000000 +0930
+++ gcc3/gcc/config/rs6000/rs6000.c	2003-04-24 21:43:35.000000000 +0930
@@ -3132,8 +3132,6 @@ init_cumulative_args (cum, fntype, libna
   else
     cum->nargs_prototype = 0;
 
-  cum->orig_nargs = cum->nargs_prototype;
-
   /* Check for a longcall attribute.  */
   if (fntype
       && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
@@ -3172,8 +3170,37 @@ function_arg_padding (mode, type)
      enum machine_mode mode;
      tree type;
 {
+#if !AGGREGATE_PADDING_FIXED
+  /* GCC used to pass structures of the same size as integer types as
+     if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
+     ie. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
+     passed padded downward, except that -mstrict-align further
+     muddied the water in that multi-component structures of 2 and 4
+     bytes in size were passed padded upward.
+
+     The following arranges for best compatibility with previous
+     versions of gcc, but removes the -mstrict-align dependency.  */
+  if (BYTES_BIG_ENDIAN)
+    {
+      HOST_WIDE_INT size = 0;
+
+      if (mode == BLKmode)
+	{
+	  if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
+	    size = int_size_in_bytes (type);
+	}
+      else
+	size = GET_MODE_SIZE (mode);
+
+      if (size == 1 || size == 2 || size == 4)
+	return downward;
+    }
+  return upward;
+#else
+#if AGGREGATES_PAD_UPWARD_ALWAYS
   if (type != 0 && AGGREGATE_TYPE_P (type))
     return upward;
+#endif
 
   /* This is the default definition.  */
   return (! BYTES_BIG_ENDIAN
@@ -3183,6 +3210,7 @@ function_arg_padding (mode, type)
                  && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
               : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
              ? downward : upward));
+#endif
 }
 
 /* If defined, a C expression that gives the alignment boundary, in bits,

^ permalink raw reply	[flat|nested] 875+ messages in thread
* function parms in regs, patch 1 of 3
@ 2003-04-24 15:34 Alan Modra
  2003-04-25 22:44 ` Richard Henderson
  2003-05-02  5:06 ` function parms in regs, patch 1 " Jim Wilson
  0 siblings, 2 replies; 875+ messages in thread
From: Alan Modra @ 2003-04-24 15:34 UTC (permalink / raw)
  To: gcc-patches

I've been playing with gcc's function call code over the last week or
so.  The goal was to properly pass structures by value in registers,
according to the PowerPC64 ABI, and avoid the problems illustrated
in PR 10397 and PR 10408.  What started out as a relatively straight-
forward patch using PARALLELs in rs6000.c:function_arg has grown a
little..  So much so that it needs splitting up.

Patch 1 of 3 (this one) mostly mucks about with locate_and_pad_parm.
Patch 2 of 3 moves special case code out of move_block_from_reg.
Patch 3 of 3 is the new code to handle big-endian reg parms, and
rs6000 specific changes.

Patch 1 and 2 can probably be applied in reverse order as they're
independent, although I haven't tested that.  Regression tested
powerpc64-linux after each patch cumulatively applied.  I'll also
bootstrap and regression test i686-linux and powerpc-linux again
(these were tested on earlier versions of the patch).

This patch
a) Packages struct arg_data fields set by locate_and_pad_parm into a
   separate struct, reducing the number of function parms.  The resulting
   change to callers happens to fix a bug in emit_library_call_value_1
   where alignment_pad was being set for each arg in one loop, then used
   in another loop for each arg.  ie. we used the last arg's
   alignment_pad for all args.
b) Calculates slot_offset in locate_and_pad_parm.  This requires an
   extra input parm to specify partial-in-reg parms, which also lets us
   correct the arg size calculation in the function instead of adjusting
   it externally.  Incidentally fixes a bug in calls.c:
   initialize_argument_information ARGS_GROW_DOWNWARD calculation of
   slot_offset for variable size args by deleting the buggy code.
c) Fixes bugs in locate_and_pad_parm handling of initial_offset_ptr.
   I can't see anything that guarantees when initial_offset_ptr->var
   is non-NULL that initial_offset_ptr->constant == 0, but that's what
   the old code assumes.
d) Removes the hacks in locate_and_pad_parm that fudged the stack offset
   for pad-down reg parms.  Instead we choose slot_offset externally.
   Note! For !ARGS_GROW_DOWNWARD, downward padding and non-BLKmode args,
   this changes the stack home for a reg arg, which shouldn't be a
   problem.  I'm raising the point here for full disclosure.  :)
e) Optimizes a few things in assign_parms.

	* calls.c (struct arg_data): Move offset, slot_offset, size and
	alignment_pad to struct locate_and_pad_arg_data.  Update all refs.
	(initialize_argument_information): Adjust call to locate_and_pad_parm.
	Delete alignment_pad var.  Don't calculate slot_offset here.
	(emit_library_call_value_1): Delete alignment_pad, offset and size
	vars.  Use struct locate_and_pad_arg_data instead.  Adjust refs.
	Adjust call to locate_and_pad_parm.  Don't tweak arg size for
	partial in-regs here.  Formatting fixes.
	* expr.h (struct locate_and_pad_arg_data): New struct.
	(locate_and_pad_parm): Adjust declaration.
	* function.c (assign_parms): Localize vars.  Use "locate" instead of
	other arg location vars.  Don't invoke FUNCTION_ARG or
	FUNCTION_INCOMING_ARG unless pretend_named is different from
	named_arg.  Heed MUST_PASS_IN_STACK and set up "partial" before
	calling locate_and_pad_parm.  Adjust locate_and_pad_parm call.
	Use slot_offset for stack home of reg parms.  Correct test for
	parm passed in memory.  Formatting fixes.
	(locate_and_pad_parm): Add "partial" to params.  Replace offset_ptr
	arg_size_ptr and alignment pad with "locate".  Set slot_offset here.
	Correct initial_offset_ptr handling.  Localize vars.  Always pad
	locate->offset even when in_regs.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

diff -urp gcc.orig/gcc/calls.c gcc1/gcc/calls.c
--- gcc.orig/gcc/calls.c	2003-04-22 18:55:34.000000000 +0930
+++ gcc1/gcc/calls.c	2003-04-24 11:25:45.000000000 +0930
@@ -98,16 +98,8 @@ struct arg_data
      even though pass_on_stack is zero, just because FUNCTION_ARG says so.
      pass_on_stack identifies arguments that *cannot* go in registers.  */
   int pass_on_stack;
-  /* Offset of this argument from beginning of stack-args.  */
-  struct args_size offset;
-  /* Similar, but offset to the start of the stack slot.  Different from
-     OFFSET if this arg pads downward.  */
-  struct args_size slot_offset;
-  /* Size of this argument on the stack, rounded up for any padding it gets,
-     parts of the argument passed in registers do not count.
-     If REG_PARM_STACK_SPACE is defined, then register parms
-     are counted here as well.  */
-  struct args_size size;
+  /* Some fields packaged up for locate_and_pad_parm.  */
+  struct locate_and_pad_arg_data locate;
   /* Location on the stack at which parameter should be stored.  The store
      has already been done if STACK == VALUE.  */
   rtx stack;
@@ -123,9 +115,6 @@ struct arg_data
      word-sized pseudos we made.  */
   rtx *aligned_regs;
   int n_aligned_regs;
-  /* The amount that the stack pointer needs to be adjusted to
-     force alignment for the next argument.  */
-  struct args_size alignment_pad;
 };
 
 /* A vector of one char per byte of stack space.  A byte if nonzero if
@@ -1120,7 +1109,6 @@ initialize_argument_information (num_act
   /* Count arg position in order args appear.  */
   int argpos;
 
-  struct args_size alignment_pad;
   int i;
   tree p;
 
@@ -1331,39 +1319,14 @@ initialize_argument_information (num_act
 #else
 			     args[i].reg != 0,
 #endif
-			     fndecl, args_size, &args[i].offset,
-			     &args[i].size, &alignment_pad);
-
-#ifndef ARGS_GROW_DOWNWARD
-      args[i].slot_offset = *args_size;
-#endif
-
-      args[i].alignment_pad = alignment_pad;
-
-      /* If a part of the arg was put into registers,
-	 don't include that part in the amount pushed.  */
-      if (reg_parm_stack_space == 0 && ! args[i].pass_on_stack)
-	args[i].size.constant -= ((args[i].partial * UNITS_PER_WORD)
-				  / (PARM_BOUNDARY / BITS_PER_UNIT)
-				  * (PARM_BOUNDARY / BITS_PER_UNIT));
+			     args[i].pass_on_stack ? 0 : args[i].partial,
+			     fndecl, args_size, &args[i].locate);
 
       /* Update ARGS_SIZE, the total stack space for args so far.  */
 
-      args_size->constant += args[i].size.constant;
-      if (args[i].size.var)
-	{
-	  ADD_PARM_SIZE (*args_size, args[i].size.var);
-	}
-
-      /* Since the slot offset points to the bottom of the slot,
-	 we must record it after incrementing if the args grow down.  */
-#ifdef ARGS_GROW_DOWNWARD
-      args[i].slot_offset = *args_size;
-
-      args[i].slot_offset.constant = -args_size->constant;
-      if (args_size->var)
-	SUB_PARM_SIZE (args[i].slot_offset, args_size->var);
-#endif
+      args_size->constant += args[i].locate.size.constant;
+      if (args[i].locate.size.var)
+	ADD_PARM_SIZE (*args_size, args[i].locate.size.var);
 
       /* Increment ARGS_SO_FAR, which has info about which arg-registers
 	 have been used, etc.  */
@@ -1616,8 +1579,8 @@ compute_argument_addresses (args, argblo
 
       for (i = 0; i < num_actuals; i++)
 	{
-	  rtx offset = ARGS_SIZE_RTX (args[i].offset);
-	  rtx slot_offset = ARGS_SIZE_RTX (args[i].slot_offset);
+	  rtx offset = ARGS_SIZE_RTX (args[i].locate.offset);
+	  rtx slot_offset = ARGS_SIZE_RTX (args[i].locate.slot_offset);
 	  rtx addr;
 
 	  /* Skip this parm if it will not be passed on the stack.  */
@@ -2060,12 +2023,12 @@ check_sibcall_argument_overlap (insn, ar
   if (mark_stored_args_map)
     {
 #ifdef ARGS_GROW_DOWNWARD
-      low = -arg->slot_offset.constant - arg->size.constant;
+      low = -arg->locate.slot_offset.constant - arg->locate.size.constant;
 #else
-      low = arg->slot_offset.constant;
+      low = arg->locate.slot_offset.constant;
 #endif
 
-      for (high = low + arg->size.constant; low < high; low++)
+      for (high = low + arg->locate.size.constant; low < high; low++)
 	SET_BIT (stored_args_map, low);
     }
   return insn != NULL_RTX;
@@ -3358,7 +3321,7 @@ expand_call (exp, target, ignore)
 		  emit_move_insn (stack_area, args[i].save_area);
 		else
 		  emit_block_move (stack_area, args[i].save_area,
-				   GEN_INT (args[i].size.constant),
+				   GEN_INT (args[i].locate.size.constant),
 				   BLOCK_OP_CALL_PARM);
 	      }
 
@@ -3507,7 +3470,6 @@ emit_library_call_value_1 (retval, orgfu
   rtx fun;
   int inc;
   int count;
-  struct args_size alignment_pad;
   rtx argblock = 0;
   CUMULATIVE_ARGS args_so_far;
   struct arg
@@ -3516,8 +3478,7 @@ emit_library_call_value_1 (retval, orgfu
     enum machine_mode mode;
     rtx reg;
     int partial;
-    struct args_size offset;
-    struct args_size size;
+    struct locate_and_pad_arg_data locate;
     rtx save_area;
   };
   struct arg *argvec;
@@ -3677,12 +3638,11 @@ emit_library_call_value_1 (retval, orgfu
 #else
 			   argvec[count].reg != 0,
 #endif
-			   NULL_TREE, &args_size, &argvec[count].offset,
-			   &argvec[count].size, &alignment_pad);
+			   0, NULL_TREE, &args_size, &argvec[count].locate);
 
       if (argvec[count].reg == 0 || argvec[count].partial != 0
 	  || reg_parm_stack_space > 0)
-	args_size.constant += argvec[count].size.constant;
+	args_size.constant += argvec[count].locate.size.constant;
 
       FUNCTION_ARG_ADVANCE (args_so_far, Pmode, (tree) 0, 1);
 
@@ -3796,18 +3756,15 @@ emit_library_call_value_1 (retval, orgfu
 #else
 			   argvec[count].reg != 0,
 #endif
-			   NULL_TREE, &args_size, &argvec[count].offset,
-			   &argvec[count].size, &alignment_pad);
+			   argvec[count].partial,
+			   NULL_TREE, &args_size, &argvec[count].locate);
 
-      if (argvec[count].size.var)
+      if (argvec[count].locate.size.var)
 	abort ();
 
-      if (reg_parm_stack_space == 0 && argvec[count].partial)
-	argvec[count].size.constant -= argvec[count].partial * UNITS_PER_WORD;
-
       if (argvec[count].reg == 0 || argvec[count].partial != 0
 	  || reg_parm_stack_space > 0)
-	args_size.constant += argvec[count].size.constant;
+	args_size.constant += argvec[count].locate.size.constant;
 
       FUNCTION_ARG_ADVANCE (args_so_far, mode, (tree) 0, 1);
     }
@@ -3945,11 +3902,11 @@ emit_library_call_value_1 (retval, orgfu
 #ifdef ARGS_GROW_DOWNWARD
 	      /* stack_slot is negative, but we want to index stack_usage_map
 		 with positive values.  */
-	      upper_bound = -argvec[argnum].offset.constant + 1;
-	      lower_bound = upper_bound - argvec[argnum].size.constant;
+	      upper_bound = -argvec[argnum].locate.offset.constant + 1;
+	      lower_bound = upper_bound - argvec[argnum].lcoate.size.constant;
 #else
-	      lower_bound = argvec[argnum].offset.constant;
-	      upper_bound = lower_bound + argvec[argnum].size.constant;
+	      lower_bound = argvec[argnum].locate.offset.constant;
+	      upper_bound = lower_bound + argvec[argnum].locate.size.constant;
 #endif
 
 	      i = lower_bound;
@@ -3962,19 +3919,16 @@ emit_library_call_value_1 (retval, orgfu
 
 	      if (i < upper_bound)
 		{
-		  /* We need to make a save area.  See what mode we can make
-		     it.  */
+		  /* We need to make a save area.  */
+		  unsigned int size
+		    = argvec[argnum].locate.size.constant * BITS_PER_UNIT;
 		  enum machine_mode save_mode
-		    = mode_for_size (argvec[argnum].size.constant
-				     * BITS_PER_UNIT,
-				     MODE_INT, 1);
+		    = mode_for_size (size, MODE_INT, 1);
+		  rtx adr
+		    = plus_constant (argblock,
+				     argvec[argnum].locate.offset.constant);
 		  rtx stack_area
-		    = gen_rtx_MEM
-		      (save_mode,
-		       memory_address
-		       (save_mode,
-			plus_constant (argblock,
-				       argvec[argnum].offset.constant)));
+		    = gen_rtx_MEM (save_mode, memory_address (save_mode, adr));
 		  argvec[argnum].save_area = gen_reg_rtx (save_mode);
 
 		  emit_move_insn (argvec[argnum].save_area, stack_area);
@@ -3983,8 +3937,9 @@ emit_library_call_value_1 (retval, orgfu
 
 	  emit_push_insn (val, mode, NULL_TREE, NULL_RTX, PARM_BOUNDARY,
 			  partial, reg, 0, argblock,
-			  GEN_INT (argvec[argnum].offset.constant),
-			  reg_parm_stack_space, ARGS_SIZE_RTX (alignment_pad));
+			  GEN_INT (argvec[argnum].locate.offset.constant),
+			  reg_parm_stack_space,
+			  ARGS_SIZE_RTX (argvec[argnum].locate.alignment_pad));
 
 	  /* Now mark the segment we just used.  */
 	  if (ACCUMULATE_OUTGOING_ARGS)
@@ -4189,12 +4144,10 @@ emit_library_call_value_1 (retval, orgfu
 	if (argvec[count].save_area)
 	  {
 	    enum machine_mode save_mode = GET_MODE (argvec[count].save_area);
-	    rtx stack_area
-	      = gen_rtx_MEM (save_mode,
-			     memory_address
-			     (save_mode,
-			      plus_constant (argblock,
-					     argvec[count].offset.constant)));
+	    rtx adr = plus_constant (argblock,
+				     argvec[count].locate.offset.constant);
+	    rtx stack_area = gen_rtx_MEM (save_mode,
+					  memory_address (save_mode, adr));
 
 	    emit_move_insn (stack_area, argvec[count].save_area);
 	  }
@@ -4321,14 +4274,14 @@ store_one_arg (arg, argblock, flags, var
 	  else
 	    upper_bound = 0;
 
-	  lower_bound = upper_bound - arg->size.constant;
+	  lower_bound = upper_bound - arg->locate.size.constant;
 #else
 	  if (GET_CODE (XEXP (arg->stack_slot, 0)) == PLUS)
 	    lower_bound = INTVAL (XEXP (XEXP (arg->stack_slot, 0), 1));
 	  else
 	    lower_bound = 0;
 
-	  upper_bound = lower_bound + arg->size.constant;
+	  upper_bound = lower_bound + arg->locate.size.constant;
 #endif
 
 	  i = lower_bound;
@@ -4341,13 +4294,11 @@ store_one_arg (arg, argblock, flags, var
 
 	  if (i < upper_bound)
 	    {
-	      /* We need to make a save area.  See what mode we can make it.  */
-	      enum machine_mode save_mode
-		= mode_for_size (arg->size.constant * BITS_PER_UNIT, MODE_INT, 1);
-	      rtx stack_area
-		= gen_rtx_MEM (save_mode,
-			       memory_address (save_mode,
-					       XEXP (arg->stack_slot, 0)));
+	      /* We need to make a save area.  */
+	      unsigned int size = arg->locate.size.constant * BITS_PER_UNIT;
+	      enum machine_mode save_mode = mode_for_size (size, MODE_INT, 1);
+	      rtx adr = memory_address (save_mode, XEXP (arg->stack_slot, 0));
+	      rtx stack_area = gen_rtx_MEM (save_mode, adr);
 
 	      if (save_mode == BLKmode)
 		{
@@ -4475,8 +4426,8 @@ store_one_arg (arg, argblock, flags, var
 	 This can either be done with push or copy insns.  */
       emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX, 
 		      PARM_BOUNDARY, partial, reg, used - size, argblock,
-		      ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
-		      ARGS_SIZE_RTX (arg->alignment_pad));
+		      ARGS_SIZE_RTX (arg->locate.offset), reg_parm_stack_space,
+		      ARGS_SIZE_RTX (arg->locate.alignment_pad));
 
       /* Unless this is a partially-in-register argument, the argument is now
 	 in the stack.  */
@@ -4498,16 +4449,17 @@ store_one_arg (arg, argblock, flags, var
       /* Round its size up to a multiple
 	 of the allocation unit for arguments.  */
 
-      if (arg->size.var != 0)
+      if (arg->locate.size.var != 0)
 	{
 	  excess = 0;
-	  size_rtx = ARGS_SIZE_RTX (arg->size);
+	  size_rtx = ARGS_SIZE_RTX (arg->locate.size);
 	}
       else
 	{
 	  /* PUSH_ROUNDING has no effect on us, because
 	     emit_push_insn for BLKmode is careful to avoid it.  */
-	  excess = (arg->size.constant - int_size_in_bytes (TREE_TYPE (pval))
+	  excess = (arg->locate.size.constant
+		    - int_size_in_bytes (TREE_TYPE (pval))
 		    + partial * UNITS_PER_WORD);
 	  size_rtx = expand_expr (size_in_bytes (TREE_TYPE (pval)),
 				  NULL_RTX, TYPE_MODE (sizetype), 0);
@@ -4521,7 +4473,7 @@ store_one_arg (arg, argblock, flags, var
 	 PARM_BOUNDARY, but the actual argument isn't.  */
       if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward)
 	{
-	  if (arg->size.var)
+	  if (arg->locate.size.var)
 	    parm_align = BITS_PER_UNIT;
 	  else if (excess)
 	    {
@@ -4533,7 +4485,7 @@ store_one_arg (arg, argblock, flags, var
       if ((flags & ECF_SIBCALL) && GET_CODE (arg->value) == MEM)
 	{
 	  /* emit_push_insn might not work properly if arg->value and
-	     argblock + arg->offset areas overlap.  */
+	     argblock + arg->locate.offset areas overlap.  */
 	  rtx x = arg->value;
 	  int i = 0;
 
@@ -4547,17 +4499,17 @@ store_one_arg (arg, argblock, flags, var
 		i = INTVAL (XEXP (XEXP (x, 0), 1));
 
 	      /* expand_call should ensure this */
-	      if (arg->offset.var || GET_CODE (size_rtx) != CONST_INT)
+	      if (arg->locate.offset.var || GET_CODE (size_rtx) != CONST_INT)
 		abort ();
 
-	      if (arg->offset.constant > i)
+	      if (arg->locate.offset.constant > i)
 		{
-		  if (arg->offset.constant < i + INTVAL (size_rtx))
+		  if (arg->locate.offset.constant < i + INTVAL (size_rtx))
 		    sibcall_failure = 1;
 		}
-	      else if (arg->offset.constant < i)
+	      else if (arg->locate.offset.constant < i)
 		{
-		  if (i < arg->offset.constant + INTVAL (size_rtx))
+		  if (i < arg->locate.offset.constant + INTVAL (size_rtx))
 		    sibcall_failure = 1;
 		}
 	    }
@@ -4565,8 +4517,8 @@ store_one_arg (arg, argblock, flags, var
 
       emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx,
 		      parm_align, partial, reg, excess, argblock,
-		      ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
-		      ARGS_SIZE_RTX (arg->alignment_pad));
+		      ARGS_SIZE_RTX (arg->locate.offset), reg_parm_stack_space,
+		      ARGS_SIZE_RTX (arg->locate.alignment_pad));
 
       /* Unless this is a partially-in-register argument, the argument is now
 	 in the stack.
diff -urp gcc.orig/gcc/expr.h gcc1/gcc/expr.h
--- gcc.orig/gcc/expr.h	2003-04-22 18:55:34.000000000 +0930
+++ gcc1/gcc/expr.h	2003-04-24 11:29:11.000000000 +0930
@@ -63,6 +63,8 @@ enum expand_modifier {EXPAND_NORMAL = 0,
    more information.  */
 #define OK_DEFER_POP (inhibit_defer_pop -= 1)
 \f
+enum direction {none, upward, downward};
+
 #ifdef TREE_CODE /* Don't lose if tree.h not included.  */
 /* Structure to record the size of a sequence of arguments
    as the sum of a tree-expression and a constant.  This structure is
@@ -74,6 +76,24 @@ struct args_size
   HOST_WIDE_INT constant;
   tree var;
 };
+
+/* Package up various arg related fields of struct args for
+   locate_and_pad_parm.  */
+struct locate_and_pad_arg_data
+{
+  /* Size of this argument on the stack, rounded up for any padding it
+     gets.  If REG_PARM_STACK_SPACE is defined, then register parms are
+     counted here, otherwise they aren't.  */
+  struct args_size size;
+  /* Offset of this argument from beginning of stack-args.  */
+  struct args_size offset;
+  /* Offset to the start of the stack slot.  Different from OFFSET
+     if this arg pads downward.  */
+  struct args_size slot_offset;
+  /* The amount that the stack pointer needs to be adjusted to
+     force alignment for the next argument.  */
+  struct args_size alignment_pad;
+};
 #endif
 
 /* Add the value of the tree INC to the `struct args_size' TO.  */
@@ -119,8 +139,6 @@ do {							\
    usually pad upward, but pad short args downward on
    big-endian machines.  */
 
-enum direction {none, upward, downward};  /* Value has this type.  */
-
 #ifndef FUNCTION_ARG_PADDING
 #define FUNCTION_ARG_PADDING(MODE, TYPE)				\
   (! BYTES_BIG_ENDIAN							\
@@ -567,11 +585,9 @@ extern rtx expand_shift PARAMS ((enum tr
 				 rtx, int));
 extern rtx expand_divmod PARAMS ((int, enum tree_code, enum machine_mode, rtx,
 				  rtx, rtx, int));
-extern void locate_and_pad_parm PARAMS ((enum machine_mode, tree, int, tree,
-					 struct args_size *,
-					 struct args_size *,
-					 struct args_size *,
-					 struct args_size *));
+extern void locate_and_pad_parm PARAMS ((enum machine_mode, tree, int, int,
+					 tree, struct args_size *,
+					 struct locate_and_pad_arg_data *));
 extern rtx expand_inline_function PARAMS ((tree, tree, rtx, int, tree, rtx));
 
 /* Return the CODE_LABEL rtx for a LABEL_DECL, creating it if necessary.  */
diff -urp gcc.orig/gcc/function.c gcc1/gcc/function.c
--- gcc.orig/gcc/function.c	2003-04-23 11:29:02.000000000 +0930
+++ gcc1/gcc/function.c	2003-04-24 17:50:45.000000000 +0930
@@ -4338,12 +4338,7 @@ assign_parms (fndecl)
      tree fndecl;
 {
   tree parm;
-  rtx entry_parm = 0;
-  rtx stack_parm = 0;
   CUMULATIVE_ARGS args_so_far;
-  enum machine_mode promoted_mode, passed_mode;
-  enum machine_mode nominal_mode, promoted_nominal_mode;
-  int unsignedp;
   /* Total space needed so far for args on the stack,
      given as a constant and a tree-expression.  */
   struct args_size stack_args_size;
@@ -4357,8 +4352,8 @@ assign_parms (fndecl)
 #ifdef SETUP_INCOMING_VARARGS
   int varargs_setup = 0;
 #endif
+  int reg_parm_stack_space = 0;
   rtx conversion_insns = 0;
-  struct args_size alignment_pad;
 
   /* Nonzero if function takes extra anonymous args.
      This means the last named arg must be on the stack
@@ -4405,6 +4400,14 @@ assign_parms (fndecl)
   max_parm_reg = LAST_VIRTUAL_REGISTER + 1;
   parm_reg_stack_loc = (rtx *) ggc_alloc_cleared (max_parm_reg * sizeof (rtx));
 
+#ifdef REG_PARM_STACK_SPACE
+#ifdef MAYBE_REG_PARM_STACK_SPACE
+  reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
+#else
+  reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
+#endif
+#endif
+
 #ifdef INIT_CUMULATIVE_INCOMING_ARGS
   INIT_CUMULATIVE_INCOMING_ARGS (args_so_far, fntype, NULL_RTX);
 #else
@@ -4417,14 +4420,19 @@ assign_parms (fndecl)
 
   for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
     {
-      struct args_size stack_offset;
-      struct args_size arg_size;
+      rtx entry_parm;
+      rtx stack_parm;
+      enum machine_mode promoted_mode, passed_mode;
+      enum machine_mode nominal_mode, promoted_nominal_mode;
+      int unsignedp;
+      struct locate_and_pad_arg_data locate;
       int passed_pointer = 0;
       int did_conversion = 0;
       tree passed_type = DECL_ARG_TYPE (parm);
       tree nominal_type = TREE_TYPE (parm);
-      int pretend_named;
       int last_named = 0, named_arg;
+      int in_regs;
+      int partial = 0;
 
       /* Set LAST_NAMED if this is last named arg before last
 	 anonymous args.  */
@@ -4488,7 +4496,7 @@ assign_parms (fndecl)
 	  || TREE_ADDRESSABLE (passed_type)
 #ifdef FUNCTION_ARG_PASS_BY_REFERENCE
 	  || FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, passed_mode,
-					      passed_type, named_arg)
+					     passed_type, named_arg)
 #endif
 	  )
 	{
@@ -4558,27 +4566,52 @@ assign_parms (fndecl)
 	 it came in a register so that REG_PARM_STACK_SPACE isn't skipped.
 	 In this case, we call FUNCTION_ARG with NAMED set to 1 instead of
 	 0 as it was the previous time.  */
-
-      pretend_named = named_arg || PRETEND_OUTGOING_VARARGS_NAMED;
-      locate_and_pad_parm (promoted_mode, passed_type,
+      in_regs = entry_parm != 0;
 #ifdef STACK_PARMS_IN_REG_PARM_AREA
-			   1,
-#else
+      in_regs = 1;
+#endif
+      if (!in_regs && !named_arg)
+	{
+	  int pretend_named = PRETEND_OUTGOING_VARARGS_NAMED;
+	  if (pretend_named)
+	    {
 #ifdef FUNCTION_INCOMING_ARG
-			   FUNCTION_INCOMING_ARG (args_so_far, promoted_mode,
-						  passed_type,
-						  pretend_named) != 0,
+	      in_regs = FUNCTION_INCOMING_ARG (args_so_far, promoted_mode,
+					       passed_type,
+					       pretend_named) != 0;
 #else
-			   FUNCTION_ARG (args_so_far, promoted_mode,
-					 passed_type,
-					 pretend_named) != 0,
+	      in_regs = FUNCTION_ARG (args_so_far, promoted_mode,
+				      passed_type,
+				      pretend_named) != 0;
 #endif
+	    }
+	}
+
+      /* If this parameter was passed both in registers and in the stack,
+	 use the copy on the stack.  */
+      if (MUST_PASS_IN_STACK (promoted_mode, passed_type))
+	entry_parm = 0;
+
+#ifdef FUNCTION_ARG_PARTIAL_NREGS
+      if (entry_parm)
+	partial = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, promoted_mode,
+					      passed_type, named_arg);
 #endif
-			   fndecl, &stack_args_size, &stack_offset, &arg_size,
-			   &alignment_pad);
+
+      memset (&locate, 0, sizeof (locate));
+      locate_and_pad_parm (promoted_mode, passed_type, in_regs,
+			   entry_parm ? partial : 0, fndecl,
+			   &stack_args_size, &locate);
 
       {
-	rtx offset_rtx = ARGS_SIZE_RTX (stack_offset);
+	rtx offset_rtx;
+
+	/* If we're passing this arg using a reg, make its stack home
+	   the aligned stack slot.  */
+	if (entry_parm)
+	  offset_rtx = ARGS_SIZE_RTX (locate.slot_offset);
+	else
+	  offset_rtx = ARGS_SIZE_RTX (locate.offset);
 
 	if (offset_rtx == const0_rtx)
 	  stack_parm = gen_rtx_MEM (promoted_mode, internal_arg_pointer);
@@ -4595,12 +4628,6 @@ assign_parms (fndecl)
 	  set_reg_attrs_for_parm (entry_parm, stack_parm);
       }
 
-      /* If this parameter was passed both in registers and in the stack,
-	 use the copy on the stack.  */
-      if (MUST_PASS_IN_STACK (promoted_mode, passed_type))
-	entry_parm = 0;
-
-#ifdef FUNCTION_ARG_PARTIAL_NREGS
       /* If this parm was passed part in regs and part in memory,
 	 pretend it arrived entirely in memory
 	 by pushing the register-part onto the stack.
@@ -4609,39 +4636,31 @@ assign_parms (fndecl)
 	 we could put it together in a pseudoreg directly,
 	 but for now that's not worth bothering with.  */
 
-      if (entry_parm)
+      if (partial)
 	{
-	  int nregs = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, promoted_mode,
-						  passed_type, named_arg);
-
-	  if (nregs > 0)
-	    {
-#if defined (REG_PARM_STACK_SPACE) && !defined (MAYBE_REG_PARM_STACK_SPACE)
-	      /* When REG_PARM_STACK_SPACE is nonzero, stack space for
-		 split parameters was allocated by our caller, so we
-		 won't be pushing it in the prolog.  */
-	      if (REG_PARM_STACK_SPACE (fndecl) == 0)
-#endif
-	      current_function_pretend_args_size
-		= (((nregs * UNITS_PER_WORD) + (PARM_BOUNDARY / BITS_PER_UNIT) - 1)
-		   / (PARM_BOUNDARY / BITS_PER_UNIT)
-		   * (PARM_BOUNDARY / BITS_PER_UNIT));
+#ifndef MAYBE_REG_PARM_STACK_SPACE
+	  /* When REG_PARM_STACK_SPACE is nonzero, stack space for
+	     split parameters was allocated by our caller, so we
+	     won't be pushing it in the prolog.  */
+	  if (reg_parm_stack_space)
+#endif
+	  current_function_pretend_args_size
+	    = (((partial * UNITS_PER_WORD) + (PARM_BOUNDARY / BITS_PER_UNIT) - 1)
+	       / (PARM_BOUNDARY / BITS_PER_UNIT)
+	       * (PARM_BOUNDARY / BITS_PER_UNIT));
 
-	      /* Handle calls that pass values in multiple non-contiguous
-		 locations.  The Irix 6 ABI has examples of this.  */
-	      if (GET_CODE (entry_parm) == PARALLEL)
-		emit_group_store (validize_mem (stack_parm), entry_parm,
-				  int_size_in_bytes (TREE_TYPE (parm)));
+	  /* Handle calls that pass values in multiple non-contiguous
+	     locations.  The Irix 6 ABI has examples of this.  */
+	  if (GET_CODE (entry_parm) == PARALLEL)
+	    emit_group_store (validize_mem (stack_parm), entry_parm,
+			      int_size_in_bytes (TREE_TYPE (parm)));
 
-	      else
-		move_block_from_reg (REGNO (entry_parm),
-				     validize_mem (stack_parm), nregs,
-				     int_size_in_bytes (TREE_TYPE (parm)));
+	  else
+	    move_block_from_reg (REGNO (entry_parm), validize_mem (stack_parm),
+				 partial, int_size_in_bytes (TREE_TYPE (parm)));
 
-	      entry_parm = stack_parm;
-	    }
+	  entry_parm = stack_parm;
 	}
-#endif
 
       /* If we didn't decide this parm came in a register,
 	 by default it came on the stack.  */
@@ -4672,9 +4691,9 @@ assign_parms (fndecl)
 #endif
 	  )
 	{
-	  stack_args_size.constant += arg_size.constant;
-	  if (arg_size.var)
-	    ADD_PARM_SIZE (stack_args_size, arg_size.var);
+	  stack_args_size.constant += locate.size.constant;
+	  if (locate.size.var)
+	    ADD_PARM_SIZE (stack_args_size, locate.size.var);
 	}
       else
 	/* No stack slot was pushed for this parm.  */
@@ -4698,7 +4717,7 @@ assign_parms (fndecl)
 
       /* If parm was passed in memory, and we need to convert it on entry,
 	 don't store it back in that same slot.  */
-      if (entry_parm != 0
+      if (entry_parm == stack_parm
 	  && nominal_mode != BLKmode && nominal_mode != passed_mode)
 	stack_parm = 0;
 
@@ -5021,7 +5040,7 @@ assign_parms (fndecl)
 	      && ! did_conversion
 	      && stack_parm != 0
 	      && GET_CODE (stack_parm) == MEM
-	      && stack_offset.var == 0
+	      && locate.offset.var == 0
 	      && reg_mentioned_p (virtual_incoming_args_rtx,
 				  XEXP (stack_parm, 0)))
 	    {
@@ -5107,7 +5126,8 @@ assign_parms (fndecl)
 		{
 		  stack_parm
 		    = assign_stack_local (GET_MODE (entry_parm),
-					  GET_MODE_SIZE (GET_MODE (entry_parm)), 0);
+					  GET_MODE_SIZE (GET_MODE (entry_parm)),
+					  0);
 		  set_mem_attributes (stack_parm, parm, 1);
 		}
 
@@ -5278,8 +5298,11 @@ promoted_input_arg (regno, pmode, punsig
    INITIAL_OFFSET_PTR points to the current offset into the stacked
    arguments.
 
-   The starting offset and size for this parm are returned in *OFFSET_PTR
-   and *ARG_SIZE_PTR, respectively.
+   The starting offset and size for this parm are returned in
+   LOCATE->OFFSET and LOCATE->SIZE, respectively.  When IN_REGS is
+   nonzero, the offset is that of stack slot, which is returned in
+   LOCATE->SLOT_OFFSET.  LOCATE->ALIGNMENT_PAD is the amount of
+   padding required from the initial offset ptr to the stack slot.
 
    IN_REGS is nonzero if the argument will be passed in registers.  It will
    never be set if REG_PARM_STACK_SPACE is not defined.
@@ -5296,45 +5319,39 @@ promoted_input_arg (regno, pmode, punsig
    initial offset is not affected by this rounding, while the size always
    is and the starting offset may be.  */
 
-/*  offset_ptr will be negative for ARGS_GROW_DOWNWARD case;
-    initial_offset_ptr is positive because locate_and_pad_parm's
+/*  LOCATE->OFFSET will be negative for ARGS_GROW_DOWNWARD case;
+    INITIAL_OFFSET_PTR is positive because locate_and_pad_parm's
     callers pass in the total size of args so far as
-    initial_offset_ptr. arg_size_ptr is always positive.  */
+    INITIAL_OFFSET_PTR.  LOCATE->SIZE is always positive.  */
 
 void
-locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
-		     initial_offset_ptr, offset_ptr, arg_size_ptr,
-		     alignment_pad)
+locate_and_pad_parm (passed_mode, type, in_regs, partial, fndecl,
+		     initial_offset_ptr, locate)
      enum machine_mode passed_mode;
      tree type;
-     int in_regs ATTRIBUTE_UNUSED;
+     int in_regs;
+     int partial;
      tree fndecl ATTRIBUTE_UNUSED;
      struct args_size *initial_offset_ptr;
-     struct args_size *offset_ptr;
-     struct args_size *arg_size_ptr;
-     struct args_size *alignment_pad;
-
+     struct locate_and_pad_arg_data *locate;
 {
-  tree sizetree
-    = type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
-  enum direction where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
-  int boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
-#ifdef ARGS_GROW_DOWNWARD
-  tree s2 = sizetree;
-#endif
+  tree sizetree;
+  enum direction where_pad;
+  int boundary;
+  int reg_parm_stack_space = 0;
+  int part_size_in_regs;
 
 #ifdef REG_PARM_STACK_SPACE
+#ifdef MAYBE_REG_PARM_STACK_SPACE
+  reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
+#else
+  reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
+#endif
+
   /* If we have found a stack parm before we reach the end of the
      area reserved for registers, skip that area.  */
   if (! in_regs)
     {
-      int reg_parm_stack_space = 0;
-
-#ifdef MAYBE_REG_PARM_STACK_SPACE
-      reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
-#else
-      reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
-#endif
       if (reg_parm_stack_space > 0)
 	{
 	  if (initial_offset_ptr->var)
@@ -5350,54 +5367,56 @@ locate_and_pad_parm (passed_mode, type, 
     }
 #endif /* REG_PARM_STACK_SPACE */
 
-  arg_size_ptr->var = 0;
-  arg_size_ptr->constant = 0;
-  alignment_pad->var = 0;
-  alignment_pad->constant = 0;
+  part_size_in_regs = 0;
+  if (reg_parm_stack_space == 0)
+    part_size_in_regs = ((partial * UNITS_PER_WORD)
+			 / (PARM_BOUNDARY / BITS_PER_UNIT)
+			 * (PARM_BOUNDARY / BITS_PER_UNIT));
+
+  sizetree
+    = type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
+  where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
+  boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
 
 #ifdef ARGS_GROW_DOWNWARD
+  locate->slot_offset.constant = -initial_offset_ptr->constant;
   if (initial_offset_ptr->var)
-    {
-      offset_ptr->constant = 0;
-      offset_ptr->var = size_binop (MINUS_EXPR, ssize_int (0),
-				    initial_offset_ptr->var);
-    }
-  else
-    {
-      offset_ptr->constant = -initial_offset_ptr->constant;
-      offset_ptr->var = 0;
-    }
+    locate->slot_offset.var = size_binop (MINUS_EXPR, ssize_int (0),
+					  initial_offset_ptr->var);
 
-  if (where_pad != none
-      && (!host_integerp (sizetree, 1)
-	  || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
-    s2 = round_up (s2, PARM_BOUNDARY / BITS_PER_UNIT);
-  SUB_PARM_SIZE (*offset_ptr, s2);
+  {
+    tree s2 = sizetree;
+    if (where_pad != none
+	&& (!host_integerp (sizetree, 1)
+	    || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
+      s2 = round_up (s2, PARM_BOUNDARY / BITS_PER_UNIT);
+    SUB_PARM_SIZE (locate->slot_offset, s2);
+  }
+
+  locate->slot_offset.constant += part_size_in_regs;
 
   if (!in_regs
 #ifdef REG_PARM_STACK_SPACE
       || REG_PARM_STACK_SPACE (fndecl) > 0
 #endif
      )
-    pad_to_arg_alignment (offset_ptr, boundary, alignment_pad);
+    pad_to_arg_alignment (&locate->slot_offset, boundary,
+			  &locate->alignment_pad);
 
+  locate->size.constant = (-initial_offset_ptr->constant
+			   - locate->slot_offset.constant);
   if (initial_offset_ptr->var)
-    arg_size_ptr->var = size_binop (MINUS_EXPR,
-				    size_binop (MINUS_EXPR,
-						ssize_int (0),
-						initial_offset_ptr->var),
-				    offset_ptr->var);
-
-  else
-    arg_size_ptr->constant = (-initial_offset_ptr->constant
-			      - offset_ptr->constant);
-
-  /* Pad_below needs the pre-rounded size to know how much to pad below.
-     We only pad parameters which are not in registers as they have their
-     padding done elsewhere.  */
-  if (where_pad == downward
-      && !in_regs)
-    pad_below (offset_ptr, passed_mode, sizetree);
+    locate->size.var = size_binop (MINUS_EXPR,
+				   size_binop (MINUS_EXPR,
+					       ssize_int (0),
+					       initial_offset_ptr->var),
+				   locate->slot_offset.var);
+
+  /* Pad_below needs the pre-rounded size to know how much to pad
+     below.  */
+  locate->offset = locate->slot_offset;
+  if (where_pad == downward)
+    pad_below (&locate->offset, passed_mode, sizetree);
 
 #else /* !ARGS_GROW_DOWNWARD */
   if (!in_regs
@@ -5405,8 +5424,9 @@ locate_and_pad_parm (passed_mode, type, 
       || REG_PARM_STACK_SPACE (fndecl) > 0
 #endif
       )
-    pad_to_arg_alignment (initial_offset_ptr, boundary, alignment_pad);
-  *offset_ptr = *initial_offset_ptr;
+    pad_to_arg_alignment (initial_offset_ptr, boundary,
+			  &locate->alignment_pad);
+  locate->slot_offset = *initial_offset_ptr;
 
 #ifdef PUSH_ROUNDING
   if (passed_mode != BLKmode)
@@ -5415,18 +5435,18 @@ locate_and_pad_parm (passed_mode, type, 
 
   /* Pad_below needs the pre-rounded size to know how much to pad below
      so this must be done before rounding up.  */
-  if (where_pad == downward
-    /* However, BLKmode args passed in regs have their padding done elsewhere.
-       The stack slot must be able to hold the entire register.  */
-      && !(in_regs && passed_mode == BLKmode))
-    pad_below (offset_ptr, passed_mode, sizetree);
+  locate->offset = locate->slot_offset;
+  if (where_pad == downward)
+    pad_below (&locate->offset, passed_mode, sizetree);
 
   if (where_pad != none
       && (!host_integerp (sizetree, 1)
 	  || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
     sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
 
-  ADD_PARM_SIZE (*arg_size_ptr, sizetree);
+  ADD_PARM_SIZE (locate->size, sizetree);
+
+  locate->size.constant -= part_size_in_regs;
 #endif /* ARGS_GROW_DOWNWARD */
 }
 
@@ -5465,7 +5485,8 @@ pad_to_arg_alignment (offset_ptr, bounda
 #endif
 	      (ARGS_SIZE_TREE (*offset_ptr),
 	       boundary / BITS_PER_UNIT);
-	  offset_ptr->constant = 0; /*?*/
+	  /* ARGS_SIZE_TREE includes constant term.  */
+	  offset_ptr->constant = 0;
 	  if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
 	    alignment_pad->var = size_binop (MINUS_EXPR, offset_ptr->var,
 					     save_var);

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [RFC] PowerPC select_section / unique_section
@ 2002-08-21 11:09 David Edelsohn
  2002-08-21 11:21 ` Franz Sirl
  2002-08-21 18:54 ` Alan Modra
  0 siblings, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2002-08-21 11:09 UTC (permalink / raw)
  To: Geoff Keating; +Cc: gcc-patches

	While investigating a problem with PowerPC ELF section decisions,
I realized that the functions need to treat PPC64 as if flag_pic were set.
I also noticed a discrepancy between the PowerPC definition and the
default definition in varasm.c: rs6000_elf_select_section should not
default to readonly when reloc is defined.

	My remaining concern is that the readonly algorithm in
rs6000_elf_unique_section does not match the algorithm in
rs6000_elf_select_section: the handling of decl CONSTRUCTOR and the
handling of default readonly.  Should the definitions match?

Thanks, David


	* config/rs6000/rs6000.c (rs6000_elf_select_section): Treat
	DEFAULT_ABI == ABI_AIX like PIC.  Test PIC & reloc for readonly
	default.
	(rs6000_elf_unique_section): Treat DEFAULT_ABI == ABI_AIX like
	PIC.
	(rs6000_xcoff_select_section): Update to recent readonly
	algorithm.

Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.364
diff -c -p -r1.364 rs6000.c
*** rs6000.c	19 Aug 2002 16:32:53 -0000	1.364
--- rs6000.c	21 Aug 2002 16:42:25 -0000
*************** rs6000_elf_select_section (decl, reloc, 
*** 12432,12439 ****
       unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
  {
    int size = int_size_in_bytes (TREE_TYPE (decl));
!   int needs_sdata;
!   int readonly;
    static void (* const sec_funcs[4]) PARAMS ((void)) = {
      &readonly_data_section,
      &sdata2_section,
--- 12462,12469 ----
       unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
  {
    int size = int_size_in_bytes (TREE_TYPE (decl));
!   bool needs_sdata;
!   bool readonly;
    static void (* const sec_funcs[4]) PARAMS ((void)) = {
      &readonly_data_section,
      &sdata2_section,
*************** rs6000_elf_select_section (decl, reloc, 
*** 12447,12468 ****
  		 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
  
    if (TREE_CODE (decl) == STRING_CST)
!     readonly = ! flag_writable_strings;
    else if (TREE_CODE (decl) == VAR_DECL)
!     readonly = (! (flag_pic && reloc)
  		&& TREE_READONLY (decl)
! 		&& ! TREE_SIDE_EFFECTS (decl)
  		&& DECL_INITIAL (decl)
  		&& DECL_INITIAL (decl) != error_mark_node
  		&& TREE_CONSTANT (DECL_INITIAL (decl)));
    else if (TREE_CODE (decl) == CONSTRUCTOR)
!     readonly = (! (flag_pic && reloc)
! 		&& ! TREE_SIDE_EFFECTS (decl)
  		&& TREE_CONSTANT (decl));
    else
!     readonly = 1;
    if (needs_sdata && rs6000_sdata != SDATA_EABI)
!     readonly = 0;
    
    (*sec_funcs[(readonly ? 0 : 2) + (needs_sdata ? 1 : 0)])();
  }
--- 12477,12499 ----
  		 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
  
    if (TREE_CODE (decl) == STRING_CST)
!     readonly = !flag_writable_strings;
    else if (TREE_CODE (decl) == VAR_DECL)
!     readonly = (!((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
  		&& TREE_READONLY (decl)
! 		&& !TREE_SIDE_EFFECTS (decl)
  		&& DECL_INITIAL (decl)
  		&& DECL_INITIAL (decl) != error_mark_node
  		&& TREE_CONSTANT (DECL_INITIAL (decl)));
    else if (TREE_CODE (decl) == CONSTRUCTOR)
!     readonly = (!((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
! 		&& !TREE_SIDE_EFFECTS (decl)
  		&& TREE_CONSTANT (decl));
    else
!     readonly = !((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc);
! 
    if (needs_sdata && rs6000_sdata != SDATA_EABI)
!     readonly = false;
    
    (*sec_funcs[(readonly ? 0 : 2) + (needs_sdata ? 1 : 0)])();
  }
*************** rs6000_elf_unique_section (decl, reloc)
*** 12501,12517 ****
      sec = 6;
    else
      {
!       int readonly;
!       int needs_sdata;
        int size;
  
-       readonly = 1;
        if (TREE_CODE (decl) == STRING_CST)
! 	readonly = ! flag_writable_strings;
        else if (TREE_CODE (decl) == VAR_DECL)
! 	readonly = (! (flag_pic && reloc)
  		    && TREE_READONLY (decl)
! 		    && ! TREE_SIDE_EFFECTS (decl)
  		    && TREE_CONSTANT (DECL_INITIAL (decl)));
  
        size = int_size_in_bytes (TREE_TYPE (decl));
--- 12532,12547 ----
      sec = 6;
    else
      {
!       bool readonly = true;
!       bool needs_sdata;
        int size;
  
        if (TREE_CODE (decl) == STRING_CST)
! 	readonly = !flag_writable_strings;
        else if (TREE_CODE (decl) == VAR_DECL)
! 	readonly = (!((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
  		    && TREE_READONLY (decl)
! 		    && !TREE_SIDE_EFFECTS (decl)
  		    && TREE_CONSTANT (DECL_INITIAL (decl)));
  
        size = int_size_in_bytes (TREE_TYPE (decl));
*************** rs6000_elf_unique_section (decl, reloc)
*** 12523,12529 ****
        if (DECL_INITIAL (decl) == 0
  	  || DECL_INITIAL (decl) == error_mark_node)
  	sec = 4;
!       else if (! readonly)
  	sec = 2;
        else
  	sec = 0;
--- 12553,12559 ----
        if (DECL_INITIAL (decl) == 0
  	  || DECL_INITIAL (decl) == error_mark_node)
  	sec = 4;
!       else if (!readonly)
  	sec = 2;
        else
  	sec = 0;
*************** xcoff_asm_named_section (name, flags)
*** 13104,13131 ****
  }
  
  static void
! rs6000_xcoff_select_section (exp, reloc, align)
!      tree exp;
       int reloc;
       unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
  {
!   if ((TREE_CODE (exp) == STRING_CST
!        && ! flag_writable_strings)
!       || (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd'
! 	  && TREE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp)
! 	  && DECL_INITIAL (exp)
! 	  && (DECL_INITIAL (exp) == error_mark_node
! 	      || TREE_CONSTANT (DECL_INITIAL (exp)))
! 	  && ! (reloc)))
      {
!       if (TREE_PUBLIC (exp))
          read_only_data_section ();
        else
          read_only_private_data_section ();
      }
    else
      {
!       if (TREE_PUBLIC (exp))
          data_section ();
        else
          private_data_section ();
--- 13134,13172 ----
  }
  
  static void
! rs6000_xcoff_select_section (decl, reloc, align)
!      tree decl;
       int reloc;
       unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
  {
!   bool readonly = false;
! 
!   if (TREE_CODE (decl) == STRING_CST)
!     readonly = !flag_writable_strings;
!   else if (TREE_CODE (decl) == VAR_DECL)
!     readonly = (!reloc
! 		&& TREE_READONLY (decl)
! 		&& !TREE_SIDE_EFFECTS (decl)
! 		&& DECL_INITIAL (decl)
! 		&& DECL_INITIAL (decl) != error_mark_node
! 		&& TREE_CONSTANT (DECL_INITIAL (decl)));
!   else if (TREE_CODE (decl) == CONSTRUCTOR)
!     readonly = (!reloc
! 		&& !TREE_SIDE_EFFECTS (decl)
! 		&& TREE_CONSTANT (decl));
!   else
!     readonly = !reloc;
! 
!   if (readonly)
      {
!       if (TREE_PUBLIC (decl))
          read_only_data_section ();
        else
          read_only_private_data_section ();
      }
    else
      {
!       if (TREE_PUBLIC (decl))
          data_section ();
        else
          private_data_section ();

^ permalink raw reply	[flat|nested] 875+ messages in thread
* power4 branch hints
@ 2002-08-01 18:39 Alan Modra
  2002-08-01 18:47 ` David Edelsohn
  0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2002-08-01 18:39 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

See the comment below.

	* config/rs6000/rs6000.c (output_cbranch): Hint differently for power4.
	* config/rs6000/rs6000.h (enum processor_type): Comment on ordering.

Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.355
diff -u -p -r1.355 rs6000.c
--- gcc/config/rs6000/rs6000.c	2 Aug 2002 01:08:01 -0000	1.355
+++ gcc/config/rs6000/rs6000.c	2 Aug 2002 01:21:55 -0000
@@ -8438,21 +8438,30 @@ output_cbranch (op, label, reversed, ins
   
   /* Maybe we have a guess as to how likely the branch is.  
      The old mnemonics don't have a way to specify this information.  */
+  pred = "";
   note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
   if (note != NULL_RTX)
     {
       /* PROB is the difference from 50%.  */
       int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
-      
-      /* For branches that are very close to 50%, assume not-taken.  */
-      if (abs (prob) > REG_BR_PROB_BASE / 20
-	  && ((prob > 0) ^ need_longbranch))
-	pred = "+";
-      else
-	pred = "-";
+      int cpu_version1_arch = rs6000_cpu < PROCESSOR_POWER4;
+
+      /* Only hint for highly probable/improbable branches on newer
+	 cpus as static prediction overrides processor dynamic
+	 prediction.  For older cpus we may as well always hint, but
+	 assume not taken for branches that are very close to 50% as a
+	 mispredicted taken branch is more expensive than a
+	 mispredicted not-taken branch.  */ 
+      if (cpu_version1_arch
+	  || abs (prob) > REG_BR_PROB_BASE / 100 * 48)
+	{
+	  if (abs (prob) > REG_BR_PROB_BASE / 20
+	      && ((prob > 0) ^ need_longbranch))
+	    pred = "+";
+	  else
+	    pred = "-";
+	}
     }
-  else
-    pred = "";
 
   if (label == NULL)
     s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
Index: gcc/config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.217
diff -u -p -r1.217 rs6000.h
--- gcc/config/rs6000/rs6000.h	1 Aug 2002 21:18:34 -0000	1.217
+++ gcc/config/rs6000/rs6000.h	2 Aug 2002 01:22:00 -0000
@@ -341,7 +341,10 @@ extern int target_flags;
 /* This is meant to be redefined in the host dependent files */
 #define SUBTARGET_SWITCHES
 
-/* Processor type.  Order must match cpu attribute in MD file.  */
+/* Processor type.  Order must match cpu attribute in MD file.
+   Please keep all Power4 type processors using "at" branch hints
+   after PROCESSOR_POWER4, and those using the "y" branch hints,
+   before.  */
 enum processor_type
  {
    PROCESSOR_RIOS1,

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 875+ messages in thread
[parent not found: <20020625081846.10430.qmail@sources.redhat.com>]
[parent not found: <20020712071414.GR30362@bubble.sa.bigpond.net.au>]
* convert 32-bit PowerPC GNU/Linux to TARGET_OS_CPP_BUILTINS
@ 2002-07-02 21:18 Matt Kraai
  2002-07-03  8:10 ` David Edelsohn
  0 siblings, 1 reply; 875+ messages in thread
From: Matt Kraai @ 2002-07-02 21:18 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1695 bytes --]

Howdy,

The following patch converts 32-bit PowerPC GNU/Linux to use
TARGET_OS_CPP_BUILTINS.  It was bootstrapped and regression
tested on powerpc-unknown-linux-gnu.

OK to commit?


If desired, I can also submit a patch which converts the other
targets which include rs6000/sysv4.h.  I will only test on
powerpc-unknown-linux-gnu and powerpc-eabisim, however.

Matt

	* config/rs6000/linux.h (CPP_PREDEFINES): Remove.
	(TARGET_OS_CPP_BUILTINS): New.

Index: gcc/config/rs6000/linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/linux.h,v
retrieving revision 1.31
diff -c -3 -p -r1.31 linux.h
*** gcc/config/rs6000/linux.h	3 Dec 2001 00:49:41 -0000	1.31
--- gcc/config/rs6000/linux.h	2 Jul 2002 17:27:45 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 28,35 ****
  #undef MD_STARTFILE_PREFIX
  
  #undef CPP_PREDEFINES
! #define CPP_PREDEFINES \
!  "-DPPC -D__ELF__ -Dpowerpc -Acpu=powerpc -Amachine=powerpc"
  
  #undef	CPP_OS_DEFAULT_SPEC
  #define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)"
--- 28,43 ----
  #undef MD_STARTFILE_PREFIX
  
  #undef CPP_PREDEFINES
! #define TARGET_OS_CPP_BUILTINS()          \
!   do                                      \
!     {                                     \
!       builtin_define_std ("PPC");         \
!       builtin_define_std ("__ELF__");     \
!       builtin_define_std ("powerpc");     \
!       builtin_assert ("cpu=powerpc");     \
!       builtin_assert ("machine=powerpc"); \
!     }                                     \
!   while (0)
  
  #undef	CPP_OS_DEFAULT_SPEC
  #define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)"

[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]

^ permalink raw reply	[flat|nested] 875+ messages in thread
* PowerPC cleanup and Power4
@ 2002-06-09  8:10 David Edelsohn
  2002-06-09  8:24 ` Neil Booth
  2002-06-09 10:05 ` Geoff Keating
  0 siblings, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2002-06-09  8:10 UTC (permalink / raw)
  To: gcc-patches

	The following patch cleans up some cruft and formatting in the
rs6000 port and adds preliminary, basic Power4 support.

	While exploring the scheduling, I noticed that cr_logical
attribute had not been applied to mfcr/mtcrf instructions.  This bumps
performance on processors with multiple SCIUs where cr_logical was being
scheduled inefficiently.

David

	* config/rs6000/{aix43.h,aix5.1} (ASM_CPU_SPEC): Add power3
	synonym for 630.  Add power4.  Remove embedded processors.  Use -m604
	assembler option.
	(CPP_CPU_SPEC): Add power3 and power4.
	(PROCESSOR_DEFAULT): Change to 604e.
	* config/rs6000/rs6000.h (ASM_CPU_SPEC): Similar additions.
	(CPP_CPU_SPEC): Similar additions.
	(enum process_type): Add POWER4.
	(RTX_COSTS): Add POWER4.
	(CPP_CPU_SPEC): Similar additions.
	* config/rs6000/linux64.h (PROCESSOR_DEFAULT): Define.
	* config/rs6000/rs6000.c (rs6000_override_options): Add power4.
	(rs6000_adjust_cost): Add 603, 604, 604e, 620, 630, Power4 to
	branch adjustment.
	(rs6000_issue_rate): Add Power4.
	* config/rs6000/rs6000.md (cpu attr): Add power4.
	(iu compare): Remove 604, 604e, 620, 630.
	Add basic Power4 scheduling information.
	(mfcr/mtcrf): Change type attribute to cr_logical.

Index: aix43.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/aix43.h,v
retrieving revision 1.23
diff -c -p -r1.23 aix43.h
*** aix43.h	23 May 2002 02:26:45 -0000	1.23
--- aix43.h	9 Jun 2002 14:40:29 -0000
*************** do {									\
*** 75,80 ****
--- 75,82 ----
  %{mcpu=common: -mcom} \
  %{mcpu=power: -mpwr} \
  %{mcpu=power2: -mpwr2} \
+ %{mcpu=power3: -m604} \
+ %{mcpu=power4: -m604} \
  %{mcpu=powerpc: -mppc} \
  %{mcpu=rios: -mpwr} \
  %{mcpu=rios1: -mpwr} \
*************** do {									\
*** 82,89 ****
  %{mcpu=rsc: -mpwr} \
  %{mcpu=rsc1: -mpwr} \
  %{mcpu=rs64a: -mppc} \
- %{mcpu=403: -mppc} \
- %{mcpu=505: -mppc} \
  %{mcpu=601: -m601} \
  %{mcpu=602: -mppc} \
  %{mcpu=603: -m603} \
--- 84,89 ----
*************** do {									\
*** 91,99 ****
  %{mcpu=604: -m604} \
  %{mcpu=604e: -m604} \
  %{mcpu=620: -mppc} \
! %{mcpu=630: -mppc} \
! %{mcpu=821: -mppc} \
! %{mcpu=860: -mppc}"
  
  #undef	ASM_DEFAULT_SPEC
  #define ASM_DEFAULT_SPEC "-mcom"
--- 91,97 ----
  %{mcpu=604: -m604} \
  %{mcpu=604e: -m604} \
  %{mcpu=620: -mppc} \
! %{mcpu=630: -m604}"
  
  #undef	ASM_DEFAULT_SPEC
  #define ASM_DEFAULT_SPEC "-mcom"
*************** do {									\
*** 135,140 ****
--- 133,140 ----
  %{mcpu=common: -D_ARCH_COM} \
  %{mcpu=power: -D_ARCH_PWR} \
  %{mcpu=power2: -D_ARCH_PWR2} \
+ %{mcpu=power3: -D_ARCH_PPC} \
+ %{mcpu=power4: -D_ARCH_PPC} \
  %{mcpu=powerpc: -D_ARCH_PPC} \
  %{mcpu=rios: -D_ARCH_PWR} \
  %{mcpu=rios1: -D_ARCH_PWR} \
*************** do {									\
*** 142,158 ****
  %{mcpu=rsc: -D_ARCH_PWR} \
  %{mcpu=rsc1: -D_ARCH_PWR} \
  %{mcpu=rs64a: -D_ARCH_PPC} \
- %{mcpu=403: -D_ARCH_PPC} \
- %{mcpu=505: -D_ARCH_PPC} \
  %{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
  %{mcpu=602: -D_ARCH_PPC} \
  %{mcpu=603: -D_ARCH_PPC} \
  %{mcpu=603e: -D_ARCH_PPC} \
  %{mcpu=604: -D_ARCH_PPC} \
  %{mcpu=620: -D_ARCH_PPC} \
! %{mcpu=630: -D_ARCH_PPC} \
! %{mcpu=821: -D_ARCH_PPC} \
! %{mcpu=860: -D_ARCH_PPC}"
  
  #undef	CPP_DEFAULT_SPEC
  #define CPP_DEFAULT_SPEC "-D_ARCH_COM"
--- 142,154 ----
  %{mcpu=rsc: -D_ARCH_PWR} \
  %{mcpu=rsc1: -D_ARCH_PWR} \
  %{mcpu=rs64a: -D_ARCH_PPC} \
  %{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
  %{mcpu=602: -D_ARCH_PPC} \
  %{mcpu=603: -D_ARCH_PPC} \
  %{mcpu=603e: -D_ARCH_PPC} \
  %{mcpu=604: -D_ARCH_PPC} \
  %{mcpu=620: -D_ARCH_PPC} \
! %{mcpu=630: -D_ARCH_PPC}"
  
  #undef	CPP_DEFAULT_SPEC
  #define CPP_DEFAULT_SPEC "-D_ARCH_COM"
*************** do {									\
*** 161,167 ****
  #define TARGET_DEFAULT MASK_NEW_MNEMONICS
  
  #undef PROCESSOR_DEFAULT
! #define PROCESSOR_DEFAULT PROCESSOR_PPC604
  
  /* Define this macro as a C expression for the initializer of an
     array of string to tell the driver program which options are
--- 157,163 ----
  #define TARGET_DEFAULT MASK_NEW_MNEMONICS
  
  #undef PROCESSOR_DEFAULT
! #define PROCESSOR_DEFAULT PROCESSOR_PPC604e
  
  /* Define this macro as a C expression for the initializer of an
     array of string to tell the driver program which options are
Index: aix51.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/aix51.h,v
retrieving revision 1.12
diff -c -p -r1.12 aix51.h
*** aix51.h	23 May 2002 02:26:45 -0000	1.12
--- aix51.h	9 Jun 2002 14:40:29 -0000
*************** do {									\
*** 75,80 ****
--- 75,82 ----
  %{mcpu=common: -mcom} \
  %{mcpu=power: -mpwr} \
  %{mcpu=power2: -mpwr2} \
+ %{mcpu=power3: -m604} \
+ %{mcpu=power4: -m604} \
  %{mcpu=powerpc: -mppc} \
  %{mcpu=rios: -mpwr} \
  %{mcpu=rios1: -mpwr} \
*************** do {									\
*** 82,89 ****
  %{mcpu=rsc: -mpwr} \
  %{mcpu=rsc1: -mpwr} \
  %{mcpu=rs64a: -mppc} \
- %{mcpu=403: -mppc} \
- %{mcpu=505: -mppc} \
  %{mcpu=601: -m601} \
  %{mcpu=602: -mppc} \
  %{mcpu=603: -m603} \
--- 84,89 ----
*************** do {									\
*** 91,99 ****
  %{mcpu=604: -m604} \
  %{mcpu=604e: -m604} \
  %{mcpu=620: -mppc} \
! %{mcpu=630: -mppc} \
! %{mcpu=821: -mppc} \
! %{mcpu=860: -mppc}"
  
  #undef	ASM_DEFAULT_SPEC
  #define ASM_DEFAULT_SPEC "-mcom"
--- 91,97 ----
  %{mcpu=604: -m604} \
  %{mcpu=604e: -m604} \
  %{mcpu=620: -mppc} \
! %{mcpu=630: -m604}"
  
  #undef	ASM_DEFAULT_SPEC
  #define ASM_DEFAULT_SPEC "-mcom"
*************** do {									\
*** 135,140 ****
--- 133,140 ----
  %{mcpu=common: -D_ARCH_COM} \
  %{mcpu=power: -D_ARCH_PWR} \
  %{mcpu=power2: -D_ARCH_PWR2} \
+ %{mcpu=power3: -D_ARCH_PPC} \
+ %{mcpu=power4: -D_ARCH_PPC} \
  %{mcpu=powerpc: -D_ARCH_PPC} \
  %{mcpu=rios: -D_ARCH_PWR} \
  %{mcpu=rios1: -D_ARCH_PWR} \
*************** do {									\
*** 142,158 ****
  %{mcpu=rsc: -D_ARCH_PWR} \
  %{mcpu=rsc1: -D_ARCH_PWR} \
  %{mcpu=rs64a: -D_ARCH_PPC} \
- %{mcpu=403: -D_ARCH_PPC} \
- %{mcpu=505: -D_ARCH_PPC} \
  %{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
  %{mcpu=602: -D_ARCH_PPC} \
  %{mcpu=603: -D_ARCH_PPC} \
  %{mcpu=603e: -D_ARCH_PPC} \
  %{mcpu=604: -D_ARCH_PPC} \
  %{mcpu=620: -D_ARCH_PPC} \
! %{mcpu=630: -D_ARCH_PPC} \
! %{mcpu=821: -D_ARCH_PPC} \
! %{mcpu=860: -D_ARCH_PPC}"
  
  #undef	CPP_DEFAULT_SPEC
  #define CPP_DEFAULT_SPEC "-D_ARCH_COM"
--- 142,154 ----
  %{mcpu=rsc: -D_ARCH_PWR} \
  %{mcpu=rsc1: -D_ARCH_PWR} \
  %{mcpu=rs64a: -D_ARCH_PPC} \
  %{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
  %{mcpu=602: -D_ARCH_PPC} \
  %{mcpu=603: -D_ARCH_PPC} \
  %{mcpu=603e: -D_ARCH_PPC} \
  %{mcpu=604: -D_ARCH_PPC} \
  %{mcpu=620: -D_ARCH_PPC} \
! %{mcpu=630: -D_ARCH_PPC}"
  
  #undef	CPP_DEFAULT_SPEC
  #define CPP_DEFAULT_SPEC "-D_ARCH_COM"
*************** do {									\
*** 161,167 ****
  #define TARGET_DEFAULT MASK_NEW_MNEMONICS
  
  #undef PROCESSOR_DEFAULT
! #define PROCESSOR_DEFAULT PROCESSOR_PPC604
  
  /* Define this macro as a C expression for the initializer of an
     array of string to tell the driver program which options are
--- 157,163 ----
  #define TARGET_DEFAULT MASK_NEW_MNEMONICS
  
  #undef PROCESSOR_DEFAULT
! #define PROCESSOR_DEFAULT PROCESSOR_PPC604e
  
  /* Define this macro as a C expression for the initializer of an
     array of string to tell the driver program which options are
Index: linux64.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/linux64.h,v
retrieving revision 1.15
diff -c -p -r1.15 linux64.h
*** linux64.h	5 Jun 2002 03:56:27 -0000	1.15
--- linux64.h	9 Jun 2002 14:40:29 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 31,36 ****
--- 31,39 ----
  #define TARGET_DEFAULT \
    (MASK_POWERPC | MASK_POWERPC64 | MASK_64BIT | MASK_NEW_MNEMONICS)
  
+ #undef PROCESSOR_DEFAULT
+ #define PROCESSOR_DEFAULT PROCESSOR_PPC630
+ 
  #undef  CPP_DEFAULT_SPEC
  #define CPP_DEFAULT_SPEC "-D_ARCH_PPC64"
  
Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.329
diff -c -p -r1.329 rs6000.c
*** rs6000.c	4 Jun 2002 07:09:27 -0000	1.329
--- rs6000.c	9 Jun 2002 14:40:30 -0000
*************** rs6000_override_options (default_cpu)
*** 353,358 ****
--- 353,361 ----
  	 {"power3", PROCESSOR_PPC630,
  	    MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
  	    POWER_MASKS | MASK_PPC_GPOPT},
+ 	 {"power4", PROCESSOR_POWER4,
+ 	    MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
+ 	    POWER_MASKS | MASK_PPC_GPOPT},
  	 {"powerpc", PROCESSOR_POWERPC,
  	    MASK_POWERPC | MASK_NEW_MNEMONICS,
  	    POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
*************** rs6000_adjust_cost (insn, link, dep_insn
*** 10696,10713 ****
        switch (get_attr_type (insn))
  	{
  	case TYPE_JMPREG:
!           /* Tell the first scheduling pass about the latency between
  	     a mtctr and bctr (and mtlr and br/blr).  The first
  	     scheduling pass will not know about this latency since
  	     the mtctr instruction, which has the latency associated
  	     to it, will be generated by reload.  */
!           return TARGET_POWER ? 5 : 4;
  	case TYPE_BRANCH:
  	  /* Leave some extra cycles between a compare and its
  	     dependent branch, to inhibit expensive mispredicts.  */
! 	  if ((rs6000_cpu_attr == CPU_PPC750
!                || rs6000_cpu_attr == CPU_PPC7400
!                || rs6000_cpu_attr == CPU_PPC7450)
  	      && recog_memoized (dep_insn)
  	      && (INSN_CODE (dep_insn) >= 0)
  	      && (get_attr_type (dep_insn) == TYPE_COMPARE
--- 10699,10722 ----
        switch (get_attr_type (insn))
  	{
  	case TYPE_JMPREG:
! 	  /* Tell the first scheduling pass about the latency between
  	     a mtctr and bctr (and mtlr and br/blr).  The first
  	     scheduling pass will not know about this latency since
  	     the mtctr instruction, which has the latency associated
  	     to it, will be generated by reload.  */
! 	  return TARGET_POWER ? 5 : 4;
  	case TYPE_BRANCH:
  	  /* Leave some extra cycles between a compare and its
  	     dependent branch, to inhibit expensive mispredicts.  */
! 	  if ((rs6000_cpu_attr == CPU_PPC603
! 	       || rs6000_cpu_attr == CPU_PPC604
! 	       || rs6000_cpu_attr == CPU_PPC604E
! 	       || rs6000_cpu_attr == CPU_PPC620
! 	       || rs6000_cpu_attr == CPU_PPC630
! 	       || rs6000_cpu_attr == CPU_PPC750
! 	       || rs6000_cpu_attr == CPU_PPC7400
! 	       || rs6000_cpu_attr == CPU_PPC7450
! 	       || rs6000_cpu_attr == CPU_POWER4)
  	      && recog_memoized (dep_insn)
  	      && (INSN_CODE (dep_insn) >= 0)
  	      && (get_attr_type (dep_insn) == TYPE_COMPARE
*************** rs6000_issue_rate ()
*** 10788,10793 ****
--- 10797,10803 ----
    case CPU_PPC604E:
    case CPU_PPC620:
    case CPU_PPC630:
+   case CPU_POWER4:
      return 4;
    default:
      return 1;
Index: rs6000.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.206
diff -c -p -r1.206 rs6000.h
*** rs6000.h	4 Jun 2002 07:09:32 -0000	1.206
--- rs6000.h	9 Jun 2002 14:40:30 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 58,63 ****
--- 58,65 ----
  %{mcpu=common: -D_ARCH_COM} \
  %{mcpu=power: -D_ARCH_PWR} \
  %{mcpu=power2: -D_ARCH_PWR2} \
+ %{mcpu=power3: -D_ARCH_PPC} \
+ %{mcpu=power4: -D_ARCH_PPC} \
  %{mcpu=powerpc: -D_ARCH_PPC} \
  %{mcpu=rios: -D_ARCH_PWR} \
  %{mcpu=rios1: -D_ARCH_PWR} \
*************** Boston, MA 02111-1307, USA.  */
*** 98,103 ****
--- 100,107 ----
  %{mcpu=common: -mcom} \
  %{mcpu=power: -mpwr} \
  %{mcpu=power2: -mpwrx} \
+ %{mcpu=power3: -m604} \
+ %{mcpu=power4: -m604} \
  %{mcpu=powerpc: -mppc} \
  %{mcpu=rios: -mpwr} \
  %{mcpu=rios1: -mpwr} \
*************** Boston, MA 02111-1307, USA.  */
*** 116,121 ****
--- 120,126 ----
  %{mcpu=604: -mppc} \
  %{mcpu=604e: -mppc} \
  %{mcpu=620: -mppc} \
+ %{mcpu=630: -m604} \
  %{mcpu=740: -mppc} \
  %{mcpu=7400: -mppc} \
  %{mcpu=7450: -mppc} \
*************** enum processor_type
*** 395,401 ****
     PROCESSOR_PPC630,
     PROCESSOR_PPC750,
     PROCESSOR_PPC7400,
!    PROCESSOR_PPC7450
  };
  
  extern enum processor_type rs6000_cpu;
--- 400,407 ----
     PROCESSOR_PPC630,
     PROCESSOR_PPC750,
     PROCESSOR_PPC7400,
!    PROCESSOR_PPC7450,
!    PROCESSOR_POWER4
  };
  
  extern enum processor_type rs6000_cpu;
*************** do {									     \
*** 2298,2303 ****
--- 2304,2310 ----
          return COSTS_N_INSNS (4);					\
        case PROCESSOR_PPC620:						\
        case PROCESSOR_PPC630:						\
+       case PROCESSOR_POWER4:						\
          return (GET_CODE (XEXP (X, 1)) != CONST_INT			\
  		? GET_MODE (XEXP (X, 1)) != DImode			\
  		? COSTS_N_INSNS (5) : COSTS_N_INSNS (7)			\
*************** do {									     \
*** 2337,2342 ****
--- 2344,2350 ----
  	return COSTS_N_INSNS (20);					\
        case PROCESSOR_PPC620:						\
        case PROCESSOR_PPC630:						\
+       case PROCESSOR_POWER4:						\
          return (GET_MODE (XEXP (X, 1)) != DImode			\
  		? COSTS_N_INSNS (21)					\
  		: COSTS_N_INSNS (37));					\
Index: rs6000.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.189
diff -c -p -r1.189 rs6000.md
*** rs6000.md	19 May 2002 17:10:47 -0000	1.189
--- rs6000.md	9 Jun 2002 14:40:30 -0000
***************
*** 56,62 ****
  ;; Processor type -- this attribute must exactly match the processor_type
  ;; enumeration in rs6000.h.
  
! (define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450"
    (const (symbol_ref "rs6000_cpu_attr")))
  
  ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
--- 56,62 ----
  ;; Processor type -- this attribute must exactly match the processor_type
  ;; enumeration in rs6000.h.
  
! (define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,power4"
    (const (symbol_ref "rs6000_cpu_attr")))
  
  ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
***************
*** 375,416 ****
--- 375,426 ----
    (and (eq_attr "type" "cr_logical")
         (eq_attr "cpu" "ppc7450"))
    1 1)
+ 
  (define_function_unit "vec_alu2" 2 0
    (and (eq_attr "type" "vecsimple")
         (eq_attr "cpu" "ppc7450"))
    1 2 [(eq_attr "type" "vecsimple")])
+ 
  (define_function_unit "vec_alu2" 2 0
    (and (eq_attr "type" "vecsimple")
         (eq_attr "cpu" "ppc7450"))
    1 1 [(eq_attr "type" "!vecsimple")])
+ 
  (define_function_unit "vec_alu2" 2 0
    (and (eq_attr "type" "veccomplex")
         (eq_attr "cpu" "ppc7450"))
    4 2 [(eq_attr "type" "veccomplex")])
+ 
  (define_function_unit "vec_alu2" 2 0
    (and (eq_attr "type" "veccomplex")
         (eq_attr "cpu" "ppc7450"))
    4 1 [(eq_attr "type" "!veccomplex")])
+ 
  (define_function_unit "vec_alu2" 2 0
    (and (eq_attr "type" "veccmp")
         (eq_attr "cpu" "ppc7450"))
    2 2 [(eq_attr "type" "veccmp")])
+ 
  (define_function_unit "vec_alu2" 2 0
    (and (eq_attr "type" "veccmp")
         (eq_attr "cpu" "ppc7450"))
    2 1 [(eq_attr "type" "!veccmp")])
+ 
  (define_function_unit "vec_alu2" 2 0
    (and (eq_attr "type" "vecfloat")
         (eq_attr "cpu" "ppc7450"))
    4 2 [(eq_attr "type" "vecfloat")])
+ 
  (define_function_unit "vec_alu2" 2 0
    (and (eq_attr "type" "vecfloat")
         (eq_attr "cpu" "ppc7450"))
    4 1 [(eq_attr "type" "!vecfloat")])
+ 
  (define_function_unit "vec_alu2" 2 0
    (and (eq_attr "type" "vecperm")
         (eq_attr "cpu" "ppc7450"))
    2 2 [(eq_attr "type" "vecperm")])
+ 
  (define_function_unit "vec_alu2" 2 0
    (and (eq_attr "type" "vecperm")
         (eq_attr "cpu" "ppc7450"))
***************
*** 489,495 ****
  
  (define_function_unit "iu" 1 0
    (and (eq_attr "type" "compare,delayed_compare")
!        (eq_attr "cpu" "rs64a,mpccore,ppc403,ppc405,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630"))
    3 1)
  
  ; some extra cycles added by TARGET_SCHED_ADJUST_COST between compare
--- 499,505 ----
  
  (define_function_unit "iu" 1 0
    (and (eq_attr "type" "compare,delayed_compare")
!        (eq_attr "cpu" "rs64a,mpccore,ppc403,ppc405,ppc601,ppc603"))
    3 1)
  
  ; some extra cycles added by TARGET_SCHED_ADJUST_COST between compare
***************
*** 699,720 ****
  
  ; RIOS2 has two symmetric FPUs.
  (define_function_unit "fpu2" 2 0
!   (and (eq_attr "type" "fp")
!        (eq_attr "cpu" "rios2"))
!   2 1)
! 
! (define_function_unit "fpu2" 2 0
!   (and (eq_attr "type" "fp")
!        (eq_attr "cpu" "ppc630"))
!   3 1)
! 
! (define_function_unit "fpu2" 2 0
!   (and (eq_attr "type" "dmul")
         (eq_attr "cpu" "rios2"))
    2 1)
  
  (define_function_unit "fpu2" 2 0
!   (and (eq_attr "type" "dmul")
         (eq_attr "cpu" "ppc630"))
    3 1)
  
--- 709,720 ----
  
  ; RIOS2 has two symmetric FPUs.
  (define_function_unit "fpu2" 2 0
!   (and (eq_attr "type" "fp,dmul")
         (eq_attr "cpu" "rios2"))
    2 1)
  
  (define_function_unit "fpu2" 2 0
!   (and (eq_attr "type" "fp,dmul")
         (eq_attr "cpu" "ppc630"))
    3 1)
  
***************
*** 748,753 ****
--- 748,854 ----
         (eq_attr "cpu" "ppc630"))
    26 26)
  
+ ;; Power4
+ (define_function_unit "lsu2" 2 0
+   (and (eq_attr "type" "load")
+        (eq_attr "cpu" "power4"))
+   3 1)
+ 
+ (define_function_unit "lsu2" 2 0
+   (and (eq_attr "type" "fpload")
+        (eq_attr "cpu" "power4"))
+   5 1)
+ 
+ (define_function_unit "lsu2" 2 0
+   (and (eq_attr "type" "store,fpstore")
+        (eq_attr "cpu" "power4"))
+   1 1)
+ 
+ (define_function_unit "iu2" 2 0
+   (and (eq_attr "type" "integer")
+        (eq_attr "cpu" "power4"))
+   2 1)
+ 
+ (define_function_unit "iu2" 2 0
+   (and (eq_attr "type" "imul,lmul")
+        (eq_attr "cpu" "power4"))
+   7 6)
+ 
+ (define_function_unit "iu2" 2 0
+   (and (eq_attr "type" "imul2")
+        (eq_attr "cpu" "power4"))
+   5 4)
+ 
+ (define_function_unit "iu2" 2 0
+   (and (eq_attr "type" "imul3")
+        (eq_attr "cpu" "power4"))
+   4 3)
+ 
+ (define_function_unit "iu2" 2 0
+   (and (eq_attr "type" "idiv")
+        (eq_attr "cpu" "power4"))
+   36 35)
+ 
+ (define_function_unit "iu2" 2 0
+   (and (eq_attr "type" "ldiv")
+        (eq_attr "cpu" "power4"))
+   68 67)
+ 
+ (define_function_unit "imuldiv" 1 0
+   (and (eq_attr "type" "idiv")
+        (eq_attr "cpu" "power4"))
+   36 35)
+ 
+ (define_function_unit "imuldiv" 1 0
+   (and (eq_attr "type" "ldiv")
+        (eq_attr "cpu" "power4"))
+   68 67)
+ 
+ (define_function_unit "iu2" 2 0
+   (and (eq_attr "type" "compare,delayed_compare")
+        (eq_attr "cpu" "power4"))
+   2 1)
+ 
+ (define_function_unit "iu2" 2 0
+   (and (eq_attr "type" "mtjmpr")
+        (eq_attr "cpu" "power4"))
+   3 1)
+ 
+ (define_function_unit "bpu" 1 0
+   (and (eq_attr "type" "mtjmpr")
+        (eq_attr "cpu" "power4"))
+   3 1)
+ 
+ (define_function_unit "bpu" 1 0
+   (and (eq_attr "type" "jmpreg,branch")
+        (eq_attr "cpu" "power4"))
+   2 1)
+ 
+ (define_function_unit "cru" 1 0
+   (and (eq_attr "type" "cr_logical")
+        (eq_attr "cpu" "power4"))
+   4 1)
+ 
+ (define_function_unit "fpu2" 2 0
+   (and (eq_attr "type" "fp,dmul")
+        (eq_attr "cpu" "power4"))
+   6 1)
+ 
+ (define_function_unit "fpu2" 2 0
+   (and (eq_attr "type" "fpcompare")
+        (eq_attr "cpu" "power4"))
+   8 2)
+ 
+ (define_function_unit "fpu2" 2 0
+   (and (eq_attr "type" "sdiv,ddiv")
+        (eq_attr "cpu" "power4"))
+   33 28)
+ 
+ (define_function_unit "fpu2" 2 0
+   (and (eq_attr "type" "ssqrt,dsqrt")
+        (eq_attr "cpu" "power4"))
+   40 35)
+ 
  \f
  ;; Start with fixed-point load and store insns.  Here we put only the more
  ;; complex forms.  Basic data transfer is done later.
***************
*** 7778,7784 ****
     mr %0,%1
     {l%U1%X1|lwz%U1%X1} %0,%1
     {st%U0%U1|stw%U0%U1} %1,%0"
!   [(set_attr "type" "*,*,*,compare,*,*,load,store")
     (set_attr "length" "*,*,12,*,8,*,*,*")])
  \f
  ;; For floating-point, we normally deal with the floating-point registers
--- 7879,7885 ----
     mr %0,%1
     {l%U1%X1|lwz%U1%X1} %0,%1
     {st%U0%U1|stw%U0%U1} %1,%0"
!   [(set_attr "type" "cr_logical,cr_logical,cr_logical,cr_logical,cr_logical,*,load,store")
     (set_attr "length" "*,*,12,*,8,*,*,*")])
  \f
  ;; For floating-point, we normally deal with the floating-point registers
***************
*** 10585,10591 ****
  			    (const_int 0)]))]
    ""
    "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
!   [(set_attr "length" "12")])
  
  (define_insn ""
    [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
--- 10686,10693 ----
  			    (const_int 0)]))]
    ""
    "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
!   [(set_attr "type" "cr_logical")
!    (set_attr "length" "12")])
  
  (define_insn ""
    [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
***************
*** 10594,10600 ****
  			    (const_int 0)]))]
    "TARGET_POWERPC64"
    "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
!   [(set_attr "length" "12")])
  
  (define_insn ""
    [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
--- 10696,10703 ----
  			    (const_int 0)]))]
    "TARGET_POWERPC64"
    "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
!   [(set_attr "type" "cr_logical")
!    (set_attr "length" "12")])
  
  (define_insn ""
    [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
***************
*** 10650,10656 ****
  
    return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
  }"
!  [(set_attr "length" "12")])
  
  (define_insn ""
    [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
--- 10753,10760 ----
  
    return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
  }"
!   [(set_attr "type" "cr_logical")
!    (set_attr "length" "12")])
  
  (define_insn ""
    [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
***************
*** 10719,10727 ****
  	(match_operator:SI 4 "scc_comparison_operator"
  			   [(match_operand 5 "cc_reg_operand" "y")
  			    (const_int 0)]))]
!    "REGNO (operands[2]) != REGNO (operands[5])"
!    "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
!    [(set_attr "length" "20")])
  
  (define_peephole
    [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
--- 10823,10832 ----
  	(match_operator:SI 4 "scc_comparison_operator"
  			   [(match_operand 5 "cc_reg_operand" "y")
  			    (const_int 0)]))]
!   "REGNO (operands[2]) != REGNO (operands[5])"
!   "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
!   [(set_attr "type" "cr_logical")
!    (set_attr "length" "20")])
  
  (define_peephole
    [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
***************
*** 10732,10740 ****
  	(match_operator:DI 4 "scc_comparison_operator"
  			   [(match_operand 5 "cc_reg_operand" "y")
  			    (const_int 0)]))]
!    "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
!    "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
!    [(set_attr "length" "20")])
  
  ;; There are some scc insns that can be done directly, without a compare.
  ;; These are faster because they don't involve the communications between
--- 10837,10846 ----
  	(match_operator:DI 4 "scc_comparison_operator"
  			   [(match_operand 5 "cc_reg_operand" "y")
  			    (const_int 0)]))]
!   "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
!   "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
!   [(set_attr "type" "cr_logical")
!    (set_attr "length" "20")])
  
  ;; There are some scc insns that can be done directly, without a compare.
  ;; These are faster because they don't involve the communications between
***************
*** 13727,13733 ****
          (unspec:SI [(reg:CC 68) (reg:CC 69) (reg:CC 70) (reg:CC 71) 
  		    (reg:CC 72)	(reg:CC 73) (reg:CC 74) (reg:CC 75)] 19))]
    ""
!   "mfcr %0")
  
  (define_insn "*stmw"
   [(match_parallel 0 "stmw_operation"
--- 13833,13840 ----
          (unspec:SI [(reg:CC 68) (reg:CC 69) (reg:CC 70) (reg:CC 71) 
  		    (reg:CC 72)	(reg:CC 73) (reg:CC 74) (reg:CC 75)] 19))]
    ""
!   "mfcr %0"
!   [(set_attr "type" "cr_logical")])
  
  (define_insn "*stmw"
   [(match_parallel 0 "stmw_operation"
***************
*** 13799,13815 ****
      mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
    operands[4] = GEN_INT (mask);
    return \"mtcrf %4,%2\";
! }")
  
  (define_insn ""
!  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
!        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
! 		   (match_operand 2 "immediate_operand" "n")] 20))]
!  "GET_CODE (operands[0]) == REG 
!   && CR_REGNO_P (REGNO (operands[0]))
!   && GET_CODE (operands[2]) == CONST_INT
!   && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
!  "mtcrf %R0,%1")
  
  ; The load-multiple instructions have similar properties.
  ; Note that "load_multiple" is a name known to the machine-independent
--- 13906,13924 ----
      mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
    operands[4] = GEN_INT (mask);
    return \"mtcrf %4,%2\";
! }"
!   [(set_attr "type" "cr_logical")])
  
  (define_insn ""
!   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
!         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
! 		    (match_operand 2 "immediate_operand" "n")] 20))]
!   "GET_CODE (operands[0]) == REG 
!    && CR_REGNO_P (REGNO (operands[0]))
!    && GET_CODE (operands[2]) == CONST_INT
!    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
!   "mtcrf %R0,%1"
!   [(set_attr "type" "cr_logical")])
  
  ; The load-multiple instructions have similar properties.
  ; Note that "load_multiple" is a name known to the machine-independent

^ permalink raw reply	[flat|nested] 875+ messages in thread
* thread-local storage: c front end and generic backend patch
@ 2002-05-21 18:54 Richard Henderson
  2002-05-22  4:25 ` Joseph S. Myers
                   ` (2 more replies)
  0 siblings, 3 replies; 875+ messages in thread
From: Richard Henderson @ 2002-05-21 18:54 UTC (permalink / raw)
  To: gcc-patches; +Cc: Joseph S. Myers

[-- Attachment #1: Type: text/plain, Size: 789 bytes --]

The following adds support in the C front end for a new 
storage specifier keyword "__thread" that marks a variable
to be allocated in storage private to every extant thread.

A similar patch for the C++ front end will follow directly;
I wanted to split that out for ease of review by the C++
front end folk.

Joseph, the extend.texi documentation has some user-level
description of the extension.  I've tried to come up with
a set of edits for C99, but I'm not sure where to put them,
or exactly what form they should take.  Thoughts?

There is a fledgeling testsuite here, but it won't get run
until you have target support as well.  I have x86 support
completed, and it'll get submitted as soon as I clean it up
properly and add some autoconf detection logic for binutils
support.


r~

[-- Attachment #2: tls-iso-changes --]
[-- Type: text/plain, Size: 1456 bytes --]

ISO/IEC 9899:1999 edits for thread-local storage:

6.2.4  Storage durations of objects

P3: Add new paragraph before

	An object whose identifier is declared with the storage-class
	specifier @code{__thread} has @dfn{thread storage duration}.
	Its lifetime is the entire execution of the thread, and its
	stored value is initialized only once, prior to thread startup.

6.5.3.2  Address and indirection operators

P3:
	[ I don't think any change is required here.  The explicit
	  semantics of @code{&} require that the result be the address
	  of the tls variable within the current thread, but I don't
	  see that at odds with "returns the address of its operand". ]

6.6 Constant expressions

P9:
	[ No change here, since we've defined @code{__thread} variables
	  to have thread storage duration, not static storage duration,
	  and that isn't listed as legal.  ]

6.7.1 Storage-class specifiers

P1: Add @code{__thread}.

P2: Change to

        With the exception of @code{__thread}, at most one storage-class
        specifier may be given [...].  The @code{__thread} specifier may
	be used alone, or immediately following @code{extern} or
	@code{static}.

P6: Add new paragraph after

        The declaration of an identifier for a variable that has
        block scope that specifies @code{__thread} shall also
        specify either @code{extern} or @code{static}.

        The @code{__thread} specifier shall be used only with
        variables.

[-- Attachment #3: d-tls-32-1 --]
[-- Type: text/plain, Size: 37346 bytes --]

        * c-common.h (enum rid): Add RID_THREAD.
        * c-decl.c (start_decl): Do not set DECL_COMMON for tls variables.
        (grokdeclarator): Grok __thread.
        * c-parse.in (reswords): Add __thread.
        (rid_to_yy): Add RID_THREAD.

        * tree.h (DECL_THREAD_LOCAL): New.
        (struct tree_decl): Add thread_local_flag.
        * print-tree.c (print_node): Dump DECL_THREAD_LOCAL.
        * tree.c (staticp): TLS variables are not static.

        * target-def.h (TARGET_HAVE_TLS): New.
        * target.h (have_tls): New.
        * output.h (SECTION_TLS): New.
        * varasm.c (assemble_variable): TLS variables can't be common for now.
        (default_section_type_flags): Handle .tdata and .tbss.
        (default_elf_asm_named_section): Handle SECTION_TLS.
        (categorize_decl_for_section): Handle DECL_THREAD_LOCAL.

        * flags.h (flag_tls_default): Declare.
        * toplev.c (flag_tls_default): Define.
        (display_help): Display help for it.
        (decode_f_option): Set it.

        * doc/extend.texi (Thread-Local): New node describing language-level
        thread-local storage.
        * doc/invoke.texi (-ftls-model): Document.

        * fixinc/inclhack.def (thread_keyword): New.
        * fixinc/fixincl.x: Rebuild.

cp/
        * lex.c (rid_to_yy): Add RID_THREAD.

testsuite/
        * gcc.dg/tls/tls.exp, gcc.dg/tls/trivial.c, gcc.dg/tls/diag-1.c,
        gcc.dg/tls/diag-2.c, gcc.dg/tls/init-1.c: New directory and files.


Index: c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.136
diff -c -p -d -r1.136 c-common.h
*** c-common.h	18 May 2002 19:02:01 -0000	1.136
--- c-common.h	21 May 2002 22:10:18 -0000
*************** enum rid
*** 58,64 ****
    RID_VOLATILE, RID_SIGNED,  RID_AUTO,  RID_RESTRICT,
  
    /* C extensions */
!   RID_BOUNDED, RID_UNBOUNDED, RID_COMPLEX,
  
    /* C++ */
    RID_FRIEND, RID_VIRTUAL, RID_EXPLICIT, RID_EXPORT, RID_MUTABLE,
--- 58,64 ----
    RID_VOLATILE, RID_SIGNED,  RID_AUTO,  RID_RESTRICT,
  
    /* C extensions */
!   RID_BOUNDED, RID_UNBOUNDED, RID_COMPLEX, RID_THREAD,
  
    /* C++ */
    RID_FRIEND, RID_VIRTUAL, RID_EXPLICIT, RID_EXPORT, RID_MUTABLE,
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.326
diff -c -p -d -r1.326 c-decl.c
*** c-decl.c	18 May 2002 19:02:02 -0000	1.326
--- c-decl.c	21 May 2002 22:10:19 -0000
*************** start_decl (declarator, declspecs, initi
*** 3350,3358 ****
    /* ANSI specifies that a tentative definition which is not merged with
       a non-tentative definition behaves exactly like a definition with an
       initializer equal to zero.  (Section 3.7.2)
!      -fno-common gives strict ANSI behavior.  Usually you don't want it.
!      This matters only for variables with external linkage.  */
!   if (!initialized && (! flag_no_common || ! TREE_PUBLIC (decl)))
      DECL_COMMON (decl) = 1;
  
    /* Set attributes here so if duplicate decl, will have proper attributes.  */
--- 3350,3368 ----
    /* ANSI specifies that a tentative definition which is not merged with
       a non-tentative definition behaves exactly like a definition with an
       initializer equal to zero.  (Section 3.7.2)
! 
!      -fno-common gives strict ANSI behavior, though this tends to break
!      a large body of code that grew up without this rule.
! 
!      Thread-local variables are never common, since there's no entrenched
!      body of code to break, and it allows more efficient variable references
!      in the presense of dynamic linking.  */
! 
!   if (TREE_CODE (decl) == VAR_DECL
!       && !initialized
!       && TREE_PUBLIC (decl)
!       && !DECL_THREAD_LOCAL (decl)
!       && !flag_no_common)
      DECL_COMMON (decl) = 1;
  
    /* Set attributes here so if duplicate decl, will have proper attributes.  */
*************** grokdeclarator (declarator, declspecs, d
*** 3933,3939 ****
  	  enum rid i = C_RID_CODE (id);
  	  if ((int) i <= (int) RID_LAST_MODIFIER)
  	    {
! 	      if (i == RID_LONG && (specbits & (1 << (int) i)))
  		{
  		  if (longlong)
  		    error ("`long long long' is too long for GCC");
--- 3943,3949 ----
  	  enum rid i = C_RID_CODE (id);
  	  if ((int) i <= (int) RID_LAST_MODIFIER)
  	    {
! 	      if (i == RID_LONG && (specbits & (1 << (int) RID_LONG)))
  		{
  		  if (longlong)
  		    error ("`long long long' is too long for GCC");
*************** grokdeclarator (declarator, declspecs, d
*** 3947,3952 ****
--- 3957,3975 ----
  		}
  	      else if (specbits & (1 << (int) i))
  		pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));
+ 
+ 	      /* Diagnose "__thread extern".  Recall that this list
+ 		 is in the reverse order seen in the text.  */
+ 	      if (i == RID_THREAD
+ 		  && (specbits & (1 << (int) RID_EXTERN
+ 				  | 1 << (int) RID_STATIC)))
+ 		{
+ 		  if (specbits & 1 << (int) RID_EXTERN)
+ 		    error ("`__thread' before `extern'");
+ 		  else
+ 		    error ("`__thread' before `static'");
+ 		}
+ 
  	      specbits |= 1 << (int) i;
  	      goto found;
  	    }
*************** grokdeclarator (declarator, declspecs, d
*** 4196,4201 ****
--- 4219,4230 ----
      if (specbits & 1 << (int) RID_REGISTER) nclasses++;
      if (specbits & 1 << (int) RID_TYPEDEF) nclasses++;
  
+     /* "static __thread" and "extern __thread" are allowed.  */
+     if ((specbits & (1 << (int) RID_THREAD
+ 		     | 1 << (int) RID_STATIC
+ 		     | 1 << (int) RID_EXTERN)) == (1 << (int) RID_THREAD))
+       nclasses++;
+ 
      /* Warn about storage classes that are invalid for certain
         kinds of declarations (parameters, typenames, etc.).  */
  
*************** grokdeclarator (declarator, declspecs, d
*** 4205,4211 ****
  	     && (specbits
  		 & ((1 << (int) RID_REGISTER)
  		    | (1 << (int) RID_AUTO)
! 		    | (1 << (int) RID_TYPEDEF))))
        {
  	if (specbits & 1 << (int) RID_AUTO
  	    && (pedantic || current_binding_level == global_binding_level))
--- 4234,4241 ----
  	     && (specbits
  		 & ((1 << (int) RID_REGISTER)
  		    | (1 << (int) RID_AUTO)
! 		    | (1 << (int) RID_TYPEDEF)
! 		    | (1 << (int) RID_THREAD))))
        {
  	if (specbits & 1 << (int) RID_AUTO
  	    && (pedantic || current_binding_level == global_binding_level))
*************** grokdeclarator (declarator, declspecs, d
*** 4214,4221 ****
  	  error ("function definition declared `register'");
  	if (specbits & 1 << (int) RID_TYPEDEF)
  	  error ("function definition declared `typedef'");
  	specbits &= ~((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
! 		      | (1 << (int) RID_AUTO));
        }
      else if (decl_context != NORMAL && nclasses > 0)
        {
--- 4244,4253 ----
  	  error ("function definition declared `register'");
  	if (specbits & 1 << (int) RID_TYPEDEF)
  	  error ("function definition declared `typedef'");
+ 	if (specbits & 1 << (int) RID_THREAD)
+ 	  error ("function definition declared `__thread'");
  	specbits &= ~((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
! 		      | (1 << (int) RID_AUTO) | (1 << (int) RID_THREAD));
        }
      else if (decl_context != NORMAL && nclasses > 0)
        {
*************** grokdeclarator (declarator, declspecs, d
*** 4238,4244 ****
  	      }
  	    specbits &= ~((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
  			  | (1 << (int) RID_AUTO) | (1 << (int) RID_STATIC)
! 			  | (1 << (int) RID_EXTERN));
  	  }
        }
      else if (specbits & 1 << (int) RID_EXTERN && initialized && ! funcdef_flag)
--- 4270,4276 ----
  	      }
  	    specbits &= ~((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
  			  | (1 << (int) RID_AUTO) | (1 << (int) RID_STATIC)
! 			  | (1 << (int) RID_EXTERN) | (1 << (int) RID_THREAD));
  	  }
        }
      else if (specbits & 1 << (int) RID_EXTERN && initialized && ! funcdef_flag)
*************** grokdeclarator (declarator, declspecs, d
*** 4249,4260 ****
  	else
  	  error ("`%s' has both `extern' and initializer", name);
        }
!     else if (specbits & 1 << (int) RID_EXTERN && funcdef_flag
! 	     && current_binding_level != global_binding_level)
!       error ("nested function `%s' declared `extern'", name);
!     else if (current_binding_level == global_binding_level
! 	     && specbits & (1 << (int) RID_AUTO))
!       error ("top-level declaration of `%s' specifies `auto'", name);
    }
  
    /* Now figure out the structure of the declarator proper.
--- 4281,4305 ----
  	else
  	  error ("`%s' has both `extern' and initializer", name);
        }
!     else if (current_binding_level == global_binding_level)
!       {
! 	if (specbits & 1 << (int) RID_AUTO)
! 	  error ("top-level declaration of `%s' specifies `auto'", name);
!       }
!     else
!       {
! 	if (specbits & 1 << (int) RID_EXTERN && funcdef_flag)
! 	  error ("nested function `%s' declared `extern'", name);
! 	else if ((specbits & (1 << (int) RID_THREAD
! 			       | 1 << (int) RID_EXTERN
! 			       | 1 << (int) RID_STATIC))
! 		 == (1 << (int) RID_THREAD))
! 	  {
! 	    error ("function-scope `%s' implicitly auto and declared `__thread'",
! 		   name);
! 	    specbits &= ~(1 << (int) RID_THREAD);
! 	  }
!       }
    }
  
    /* Now figure out the structure of the declarator proper.
*************** grokdeclarator (declarator, declspecs, d
*** 4842,4847 ****
--- 4887,4894 ----
  	  pedwarn ("invalid storage class for function `%s'", name);
  	if (specbits & (1 << (int) RID_REGISTER))
  	  error ("invalid storage class for function `%s'", name);
+ 	if (specbits & (1 << (int) RID_THREAD))
+ 	  error ("invalid storage class for function `%s'", name);
  	/* Function declaration not at top level.
  	   Storage classes other than `extern' are not allowed
  	   and `extern' makes no difference.  */
*************** grokdeclarator (declarator, declspecs, d
*** 4934,4955 ****
  	  pedwarn_with_decl (decl, "variable `%s' declared `inline'");
  
  	DECL_EXTERNAL (decl) = extern_ref;
  	/* At top level, the presence of a `static' or `register' storage
  	   class specifier, or the absence of all storage class specifiers
  	   makes this declaration a definition (perhaps tentative).  Also,
  	   the absence of both `static' and `register' makes it public.  */
  	if (current_binding_level == global_binding_level)
  	  {
! 	    TREE_PUBLIC (decl)
! 	      = !(specbits
! 		  & ((1 << (int) RID_STATIC) | (1 << (int) RID_REGISTER)));
! 	    TREE_STATIC (decl) = ! DECL_EXTERNAL (decl);
  	  }
  	/* Not at top level, only `static' makes a static definition.  */
  	else
  	  {
  	    TREE_STATIC (decl) = (specbits & (1 << (int) RID_STATIC)) != 0;
! 	    TREE_PUBLIC (decl) = DECL_EXTERNAL (decl);
  	  }
        }
  
--- 4981,5012 ----
  	  pedwarn_with_decl (decl, "variable `%s' declared `inline'");
  
  	DECL_EXTERNAL (decl) = extern_ref;
+ 
  	/* At top level, the presence of a `static' or `register' storage
  	   class specifier, or the absence of all storage class specifiers
  	   makes this declaration a definition (perhaps tentative).  Also,
  	   the absence of both `static' and `register' makes it public.  */
  	if (current_binding_level == global_binding_level)
  	  {
! 	    TREE_PUBLIC (decl) = !(specbits & ((1 << (int) RID_STATIC)
! 					       | (1 << (int) RID_REGISTER)));
! 	    TREE_STATIC (decl) = !extern_ref;
  	  }
  	/* Not at top level, only `static' makes a static definition.  */
  	else
  	  {
  	    TREE_STATIC (decl) = (specbits & (1 << (int) RID_STATIC)) != 0;
! 	    TREE_PUBLIC (decl) = extern_ref;
! 	  }
! 
! 	if (specbits & 1 << (int) RID_THREAD)
! 	  {
! 	    if (targetm.have_tls)
! 	      DECL_THREAD_LOCAL (decl) = 1;
! 	    else
! 	      /* A mere warning is sure to result in improper semantics
! 		 at runtime.  Don't bother to allow this to compile.  */
! 	      error ("thread-local storage not supported for this target");
  	  }
        }
  
Index: c-parse.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-parse.in,v
retrieving revision 1.139
diff -c -p -d -r1.139 c-parse.in
*** c-parse.in	27 Apr 2002 06:53:06 -0000	1.139
--- c-parse.in	21 May 2002 22:10:19 -0000
*************** static const struct resword reswords[] =
*** 3343,3348 ****
--- 3343,3349 ----
    { "__restrict__",	RID_RESTRICT,	0 },
    { "__signed",		RID_SIGNED,	0 },
    { "__signed__",	RID_SIGNED,	0 },
+   { "__thread",		RID_THREAD,	0 },
    { "__typeof",		RID_TYPEOF,	0 },
    { "__typeof__",	RID_TYPEOF,	0 },
    { "__unbounded",	RID_UNBOUNDED,	0 },
*************** static const short rid_to_yy[RID_MAX] =
*** 3438,3443 ****
--- 3439,3445 ----
    /* RID_BOUNDED */	TYPE_QUAL,
    /* RID_UNBOUNDED */	TYPE_QUAL,
    /* RID_COMPLEX */	TYPESPEC,
+   /* RID_THREAD */	SCSPEC,
  
    /* C++ */
    /* RID_FRIEND */	0,
Index: flags.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flags.h,v
retrieving revision 1.84
diff -c -p -d -r1.84 flags.h
*** flags.h	15 May 2002 09:00:01 -0000	1.84
--- flags.h	21 May 2002 22:10:19 -0000
*************** extern int flag_dump_unnumbered;
*** 458,467 ****
  
  extern int flag_pedantic_errors;
  
! /* Nonzero means generate position-independent code.
!    This is not fully implemented yet.  */
  
  extern int flag_pic;
  
  /* Nonzero means generate extra code for exception handling and enable
     exception handling.  */
--- 458,478 ----
  
  extern int flag_pedantic_errors;
  
! /* Nonzero means generate position-independent code.  1 vs 2 for a 
!    target-dependent "small" or "large" mode.  */
  
  extern int flag_pic;
+ 
+ /* Set to the default thread-local storage (tls) model to use.  */
+ 
+ enum tls_model {
+   TLS_MODEL_GLOBAL_DYNAMIC,
+   TLS_MODEL_LOCAL_DYNAMIC,
+   TLS_MODEL_INITIAL_EXEC,
+   TLS_MODEL_LOCAL_EXEC
+ };
+ 
+ extern enum tls_model flag_tls_default;
  
  /* Nonzero means generate extra code for exception handling and enable
     exception handling.  */
Index: output.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/output.h,v
retrieving revision 1.105
diff -c -p -d -r1.105 output.h
*** output.h	19 May 2002 09:50:11 -0000	1.105
--- output.h	21 May 2002 22:10:19 -0000
*************** extern void no_asm_to_stream PARAMS ((FI
*** 507,513 ****
  #define SECTION_STRINGS  0x10000	/* contains zero terminated strings without
  					   embedded zeros */
  #define SECTION_OVERRIDE 0x20000	/* allow override of default flags */
! #define SECTION_MACH_DEP 0x40000	/* subsequent bits reserved for target */
  
  extern unsigned int get_named_section_flags PARAMS ((const char *));
  extern bool set_named_section_flags	PARAMS ((const char *, unsigned int));
--- 507,514 ----
  #define SECTION_STRINGS  0x10000	/* contains zero terminated strings without
  					   embedded zeros */
  #define SECTION_OVERRIDE 0x20000	/* allow override of default flags */
! #define SECTION_TLS	 0x40000	/* contains thread-local storage */
! #define SECTION_MACH_DEP 0x80000	/* subsequent bits reserved for target */
  
  extern unsigned int get_named_section_flags PARAMS ((const char *));
  extern bool set_named_section_flags	PARAMS ((const char *, unsigned int));
Index: print-tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/print-tree.c,v
retrieving revision 1.57
diff -c -p -d -r1.57 print-tree.c
*** print-tree.c	20 May 2002 18:06:54 -0000	1.57
--- print-tree.c	21 May 2002 22:10:19 -0000
*************** print_node (file, prefix, node, indent)
*** 352,357 ****
--- 352,359 ----
  
        if (TREE_CODE (node) == VAR_DECL && DECL_IN_TEXT_SECTION (node))
  	fputs (" in-text-section", file);
+       if (TREE_CODE (node) == VAR_DECL && DECL_THREAD_LOCAL (node))
+ 	fputs (" thread-local", file);
  
        if (TREE_CODE (node) == PARM_DECL && DECL_TRANSPARENT_UNION (node))
  	fputs (" transparent-union", file);
Index: target-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target-def.h,v
retrieving revision 1.28
diff -c -p -d -r1.28 target-def.h
*** target-def.h	19 May 2002 09:50:12 -0000	1.28
--- target-def.h	21 May 2002 22:10:19 -0000
*************** Foundation, 59 Temple Place - Suite 330,
*** 110,115 ****
--- 110,119 ----
  #define TARGET_HAVE_NAMED_SECTIONS false
  #endif
  
+ #ifndef TARGET_HAVE_TLS
+ #define TARGET_HAVE_TLS false
+ #endif
+ 
  #ifndef TARGET_ASM_EXCEPTION_SECTION
  #define TARGET_ASM_EXCEPTION_SECTION default_exception_section
  #endif
*************** Foundation, 59 Temple Place - Suite 330,
*** 244,249 ****
--- 248,254 ----
    TARGET_STRIP_NAME_ENCODING,			\
    TARGET_HAVE_NAMED_SECTIONS,			\
    TARGET_HAVE_CTORS_DTORS,			\
+   TARGET_HAVE_TLS				\
  }
  
  #include "hooks.h"
Index: target.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target.h,v
retrieving revision 1.30
diff -c -p -d -r1.30 target.h
*** target.h	19 May 2002 09:50:14 -0000	1.30
--- target.h	21 May 2002 22:10:19 -0000
*************** struct gcc_target
*** 256,261 ****
--- 256,264 ----
    /* True if "native" constructors and destructors are supported,
       false if we're using collect2 for the job.  */
    bool have_ctors_dtors;
+ 
+   /* True if thread-local storage is supported.  */
+   bool have_tls;
  };
  
  extern struct gcc_target targetm;
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.628
diff -c -p -d -r1.628 toplev.c
*** toplev.c	19 May 2002 08:31:47 -0000	1.628
--- toplev.c	21 May 2002 22:10:19 -0000
*************** int flag_shared_data;
*** 685,696 ****
  int flag_delayed_branch;
  
  /* Nonzero if we are compiling pure (sharable) code.
!    Value is 1 if we are doing reasonable (i.e. simple
!    offset into offset table) pic.  Value is 2 if we can
!    only perform register offsets.  */
  
  int flag_pic;
  
  /* Nonzero means generate extra code for exception handling and enable
     exception handling.  */
  
--- 685,699 ----
  int flag_delayed_branch;
  
  /* Nonzero if we are compiling pure (sharable) code.
!    Value is 1 if we are doing "small" pic; value is 2 if we're doing
!    "large" pic.  */
  
  int flag_pic;
  
+ /* Set to the default thread-local storage (tls) model to use.  */
+ 
+ enum tls_model flag_tls_default;
+ 
  /* Nonzero means generate extra code for exception handling and enable
     exception handling.  */
  
*************** display_help ()
*** 3547,3552 ****
--- 3550,3556 ----
    printf (_("  -finline-limit=<number> Limits the size of inlined functions to <number>\n"));
    printf (_("  -fmessage-length=<number> Limits diagnostics messages lengths to <number> characters per line.  0 suppresses line-wrapping\n"));
    printf (_("  -fdiagnostics-show-location=[once | every-line] Indicates how often source location information should be emitted, as prefix, at the beginning of diagnostics when line-wrapping\n"));
+   printf (_("  -ftls-model=[global-dynamic | local-dynamic | initial-exec | local-exec] Indicates the default thread-local storage code generation model\n"));
  
    for (i = ARRAY_SIZE (f_options); i--;)
      {
*************** decode_f_option (arg)
*** 3824,3829 ****
--- 3828,3846 ----
  	read_integral_parameter (option_value, arg - 2,
  				 MAX_INLINE_INSNS);
        set_param_value ("max-inline-insns", val);
+     }
+   else if ((option_value = skip_leading_substring (arg, "tls-model=")))
+     {
+       if (strcmp (option_value, "global-dynamic") == 0)
+ 	flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC;
+       else if (strcmp (option_value, "local-dynamic") == 0)
+ 	flag_tls_default = TLS_MODEL_LOCAL_DYNAMIC;
+       else if (strcmp (option_value, "initial-exec") == 0)
+ 	flag_tls_default = TLS_MODEL_INITIAL_EXEC;
+       else if (strcmp (option_value, "local-exec") == 0)
+ 	flag_tls_default = TLS_MODEL_LOCAL_EXEC;
+       else
+ 	warning ("`%s': unknown tls-model option", arg - 2);
      }
  #ifdef INSN_SCHEDULING
    else if ((option_value = skip_leading_substring (arg, "sched-verbose=")))
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.257
diff -c -p -d -r1.257 tree.c
*** tree.c	9 May 2002 22:48:33 -0000	1.257
--- tree.c	21 May 2002 22:10:19 -0000
*************** staticp (arg)
*** 1349,1360 ****
      case FUNCTION_DECL:
        /* Nested functions aren't static, since taking their address
  	 involves a trampoline.  */
!       return (decl_function_context (arg) == 0 || DECL_NO_STATIC_CHAIN (arg))
! 	&& ! DECL_NON_ADDR_CONST_P (arg);
  
      case VAR_DECL:
!       return (TREE_STATIC (arg) || DECL_EXTERNAL (arg))
! 	&& ! DECL_NON_ADDR_CONST_P (arg);
  
      case CONSTRUCTOR:
        return TREE_STATIC (arg);
--- 1349,1361 ----
      case FUNCTION_DECL:
        /* Nested functions aren't static, since taking their address
  	 involves a trampoline.  */
!       return ((decl_function_context (arg) == 0 || DECL_NO_STATIC_CHAIN (arg))
! 	      && ! DECL_NON_ADDR_CONST_P (arg));
  
      case VAR_DECL:
!       return ((TREE_STATIC (arg) || DECL_EXTERNAL (arg))
! 	      && ! DECL_THREAD_LOCAL (arg)
! 	      && ! DECL_NON_ADDR_CONST_P (arg));
  
      case CONSTRUCTOR:
        return TREE_STATIC (arg);
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.336
diff -c -p -d -r1.336 tree.h
*** tree.h	12 May 2002 21:42:00 -0000	1.336
--- tree.h	21 May 2002 22:10:19 -0000
*************** struct tree_type
*** 1615,1620 ****
--- 1615,1624 ----
  /* In a FUNCTION_DECL, nonzero if the function cannot be inlined.  */
  #define DECL_UNINLINABLE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.uninlinable)
  
+ /* In a VAR_DECL, nonzero if the data should be allocated from 
+    thread-local storage.  */
+ #define DECL_THREAD_LOCAL(NODE) (VAR_DECL_CHECK (NODE)->decl.thread_local_flag)
+ 
  /* In a FUNCTION_DECL, the saved representation of the body of the
     entire function.  Usually a COMPOUND_STMT, but in C++ this may also
     be a RETURN_INIT, CTOR_INITIALIZER, or TRY_BLOCK.  */
*************** struct tree_decl
*** 1793,1799 ****
    unsigned non_addressable : 1;
    unsigned user_align : 1;
    unsigned uninlinable : 1;
!   /* Three unused bits.  */
  
    unsigned lang_flag_0 : 1;
    unsigned lang_flag_1 : 1;
--- 1797,1804 ----
    unsigned non_addressable : 1;
    unsigned user_align : 1;
    unsigned uninlinable : 1;
!   unsigned thread_local_flag : 1;
!   /* Two unused bits.  */
  
    unsigned lang_flag_0 : 1;
    unsigned lang_flag_1 : 1;
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.283
diff -c -p -d -r1.283 varasm.c
*** varasm.c	19 May 2002 20:17:50 -0000	1.283
--- varasm.c	21 May 2002 22:10:19 -0000
*************** assemble_variable (decl, top_level, at_e
*** 1586,1604 ****
  
    /* Handle uninitialized definitions.  */
  
!   if ((DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node
! #if defined ASM_EMIT_BSS
!        || (flag_zero_initialized_in_bss
! 	   && initializer_zerop (DECL_INITIAL (decl)))
! #endif
!        )
!       /* If the target can't output uninitialized but not common global data
! 	 in .bss, then we have to use .data.  */
! #if ! defined ASM_EMIT_BSS
!       && DECL_COMMON (decl)
  #endif
!       && DECL_SECTION_NAME (decl) == NULL_TREE
!       && ! dont_output_data)
      {
        unsigned HOST_WIDE_INT size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
        unsigned HOST_WIDE_INT rounded = size;
--- 1586,1613 ----
  
    /* Handle uninitialized definitions.  */
  
!   /* If the decl has been given an explicit section name, then it
!      isn't common, and shouldn't be handled as such.  */
!   if (DECL_SECTION_NAME (decl) || dont_output_data)
!     ;
!   /* We don't implement common thread-local data at present.  */
!   else if (DECL_THREAD_LOCAL (decl))
!     {
!       if (DECL_COMMON (decl))
! 	sorry ("thread-local COMMON data not implemented");
!     }
! #ifndef ASM_EMIT_BSS
!   /* If the target can't output uninitialized but not common global data
!      in .bss, then we have to use .data.  */
!   /* ??? We should handle .bss via select_section mechanisms rather than
!      via special target hooks.  That would eliminate this special case.  */
!   else if (!DECL_COMMON (decl))
!     ;
  #endif
!   else if (DECL_INITIAL (decl) == 0
! 	   || DECL_INITIAL (decl) == error_mark_node
!            || (flag_zero_initialized_in_bss
! 	       && initializer_zerop (DECL_INITIAL (decl))))
      {
        unsigned HOST_WIDE_INT size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
        unsigned HOST_WIDE_INT rounded = size;
*************** default_section_type_flags (decl, name, 
*** 5101,5109 ****
        || strncmp (name, ".gnu.linkonce.b.", 16) == 0
        || strcmp (name, ".sbss") == 0
        || strncmp (name, ".sbss.", 6) == 0
!       || strncmp (name, ".gnu.linkonce.sb.", 17) == 0)
      flags |= SECTION_BSS;
  
    return flags;
  }
  
--- 5110,5123 ----
        || strncmp (name, ".gnu.linkonce.b.", 16) == 0
        || strcmp (name, ".sbss") == 0
        || strncmp (name, ".sbss.", 6) == 0
!       || strncmp (name, ".gnu.linkonce.sb.", 17) == 0
!       || strcmp (name, ".tbss") == 0)
      flags |= SECTION_BSS;
  
+   if (strcmp (name, ".tdata") == 0
+       || strcmp (name, ".tbss") == 0)
+     flags |= SECTION_TLS;
+ 
    return flags;
  }
  
*************** default_elf_asm_named_section (name, fla
*** 5146,5151 ****
--- 5160,5167 ----
      *f++ = 'M';
    if (flags & SECTION_STRINGS)
      *f++ = 'S';
+   if (flags & SECTION_TLS)
+     *f++ = 'T';
    *f = '\0';
  
    if (flags & SECTION_BSS)
*************** categorize_decl_for_section (decl, reloc
*** 5353,5360 ****
    else
      ret = SECCAT_RODATA;
  
    /* If the target uses small data sections, select it.  */
!   if ((*targetm.in_small_data_p) (decl))
      {
        if (ret == SECCAT_BSS)
  	ret = SECCAT_SBSS;
--- 5369,5385 ----
    else
      ret = SECCAT_RODATA;
  
+   /* There are no read-only thread-local sections.  */
+   if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
+     {
+       if (ret == SECCAT_BSS)
+ 	ret = SECCAT_TBSS;
+       else
+ 	ret = SECCAT_TDATA;
+     }
+ 
    /* If the target uses small data sections, select it.  */
!   else if ((*targetm.in_small_data_p) (decl))
      {
        if (ret == SECCAT_BSS)
  	ret = SECCAT_SBSS;
Index: cp/lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/lex.c,v
retrieving revision 1.277
diff -c -p -d -r1.277 lex.c
*** cp/lex.c	25 Apr 2002 06:24:34 -0000	1.277
--- cp/lex.c	21 May 2002 22:10:21 -0000
*************** const short rid_to_yy[RID_MAX] =
*** 474,479 ****
--- 474,480 ----
    /* RID_BOUNDED */	0,
    /* RID_UNBOUNDED */	0,
    /* RID_COMPLEX */	TYPESPEC,
+   /* RID_THREAD */	0,
  
    /* C++ */
    /* RID_FRIEND */	SCSPEC,
Index: doc/extend.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/extend.texi,v
retrieving revision 1.70
diff -c -p -d -r1.70 extend.texi
*** doc/extend.texi	11 May 2002 16:25:04 -0000	1.70
--- doc/extend.texi	21 May 2002 22:10:22 -0000
*************** extensions, accepted by GCC in C89 mode 
*** 432,437 ****
--- 432,438 ----
  * Target Builtins::     Built-in functions specific to particular targets.
  * Pragmas::             Pragmas accepted by GCC.
  * Unnamed Fields::      Unnamed struct/union fields within structs/unions.
+ * Thread-Local::        Per-thread variables.
  @end menu
  
  @node Statement Exprs
*************** struct @{
*** 6164,6169 ****
--- 6165,6219 ----
  It is ambiguous which @code{a} is being referred to with @samp{foo.a}.
  Such constructs are not supported and must be avoided.  In the future,
  such constructs may be detected and treated as compilation errors.
+ 
+ @node Thread-Local
+ @section Thread-Local Storage
+ @cindex Thread-Local Storage
+ @cindex TLS
+ @cindex __thread
+ 
+ Thread-local storage (TLS) is a mechanism by which variables are
+ allocated such that there is one instance of the variable per extant
+ thread.  The run-time model GCC uses to implement this originates
+ in the IA-64 processor-specific ABI, but has since been migrated
+ to other processors as well.  It requires significant support from
+ the linker (@command{ld}), dynamic linker (@command{ld.so}), and
+ system libraries (@file{libc.so} and @file{libpthread.so}), so it
+ is not supported everywhere.
+ 
+ At the user level, the extension is visible with a new storage
+ class keyword: @code{__thread}.  For example:
+ 
+ @example
+ __thread int i;
+ extern __thread struct state s;
+ static __thread char *p;
+ @end example
+ 
+ The @code{__thread} specifier may be used alone, with the @code{extern}
+ or @code{static} specifiers, but with no other storage class specifier.
+ When used with @code{extern} or @code{static}, @code{__thread} must appear
+ immediately after the other storage class specifier.
+ 
+ The @code{__thread} specifier may be applied to any global, file-scoped
+ static, function-scoped static, or class-scoped static variable.  It may
+ not be applied to function-scoped automatic or class-scoped member variables.
+ 
+ When the address-of operator is applied to a thread-local variable, it is
+ evaluated at run-time and returns the address of the current thread's
+ instance of that variable.  An address so obtained may be used by any
+ thread.  When a thread terminates, any pointers to thread-local variables
+ in that thread become invalid.
+ 
+ No static initialization may refer to the address of a thread-local variable.
+ 
+ In C++, a thread-local variable may not be initialized by a static
+ constructor.
+ 
+ See @uref{http://people.redhat.com/drepper/tls.pdf,
+ ELF Handling For Thread-Local Storage} for a detailed explanation of
+ the four thread-local storage addressing models, and how the run-time
+ is expected to function.
  
  @node C++ Extensions
  @chapter Extensions to the C++ Language
Index: doc/invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.146
diff -c -p -d -r1.146 invoke.texi
*** doc/invoke.texi	18 May 2002 19:02:02 -0000	1.146
--- doc/invoke.texi	21 May 2002 22:10:22 -0000
*************** in the following sections.
*** 677,683 ****
  -fverbose-asm  -fpack-struct  -fstack-check @gol
  -fstack-limit-register=@var{reg}  -fstack-limit-symbol=@var{sym} @gol
  -fargument-alias  -fargument-noalias @gol
! -fargument-noalias-global  -fleading-underscore}
  @end table
  
  @menu
--- 677,683 ----
  -fverbose-asm  -fpack-struct  -fstack-check @gol
  -fstack-limit-register=@var{reg}  -fstack-limit-symbol=@var{sym} @gol
  -fargument-alias  -fargument-noalias @gol
! -fargument-noalias-global  -fleading-underscore -ftls-model=@var{model}}
  @end table
  
  @menu
*************** is to help link with legacy assembly cod
*** 9915,9920 ****
--- 9915,9928 ----
  
  Be warned that you should know what you are doing when invoking this
  option, and that not all targets provide complete support for it.
+ 
+ @item -ftls-model=@var{model}
+ Alter the thread-local storage model to be used (@pxref{Thread-Local}).
+ The @var{model} argument should be one of @code{global-dynamic},
+ @code{local-dynamic}, @code{initial-exec} or @code{local-exec}.
+ 
+ The default without @option{-fpic} is @code{initial-exec}; with
+ @option{-fpic} the default is @code{global-dynamic}.
  @end table
  
  @c man end
Index: fixinc/inclhack.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fixinc/inclhack.def,v
retrieving revision 1.128
diff -c -p -d -r1.128 inclhack.def
*** fixinc/inclhack.def	14 May 2002 00:33:14 -0000	1.128
--- fixinc/inclhack.def	21 May 2002 22:10:23 -0000
***************
*** 1,4 ****
- 
  /* -*- Mode: C -*-  */
  
  autogen definitions fixincl;
--- 1,3 ----
*************** fix = {
*** 2885,2890 ****
--- 2884,2903 ----
      "extern char*\tbsearch(void*,size_t,size_t);\n";
  };
  
+ 
+ /*
+  * __thread is now a keyword.
+  */
+ fix = {
+     hackname	= thread_keyword;
+     files	= "pthread.h";
+     files	= "bits/sigthread.h";
+     select	= "pthread_t __thread";
+ 
+     sed		= "s/pthread_t __thread\\([^a-z0-9_]\\)/pthread_t __thr\\1/";
+ 
+     test_text	= "extern int pthread_kill (pthread_t __thread, int __signo);";
+ };
  
  /*
   *  if the #if says _cplusplus, not the double underscore __cplusplus
Index: testsuite/gcc.dg/tls/diag-1.c
===================================================================
RCS file: testsuite/gcc.dg/tls/diag-1.c
diff -N testsuite/gcc.dg/tls/diag-1.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/tls/diag-1.c	21 May 2002 22:51:13 -0000
***************
*** 0 ****
--- 1,11 ----
+ /* Valid __thread specifiers.  */
+ 
+ __thread int g1;
+ extern __thread int g2;
+ static __thread int g3;
+ 
+ void foo()
+ {
+   extern __thread int l1;
+   static __thread int l2;
+ }
Index: testsuite/gcc.dg/tls/diag-2.c
===================================================================
RCS file: testsuite/gcc.dg/tls/diag-2.c
diff -N testsuite/gcc.dg/tls/diag-2.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/tls/diag-2.c	21 May 2002 22:51:13 -0000
***************
*** 0 ****
--- 1,21 ----
+ /* Invalid __thread specifiers.  */
+ 
+ __thread extern int g1;		/* { dg-error "`__thread' before `extern'" } */
+ __thread static int g2;		/* { dg-error "`__thread' before `static'" } */
+ __thread __thread int g3;	/* { dg-error "duplicate `__thread'" } */
+ typedef __thread int g4;	/* { dg-error "multiple storage classes" } */
+ 
+ void foo()
+ {
+   __thread int l1;		/* { dg-error "implicitly auto and declared `__thread'" } */
+   auto __thread int l2;		/* { dg-error "multiple storage classes" } */
+   __thread extern int l3;	/* { dg-error "`__thread' before `extern'" } */
+   register __thread int l4;	/* { dg-error "multiple storage classes" } */
+ }
+ 
+ __thread void f1 ();		/* { dg-error "invalid storage class for function" } */
+ extern __thread void f2 ();	/* { dg-error "invalid storage class for function" } */
+ static __thread void f3 ();	/* { dg-error "invalid storage class for function" } */
+ __thread void f4 () { }		/* { dg-error "function definition declared `__thread'" } */
+ 
+ void bar(__thread int p1);	/* { dg-error "storage class specified for parameter" } */
Index: testsuite/gcc.dg/tls/init-1.c
===================================================================
RCS file: testsuite/gcc.dg/tls/init-1.c
diff -N testsuite/gcc.dg/tls/init-1.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/tls/init-1.c	21 May 2002 22:51:13 -0000
***************
*** 0 ****
--- 1,4 ----
+ /* Invalid initializations.  */
+ 
+ extern __thread int i;
+ int *p = &i;	/* { dg-error "initializer element is not constant" } */
Index: testsuite/gcc.dg/tls/tls.exp
===================================================================
RCS file: testsuite/gcc.dg/tls/tls.exp
diff -N testsuite/gcc.dg/tls/tls.exp
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/tls/tls.exp	21 May 2002 22:51:13 -0000
***************
*** 0 ****
--- 1,45 ----
+ #   Copyright (C) 2002 Free Software Foundation, Inc.
+ 
+ # This program is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU General Public License as published by
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+ # 
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ # GNU General Public License for more details.
+ # 
+ # You should have received a copy of the GNU General Public License
+ # along with this program; if not, write to the Free Software
+ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+ 
+ # GCC testsuite that uses the `dg.exp' driver.
+ 
+ # Load support procs.
+ load_lib gcc-dg.exp
+ 
+ # Test for thread-local data supported by the platform.  If it
+ # isn't, everything will fail with the "not supported" message.
+ 
+ set comp_output [gcc_target_compile \
+ 		"$srcdir/$subdir/trivial.c" "trivial.S" assembly ""]
+ if { [string match "*not supported*" $comp_output] } {
+   return 0
+ }
+ 
+ # If a testcase doesn't have special options, use these.
+ global DEFAULT_CFLAGS
+ if ![info exists DEFAULT_CFLAGS] then {
+     set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+ }
+ 
+ # Initialize `dg'.
+ dg-init
+ 
+ # Main loop.
+ dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
+         "" $DEFAULT_CFLAGS
+ 
+ # All done.
+ dg-finish
Index: testsuite/gcc.dg/tls/trivial.c
===================================================================
RCS file: testsuite/gcc.dg/tls/trivial.c
diff -N testsuite/gcc.dg/tls/trivial.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/tls/trivial.c	21 May 2002 22:51:13 -0000
***************
*** 0 ****
--- 1 ----
+ __thread int i;

^ permalink raw reply	[flat|nested] 875+ messages in thread
* biggest alignment for sysv4.h altivec
@ 2002-03-08 14:25 Aldy Hernandez
  2002-03-08 14:49 ` Geoff Keating
  0 siblings, 1 reply; 875+ messages in thread
From: Aldy Hernandez @ 2002-03-08 14:25 UTC (permalink / raw)
  To: dje, gcc-patches

obvious.

committing to branch and mainline.

2002-03-08  Aldy Hernandez  <aldyh@redhat.com>

	* config/rs6000/sysv4.h (BIGGEST_ALIGNMENT): Change for altivec.

Index: config/rs6000/sysv4.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/sysv4.h,v
retrieving revision 1.84
diff -c -p -r1.84 sysv4.h
*** sysv4.h	2002/02/19 19:40:41	1.84
--- sysv4.h	2002/03/08 22:23:47
*************** do {									\
*** 385,391 ****
  
  /* No data type wants to be aligned rounder than this.  */
  #undef	BIGGEST_ALIGNMENT
! #define BIGGEST_ALIGNMENT (TARGET_EABI ? 64 : 128)
  
  /* An expression for the alignment of a structure field FIELD if the
     alignment computed in the usual way is COMPUTED.  */
--- 385,391 ----
  
  /* No data type wants to be aligned rounder than this.  */
  #undef	BIGGEST_ALIGNMENT
! #define BIGGEST_ALIGNMENT ((TARGET_EABI && !TARGET_ALTIVEC) ? 64 : 128)
  
  /* An expression for the alignment of a structure field FIELD if the
     alignment computed in the usual way is COMPUTED.  */

^ permalink raw reply	[flat|nested] 875+ messages in thread
* f build dies with: undefined reference to `lookup_name'
@ 2002-03-06  6:54 Andrew Cagney
  2002-03-06  8:29 ` David Edelsohn
  0 siblings, 1 reply; 875+ messages in thread
From: Andrew Cagney @ 2002-03-06  6:54 UTC (permalink / raw)
  To: gcc-patches

Hello,

I'm trying to get some patches committed but am finding that my build 
dies in while building fortran with:

gcc -DIN_GCC    -g -O -W -Wall -Wwrite-strings -Wstrict-prototypes 
-Wmissing-prototypes -Wtraditional -pedantic -Wno-long-long 
-DHAVE_CONFIG_H  -o f771 f/bad.o f/bit.o f/bld.o f/com.o f/data.o 
f/equiv.o f/expr.o f/global.o f/implic.o f/info.o f/intrin.o f/lab.o 
f/lex.o f/malloc.o f/name.o f/parse.o f/src.o f/st.o f/sta.o f/stb.o 
f/stc.o f/std.o f/ste.o f/storag.o f/stp.o f/str.o f/sts.o f/stt.o 
f/stu.o f/stv.o f/stw.o f/symbol.o f/target.o f/top.o f/type.o 
f/version.o f/where.o main.o libbackend.a   ../libiberty/libiberty.a
libbackend.a(varasm.o): In function `weak_finish':
/home/scratch/PENDING/GCC-2002-02-02-switch-default/gcc/gcc/varasm.c:5111: 
undefined reference to `lookup_name'

on a powerpc-unknown-netbsd1.5ZA native build.

I suspect this change:

2002-03-01  Alan Modra  <amodra@bigpond.net.au>
             David Edelsohn  <edelsohn@gnu.org>

	.....
         (weak_finish): Use ASM_WEAKEN_DECL. Try to find decl.
         (remove_from_pending_weak_list): Declare and define for
         ASM_WEAKEN_DECL.

Andrew

^ permalink raw reply	[flat|nested] 875+ messages in thread
* [PATCH] PowerPC fsel PR5217
@ 2002-02-03 19:14 David Edelsohn
  2002-02-03 21:14 ` Geoff Keating
  0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-02-03 19:14 UTC (permalink / raw)
  To: Geoff Keating; +Cc: gcc-patches

	This problem seems to be a mismatch between the mode of the
if_then_else in the generated RTL versus the machine description.  I think
this mixed mode pattern only can be generated by GCC internally, not any
machine description pattern, so we might as well follow the canonical
modes that GCC chooses.

	Does this seem correct to you, Geoff?  Or should the if_then_else
be the other mode?

David


Index: rs6000.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.162
diff -c -p -r1.162 rs6000.md
*** rs6000.md	2002/01/29 22:49:55	1.162
--- rs6000.md	2002/02/04 00:46:26
***************
*** 5084,5090 ****
  
  (define_insn "*fseldfsf4"
    [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
! 	(if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
  			     (match_operand:DF 4 "zero_fp_constant" "F"))
  			 (match_operand:SF 2 "gpc_reg_operand" "f")
  			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
--- 5084,5090 ----
  
  (define_insn "*fseldfsf4"
    [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
! 	(if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
  			     (match_operand:DF 4 "zero_fp_constant" "F"))
  			 (match_operand:SF 2 "gpc_reg_operand" "f")
  			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
***************
*** 5248,5254 ****
  
  (define_insn "*fselsfdf4"
    [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
! 	(if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
  			     (match_operand:SF 4 "zero_fp_constant" "F"))
  			 (match_operand:DF 2 "gpc_reg_operand" "f")
  			 (match_operand:DF 3 "gpc_reg_operand" "f")))]
--- 5248,5254 ----
  
  (define_insn "*fselsfdf4"
    [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
! 	(if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
  			     (match_operand:SF 4 "zero_fp_constant" "F"))
  			 (match_operand:DF 2 "gpc_reg_operand" "f")
  			 (match_operand:DF 3 "gpc_reg_operand" "f")))]

^ permalink raw reply	[flat|nested] 875+ messages in thread
* ppc call_value* fixes (plus minor apple gripe)
@ 2002-01-28  1:05 Aldy Hernandez
  2002-01-28  7:26 ` Stan Shebs
                   ` (3 more replies)
  0 siblings, 4 replies; 875+ messages in thread
From: Aldy Hernandez @ 2002-01-28  1:05 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn, Stan Shebs

[-- Attachment #1: Type: text/plain, Size: 5474 bytes --]

<gripe>
both of the problems described here had obviously
been debugged and fixed by apple, and at least one of them was coded
after my altivec changes went in, so it would have been VERY simple
to submit the fix to the gcc list as well.

guys, if you have fixes in your local tree that are very obviously 
correct,
and will undoubtedly be encountered by others, post them.  it saves
the rest of us cycles that could be used to do other cool things in gcc
(and not spent re-fixing things that have already been fixed).
</gripe>

find_reloads was dying trying to fit the register constraints of
*call_value_nonlocal_sysv.  the first operand needed a "v" constraint 
added.
likewise for a couple more call_value* patterns.  i didn't mess with the 
AIX
call_value patterns because currently there is no AIX altivec, but i 
could
add it if someone wants it.

i also added a new register class because find_reloads was picking the
wrong register for the pattern:

	(define_insn "*call_value_nonlocal_sysv"
	  [(set (match_operand 0 "" "=fgv,fgv,fgv,fgv")

upon seeing f and g, the biggest subunion containing them was set to
NON_SPECIAL_REGS, then when it tried to get the union of that and
ALTIVEC_REGS it got confused.  i noticed apple-gcc has moved
NON_SPECIAL_REGS before ALTIVEC_REGS to fix the problem, but
i believe the proper solution is to add a register class encompassing all
three register classes.

so... this patch:
	a) fixes the call_value patterns to handle vector return values
	b) adds GEN_OR_FLOAT_OR_ALTIVEC_REGS

ok?

2002-01-28  Aldy Hernandez  <aldyh@redhat.com>

	* config/rs6000/rs6000.h (reg_class): New class
	GEN_OR_FLOAT_OR_ALTIVEC_REGS.
	(REG_CLASS_NAMES): Same.
	(REG_CLASS_CONTENTS): Same.

	* rs6000.md ("*call_value_local32"): Support vector registers.
	("*call_value_local64"): Same.
	("*call_value_nonlocal_sysv"): Same.

Index: config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.176
diff -c -p -r1.176 rs6000.h
*** rs6000.h	2002/01/22 02:36:52	1.176
--- rs6000.h	2002/01/28 07:30:17
*************** enum reg_class
*** 1046,1051 ****
--- 1046,1052 ----
     GENERAL_REGS,
     FLOAT_REGS,
     ALTIVEC_REGS,
+   GEN_OR_FLOAT_OR_ALTIVEC_REGS,
     VRSAVE_REGS,
     NON_SPECIAL_REGS,
     MQ_REGS,
*************** enum reg_class
*** 1073,1078 ****
--- 1074,1080 ----
     "GENERAL_REGS",							\
     "FLOAT_REGS",								\
     "ALTIVEC_REGS",							\
+   
"GEN_OR_FLOAT_OR_ALTIVEC_REGS",                                       \
     "VRSAVE_REGS",							\
     "NON_SPECIAL_REGS",							\
     "MQ_REGS",								\
*************** enum reg_class
*** 1099,1104 ****
--- 1101,1107 ----
     { 0xffffffff, 0x00000000, 0x00000008, 0x00000000 }, /* 
GENERAL_REGS */     \
     { 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* 
FLOAT_REGS */       \
     { 0x00000000, 0x00000000, 0xffffe000, 0x00001fff }, /* 
ALTIVEC_REGS */     \
+   { 0xffffffff, 0xffffffff, 0xffffe008, 0x00001fff }, /* 
GEN_OR_FLOAT_OR_ALTIVEC_REGS */ \
     { 0x00000000, 0x00000000, 0x00000000, 0x00002000 }, /* VRSAVE_REGS */	
      \
     { 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /* 
NON_SPECIAL_REGS */ \
     { 0x00000000, 0x00000000, 0x00000001, 0x00000000 }, /* MQ_REGS */	    
  \
Index: config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.161
diff -c -p -r1.161 rs6000.md
*** rs6000.md	2002/01/25 17:52:43	1.161
--- rs6000.md	2002/01/28 07:30:28
***************
*** 9878,9884 ****
      (set_attr "length" "4,8")])

   (define_insn "*call_value_local32"
!   [(set (match_operand 0 "" "=fg,fg")
   	(call (mem:SI (match_operand:SI 1 "current_file_function_operand" 
"s,s"))
   	      (match_operand 2 "" "g,g")))
      (use (match_operand:SI 3 "immediate_operand" "O,n"))
--- 9878,9884 ----
      (set_attr "length" "4,8")])

   (define_insn "*call_value_local32"
!   [(set (match_operand 0 "" "=fgv,fgv")
   	(call (mem:SI (match_operand:SI 1 "current_file_function_operand" 
"s,s"))
   	      (match_operand 2 "" "g,g")))
      (use (match_operand:SI 3 "immediate_operand" "O,n"))
***************
*** 9899,9905 ****


   (define_insn "*call_value_local64"
!   [(set (match_operand 0 "" "=fg,fg")
   	(call (mem:SI (match_operand:DI 1 "current_file_function_operand" 
"s,s"))
   	      (match_operand 2 "" "g,g")))
      (use (match_operand:SI 3 "immediate_operand" "O,n"))
--- 9899,9905 ----


   (define_insn "*call_value_local64"
!   [(set (match_operand 0 "" "=fgv,fgv")
   	(call (mem:SI (match_operand:DI 1 "current_file_function_operand" 
"s,s"))
   	      (match_operand 2 "" "g,g")))
      (use (match_operand:SI 3 "immediate_operand" "O,n"))
***************
*** 10067,10073 ****
      (set_attr "length" "4,8,4,8")])

   (define_insn "*call_value_nonlocal_sysv"
!   [(set (match_operand 0 "" "=fg,fg,fg,fg")
   	(call (mem:SI (match_operand:SI 1 "call_operand" "cl,cl,s,s"))
   	      (match_operand 2 "" "g,g,g,g")))
      (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
--- 10067,10073 ----
      (set_attr "length" "4,8,4,8")])

   (define_insn "*call_value_nonlocal_sysv"
!   [(set (match_operand 0 "" "=fgv,fgv,fgv,fgv")
   	(call (mem:SI (match_operand:SI 1 "call_operand" "cl,cl,s,s"))
   	      (match_operand 2 "" "g,g,g,g")))
      (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))

[-- Attachment #2: Type: text/enriched, Size: 5615 bytes --]

<fontfamily><param>Helvetica</param><<gripe>

both of the problems described here had obviously 

been debugged and fixed by apple, and at least one of them was coded

after my altivec changes went in, so it would have been VERY simple

to submit the fix to the gcc list as well.


guys, if you have fixes in your local tree that are very obviously
correct, 

and will undoubtedly be encountered by others, post them.  it saves

the rest of us cycles that could be used to do other cool things in
gcc 

(and not spent re-fixing things that have already been fixed).

<</gripe>


find_reloads was dying trying to fit the register constraints of 

*call_value_nonlocal_sysv.  the first operand needed a "v" constraint
added.

likewise for a couple more call_value* patterns.  i didn't mess with
the AIX

call_value patterns because currently there is no AIX altivec, but i
could 

add it if someone wants it.


i also added a new register class because find_reloads was picking the

wrong register for the pattern:


	(define_insn "*call_value_nonlocal_sysv"

	  [(set (match_operand 0 "" "=fgv,fgv,fgv,fgv")


upon seeing f and g, the biggest subunion containing them was set to

NON_SPECIAL_REGS, then when it tried to get the union of that and

ALTIVEC_REGS it got confused.  i noticed apple-gcc has moved

NON_SPECIAL_REGS before ALTIVEC_REGS to fix the problem, but

i believe the proper solution is to add a register class encompassing
all

three register classes.


so... this patch:

	a) fixes the call_value patterns to handle vector return values

	b) adds GEN_OR_FLOAT_OR_ALTIVEC_REGS


ok?


2002-01-28  Aldy Hernandez  <<aldyh@redhat.com>


	* config/rs6000/rs6000.h (reg_class): New class

	GEN_OR_FLOAT_OR_ALTIVEC_REGS.

	(REG_CLASS_NAMES): Same.

	(REG_CLASS_CONTENTS): Same.


	* rs6000.md ("*call_value_local32"): Support vector registers.

	("*call_value_local64"): Same.

	("*call_value_nonlocal_sysv"): Same.


Index: config/rs6000/rs6000.h

===================================================================

RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.h,v

retrieving revision 1.176

diff -c -p -r1.176 rs6000.h

*** rs6000.h	2002/01/22 02:36:52	1.176

--- rs6000.h	2002/01/28 07:30:17

*************** enum reg_class

*** 1046,1051 ****

--- 1046,1052 ----

    GENERAL_REGS,

    FLOAT_REGS,

    ALTIVEC_REGS,

+   GEN_OR_FLOAT_OR_ALTIVEC_REGS,

    VRSAVE_REGS,

    NON_SPECIAL_REGS,

    MQ_REGS,

*************** enum reg_class

*** 1073,1078 ****

--- 1074,1080 ----

    "GENERAL_REGS",							\

    "FLOAT_REGS",								\

    "ALTIVEC_REGS",							\

+   "GEN_OR_FLOAT_OR_ALTIVEC_REGS",                                       \

    "VRSAVE_REGS",							\

    "NON_SPECIAL_REGS",							\

    "MQ_REGS",								\

*************** enum reg_class

*** 1099,1104 ****

--- 1101,1107 ----

    { 0xffffffff, 0x00000000, 0x00000008, 0x00000000 }, /*
GENERAL_REGS */     \

    { 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS
*/       \

    { 0x00000000, 0x00000000, 0xffffe000, 0x00001fff }, /*
ALTIVEC_REGS */     \

+   { 0xffffffff, 0xffffffff, 0xffffe008, 0x00001fff }, /*
GEN_OR_FLOAT_OR_ALTIVEC_REGS */ \

    { 0x00000000, 0x00000000, 0x00000000, 0x00002000 }, /* VRSAVE_REGS
*/	     \

    { 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /*
NON_SPECIAL_REGS */ \

    { 0x00000000, 0x00000000, 0x00000001, 0x00000000 }, /* MQ_REGS */	     \

Index: config/rs6000/rs6000.md

===================================================================

RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.md,v

retrieving revision 1.161

diff -c -p -r1.161 rs6000.md

*** rs6000.md	2002/01/25 17:52:43	1.161

--- rs6000.md	2002/01/28 07:30:28

***************

*** 9878,9884 ****

     (set_attr "length" "4,8")])

  

  (define_insn "*call_value_local32"

!   [(set (match_operand 0 "" "=fg,fg")

  	(call (mem:SI (match_operand:SI 1 "current_file_function_operand"
"s,s"))

  	      (match_operand 2 "" "g,g")))

     (use (match_operand:SI 3 "immediate_operand" "O,n"))

--- 9878,9884 ----

     (set_attr "length" "4,8")])

  

  (define_insn "*call_value_local32"

!   [(set (match_operand 0 "" "=fgv,fgv")

  	(call (mem:SI (match_operand:SI 1 "current_file_function_operand"
"s,s"))

  	      (match_operand 2 "" "g,g")))

     (use (match_operand:SI 3 "immediate_operand" "O,n"))

***************

*** 9899,9905 ****

  

  

  (define_insn "*call_value_local64"

!   [(set (match_operand 0 "" "=fg,fg")

  	(call (mem:SI (match_operand:DI 1 "current_file_function_operand"
"s,s"))

  	      (match_operand 2 "" "g,g")))

     (use (match_operand:SI 3 "immediate_operand" "O,n"))

--- 9899,9905 ----

  

  

  (define_insn "*call_value_local64"

!   [(set (match_operand 0 "" "=fgv,fgv")

  	(call (mem:SI (match_operand:DI 1 "current_file_function_operand"
"s,s"))

  	      (match_operand 2 "" "g,g")))

     (use (match_operand:SI 3 "immediate_operand" "O,n"))

***************

*** 10067,10073 ****

     (set_attr "length" "4,8,4,8")])

  

  (define_insn "*call_value_nonlocal_sysv"

!   [(set (match_operand 0 "" "=fg,fg,fg,fg")

  	(call (mem:SI (match_operand:SI 1 "call_operand" "cl,cl,s,s"))

  	      (match_operand 2 "" "g,g,g,g")))

     (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))

--- 10067,10073 ----

     (set_attr "length" "4,8,4,8")])

  

  (define_insn "*call_value_nonlocal_sysv"

!   [(set (match_operand 0 "" "=fgv,fgv,fgv,fgv")

  	(call (mem:SI (match_operand:SI 1 "call_operand" "cl,cl,s,s"))

  	      (match_operand 2 "" "g,g,g,g")))

     (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))

</fontfamily>

^ permalink raw reply	[flat|nested] 875+ messages in thread
* PATCH, rs6000 (alpha?) long const
@ 2001-12-29  7:03 Tom Rix
  2001-12-29 11:40 ` Richard Henderson
  0 siblings, 1 reply; 875+ messages in thread
From: Tom Rix @ 2001-12-29  7:03 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 552 bytes --]

This patch fixes an incorrect add of a large immediate in
rs6000_emit_set_long_const.    d2 can not be added because it is greater
than 2^16.

To reproduce the problem, run the testsuite with the -maix64 switch.  A
large number of internal compiler errors are generated.   The one I
looked specifically was execute/920410-1.c

With the patch, -maix64 c failures are reduced from 216  to 115.

Looks like alpha also uses this logic.  Can someone familar with alpha
comment on the old logic's correctness?

Tom

--
Tom Rix
GCC Engineer
trix@redhat.com



[-- Attachment #2: long_const-001fa.patch --]
[-- Type: text/plain, Size: 2939 bytes --]

2001-12-28  Tom Rix  <trix@redhat.com>

	* config/rs6000/rs6000.c (rs6000_emit_set_long_const): Fix invalid add 
	of large immediate.
 
diff -rcp gcc-old/gcc/config/rs6000/rs6000.c gcc/gcc/config/rs6000/rs6000.c
*** gcc-old/gcc/config/rs6000/rs6000.c	Fri Dec 28 10:00:02 2001
--- gcc/gcc/config/rs6000/rs6000.c	Fri Dec 28 22:59:44 2001
*************** rs6000_emit_set_long_const (dest, c1, c2
*** 2002,2008 ****
      }
    else
      {
!       HOST_WIDE_INT d1, d2, d3, d4;
  
    /* Decompose the entire word */
  #if HOST_BITS_PER_WIDE_INT >= 64
--- 2002,2008 ----
      }
    else
      {
!       HOST_WIDE_INT d1, d2, d2_s, d3, d4;
  
    /* Decompose the entire word */
  #if HOST_BITS_PER_WIDE_INT >= 64
*************** rs6000_emit_set_long_const (dest, c1, c2
*** 2011,2016 ****
--- 2011,2017 ----
        d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
        c1 -= d1;
        d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
+       d2_s = d2 >> 16;
        c1 = (c1 - d2) >> 32;
        d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
        c1 -= d3;
*************** rs6000_emit_set_long_const (dest, c1, c2
*** 2021,2026 ****
--- 2022,2028 ----
        d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
        c1 -= d1;
        d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
+       d2_s = d2 >> 16;
        if (c1 != d2)
  	abort ();
        c2 += (d2 < 0);
*************** rs6000_emit_set_long_const (dest, c1, c2
*** 2039,2056 ****
  	    emit_move_insn (dest,
  			    gen_rtx_PLUS (DImode, dest, GEN_INT (d3)));
  	}
!       else
  	emit_move_insn (dest, GEN_INT (d3));
  
        /* Shift it into place */
        if (d3 != 0 || d4 != 0)
! 	emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
  
        /* Add in the low bits.  */
        if (d2 != 0)
! 	emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT (d2)));
        if (d1 != 0)
! 	emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT (d1)));
      }
  
    return dest;
--- 2041,2074 ----
  	    emit_move_insn (dest,
  			    gen_rtx_PLUS (DImode, dest, GEN_INT (d3)));
  	}
!       else if (d3 != 0)
  	emit_move_insn (dest, GEN_INT (d3));
  
        /* Shift it into place */
        if (d3 != 0 || d4 != 0)
!  	if (d2 != 0) 
!  	  emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
!  	else 
! 	  emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
  
        /* Add in the low bits.  */
        if (d2 != 0)
! 	{
! 	  if (d3 != 0 || d4 != 0)
! 	    {
!  	      emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, 
!  						  GEN_INT (d2_s)));
!  	      emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest,  
!  						    GEN_INT (16)));
! 	    }
! 	  else
! 	    emit_move_insn (dest, GEN_INT (d2));
! 	}
        if (d1 != 0)
! 	if (d2 != 0 || d3 != 0 || d4 != 0)
! 	  emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT (d1)));
! 	else
! 	  emit_move_insn (dest, GEN_INT (d1));
      }
  
    return dest;

^ permalink raw reply	[flat|nested] 875+ messages in thread
* Re: [PATCH] adds powerpc-*-freebsd? to mainline
@ 2001-11-13 15:03 David Edelsohn
  2001-11-13 15:03 ` Geoff Keating
  0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Geoff Keating, Stan Shebs, David O'Brien; +Cc: gcc-patches

>>>>> Geoff writes:

Geoff> I don't think that would be a problem.

	I have a problem with that.  Adding freebsd-spec.h to the generic
PowerPC ELF targets is fine, but adding it to every ELF target is not
acceptable to me.  I do not agree with the config.gcc changes in this
patch and it needs to be revised or reverted.

David

^ permalink raw reply	[flat|nested] 875+ messages in thread

end of thread, other threads:[~2007-09-04 13:46 UTC | newest]

Thread overview: 875+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-04-09 19:34 [PATCH] fold-const.c use of BRANCH_COST David Edelsohn
2003-04-11  4:11 ` Richard Henderson
2003-04-11  4:23   ` Andrew Pinski
2003-04-11 17:47     ` Geoff Keating
2003-04-12  2:48       ` Segher Boessenkool
2003-04-11  4:24   ` David Edelsohn
2003-04-11  4:43     ` Richard Henderson
2003-04-11  4:58       ` David Edelsohn
2003-04-11  5:11         ` Richard Henderson
2003-04-11 14:41           ` David Edelsohn
2003-04-11 14:47             ` Jan Hubicka
2003-04-11 15:51               ` David Edelsohn
2003-04-11 16:57                 ` Jan Hubicka
2003-04-11 16:58                   ` David Edelsohn
2003-04-21 17:24                   ` David Edelsohn
2003-04-21 18:00                     ` Richard Henderson
2003-04-22 15:02                       ` David Edelsohn
2003-04-11 17:49             ` Geoff Keating
2003-04-11 17:08         ` Dale Johannesen
2003-04-11 17:54           ` David Edelsohn
  -- strict thread matches above, loose matches on Subject: below --
2007-08-14 20:00 Fix a reload ICE on e500 Daniel Jacobowitz
2007-08-20  7:38 ` Andrew Pinski
2007-09-04 12:55   ` Daniel Jacobowitz
2007-08-13 13:31 Mark PowerPC vector ABI in binary attributes Daniel Jacobowitz
2007-07-31  8:20 [patch] set -mabi=altivec with -ftree-vectorize Zdenek Dvorak
2007-07-31 12:01 ` Daniel Jacobowitz
2006-08-09 12:49 [PATCH] Fix comments in PPC e500 code Eric Botcazou
2006-08-09 14:02 ` David Edelsohn
2006-08-09 14:15   ` Daniel Jacobowitz
2006-07-06 19:53 [PATCH, committed] PR 28150 and PR 28170 David Edelsohn
2006-07-07  3:07 ` Alan Modra
2006-04-12  0:50 [PowerPC] Avoid ICE on DFmode subreg Alan Modra
2006-04-04 16:21 [RFT/RFA] Fix AIX fallout from PR/19653 patch Paolo Bonzini
2006-04-04 17:52 ` David Edelsohn
2006-04-05 17:10   ` Geoff Keating
2006-04-06  3:38     ` David Edelsohn
2006-04-06  4:57       ` Roger Sayle
2006-04-06  7:31         ` Paolo Bonzini
2006-04-06 14:31           ` David Edelsohn
2006-04-06 14:42             ` Paolo Bonzini
2006-04-06 22:44               ` David Edelsohn
2006-04-07  7:39                 ` Paolo Bonzini
2006-04-07 14:01                   ` David Edelsohn
     [not found]                   ` <E5778C9D-8FC1-422A-82ED-ABEF7AFA7685@geoffk.org>
     [not found]                     ` <443A1765.2030609@lu.unisi.ch>
     [not found]                       ` <1880BA7B-88BD-41EE-B9E7-33045526437F@geoffk.org>
2006-04-10 16:33                         ` Paolo Bonzini
2006-04-10 16:40                           ` Geoff Keating
2006-04-07 20:49             ` Geoff Keating
2006-04-06 18:46       ` Dale Johannesen
2006-04-06 19:17         ` David Edelsohn
2006-04-05  2:20 ` Alan Modra
2006-04-05  7:12   ` Paolo Bonzini
2006-04-05 14:48     ` Alan Modra
2006-03-30 14:20 [PowerPC] PR26459 again Alan Modra
2006-03-30  4:42 [PowerPC] linuxspe vs. ibm long double Alan Modra
2006-03-30 12:51 ` Joseph S. Myers
2006-02-24  2:22 [PowerPC64] Fix 26453, segfault -m64 -mtraceback=full Alan Modra
2006-02-24  3:57 ` Mark Mitchell
2005-12-28 10:31 [PowerPC] Fix PR25572, -mminimal-toc trashes r30 Alan Modra
2005-12-14 14:56 [PowerPC] Fix 25406, rs6000_special_round_type_align Alan Modra
2005-12-14 23:50 ` Alan Modra
2005-12-09  1:59 [PowerPC] Default TARGET_ALIGN_NATURAL properly for target libs Alan Modra
2005-12-09 16:15 ` Andrew Pinski
     [not found]   ` <20051212022850.GI1563@bubble.grove.modra.org>
     [not found]     ` <26af44d2c30b82a28cfc4fc6e5df2e0d@physics.uc.edu>
2005-12-12  3:34       ` Alan Modra
2005-12-12  6:35         ` Mark Mitchell
2005-12-13  1:02           ` Mike Stump
2005-12-13  2:08             ` Gabriel Dos Reis
2005-12-07  5:09 [PowerPC] Fix pr25212, indexed address predicates Alan Modra
2005-11-28  2:26 [PowerPC] PR24997: ICE with -ftree-vectorize Alan Modra
2005-11-25  4:49 [RS6000] Add some more functions to ppc64-fp.c Alan Modra
2005-11-09 16:28 [PATCH] volatile global register variable David Edelsohn
2005-11-09 18:13 ` Joseph S. Myers
2005-11-09 19:33   ` Ian Lance Taylor
2005-11-09 18:41 ` Daniel Jacobowitz
2005-11-08  2:55 [PowerPC] Fix PR23704, -m64 overrides prior -mno-powerpc-gfxopt Alan Modra
2005-11-02 23:22 [PowerPC64] gcc.c-torture/compile/pr20928.c failure Alan Modra
2005-10-20 11:00 [PowerPC] -msdata=data needless use of .sbss section Alan Modra
2005-10-20 16:28 ` David Edelsohn
2005-10-20 23:04   ` Alan Modra
2005-11-27 23:21 ` Alan Modra
2005-09-12  3:41 [PowerPC] Fix PR23774 stack backchain broken Alan Modra
2005-09-12  2:03 [RS6000] Nop-insertion fix Alan Modra
2005-09-12  7:23 ` Richard Henderson
2005-09-12 14:16   ` Alan Modra
2005-06-23 13:33 [PATCH, committed] PPC405 atomic support (PR target/21760) David Edelsohn
2005-06-23 13:51 ` Andreas Schwab
2005-06-23 19:32   ` David Edelsohn
2005-06-24  2:07     ` Geoffrey Keating
2005-06-24  2:35       ` Andrew Pinski
2005-06-24  3:30         ` Daniel Jacobowitz
2005-06-24 14:16           ` David Edelsohn
2005-06-24 19:10             ` Daniel Jacobowitz
2005-06-27  6:06             ` Richard Henderson
2005-06-27 15:17               ` David Edelsohn
2005-06-24 18:41       ` Zack Weinberg
     [not found]       ` <geoffk@geoffk.org>
2005-06-25 21:46         ` David Edelsohn
2005-06-10  1:09 [PATCH] PowerPC SVR4 _mcount calls Alan Modra
2005-05-12 16:05 powerpc new PLT and GOT Alan Modra
2005-05-12 16:09 ` Andrew Pinski
2005-05-12 20:00   ` Mike Stump
2005-05-13  0:10     ` Alan Modra
2005-05-12 16:53 ` Matt Thomas
2005-05-13  0:00   ` Alan Modra
2005-05-19 13:01 ` Alan Modra
2005-05-25 14:26   ` Alan Modra
2005-05-25 15:17     ` Paolo Carlini
2005-05-30 15:49     ` Alan Modra
2005-05-31  0:35       ` Alan Modra
2005-05-31 10:53     ` Alan Modra
2005-05-31 13:42       ` Joseph S. Myers
2005-05-31 15:03         ` Alan Modra
2005-05-31 17:11           ` Joseph S. Myers
2005-06-01  0:06             ` Alan Modra
2005-03-30 20:02 Patch ping! (4.1 projects, stage 1.2) Hot/cold partitioning fixes Caroline Tice
2005-03-30 23:14 ` Geoffrey Keating
     [not found]   ` <5c0e321f26901d84492dfe29fa755d7e@apple.com>
     [not found]     ` <776b1297c1d3595d7b8c9d3699a40431@geoffk.org>
     [not found]       ` <87ll84llvz.fsf@codesourcery.com>
2005-03-31  0:19         ` Caroline Tice
2005-03-31  0:29           ` Zack Weinberg
2005-03-31  0:43             ` Richard Henderson
2005-04-01 13:55 ` AIX bootstrap failure (was Re: Hot/cold partitioning fixes) David Edelsohn
2005-04-01 16:44   ` David Edelsohn
2005-04-01 17:13     ` Caroline Tice
2005-04-01 18:24       ` David Edelsohn
2005-04-01 19:20         ` Caroline Tice
2005-04-01 19:25           ` David Edelsohn
2005-04-01 19:45           ` Mark Mitchell
2005-04-01 20:02             ` Caroline Tice
2005-04-01 21:34             ` Caroline Tice
2005-04-01 21:44               ` David Edelsohn
2005-04-01 21:55                 ` Daniel Jacobowitz
2005-04-01 22:02                 ` Caroline Tice
2005-04-01 21:46               ` Mark Mitchell
2005-04-01 22:06                 ` Caroline Tice
2005-04-01 19:50           ` Daniel Jacobowitz
2005-04-01 20:00             ` Caroline Tice
2005-04-01 20:07               ` Daniel Jacobowitz
2005-04-01 20:09                 ` Caroline Tice
2005-04-01 21:19                   ` Mark Mitchell
2005-04-01 22:08                 ` Geoffrey Keating
2005-04-01 22:12                   ` Caroline Tice
2005-04-01 22:21                     ` Geoffrey Keating
2005-04-01 22:31                       ` Caroline Tice
2005-04-01 22:57                         ` Caroline Tice
2005-04-02  2:22                           ` Mark Mitchell
2005-04-02  2:51                             ` Daniel Jacobowitz
2005-04-01 22:14         ` Geoffrey Keating
2005-04-01 22:17           ` David Edelsohn
2005-04-01 22:24             ` Daniel Jacobowitz
2005-04-01 22:31               ` David Edelsohn
2005-04-01 18:48     ` Caroline Tice
2005-04-01 17:04   ` Joseph S. Myers
2005-04-01 17:21     ` Caroline Tice
2005-03-30  3:38 [RS6000] Fix PR20611, duplicate label for inlined function referencing TLS Alan Modra
2005-03-17  0:27 powerpc-linux unwinder fix for 3.4 Alan Modra
2005-03-14 12:58 [PATCH] PowerPC function arg alignment tidy Alan Modra
     [not found] <1109545242.14992.234.camel@gaston>
     [not found] ` <200502272335.j1RNZDD27844@makai.watson.ibm.com>
     [not found]   ` <653d1ad4308fa0e72f08252032f6c753@physics.uc.edu>
2005-02-28 10:52     ` Implicit altivec vs. linux kernel build Alan Modra
2005-02-15  2:20 [RFC] PowerPC 128 bit long double compatibility (PR target/19019) David Edelsohn
2005-02-15  2:22 ` Geoffrey Keating
2005-02-15  2:29   ` David Edelsohn
2005-02-15 11:20     ` Geoffrey Keating
2005-02-15  2:53 ` Richard Henderson
2005-02-15  3:19   ` David Edelsohn
2005-02-15 15:54     ` Alan Modra
2005-02-15 16:11       ` Richard Henderson
2005-02-15 16:31         ` Alan Modra
2005-02-15 17:17           ` Alan Modra
2005-02-16  0:20       ` Geoffrey Keating
2005-02-23 17:43       ` [3.4 PATCH] Fix powerpc*-*-linux* bootstrap " Jakub Jelinek
2005-02-23 19:28         ` David Edelsohn
2005-02-23 19:33           ` [PATCH] Fix powerpc*-*-linux* libgcc.a " Jakub Jelinek
2005-02-24 14:08           ` [3.4 PATCH] Fix powerpc*-*-linux* bootstrap " Alan Modra
2005-02-24 14:51             ` Jakub Jelinek
2005-02-24 14:59               ` Richard Henderson
2005-02-24 15:09               ` Alan Modra
2005-02-24 15:17                 ` Jakub Jelinek
2005-02-25  2:12                 ` [PATCH] Fix powerpc*-*-linux* libgcc.a (PR target/19019, take 2) Jakub Jelinek
2005-02-25  2:18                   ` Richard Henderson
2005-01-29  7:47 [PATCH] powerpc dwarf2 unwinder fallback Alan Modra
2005-01-12  5:02 [PATCH] PR target/19389 Odd gpr mem load unrecognizable insn Alan Modra
2004-12-24 13:47 [PATCH] Fix target/19147: invalid rlwinm patterns Alan Modra
2004-12-23 14:57 [PATCH] PR target/19137: ICE with load of TImode constant Alan Modra
2004-12-02 12:13 mklibgcc fallout Alan Modra
2004-12-02 17:12 ` Zack Weinberg
2004-12-02 18:21   ` Joseph S. Myers
2004-12-02 18:47     ` Zack Weinberg
2004-12-02 19:02       ` David Edelsohn
2004-12-02 21:05         ` Richard Henderson
2004-12-02 21:37         ` Alan Modra
2004-12-02 22:10           ` Zack Weinberg
2004-12-02 22:27             ` David Edelsohn
2004-12-02 23:08               ` Zack Weinberg
2004-12-02 23:26                 ` David Edelsohn
2004-12-04  2:41                   ` Zack Weinberg
2004-12-04  2:48                     ` David Edelsohn
2004-12-03  9:09             ` Alan Modra
2004-12-02 23:13           ` Andreas Schwab
2004-11-26 10:32 [RS6000] Fix PR12817 Alan Modra
2004-11-26  2:32 [PATCH] Fix PR16356 Alan Modra
2004-11-10  2:36 fix pr 16480 on gcc-3.4 Alan Modra
2004-11-08 23:07 [RFC] PowerPC sCC patterns David Edelsohn
2004-11-24 11:40 ` Alan Modra
2004-11-24 21:39   ` David Edelsohn
2004-09-02 18:53 Release RTL bodies after compilation (sometimes) Jan Hubicka
2004-09-02 18:56 ` Jakub Jelinek
2004-09-02 18:58   ` Jan Hubicka
2004-09-03  5:43     ` Mark Mitchell
2004-09-03 22:41       ` Jan Hubicka
2004-09-14 20:00       ` Diego Novillo
2004-09-14 20:15         ` Jan Hubicka
2004-09-14 20:35           ` Richard Henderson
2004-09-14 20:51             ` Jan Hubicka
2004-09-14 21:07               ` Jeffrey A Law
2004-09-14 21:12                 ` Jakub Jelinek
2004-09-14 22:33                   ` Daniel Jacobowitz
2004-09-14 22:53                   ` Richard Henderson
2004-09-16  8:35                   ` Jeffrey A Law
2004-09-14 21:26                 ` Jan Hubicka
2004-09-14 21:40                 ` Diego Novillo
2004-09-14 22:08                   ` Jeffrey A Law
2004-09-14 22:25                     ` Jan Hubicka
2004-09-14 23:55                     ` Michael Matz
2004-09-15  0:25                       ` Jan Hubicka
2004-09-15  4:38                     ` David Edelsohn
2004-09-15 12:25                       ` Jan Hubicka
2004-09-15 12:30                         ` Jan Hubicka
2004-09-15 13:05                           ` Diego Novillo
2004-09-15 13:13                             ` Daniel Jacobowitz
2004-09-15 13:32                               ` Jan Hubicka
2004-09-15 15:59                               ` Diego Novillo
2004-09-15 16:12                                 ` Daniel Jacobowitz
2004-09-15 17:07                                   ` David Edelsohn
2004-09-15 18:48                                     ` Daniel Jacobowitz
2004-09-15 20:35                                     ` Michael Matz
2004-09-16  7:38                                       ` Jeffrey A Law
2004-09-18  7:47                                         ` Geoffrey Keating
2004-09-18 13:58                                           ` Daniel Berlin
2004-09-18 14:52                                             ` Daniel Berlin
2004-09-18 15:33                                               ` Daniel Jacobowitz
2004-09-18 18:47                                                 ` Daniel Berlin
2004-09-18 19:47                                                   ` Daniel Jacobowitz
2004-09-18 20:20                                                     ` Daniel Berlin
2004-09-18  7:36                                       ` Geoffrey Keating
     [not found]                               ` <drow@false.org>
2004-09-15 15:46                                 ` David Edelsohn
2004-09-15 20:17                                   ` Geoffrey Keating
2004-09-16  4:22                                     ` Jeffrey A Law
2005-04-01 21:58                                 ` AIX bootstrap failure (was Re: Hot/cold partitioning fixes) David Edelsohn
2005-06-27 17:18                                 ` [PATCH, committed] PPC405 atomic support (PR target/21760) David Edelsohn
2005-06-28  7:54                                   ` Gunther Nikl
2005-11-09 19:39                                 ` [PATCH] volatile global register variable David Edelsohn
2005-11-10 21:18                                   ` Mark Mitchell
2005-11-11  3:10                                     ` David Edelsohn
2005-11-11  5:50                                       ` Mark Mitchell
2005-11-11  3:37                                     ` David Edelsohn
2006-08-09 14:59                                 ` [PATCH] Fix comments in PPC e500 code David Edelsohn
2006-08-09 16:21                                   ` Eric Botcazou
2006-08-09 16:22                                     ` David Edelsohn
2006-08-09 16:53                                       ` Eric Botcazou
2007-07-31 12:37                                 ` [patch] set -mabi=altivec with -ftree-vectorize David Edelsohn
2007-07-31 14:14                                   ` Daniel Jacobowitz
2007-08-07 15:36                                     ` Daniel Jacobowitz
2007-08-07 15:58                                       ` Andrew Pinski
2007-08-07 17:00                                         ` Daniel Jacobowitz
2007-08-08  2:21                                       ` Daniel Jacobowitz
2007-08-15 22:22                                 ` Mark PowerPC vector ABI in binary attributes David Edelsohn
2007-08-15 22:29                                   ` Daniel Jacobowitz
2007-09-04 13:05                                 ` Fix a reload ICE on e500 David Edelsohn
2007-09-04 13:46                                   ` Daniel Jacobowitz
2004-09-15 13:13                             ` Release RTL bodies after compilation (sometimes) Daniel Berlin
2004-09-15 16:53                             ` Jeffrey A Law
2004-09-15 17:20                               ` Jan Hubicka
2004-09-16  9:03                                 ` Jeffrey A Law
2004-09-16 13:13                                   ` Jan Hubicka
2004-09-15 19:50                       ` Mike Stump
2004-09-15 19:58                         ` David Edelsohn
2004-09-15 20:10                           ` Michael Matz
2004-09-15 20:51                             ` David Edelsohn
2004-09-15 21:02                               ` Daniel Jacobowitz
2004-09-16  4:58                                 ` Jeffrey A Law
2004-09-16  3:43                           ` Jeffrey A Law
2004-09-16  4:29                         ` Jeffrey A Law
2004-09-14 21:07           ` Jeffrey A Law
2004-09-14 21:19             ` Jan Hubicka
2004-09-15 11:59             ` Jan Hubicka
2004-09-15 13:07               ` Diego Novillo
2004-09-14 20:18         ` Jan Hubicka
2004-09-03  6:58 ` Richard Henderson
2004-09-03  8:03   ` Jan Hubicka
2004-09-03 19:08 ` Geoffrey Keating
2004-09-03 19:50   ` Jan Hubicka
2004-08-25 14:28 RS6000 fix pr16480 Alan Modra
2004-08-25 15:45 ` David Edelsohn
2004-08-25 23:09   ` Alan Modra
2004-08-11 11:13 powerpc64 fixes missing from 3.4 branch Alan Modra
2004-08-10 11:55 powerpc64 linux dot symbols Alan Modra
2004-08-10 12:37 ` Joseph S. Myers
2004-08-10 13:34   ` Alan Modra
2004-08-13 13:04 ` Jakub Jelinek
2004-08-13 13:58   ` Alan Modra
2004-08-16 11:49 ` Jakub Jelinek
2004-08-17  0:43   ` Alan Modra
2004-08-20  5:54     ` Alan Modra
2004-08-21 11:58       ` Jakub Jelinek
2004-08-21 15:39         ` Alan Modra
2004-07-14 21:21 [PATCH, committed] SFmode arg padding and va_arg cleanup David Edelsohn
2004-07-26 20:30 ` Alan Modra
2004-05-26 17:31 rs6000 mainline patch for pr 14478 Alan Modra
2004-05-08 15:54 Fixes for powerpc-linux param passing Alan Modra
2004-05-08 15:54 ` Aldy Hernandez
2004-05-08 22:43   ` Geoff Keating
2004-05-09 15:16   ` Alan Modra
2004-05-09 14:21     ` Aldy Hernandez
2004-05-09 14:22     ` Geoff Keating
2004-05-11  6:55     ` Alan Modra
2004-05-10 14:01       ` Aldy Hernandez
2004-05-08 16:41 ` Andrew Pinski
2004-05-08 22:20   ` Aldy Hernandez
2004-05-15 15:00 ` Alan Modra
2004-04-30 14:46 rs6000 stack boundary Alan Modra
2004-04-30 22:26 ` Geoff Keating
2004-04-30 23:06   ` David Edelsohn
     [not found]     ` <200404302355.i3UNtw61022391@desire.geoffk.org>
2004-05-01  0:40       ` David Edelsohn
2004-05-01  2:08       ` Alan Modra
2004-03-30 14:55 [lno] PATCH rs6000.md fix Mostafa Hagog
2004-03-30 15:36 ` David Edelsohn
2004-03-31  4:35   ` Alan Modra
2004-04-01 12:43 ` Dorit Naishlos
2004-04-06 14:21   ` Dorit Naishlos
2004-04-09 20:06   ` Dorit Naishlos
2004-03-13 11:43 [csl-arm, HEAD] ARM PATCH - fix QImode addressing on ARMv4 Richard Earnshaw
2004-03-13 13:01 ` Richard Earnshaw
2004-03-13 21:44   ` Daniel Jacobowitz
2004-03-14  0:43     ` Richard Earnshaw
2004-03-19  8:14       ` Richard Earnshaw
2004-03-19  8:14     ` Daniel Jacobowitz
2004-03-19  8:14   ` Richard Earnshaw
2004-03-19  8:14 ` Richard Earnshaw
     [not found] <40491948.2010900@us.ibm.com>
2004-03-06  9:52 ` Powerpc64 long double support Alan Modra
2004-03-19  8:14   ` Alan Modra
2004-03-06 10:50 ` Alan Modra
2004-03-06 23:13   ` Geoff Keating
2004-03-07  6:37     ` Alan Modra
2004-03-07  7:30       ` Richard Henderson
2004-03-09  5:05         ` Alan Modra
2004-03-09  7:59           ` Richard Henderson
2004-03-09 23:49             ` Alan Modra
2004-03-10  9:42               ` Richard Sandiford
2004-03-10 11:01                 ` Alan Modra
2004-03-10 11:11                   ` Richard Sandiford
2004-03-10 18:48                     ` David Edelsohn
2004-03-10 20:11                       ` Richard Sandiford
2004-03-19  8:14                         ` Richard Sandiford
2004-03-19  8:14                       ` David Edelsohn
2004-03-19  8:14                     ` Richard Sandiford
2004-03-10 11:13                   ` Alan Modra
2004-03-10 11:25                     ` Richard Sandiford
2004-03-10 11:58                       ` Alan Modra
2004-03-10 12:06                         ` Richard Sandiford
2004-03-10 12:25                           ` Alan Modra
2004-03-19  8:14                             ` Alan Modra
2004-03-10 12:42                           ` Andreas Schwab
2004-03-10 12:53                             ` Richard Sandiford
2004-03-19  8:14                               ` Richard Sandiford
2004-03-10 13:48                             ` Alan Modra
2004-03-19  8:14                               ` Alan Modra
2004-03-19  8:14                             ` Andreas Schwab
2004-03-19  8:14                           ` Richard Sandiford
2004-03-19  8:14                         ` Alan Modra
2004-03-19  8:14                       ` Richard Sandiford
2004-03-19  8:14                     ` Alan Modra
2004-03-19  8:14                   ` Alan Modra
2004-03-10 16:18                 ` David Edelsohn
2004-03-11 15:05                   ` Correct powerpc64 long double -0.0 to double conversion Alan Modra
2004-03-19  8:14                     ` Alan Modra
2004-03-19  8:14                   ` Powerpc64 long double support David Edelsohn
2004-03-19  8:14                 ` Richard Sandiford
2004-03-19  8:14               ` Alan Modra
2004-04-01  0:56               ` Geoff Keating
2004-04-06 14:21                 ` Geoff Keating
2004-04-09 20:06                 ` Geoff Keating
2004-03-19  8:14             ` Richard Henderson
2004-03-19  8:14           ` Alan Modra
2004-03-19  8:14         ` Richard Henderson
2004-03-19  8:14       ` Alan Modra
2004-03-19  8:14     ` Geoff Keating
2004-03-19  8:14   ` Alan Modra
2004-03-03 15:14 Fix PR 14406 (rs6000 abstf2) Alan Modra
2004-03-19  8:14 ` Alan Modra
2004-02-10 11:42 Fix libjava failure on powerpc64-linux Alan Modra
2004-02-10 12:34 ` Andrew Haley
2004-02-10 13:31   ` Alan Modra
2004-02-10 14:12     ` Andrew Haley
2004-02-21 13:45       ` Andrew Haley
2004-02-21 13:45     ` Alan Modra
2004-02-21 13:45   ` Andrew Haley
2004-02-21 13:45 ` Alan Modra
     [not found] <20040108000828.GQ2533@bubble.modra.org>
     [not found] ` <jmllojuvbk.fsf@desire.geoffk.org>
     [not found]   ` <20040108005715.GS2533@bubble.modra.org>
     [not found]     ` <200401080107.i0817HT26846@makai.watson.ibm.com>
2004-01-08  2:01       ` mainline -mcpu=power4 Alan Modra
     [not found] <OFEA5CA921.302AEEB5-ON41256E00.005FB141@de.ibm.com>
     [not found] ` <200312182258.hBIMwgT25422@makai.watson.ibm.com>
     [not found]   ` <200312201527.hBKFRHgI000712@elgar.kettenis.dyndns.org>
     [not found]     ` <3FF5A069.1040306@gnu.org>
     [not found]       ` <200401022317.i02NHQBR001191@desire.geoffk.org>
2004-01-06 15:27         ` Incorrect DWARF-2 register numbers on PPC64? Alan Modra
2004-01-06 18:07           ` Geoff Keating
2004-01-06 18:10             ` David Edelsohn
2004-01-06 22:05               ` Geoff Keating
2004-01-06 22:08                 ` David Edelsohn
2004-01-06 22:34                   ` Geoff Keating
2004-01-07  0:26                     ` Alan Modra
2004-01-07 17:43           ` Mark Kettenis
2004-01-07 22:29             ` Alan Modra
2004-01-07 23:36               ` Andrew Cagney
2004-01-08  0:48                 ` Alan Modra
2004-01-08  5:01                   ` Geoff Keating
2004-01-09  2:34                     ` Alan Modra
2004-01-09  2:49                       ` Alan Modra
2004-01-09  6:39                       ` Alan Modra
2004-01-17  6:54                         ` Alan Modra
2004-01-17  8:05                           ` Geoff Keating
2004-01-18  6:03                             ` Alan Modra
2004-01-09 15:15                       ` Mark Kettenis
     [not found]           ` <amodra@bigpond.net.au>
2002-05-23  7:02             ` rs6000.c:output_toc Alan Modra
2002-05-23  9:21               ` rs6000.c:output_toc David Edelsohn
     [not found]             ` <200209140219.WAA25730@makai.watson.ibm.com>
2002-09-13 19:59               ` SYMBOL_REF_FLAG Alan Modra
2002-09-13 22:17                 ` SYMBOL_REF_FLAG Richard Henderson
2002-09-14  0:09                   ` SYMBOL_REF_FLAG David Edelsohn
2002-09-14  0:01                 ` SYMBOL_REF_FLAG David Edelsohn
2002-10-03 19:25             ` powerpc fix for gcc.dg/asm-names.c failure Alan Modra
2002-10-03 19:32               ` David Edelsohn
2003-06-07  5:59             ` powerpc64 crt* tweak Alan Modra
2003-06-07  6:00               ` David Edelsohn
2003-08-01 14:57             ` powerpc64-linux libffi update Alan Modra
2003-08-01 15:08               ` David Edelsohn
2004-01-06 16:02             ` Incorrect DWARF-2 register numbers on PPC64? David Edelsohn
2004-01-08  2:09             ` mainline -mcpu=power4 David Edelsohn
2004-01-08 15:14               ` Alan Modra
2004-02-10 15:07             ` Fix libjava failure on powerpc64-linux David Edelsohn
2004-02-10 15:09               ` Andrew Haley
2004-02-10 15:39                 ` David Edelsohn
2004-02-10 15:59                   ` Andrew Haley
2004-02-10 16:14                     ` David Edelsohn
2004-02-21 13:45                       ` David Edelsohn
2004-02-21 13:45                     ` Andrew Haley
2004-02-21 13:45                   ` David Edelsohn
2004-02-21 13:45                 ` Andrew Haley
2004-02-21 13:45               ` David Edelsohn
2004-03-03 21:03             ` Fix PR 14406 (rs6000 abstf2) David Edelsohn
2004-03-03 21:34               ` Alan Modra
2004-03-04  2:44                 ` Alan Modra
2004-03-19  8:14                   ` Alan Modra
2004-03-19  8:14                 ` Alan Modra
2004-03-19  8:14               ` David Edelsohn
2004-03-04  2:47             ` David Edelsohn
2004-03-19  8:14               ` David Edelsohn
2004-03-10  6:23             ` Powerpc64 long double support David Edelsohn
2004-03-10  6:44               ` Alan Modra
2004-03-19  8:14                 ` Alan Modra
2004-03-19  8:14               ` David Edelsohn
2004-03-12 20:26             ` Correct powerpc64 long double -0.0 to double conversion David Edelsohn
2004-03-19  8:14               ` David Edelsohn
2004-04-30 14:55             ` rs6000 stack boundary David Edelsohn
2004-05-09 14:19             ` Fixes for powerpc-linux param passing David Edelsohn
2004-05-09 14:22               ` Aldy Hernandez
2004-05-18  4:23             ` [lno] PATCH rs6000.md fix David Edelsohn
2004-05-26 18:52             ` rs6000 mainline patch for pr 14478 David Edelsohn
2004-05-26 20:17               ` Alan Modra
2004-05-26 21:18             ` David Edelsohn
2004-07-26 22:22             ` [PATCH, committed] SFmode arg padding and va_arg cleanup David Edelsohn
2004-07-28 11:26               ` Alan Modra
2004-07-28 12:11                 ` Alan Modra
2004-08-06  7:58                   ` Alan Modra
2004-07-28 12:17             ` David Edelsohn
2004-08-06 14:53             ` David Edelsohn
2004-08-11 14:47             ` powerpc64 fixes missing from 3.4 branch David Edelsohn
2004-08-20 22:35             ` powerpc64 linux dot symbols David Edelsohn
2004-08-25 23:56             ` RS6000 fix pr16480 David Edelsohn
2004-08-26  1:21               ` Alan Modra
2004-08-26  1:30             ` David Edelsohn
2004-11-10  4:48             ` fix pr 16480 on gcc-3.4 David Edelsohn
2004-11-24 18:27             ` [RFC] PowerPC sCC patterns David Edelsohn
2004-11-26  4:45             ` [PATCH] Fix PR16356 David Edelsohn
2004-11-27  0:00             ` [RS6000] Fix PR12817 David Edelsohn
2004-11-27  0:18               ` Alan Modra
2004-11-27  4:55                 ` Geoffrey Keating
2004-11-27  8:41                   ` Alan Modra
2004-11-27  7:34                 ` Alan Modra
2004-11-27 19:56                 ` Dale Johannesen
2004-11-27  4:15               ` Geoffrey Keating
2004-11-27 22:30               ` Mike Stump
2004-11-27 22:03             ` David Edelsohn
2004-11-27 22:23               ` Mike Stump
2004-11-27 22:48               ` Dale Johannesen
2004-11-27 22:52                 ` Alan Modra
2004-11-28  0:20                   ` Dale Johannesen
2004-11-29  2:38               ` Geoffrey Keating
2004-12-03 16:02             ` mklibgcc fallout David Edelsohn
2004-12-03 21:55               ` Mark Mitchell
2004-12-03 22:18                 ` David Edelsohn
2004-12-03 22:42                   ` Mark Mitchell
2004-12-04  3:06                     ` Alan Modra
2004-12-04  3:40                       ` Zack Weinberg
2004-12-08 12:09                       ` Richard Sandiford
2004-12-08 13:54                         ` Alan Modra
2004-12-08 14:08                           ` Richard Sandiford
2004-12-23 17:46             ` [PATCH] PR target/19137: ICE with load of TImode constant David Edelsohn
     [not found]               ` <20041224002336.GB2765@bubble.modra.org>
2004-12-24 19:30                 ` David Edelsohn
2004-12-24 15:55             ` [PATCH] Fix target/19147: invalid rlwinm patterns David Edelsohn
2005-01-12  5:23             ` [PATCH] PR target/19389 Odd gpr mem load unrecognizable insn David Edelsohn
2005-01-29 17:21             ` [PATCH] powerpc dwarf2 unwinder fallback David Edelsohn
2005-02-15 19:41             ` [RFC] PowerPC 128 bit long double compatibility (PR target/19019) David Edelsohn
2005-02-16  1:52               ` Geoffrey Keating
2005-03-02 16:17             ` Implicit altivec vs. linux kernel build David Edelsohn
2005-03-17  0:48             ` powerpc-linux unwinder fix for 3.4 David Edelsohn
2005-03-20 23:01             ` [PATCH] PowerPC function arg alignment tidy David Edelsohn
2005-03-31  0:16             ` [RS6000] Fix PR20611, duplicate label for inlined function referencing TLS David Edelsohn
2005-05-31 14:32             ` powerpc new PLT and GOT David Edelsohn
2005-06-10  1:13             ` [PATCH] PowerPC SVR4 _mcount calls David Edelsohn
2005-09-12  3:15             ` [RS6000] Nop-insertion fix David Edelsohn
2005-09-12  3:59             ` [PowerPC] Fix PR23774 stack backchain broken David Edelsohn
2005-09-13  0:44             ` David Edelsohn
2005-09-13  4:19               ` Alan Modra
2005-10-21  2:01             ` [PowerPC] -msdata=data needless use of .sbss section David Edelsohn
2005-11-02 23:37             ` [PowerPC64] gcc.c-torture/compile/pr20928.c failure David Edelsohn
2005-11-08  2:59             ` [PowerPC] Fix PR23704, -m64 overrides prior -mno-powerpc-gfxopt David Edelsohn
2005-11-25  5:15             ` [RS6000] Add some more functions to ppc64-fp.c David Edelsohn
2005-11-27 23:25             ` [PowerPC] -msdata=data needless use of .sbss section David Edelsohn
2005-11-28  2:51             ` [PowerPC] PR24997: ICE with -ftree-vectorize David Edelsohn
2005-12-07 13:35             ` [PowerPC] Fix pr25212, indexed address predicates David Edelsohn
2005-12-10 18:14             ` [PowerPC] Default TARGET_ALIGN_NATURAL properly for target libs David Edelsohn
2005-12-15  7:04             ` [PowerPC] Fix 25406, rs6000_special_round_type_align David Edelsohn
2005-12-28 15:07             ` [PowerPC] Fix PR25572, -mminimal-toc trashes r30 David Edelsohn
2006-02-24  3:03             ` [PowerPC64] Fix 26453, segfault -m64 -mtraceback=full David Edelsohn
2006-03-30 21:46             ` [PowerPC] linuxspe vs. ibm long double David Edelsohn
2006-03-30 23:42               ` Alan Modra
2006-03-30 21:50             ` [PowerPC] PR26459 again David Edelsohn
2006-03-30 23:12               ` Alan Modra
2006-03-30 23:50             ` [PowerPC] linuxspe vs. ibm long double David Edelsohn
2006-03-31  0:33             ` [PowerPC] PR26459 again David Edelsohn
2006-04-05  2:26             ` [RFT/RFA] Fix AIX fallout from PR/19653 patch David Edelsohn
2006-04-12  0:53             ` [PowerPC] Avoid ICE on DFmode subreg David Edelsohn
2006-07-07 13:08             ` [PATCH, committed] PR 28150 and PR 28170 David Edelsohn
2003-10-24 13:52 [PATCH] - Use of powerpc 64bit instructions in 32bit ABI Ulrich Weigand
2003-10-24 17:32 ` David Edelsohn
2003-10-24 18:07   ` Richard Henderson
2003-10-24 18:34     ` Fariborz Jahanian
2003-10-24 18:34     ` David Edelsohn
2003-10-24 18:57       ` Richard Henderson
2003-11-03 20:55         ` David Edelsohn
2003-12-01 14:27           ` Eric Botcazou
2003-12-01 15:46             ` David Edelsohn
2003-12-01 16:15               ` Eric Botcazou
2003-12-01 18:44                 ` David Edelsohn
2003-12-01 19:29                   ` Fariborz Jahanian
2003-12-01 19:33                     ` David Edelsohn
2003-12-02  9:20                       ` Eric Botcazou
2003-12-02 16:17                         ` David Edelsohn
2003-12-02 17:28                           ` Eric Botcazou
2003-12-02 17:39                             ` Fariborz Jahanian
2003-12-02 18:50                               ` Eric Botcazou
2003-12-02 17:41                             ` David Edelsohn
2003-12-02 18:50                               ` Eric Botcazou
2003-12-02 18:02                             ` David Edelsohn
2003-12-02 23:34                               ` Eric Botcazou
2003-12-02 23:42                                 ` fj
2003-12-05 16:41                                   ` Eric Botcazou
2003-12-02  8:00                   ` Eric Botcazou
2003-10-24 19:08       ` Geoff Keating
2003-10-24 19:10         ` David Edelsohn
2003-10-24 19:22       ` Dale Johannesen
2003-10-24 19:28         ` Dale Johannesen
2003-10-24 21:25         ` Richard Henderson
2003-10-25  3:10         ` David S. Miller
     [not found] <20030911193937.GD16280@redhat.com>
2003-09-11 20:08 ` C++ testsuite failures on AIX David Edelsohn
2003-09-11 20:09   ` Richard Henderson
2003-09-11 20:17     ` David Edelsohn
2003-09-11 20:20       ` Richard Henderson
2003-09-11 20:49         ` Mark Mitchell
2003-09-11 21:33           ` Jan Hubicka
2003-09-11 20:29     ` Jan Hubicka
2003-09-11 20:31       ` David Edelsohn
2003-09-11 20:32         ` Jan Hubicka
2003-09-11 20:48           ` David Edelsohn
2003-09-11 20:50           ` David Edelsohn
     [not found] <20030612184851.E41510@forte.austin.ibm.com>
     [not found] ` <20030613020133.GK23826@bubble.sa.bigpond.net.au>
2003-06-13 15:07   ` ppc64 floating point usage [was Re: PPC64 Compiler bug !!] Alan Modra
2003-06-13 15:38     ` David Edelsohn
2003-06-13 20:04     ` David Edelsohn
2003-06-13 20:06       ` Jakub Jelinek
2003-06-13 20:38         ` David Edelsohn
2003-06-13 21:06           ` linas
2003-06-13 21:17             ` Michael S. Zick
2003-06-14  3:14               ` Michael Meissner
2003-06-14  3:14                 ` gp
2003-06-14  9:07                 ` Alan Modra
2003-06-14 14:59                 ` Michael S. Zick
2003-06-14 22:52                   ` Michael Meissner
2003-06-13 22:19             ` Janis Johnson
2003-06-13 21:08       ` linas
2003-08-08  7:24       ` Alan Modra
2003-08-08 14:01         ` David Edelsohn
2003-08-09  1:55           ` ppc64 floating point usage Zack Weinberg
2003-08-09  2:42             ` David Edelsohn
2003-08-09  2:56               ` Alan Modra
2003-08-09  3:15                 ` David Edelsohn
2003-08-09  3:40                   ` Alan Modra
2003-08-09  2:23           ` ppc64 floating point usage [was Re: PPC64 Compiler bug !!] Eric Christopher
2003-08-09  2:50             ` David Edelsohn
2003-08-09  3:06               ` Eric Christopher
2003-08-09  3:27                 ` David Edelsohn
2003-08-09 23:14                   ` Eric Christopher
2003-08-09 23:27                     ` David Edelsohn
2003-08-10  0:15                       ` Eric Christopher
2003-08-10  5:17                   ` Geoff Keating
2003-08-10  6:43                     ` Alan Modra
2003-08-10  7:00                       ` Geoff Keating
2003-05-27 11:58 [PATCH] powerpc64-linux bi-arch support Jakub Jelinek
2003-05-27 14:57 ` David Edelsohn
2003-05-27 15:06   ` Jakub Jelinek
2003-05-27 15:25     ` David Edelsohn
2003-05-27 15:52       ` Jakub Jelinek
2003-05-27 22:44         ` David Edelsohn
2003-05-29 22:50           ` Alan Modra
2003-05-30  0:52             ` David Edelsohn
2003-05-31 20:52               ` Jakub Jelinek
2003-06-02 20:24                 ` David Edelsohn
2003-06-02 22:08                 ` David Edelsohn
2003-06-02 22:37                   ` Michael Meissner
2003-06-04 14:48 ` David Edelsohn
2003-06-04 16:51 ` David Edelsohn
2003-06-04 16:58   ` Jakub Jelinek
2003-08-19 20:07 ` David Edelsohn
2003-08-20  0:42   ` Alan Modra
2003-05-14 16:25 powerpc-unknown-linux-gnu bootstrap fix Matt Kraai
2003-05-14 17:12 ` David Edelsohn
2003-05-14 17:23   ` Richard Henderson
2003-05-14 17:26     ` David Edelsohn
2003-05-14 17:52       ` Richard Henderson
2003-05-14 18:58         ` David Edelsohn
2003-05-15 23:22       ` Geoff Keating
2003-05-18 23:17         ` Matt Kraai
2003-05-19  0:16           ` Geoff Keating
2003-04-24 15:34 function parms in regs, patch 3 of 3 Alan Modra
2003-04-24 15:34 function parms in regs, patch 1 " Alan Modra
2003-04-25 22:44 ` Richard Henderson
2003-04-26  0:33   ` Janis Johnson
2003-04-27 23:34   ` Alan Modra
2003-04-30 13:29     ` function parms in regs, patch 3 " Alan Modra
2003-05-02  6:05       ` Jim Wilson
2003-05-02 12:38         ` Alan Modra
2003-05-02 20:23           ` Jim Wilson
2003-05-03  1:22             ` Alan Modra
2003-07-10  6:55       ` Jim Wilson
2003-07-14  2:51         ` Alan Modra
2003-07-14  3:00           ` David Edelsohn
2003-07-15 15:08           ` David Edelsohn
2003-07-16  3:49             ` Alan Modra
2003-07-16 15:08               ` David Edelsohn
2003-07-16 15:10               ` David Edelsohn
2003-05-02  5:06 ` function parms in regs, patch 1 " Jim Wilson
2003-05-02  5:20   ` Richard Henderson
2002-08-21 11:09 [RFC] PowerPC select_section / unique_section David Edelsohn
2002-08-21 11:21 ` Franz Sirl
2002-08-21 11:29   ` David Edelsohn
2002-08-21 12:01     ` Franz Sirl
2002-08-21 12:15       ` David Edelsohn
2002-08-29 18:01         ` Richard Henderson
2002-08-21 19:02     ` Alan Modra
2002-08-21 19:19       ` David Edelsohn
2002-08-21 19:25         ` Alan Modra
2002-08-21 21:28           ` David Edelsohn
2002-08-29 18:19             ` Richard Henderson
2002-08-29 18:03       ` Richard Henderson
2002-08-30  7:15         ` Alan Modra
2002-08-30  8:27           ` Alan Modra
2002-08-30  8:42           ` David Edelsohn
2002-08-30 11:17             ` Franz Sirl
2002-08-30 11:26               ` Franz Sirl
2002-08-30 11:29               ` David Edelsohn
2002-08-30 17:32             ` Alan Modra
2002-08-30 18:17               ` Richard Henderson
2002-08-30 18:48                 ` Geoff Keating
2002-08-30 19:40                   ` -finline-functions vs -fpic Richard Henderson
2002-08-30 20:57                     ` Richard Henderson
2002-09-02 15:41                 ` [RFC] PowerPC select_section / unique_section David Edelsohn
2002-09-02 16:32                   ` Alan Modra
2002-09-02 16:51                     ` David Edelsohn
2002-09-02 17:13                       ` Alan Modra
2002-09-02 17:57                         ` David Edelsohn
2002-09-02 18:27                           ` Alan Modra
2002-09-02 18:49                             ` David Edelsohn
2002-09-02 19:41                               ` Alan Modra
2002-09-02 19:59                                 ` David Edelsohn
2002-09-02 20:17                               ` Richard Henderson
2002-09-02 20:11                             ` Jeff Sturm
2002-09-02 20:19                               ` David Edelsohn
2002-09-03  0:16                                 ` Richard Henderson
2002-09-03  8:22                                   ` David Edelsohn
2002-09-03  9:04                                     ` Richard Henderson
2002-09-03 10:40                                       ` David Edelsohn
2002-09-03 13:44                                         ` Richard Henderson
2002-09-03  9:29                             ` Mark Mitchell
2002-09-03  8:41                           ` Geoff Keating
2002-09-03  9:50                             ` David Edelsohn
2002-08-21 18:54 ` Alan Modra
2002-08-21 18:59   ` David Edelsohn
2002-08-01 18:39 power4 branch hints Alan Modra
2002-08-01 18:47 ` David Edelsohn
2002-08-01 19:50   ` Alan Modra
2002-08-01 20:25     ` David Edelsohn
2002-08-02 13:25   ` Geoff Keating
     [not found] <20020625081846.10430.qmail@sources.redhat.com>
2002-07-15  2:43 ` other/7114: ICE building strcoll.op from glibc-2.2.5 Alan Modra
2002-07-15  5:22   ` Alan Modra
2002-07-15 12:51   ` Geoff Keating
2002-07-15 16:54     ` Alan Modra
2002-07-15 18:38       ` Alan Modra
2002-07-15 22:08         ` Richard Henderson
2002-07-16  0:03           ` Alan Modra
2002-07-16 11:23         ` Geoff Keating
2002-07-16 18:51           ` Alan Modra
2002-07-16 22:07             ` Alan Modra
2002-07-17  0:58             ` Geoff Keating
2002-07-17  2:04               ` Alan Modra
2002-07-17 10:42                 ` David Edelsohn
2002-07-17 12:10                 ` Geoff Keating
2002-07-17  8:45               ` David Edelsohn
2002-07-17 12:26                 ` Geoff Keating
2002-07-17 14:05                   ` David Edelsohn
2002-07-17 19:20                   ` Alan Modra
2002-07-17 19:45                     ` David Edelsohn
2002-07-17 20:50                     ` David Edelsohn
2002-07-17 20:52                       ` Alan Modra
2002-07-16 10:46       ` Geoff Keating
     [not found] <20020712071414.GR30362@bubble.sa.bigpond.net.au>
2002-07-13  4:58 ` target/7282: powerpc64 SImode in FPR Alan Modra
2002-07-13  7:25   ` David Edelsohn
2002-07-13 23:36     ` Alan Modra
2002-07-14  7:59       ` David Edelsohn
2002-07-02 21:18 convert 32-bit PowerPC GNU/Linux to TARGET_OS_CPP_BUILTINS Matt Kraai
2002-07-03  8:10 ` David Edelsohn
2002-07-03  9:15   ` Matt Kraai
2002-07-03  9:25     ` Stan Shebs
2002-07-03  9:32     ` David Edelsohn
2002-07-03  9:36     ` Jason R Thorpe
2002-07-03 10:29       ` Matt Kraai
2002-07-03 23:50     ` Alan Modra
2002-07-04  9:22       ` David Edelsohn
2002-07-08 18:27         ` Matt Kraai
2002-07-08 19:05           ` Geoff Keating
2002-07-08 19:16           ` David Edelsohn
2002-07-09  0:37             ` Matt Kraai
2002-06-09  8:10 PowerPC cleanup and Power4 David Edelsohn
2002-06-09  8:24 ` Neil Booth
2002-06-09  8:31   ` David Edelsohn
2002-06-09 10:05 ` Geoff Keating
2002-06-09 10:33   ` David Edelsohn
2002-06-09 12:08     ` Geoff Keating
2002-06-09 12:15       ` David Edelsohn
2002-05-21 18:54 thread-local storage: c front end and generic backend patch Richard Henderson
2002-05-22  4:25 ` Joseph S. Myers
2002-05-22 13:53 ` Mark Mitchell
2002-05-22 14:22   ` Richard Henderson
2002-05-22 14:44     ` Gabriel Dos Reis
2002-05-22 14:55       ` Joseph S. Myers
2002-05-22 14:52     ` Mark Mitchell
2002-05-22 15:01       ` Richard Henderson
2002-05-22 15:13         ` Jakub Jelinek
2002-05-22 15:36           ` Richard Henderson
2002-05-22 15:42             ` Mark Mitchell
2002-05-22 15:56               ` Richard Henderson
2002-05-29 23:48           ` Fergus Henderson
2002-05-22 15:39         ` Mark Mitchell
2002-05-22 16:30           ` Richard Henderson
2002-05-22 16:46     ` Alexandre Oliva
2002-05-22 16:53       ` Richard Henderson
2002-07-11  9:00 ` David Edelsohn
2002-07-11 11:02   ` Richard Henderson
2002-07-26 11:08     ` [PATCH] " David Edelsohn
2002-07-27 15:40       ` Richard Henderson
2002-07-27 16:18         ` David Edelsohn
2002-07-29 11:02           ` Richard Henderson
2002-07-29 11:36             ` David Edelsohn
2002-07-29 15:30               ` Richard Henderson
2002-07-29 22:10                 ` David Edelsohn
2002-07-30  9:41                   ` Richard Henderson
2002-03-08 14:25 biggest alignment for sysv4.h altivec Aldy Hernandez
2002-03-08 14:49 ` Geoff Keating
2002-03-08 14:52   ` Aldy Hernandez
2002-03-08 15:16     ` Geoff Keating
2002-03-08 15:26       ` Aldy Hernandez
2002-03-08 15:48         ` Geoff Keating
2002-03-08 15:53           ` Aldy Hernandez
2002-03-08 17:34             ` Richard Henderson
2002-03-08 18:52       ` Richard Henderson
2002-03-08 20:09       ` David Edelsohn
2002-03-09  2:11         ` Geoff Keating
2002-03-09 15:09           ` David Edelsohn
2002-03-09 16:17             ` Geoff Keating
2002-03-06  6:54 f build dies with: undefined reference to `lookup_name' Andrew Cagney
2002-03-06  8:29 ` David Edelsohn
2002-03-06  8:53   ` Andrew Cagney
2002-03-06 10:18     ` David Edelsohn
2002-03-06 10:59       ` Richard Henderson
2002-03-06 11:27         ` David Edelsohn
2002-03-06 12:41           ` Richard Henderson
2002-03-06 14:18             ` David Edelsohn
2002-03-06 14:22               ` Richard Henderson
2002-03-06 15:06                 ` David Edelsohn
2002-03-06 15:07                   ` Richard Henderson
2002-03-06 15:09                     ` David Edelsohn
2002-03-06 15:13                       ` Richard Henderson
2002-03-06 15:18                 ` Alan Modra
2002-03-06 19:01                   ` Alan Modra
2002-03-10 14:27                     ` Andrew Cagney
2002-03-10 14:34                       ` David Edelsohn
2002-03-10 16:00                         ` Richard Henderson
2002-03-06 15:40         ` David Edelsohn
2002-03-14 11:34         ` David Edelsohn
2002-03-14 12:02           ` Neil Booth
2002-03-14 13:47           ` Geoff Keating
2002-03-14 14:07             ` David Edelsohn
2002-03-14 15:02               ` Geoff Keating
2002-03-14 15:24             ` David Edelsohn
2002-03-14 16:57               ` Alan Modra
2002-03-14 18:05                 ` Geoff Keating
2002-03-14 18:35                   ` David Edelsohn
2002-03-14 20:07                     ` Geoff Keating
2002-03-14 21:10                       ` Richard Henderson
2002-03-14 23:03                         ` Richard Henderson
2002-03-15  8:20                           ` David Edelsohn
2002-03-15 17:01                             ` Richard Henderson
2002-03-19 16:40                               ` Alan Modra
2002-03-19 17:02                                 ` Richard Henderson
2002-03-14 16:00         ` David Edelsohn
2002-03-06 11:43       ` Stan Shebs
2002-02-03 19:14 [PATCH] PowerPC fsel PR5217 David Edelsohn
2002-02-03 21:14 ` Geoff Keating
2002-02-03 21:40   ` David Edelsohn
2002-02-03 22:08     ` Geoff Keating
2002-02-03 22:45       ` David Edelsohn
2002-02-03 23:14         ` Geoff Keating
2002-02-04  9:26           ` David Edelsohn
2002-02-04 10:24             ` Geoff Keating
2002-02-04 10:40               ` David Edelsohn
2002-02-04 11:18                 ` Dale Johannesen
2002-02-04 11:44                 ` Geoff Keating
2002-02-05 11:20                   ` David Edelsohn
2002-02-05 12:47                     ` David Edelsohn
2002-02-05 14:17                       ` Mark Mitchell
2002-01-28  1:05 ppc call_value* fixes (plus minor apple gripe) Aldy Hernandez
2002-01-28  7:26 ` Stan Shebs
2002-01-29 14:30   ` Aldy Hernandez
2002-01-28  7:43 ` Geoff Keating
2002-01-28  7:49 ` David Edelsohn
2002-01-28 11:12 ` Richard Henderson
2002-01-28 12:52   ` David Edelsohn
2002-01-28 22:44   ` Aldy Hernandez
2002-01-29 10:51     ` David Edelsohn
2001-12-29  7:03 PATCH, rs6000 (alpha?) long const Tom Rix
2001-12-29 11:40 ` Richard Henderson
2001-12-29 12:40   ` Tom Rix
2001-12-29 17:00     ` Richard Henderson
2001-12-29 18:37       ` Tom Rix
2001-12-29 20:45         ` Richard Henderson
2001-12-29 21:24           ` PATCH, rs6000 (alpha?) long const --verbose Tom Rix
2001-12-29 23:01             ` Richard Henderson
2001-12-29 23:02             ` Richard Henderson
2002-01-01 12:21               ` PATCH, rs6000 (alpha?) long const take 2 Tom Rix
2002-01-01 13:46                 ` Richard Henderson
2002-01-02 13:20                   ` Geoff Keating
2002-01-02 13:22                     ` Richard Henderson
2002-01-02 20:44                     ` David Edelsohn
2002-01-03  0:52                       ` Richard Henderson
2002-01-03  8:06                         ` David Edelsohn
2002-01-04 12:04                           ` Geoff Keating
2002-01-04 14:31                             ` David Edelsohn
2002-01-10 14:00                               ` PATCH, rs6000 long const take 3 Tom Rix
2002-01-10 14:08                                 ` Richard Henderson
2002-01-10 14:20                                 ` David Edelsohn
2001-11-13 15:03 [PATCH] adds powerpc-*-freebsd? to mainline David Edelsohn
2001-11-13 15:03 ` Geoff Keating
2001-11-13 15:03   ` David Edelsohn
2001-11-13 15:03     ` David O'Brien
2001-11-13 15:03     ` Geoff Keating
2001-11-13 15:03       ` David Edelsohn
2001-11-13 15:03         ` David O'Brien
2001-11-13 15:03         ` Richard Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).