From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mark Kettenis To: gdb-patches@sources.redhat.com Cc: grossman@juniper.dot.net Subject: [PATCH] Fix returning floating points values for x86 Date: Wed, 11 Jul 2001 01:49:00 -0000 Message-id: <200107110849.f6B8nGB19158@delius.kettenis.local> X-SW-Source: 2001-07/msg00250.html Fixes two FAILS in gdb.base/return2.exp. Stu, I was about to commit this patch when I saw you FreeBSD patch. Patch is almost identical (modulo comments), so it must be right :-). I nevertheless took all the credit ;-). I will come back to you on some of the other stuff in your patch. Checked in. Mark Index: ChangeLog from Mark Kettenis * i386-tdep.c (i386_extract_return_value): "Fix" comment. (i386_store_return_value): Frob FPU status and tag word to make sure the return value is the only value on the FPU stack. Index: i386-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/i386-tdep.c,v retrieving revision 1.31 diff -u -p -r1.31 i386-tdep.c --- i386-tdep.c 2001/05/09 16:16:33 1.31 +++ i386-tdep.c 2001/07/11 08:38:27 @@ -803,7 +803,8 @@ i386_extract_return_value (struct type * return; } - /* Floating-point return values can be found in %st(0). */ + /* Floating-point return values can be found in %st(0). + FIXME: Does %st(0) always correspond to FP0? */ if (len == TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT && TARGET_LONG_DOUBLE_FORMAT == &floatformat_i387_ext) { @@ -861,6 +862,8 @@ i386_store_return_value (struct type *ty if (TYPE_CODE (type) == TYPE_CODE_FLT) { + unsigned int fstat; + if (NUM_FREGS == 0) { warning ("Cannot set floating-point return value."); @@ -889,6 +892,16 @@ i386_store_return_value (struct type *ty write_register_bytes (REGISTER_BYTE (FP0_REGNUM), buf, FPU_REG_RAW_SIZE); } + + /* Set the top of the floating point register stack to 7. That + makes sure that FP0 (which we set above) is indeed %st(0). + FIXME: Perhaps we should completely reset the status word? */ + fstat = read_register (FSTAT_REGNUM); + fstat |= (7 << 11); + write_register (FSTAT_REGNUM, fstat); + + /* Mark %st(1) through %st(7) as empty. */ + write_register (FTAG_REGNUM, 0x3fff); } else {