diff mbox series

[2/4] target/m68k: pass sign directly into make_quotient()

Message ID 20230101144339.60307-3-mark.cave-ayland@ilande.co.uk
State New
Headers show
Series target/m68k: fix FPSR quotient byte for fmod and frem | expand

Commit Message

Mark Cave-Ayland Jan. 1, 2023, 2:43 p.m. UTC
This enables the quotient parameter to be changed from int32_t to uint32_t and
also allows the extra sign logic in make_quotient() to be removed.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 target/m68k/fpu_helper.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

Comments

Laurent Vivier Jan. 1, 2023, 5:20 p.m. UTC | #1
Le 01/01/2023 à 15:43, Mark Cave-Ayland a écrit :
> This enables the quotient parameter to be changed from int32_t to uint32_t and
> also allows the extra sign logic in make_quotient() to be removed.
> 
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> ---
>   target/m68k/fpu_helper.c | 15 +++++----------
>   1 file changed, 5 insertions(+), 10 deletions(-)
> 

Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Laurent Vivier Jan. 1, 2023, 5:26 p.m. UTC | #2
Le 01/01/2023 à 15:43, Mark Cave-Ayland a écrit :
> This enables the quotient parameter to be changed from int32_t to uint32_t and
> also allows the extra sign logic in make_quotient() to be removed.
> 
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> ---
>   target/m68k/fpu_helper.c | 15 +++++----------
>   1 file changed, 5 insertions(+), 10 deletions(-)
> 
> diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
> index 0932c464fd..ae839785fa 100644
> --- a/target/m68k/fpu_helper.c
> +++ b/target/m68k/fpu_helper.c
> @@ -515,15 +515,8 @@ 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, int32_t quotient)
> +static void make_quotient(CPUM68KState *env, int sign, uint32_t quotient)
>   {
> -    int sign;
> -
> -    sign = quotient < 0;
> -    if (sign) {
> -        quotient = -quotient;
> -    }
> -
>       quotient = (sign << 7) | (quotient & 0x7f);
>       env->fpsr = (env->fpsr & ~FPSR_QT_MASK) | (quotient << FPSR_QT_SHIFT);
>   }
> @@ -536,7 +529,8 @@ void HELPER(fmod)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
>           return;
>       }
>   
> -    make_quotient(env, floatx80_to_int32(res->d, &env->fp_status));
> +    make_quotient(env, extractFloatx80Sign(res->d),
> +                  floatx80_to_int32(res->d, &env->fp_status));
>   }
>   
>   void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
> @@ -547,7 +541,8 @@ void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
>           return;
>       }
>   
> -    make_quotient(env, floatx80_to_int32(res->d, &env->fp_status));
> +    make_quotient(env, extractFloatx80Sign(res->d),
> +                  floatx80_to_int32(res->d, &env->fp_status));
>   }
>   
>   void HELPER(fgetexp)(CPUM68KState *env, FPReg *res, FPReg *val)

I think you need an "abs(floatx80_to_int32())" in both cases as you do in PATCH 4

Thanks,
Laurent
Richard Henderson Jan. 1, 2023, 6:53 p.m. UTC | #3
On 1/1/23 09:26, Laurent Vivier wrote:
> Le 01/01/2023 à 15:43, Mark Cave-Ayland a écrit :
>> This enables the quotient parameter to be changed from int32_t to uint32_t and
>> also allows the extra sign logic in make_quotient() to be removed.
>>
>> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>> ---
>>   target/m68k/fpu_helper.c | 15 +++++----------
>>   1 file changed, 5 insertions(+), 10 deletions(-)
>>
>> diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
>> index 0932c464fd..ae839785fa 100644
>> --- a/target/m68k/fpu_helper.c
>> +++ b/target/m68k/fpu_helper.c
>> @@ -515,15 +515,8 @@ 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, int32_t quotient)
>> +static void make_quotient(CPUM68KState *env, int sign, uint32_t quotient)
>>   {
>> -    int sign;
>> -
>> -    sign = quotient < 0;
>> -    if (sign) {
>> -        quotient = -quotient;
>> -    }
>> -
>>       quotient = (sign << 7) | (quotient & 0x7f);
>>       env->fpsr = (env->fpsr & ~FPSR_QT_MASK) | (quotient << FPSR_QT_SHIFT);
>>   }
>> @@ -536,7 +529,8 @@ void HELPER(fmod)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg 
>> *val1)
>>           return;
>>       }
>> -    make_quotient(env, floatx80_to_int32(res->d, &env->fp_status));
>> +    make_quotient(env, extractFloatx80Sign(res->d),
>> +                  floatx80_to_int32(res->d, &env->fp_status));
>>   }
>>   void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
>> @@ -547,7 +541,8 @@ void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg 
>> *val1)
>>           return;
>>       }
>> -    make_quotient(env, floatx80_to_int32(res->d, &env->fp_status));
>> +    make_quotient(env, extractFloatx80Sign(res->d),
>> +                  floatx80_to_int32(res->d, &env->fp_status));
>>   }
>>   void HELPER(fgetexp)(CPUM68KState *env, FPReg *res, FPReg *val)
> 
> I think you need an "abs(floatx80_to_int32())" in both cases as you do in PATCH 4

