On Wed, Dec 4, 2013 at 8:07 PM, Jakub Jelinek <ja...@redhat.com> 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. I believe it should work, please see for example expNcorexf3 expander and many of its (match_dup X) expressions. >> 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. gen_int_mode calls trunc_int_for_mode that is introduced by the comment: /* Truncate and perhaps sign-extend C as appropriate for MODE. */ But, admittedly, I didn't test it... Uros.