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


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

reg-stack and complex return value



Hi
This appears to be all changes needed to get complex return values working
in reg-stack.c
Most trickery comes from the part that when returning, we may have live just
half of the value. Also handling of clobbers needs updating, since these
never get to reg-stack usually, because they are elliminated in flow,
but they can't for register halves.

Honza

Thu May  3 18:45:30 CEST 2001  Jan Hubicka  <jh@suse.cz>
	* reg-stack.c (emit_pop_insn): Pop both halves of complex number
	(subst_stack_regs_pat): Push the second register to stack if needed.
	(subst_stack_regs): Avoid processing of clobber with REG_UNUSED note.
	(convert_regs_exit): Convert registers in reversed order to get
	them properly pushed.

*** /home/hubicka/egcs/gcc/reg-stack.c	Tue May  1 14:59:26 2001
--- reg-stack.c	Thu May  3 18:19:02 2001
*************** emit_pop_insn (insn, regstack, reg, wher
*** 937,942 ****
--- 937,959 ----
        return pop_insn;
      }
  
+   /* For complex types take care to pop both halves.  These may survive in
+      CLOBBER and USE expressions.  */
+   if (COMPLEX_MODE_P (GET_MODE (reg)))
+     {
+       rtx reg1 = FP_MODE_REG (REGNO (reg), DFmode);
+       rtx reg2 = FP_MODE_REG (REGNO (reg) + 1, DFmode);
+ 
+       pop_insn = NULL_RTX;
+       if (get_hard_regnum (regstack, reg1) >= 0)
+          pop_insn = emit_pop_insn (insn, regstack, reg1, where);
+       if (get_hard_regnum (regstack, reg2) >= 0)
+          pop_insn = emit_pop_insn (insn, regstack, reg2, where);
+       if (!pop_insn)
+ 	abort ();
+       return pop_insn;
+     }
+ 
    hard_regno = get_hard_regnum (regstack, reg);
  
    if (hard_regno < FIRST_STACK_REG)
*************** subst_stack_regs_pat (insn, regstack, pa
*** 1468,1478 ****
  	      }
  	    else
  	      {
! 		/* A top-level clobber with no REG_DEAD, and no hard-regnum
! 		   indicates an uninitialized value.  Because reload removed
! 		   all other clobbers, this must be due to a function 
! 		   returning without a value.  Load up a NaN.  */
  
  		if (! note
  		    && get_hard_regnum (regstack, *dest) == -1)
  		  {
--- 1485,1506 ----
  	      }
  	    else
  	      {
! 		/* A top-level clobber with no REG_DEAD nor REG_UNUSED,
! 		   and no hard-regnum indicates an uninitialized value.
! 		   Because reload removed all other clobbers, this must
! 		   be due to a function returning without a value.  Load
! 		   up a NaN.  */
  
+ 		if (! note && COMPLEX_MODE_P (GET_MODE (*dest))
+ 		    && get_hard_regnum (regstack, FP_MODE_REG (REGNO (*dest) + 1,
+ 					DFmode)) == -1)
+ 		  {
+ 		    pat = gen_rtx_SET (VOIDmode,
+ 				       FP_MODE_REG (REGNO (*dest) + 1, SFmode),
+ 				       nan);
+ 		    insn = emit_insn_before (pat, insn);
+ 		    move_for_stack_reg (emit_insn_before (pat, insn), regstack, pat);
+ 		  }
  		if (! note
  		    && get_hard_regnum (regstack, *dest) == -1)
  		  {
*************** subst_stack_regs (insn, regstack)
*** 2154,2159 ****
--- 2182,2205 ----
  	}
      }
  
+   /* Clobber with REG_UNUSED note may not have register alive previously.
+      Handle it early, otherwise we will emit dumy load and pop of the
+      register.  */
+   if (GET_CODE (PATTERN (insn)) == CLOBBER)
+     {
+       rtx dest = *get_true_reg (&XEXP (PATTERN (insn), 0));
+       note = find_reg_note (insn, REG_UNUSED, dest);
+       if (note && get_hard_regnum (regstack, dest) == -1
+ 	  && (!COMPLEX_MODE_P (GET_MODE (dest))
+ 	      || get_hard_regnum (regstack, FP_MODE_REG (REGNO (dest) + 1,
+ 			          DFmode)) == -1))
+ 	{
+ 	  delete_insn_for_stacker (insn);
+ 	  return;
+ 	}
+ 
+     }
+ 
    /* Do the actual substitution if any stack regs are mentioned.
       Since we only record whether entire insn mentions stack regs, and
       subst_stack_regs_pat only works for patterns that contain stack regs,
*************** convert_regs_exit ()
*** 2440,2446 ****
        output_stack->top = value_reg_high - value_reg_low;
        for (reg = value_reg_low; reg <= value_reg_high; ++reg)
  	{
! 	  output_stack->reg[reg - value_reg_low] = reg;
  	  SET_HARD_REG_BIT (output_stack->reg_set, reg);
  	}
      }
--- 2486,2492 ----
        output_stack->top = value_reg_high - value_reg_low;
        for (reg = value_reg_low; reg <= value_reg_high; ++reg)
  	{
! 	  output_stack->reg[value_reg_high - reg] = reg;
  	  SET_HARD_REG_BIT (output_stack->reg_set, reg);
  	}
      }


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