On 4/7/20 1:27 PM, Segher Boessenkool wrote: > On Mon, Apr 06, 2020 at 12:19:42PM +0100, Richard Sandiford wrote: >> The reason I'm not keen on using special modes for this case is that >> they'd describe one way in which the result can be used rather than >> describing what the instruction actually does. The instruction really >> does set all four flags to useful values. The "problem" is that they're >> not the values associated with a compare between two values, so representing >> them that way will always lose information. > > CC modes describe how the flags are set, not how the flags are used. > You cannot easily describe the V bit setting with a compare (it needs > a mode bigger than the register), is that what you mean?
I think that is a good deal of the effort. I wonder if it would be helpful to have (uoverflow_plus x y carry) (soverflow_plus x y carry) etc. (define_insn "uaddsi3_cout" [(set (reg:CC_C CC_REGNUM) (uoverflow_plus:CC_C (match_operand:SI 1 "register_operand") (match_operand:SI 2 "plus_operand") (const_int 0))) (set (match_operand:SI 0 "register_operand") (plus:SI (match_dup 1) (match_dup 2)))] ... ) (define_insn "uaddsi4_cin_cout" [(set (reg:CC_C CC_REGNUM) (uoverflow_plus:CC_C (match_operand:SI 1 "register_operand") (match_operand:SI 2 "reg_or_zero_operand") (match_operand:SI 3 "carry_operand"))) (set (match_operand:SI 0 "register_operand") (plus:SI (plus:SI (match_dup 3) (match_dup 1)) (match_dup 2)))] ... ) (define_insn "usubsi4_cin_cout" [(set (reg:CC_C CC_REGNUM) (uoverflow_plus:CC_C (match_operand:SI 1 "register_operand") (not:SI (match_operand:SI 2 "reg_or_zero_operand")) (match_operand:SI 3 "carry_operand"))) (set (match_operand:SI 0 "register_operand") (minus:SI (minus:SI (match_dup 1) (match_dup 2)) (match_operand:SI 4 "borrow_operand")))] ... ) This does have the advantage of avoiding the extensions, so that constants can be retained in the original mode. Though of course if we go this way, there will be incentive to add <s,u>overflow codes for all __builtin_*_overflow_p. r~