On Wed, Jul 29, 2015 at 04:59:23PM -0500, Segher Boessenkool wrote: > On Wed, Jul 29, 2015 at 04:04:28PM -0400, Michael Meissner wrote: > > +;; Return constant 0x80000000000000000000000000000000 in an Altivec > > register. > > + > > +(define_expand "altivec_high_bit" > > + [(set (match_dup 1) > > + (vec_duplicate:V16QI (const_int 7))) > > + (set (match_dup 2) > > + (ashift:V16QI (match_dup 1) > > + (match_dup 1))) > > + (set (match_dup 3) > > + (match_dup 4)) > > + (set (match_operand:V16QI 0 "register_operand" "") > > + (unspec:V16QI [(match_dup 2) > > + (match_dup 3) > > + (const_int 15)] UNSPEC_VSLDOI))] > > + "TARGET_ALTIVEC" > > +{ > > + if (can_create_pseudo_p ()) > > + { > > + operands[1] = gen_reg_rtx (V16QImode); > > + operands[2] = gen_reg_rtx (V16QImode); > > + operands[3] = gen_reg_rtx (V16QImode); > > + } > > + else > > + operands[1] = operands[2] = operands[3] = operands[0]; > > This won't work (in the pattern you write to op 3 before reading from op 2). > Do you ever call this expander late, anyway?
I'm not sure I follow you. Without the patch lines the insns are as follows (I put in blank lines to separate the insns): (define_expand "altivec_high_bit" [(set (match_dup 1) (vec_duplicate:V16QI (const_int 7))) (set (match_dup 2) (ashift:V16QI (match_dup 1) (match_dup 1))) (set (match_dup 3) (match_dup 4)) (set (match_operand:V16QI 0 "register_operand" "") (unspec:V16QI [(match_dup 2) (match_dup 3) (const_int 15)] UNSPEC_VSLDOI))] "TARGET_ALTIVEC" { if (can_create_pseudo_p ()) { operands[1] = gen_reg_rtx (V16QImode); operands[2] = gen_reg_rtx (V16QImode); operands[3] = gen_reg_rtx (V16QImode); } else operands[1] = operands[2] = operands[3] = operands[0]; operands[4] = CONST0_RTX (V16QImode); }) The first insn sets operands[1] to be 0x07070707070707070707070707070707LL. The second insn sets operands[2] to be operands[1] << operands[1], i.e. 0x80808080808080808080808080808080LL. The third insn sets operands[3] to be 0. The fourth does a double vector shift left 15 bytes, filing in 0's in the bottom bits, which leaves the following in the register: 0x80000000000000000000000000000000LL This is negative -0.0 in IEEE 128-bit, which is used to flip the sign bit. The code is used for negate and absolute value (which is done during rtl expansion). Here is the negate use case. (define_insn_and_split "ieee_128bit_vsx_neg<mode>2" [(set (match_operand:TFIFKF 0 "register_operand" "=wa") (neg:TFIFKF (match_operand:TFIFKF 1 "register_operand" "wa"))) (clobber (match_scratch:V16QI 2 "=v"))] "TARGET_FLOAT128 && FLOAT128_IEEE_P (<MODE>mode)" "#" "" [(parallel [(set (match_dup 0) (neg:TFIFKF (match_dup 1))) (use (match_dup 2))])] { if (GET_CODE (operands[2]) == SCRATCH) operands[2] = gen_reg_rtx (V16QImode); operands[3] = gen_reg_rtx (V16QImode); emit_insn (gen_altivec_high_bit (operands[2])); } [(set_attr "length" "8") (set_attr "type" "vecsimple")]) (define_insn "*ieee_128bit_vsx_neg<mode>2_internal" [(set (match_operand:TFIFKF 0 "register_operand" "=wa") (neg:TFIFKF (match_operand:TFIFKF 1 "register_operand" "wa"))) (use (match_operand:V16QI 2 "register_operand" "=v"))] "TARGET_FLOAT128" "xxlxor %x0,%x1,%x2" [(set_attr "length" "4") (set_attr "type" "vecsimple")]) -- Michael Meissner, IBM IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797