View | Details | Raw Unified | Return to bug 50906 | Differences between
and this patch

Collapse All | Expand All

(-)gcc/config/rs6000/rs6000.c (-78 / +73 lines)
Lines 20643-20698 rs6000_emit_prologue (void) Link Here
20643
    {
20643
    {
20644
      int i;
20644
      int i;
20645
      rtx spe_save_area_ptr;
20645
      rtx spe_save_area_ptr;
20646
 
20646
      int save_ptr_to_sp;
20647
      int ool_adjust = 0;
20648
20647
      /* Determine whether we can address all of the registers that need
20649
      /* Determine whether we can address all of the registers that need
20648
	 to be saved with an offset from the stack pointer that fits in
20650
	 to be saved with an offset from frame_reg_rtx that fits in
20649
	 the small const field for SPE memory instructions.  */
20651
	 the small const field for SPE memory instructions.  */
20650
      int spe_regs_addressable_via_sp
20652
      int spe_regs_addressable
20651
	= (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20653
	= (SPE_CONST_OFFSET_OK (info->spe_gp_save_offset + sp_offset
20652
			       + (32 - info->first_gp_reg_save - 1) * reg_size)
20654
				+ reg_size * (32 - info->first_gp_reg_save - 1))
20653
	   && saving_GPRs_inline);
20655
	   && saving_GPRs_inline);
20654
      int spe_offset;
20656
      int spe_offset;
20655
 
20657
20656
      if (spe_regs_addressable_via_sp)
20658
      if (spe_regs_addressable)
20657
	{
20659
	{
20658
	  spe_save_area_ptr = frame_reg_rtx;
20660
	  spe_save_area_ptr = frame_reg_rtx;
20661
	  save_ptr_to_sp = info->total_size - sp_offset;
20659
	  spe_offset = info->spe_gp_save_offset + sp_offset;
20662
	  spe_offset = info->spe_gp_save_offset + sp_offset;
20660
	}
20663
	}
20661
      else
20664
      else
20662
	{
20665
	{
20663
	  /* Make r11 point to the start of the SPE save area.  We need
20666
	  /* Make r11 point to the start of the SPE save area.  We need
20664
	     to be careful here if r11 is holding the static chain.  If
20667
	     to be careful here if r11 is holding the static chain.  If
20665
	     it is, then temporarily save it in r0.  We would use r0 as
20668
	     it is, then temporarily save it in r0.  */
20666
	     our base register here, but using r0 as a base register in
20669
	  int offset;
20667
	     loads and stores means something different from what we
20670
20668
	     would like.  */
20671
	  if (!saving_GPRs_inline)
20669
	  int ool_adjust = (saving_GPRs_inline
20672
	    ool_adjust = 8 * (info->first_gp_reg_save
20670
			    ? 0
20673
			      - (FIRST_SAVRES_REGISTER + 1));
20671
			    : (info->first_gp_reg_save
20674
	  offset = info->spe_gp_save_offset + sp_offset - ool_adjust;
20672
			       - (FIRST_SAVRES_REGISTER+1))*8);
20675
	  spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20673
	  HOST_WIDE_INT offset = (info->spe_gp_save_offset
20676
	  save_ptr_to_sp = info->total_size - sp_offset + offset;
20674
				  + sp_offset - ool_adjust);
20677
	  spe_offset = 0;
20675
20678
20676
	  if (using_static_chain_p)
20679
	  if (using_static_chain_p)
20677
	    {
20680
	    {
20678
	      rtx r0 = gen_rtx_REG (Pmode, 0);
20681
	      rtx r0 = gen_rtx_REG (Pmode, 0);
20679
	      gcc_assert (info->first_gp_reg_save > 11);
20682
	      gcc_assert (info->first_gp_reg_save > 11);
20680
 
20683
20681
	      emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20684
	      emit_move_insn (r0, spe_save_area_ptr);
20682
	    }
20685
	    }
20683
 
20686
	  emit_insn (gen_addsi3 (spe_save_area_ptr,
20684
	  spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20687
				 frame_reg_rtx, GEN_INT (offset)));
20685
	  insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20688
	  if (REGNO (frame_reg_rtx) == 11)
20686
					frame_reg_rtx,
20689
	    sp_offset = -info->spe_gp_save_offset + ool_adjust;
20687
					GEN_INT (offset)));
20688
	  /* We need to make sure the move to r11 gets noted for
20689
	     properly outputting unwind information.  */
20690
	  if (!saving_GPRs_inline)
20691
	    rs6000_frame_related (insn, frame_reg_rtx, offset,
20692
				  NULL_RTX, NULL_RTX);
20693
	  spe_offset = 0;
20694
	}
