1 /* SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0 */ 2 #include <linux/linkage.h> 3 #include <asm/asmmacro.h> 4 #include <asm/core.h> 5 6 ENTRY(__udivsi3) 7 8 abi_entry_default 9 #if XCHAL_HAVE_DIV32 10 quou a2, a2, a3 11 #else 12 bltui a3, 2, .Lle_one /* check if the divisor <= 1 */ 13 14 mov a6, a2 /* keep dividend in a6 */ 15 do_nsau a5, a6, a2, a7 /* dividend_shift = nsau (dividend) */ 16 do_nsau a4, a3, a2, a7 /* divisor_shift = nsau (divisor) */ 17 bgeu a5, a4, .Lspecial 18 19 sub a4, a4, a5 /* count = divisor_shift - dividend_shift */ 20 ssl a4 21 sll a3, a3 /* divisor <<= count */ 22 movi a2, 0 /* quotient = 0 */ 23 24 /* test-subtract-and-shift loop; one quotient bit on each iteration */ 25 #if XCHAL_HAVE_LOOPS 26 loopnez a4, .Lloopend 27 #endif /* XCHAL_HAVE_LOOPS */ 28 .Lloop: 29 bltu a6, a3, .Lzerobit 30 sub a6, a6, a3 31 addi a2, a2, 1 32 .Lzerobit: 33 slli a2, a2, 1 34 srli a3, a3, 1 35 #if !XCHAL_HAVE_LOOPS 36 addi a4, a4, -1 37 bnez a4, .Lloop 38 #endif /* !XCHAL_HAVE_LOOPS */ 39 .Lloopend: 40 41 bltu a6, a3, .Lreturn 42 addi a2, a2, 1 /* increment quotient if dividend >= divisor */ 43 .Lreturn: 44 abi_ret_default 45 46 .Lle_one: 47 beqz a3, .Lerror /* if divisor == 1, return the dividend */ 48 abi_ret_default 49 50 .Lspecial: 51 /* return dividend >= divisor */ 52 bltu a6, a3, .Lreturn0 53 movi a2, 1 54 abi_ret_default 55 56 .Lerror: 57 /* Divide by zero: Use an illegal instruction to force an exception. 58 The subsequent "DIV0" string can be recognized by the exception 59 handler to identify the real cause of the exception. */ 60 ill 61 .ascii "DIV0" 62 63 .Lreturn0: 64 movi a2, 0 65 #endif /* XCHAL_HAVE_DIV32 */ 66 abi_ret_default 67 68 ENDPROC(__udivsi3) 69 EXPORT_SYMBOL(__udivsi3)
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.