Add preliminary support for 128-bit integer types
authorEric Botcazou <ebotcazou@adacore.com>
Sat, 12 Sep 2020 10:59:09 +0000 (12:59 +0200)
committerEric Botcazou <ebotcazou@adacore.com>
Sat, 12 Sep 2020 11:01:19 +0000 (13:01 +0200)
This is only the gigi part, in preparation for the bulk of the
implementation.

gcc/ada/ChangeLog:
* fe.h: Fix pilot error in previous change.
* gcc-interface/gigi.h (enum standard_datatypes): Add ADT_mulv128_decl.
(mulv128_decl): New macro.
(get_target_long_long_long_size): Declare.
* gcc-interface/decl.c (gnat_to_gnu_entity): Use a maximum size of
128 bits for discrete types if Enable_128bit_Types is true.
* gcc-interface/targtyps.c: Include target.h.
(get_target_long_long_long_size): New function.
* gcc-interface/trans.c (gigi): Initialize mulv128_decl if need be.
(build_binary_op_trapv): Call it for 128-bit multiplication.
* gcc-interface/utils.c (make_type_from_size): Enforce a maximum
size of 128 bits if Enable_128bit_Types is true.

gcc/ada/fe.h
gcc/ada/gcc-interface/decl.c
gcc/ada/gcc-interface/gigi.h
gcc/ada/gcc-interface/targtyps.c
gcc/ada/gcc-interface/trans.c
gcc/ada/gcc-interface/utils.c

index 520301e4c3e9a05875b92161c5bf793ae214fb8f..858a28acb8e05f47fa25d05639498c9b18bf89e6 100644 (file)
@@ -213,6 +213,7 @@ typedef enum {
 extern Ada_Version_Type Ada_Version;
 extern Boolean Back_End_Inlining;
 extern Boolean Debug_Generated_Code;
+extern Boolean Enable_128bit_Types;
 extern Boolean Exception_Extra_Info;
 extern Boolean Exception_Locations_Suppressed;
 extern Exception_Mechanism_Type Exception_Mechanism;
index d19f5aac81f9826ccac9f44888e780e760f06743..c9c2a95170f36c8d1fc0fd00c0b074b8ed02bb89 100644 (file)
@@ -524,7 +524,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
          else if (IN (kind, Access_Kind))
            max_esize = POINTER_SIZE * 2;
          else
-           max_esize = LONG_LONG_TYPE_SIZE;
+           max_esize = Enable_128bit_Types ? 128 : LONG_LONG_TYPE_SIZE;
 
          if (esize > max_esize)
           esize = max_esize;
index e43b3db59a992de7fc5e313182aaeaa44a8f2a0f..355178e284f2273f896d48470ccce7e3cf05fa2c 100644 (file)
@@ -390,6 +390,9 @@ enum standard_datatypes
   /* Function decl node for 64-bit multiplication with overflow checking.  */
   ADT_mulv64_decl,
 
+  /* Function decl node for 128-bit multiplication with overflow checking.  */
+  ADT_mulv128_decl,
+
   /* Identifier for the name of the _Parent field in tagged record types.  */
   ADT_parent_name_id,
 
@@ -462,6 +465,7 @@ extern GTY(()) tree gnat_raise_decls_ext[(int) LAST_REASON_CODE + 1];
 #define free_decl gnat_std_decls[(int) ADT_free_decl]
 #define realloc_decl gnat_std_decls[(int) ADT_realloc_decl]
 #define mulv64_decl gnat_std_decls[(int) ADT_mulv64_decl]
+#define mulv128_decl gnat_std_decls[(int) ADT_mulv128_decl]
 #define parent_name_id gnat_std_decls[(int) ADT_parent_name_id]
 #define exception_data_name_id gnat_std_decls[(int) ADT_exception_data_name_id]
 #define jmpbuf_type gnat_std_decls[(int) ADT_jmpbuf_type]
@@ -1035,6 +1039,7 @@ extern Pos get_target_short_size (void);
 extern Pos get_target_int_size (void);
 extern Pos get_target_long_size (void);
 extern Pos get_target_long_long_size (void);
+extern Pos get_target_long_long_long_size (void);
 extern Pos get_target_pointer_size (void);
 extern Pos get_target_maximum_default_alignment (void);
 extern Pos get_target_system_allocator_alignment (void);
index 9b2d24146a18e44a5e9ebeaffe5fe01465aa067a..60a37e1463b9021bd01c89f1573e6f8616581646 100644 (file)
@@ -29,6 +29,7 @@
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
+#include "target.h"
 #include "tree.h"
 
 #include "ada.h"
@@ -94,6 +95,15 @@ get_target_long_long_size (void)
   return LONG_LONG_TYPE_SIZE;
 }
 
+Pos
+get_target_long_long_long_size (void)
+{
+  if (targetm.scalar_mode_supported_p (TImode))
+    return GET_MODE_BITSIZE (TImode);
+  else
+    return LONG_LONG_TYPE_SIZE;
+}
+
 Pos
 get_target_pointer_size (void)
 {
index 39d4d28fa67ba8c522cba3607b291697e07ff663..9be12952c5bf7ce9c4bae39481493022dd1b0be6 100644 (file)
@@ -439,6 +439,19 @@ gigi (Node_Id gnat_root,
                           NULL_TREE, is_default, true, true, true, false,
                           false, NULL, Empty);
 
+  if (Enable_128bit_Types)
+    {
+      tree int128_type = gnat_type_for_size (128, 0);
+      mulv128_decl
+       = create_subprog_decl (get_identifier ("__gnat_mulv128"), NULL_TREE,
+                              build_function_type_list (int128_type,
+                                                        int128_type,
+                                                        int128_type,
+                                                        NULL_TREE),
+                              NULL_TREE, is_default, true, true, true, false,
+                              false, NULL, Empty);
+    }
+
   /* Name of the _Parent field in tagged record types.  */
   parent_name_id = get_identifier (Get_Name_String (Name_uParent));
 
@@ -9388,6 +9401,15 @@ build_binary_op_trapv (enum tree_code code, tree gnu_type, tree left,
                                                       convert (int64, rhs)));
        }
 
+      /* Likewise for a 128-bit mult and a 64-bit target.  */
+      else if (code == MULT_EXPR && precision == 128 && BITS_PER_WORD < 128)
+       {
+         tree int128 = gnat_type_for_size (128, 0);
+         return convert (gnu_type, build_call_n_expr (mulv128_decl, 2,
+                                                      convert (int128, lhs),
+                                                      convert (int128, rhs)));
+       }
+
       enum internal_fn icode;
 
       switch (code)
index 3065fcb6260d26fb489eaf11fe15cd9f960f5e6e..048a0cf13b44dc13bc81f6302f61a192c50f25b4 100644 (file)
@@ -1343,7 +1343,7 @@ make_type_from_size (tree type, tree size_tree, bool for_biased)
         not already have the proper size and the size is not too large.  */
       if (BIT_PACKED_ARRAY_TYPE_P (type)
          || (TYPE_PRECISION (type) == size && biased_p == for_biased)
-         || size > LONG_LONG_TYPE_SIZE)
+         || size > (Enable_128bit_Types ? 128 : LONG_LONG_TYPE_SIZE))
        break;
 
       biased_p |= for_biased;