From: Alexander Graf <agraf@suse.de>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: QEMU-devel Developers <qemu-devel@nongnu.org>,
Aurelien Jarno <aurelien@aurel32.net>,
Richard Henderson <rth@twiddle.net>
Subject: Re: [Qemu-devel] [PATCH 14/17] s390x: Implement opcode helpers
Date: Mon, 28 Mar 2011 19:23:52 +0200 [thread overview]
Message-ID: <4D90C428.2030101@suse.de> (raw)
In-Reply-To: <AANLkTi=6dGucz1sjwWLxVqY2JsO=SWd=E4_z6R-T1krS@mail.gmail.com>
On 03/24/2011 06:29 PM, Peter Maydell wrote:
> On 24 March 2011 15:58, Alexander Graf<agraf@suse.de> wrote:
>
> This is more random comments in passing than a thorough review; sorry.
>
>> +#if HOST_LONG_BITS == 64&& defined(__GNUC__)
>> + /* assuming 64-bit hosts have __uint128_t */
>> + __uint128_t dividend = (((__uint128_t)env->regs[r1])<< 64) |
>> + (env->regs[r1+1]);
>> + __uint128_t quotient = dividend / divisor;
>> + env->regs[r1+1] = quotient;
>> + __uint128_t remainder = dividend % divisor;
>> + env->regs[r1] = remainder;
>> +#else
>> + /* 32-bit hosts would need special wrapper functionality - just abort if
>> + we encounter such a case; it's very unlikely anyways. */
>> + cpu_abort(env, "128 -> 64/64 division not implemented\n");
>> +#endif
> ...I'm still using a 32 bit system :-)
>
>> +/* condition codes for binary FP ops */
>> +static uint32_t set_cc_f32(float32 v1, float32 v2)
>> +{
>> + if (float32_is_any_nan(v1) || float32_is_any_nan(v2)) {
>> + return 3;
>> + } else if (float32_eq(v1, v2,&env->fpu_status)) {
>> + return 0;
>> + } else if (float32_lt(v1, v2,&env->fpu_status)) {
>> + return 1;
>> + } else {
>> + return 2;
>> + }
>> +}
> Can you not use float32_compare_quiet() (returns a value
> telling you if it's less/equal/greater/unordered)?
> If not, needs a comment saying why you need to do it the hard way.
I just checked the macros there and it looks like float32_compare_quiet
returns eq when both numbers are NaN. We would still have to convert
from the return value from that over to a CC value. I honestly don't see
any benefit - the code doesn't become cleaner or smaller.
int float32_compare_quiet( float32 a, float32 b STATUS_PARAM )
{
if (isless(a, b)) {
return float_relation_less;
} else if (a == b) {
return float_relation_equal;
} else if (isgreater(a, b)) {
return float_relation_greater;
} else {
return float_relation_unordered;
}
}
so
static uint32_t set_cc_f32(float32 v1, float32 v2)
{
if (float32_is_any_nan(v1) || float32_is_any_nan(v2)) {
return 3;
} else if (float32_eq(v1, v2, &env->fpu_status)) {
return 0;
} else if (float32_lt(v1, v2, &env->fpu_status)) {
return 1;
} else {
return 2;
}
}
would become
static uint32_t set_cc_f32(float32 v1, float32 v2)
{
int r;
if (float32_is_any_nan(v1) || float32_is_any_nan(v2)) {
return 3;
}
r = float32_compare_quiet(v1, v2, &env->fpu_status);
switch (r) {
case float_relation_equal:
return 0;
case float_relation_less:
return 1;
default:
return 2;
}
}
>> +/* negative absolute of 32-bit float */
>> +uint32_t HELPER(lcebr)(uint32_t f1, uint32_t f2)
>> +{
>> + env->fregs[f1].l.upper = float32_sub(float32_zero, env->fregs[f2].l.upper,
>> +&env->fpu_status);
>> + return set_cc_nz_f32(env->fregs[f1].l.upper);
>> +}
> Google suggests this is wrong:
> http://publib.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/DZ9AR006/19.4.10?SHELF=&DT=19990630131355&CASE=
> says for lcebr that:
> "The sign is inverted for any operand, including a QNaN or SNaN,
> without causing an arithmetic exception."
>
> but float32_sub will raise exceptions for NaNs. You want
> float32_chs() (and similarly for the other types).
Ah, nice :). Thanks!
>> +/* convert 64-bit float to 128-bit float */
>> +uint32_t HELPER(lcxbr)(uint32_t f1, uint32_t f2)
> Wrong comment? Looks like another invert-sign op from
> the online POO.
Yup, wrong comment and the same as above for chs :).
>> +/* 128-bit FP compare RR */
>> +uint32_t HELPER(cxbr)(uint32_t f1, uint32_t f2)
>> +{
>> + CPU_QuadU v1;
>> + v1.ll.upper = env->fregs[f1].ll;
>> + v1.ll.lower = env->fregs[f1 + 2].ll;
>> + CPU_QuadU v2;
>> + v2.ll.upper = env->fregs[f2].ll;
>> + v2.ll.lower = env->fregs[f2 + 2].ll;
>> + if (float128_is_any_nan(v1.q) || float128_is_any_nan(v2.q)) {
>> + return 3;
>> + } else if (float128_eq(v1.q, v2.q,&env->fpu_status)) {
>> + return 0;
>> + } else if (float128_lt(v1.q, v2.q,&env->fpu_status)) {
>> + return 1;
>> + } else {
>> + return 2;
>> + }
>> +}
> float128_compare_quiet() again?
See above :)
>> +/* convert 32-bit float to 64-bit int */
>> +uint32_t HELPER(cgebr)(uint32_t r1, uint32_t f2, uint32_t m3)
>> +{
>> + float32 v2 = env->fregs[f2].l.upper;
>> + set_round_mode(m3);
>> + env->regs[r1] = float32_to_int64(v2,&env->fpu_status);
>> + return set_cc_nz_f32(v2);
>> +}
> Should this really be permanently setting the rounding mode
> for future instructions as well as for the op it does itself?
IIUC every op that does rounding sets the rounding mode, no?
>> +/* load 32-bit FP zero */
>> +void HELPER(lzer)(uint32_t f1)
>> +{
>> + env->fregs[f1].l.upper = float32_zero;
>> +}
> Surely this is trivial enough to inline rather than
> calling a helper function...
Lots of the FPU code could use inlining. The CC stuff does too. For now,
I kept things the way Uli wrote them :).
>> +/* load 128-bit FP zero */
>> +void HELPER(lzxr)(uint32_t f1)
>> +{
>> + CPU_QuadU x;
>> + x.q = float64_to_float128(float64_zero,&env->fpu_status);
> Yuck. Just define a float128_zero if we need one.
Good point. Mind to do so? I find myself struggling with the code there.
>> +uint32_t HELPER(tceb)(uint32_t f1, uint64_t m2)
>> +{
>> + float32 v1 = env->fregs[f1].l.upper;
>> + int neg = float32_is_neg(v1);
>> + uint32_t cc = 0;
>> +
>> + HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __FUNCTION__, (long)v1, m2, neg);
>> + if ((float32_is_zero(v1)&& (m2& (1<< (11-neg)))) ||
>> + (float32_is_infinity(v1)&& (m2& (1<< (5-neg)))) ||
>> + (float32_is_any_nan(v1)&& (m2& (1<< (3-neg)))) ||
>> + (float32_is_signaling_nan(v1)&& (m2& (1<< (1-neg))))) {
>> + cc = 1;
>> + } else if (m2& (1<< (9-neg))) {
>> + /* assume normalized number */
>> + cc = 1;
>> + }
>> +
>> + /* FIXME: denormalized? */
>> + return cc;
>> +}
> There's a float32_is_zero_or_denormal(); if you need a
> float32_is_denormal() which is false for real zero we
> could add it, I guess.
Good point for a follow-up :)
>> +static inline uint32_t cc_calc_nabs_32(CPUState *env, int32_t dst)
>> +{
>> + return !!dst;
>> +}
> Another candidate for inlining.
Same as above :)
Alex
next prev parent reply other threads:[~2011-03-28 17:23 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-24 15:58 [Qemu-devel] [PATCH 00/17] s390x emulation support Alexander Graf
2011-03-24 15:58 ` [Qemu-devel] [PATCH 01/17] Only build ivshmem when CONFIG_PCI && CONFIG_KVM Alexander Graf
2011-03-24 21:46 ` [Qemu-devel] " Juan Quintela
2011-03-25 11:04 ` Alexander Graf
2011-03-24 15:58 ` [Qemu-devel] [PATCH 02/17] virtio: use generic name when possible Alexander Graf
2011-03-24 15:58 ` [Qemu-devel] [PATCH 03/17] s390x: Enable disassembler for s390x Alexander Graf
2011-03-24 15:58 ` [Qemu-devel] [PATCH 04/17] s390x: Enable nptl " Alexander Graf
2011-03-24 15:58 ` [Qemu-devel] [PATCH 05/17] s390x: enable CPU_QuadU Alexander Graf
2011-03-24 16:52 ` Peter Maydell
2011-03-24 16:54 ` Alexander Graf
2011-03-24 15:58 ` [Qemu-devel] [PATCH 06/17] s390x: s390x-linux-user support Alexander Graf
2011-03-24 15:58 ` [Qemu-devel] [PATCH 07/17] linux-user: define a couple of syscalls for non-uid16 targets Alexander Graf
2011-03-24 15:58 ` [Qemu-devel] [PATCH 08/17] s390x: Enable s390x-softmmu target Alexander Graf
2011-03-24 15:58 ` [Qemu-devel] [PATCH 09/17] s390x: Dispatch interrupts to KVM or the real CPU Alexander Graf
2011-03-24 15:58 ` [Qemu-devel] [PATCH 10/17] s390x: Adjust GDB stub Alexander Graf
2011-03-25 12:07 ` Nathan Froyd
2011-03-25 12:16 ` Alexander Graf
2011-03-24 15:58 ` [Qemu-devel] [PATCH 11/17] s390x: virtio machine storage keys Alexander Graf
2011-03-24 15:58 ` [Qemu-devel] [PATCH 12/17] s390x: Prepare cpu.h for emulation Alexander Graf
2011-03-28 14:54 ` Peter Maydell
2011-03-29 10:14 ` Alexander Graf
2011-03-24 15:58 ` [Qemu-devel] [PATCH 13/17] s390x: helper functions for system emulation Alexander Graf
2011-03-24 15:58 ` [Qemu-devel] [PATCH 14/17] s390x: Implement opcode helpers Alexander Graf
2011-03-24 17:29 ` Peter Maydell
2011-03-24 17:41 ` Richard Henderson
2011-03-24 18:09 ` Alexander Graf
2011-03-24 18:13 ` Alexander Graf
2011-03-28 17:23 ` Alexander Graf [this message]
2011-03-28 17:42 ` Richard Henderson
2011-03-28 17:55 ` Peter Maydell
2011-03-29 9:04 ` Alexander Graf
2011-03-24 15:58 ` [Qemu-devel] [PATCH 15/17] s390x: Adjust internal kvm code Alexander Graf
2011-03-24 15:58 ` [Qemu-devel] [PATCH 16/17] s390x: translate engine for s390x CPU Alexander Graf
2011-03-28 15:40 ` Peter Maydell
2011-03-29 8:55 ` Alexander Graf
2011-03-29 9:17 ` Peter Maydell
2011-03-29 9:25 ` Alexander Graf
2011-03-29 9:56 ` Peter Maydell
2011-03-29 10:40 ` Alexander Graf
2011-03-31 10:37 ` Peter Maydell
2011-03-24 15:58 ` [Qemu-devel] [PATCH 17/17] s390x: build s390x by default Alexander Graf
2011-03-28 14:20 ` [Qemu-devel] [PATCH 00/17] s390x emulation support Alexander Graf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4D90C428.2030101@suse.de \
--to=agraf@suse.de \
--cc=aurelien@aurel32.net \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.