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]

Re: Your Jan 15 change broke the x86


On Sat, Jan 30, 1999 at 03:40:19PM -0700, Jeffrey A Law wrote:
> It doesn't fix the PA problem.  Give me about 5 minutes to get a testcase
> ready.

The problem in the PA case was a register output constraint ("=r"),
and a stack frame memory operand (bm).  So the initially generated
insn was invalid as far as check_asm_operands was concerned.

With a bit more care, we can fix this up in expand_asm_operands.

There is a regression over recent code concerns in-out constraints.
Something of the form

	asm("" : "+r"(*ptr))

won't be handled properly.  Correcting this will take some more
thought, especially if `ptr' were more complex like `foo()'.  I
will not generate incorrect code in this instance, but will error:

	zz.c:3: output number 0 not restored to memory

Given that in-out constraints were not until recently legal,
this should not affect many people yet, so it may be considered
acceptible to commit this to fix known pa/x86 problems and then
correct the other problem at leisure.

But I would like to see glibc build with this in, just to be
sure I'm not forgetting something.


r~


	* recog.c (check_asm_operands): Treat indeterminate operand ok
	results as success.  Try harder to resolve a matching constraint.
	* stmt.c (expand_asm_operands): Recognize when an output operand's
	constraint does not allow memory.  Treat indeterminate operand ok
	results as failure.  Try harder to resolve a matching constraint.

Index: stmt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/stmt.c,v
retrieving revision 1.59
diff -c -p -d -r1.59 stmt.c
*** stmt.c	1999/01/24 07:23:59	1.59
--- stmt.c	1999/01/30 23:57:55
*************** expand_asm_operands (string, outputs, in
*** 1251,1256 ****
--- 1251,1257 ----
        int j;
        int is_inout = 0;
        int allows_reg = 0;
+       int allows_mem = 0;
  
        /* If there's an erroneous arg, emit no insn.  */
        if (TREE_TYPE (val) == error_mark_node)
*************** expand_asm_operands (string, outputs, in
*** 1315,1322 ****
  	      }
  	    break;
  
! 	  case '?':  case '!':  case '*':  case '&':
! 	  case 'V':  case 'm':  case 'o':  case '<':  case '>':
  	  case 'E':  case 'F':  case 'G':  case 'H':  case 'X':
  	  case 's':  case 'i':  case 'n':
  	  case 'I':  case 'J':  case 'K':  case 'L':  case 'M':
--- 1316,1322 ----
  	      }
  	    break;
  
! 	  case '?':  case '!':  case '*':  case '&': case '<':  case '>':
  	  case 'E':  case 'F':  case 'G':  case 'H':  case 'X':
  	  case 's':  case 'i':  case 'n':
  	  case 'I':  case 'J':  case 'K':  case 'L':  case 'M':
