Hi,

./gcc/config/avr/avr.md

defines andsi3 as follows:

(define_insn "andsi3"
  [(set (match_operand:SI 0 "register_operand" "=r,d")
        (and:SI (match_operand:SI 1 "register_operand" "%0,0")
                (match_operand:SI 2 "nonmemory_operand" "r,i")))]
  ""
  "*{
  if (which_alternative==0)
    ...
  else if (which_alternative==1)
    {
      if (GET_CODE (operands[2]) == CONST_INT)
        {
          HOST_WIDE_INT mask = INTVAL (operands[2]);
          if ((mask & 0xff) != 0xff)
            output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
          if ((mask & 0xff00) != 0xff00)
            output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
          if ((mask & 0xff0000L) != 0xff0000L)
            output_asm_insn (AS2 (andi,%C0,hlo8(%2)), operands);
          if ((mask & 0xff000000L) != 0xff000000L)
            output_asm_insn (AS2 (andi,%D0,hhi8(%2)), operands);
          return \"\";
        }
      return ...
    }
  return \"bug\";
}"
  [(set_attr "length" "4,4")
   (set_attr "cc" "set_n,set_n")])

For alternative 1 "d,0,i" the effect on cc_status is described as set_n.
However, if the high byte of [2] is 0xff, then the PSW (i.e. SREG.N)
does not contain the MSB of the result.

I did not try to find a source that produces a bug basing on that,
but obviously the insn does not do what it states algebraically.

Besides that, andhi3 says cc=clobber in the similar case "d,0,i",
which is correct IMHO.

regards,

Georg-Johann

Reply via email to