This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Your Jan 15 change broke the x86
- To: law at cygnus dot com
- Subject: Re: Your Jan 15 change broke the x86
- From: Richard Henderson <rth at cygnus dot com>
- Date: Sat, 30 Jan 1999 16:17:42 -0800
- Cc: egcs-bugs at cygnus dot com, egcs-patches at cygnus dot com, drepper at cygnus dot com
- References: <19990130142632.A27028@cygnus.com> <7487.917736019@hurl.cygnus.com>
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,