aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/fe.h1
-rw-r--r--gcc/ada/gcc-interface/decl.c2
-rw-r--r--gcc/ada/gcc-interface/gigi.h5
-rw-r--r--gcc/ada/gcc-interface/targtyps.c10
-rw-r--r--gcc/ada/gcc-interface/trans.c22
-rw-r--r--gcc/ada/gcc-interface/utils.c2
6 files changed, 40 insertions, 2 deletions
diff --git a/gcc/ada/fe.h b/gcc/ada/fe.h
index 520301e..858a28a 100644
--- a/gcc/ada/fe.h
+++ b/gcc/ada/fe.h
@@ -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;
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index d19f5aa..c9c2a95 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -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;
diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h
index e43b3db..355178e 100644
--- a/gcc/ada/gcc-interface/gigi.h
+++ b/gcc/ada/gcc-interface/gigi.h
@@ -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);
diff --git a/gcc/ada/gcc-interface/targtyps.c b/gcc/ada/gcc-interface/targtyps.c
index 9b2d241..60a37e1 100644
--- a/gcc/ada/gcc-interface/targtyps.c
+++ b/gcc/ada/gcc-interface/targtyps.c
@@ -29,6 +29,7 @@
#include "system.h"
#include "coretypes.h"
#include "tm.h"
+#include "target.h"
#include "tree.h"
#include "ada.h"
@@ -95,6 +96,15 @@ get_target_long_long_size (void)
}
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)
{
return POINTER_SIZE;
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 39d4d28..9be1295 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -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)
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 3065fcb..048a0cf 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -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;