*************** expand_asm_operands (string, outputs, in
*** 1331,1337 ****
  	    error ("matching constraint not valid in output operand");
  	    break;
  
! 	  case 'p':  case 'g':  case 'r':
  	  default:
  	    allows_reg = 1;
  	    break;
--- 1331,1346 ----
  	    error ("matching constraint not valid in output operand");
  	    break;
  
! 	  case 'V':  case 'm':  case 'o':
! 	    allows_mem = 1;
! 	    break;
! 
! 	  case 'g': 
! 	    allows_reg = 1;
! 	    allows_mem = 1;
! 	    break;
! 
! 	  case 'p': case 'r':
  	  default:
  	    allows_reg = 1;
  	    break;
*************** expand_asm_operands (string, outputs, in
*** 1342,1349 ****
  	 Make the asm insn write into that, then our caller will copy it to
  	 the real output operand.  Likewise for promoted variables.  */
  
!       if (TREE_CODE (val) == INDIRECT_REF
  	  || (TREE_CODE_CLASS (TREE_CODE (val)) == 'd'
  	      && ! (GET_CODE (DECL_RTL (val)) == REG
  		    && GET_MODE (DECL_RTL (val)) != TYPE_MODE (type)))
  	  || ! allows_reg
--- 1351,1360 ----
  	 Make the asm insn write into that, then our caller will copy it to
  	 the real output operand.  Likewise for promoted variables.  */
  
!       if ((TREE_CODE (val) == INDIRECT_REF
! 	   && allows_mem)
  	  || (TREE_CODE_CLASS (TREE_CODE (val)) == 'd'
+ 	      && (allows_mem || GET_CODE (DECL_RTL (val)) == REG)
  	      && ! (GET_CODE (DECL_RTL (val)) == REG
  		    && GET_MODE (DECL_RTL (val)) != TYPE_MODE (type)))
  	  || ! allows_reg
*************** expand_asm_operands (string, outputs, in
*** 1358,1363 ****
--- 1369,1376 ----
  
  	  if (! allows_reg && GET_CODE (output_rtx[i]) != MEM)
  	    error ("output number %d not directly addressable", i);
+ 	  if (! allows_mem && GET_CODE (output_rtx[i]) == MEM)
+ 	    error ("output number %d not restored to memory", i);
  	}
        else
  	{
*************** expand_asm_operands (string, outputs, in
*** 1472,1478 ****
  	      }
  
  	    /* Try and find the real constraint for this dup.  */
! 	    if (j == 0 && c_len == 1)
  	      {
  		tree o = outputs;
  		for (j = constraint[j] - '0'; j > 0; --j)
--- 1485,1492 ----
  	      }
  
  	    /* Try and find the real constraint for this dup.  */
! 	    if ((j == 0 && c_len == 1)
! 		|| (j == 1 && c_len == 2 && constraint[0] == '%'))
  	      {
  		tree o = outputs;
  		for (j = constraint[j] - '0'; j > 0; --j)
*************** expand_asm_operands (string, outputs, in
*** 1502,1508 ****
  
        op = expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0);
  
!       if (! asm_operand_ok (op, constraint))
  	{
  	  if (allows_reg)
  	    op = force_reg (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))), op);
--- 1516,1522 ----
  
        op = expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0);
  
!       if (asm_operand_ok (op, constraint) <= 0)
  	{
  	  if (allows_reg)
  	    op = force_reg (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))), op);
Index: recog.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/recog.c,v
retrieving revision 1.27
diff -c -p -d -r1.27 recog.c
*** recog.c	1999/01/23 19:45:40	1.27
--- recog.c	1999/01/30 23:58:13
*************** check_asm_operands (x)
*** 188,194 ****
    for (i = 0; i < noperands; i++)
      {
        const char *c = constraints[i];
!       if (ISDIGIT ((unsigned char)c[0]))
  	c = constraints[c[0] - '0'];
  
        if (! asm_operand_ok (operands[i], c))
--- 188,196 ----
    for (i = 0; i < noperands; i++)
      {
        const char *c = constraints[i];
!       if (c[0] == '%')
! 	c++;
!       if (ISDIGIT ((unsigned char)c[0]) && c[1] == '\0')
  	c = constraints[c[0] - '0'];
  
        if (! asm_operand_ok (operands[i], c))
*************** decode_asm_operands (body, operands, ope
*** 1550,1562 ****
    return template;
  }
  
! /* Check if an asm_operand matches it's constraints.  */
  
  int
  asm_operand_ok (op, constraint)
       rtx op;
       const char *constraint;
  {
    /* Use constrain_operands after reload.  */
    if (reload_completed)
      abort ();
--- 1552,1567 ----
    return template;
  }
  
! /* Check if an asm_operand matches it's constraints. 
!    Return > 0 if ok, = 0 if bad, < 0 if inconclusive.  */
  
  int
  asm_operand_ok (op, constraint)
       rtx op;
       const char *constraint;
  {
+   int result = 0;
+ 
    /* Use constrain_operands after reload.  */
    if (reload_completed)
      abort ();
*************** asm_operand_ok (op, constraint)
*** 1578,1586 ****
  
  	case '0': case '1': case '2': case '3': case '4':
  	case '5': case '6': case '7': case '8': case '9':
! 	  /* Our caller is supposed to have given us the proper
! 	     matching constraint.  */
! 	  /* abort (); */
  	  break;
  
  	case 'p':
--- 1583,1593 ----
  
  	case '0': case '1': case '2': case '3': case '4':
  	case '5': case '6': case '7': case '8': case '9':
! 	  /* For best results, our caller should have given us the
! 	     proper matching constraint, but we can't actually fail
! 	     the check if they didn't.  Indicate that results are
! 	     inconclusive.  */
! 	  result = -1;
  	  break;
  
  	case 'p':
*************** asm_operand_ok (op, constraint)
*** 1745,1751 ****
  	}
      }
  
!   return 0;
  }
  
  /* Given an rtx *P, if it is a sum containing an integer constant term,
--- 1752,1758 ----
  	}
      }
  
!   return result;
  }
  
  /* Given an rtx *P, if it is a sum containing an integer constant term,


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