Bug 20991 - [meta] __int128 type support
Summary: [meta] __int128 type support
Status: NEW
Alias: None
Product: gdb
Classification: Unclassified
Component: exp (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on: 28127 30189 30191 33123 16225 19423 21185 30188 30190 33366
Blocks:
  Show dependency treegraph
 
Reported: 2016-12-22 21:52 UTC by Tom Tromey
Modified: 2025-09-13 15:06 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
Project(s) to access:
ssh public key:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tom Tromey 2016-12-22 21:52:25 UTC
I tried a couple experiments with __int128 and found some gdb issues.

My test code:

__int128 x = 72;

I compiled with -g -c then ran gdb on the .o.

Printing kind of works, but chooses hex by default and zero-pads:

(gdb) p x
$1 = 0x00000000000000000000000000000048

Specifying decimal still zero-pads, which looks very weird:

(gdb) p/d x
$2 = 00000000000000000000000000000072

Addition doesn't work:

(gdb) p x + 5
That operation is not available on integers of more than 8 bytes.
Comment 1 Tom Tromey 2017-02-21 22:19:47 UTC
One super intrusive option would be to use GMP everywhere.

Another possibility would be to redefine LONGEST as __int128
where available.
Comment 2 Tom Tromey 2017-06-02 19:22:42 UTC
Handling the printing in bug 16225, so maybe this bug could be
for the operations.  See some discussion in bug 21185 for how to do that.
Comment 3 Tom Tromey 2018-04-30 16:32:55 UTC
Another issue is that c-exp.y has productions for things like
"unsigned long" and "long unsigned" -- but there isn't one for
__int128.  This came up during the alignment patch.
Comment 4 Hannes Domani 2020-04-10 00:21:30 UTC
(In reply to Tom Tromey from comment #0)
> I tried a couple experiments with __int128 and found some gdb issues.
> 
> My test code:
> 
> __int128 x = 72;
> 
> I compiled with -g -c then ran gdb on the .o.
> 
> Printing kind of works, but chooses hex by default and zero-pads:
> 
> (gdb) p x
> $1 = 0x00000000000000000000000000000048
> 
> Specifying decimal still zero-pads, which looks very weird:
> 
> (gdb) p/d x
> $2 = 00000000000000000000000000000072
> 
> Addition doesn't work:
> 
> (gdb) p x + 5
> That operation is not available on integers of more than 8 bytes.

There is no longer zero-padding since 8.1, but addition still doesn't work.
Comment 5 Sourceware Commits 2021-07-21 12:19:56 UTC
The master branch has been updated by Tom de Vries <vries@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=0057a7ee0d963eb9aee5cdfb9d6da5279bc8caf9

commit 0057a7ee0d963eb9aee5cdfb9d6da5279bc8caf9
Author: Tom de Vries <tdevries@suse.de>
Date:   Wed Jul 21 14:19:51 2021 +0200

    [gdb/testsuite] Add KFAILs for gdb.ada FAILs with gcc-11
    
    With gcc-11 we run into:
    ...
    (gdb) print pa_ptr.all^M
    That operation is not available on integers of more than 8 bytes.^M
    (gdb) KFAIL: gdb.ada/arrayptr.exp: scenario=all: print pa_ptr.all (PRMS: gdb/20991)
    ...
    
    This is due to PR exp/20991 - "__int128 type support".  Mark this and similar
    FAILs as KFAIL.
    
    Also mark this FAIL:
    ....
    (gdb) print pa_ptr(3)^M
    cannot subscript or call something of type `foo__packed_array_ptr'^M
    (gdb) FAIL: gdb.ada/arrayptr.exp: scenario=minimal: print pa_ptr(3)
    ...
    as a KFAIL for PR ada/28115 - "Support packed array encoded as
    DW_TAG_subrange_type".
    
    Tested on x86_64-linux, with gcc-10 and gcc-11.
    
    gdb/testsuite/ChangeLog:
    
    2021-07-21  Tom de Vries  <tdevries@suse.de>
    
            * gdb.ada/arrayptr.exp: Add KFAILs for PR20991 and PR28115.
            * gdb.ada/exprs.exp: Add KFAILs for PR20991.
            * gdb.ada/packed_array_assign.exp: Same.
Comment 6 Sourceware Commits 2021-07-21 12:22:21 UTC
The gdb-11-branch branch has been updated by Tom de Vries <vries@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f26101b199482bd13b5f9c45fb4f43a4eb8b16e6

commit f26101b199482bd13b5f9c45fb4f43a4eb8b16e6
Author: Tom de Vries <tdevries@suse.de>
Date:   Wed Jul 21 14:22:16 2021 +0200

    [gdb/testsuite] Add KFAILs for gdb.ada FAILs with gcc-11
    
    With gcc-11 we run into:
    ...
    (gdb) print pa_ptr.all^M
    That operation is not available on integers of more than 8 bytes.^M
    (gdb) KFAIL: gdb.ada/arrayptr.exp: scenario=all: print pa_ptr.all (PRMS: gdb/20991)
    ...
    
    This is due to PR exp/20991 - "__int128 type support".  Mark this and similar
    FAILs as KFAIL.
    
    Also mark this FAIL:
    ....
    (gdb) print pa_ptr(3)^M
    cannot subscript or call something of type `foo__packed_array_ptr'^M
    (gdb) FAIL: gdb.ada/arrayptr.exp: scenario=minimal: print pa_ptr(3)
    ...
    as a KFAIL for PR ada/28115 - "Support packed array encoded as
    DW_TAG_subrange_type".
    
    Tested on x86_64-linux, with gcc-10 and gcc-11.
    
    gdb/testsuite/ChangeLog:
    
    2021-07-21  Tom de Vries  <tdevries@suse.de>
    
            * gdb.ada/arrayptr.exp: Add KFAILs for PR20991 and PR28115.
            * gdb.ada/exprs.exp: Add KFAILs for PR20991.
            * gdb.ada/packed_array_assign.exp: Same.
Comment 7 Tom Tromey 2023-02-23 16:37:20 UTC
*** Bug 21185 has been marked as a duplicate of this bug. ***
Comment 8 Tom Tromey 2023-02-23 16:44:14 UTC
In bug #21185, using gcc's wide-int was suggested as one option.
I looked into this, and I can make wide-int compile in gdb
with some hacks.  However, since gdb already requires GMP,
I think it's probably better to just use that.

Also it seems like there are multiple parts to this bug.
Perhaps we should treat them individually...

* Parsers should recognize 128-bit types and lexers should make
  128-bit quantities.

* valops should extract a GMP from a struct value and work on that
  representation.

* Type ranges / dynamic props should be converted to 128-bit
  quantities where needed.  (My thinking here is that the
  data would be stored in some convenient & compact format,
  but convert to GMP when working with the values.)
Comment 9 Pedro Alves 2023-02-23 19:40:20 UTC
GMP has a surprising and unfortunate design choice that IMHO may make it undesirable for a fixed-width type -- it uses the heap for _every_ integer.

This is last discussed in this thread:

 https://sourceware.org/pipermail/gdb/2022-October/050375.html
Comment 10 Tom Tromey 2023-02-23 21:08:23 UTC
(In reply to Pedro Alves from comment #9)
> GMP has a surprising and unfortunate design choice that IMHO may make it
> undesirable for a fixed-width type -- it uses the heap for _every_ integer.

I suspect it won't matter much, but if it does, we can always
adopt wide-int.
Comment 11 Pedro Alves 2023-02-24 10:55:44 UTC
Yeah, or something else.  As long as the type we use looks like an integer (implements arithmetic operators, etc.), then swapping one implementation for another is not a big deal.
Comment 12 Pedro Alves 2023-02-24 12:35:20 UTC
I was looking at whether GMP already has built-in support for _finite_ precision, for example so that we handle wraparound of "unsigned __int128" values propertly, left shifting, etc.  I couldn't find anything for that, so I guess we'd have to implement wraparound, etc. ourselves?
Comment 13 Tom Tromey 2023-02-24 14:46:51 UTC
(In reply to Pedro Alves from comment #12)
> I was looking at whether GMP already has built-in support for _finite_
> precision, for example so that we handle wraparound of "unsigned __int128"
> values propertly, left shifting, etc.  I couldn't find anything for that, so
> I guess we'd have to implement wraparound, etc. ourselves?

Yeah.  I suppose gcc's is nicer this way, you can specify the
precision.
Comment 14 Tom Tromey 2023-02-24 16:13:50 UTC
> Yeah.  I suppose gcc's is nicer this way, you can specify the
> precision.

It occurs to me, though, that not many things in gdb are using
"chained" expressions.  Normally we'd unpack a value to a GMP,
operate on it, then put it back into a value.  So, frequently,
we wouldn't actually have to worry about the size of intermediates
Comment 15 Pedro Alves 2023-02-24 23:21:41 UTC
That may be true.  If we can make valarith.c:scalar_binop work for any
kind of fixed-precision type instead of doing host arithmetic on LONGEST, with the precision being a runtime property, then we would get most of value arithmetic done for all types, including types wider than 128 bits when they come.

It still seems to me though like if we need to implement the fixed-precision logic, we might as well consider factoring it out to an integer class.  That type may be based on wide-int, some other integer template (there are plenty such templates around we could borrow), or a wrapper around GMP (or a fixed-precision wrapper around our C++ GMP infinite-precision wrapper).
Comment 16 Tom Tromey 2023-02-25 01:15:03 UTC
Yeah.  I even considered just writing our own.

Monday or so I'll push my WIP patch to add wide-int to the tree
and you can see what it looks like.  A few hacks were needed,
though nothing too serious.  Mostly I couldn't be bothered to
figure out how all the classes work.

The main attraction of GMP is we already have it, and I recently
added a few operators and such.

For constants and values in type properties we can either just
store the number on some obstack, or use LEB.  The latter can
be nice since we can sometimes just use a pointer directly into
the DWARF data.
Comment 17 Tom Tromey 2023-02-27 18:01:52 UTC
(In reply to Tom Tromey from comment #16)
 
> Monday or so I'll push my WIP patch to add wide-int to the tree
> and you can see what it looks like

It is submit/wide-int-hacks in my github
Comment 18 Tom Tromey 2023-02-28 19:31:03 UTC
See also submit/pr-20991-more-gmp for the WIP.
Comment 19 Tom Tromey 2023-03-01 22:01:43 UTC
(In reply to Tom Tromey from comment #8)

> Also it seems like there are multiple parts to this bug.
> Perhaps we should treat them individually...

I filed new bugs and I'm turning this into a meta bug.