This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH], PowerPC IEEE 128-bit patch #4


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: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]