20690
	}
20695
 
20691
20696
      if (saving_GPRs_inline)
20692
      if (saving_GPRs_inline)
20697
	{
20693
	{
20698
	  for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20694
	  for (i = 0; i < 32 - info->first_gp_reg_save; i++)
Lines 20704-20739 rs6000_emit_prologue (void) Link Here
20704
		/* We're doing all this to ensure that the offset fits into
20700
		/* We're doing all this to ensure that the offset fits into
20705
		   the immediate offset of 'evstdd'.  */
20701
		   the immediate offset of 'evstdd'.  */
20706
		gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20702
		gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20707
 
20703
20708
		offset = GEN_INT (reg_size * i + spe_offset);
20704
		offset = GEN_INT (reg_size * i + spe_offset);
20709
		addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20705
		addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20710
		mem = gen_rtx_MEM (V2SImode, addr);
20706
		mem = gen_rtx_MEM (V2SImode, addr);
20711
  
20707
20712
		insn = emit_move_insn (mem, reg);
20708
		insn = emit_move_insn (mem, reg);
20713
	   
20709
20714
		rs6000_frame_related (insn, spe_save_area_ptr,
20710
		rs6000_frame_related (insn,
20715
				      info->spe_gp_save_offset
20711
				      spe_save_area_ptr, save_ptr_to_sp,
20716
				      + sp_offset + reg_size * i,
20712
				      NULL_RTX, NULL_RTX);
20717
				      offset, const0_rtx);
20718
	      }
20713
	      }
20719
	}
20714
	}
20720
      else
20715
      else
20721
	{
20716
	{
20722
	  rtx par;
20717
	  rtx par;
20723
20718
20724
	  par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20719
	  par = rs6000_make_savres_rtx (info, spe_save_area_ptr,
20725
					0, reg_mode,
20720
					ool_adjust, reg_mode,
20726
					/*savep=*/true, /*gpr=*/true,
20721
					/*savep=*/true, /*gpr=*/true,
20727
					/*lr=*/false);
20722
					/*lr=*/false);
20728
	  insn = emit_insn (par);
20723
	  insn = emit_insn (par);
20729
	  rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20724
	  rs6000_frame_related (insn, spe_save_area_ptr, save_ptr_to_sp,
20730
				NULL_RTX, NULL_RTX);
20725
				NULL_RTX, NULL_RTX);
20731
	}
20726
	}
20732
					
20727
20733
 
20734
      /* Move the static chain pointer back.  */
20728
      /* Move the static chain pointer back.  */
20735
      if (using_static_chain_p && !spe_regs_addressable_via_sp)
20729
      if (using_static_chain_p && !spe_regs_addressable)
20736
	emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20730
	emit_move_insn (spe_save_area_ptr, gen_rtx_REG (Pmode, 0));
20737
    }
20731
    }
20738
  else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20732
  else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20739
    {
20733
    {
Lines 20742-20751 rs6000_emit_prologue (void) Link Here
20742
      /* Need to adjust r11 (r12) if we saved any FPRs.  */
20736
      /* Need to adjust r11 (r12) if we saved any FPRs.  */
20743
      if (info->first_fp_reg_save != 64)
20737
      if (info->first_fp_reg_save != 64)
20744
        {
20738
        {
20745
	  rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20739
	  rtx dest_reg = gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX ? 12 : 11);
20746
				      ? 12 : 11);
20740
	  int save_off = 8 * (64 - info->first_fp_reg_save);
20747
	  rtx offset = GEN_INT (sp_offset
20741
	  rtx offset = GEN_INT (sp_offset - save_off);
20748
                                + (-8 * (64-info->first_fp_reg_save)));
20742
20743
	  if (dest_reg == frame_reg_rtx)
20744
	    sp_offset = save_off;
20749
	  emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20745
	  emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20750
        }
20746
        }
20751
20747
Lines 21621-21660 rs6000_emit_epilogue (int sibcall) Link Here
21621
      && info->first_gp_reg_save != 32)
21617
      && info->first_gp_reg_save != 32)
