diff options
author | Mark Kettenis <kettenis@gnu.org> | 2012-10-23 18:16:55 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@gnu.org> | 2012-10-23 18:16:55 +0000 |
commit | 7f7930dd889bc0dcfd56b5dc362eb805b1f93560 (patch) | |
tree | 0df5344756f59cfd322dbdbf7b4eea78f5e1f3ea /gdb/amd64-tdep.c | |
parent | 9ece1fa9916f3105bc410a454d23e3d13021e3ac (diff) | |
download | gdb-7f7930dd889bc0dcfd56b5dc362eb805b1f93560.zip gdb-7f7930dd889bc0dcfd56b5dc362eb805b1f93560.tar.gz gdb-7f7930dd889bc0dcfd56b5dc362eb805b1f93560.tar.bz2 |
PR gdb/12796
PR gdb/12798
PR gdb/12800
* amd64-tdep.h (enum amd64_regnum): Add AMD64_ST1_REGNUM and
AMD64_FTAG_REGNUM.
* amd64-tdep.c (amd64_classify): Classify complex types.
(amd64_return_value): Handle the COMPLEX_X87 class.
Diffstat (limited to 'gdb/amd64-tdep.c')
-rw-r--r-- | gdb/amd64-tdep.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index 9cee464..a4172fc 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -586,6 +586,23 @@ amd64_classify (struct type *type, enum amd64_reg_class class[2]) /* Class X87 and X87UP. */ class[0] = AMD64_X87, class[1] = AMD64_X87UP; + /* Arguments of complex T where T is one of the types float or + double get treated as if they are implemented as: + + struct complexT { + T real; + T imag; + }; */ + else if (code == TYPE_CODE_COMPLEX && len == 8) + class[0] = AMD64_SSE; + else if (code == TYPE_CODE_COMPLEX && len == 16) + class[0] = class[1] = AMD64_SSE; + + /* A variable of type complex long double is classified as type + COMPLEX_X87. */ + else if (code == TYPE_CODE_COMPLEX && len == 32) + class[0] = AMD64_COMPLEX_X87; + /* Aggregates. */ else if (code == TYPE_CODE_ARRAY || code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION) @@ -636,6 +653,30 @@ amd64_return_value (struct gdbarch *gdbarch, struct value *function, return RETURN_VALUE_ABI_RETURNS_ADDRESS; } + /* 8. If the class is COMPLEX_X87, the real part of the value is + returned in %st0 and the imaginary part in %st1. */ + if (class[0] == AMD64_COMPLEX_X87) + { + if (readbuf) + { + regcache_raw_read (regcache, AMD64_ST0_REGNUM, readbuf); + regcache_raw_read (regcache, AMD64_ST1_REGNUM, readbuf + 16); + } + + if (writebuf) + { + i387_return_value (gdbarch, regcache); + regcache_raw_write (regcache, AMD64_ST0_REGNUM, writebuf); + regcache_raw_write (regcache, AMD64_ST1_REGNUM, writebuf + 16); + + /* Fix up the tag word such that both %st(0) and %st(1) are + marked as valid. */ + regcache_raw_write_unsigned (regcache, AMD64_FTAG_REGNUM, 0xfff); + } + + return RETURN_VALUE_REGISTER_CONVENTION; + } + gdb_assert (class[1] != AMD64_MEMORY); gdb_assert (len <= 16); |