diff options
author | Oleg Endo <oleg.endo@t-online.de> | 2014-11-28 19:39:39 +0400 |
---|---|---|
committer | Joel Brobecker <brobecker@adacore.com> | 2014-11-28 19:44:03 +0400 |
commit | 57df9adf2d437e3c7f17a77c3e0f3c0d8e56aa40 (patch) | |
tree | 73a55ed62e5e2bde5d03fd54513570594f98b050 /sim/sh/gencode.c | |
parent | f7ca3fcfccd144c234370aa939e4f5f15f3b2a88 (diff) | |
download | fsf-binutils-gdb-57df9adf2d437e3c7f17a77c3e0f3c0d8e56aa40.zip fsf-binutils-gdb-57df9adf2d437e3c7f17a77c3e0f3c0d8e56aa40.tar.gz fsf-binutils-gdb-57df9adf2d437e3c7f17a77c3e0f3c0d8e56aa40.tar.bz2 |
Correct fabs and fneg insns in simulator
It seems that the implementation of the SH fabs and fneg insns in the
simulator is not correct. They use the FP_UNARY macro which checks the
FPSCR.PR setting and raises an exception if PR = 1 (double precision)
and the register number is not even (i.e. a valid DF reg number).
For normal unary FP insns this is fine. However, fneg and fabs perform
the same (integer) operations regardless of the FPSCR.PR setting.
This issue initially popped up here
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63260
I've checked some of the failing tests mentioned in GCC PR 63260 above
with the patch applied and the failures go away.
sim/sh/ChangeLog (tiny patch):
* gencode.c (fabs, fneg): Implement as integer operation
instead of using the FP_UNARY macro.
Diffstat (limited to 'sim/sh/gencode.c')
-rw-r--r-- | sim/sh/gencode.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/sim/sh/gencode.c b/sim/sh/gencode.c index 738b718..bc65604 100644 --- a/sim/sh/gencode.c +++ b/sim/sh/gencode.c @@ -429,8 +429,14 @@ op tab[] = /* sh2e */ { "", "", "fabs <FREG_N>", "1111nnnn01011101", - "FP_UNARY (n, fabs);", - "/* FIXME: FR (n) &= 0x7fffffff; */", + " union", + " {", + " unsigned int i;", + " float f;", + " } u;", + " u.f = FR (n);", + " u.i &= 0x7fffffff;", + " SET_FR (n, u.f);", }, /* sh2e */ @@ -662,7 +668,14 @@ op tab[] = /* sh2e */ { "", "", "fneg <FREG_N>", "1111nnnn01001101", - "FP_UNARY (n, -);", + " union", + " {", + " unsigned int i;", + " float f;", + " } u;", + " u.f = FR (n);", + " u.i ^= 0x80000000;", + " SET_FR (n, u.f);", }, /* sh4a */ |