21622
    {
21618
    {
21623
      /* Determine whether we can address all of the registers that need
21619
      /* Determine whether we can address all of the registers that need
21624
         to be saved with an offset from the stack pointer that fits in
21620
	 to be saved with an offset from frame_reg_rtx that fits in
21625
         the small const field for SPE memory instructions.  */
21621
	 the small const field for SPE memory instructions.  */
21626
      int spe_regs_addressable_via_sp
21622
      int spe_regs_addressable
21627
	= (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21623
	= (SPE_CONST_OFFSET_OK (info->spe_gp_save_offset + sp_offset
21628
			       + (32 - info->first_gp_reg_save - 1) * reg_size)
21624
				+ reg_size * (32 - info->first_gp_reg_save - 1))
21629
	   && restoring_GPRs_inline);
21625
	   && restoring_GPRs_inline);
21630
      int spe_offset;
21626
      int spe_offset;
21627
      int ool_adjust = 0;
21631
21628
21632
      if (spe_regs_addressable_via_sp)
21629
      if (spe_regs_addressable)
21633
	spe_offset = info->spe_gp_save_offset + sp_offset;
21630
	spe_offset = info->spe_gp_save_offset + sp_offset;
21634
      else
21631
      else
21635
        {
21632
	{
21636
	  rtx old_frame_reg_rtx = frame_reg_rtx;
21633
	  rtx old_frame_reg_rtx = frame_reg_rtx;
21637
          /* Make r11 point to the start of the SPE save area.  We worried about
21634
	  /* Make r11 point to the start of the SPE save area.  We worried about
21638
             not clobbering it when we were saving registers in the prologue.
21635
	     not clobbering it when we were saving registers in the prologue.
21639
             There's no need to worry here because the static chain is passed
21636
	     There's no need to worry here because the static chain is passed
21640
             anew to every function.  */
21637
	     anew to every function.  */
21641
	  int ool_adjust = (restoring_GPRs_inline
21638
21642
			    ? 0
21639
	  if (!restoring_GPRs_inline)
21643
			    : (info->first_gp_reg_save
21640
	    ool_adjust = 8 * (info->first_gp_reg_save
21644
			       - (FIRST_SAVRES_REGISTER+1))*8);
21641
			      - (FIRST_SAVRES_REGISTER + 1));
21645
21642
	  frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21646
	  if (frame_reg_rtx == sp_reg_rtx)
21643
	  emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21647
	    frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21648
          emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21649
				 GEN_INT (info->spe_gp_save_offset
21644
				 GEN_INT (info->spe_gp_save_offset
21650
					  + sp_offset
21645
					  + sp_offset
21651
					  - ool_adjust)));
21646
					  - ool_adjust)));
21652
	  /* Keep the invariant that frame_reg_rtx + sp_offset points
21647
	  /* Keep the invariant that frame_reg_rtx + sp_offset points
21653
	     at the top of the stack frame.  */
21648
	     at the top of the stack frame.  */
21654
	  sp_offset = -info->spe_gp_save_offset;
21649
	  sp_offset = -info->spe_gp_save_offset + ool_adjust;
21655
21650
21656
          spe_offset = 0;
21651
	  spe_offset = 0;
21657
        }
21652
	}
21658
21653
21659
      if (restoring_GPRs_inline)
21654
      if (restoring_GPRs_inline)
21660
	{
21655
	{
Lines 21694-21701 rs6000_emit_epilogue (int sibcall) Link Here
21694
	{
21689
	{
21695
	  rtx par;
21690
	  rtx par;
21696
21691
21697
	  par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21692
	  par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21698
					0, reg_mode,
21693
					ool_adjust, reg_mode,
21699
					/*savep=*/false, /*gpr=*/true,
21694
					/*savep=*/false, /*gpr=*/true,
21700
					/*lr=*/true);
21695
					/*lr=*/true);
21701
	  emit_jump_insn (par);
21696
	  emit_jump_insn (par);
Lines 21716-21727 rs6000_emit_epilogue (int sibcall) Link Here
21716
				 sp_offset, can_use_exit);
21711
				 sp_offset, can_use_exit);
21717
      else
21712
      else
21718
	{
21713
	{
21719
	  emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21714
	  rtx src_reg = gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX ? 12 : 11);
21720
							? 12 : 11),
21715
21721
				    frame_reg_rtx,
21716
	  emit_insn (gen_add3_insn (src_reg, frame_reg_rtx,
21722
				    GEN_INT (sp_offset - info->fp_size)));
21717
				    GEN_INT (sp_offset - info->fp_size)));
21723
	  if (REGNO (frame_reg_rtx) == 11)
21718
	  if (frame_reg_rtx == src_reg)
21724
	    sp_offset += info->fp_size;
21719
	    sp_offset = info->fp_size;
21725
	}
21720
	}
21726
21721
21727
      par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21722
      par = rs6000_make_savres_rtx (info, frame_reg_rtx,

Return to bug 50906