This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: alphaev6-unknown-linux-gnu: error in extract_insn, at recog.c:2127
On Tue, Jul 24, 2001 at 05:40:38PM -0700, Richard Henderson wrote:
> As a workaround, give the following a try.
I should have looked at the actual assembly output closer -- that
patch is incorrect in that it will _never_ match a true zero. I
forgot about the hidden const_double_chain member of CONST_DOUBLE.
r~
Index: config/alpha/alpha.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.c,v
retrieving revision 1.175
diff -c -p -d -r1.175 alpha.c
*** alpha.c 2001/07/22 16:02:06 1.175
--- alpha.c 2001/07/25 00:54:17
*************** mul8_operand (op, mode)
*** 566,579 ****
}
/* Return 1 if OP is the constant zero in floating-point. */
int
fp0_operand (op, mode)
register rtx op;
enum machine_mode mode;
{
! return (GET_MODE (op) == mode
! && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
}
/* Return 1 if OP is the floating-point constant zero or a register. */
--- 566,596 ----
}
/* Return 1 if OP is the constant zero in floating-point. */
+ /* ??? Use of CONST0_RTX in nested functions is currently broken. */
int
fp0_operand (op, mode)
register rtx op;
enum machine_mode mode;
{
! int i;
!
! if (GET_CODE (op) != CONST_DOUBLE)
! return 0;
!
! if (mode == VOIDmode)
! {
! if (GET_MODE_CLASS (GET_MODE (op)) != MODE_FLOAT)
! return 0;
! }
! else if (GET_MODE (op) != mode)
! return 0;
!
! for (i = GET_RTX_LENGTH (CONST_DOUBLE) - 1; i > 1; --i)
! if (XWINT (op, i) != 0)
! return 0;
!
! return 1;
}
/* Return 1 if OP is the floating-point constant zero or a register. */
*************** input_operand (op, mode)
*** 705,711 ****
&& general_operand (op, mode));
case CONST_DOUBLE:
! return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
case CONST_INT:
return mode == QImode || mode == HImode || add_operand (op, mode);
--- 722,728 ----
&& general_operand (op, mode));
case CONST_DOUBLE:
! return op == CONST0_RTX (mode) || fp0_operand (op, VOIDmode);
case CONST_INT:
return mode == QImode || mode == HImode || add_operand (op, mode);
*************** alpha_emit_conditional_branch (code)
*** 1768,1776 ****
{
/* When we are not as concerned about non-finite values, and we
are comparing against zero, we can branch directly. */
! if (op1 == CONST0_RTX (DFmode))
cmp_code = NIL, branch_code = code;
! else if (op0 == CONST0_RTX (DFmode))
{
/* Undo the swap we probably did just above. */
tem = op0, op0 = op1, op1 = tem;
--- 1785,1793 ----
{
/* When we are not as concerned about non-finite values, and we
are comparing against zero, we can branch directly. */
! if (fp0_operand (op1, DFmode))
cmp_code = NIL, branch_code = code;
! else if (fp0_operand (op0, DFmode))
{
/* Undo the swap we probably did just above. */
tem = op0, op0 = op1, op1 = tem;
*************** print_operand (file, x, code)
*** 3866,3871 ****
--- 3883,3890 ----
fprintf (file, "%s", reg_names[REGNO (x)]);
else if (x == CONST0_RTX (GET_MODE (x)))
fprintf (file, "$31");
+ else if (fp0_operand (x, VOIDmode))
+ fprintf (file, "$31");
else
output_operand_lossage ("invalid %%r value");
*************** print_operand (file, x, code)
*** 3876,3881 ****
--- 3895,3902 ----
if (GET_CODE (x) == REG)
fprintf (file, "%s", reg_names[REGNO (x)]);
else if (x == CONST0_RTX (GET_MODE (x)))
+ fprintf (file, "$f31");
+ else if (fp0_operand (x, VOIDmode))
fprintf (file, "$f31");
else
output_operand_lossage ("invalid %%R value");
Index: config/alpha/alpha.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.h,v
retrieving revision 1.126
diff -c -p -d -r1.126 alpha.h
*** alpha.h 2001/07/22 16:02:06 1.126
--- alpha.h 2001/07/25 00:54:18
*************** enum reg_class { NO_REGS, PV_REG, GENERA
*** 766,773 ****
that is the operand of a ZAP insn. */
#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
! ((C) == 'G' ? (GET_MODE_CLASS (GET_MODE (VALUE)) == MODE_FLOAT \
! && (VALUE) == CONST0_RTX (GET_MODE (VALUE))) \
: (C) == 'H' ? (GET_MODE (VALUE) == VOIDmode \
&& zap_mask (CONST_DOUBLE_LOW (VALUE)) \
&& zap_mask (CONST_DOUBLE_HIGH (VALUE))) \
--- 766,772 ----
that is the operand of a ZAP insn. */
#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
! ((C) == 'G' ? fp0_operand ((VALUE), VOIDmode) \
: (C) == 'H' ? (GET_MODE (VALUE) == VOIDmode \
&& zap_mask (CONST_DOUBLE_LOW (VALUE)) \
&& zap_mask (CONST_DOUBLE_HIGH (VALUE))) \