On 21/10/11 22:41, Richard Henderson wrote:
On 10/21/2011 10:15 AM, Paulo J. Matos wrote:
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";
})

There are lots of parts of the compiler that don't optimize well when an
insn has more than one output.  For the normal insn, just clobber the flags;
don't include a second SET.


But this case is not a normal insn per se, I did this to negqi2 because I need GCC to know that this instruction explicitly changes RCC and that the following instruction will use the carry flag (addc).

The reason I say it is not a normal insn is because it comes often in a pair negqi2 / addc_internal, like for example addqi3 / addc_internal or subqi3 / subc_internal.

(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")

You don't need the USE, because you mention RCC inside the LTU.

(define_insn "*addc_internal_flags"

Likewise.


Got it, thanks.

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.

Surely the NADD insn is simply a normal subtract (with reversed operands).
You shouldn't *need* to implement NEG at all, as the middle-end will let
NEG expand via MINUS.

Just so you know...


But it is not exactly the same thing in this arch because:
subqi3 generates a
sub <register>, <data> == <register> = <register> - <data>

to represent negqi2 of register R with a nadd I just do:
nadd R,#0

to represent it using a sub I require more moves:
ld R1, #0
sub R1, @R ; @R is memory mapped R
ld R, @R1

* 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?

Yes.

Also, do I need to specify in the RCC
clobber, exactly which flags are clobbered, or should I use a set
instead?

No, the compiler will assume the entire register is changed, no matter
what CCmode you place there.


Got it, so the only way to deal with the carry flag by itself would be to represent the Carry flag as a separate flags register. Although that would require more than one flags register and it feels messy.

--
PMatos

Reply via email to