Define the __int128 type as an integer with an alignment of 16, which is
always passed and returned in memory. An alignment of 16 is consistent
with __float128 and __m128, LLVM's i128, and __int128 on x86-64. The
in-memory endian description is consistent with the x86-64 ABI.
---
Various other languages already provide a 128-bit integer type on 32-bit
platforms (e.g. Rust, Swift, Zig, all via LLVM), so it seems reasonable to
codeify an interface here and allow C to use it as well. This is a useful
type to have anyway, a same-sized integer is helpful in soft float libraries
supporting the already-specified __float128.
I picked 16 as the alignment for the consistency reasons described in
the commit message, but I don't think any reason listed there is overly
strong. It seems a bit unusual to jump from 4 (`long long`) directly to 16
(__int128), though the same is done for double -> __float128.
Any thoughts?
Best,
Trevor
P.S. H.J.,
https://gitlab.com/x86-psABIs/i386-ABI shows hjl/master by
default, which looks to be the x86-64 ABI. It appears hjl/x86/master is
the latest x86-32 ABI; would you be able to change the default branch?
[^1]: Note that LLVM reports i128 is 16-byte aligned but does not pass
the type on the stack with this alignment, which would mean an ABI
bug against the change as described here. __float128 has the same
behavior, however, this is a known bug and GCC incompatibility.
low-level-sys-info.tex | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/low-level-sys-info.tex b/low-level-sys-info.tex
index 09ad7f6..5b2d614 100644
--- a/low-level-sys-info.tex
+++ b/low-level-sys-info.tex
@@ -30,9 +30,9 @@ object, and the term \emph{\textindex{\sixteenbyte{}}} refers to a
\subsubsection{Fundamental Types}
Table~\ref{basic-types} shows the correspondence between ISO C
-scalar types and the processor scalar types. \code{_Float16},
-\code{__float80},
-\code{__float128}, \code{__m64}, \code{__m128}, \code{__m256} and
+scalar types and the processor scalar types. \code{__int128},
+\code{_Float16}, \code{__float80}, \code{__float128},
+\code{__m64}, \code{__m128}, \code{__m256} and
\code{__m512} types are optional.
\begin{table}
@@ -75,6 +75,11 @@ scalar types and the processor scalar types. \code{_Float16},
\cline{2-5}
& \texttt{unsigned long long} & 8 & 4 & unsigned \eightbyte \\
\cline{2-5}
+ & \texttt{__int128}$^{\dagger\dagger}$ & 16 & 16 & signed \sixteenbyte \\
+ & \texttt{signed __int128}$^{\dagger\dagger}$ & 16 & 16 & signed \sixteenbyte \\
+ \cline{2-5}
+ & \texttt{unsigned __int128}$^{\dagger\dagger}$ & 16 & 16 & unsigned \sixteenbyte \\
+ \cline{2-5}
\hline
Pointer
& \texttt{\textit{any-type} *} & 4 & 4 & unsigned \fourbyte \\
@@ -146,7 +151,11 @@ bias of 16383.\footnote{Initial implementations of the \xARCH
The 80-bit floating-point type uses a 15 bit exponent, a 64-bit mantissa
with an explicit high order significant bit and an exponent bias of
16383.\footnote{This type is the x87 double extended precision data
- type.}
+ type.}
+
+The \code{__int128} type is stored in little-endian order in memory,
+i.e., the 64 low-order bits are stored at a a lower address than the
+64 high-order bits.
The value of \code{_Alignof(max_align_t)} is 16.
@@ -439,6 +448,10 @@ and \texttt{unions}) are always returned in memory.
& \texttt{unsigned long long} & significant 32 bits are returned in
\EAX. \\
\cline{2-3}
+ & \texttt{__int128} & memory \\
+ & \texttt{signed __int128} & \\
+ & \texttt{unsigned __int128} & \\
+ \cline{2-3}
\hline
Pointer
& \texttt{\textit{any-type} *} & \EAX \\
--
2.39.5 (Apple Git-154)