Or in fact

     sign = extractFloatx80Sign(res);
     quot = floatx80_to_int32(floatx80_abs(res->d), status);
     make_quotient(env, sign, quot);


r~
Mark Cave-Ayland Jan. 2, 2023, 10:04 a.m. UTC | #4
On 01/01/2023 17:26, Laurent Vivier wrote:

> Le 01/01/2023 à 15:43, Mark Cave-Ayland a écrit :
>> This enables the quotient parameter to be changed from int32_t to uint32_t and
>> also allows the extra sign logic in make_quotient() to be removed.
>>
>> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>> ---
>>   target/m68k/fpu_helper.c | 15 +++++----------
>>   1 file changed, 5 insertions(+), 10 deletions(-)
>>
>> diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
>> index 0932c464fd..ae839785fa 100644
>> --- a/target/m68k/fpu_helper.c
>> +++ b/target/m68k/fpu_helper.c
>> @@ -515,15 +515,8 @@ 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, int32_t quotient)
>> +static void make_quotient(CPUM68KState *env, int sign, uint32_t quotient)
>>   {
>> -    int sign;
>> -
>> -    sign = quotient < 0;
>> -    if (sign) {
>> -        quotient = -quotient;
>> -    }
>> -
>>       quotient = (sign << 7) | (quotient & 0x7f);
>>       env->fpsr = (env->fpsr & ~FPSR_QT_MASK) | (quotient << FPSR_QT_SHIFT);
>>   }
>> @@ -536,7 +529,8 @@ void HELPER(fmod)(CPUM68KState *env, FPReg *res, FPReg *val0, 
>> FPReg *val1)
>>           return;
>>       }
>> -    make_quotient(env, floatx80_to_int32(res->d, &env->fp_status));
>> +    make_quotient(env, extractFloatx80Sign(res->d),
>> +                  floatx80_to_int32(res->d, &env->fp_status));
>>   }
>>   void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
>> @@ -547,7 +541,8 @@ void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, 
>> FPReg *val1)
>>           return;
>>       }
>> -    make_quotient(env, floatx80_to_int32(res->d, &env->fp_status));
>> +    make_quotient(env, extractFloatx80Sign(res->d),
>> +                  floatx80_to_int32(res->d, &env->fp_status));
>>   }
>>   void HELPER(fgetexp)(CPUM68KState *env, FPReg *res, FPReg *val)
> 
> I think you need an "abs(floatx80_to_int32())" in both cases as you do in PATCH 4

Ah yes that's probably true - I suspect I didn't notice because the static tests fail 
immediately until patches 3 and 4.


ATB,

Mark.
Mark Cave-Ayland Jan. 2, 2023, 10:10 a.m. UTC | #5
On 01/01/2023 18:53, Richard Henderson wrote:

