diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2023-01-16 16:55:30 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2023-01-16 16:55:30 +0000 |
commit | 2f8d6a88e44928e1afaab5fd37fafefc94bf395c (patch) | |
tree | 8e9eb0b1a54a1e46aaa09a5d2c30dd36ce772ec6 /target | |
parent | fb7e7990342e59cf67dbd895c1a1e3fb1741df7a (diff) | |
parent | 1a282f60a971aa86e3cdd1b7ca000790e43bb310 (diff) |
Merge tag 'm68k-next-pull-request' of https://github.com/vivier/qemu-m68k into staging
M68K pull request 20230116
fix FPSR quotient byte
# -----BEGIN PGP SIGNATURE-----
#
# iQJGBAABCAAwFiEEzS913cjjpNwuT1Fz8ww4vT8vvjwFAmPFFmsSHGxhdXJlbnRA
# dml2aWVyLmV1AAoJEPMMOL0/L748Dk4P+QH1tlWGWzOiuKZOSUjdJ3NDEw+xpGhH
# oS7I7swiz30RCJUJx9R2nL7u5lBN7kcP0duNDp58gwkmReuotrx5HYeN4WwTh/94
# 78CWDKMMT59ag0dA+41WxhXE2sQ6uVgDTtSXTH/1c4rCEm1NuXa+LGBD8oh0IxxW
# K0/OHfySQvK3mLRrZtx8h6Ug77Hj5AjYKJZ1tONAe0SkcTe/qXkA4npluVnJl+TQ
# /M31uzAD98Td0tSd6YxACkpV++JqEF6Uenbe0iT4A1izRa6GJb56xp+ENeUCavpD
# vh5MmJeqTfe/jvdzjWqLv0v88Z+U/TQ8VvvBAUn7aThVo5f/Njclkaxx/i581zpE
# pT6jCMxZYKCFdXH+QFqX6B9YBa0fTUxwynWQovIs9bwuWfRYA9IvHLCSWUZHZITi
# GQSPbioPcIi4Hc/EJMeRhnZl/9TcGE0tnc+Agib/WI5QaE8Hmj26b7+5v3vxgqQV
# vZ3HWOFSZ4sK3MoIsYoKqoRhFX8DtMqXsf70xKBWn5Yx1kol7vz34UYisLaQFJPZ
# NBKtVPbyAbMP37h7OMzToiGWw0pitgAERHoj7Qq0juT7U9mjfV/xacdniLMPbSUq
# UKzEYgEBNU1728A2TKJUZiXwrdQOx/nZQwJljYMG5RE9ePkhPJ3UvRWMRdxopT+f
# 3Lvgvj+qZ8Aq
# =VVZK
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 16 Jan 2023 09:18:35 GMT
# gpg: using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C
# gpg: issuer "laurent@vivier.eu"
# gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full]
# gpg: aka "Laurent Vivier <laurent@vivier.eu>" [full]
# gpg: aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full]
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F 5173 F30C 38BD 3F2F BE3C
* tag 'm68k-next-pull-request' of https://github.com/vivier/qemu-m68k:
target/m68k: fix FPSR quotient byte for frem instruction
target/m68k: fix FPSR quotient byte for fmod instruction
target/m68k: pass sign directly into make_quotient()
target/m68k: pass quotient directly into make_quotient()
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r-- | target/m68k/fpu_helper.c | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c index fdc4937e29..3a37d8f584 100644 --- a/target/m68k/fpu_helper.c +++ b/target/m68k/fpu_helper.c @@ -515,37 +515,50 @@ uint32_t HELPER(fmovemd_ld_postinc)(CPUM68KState *env, uint32_t addr, return fmovem_postinc(env, addr, mask, cpu_ld_float64_ra); } -static void make_quotient(CPUM68KState *env, floatx80 val) +static void make_quotient(CPUM68KState *env, int sign, uint32_t quotient) { - int32_t quotient; - int sign; - - if (floatx80_is_any_nan(val)) { - return; - } - - quotient = floatx80_to_int32(val, &env->fp_status); - sign = quotient < 0; - if (sign) { - quotient = -quotient; - } - quotient = (sign << 7) | (quotient & 0x7f); env->fpsr = (env->fpsr & ~FPSR_QT_MASK) | (quotient << FPSR_QT_SHIFT); } void HELPER(fmod)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) { - res->d = floatx80_mod(val1->d, val0->d, &env->fp_status); + uint64_t quotient; + int sign = extractFloatx80Sign(val1->d) ^ extractFloatx80Sign(val0->d); + + res->d = floatx80_modrem(val1->d, val0->d, true, "ient, + &env->fp_status); - make_quotient(env, res->d); + if (floatx80_is_any_nan(res->d)) { + return; + } + + make_quotient(env, sign, quotient); } void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) { - res->d = floatx80_rem(val1->d, val0->d, &env->fp_status); + FPReg fp_quot; + floatx80 fp_rem; + + fp_rem = floatx80_rem(val1->d, val0->d, &env->fp_status); + if (!floatx80_is_any_nan(fp_rem)) { + float_status fp_status = { }; + uint32_t quotient; + int sign; + + /* Calculate quotient directly using round to nearest mode */ + set_float_rounding_mode(float_round_nearest_even, &fp_status); + set_floatx80_rounding_precision( + get_floatx80_rounding_precision(&env->fp_status), &fp_status); + fp_quot.d = floatx80_div(val1->d, val0->d, &fp_status); + + sign = extractFloatx80Sign(fp_quot.d); + quotient = floatx80_to_int32(floatx80_abs(fp_quot.d), &env->fp_status); + make_quotient(env, sign, quotient); + } - make_quotient(env, res->d); + res->d = fp_rem; } void HELPER(fgetexp)(CPUM68KState *env, FPReg *res, FPReg *val) |