On 19/10/11 01:48, paul_kon...@dell.com wrote:
From: gcc-ow...@gcc.gnu.org [mailto:gcc-ow...@gcc.gnu.org] On Behalf Of Richard 
Henderson
On 10/17/2011 03:50 AM, Paulo J. Matos wrote:
...
(for example, it would be ok to output negqi2, xorqi3 and
addc_internal since xorqi3 only sets N and Z, not the Carry bit)

For that you'd have to model all of the flags bits independently.
I don't believe any target has found that level of complexity to be worth the 
trouble.

Something like that shows up in the pdp11, where "mov" does not touch C.  And C 
matters for multi-word arithmetic, and also for unsigned compares.  So I think a CCmode 
implementation there would  model C separately from the other three flag bits.  So not 4 
separate elements but two.  Right now it's a cc0 target but I figure on changing that at 
some point.  The reasons Paulo mentioned are one of the main reasons for that.

        paul



I have several CC modes depending on which flags are set by each instruction:
CC - all flags set
CC_C - Carry flag set
CC_NZ - Negative and Zero flags set

For neghi2 mode which transforms into an xor, nadd and addc in my arch I need to establish that the addc adds the carry produced by the nadd.

So I have implemented the nadd and addc as:

(define_insn "negqi2"
  [(set (match_operand:QI 0 "register_operand" "=c")
        (neg:QI (match_operand:QI 1 "register_operand" "0")))
   (set (reg:CC_C RCC) (eq (match_dup 1) (const_int 0)))
   (clobber (reg:CC RCC))]
  ""
{
    operands[2] = const0_rtx;
    return  "nadd\\t%0,%2";
})

(define_insn "*negqi2_flags"
  [(set (match_operand:QI 0 "register_operand" "=c")
        (neg:QI (match_operand:QI 1 "register_operand" "0")))
   (set (reg RCC)
        (compare (neg:QI (match_dup 1))
                 (const_int 0)))]
  "reload_completed && xap_match_ccmode(insn, CCmode)"
{
    operands[2] = const0_rtx;
    return  "nadd\\t%0,%2";
})

(define_insn "addc_internal"
  [(set (match_operand:QI 0 "nonimmediate_operand" "=c")
        (plus:QI
          (plus:QI
            (ltu:QI (reg:CC RCC) (const_int 0))
            (match_operand:QI 1 "nonimmediate_operand" "%0"))
          (match_operand:QI 2 "general_operand" "cwmi")))
   (use (reg:CC_C RCC))
   (clobber (reg:CC RCC))]
  ""
  "addc\\t%0,%f2")

(define_insn "*addc_internal_flags"
  [(set (match_operand:QI 0 "nonimmediate_operand" "=c")
        (plus:QI
          (plus:QI
            (ltu:QI (reg:CC RCC) (const_int 0))
            (match_operand:QI 1 "nonimmediate_operand" "%0"))
          (match_operand:QI 2 "general_operand" "cwmi")))
   (use (reg:CC_C RCC))
   (set (reg RCC)
        (compare
          (plus:QI
            (plus:QI
              (ltu:QI (reg:CC RCC) (const_int 0))
              (match_dup 1))
            (match_dup 2))
          (const_int 0)))]
  "reload_completed && xap_match_ccmode(insn, CCmode)"
  "addc\\t%0,%f2")

A couple of things to note:
* negqi (which generates the nadd x, y equivalent to -x + y) has a set RCC in C mode followed by a clobber. The set in C mode doesn't show up in the _flags variant which is used only for the compare-elim since it doesn't really matter and it already contains a set RCC anyway.
* the addc internal specifically says that it uses the RCC in C mode

Now, some things still remain a mistery:
* is this enough for GCC to understand that anything that clobbers RCC or specifically touches the RCC in C mode shouldn't go in between these two instructions? Also, do I need to specify in the RCC clobber, exactly which flags are clobbered, or should I use a set instead? * in the case of using sets, it was easy in the case of the negqi of findind the source of the set RCC, however, it's not so easy for the general case. Is unspec the answer? Is unspec the way of saying: "hey, I am setting RCC in Cmode here, you shouldn't bother about the value that I put there. Just know that RCC is going to be set."

--
PMatos

Reply via email to