From 6ecfd2b55333dbaf8755bcab53ae9d37b6bca7c1 Mon Sep 17 00:00:00 2001 From: Chunwei Chen Date: Thu, 3 Aug 2017 10:41:42 -0700 Subject: Add __divmoddi4 and __udivmoddi4 for 32-bit arch gcc-7 seems to use __udivmoddi4 for 64-bit division on 32-bit arch. This patch implement them so we don't get undefined reference error. Reviewed-by: Brian Behlendorf Reviewed-by: loli10K Signed-off-by: Chunwei Chen Closes zfsonlinux/zfs#6417 Closes #636 --- module/spl/spl-generic.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'module') diff --git a/module/spl/spl-generic.c b/module/spl/spl-generic.c index 10061620e..f6782dae7 100644 --- a/module/spl/spl-generic.c +++ b/module/spl/spl-generic.c @@ -277,6 +277,49 @@ __umoddi3(uint64_t dividend, uint64_t divisor) } EXPORT_SYMBOL(__umoddi3); +/* + * Implementation of 64-bit unsigned division/modulo for 32-bit machines. + */ +uint64_t +__udivmoddi4(uint64_t n, uint64_t d, uint64_t *r) +{ + uint64_t q = __udivdi3(n, d); + if (r) + *r = n - d * q; + return (q); +} +EXPORT_SYMBOL(__udivmoddi4); + +/* + * Implementation of 64-bit signed division/modulo for 32-bit machines. + */ +int64_t +__divmoddi4(int64_t n, int64_t d, int64_t *r) +{ + int64_t q, rr; + boolean_t nn = B_FALSE; + boolean_t nd = B_FALSE; + if (n < 0) { + nn = B_TRUE; + n = -n; + } + if (d < 0) { + nd = B_TRUE; + d = -d; + } + + q = __udivmoddi4(n, d, (uint64_t *)&rr); + + if (nn != nd) + q = -q; + if (nn) + rr = -rr; + if (r) + *r = rr; + return (q); +} +EXPORT_SYMBOL(__divmoddi4); + #if defined(__arm) || defined(__arm__) /* * Implementation of 64-bit (un)signed division for 32-bit arm machines. -- cgit v1.2.3