Paulo J. Matos schrieb:
Hi,
I am having some trouble really understanding the working of cc_status.
In order to understand it better I was looking at the code for avr under
gcc 4.3.
My assumption is that set_zn, set_* means that an instructions _changes_
these flags. So an instruction that set_zn means that Z and N are
modified but we are not sure to which values. I assume clobber means
that an instruction changes some flags but we don't know which.
set_* tells you which condition code flags have been set in a usable
way, e.g. to be used in a subsequent branch instruction. For example, if
* contains 'z' you can use the Z-Flag to test if the value just set is
equal to zero or not. Look at "andqi3" insn which sets Z and N, but
"andhi3" just sets N or clobbers CC. Z just reflects the andi-action of
the high byte of the result, so you cannot use Z-flag to test wether or
not the result is zero or not. However, for alternatives 0 and 2, you
can use N to test the result (interpreted as signed) for <0 resp. >= 0.
'clobber' means the instruction leaves CC in a mess. 'none' means CC is
unchanged.
Now, the first thing that surprises me is clobber. Given a processor
instruction description we know exactly which instructions set what.
What's the need for clobber?
Check the following example from avr:
(define_insn "*strlenhi"
[(set (match_operand:HI 0 "register_operand" "=e")
(unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
(const_int 0)
(match_operand:HI 2 "immediate_operand" "i")]
UNSPEC_STRLEN))]
""
"ld __tmp_reg__,%a0+
tst __tmp_reg__
brne .-6"
[(set_attr "length" "3")
(set_attr "cc" "clobber")])
From the instruction manual I have [1] ld changes none, tst changes Z,N
and brne changes none so I would expect this instruction to have
(set_attr "cc" "set_zn") instead of the clobber. Why is this?
No. Z will always be set after that insn, even if op0 is not zero. Thus,
Z has nothing to do with op0, dito for N. Therefore, CC is 'clobber'
because it is not unchanged.
Johann