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 | |
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.
-rw-r--r-- | gdb/ChangeLog | 10 | ||||
-rw-r--r-- | gdb/amd64-tdep.c | 41 | ||||
-rw-r--r-- | gdb/amd64-tdep.h | 2 |
3 files changed, 53 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d3d534d..2ccc5d7 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2012-10-23 Mark Kettenis <kettenis@gnu.org> + + 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. + 2012-10-23 Joel Brobecker <brobecker@adacore.com> * rs6000-aix-tdep.c (rs6000_aix_auto_wide_charset): New function. 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); diff --git a/gdb/amd64-tdep.h b/gdb/amd64-tdep.h index cb901cc..eba0d6d 100644 --- a/gdb/amd64-tdep.h +++ b/gdb/amd64-tdep.h @@ -57,8 +57,10 @@ enum amd64_regnum AMD64_FS_REGNUM, /* %fs */ AMD64_GS_REGNUM, /* %gs */ AMD64_ST0_REGNUM = 24, /* %st0 */ + AMD64_ST1_REGNUM, /* %st1 */ AMD64_FCTRL_REGNUM = AMD64_ST0_REGNUM + 8, AMD64_FSTAT_REGNUM = AMD64_ST0_REGNUM + 9, + AMD64_FTAG_REGNUM = AMD64_ST0_REGNUM + 10, AMD64_XMM0_REGNUM = 40, /* %xmm0 */ AMD64_XMM1_REGNUM, /* %xmm1 */ AMD64_MXCSR_REGNUM = AMD64_XMM0_REGNUM + 16, |