[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 1/7] target/ppc: introduce get_dfp{64,128}() helper functions
From: |
Mark Cave-Ayland |
Subject: |
Re: [PATCH 1/7] target/ppc: introduce get_dfp{64,128}() helper functions |
Date: |
Tue, 24 Sep 2019 22:05:31 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.9.0 |
On 24/09/2019 20:21, Richard Henderson wrote:
> On 9/24/19 8:35 AM, Mark Cave-Ayland wrote:
>> +static void get_dfp64(uint64_t *dst, uint64_t *dfp)
>> +{
>> + dst[0] = dfp[0];
>> +}
>> +
>> +static void get_dfp128(uint64_t *dst, uint64_t *dfp)
>> +{
>> + dst[0] = dfp[HI_IDX];
>> + dst[1] = dfp[LO_IDX];
>> +}
>
> I'm not keen on this. I would prefer some type difference that prevents you
> from getting the arguments the wrong way around.
>
> I'm thinking that a combination helper like
>
> static void get_dfp64(decNumber *out, uint64_t *in)
> {
> union {
> uint64_t i;
> decimal64 d;
> } u;
>
> u.i = *in;
> decimal64ToNumber(&u.d, out);
> }
>
>> @@ -129,7 +140,7 @@ static void dfp_prepare_decimal64(struct PPC_DFP *dfp,
>> uint64_t *a,
>> dfp->env = env;
>>
>> if (a) {
>> - dfp->a64[0] = *a;
>> + get_dfp64(dfp->a64, a);
>> decimal64ToNumber((decimal64 *)dfp->a64, &dfp->a);
>> } else {
>> dfp->a64[0] = 0;
>
> becomes
>
> get_dfp64(&dfp->a, a);
>
> and that might clean up a lot of the code.
Right, and in fact I had a similar thought myself regarding type safety since
one of
the issues with working with the existing code in dfp_helper.c is that
everything
uses a uint64_t * which makes it really difficult to figure out why things are
crashing if you make a typo :/
Note that this patch simply introduces the helpers without making changes to the
existing logic which is why both arguments are still uint64_t *. The real work
is
done in patch 3 where ppc_fptr_t type is introduced, and also see the switch
from
uint64_t * to ppc_vsr_t in patch 5.
With the full patchset applied you'll see that get_dfp64() and friends are in
exactly
the same form you show above, and if I swap the arguments then the compiler does
actually complain, although somewhat cryptically.
>> @@ -617,10 +626,12 @@ uint32_t helper_##op(CPUPPCState *env, uint64_t *a,
>> uint64_t *b) \
>> { \
>> struct PPC_DFP dfp; \
>> unsigned k; \
>> + uint64_t a64; \
>> \
>> dfp_prepare_decimal##size(&dfp, 0, b, env); \
>> \
>> - k = *a & 0x3F; \
>> + get_dfp64(&a64, a); \
>> + k = a64 & 0x3F; \
>> \
>> if (unlikely(decNumberIsSpecial(&dfp.b))) { \
>> dfp.crbf = 1; \
>
> Whereas cases like this, where a scalar is being passed in, I don't think that
> re-using the same helper is appropriate. Ideally, they would be passed in by
> value, and not by reference at all. That, of course, requires changes to the
> translator beyond the scope of this patch.
Agreed. I was really keen to avoid any translator changes if possible since the
PPC
translator code tends to be quite tricky which is why I went with the above
approach.
>> void helper_dctqpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
>> {
>> struct PPC_DFP dfp;
>> + uint64_t b64;
>> dfp_prepare_decimal128(&dfp, 0, 0, env);
>> - decimal64ToNumber((decimal64 *)b, &dfp.t);
>> + get_dfp64(&b64, b);
>> + decimal64ToNumber((decimal64 *)&b64, &dfp.t);
>
> This would become
>
> get_dfp64(&dfp.t, b);
>
> with no intermediate b64 temp.
Funnily enough that did cross my mind, but I wasn't 100% sure that this wasn't
doing
something extra within libdecnumber. If you think it makes sense then I can
easily
add it into a v2.
ATB,
Mark.
- [PATCH 0/7] target/ppc: DFP fixes and improvements, Mark Cave-Ayland, 2019/09/24
- [PATCH 2/7] target/ppc: introduce set_dfp{64,128}() helper functions, Mark Cave-Ayland, 2019/09/24
- [PATCH 3/7] target/ppc: update {get, set}_dfp{64, 128}() helper functions to read/write DFP numbers correctly, Mark Cave-Ayland, 2019/09/24
- [PATCH 6/7] target/ppc: use existing VsrD() macro to eliminate HI_IDX and LO_IDX from dfp_helper.c, Mark Cave-Ayland, 2019/09/24