Thanks for your comment!
Date: Wed, 30 Nov 2022 12:30:02 +0800
Message-ID: <7ebkopxdx1....@pike.rch.stglabs.ibm.com>

Segher Boessenkool <seg...@kernel.crashing.org> writes:

>> > +  else if ((ud4 == 0xffff && ud3 == 0xffff)
>> > +     && ((ud1 & 0x8000) || (ud1 == 0 && !(ud2 & 0x8000))))
>> > +    {
>> > +      temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
>> > +
>> > +      HOST_WIDE_INT imm = (ud1 & 0x8000) ? ((ud1 ^ 0x8000) - 0x8000)
>> > +                                   : ((ud2 << 16) - 0x80000000);
>
> We really should have some "hwi::sign_extend (ud1, 16)" helper function,
> heh.  Maybe there already is?  Ah, "sext_hwi".  Fixing that up
> everywhere in this function is preapproved.

I drafted a seperate patch for this like below.  Maybe I could update other
code like "((v & 0xf..f) ^ 0x80..0) - 0x80..0" in rs6000.cc and rs6000.md
with sext_hwi too. 

BR,
Jeff (Jiufu)

Below NFC patch just uses sext_hwi to hand expresion like:
(xx ^ 0x80..0) - 0x80..0 in rs6000_emit_set_long_const.

---
 gcc/config/rs6000/rs6000.cc | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 5efe9b22d8b..b03e059222b 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -10242,7 +10242,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
 
   if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
       || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
-    emit_move_insn (dest, GEN_INT ((ud1 ^ 0x8000) - 0x8000));
+    emit_move_insn (dest, GEN_INT (sext_hwi (ud1, 16)));
 
   else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
           || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
@@ -10250,7 +10250,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
 
       emit_move_insn (ud1 != 0 ? copy_rtx (temp) : dest,
-                     GEN_INT (((ud2 << 16) ^ 0x80000000) - 0x80000000));
+                     GEN_INT (sext_hwi (ud2 << 16, 32)));
       if (ud1 != 0)
        emit_move_insn (dest,
                        gen_rtx_IOR (DImode, copy_rtx (temp),
@@ -10261,8 +10261,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
 
       gcc_assert (ud2 & 0x8000);
-      emit_move_insn (copy_rtx (temp),
-                     GEN_INT (((ud2 << 16) ^ 0x80000000) - 0x80000000));
+      emit_move_insn (copy_rtx (temp), GEN_INT (sext_hwi (ud2 << 16, 32)));
       if (ud1 != 0)
        emit_move_insn (copy_rtx (temp),
                        gen_rtx_IOR (DImode, copy_rtx (temp),
@@ -10273,7 +10272,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
       HOST_WIDE_INT num = (ud2 << 16) | ud1;
-      rs6000_emit_set_long_const (temp, (num ^ 0x80000000) - 0x80000000);
+      rs6000_emit_set_long_const (temp, sext_hwi (num, 32));
       rtx one = gen_rtx_AND (DImode, temp, GEN_INT (0xffffffff));
       rtx two = gen_rtx_ASHIFT (DImode, temp, GEN_INT (32));
       emit_move_insn (dest, gen_rtx_IOR (DImode, one, two));
@@ -10283,8 +10282,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
 
-      emit_move_insn (copy_rtx (temp),
-                     GEN_INT (((ud3 << 16) ^ 0x80000000) - 0x80000000));
+      emit_move_insn (copy_rtx (temp), GEN_INT (sext_hwi (ud3 << 16, 32)));
       if (ud2 != 0)
        emit_move_insn (copy_rtx (temp),
                        gen_rtx_IOR (DImode, copy_rtx (temp),
@@ -10336,8 +10334,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
 
-      emit_move_insn (copy_rtx (temp),
-                     GEN_INT (((ud4 << 16) ^ 0x80000000) - 0x80000000));
+      emit_move_insn (copy_rtx (temp), GEN_INT (sext_hwi (ud4 << 16, 32)));
       if (ud3 != 0)
        emit_move_insn (copy_rtx (temp),
                        gen_rtx_IOR (DImode, copy_rtx (temp),
-- 
2.17.1

>
>> > +      else
>> > +  {
>> > +    emit_move_insn (temp,
>> > +                    GEN_INT (((ud2 << 16) ^ 0x80000000) - 0x80000000));
>> > +    if (ud1 != 0)
>> > +      emit_move_insn (temp, gen_rtx_IOR (DImode, temp, GEN_INT (ud1)));
>> > +    emit_move_insn (dest,
>> > +                    gen_rtx_ZERO_EXTEND (DImode,
>> > +                                         gen_lowpart (SImode, temp)));
>> > +  }
>
> Why this?  Please just write it in DImode, do not go via SImode?
>
>> > --- /dev/null
>> > +++ b/gcc/testsuite/gcc.target/powerpc/pr106708.h
>> > @@ -0,0 +1,9 @@
>> > +/* Test constants which can be built by li/lis + oris/xoris */
>> > +void  __attribute__ ((__noinline__, __noclone__)) foo (long long *arg)
>> > +{
>> > +  *arg++ = 0x98765432ULL;
>> > +  *arg++ = 0xffffffff7cdeab55ULL;
>> > +  *arg++ = 0xffffffff65430000ULL;
>> > +}
>
> Use noipa please (it is shorter, simpler, and covers more :-) )
>
> Could you comment what exact instructions are expected?
> li;xoris and li;xoris and lis;xoris I guess?  It helps if you just tell
> the reader here.
>
> The li;oris and li;xoris parts look good.
>
>
> Segher

Reply via email to