Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define _BitInt ABI #300

Open
jsm28 opened this issue Jul 19, 2022 · 6 comments · May be fixed by #419
Open

Define _BitInt ABI #300

jsm28 opened this issue Jul 19, 2022 · 6 comments · May be fixed by #419
Milestone

Comments

@jsm28
Copy link

jsm28 commented Jul 19, 2022

C23 (current draft: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2912.pdf ) defines "bit-precise integer types": types _BitInt(N) and unsigned _BitInt(N) with a given width. The RISC-V ABI needs to define the ABI for these types; see the x86_64 ABI https://gitlab.com/x86-psABIs/x86-64-ABI for an example.

This means specifying the size, alignment and representation for objects of those types (including whether there are any requirements on the values of padding bits in the in-memory representation), and the interface for argument passing and return (including, again, any requirements on padding bits - both padding bits up to the size of an object of that type, and any further padding beyond that within the size of a register or stack slot used for argument passing or return).

@kito-cheng kito-cheng added this to the Post 1.0 milestone Jul 21, 2022
@kito-cheng
Copy link
Collaborator

Thanks for remind that! we will take a look after 1.0 release!

@kito-cheng
Copy link
Collaborator

kito-cheng commented Jul 25, 2022

Notes for x86-64 ABI and current implementation status for open source toolchain:

x86-64 ABI for _BitInt:

  • For N <= 64, they have the same size and alignment as the smallest of (signed and unsigned) char, short, int, long and long long types that can contain them.
  • For N > 64, they are treated as struct of 64-bit integer chunks. The number of chunks is the smallest number that can contain the type. _BitInt(N) types are byte-aligned to the next greatest power-of-2 up to 64 bits. The size of these types is the smallest multiple of the 64-bit chunks greater than or equal to N. The value of the unused bits beyond the width of the _BitInt(N) value but within the size of the _BitInt(N) are unspecified when stored in memory or register.

NOTE: Added by this commit

Implementation status for open source toolchain

  • clang/LLVM: Done.
  • gcc: Not yet.

@cmuellner
Copy link
Collaborator

Some more context:

  • LLVM had _ExtInt(N) before, so they could implement this feature using #define _BitInt(N) _ExtInt(N)
  • The language standardization group adopted this feature under the name _BitInt(N) with N being an integral constant expression
  • I could not see any patches for _BitInt(N) targeting GCC so far

Further links:

@workingjubilee
Copy link

Hello,

I am raising the concern that I had with the System V x86-64 psABI specification here, in advance of this being specified at all. Namely: on a platform that has already specified __int128 with a 16-byte alignment, defining a _BitInt(N) with between 65 and 128 bits as being aligned to less than 16 bytes can have awkward results. It could significantly complicate inter-language compatibility for otherwise fairly easy-to-handle psABIs for those languages which use the system ABI (and thus the "C ABI") for parameter passing and argument return in order to translate between each other, as it creates two distinct types that nonetheless both believe they are handled as a "128-bit integer", yet have different alignments and thus different nuances, especially in stack passing.

Obviously, this concern mostly applies to the RV64-related ABIs, but to them it applies especially so, on account of the question of stack alignment. I merely took an initial reading and I am not sure I fully and correctly have calculated the cases where this will actually cause a concern for the LP64D ABI's parameter passing algorithm, so it is possible this is not a real issue for arguments, even for a very large set of function parameters. However, it still seems like it would be awkward for programmers if pointers to _BitInt(65-128) on RV64 are under-aligned for various type puns and the like.

@pinskia
Copy link

pinskia commented Jan 5, 2024

Any news on this. It would be useful to get an ABI defined soon on this and then support for _BitInt can be added to GCC.

@kito-cheng
Copy link
Collaborator

@pinskia thanks for the reminder, will post draft proposal soon :)

kito-cheng added a commit that referenced this issue Jan 5, 2024
`_BitInt (N)` is the type defined in C23, allow user to define an
arbitrary-sized integer type, where N is a postive integer larger than zero.

This proposal defined the size and alignment of _BitInt, and define the
unused bits as unspecified which is same as x86-64 and AArch64.

For the calling convention part, we keep unused bits as unspecified.

Ref:

- ISO/IEC WG14 N2763:
  https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2763.pdf

- [AArch64] Rationale Document for ABI related to the C23 _BitInt type.
  https://github.com/ARM-software/abi-aa/tree/main/design-documents/bit-precise-types.rst

- AAPCS64 for _BitInt(N)
  ARM-software/abi-aa@d621417

- x86-64 ABI for _BitInt(N)
  https://gitlab.com/x86-psABIs/x86-64-ABI/-/commit/8ca45392570e96920f8a15d903d6122f6d263cd0

Fix #300
@kito-cheng kito-cheng linked a pull request Jan 5, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants