This is the mail archive of the gcc@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]

[patch] asms with more than 10 operands (was: Re: egcs 1.0.1 miscompiles Linux 2.0.33)



Geoffrey Keating wrote:

> On PPC, I want to inline a 5-word by 1-word multiply, and can't
> (reliably) because:
>
> * A single inline asm will have 6 inputs and 5 outputs, and the limit
> is 10;

I've had the same problems on Sparc recently, with some asm code which
used about 12 asm arguments. The hard limit of 10 asm arguments (counting
in-out registers twice!) is very bad. Here is a patch which fixes it
for Sparc; support for other CPUs is trivial to add. Can you please put
this in?

                       Bruno



Thu Mar  5 12:29:29 1998  Bruno Haible  <bruno@linuix.mathematik.uni-karlsruhe.de>

        * genconfig.c (main): Make MAX_RECOG_OPERANDS customizable.
        * regmove.c (find_matches): Accept multi-digit constraints.
        * reload.c (find_reloads): Likewise.
        * stmt.c (expand_asm_operands): Likewise.
        * sparc.h (MAX_RECOG_OPERANDS): Define.

*** egcs-980302/gcc/genconfig.c.bak	Wed Mar  4 02:47:01 1998
--- egcs-980302/gcc/genconfig.c	Thu Mar  5 11:42:43 1998
***************
*** 336,342 ****
  	gen_peephole (desc);
      }
  
!   printf ("\n#define MAX_RECOG_OPERANDS %d\n", max_recog_operands + 1);
  
    printf ("\n#define MAX_DUP_OPERANDS %d\n", max_dup_operands);
  
--- 336,345 ----
  	gen_peephole (desc);
      }
  
!   /* This is conditionally defined, so that the user can write code which
!      uses more than 10 asm operands.  */
!   printf ("\n#ifndef MAX_RECOG_OPERANDS\n#define MAX_RECOG_OPERANDS %d\n#endif\n",
! 	  max_recog_operands + 1);
  
    printf ("\n#define MAX_DUP_OPERANDS %d\n", max_dup_operands);
  
*** egcs-980302/gcc/md.texi.bak	Wed Mar  4 02:44:38 1998
--- egcs-980302/gcc/md.texi	Thu Mar  5 11:42:44 1998
***************
*** 808,814 ****
  @item @samp{0}, @samp{1}, @samp{2}, @dots{} @samp{9}
  An operand that matches the specified operand number is allowed.  If a
  digit is used together with letters within the same alternative, the
! digit should come last.
  
  @cindex matching constraint
  @cindex constraint, matching
--- 808,816 ----
  @item @samp{0}, @samp{1}, @samp{2}, @dots{} @samp{9}
  An operand that matches the specified operand number is allowed.  If a
  digit is used together with letters within the same alternative, the
! digit should come last. Several consecutive digits are allowed, if they
! form an operand number less than @samp{MAX_RECOG_OPERANDS}.
! @samp{MAX_RECOG_OPERANDS} is normally 10, but can be increased up to 128.
  
  @cindex matching constraint
  @cindex constraint, matching
*** egcs-980302/gcc/regmove.c.bak	Wed Mar  4 02:47:12 1998
--- egcs-980302/gcc/regmove.c	Thu Mar  5 11:48:38 1998
***************
*** 29,34 ****
--- 29,37 ----
  #else
  #include <varargs.h>
  #endif
+ #ifdef HAVE_STDLIB_H
+ #include <stdlib.h>
+ #endif
  
  /* Must precede rtl.h for FFS.  */
  #include <stdio.h>
***************
*** 1201,1207 ****
  	    break;
  	  case '0': case '1': case '2': case '3': case '4':
  	  case '5': case '6': case '7': case '8': case '9':
! 	    c -= '0';
  	    if (c < operand_number && likely_spilled[c])
  	      break;
  	    matchp->with[operand_number] = c;
--- 1204,1216 ----
  	    break;
  	  case '0': case '1': case '2': case '3': case '4':
  	  case '5': case '6': case '7': case '8': case '9':
