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]

INDREG infrastructure (small)


Hi
I've decided to split out this part of INDREG patch. It is small (smaller
than my comments in the front :)
and contain 99% of design decision needed to add INDREG infrastructure
to gcc. So I believe that it has much better chance to get reviewed
than whole large INDREG patch, where 90% of size is almost-mechanical
rewrite of i386.md and reg-stack.c. (and I feell much more competent
to do the second part than this one)

The patch apply cleanly to current tree and don't break (or change
behaviour) of anything.

So hope I will get your suggestions soon.

Here are few notes:

This patch adds INDREG rtl constructions to several places where I believe
it belongs. Note that it is first time I am adding new RTL code to gcc,
so I am not sure what to do exactly. I've searched trought emit-rtl
rtl and rtlanal and added INDREG support where it seemed to be usefull
(note that we need to support INDREG only in shorten-branches and finial)

It also adds infrastructure to match INDREG to register classes using
hooks defined in md file. This is usefull to keep my code simple. While
this can be doable by adding extra constraints, this can be pretty hard
to implement. It would require translating of existing asm statements
and adding of EXTRA_CONSTRAINTS to i386.c because of:
#ifdef EXTRA_CONSTRAINT
/* If EXTRA_CONSTRAINT is defined, then the 'S'
   constraint in REG_CLASS_FROM_LETTER will no longer work, and various
   asm statements that need 'S' for class SIREG will break.  */
 error EXTRA_CONSTRAINT conflicts with S constraint letter
/* The previous line used to be #error, but some compilers barf
   even if the conditional was untrue.  */
#endif

(so extra hook into stmt.c translating letter 'S' to something else
will be required as well.)

and because INDREG is register I think it is convenient to let it handle
as register, but I am not sure if my solution is acceptable.

The extra hooks are INDREG_MATCH needed by operand_match_p (because
matching of registers don't require same mode, I need the same for
indreg too. Also I need to match popping and non-popping variants
of representation of the same register.)

Second is INDREG_FITS_CLASS that does actual register class matching.

But I have alternative plan (extra constraints and renaming of 'S')
if that fails, so let me know.

Sun Aug  8 22:00:35 EDT 1999  Jan Hubicka  <hubicka@freesoft.cz>
	* rtl.def (INDREG): New.
	* emit-rtl.c (copy_rtx_if_shared): Add support for INDREG.
	* recog.c (constrain_operands): Add support for INDREG.
	* reload.c (operands_match_p): Call INDREG_MATCH
	* rtl.c (copy_rtx): Support INDREG.
	* rtl.c (copy_most_rtx): Support INDREG.
	* rtl.h (INDREG_P): New macro.
	(stack_regs_mentioned): Remove.
	* rtlanal.c (rtx_unstable_p): Support INDREG.
	(rtx_varies_p): Support INDREG.
	(rtx_addr_can_trap_p): Support INDREG.
	(modified_between_p): Support INDREG.
	(modified_in_p): Support INDREG.
	(reg_overlap_mentioned_p): Support INDREG.
	(volatile_insn_p): Support INDREG.
	(volatile_refs_p): Support INDREG.
	(side_effects_p): Support INDREG.
	(may_trap_p): Support INDREG.

*** emit-rtl.c.noir	Sat Aug  7 17:32:40 1999
--- emit-rtl.c	Sat Aug  7 17:34:50 1999
*************** copy_rtx_if_shared (orig)
*** 1795,1800 ****
--- 1795,1801 ----
    switch (code)
      {
      case REG:
+     case INDREG:
      case QUEUED:
      case CONST_INT:
      case CONST_DOUBLE:
*** recog.c.noir	Sat Aug  7 17:38:05 1999
--- recog.c	Sun Aug  8 11:06:50 1999
*************** constrain_operands (strict)
*** 2511,2516 ****
--- 2511,2520 ----
  			&& GET_CODE (op) == REG
  			&& REGNO (op) >= FIRST_PSEUDO_REGISTER)
  		    || (strict == 0 && GET_CODE (op) == SCRATCH)
+ #ifdef INDREG_FITS_CLASS
+ 		    || (GET_CODE (op) == INDREG
+ 			&& INDREG_FITS_CLASS (op, c, offset, mode))
+ #endif
  		    || (GET_CODE (op) == REG
  			&& reg_fits_class_p (op, REG_CLASS_FROM_LETTER (c),
  					     offset, mode)))
*** reload.c.noir	Sun Aug  8 15:00:03 1999
--- reload.c	Sun Aug  8 15:07:13 1999
*************** operands_match_p (x, y)
*** 2079,2084 ****
--- 2079,2088 ----
        
    if (x == y)
      return 1;
+ #ifdef INDREG_MATCH
+   if (code == INDREG && GET_CODE (y) == INDREG)
+     return INDREG_MATCH (x, y);
+ #endif
    if ((code == REG || (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG))
        && (GET_CODE (y) == REG || (GET_CODE (y) == SUBREG
  				  && GET_CODE (SUBREG_REG (y)) == REG)))
