This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: __builtin_clzll and uintmax_t


Quoting Jakub Jelinek <jakub@redhat.com>:

On Sun, Mar 06, 2011 at 09:56:52AM +0100, Marc Glisse wrote:
>uintmax_t is the largest of the standard unsigned C types, so it cannot be larger than unsigned long long.

That's a gcc property then. The C99 standard only guarantees that
uintmax_t is at least as large as unsigned long long, but it is
allowed to be some other larger type:

Yeah, it could be larger than unsigned long long.
On no target GCC supports currently it is larger than long long though currently.

But it's not too far out that a future target might have that. E.g. if the arc/mxp toolchain was revived, with the 128 bit word with of the mxp, it would be natural to have a named integer type for 128bit. Right now, the branch has 16 bit short, 16 or 32 bit int, 32 bit long, 64 bit long long, and an anonymous 128 bit type to handle words. (The preferred size to compute addresses, loop counters and vectorizable integers is 16 bit.)

Even if the GCC mxp port never gets integrated in mainline, I think
it is likely that in the future, we'll have a GPU port or CPU vector
extension support with an intmax_t type wider than long long.

It is also an ABI issue, you can't change what uintmax_t was
once you use some particular type in an ABI.

As long as you define the libc view of the kernel interface appropriately, you should be able to multilib around this issue.

Bonus points if anyone implements a scheme so that only those object files
for which it matters need to exist in multiple versions.
I.e. if we don't have any function argument / return value, aggregate member,
or debug info involving intmax_t / unitmax_t, we should be able to use the
same object file with code of either intmax_t size.

At any rate, for embedded and/or new targets, ABI churn is often
more acceptable.

What you could do is use __builtin_clzll if sizeof (uintmax_t) == sizeof > (unsigned long long),
for sizeof (uintmax_t) == 2 * sizeof (unsigned long long) perhaps use

int
clzmax (uintmax_t x)
{
...
and give up for other cases.

The main point is to have the code fail to compile if the size is not supported, and implement this abstraction in one place, so handling of new sizes can be added in an efficient manner.

In fact, without the ability to test the 2*long long code, I would
prefer the code to be written so that the compiler will complain initially
when this code is used, so people have to explicitly enable it to be used,
and are thus aware of what might not quite work.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]