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