*** rtl.c.noir	Sat Aug  7 17:22:28 1999
--- rtl.c	Sat Aug  7 17:23:24 1999
*************** copy_rtx (orig)
*** 289,294 ****
--- 289,295 ----
    switch (code)
      {
      case REG:
+     case INDREG:
      case QUEUED:
      case CONST_INT:
      case CONST_DOUBLE:
*************** copy_most_rtx (orig, may_share)
*** 420,425 ****
--- 421,427 ----
    switch (code)
      {
      case REG:
+     case INDREG:
      case QUEUED:
      case CONST_INT:
      case CONST_DOUBLE:
*** rtl.def.noir	Sat Aug  7 17:17:37 1999
--- rtl.def	Sat Aug  7 17:21:35 1999
*************** DEF_RTL_EXPR(PC, "pc", "", 'o')
*** 552,557 ****
--- 552,562 ----
     somehow.  Then, the trailing `0' can be removed here.  */
  DEF_RTL_EXPR(REG, "reg", "i0", 'o')
  
+ /* A indexed register.  The "operand" is the register number given 
+    as expression.  This construction is used by i386 backend to describe
+    register stack used by i387.  */
+ DEF_RTL_EXPR(INDREG, "indreg", "e", 'o')
+ 
  /* A scratch register.  This represents a register used only within a
     single insn.  It will be turned into a REG during register allocation
     or reload unless the constraint indicates that the register won't be
*** rtlanal.c.noir	Sat Aug  7 17:23:54 1999
--- rtlanal.c	Sat Aug  7 17:32:16 1999
*************** rtx_unstable_p (x)
*** 50,56 ****
    register int i;
    register char *fmt;
  
!   if (code == MEM)
      return ! RTX_UNCHANGING_P (x);
  
    if (code == QUEUED)
--- 50,56 ----
    register int i;
    register char *fmt;
  
!   if (code == MEM || code == INDREG)
      return ! RTX_UNCHANGING_P (x);
  
    if (code == QUEUED)
*************** rtx_varies_p (x)
*** 88,93 ****
--- 88,94 ----
  
    switch (code)
      {
+     case INDREG:
      case MEM:
      case QUEUED:
        return 1;
*************** rtx_addr_can_trap_p (x)
*** 142,147 ****
--- 143,151 ----
  	 now, we ignore the impact of #pragma weak.  */
        return 0;
  
+     case INDREG:
+       return 1;
+ 
      case REG:
        /* As in rtx_varies_p, we have to use the actual rtx, not reg number.  */
        return ! (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
*************** modified_between_p (x, start, end)
*** 591,596 ****
--- 595,601 ----
        return 1;
  
      case MEM:
+     case INDREG:
        /* If the memory is not constant, assume it is modified.  If it is
  	 constant, we still have to check the address.  */
        if (! RTX_UNCHANGING_P (x))
*************** modified_in_p (x, insn)
*** 646,651 ****
--- 651,657 ----
        return 1;
  
      case MEM:
+     case INDREG:
        /* If the memory is not constant, assume it is modified.  If it is
  	 constant, we still have to check the address.  */
        if (! RTX_UNCHANGING_P (x))
*************** reg_overlap_mentioned_p (x, in)
*** 931,937 ****
      }
    else if (GET_CODE (x) == REG)
      regno = REGNO (x);
!   else if (GET_CODE (x) == MEM)
      {
        char *fmt;
        int i;
--- 937,943 ----
      }
    else if (GET_CODE (x) == REG)
      regno = REGNO (x);
!   else if (GET_CODE (x) == MEM || GET_CODE (x) == INDREG)
      {
        char *fmt;
        int i;
*************** reg_overlap_mentioned_p (x, in)
*** 939,944 ****
--- 945,953 ----
        if (GET_CODE (in) == MEM)
  	return 1;
  
+       if (GET_CODE (in) == INDREG)
+ 	return 1;
+ 
        fmt = GET_RTX_FORMAT (GET_CODE (in));
  
        for (i = GET_RTX_LENGTH (GET_CODE (in)) - 1; i >= 0; i--)
*************** volatile_insn_p (x)
*** 1586,1592 ****
      case CONST_DOUBLE:
      case CC0:
      case PC:
!     case REG:
      case SCRATCH:
      case CLOBBER:
      case ASM_INPUT:
--- 1595,1601 ----
      case CONST_DOUBLE:
      case CC0:
      case PC:
!     case INDREG:
      case SCRATCH:
      case CLOBBER:
      case ASM_INPUT:
*************** volatile_refs_p (x)
*** 1653,1658 ****
--- 1662,1668 ----
      case CC0:
      case PC:
      case REG:
+     case INDREG:
      case SCRATCH:
      case CLOBBER:
      case ASM_INPUT:
*************** side_effects_p (x)
*** 1719,1724 ****
--- 1729,1735 ----
      case CC0:
      case PC:
      case REG:
+     case INDREG:
      case SCRATCH:
      case ASM_INPUT:
      case ADDR_VEC:
*************** may_trap_p (x)
*** 1804,1809 ****
--- 1815,1821 ----
        /* Conditional trap can trap!  */
      case UNSPEC_VOLATILE:
      case TRAP_IF:
+     case INDREG:
        return 1;
  
        /* Memory ref can trap unless it's a static var or a stack slot.  */
237a238
*** rtl.h.noir	Sun Aug  8 13:50:16 1999
--- rtl.h	Tue Aug 10 17:23:11 1999
*************** typedef struct rtvec_def{
*** 214,219 ****
--- 214,223 ----
  
  #define REG_P(X) (GET_CODE (X) == REG)
  
+ /* 1 if X is a INDREG.  */
+ 
+ #define INDREG_P(X) (GET_CODE (X) == INDREG)
+ 
  /* 1 if X is a constant value that is an integer.  */
  
  #define CONSTANT_P(X)   \


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