! 	    if (MAX_RECOG_OPERANDS > 10 && *p >= '0' && *p <= '9')
! 	      {
! 		c = atoi (p - 1);
! 		while (*p >= '0' && *p <= '9') p++;
! 	      }
! 	    else
! 	      c -= '0';
  	    if (c < operand_number && likely_spilled[c])
  	      break;
  	    matchp->with[operand_number] = c;
*** egcs-980302/gcc/reload.c.bak	Wed Mar  4 02:47:13 1998
--- egcs-980302/gcc/reload.c	Thu Mar  5 11:49:11 1998
***************
*** 89,94 ****
--- 89,97 ----
  
  #include "config.h"
  #include <stdio.h>
+ #ifdef HAVE_STDLIB_H
+ #include <stdlib.h>
+ #endif
  #include "rtl.h"
  #include "insn-config.h"
  #include "insn-codes.h"
***************
*** 2481,2487 ****
  	    }
  	  else if (c >= '0' && c <= '9')
  	    {
! 	      c -= '0';
  	      operands_match[c][i]
  		= operands_match_p (recog_operand[c], recog_operand[i]);
  
--- 2484,2496 ----
  	    }
  	  else if (c >= '0' && c <= '9')
  	    {
! 	      if (MAX_RECOG_OPERANDS > 10 && *p >= '0' && *p <= '9')
! 		{
! 		  c = atoi (p - 1);
! 		  while (*p >= '0' && *p <= '9') p++;
! 		}
! 	      else
! 		c -= '0';
  	      operands_match[c][i]
  		= operands_match_p (recog_operand[c], recog_operand[i]);
  
*** egcs-980302/gcc/stmt.c.bak	Wed Mar  4 02:47:17 1998
--- egcs-980302/gcc/stmt.c	Thu Mar  5 11:42:46 1998
***************
*** 1320,1325 ****
--- 1320,1326 ----
      {
        int j;
        int allows_reg = 0;
+       char c;
  
        /* If there's an erroneous arg, emit no insn,
  	 because the ASM_INPUT would get VOIDmode
***************
*** 1361,1368 ****
  	       operands to memory.  */
  	  case '0':  case '1':  case '2':  case '3':  case '4':
  	  case '5':  case '6':  case '7':  case '8':  case '9':
! 	    if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j]
! 		>= '0' + noutputs)
  	      {
  		error
  		  ("matching constraint references invalid operand number");
--- 1362,1380 ----
  	       operands to memory.  */
  	  case '0':  case '1':  case '2':  case '3':  case '4':
  	  case '5':  case '6':  case '7':  case '8':  case '9':
! 	    if (j + 1 < TREE_STRING_LENGTH (TREE_PURPOSE (tail)) - 1
! 		&& TREE_STRING_POINTER (TREE_PURPOSE (tail))[j+1] >= '0'
! 		&& TREE_STRING_POINTER (TREE_PURPOSE (tail))[j+1] <= '9')
! 	      {
! 		c = atoi (&TREE_STRING_POINTER (TREE_PURPOSE (tail))[j]);
! 		while (j + 1 < TREE_STRING_LENGTH (TREE_PURPOSE (tail)) - 1
! 		       && TREE_STRING_POINTER (TREE_PURPOSE (tail))[j+1] >= '0'
! 		       && TREE_STRING_POINTER (TREE_PURPOSE (tail))[j+1] <= '9')
! 		  j++;
! 	      }
! 	    else
! 	      c = TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] - '0';
! 	    if (c >= noutputs)
  	      {
  		error
  		  ("matching constraint references invalid operand number");
*** egcs-980302/gcc/config/sparc/sparc.h.bak	Sun Feb 22 10:25:31 1998
--- egcs-980302/gcc/config/sparc/sparc.h	Thu Mar  5 11:57:51 1998
***************
*** 3182,3187 ****
--- 3182,3190 ----
  
  #define DONT_ACCESS_GBLS_AFTER_EPILOGUE (flag_pic)
  
+ /* Allow asm statements with upto 20 arguments.  */
+ #define MAX_RECOG_OPERANDS 20
+ 
  /* Declare functions defined in sparc.c and used in templates.  */
  
  extern char *singlemove_string ();


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