The ISA has a 128/64-bit division instruction, though it assumes the
low 64-bits of the numerator are 0, and so requires a bit more fixup
than a full 128-bit division insn.
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/fpu/softfloat-macros.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h
index eafc68932b..c86687fa5e 100644
--- a/include/fpu/softfloat-macros.h
+++ b/include/fpu/softfloat-macros.h
@@ -647,6 +647,22 @@ static inline uint64_t udiv_qrnnd(uint64_t *r, uint64_t n1,
asm("dlgr %0, %1" : "+r"(n) : "r"(d));
*r = n >> 64;
return n;
+#elif defined(_ARCH_PPC64)
+ /* From Power ISA 3.0B, programming note for divdeu. */
+ uint64_t q1, q2, Q, r1, r2, R;
+ asm("divdeu %0,%2,%4; divdu %1,%3,%4"
+ : "=&r"(q1), "=r"(q2)
+ : "r"(n1), "r"(n0), "r"(d));
+ r1 = -(q1 * d); /* low part of (n1<<64) - (q1 * d) */
+ r2 = n0 - (q2 * d);
+ Q = q1 + q2;
+ R = r1 + r2;
+ if (R >= d || R < r2) { /* overflow implies R > d */
+ Q += 1;
+ R -= d;
+ }
+ *r = R;
+ return Q;
#else
uint64_t d0, d1, q0, q1, r1, r0, m;
--
2.17.1
On 05/10/2018 20:02, Richard Henderson wrote:
> The ISA has a 128/64-bit division instruction, though it assumes the
> low 64-bits of the numerator are 0, and so requires a bit more fixup
> than a full 128-bit division insn.
>
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> include/fpu/softfloat-macros.h | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h
> index eafc68932b..c86687fa5e 100644
> --- a/include/fpu/softfloat-macros.h
> +++ b/include/fpu/softfloat-macros.h
> @@ -647,6 +647,22 @@ static inline uint64_t udiv_qrnnd(uint64_t *r, uint64_t n1,
> asm("dlgr %0, %1" : "+r"(n) : "r"(d));
> *r = n >> 64;
> return n;
> +#elif defined(_ARCH_PPC64)
> + /* From Power ISA 3.0B, programming note for divdeu. */
> + uint64_t q1, q2, Q, r1, r2, R;
> + asm("divdeu %0,%2,%4; divdu %1,%3,%4"
> + : "=&r"(q1), "=r"(q2)
> + : "r"(n1), "r"(n0), "r"(d));
> + r1 = -(q1 * d); /* low part of (n1<<64) - (q1 * d) */
> + r2 = n0 - (q2 * d);
> + Q = q1 + q2;
> + R = r1 + r2;
> + if (R >= d || R < r2) { /* overflow implies R > d */
> + Q += 1;
> + R -= d;
> + }
> + *r = R;
> + return Q;
> #else
> uint64_t d0, d1, q0, q1, r1, r0, m;
>
>
This breaks qemu-s390x (and probably some others) on PPC64.
sudo chroot chroot/s390x/stretch/ apt-get update --yes
Ign:1 http://ftp.de.debian.org/debian stretch InRelease
Hit:2 http://ftp.de.debian.org/debian stretch Release
0% [Working]Illegal instruction
I didn't find any relevant information with "QEMU_STRACE=
QEMU_SINGLESTEP= QEMU_LOG=in_asm,op,unimp,int"
I will try to add some traces manually.
Thanks,
Laurent
On 31/10/2018 19:46, Laurent Vivier wrote:
> On 05/10/2018 20:02, Richard Henderson wrote:
>> The ISA has a 128/64-bit division instruction, though it assumes the
>> low 64-bits of the numerator are 0, and so requires a bit more fixup
>> than a full 128-bit division insn.
>>
>> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>> include/fpu/softfloat-macros.h | 16 ++++++++++++++++
>> 1 file changed, 16 insertions(+)
>>
>> diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h
>> index eafc68932b..c86687fa5e 100644
>> --- a/include/fpu/softfloat-macros.h
>> +++ b/include/fpu/softfloat-macros.h
>> @@ -647,6 +647,22 @@ static inline uint64_t udiv_qrnnd(uint64_t *r, uint64_t n1,
>> asm("dlgr %0, %1" : "+r"(n) : "r"(d));
>> *r = n >> 64;
>> return n;
>> +#elif defined(_ARCH_PPC64)
>> + /* From Power ISA 3.0B, programming note for divdeu. */
So it fails because my PowerMac G5 is not Power ISA 3.0B...
Something like this fixes the problem. I'm not sure it's the cleanest way:
diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h
index c86687fa5e..5a724da2ea 100644
--- a/include/fpu/softfloat-macros.h
+++ b/include/fpu/softfloat-macros.h
@@ -79,6 +79,10 @@ this code that are retained.
* version 2 or later. See the COPYING file in the top-level directory.
*/
+#if defined(_ARCH_PPC64)
+extern bool have_isa_3_00;
+#endif
+
/*----------------------------------------------------------------------------
| Shifts `a' right by the number of bits given in `count'. If any nonzero
| bits are shifted off, they are ``jammed'' into the least significant
bit of
@@ -647,7 +651,9 @@ static inline uint64_t udiv_qrnnd(uint64_t *r,
uint64_t n1,
asm("dlgr %0, %1" : "+r"(n) : "r"(d));
*r = n >> 64;
return n;
-#elif defined(_ARCH_PPC64)
+#else
+#if defined(_ARCH_PPC64)
+ if (have_isa_3_00) {
/* From Power ISA 3.0B, programming note for divdeu. */
uint64_t q1, q2, Q, r1, r2, R;
asm("divdeu %0,%2,%4; divdu %1,%3,%4"
@@ -663,7 +669,8 @@ static inline uint64_t udiv_qrnnd(uint64_t *r,
uint64_t n1,
}
*r = R;
return Q;
-#else
+ }
+#endif
uint64_t d0, d1, q0, q1, r1, r0, m;
d0 = (uint32_t)d;
Thanks,
Laurent
© 2016 - 2025 Red Hat, Inc.