On Wed, Feb 14, 2007 at 08:30:52PM +0000, Sami Khawam wrote:
> Hi Rask,
>
> Basically the CPU has the 'SCALE_28_4' instruction which does the following:
> output = (operand1 >> 28) | (operand2 << 4)
>
> From my understanding the OR operation (ior), doesn't get canonicalized
> since it's second operand (in this case (lshiftrt:SI (match_operand:SI 2
> "register_operand" "r") (const_int 4)) ) is not a constant.
OK, I see what you mean. The reason you can get both (ior (ashift ...)
(lshiftrt ...)) and (ior (lshiftrt ...) (ashift ...)) is that simplify-rtx.c
has no rule to canonicalize such expressions and that LSHIFTRT and
ASHIFT have the same precedence.
Hmm, in simplify_binary_operation_1(), it says:
/* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
mode size to (rotate A CX). */
Right after that is code to make sure ASHIFT is the first operand for the
simplification attempts that follow. You could try adding code to do this in
general, but I don't know where such code should be added.
Btw, I found this in rtlanal.c:
/* Return a value indicating whether OP, an operand of a commutative
operation, is preferred as the first or second operand. The higher
the value, the stronger the preference for being the first operand.
We use negative values to indicate a preference for the first operand
and positive values for the second operand. */
int
commutative_operand_precedence (rtx op)
{
enum rtx_code code = GET_CODE (op);
/* Constants always come the second operand. Prefer "nice" constants. */
if (code == CONST_INT)
return -7;
[...]
The comment disagrees with the code.
--
Rask Ingemann Lambertsen