> On 1/1/23 09:26, Laurent Vivier wrote:
>> Le 01/01/2023 à 15:43, Mark Cave-Ayland a écrit :
>>> This enables the quotient parameter to be changed from int32_t to uint32_t and
>>> also allows the extra sign logic in make_quotient() to be removed.
>>>
>>> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>>> ---
>>>   target/m68k/fpu_helper.c | 15 +++++----------
>>>   1 file changed, 5 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
>>> index 0932c464fd..ae839785fa 100644
>>> --- a/target/m68k/fpu_helper.c
>>> +++ b/target/m68k/fpu_helper.c
>>> @@ -515,15 +515,8 @@ 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, int32_t quotient)
>>> +static void make_quotient(CPUM68KState *env, int sign, uint32_t quotient)
>>>   {
>>> -    int sign;
>>> -
>>> -    sign = quotient < 0;
>>> -    if (sign) {
>>> -        quotient = -quotient;
>>> -    }
>>> -
>>>       quotient = (sign << 7) | (quotient & 0x7f);
>>>       env->fpsr = (env->fpsr & ~FPSR_QT_MASK) | (quotient << FPSR_QT_SHIFT);
>>>   }
>>> @@ -536,7 +529,8 @@ void HELPER(fmod)(CPUM68KState *env, FPReg *res, FPReg *val0, 
>>> FPReg *val1)
>>>           return;
>>>       }
>>> -    make_quotient(env, floatx80_to_int32(res->d, &env->fp_status));
>>> +    make_quotient(env, extractFloatx80Sign(res->d),
>>> +                  floatx80_to_int32(res->d, &env->fp_status));
>>>   }
>>>   void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
>>> @@ -547,7 +541,8 @@ void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, 
>>> FPReg *val1)
>>>           return;
>>>       }
>>> -    make_quotient(env, floatx80_to_int32(res->d, &env->fp_status));
>>> +    make_quotient(env, extractFloatx80Sign(res->d),
>>> +                  floatx80_to_int32(res->d, &env->fp_status));
>>>   }
>>>   void HELPER(fgetexp)(CPUM68KState *env, FPReg *res, FPReg *val)
>>
>> I think you need an "abs(floatx80_to_int32())" in both cases as you do in PATCH 4
> 
> Or in fact
> 
>      sign = extractFloatx80Sign(res);
>      quot = floatx80_to_int32(floatx80_abs(res->d), status);
>      make_quotient(env, sign, quot);

Thanks for the suggestion. Just out of curiosity, how does moving the abs to before 
the integer conversion make a difference here? Is it because floatx80_to_int32() can 
fail in some circumstances because of the sign of the result?


ATB,

Mark.
Richard Henderson Jan. 2, 2023, 5:35 p.m. UTC | #6
On 1/2/23 02:10, Mark Cave-Ayland wrote:
>>> I think you need an "abs(floatx80_to_int32())" in both cases as you do in PATCH 4
>>
>> Or in fact
>>
>>      sign = extractFloatx80Sign(res);
>>      quot = floatx80_to_int32(floatx80_abs(res->d), status);
>>      make_quotient(env, sign, quot);
> 
> Thanks for the suggestion. Just out of curiosity, how does moving the abs to before the 
> integer conversion make a difference here? Is it because floatx80_to_int32() can fail in 
> some circumstances because of the sign of the result?

It's a simple and operation on floats, instead of cmp+cmov on integers.

I think it's a touch clearer as well, having just saved the fp sign, you discard it before 
moving on to the next thing.


r~
diff mbox series

Patch

diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index 0932c464fd..ae839785fa 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -515,15 +515,8 @@  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, int32_t quotient)
+static void make_quotient(CPUM68KState *env, int sign, uint32_t quotient)
 {
-    int sign;
-
-    sign = quotient < 0;
-    if (sign) {
-        quotient = -quotient;
-    }
-
     quotient = (sign << 7) | (quotient & 0x7f);
     env->fpsr = (env->fpsr & ~FPSR_QT_MASK) | (quotient << FPSR_QT_SHIFT);
 }
@@ -536,7 +529,8 @@  void HELPER(fmod)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
         return;
     }
 
-    make_quotient(env, floatx80_to_int32(res->d, &env->fp_status));
+    make_quotient(env, extractFloatx80Sign(res->d),
+                  floatx80_to_int32(res->d, &env->fp_status));
 }
 
 void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
@@ -547,7 +541,8 @@  void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
         return;
     }
 
-    make_quotient(env, floatx80_to_int32(res->d, &env->fp_status));
+    make_quotient(env, extractFloatx80Sign(res->d),
+                  floatx80_to_int32(res->d, &env->fp_status));
 }
 
 void HELPER(fgetexp)(CPUM68KState *env, FPReg *res, FPReg *val)