public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 1/3]rs6000: update num_insns_constant for 2 insns
@ 2023-10-25  2:00 Jiufu Guo
  2023-10-25  2:00 ` [PATCH 2/3]rs6000: using 'pli' to load 34bit-constant Jiufu Guo
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Jiufu Guo @ 2023-10-25  2:00 UTC (permalink / raw)
  To: gcc-patches; +Cc: segher, dje.gcc, linkw, bergner, guojiufu

Hi,

Trunk gcc supports more constants to be built via two instructions: e.g.
"li/lis; xori/xoris/rldicl/rldicr/rldic".
And then num_insns_constant should also be updated.

Bootstrap & regtest pass ppc64{,le}.
Is this ok for trunk?

BR,
Jeff (Jiufu Guo)

gcc/ChangeLog:

	* config/rs6000/rs6000.cc (can_be_built_by_lilis_and_rldicX): New
	function.
	(num_insns_constant_gpr): Update to return 2 for more cases.
	(rs6000_emit_set_long_const): Update to use
	can_be_built_by_lilis_and_rldicX.

---
 gcc/config/rs6000/rs6000.cc | 64 ++++++++++++++++++++++++-------------
 1 file changed, 41 insertions(+), 23 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index cc24dd5301e..b23ff3d7917 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -6032,6 +6032,9 @@ direct_return (void)
   return 0;
 }
 
+static bool
+can_be_built_by_lilis_and_rldicX (HOST_WIDE_INT, int *, HOST_WIDE_INT *);
+
 /* Helper for num_insns_constant.  Calculate number of instructions to
    load VALUE to a single gpr using combinations of addi, addis, ori,
    oris, sldi and rldimi instructions.  */
@@ -6044,35 +6047,41 @@ num_insns_constant_gpr (HOST_WIDE_INT value)
     return 1;
 
   /* constant loadable with addis */
-  else if ((value & 0xffff) == 0
-	   && (value >> 31 == -1 || value >> 31 == 0))
+  if ((value & 0xffff) == 0 && (value >> 31 == -1 || value >> 31 == 0))
     return 1;
 
   /* PADDI can support up to 34 bit signed integers.  */
-  else if (TARGET_PREFIXED && SIGNED_INTEGER_34BIT_P (value))
+  if (TARGET_PREFIXED && SIGNED_INTEGER_34BIT_P (value))
     return 1;
 
-  else if (TARGET_POWERPC64)
-    {
-      HOST_WIDE_INT low = sext_hwi (value, 32);
-      HOST_WIDE_INT high = value >> 31;
+  if (!TARGET_POWERPC64)
+    return 2;
 
-      if (high == 0 || high == -1)
-	return 2;
+  HOST_WIDE_INT low = sext_hwi (value, 32);
+  HOST_WIDE_INT high = value >> 31;
 
-      high >>= 1;
+  if (high == 0 || high == -1)
+    return 2;
 
-      if (low == 0 || low == high)
-	return num_insns_constant_gpr (high) + 1;
-      else if (high == 0)
-	return num_insns_constant_gpr (low) + 1;
-      else
-	return (num_insns_constant_gpr (high)
-		+ num_insns_constant_gpr (low) + 1);
-    }
+  high >>= 1;
 
-  else
+  HOST_WIDE_INT ud2 = (low >> 16) & 0xffff;
+  HOST_WIDE_INT ud1 = low & 0xffff;
+  if (high == -1 && ((!(ud2 & 0x8000) && ud1 == 0) || (ud1 & 0x8000)))
+    return 2;
+  if (high == 0 && (ud1 == 0 || (!(ud1 & 0x8000))))
     return 2;
+
+  int shift;
+  HOST_WIDE_INT mask;
+  if (can_be_built_by_lilis_and_rldicX (value, &shift, &mask))
+    return 2;
+
+  if (low == 0 || low == high)
+    return num_insns_constant_gpr (high) + 1;
+  if (high == 0)
+    return num_insns_constant_gpr (low) + 1;
+  return (num_insns_constant_gpr (high) + num_insns_constant_gpr (low) + 1);
 }
 
 /* Helper for num_insns_constant.  Allow constants formed by the
@@ -10492,6 +10501,18 @@ can_be_built_by_li_and_rldic (HOST_WIDE_INT c, int *shift, HOST_WIDE_INT *mask)
   return false;
 }
 
+/* Combine the above checking functions for  li/lis;rldicX. */
+
+static bool
+can_be_built_by_lilis_and_rldicX (HOST_WIDE_INT c, int *shift,
+				  HOST_WIDE_INT *mask)
+{
+  return (can_be_built_by_li_lis_and_rotldi (c, shift, mask)
+	  || can_be_built_by_li_lis_and_rldicl (c, shift, mask)
+	  || can_be_built_by_li_lis_and_rldicr (c, shift, mask)
+	  || can_be_built_by_li_and_rldic (c, shift, mask));
+}
+
 /* Subroutine of rs6000_emit_set_const, handling PowerPC64 DImode.
    Output insns to set DEST equal to the constant C as a series of
    lis, ori and shl instructions.  */
@@ -10538,10 +10559,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
       emit_move_insn (dest, gen_rtx_XOR (DImode, temp,
 					 GEN_INT ((ud2 ^ 0xffff) << 16)));
     }
-  else if (can_be_built_by_li_lis_and_rotldi (c, &shift, &mask)
-	   || can_be_built_by_li_lis_and_rldicl (c, &shift, &mask)
-	   || can_be_built_by_li_lis_and_rldicr (c, &shift, &mask)
-	   || can_be_built_by_li_and_rldic (c, &shift, &mask))
+  else if (can_be_built_by_lilis_and_rldicX (c, &shift, &mask))
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
       unsigned HOST_WIDE_INT imm = (c | ~mask);
-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2023-10-25  9:40 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-25  2:00 [PATCH 1/3]rs6000: update num_insns_constant for 2 insns Jiufu Guo
2023-10-25  2:00 ` [PATCH 2/3]rs6000: using 'pli' to load 34bit-constant Jiufu Guo
2023-10-25  2:33   ` Kewen.Lin
2023-10-25  7:37     ` Jiufu Guo
2023-10-25  2:00 ` [PATCH 3/3]rs6000: split complicate constant to constant pool Jiufu Guo
2023-10-25  2:43   ` Kewen.Lin
2023-10-25  8:14     ` Jiufu Guo
2023-10-25  8:29       ` Kewen.Lin
2023-10-25  9:40         ` Jiufu Guo
2023-10-25  2:27 ` [PATCH 1/3]rs6000: update num_insns_constant for 2 insns Kewen.Lin
2023-10-25  7:27   ` Jiufu Guo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).