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