On Wed, Dec 04, 2013 at 07:58:20PM +0100, Uros Bizjak wrote:
> > @@ -8617,6 +8740,49 @@
> > [(set_attr "type" "negnot")
> > (set_attr "mode" "SI")])
> >
> > +;; Negate with jump on overflow.
> > +(define_expand "negv<mode>3"
> > + [(parallel [(set (reg:CCO FLAGS_REG)
> > + (ne:CCO (match_operand:SWI 1 "register_operand")
> > + (const_int 0)))
> > + (set (match_operand:SWI 0 "register_operand")
> > + (neg:SWI (match_dup 1)))])
> > + (set (pc) (if_then_else
> > + (eq (reg:CCO FLAGS_REG) (const_int 0))
> > + (label_ref (match_operand 2))
> > + (pc)))]
> > + ""
> > +{
> > + rtx minv = GEN_INT (HOST_WIDE_INT_M1U
> > + << (GET_MODE_BITSIZE (<MODE>mode) - 1));
> > + emit_insn (gen_negv<mode>3_1 (operands[0], operands[1], minv,
> > operands[2]));
> > + DONE;
> > +})
>
> No, please use
>
> "operands[3] = GEN_INT (....);"
>
> and use (match_dup 3) in the pattern. The pattern below is not needed then.
My memory is fuzzy about that, but I think that was my first version which
didn't work, because with match_dup then it requires on the internal-fn.c
side to pass 4 arguments instead of just 3. I can try again though.
> BTW: can we use
>
> gen_int_mode (1 << (GET_MODE_BITSIZE (mode) - 1), mode)
>
> instead?
With HOST_WIDE_INT_1U instead of 1 and s/mode/<MODE>mode/g perhaps.
Jakub