Subject: Re: gcc 3.3.1 bug + patch
To: Martin Husemann <martin@duskware.de>
From: Ian Lance Taylor <ian@airs.com>
List: tech-toolchain
Date: 08/15/2003 10:53:44
Martin Husemann <martin@duskware.de> writes:

> I did a small change to sparc.md that seems to avoid it, and while there did
> the same for all similar instructions (srl and sra). I assume if compiling for
> 32bit targets gcc somehow knows that a register can not be shifted more than
> 31bit - so there is no need to protect the "x" variants of the instruction for
> sparc targets. Is that assumption correct? (If not, I'd have no idea how to
> deal with that)

As far as I know, that assumption is not correct.  One way to deal
with it is the way the MIPS backend does it:

  if (GET_CODE (operands[2]) == CONST_INT)
    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);

  return \"sll\\t%0,%1,%2\";

>  {
>    if (operands[2] == const1_rtx)
>      return "add\t%1, %1, %0";
> -  return "sll\t%1, %2, %0";
> +  if ((GET_CODE (operands[2]) == CONST_INT
> +     && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
> +   || (GET_CODE (operands[2]) == CONST_DOUBLE
> +     && CONST_DOUBLE_HIGH (operands[2]) == 0
> +      && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))
> +    return "sll\t%1, %2, %0";
> +  else
> +    return "sllx\t%1, %2, %0";

You don't need to check for CONST_DOUBLE here, because the constraints
do not permit a CONST_DOUBLE.  They only permit a register or a
CONST_INT.  Likewise in other places.

> @@ -6977,7 +6993,16 @@
>  	(sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
>  				     (match_operand:SI 2 "arith_operand" "r"))))]
>    "TARGET_ARCH64"
> -  "sra\t%1, %2, %0"
> +{
> +  if ((GET_CODE (operands[2]) == CONST_INT
> +     && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
> +   || (GET_CODE (operands[2]) == CONST_DOUBLE
> +     && CONST_DOUBLE_HIGH (operands[2]) == 0
> +      && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))
> +    return "sra\t%1, %2, %0";
> +  else
> +    return "srax\t%1, %2, %0";
> +}

Here the constraints only permit a register, so there is no need for
any change.

Ian