-
-
Notifications
You must be signed in to change notification settings - Fork 714
Implement cent/ucent #23575
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
base: master
Are you sure you want to change the base?
Implement cent/ucent #23575
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| Implement the 128-bit integer types `cent` and `ucent` | ||
|
|
||
| The previously reserved 128-bit integer types `cent` and `ucent` are now | ||
| implemented and usable. They behave like the other integer types: | ||
|
|
||
| - 16-byte values with 8-byte alignment, supporting all integer operators: | ||
| arithmetic, bitwise, shifts, comparisons, and compound assignment. | ||
| - Integer literals that do not fit in 64 bits now have type `cent` (or | ||
| `ucent` with a `u` suffix) instead of being an error. | ||
| - Constant folding and compile-time evaluation (CTFE) work with 128-bit | ||
| values, including `enum` constants, `static assert`, and compile-time | ||
| functions. | ||
| - On x86-64, arithmetic is lowered to inline hardware instructions, | ||
| including a single `DIV`/`IDIV` for division by a 64-bit divisor; | ||
| 128/128-bit division and modulo fall back to the existing `core.int128` | ||
| runtime functions. | ||
| - On 32-bit x86, all arithmetic, division and comparisons are lowered to the | ||
| existing `core.int128` runtime functions (the platform has no 128-bit | ||
| registers). This also covers returning 128-bit values from functions, | ||
| conditional expressions, boolean tests, and casts to smaller integer types. | ||
| - The `.min` and `.max` properties and importC's `__int128`/`unsigned __int128` | ||
| are supported. | ||
| - `typeid(cent)` and `typeid(ucent)` are supported; the runtime types | ||
| `TypeInfo_zi`/`TypeInfo_zk` are provided by a rebuilt druntime. | ||
|
|
||
| Conversions between 128-bit integers and floating point types are not yet | ||
| implemented and produce a compile-time error. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
|
|
||
| /* Compiler implementation of the D programming language | ||
| * Copyright (C) 1999-2026 by The D Language Foundation, All Rights Reserved | ||
| * written by Walter Bright | ||
| * https://www.digitalmars.com | ||
| * Distributed under the Boost Software License, Version 1.0. | ||
| * https://www.boost.org/LICENSE_1_0.txt | ||
| * https://github.com/dlang/dmd/blob/master/src/dmd/common/int128.h | ||
| */ | ||
|
|
||
| #pragma once | ||
|
|
||
| #include "dsystem.h" | ||
|
|
||
| // Mirrors dmd.common.int128.Cent | ||
| struct alignas(16) Cent | ||
| { | ||
| uint64_t lo; // low 64 bits | ||
| uint64_t hi; // high 64 bits | ||
| }; | ||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -19,6 +19,7 @@ | |||
| #include "root/complex_t.h" | ||||
| #include "root/dcompat.h" | ||||
| #include "root/optional.h" | ||||
| #include "common/int128.h" | ||||
|
|
||||
| class Type; | ||||
| class TypeVector; | ||||
|
|
@@ -117,6 +118,7 @@ class Expression : public ASTNode | |||
| } | ||||
|
|
||||
| IntegerExp* isIntegerExp(); | ||||
| BigIntegerExp* isBigIntegerExp(); | ||||
| ErrorExp* isErrorExp(); | ||||
| VoidInitExp* isVoidInitExp(); | ||||
| RealExp* isRealExp(); | ||||
|
|
@@ -239,6 +241,16 @@ class IntegerExp final : public Expression | |||
| static IntegerExp literal(); | ||||
| }; | ||||
|
|
||||
| class BigIntegerExp final : public Expression | ||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No to introducing a new integer expression. Instead adapt the existing IntegerExp. 99% of the time it'll still use the fast path and do arithmetic on You can still keep around the helpers like
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have some concerns with that, which is why I did not do it that way.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There'll be no growth in memory. It'll just be extended as needed, we already do this for general arrays. And we can get away with gating on the Type for now when reading the value as it's only cent to support. To future proof for
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've checked dmd/compiler/src/dmd/expression.d Line 129 in 9703ff2
Obviously, just store a
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||
| { | ||||
| public: | ||||
| Cent value; | ||||
|
|
||||
| static BigIntegerExp *create(Loc loc, Cent value, Type *type); | ||||
| void accept(Visitor *v) override { v->visit(this); } | ||||
| BigIntegerExp *syntaxCopy() override { return this; } | ||||
| }; | ||||
|
|
||||
| class ErrorExp final : public Expression | ||||
| { | ||||
| public: | ||||
|
|
||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI this is not common code, so it's location is only a bit odd for that reason alone.
Other backends implement they own versions/library of double-int (and wide-int for N-sized integers), so maybe better to move to root library, along with overloads of all operators.
See longdouble as an example.
Though not really a problem. As downstreams can just move this file (and int128.d) to the bin and implement their own version that wraps their own backend type irrespective of where it is placed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not add dmd.common.int128.
Also, common is just root but with some -betterC stuff, like attributes that were added. It's something that Andrei worked on years ago but didn't get very far with.