This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH], PowerPC IEEE 128-bit patch #4
- From: Michael Meissner <meissner at linux dot vnet dot ibm dot com>
- To: Segher Boessenkool <segher at kernel dot crashing dot org>
- Cc: Michael Meissner <meissner at linux dot vnet dot ibm dot com>, gcc-patches at gcc dot gnu dot org, dje dot gcc at gmail dot com
- Date: Wed, 29 Jul 2015 18:38:45 -0400
- Subject: Re: [PATCH], PowerPC IEEE 128-bit patch #4
- Authentication-results: sourceware.org; auth=none
- References: <20150729200428 dot GA30347 at ibm-tiger dot the-meissners dot org> <20150729215923 dot GM28839 at gate dot crashing dot org>
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