diff options
author | Chunwei Chen <[email protected]> | 2017-08-03 10:41:42 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2017-08-03 10:41:42 -0700 |
commit | 6ecfd2b55333dbaf8755bcab53ae9d37b6bca7c1 (patch) | |
tree | fae8fe09a988c9f91419e1d501f1c58b4ea068e0 /module | |
parent | 98cdcb8286db2dadf369a22d33a53e49b11e3288 (diff) |
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 <[email protected]>
Reviewed-by: loli10K <[email protected]>
Signed-off-by: Chunwei Chen <[email protected]>
Closes zfsonlinux/zfs#6417
Closes #636
Diffstat (limited to 'module')
-rw-r--r-- | module/spl/spl-generic.c | 43 |
1 files changed, 43 insertions, 0 deletions
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. |