This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
[patch] asms with more than 10 operands (was: Re: egcs 1.0.1 miscompiles Linux 2.0.33)
- To: egcs at cygnus dot com
- Subject: [patch] asms with more than 10 operands (was: Re: egcs 1.0.1 miscompiles Linux 2.0.33)
- From: Bruno Haible <haible at ilog dot fr>
- Date: Thu, 5 Mar 1998 17:21:06 +0100 (MET)
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 ();