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

Reply via email to