aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/config/i386/i386.cc1
-rw-r--r--gcc/doc/tm.texi4
-rw-r--r--gcc/gimple-fold.cc5
-rw-r--r--gcc/stor-layout.cc9
-rw-r--r--gcc/target.def4
-rw-r--r--gcc/target.h16
-rw-r--r--gcc/varasm.cc3
7 files changed, 29 insertions, 13 deletions
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 3e78949..0bba93f 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -25679,6 +25679,7 @@ ix86_bitint_type_info (int n, struct bitint_info *info)
info->limb_mode = SImode;
else
info->limb_mode = DImode;
+ info->abi_limb_mode = info->limb_mode;
info->big_endian = false;
info->extended = false;
return true;
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 768ada0a..0bb6da0 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -1032,8 +1032,8 @@ applied.
@deftypefn {Target Hook} bool TARGET_C_BITINT_TYPE_INFO (int @var{n}, struct bitint_info *@var{info})
This target hook returns true if @code{_BitInt(@var{N})} is supported and
provides details on it. @code{_BitInt(@var{N})} is to be represented as
-series of @code{info->limb_mode}
-@code{CEIL (@var{N}, GET_MODE_PRECISION (info->limb_mode))} limbs,
+series of @code{info->abi_limb_mode}
+@code{CEIL (@var{N}, GET_MODE_PRECISION (info->abi_limb_mode))} limbs,
ordered from least significant to most significant if
@code{!info->big_endian}, otherwise from most significant to least
significant. If @code{info->extended} is false, the bits above or equal to
diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index a5be2ee..cb4b572 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -4604,7 +4604,7 @@ clear_padding_bitint_needs_padding_p (tree type)
gcc_assert (ok);
if (info.extended)
return false;
- scalar_int_mode limb_mode = as_a <scalar_int_mode> (info.limb_mode);
+ scalar_int_mode limb_mode = as_a <scalar_int_mode> (info.abi_limb_mode);
if (TYPE_PRECISION (type) < GET_MODE_PRECISION (limb_mode))
return true;
else if (TYPE_PRECISION (type) == GET_MODE_PRECISION (limb_mode))
@@ -4881,7 +4881,8 @@ clear_padding_type (clear_padding_struct *buf, tree type,
struct bitint_info info;
bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
gcc_assert (ok);
- scalar_int_mode limb_mode = as_a <scalar_int_mode> (info.limb_mode);
+ scalar_int_mode limb_mode
+ = as_a <scalar_int_mode> (info.abi_limb_mode);
if (TYPE_PRECISION (type) <= GET_MODE_PRECISION (limb_mode))
{
gcc_assert ((size_t) sz <= clear_padding_unit);
diff --git a/gcc/stor-layout.cc b/gcc/stor-layout.cc
index ba375fa..0c095aa 100644
--- a/gcc/stor-layout.cc
+++ b/gcc/stor-layout.cc
@@ -2154,7 +2154,8 @@ finish_bitfield_representative (tree repr, tree field)
unsigned prec = TYPE_PRECISION (TREE_TYPE (field));
bool ok = targetm.c.bitint_type_info (prec, &info);
gcc_assert (ok);
- scalar_int_mode limb_mode = as_a <scalar_int_mode> (info.limb_mode);
+ scalar_int_mode limb_mode
+ = as_a <scalar_int_mode> (info.abi_limb_mode);
unsigned lprec = GET_MODE_PRECISION (limb_mode);
if (prec > lprec)
{
@@ -2416,16 +2417,20 @@ layout_type (tree type)
int cnt;
bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
gcc_assert (ok);
- scalar_int_mode limb_mode = as_a <scalar_int_mode> (info.limb_mode);
+ scalar_int_mode limb_mode
+ = as_a <scalar_int_mode> (info.abi_limb_mode);
if (TYPE_PRECISION (type) <= GET_MODE_PRECISION (limb_mode))
{
SET_TYPE_MODE (type, limb_mode);
+ gcc_assert (info.abi_limb_mode == info.limb_mode);
cnt = 1;
}
else
{
SET_TYPE_MODE (type, BLKmode);
cnt = CEIL (TYPE_PRECISION (type), GET_MODE_PRECISION (limb_mode));
+ gcc_assert (info.abi_limb_mode == info.limb_mode
+ || !info.big_endian == !WORDS_BIG_ENDIAN);
}
TYPE_SIZE (type) = bitsize_int (cnt * GET_MODE_BITSIZE (limb_mode));
TYPE_SIZE_UNIT (type) = size_int (cnt * GET_MODE_SIZE (limb_mode));
diff --git a/gcc/target.def b/gcc/target.def
index 08218f3..ca030ab 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -6357,8 +6357,8 @@ DEFHOOK
(bitint_type_info,
"This target hook returns true if @code{_BitInt(@var{N})} is supported and\n\
provides details on it. @code{_BitInt(@var{N})} is to be represented as\n\
-series of @code{info->limb_mode}\n\
-@code{CEIL (@var{N}, GET_MODE_PRECISION (info->limb_mode))} limbs,\n\
+series of @code{info->abi_limb_mode}\n\
+@code{CEIL (@var{N}, GET_MODE_PRECISION (info->abi_limb_mode))} limbs,\n\
ordered from least significant to most significant if\n\
@code{!info->big_endian}, otherwise from most significant to least\n\
significant. If @code{info->extended} is false, the bits above or equal to\n\
diff --git a/gcc/target.h b/gcc/target.h
index a055b25..53f03b3 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -69,15 +69,23 @@ union cumulative_args_t { void *p; };
#endif /* !CHECKING_P */
/* Target properties of _BitInt(N) type. _BitInt(N) is to be represented
- as series of limb_mode CEIL (N, GET_MODE_PRECISION (limb_mode)) limbs,
- ordered from least significant to most significant if !big_endian,
+ as series of abi_limb_mode CEIL (N, GET_MODE_PRECISION (abi_limb_mode))
+ limbs, ordered from least significant to most significant if !big_endian,
otherwise from most significant to least significant. If extended is
false, the bits above or equal to N are undefined when stored in a register
or memory, otherwise they are zero or sign extended depending on if
- it is unsigned _BitInt(N) or _BitInt(N) / signed _BitInt(N). */
+ it is unsigned _BitInt(N) or _BitInt(N) / signed _BitInt(N).
+ limb_mode is either the same as abi_limb_mode, or some narrower mode
+ in which _BitInt lowering should actually perform operations in and
+ what libgcc _BitInt helpers should use.
+ E.g. abi_limb_mode could be TImode which is something some processor
+ specific ABI would specify to use, but it would be desirable to handle
+ it as an array of DImode instead for efficiency.
+ Note, abi_limb_mode can be different from limb_mode only if big_endian
+ matches WORDS_BIG_ENDIAN. */
struct bitint_info {
- machine_mode limb_mode;
+ machine_mode abi_limb_mode, limb_mode;
bool big_endian;
bool extended;
};
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 167aea8..69f8f8e 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -5315,7 +5315,8 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align,
tree type = TREE_TYPE (exp);
bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
gcc_assert (ok);
- scalar_int_mode limb_mode = as_a <scalar_int_mode> (info.limb_mode);
+ scalar_int_mode limb_mode
+ = as_a <scalar_int_mode> (info.abi_limb_mode);
if (TYPE_PRECISION (type) <= GET_MODE_PRECISION (limb_mode))
{
cst = expand_expr (exp, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);