128 bit integers is on topic

S

Seebs

int128_t should be a typedef, defined in <stdint.h> and <inttypes.h>.
Which implies that there needs to be another name for the typedef
declaration to use, perhaps something like __int128. It would
be stupid^H^H^H^H^H^H unwise to declare the name "int128_t" in,
say, <int128.h>, since it would conflict with the declaration in
<stdint.h> and <inttypes.h>.

Not necessarily -- you could just have all three refer to a single shared
file which provides the declaration and is idempotent. Sort of like how
many headers define NULL.

-s
 
K

Keith Thompson

Seebs said:
Not necessarily -- you could just have all three refer to a single shared
file which provides the declaration and is idempotent. Sort of like how
many headers define NULL.

Yes, you're right.
 
B

BGB / cr88192

jacob navia said:
BGB / cr88192 a écrit :


That's why I was forced to rewrite printf.

ok.



Sure, writing the runtime is a big mess. It is very difficult to do.

I once wrote a C runtime, but this was for a standalone OS, and the result
was very buggy...

Very easy. You need just to change the linker, and put your static
library before the import library of crtdll.dll Then you rewrite only
the functions you need to replace.

this (simple patching), however, would be very problematic to do on a
project-wide scale, where each component is built independently (its own
Makefiles, ...), and where the project is built of many separate DLL's...

to be made to work, this patch library would need to be specifically
referred to almost everywhere.


for a name-mangled scheme, it is a lot less of a mess, since then one only
needs to modify the name resolution, AKA, to search for the mangled name
prior to the actual name.


granted, it is still a little bit of a hack, and there are special cases in
my framework where this behavior would need to be inverted (namely, in cases
where "proxying" is used, yet the 'proxy' should still resolve to the
mangled version before the actual version).


add, may add support for a 'version' as well,
"BSRT1__printf"
"BSRT2__printf"

which would mostly effect resolution order (higher numbers checked before
lower ones).

I will probably add the hack to the OS-level resolver, essentially avoiding
most of the issues by pretenting that it is the DLL subsystem doing this
hackery (it would then be largely invisible within the framework's dynamic
linker).

Well, in 32 bits you have to generate a function call anyway, so it
doesn't
make any difference. In 64 bits there are no function calls and the
code can be generated directly.

granted, I often do this already.

however, the "function calls" in 32 bit mode (and for relevant operations in
64 bit mode, such as division), are not ordinary functions, but rather are
specialized ASM helpers (typically, using very specialized calling
conventions, and usually with a rule of being "register opaque").


the cost though, is in cases where these sorts of helpers actually need to
make a general-purpose function call, which essentially forces them to save
and restore any registers which may be potentially modified by the call
(essentially, all the caller save registers...).

this case is not an issue for my arithmetic helpers (which are
self-contained), but may be an issue for my OO and TLS helpers (the former
of which have been 'helped' by passing in a partial register-allocator
state, allowing them to know which registers they don't need to save).

[snip]
originally, I passed them directly on the stack in Win64, but then
discovered that this was apparently incorrect, and these issues have been
internally addressed via kludges (something I call "vrefs" or "virtual
references", which are like a C++ references, only added silently by the
compiler to gloss over the calling convention...).

Well, this is easy... You just copy the object in the stack and pass
a pointer to that stack area in some register. Note that you should copy
since C passes by value!

I am dealing with the Win64 calling convention, which apparently passes
structs by reference.
the only thing then present in the passed arguments is, then, the pointer.

the hack is then partially, that I have to allocate a "tvar" (temporary
variable), to hold the value of the passed struct (or XMM register, ...),
and then the 'value' is replaced implicitly by a 'vref to the value'.

sadly, my compiler is currently too stupid to know how to properly free the
tvar afterwards, but oh well... (this could waste a lot of stack space for a
single function containing a large number of calls directly passing structs
or SIMD types).

struct foo {int a,b,c,d;};
struct foo Foo;

void fn(struct foo f);

fn(Foo);

Here fn should work with a COPY of the structure Foo.

theoretically, yes, but AFAICT Win64 does not do it this way, instead,
leaving the memory for the struct in the caller (in a temporary piece of
memory), and modifying it in-place (rather than, say, making a local copy in
the callee).

so, if you pass Foo, the caller will make a copy of the struct, and pass the
pointer to this copy, and the callee will modify the struct as-given (so, if
directly passes a pointer to Foo, one is liable to get their struct
thrashed?...).

(intuitively, I would think instead the callee 'should' make the copy, vs
the caller, but oh well...).


I have not fully investigated the matter (such as whether or not this is a
defined, or at least 'safe', practice), but this seems to be the practice...

this is in contrast to Win32 + cdecl, which passes the entire structure
directly on the stack (vs a pointer).


note that I have also seen MSVC moving memory around via 'rep movsb' when
clearly 'movaps' would be safe, and a much faster alternative (I don't
personally give MSVC's optimizer much credit after seeing a lot of the code
it spews out, or at least for x64...).
 
G

Guest

| This doesn't really address your statement, but how often would 128 bit
| int's be used anyways? How common is the case where 64 bit int's would be
| insufficient, but 128 bits be enough? I suppose it would make keeping a
| bitmap of between 65 and 128 bits more convienent, but other than that (at
| least for everything else I can think of) if 64 bit int's aren't enough,
| then you really need true Bignum's, or at least integers which are
| significantly larger (256+ bits).

I could actually use them now for a broadly uniform single time type that
can represent both high resolutions in today's time frame where that can
be needed, as well as represent times from the big bang to the big crunch.
I can do that now with two different types, one to solve the resolution
issue, and the other to solve the range issue. I'd prefer to have a single
type to do that.
 
T

Tim Rentsch

Keith Thompson said:
Seebs said:
I don't think the name changes whether or not the type is an
integral type. If there IS a 128-bit integral type, defined in
<stdint.h>, then it should be int128_t and so on... But I don't see
anything prohibiting you from having something that isn't quite a
fully implemented 128-bit integral type, and naming it int128_t, as
long as it's in some non-standard header.
[...]

Integer types aren't *defined* in <stdint.h>. Generally they're
defined by the core language or, in the case of extended types, by
the implementation. <stdint.h> merely defines typedefs (aliases)
for existing integer types.

In this case, the compiler could predefine __int128, and
(eventually) <stdint.h> could declare
typedef int128_t __int128;
typedef int_least128_t __int128;
typedef int_fast128_t __int128;
typedef intmax_t __int128;
and likewise for __uint128. [...]

Of course you meant these typedef lines to be written
in the other order.
 
K

Keith Thompson

Tim Rentsch said:
In this case, the compiler could predefine __int128, and
(eventually) <stdint.h> could declare
typedef int128_t __int128;
typedef int_least128_t __int128;
typedef int_fast128_t __int128;
typedef intmax_t __int128;
and likewise for __uint128. [...]

Of course you meant these typedef lines to be written
in the other order.

Yeah, thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top