[gcc(refs/users/wschmidt/heads/builtins3)] rs6000: Permit "long" for builtins requiring 64 bits

William Schmidt wschmidt@gcc.gnu.org
Thu Oct 29 19:53:28 GMT 2020


https://gcc.gnu.org/g:8cd40d53127f6c8d1e03f9e478ced5312b4cb41a

commit 8cd40d53127f6c8d1e03f9e478ced5312b4cb41a
Author: Bill Schmidt <wschmidt@linux.ibm.com>
Date:   Tue Oct 6 12:13:28 2020 -0500

    rs6000: Permit "long" for builtins requiring 64 bits
    
    2020-10-06  Bill Schmidt  <wschmidt@linux.ibm.com>
    
            * config/rs6000/rs6000-builtin-new.def (__builtin_ppc_mftb): Use
            unsigned long for the return value.
            (__builtin_bpermd): Use signed long for parameters and return
            value.
            * config/rs6000/rs6000-gen-builtins.c (basetype): Add BT_LONG.
            (TYPE_MAP_SIZE): Enlarge.
            (type_map): Add entries for "lg" and "ulg".
            (match_basetype): Support "long" as a base type.
            (complete_base_type): Handle BT_LONG.

Diff:
---
 gcc/config/rs6000/rs6000-builtin-new.def | 10 +++++++--
 gcc/config/rs6000/rs6000-gen-builtins.c  | 35 ++++++++++++++++++++++----------
 2 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def b/gcc/config/rs6000/rs6000-builtin-new.def
index c8195ef7bfe..f9e391964e0 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -181,7 +181,10 @@
   double __builtin_mffs ();
     MFFS rs6000_mffs {}
 
-  unsigned long long __builtin_ppc_mftb ();
+; This one requires special handling at expand time; it should be
+; expanded to rs6000_mftb_di in 64-bit mode, and rs6000_mftb_si in
+; 32-bit mode.  Use of "long" for this builtin is sanctioned.
+  unsigned long __builtin_ppc_mftb ();
     MFTB rs6000_mftb_di {}
 
   void __builtin_mtfsb0 (const int<5>);
@@ -1969,7 +1972,10 @@
   const unsigned int __builtin_addg6s (unsigned int, unsigned int);
     ADDG6S addg6s {}
 
-  const signed long long __builtin_bpermd (signed long long, signed long long);
+; This one requires special handling at expand time; it should be
+; expanded to bperm_di in 64-bit mode and bpermd_si in 32-bit mode.
+; Use of "long" for this builtin is sanctioned.
+  const signed long __builtin_bpermd (signed long, signed long);
     BPERMD bpermd_di {}
 
   const unsigned int __builtin_cbcdtd (unsigned int);
diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c b/gcc/config/rs6000/rs6000-gen-builtins.c
index 7f2e5efb4c3..b745d494b7f 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -270,6 +270,7 @@ enum basetype {
   BT_CHAR,
   BT_SHORT,
   BT_INT,
+  BT_LONG,
   BT_LONGLONG,
   BT_FLOAT,
   BT_DOUBLE,
@@ -441,7 +442,7 @@ struct typemap
    maps tokens from a fntype string to a tree type.  For example,
    in "si_ftype_hi" we would map "si" to "intSI_type_node" and
    map "hi" to "intHI_type_node".  */
-#define TYPE_MAP_SIZE 42
+#define TYPE_MAP_SIZE 44
 static typemap type_map[TYPE_MAP_SIZE] =
   {
     { "bi",	"bool_int" },
@@ -455,6 +456,7 @@ static typemap type_map[TYPE_MAP_SIZE] =
     { "hi",	"intHI" },
     { "if",	"ibm128_float" },
     { "ld",	"long_double" },
+    { "lg",	"long_integer" },
     { "opaque", "opaque_V4SI" },
     { "pcvoid",	"pcvoid" },
     { "pv",	"ptr" },
@@ -467,6 +469,7 @@ static typemap type_map[TYPE_MAP_SIZE] =
     { "ti",	"intTI" },
     { "udi",	"unsigned_intDI" },
     { "uhi",	"unsigned_intHI" },
+    { "ulg",	"long_unsigned" },
     { "uqi",	"unsigned_intQI" },
     { "usi",	"unsigned_intSI" },
     { "uti",	"unsigned_intTI" },
@@ -670,19 +673,26 @@ match_basetype (typeinfo *typedata)
   else if (!strcmp (token, "long"))
     {
       consume_whitespace ();
+      oldpos = pos;
       char *mustbelongordbl = match_identifier ();
-      if (!mustbelongordbl
-	  || (strcmp (mustbelongordbl, "long")
-	      && strcmp (mustbelongordbl, "double")))
-	{
-	  (*diag) ("incomplete 'long long' or 'long double' at column %d\n",
-		   oldpos + 1);
-	  return 0;
-	}
-      if (!strcmp (mustbelongordbl, "long"))
+      /* We rarely permit just "long".  There are a couple of builtins
+	 for which an argument or return type is 32 bits in 32-bit mode
+	 and 64 bits in 64-bit mode.  This is the only time that "long"
+	 should be used instead of "int" or "long long".  */
+      if (!mustbelongordbl)
+	typedata->base = BT_LONG;
+      else if (!strcmp (mustbelongordbl, "long"))
 	typedata->base = BT_LONGLONG;
-      else
+      else if (!strcmp (mustbelongordbl, "double"))
 	typedata->base = BT_LONGDOUBLE;
+      else
+	/* Speculatively accept "long" here and push back the token.
+	   This occurs when "long" is a return type and the next token
+	   is the function name.  */
+	{
+	  typedata->base = BT_LONG;
+	  pos = oldpos;
+	}
     }
   else if (!strcmp (token, "float"))
     typedata->base = BT_FLOAT;
@@ -1432,6 +1442,9 @@ complete_base_type (typeinfo *typeptr, char *buf, int *bufi)
     case BT_INT:
       memcpy (&buf[*bufi], "si", 2);
       break;
+    case BT_LONG:
+      memcpy (&buf[*bufi], "lg", 2);
+      break;
     case BT_LONGLONG:
       memcpy (&buf[*bufi], "di", 2);
       break;


More information about the Gcc-cvs mailing list