1*2874c5fdSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-or-later */ 294b212c2SPaul Mackerras/* 394b212c2SPaul Mackerras * Divide a 64-bit unsigned number by a 32-bit unsigned number. 494b212c2SPaul Mackerras * This routine assumes that the top 32 bits of the dividend are 594b212c2SPaul Mackerras * non-zero to start with. 694b212c2SPaul Mackerras * On entry, r3 points to the dividend, which get overwritten with 794b212c2SPaul Mackerras * the 64-bit quotient, and r4 contains the divisor. 894b212c2SPaul Mackerras * On exit, r3 contains the remainder. 994b212c2SPaul Mackerras * 1094b212c2SPaul Mackerras * Copyright (C) 2002 Paul Mackerras, IBM Corp. 1194b212c2SPaul Mackerras */ 1294b212c2SPaul Mackerras#include "ppc_asm.h" 1394b212c2SPaul Mackerras 1494b212c2SPaul Mackerras .globl __div64_32 1594b212c2SPaul Mackerras__div64_32: 1694b212c2SPaul Mackerras lwz r5,0(r3) # get the dividend into r5/r6 1794b212c2SPaul Mackerras lwz r6,4(r3) 1894b212c2SPaul Mackerras cmplw r5,r4 1994b212c2SPaul Mackerras li r7,0 2094b212c2SPaul Mackerras li r8,0 2194b212c2SPaul Mackerras blt 1f 2294b212c2SPaul Mackerras divwu r7,r5,r4 # if dividend.hi >= divisor, 2394b212c2SPaul Mackerras mullw r0,r7,r4 # quotient.hi = dividend.hi / divisor 2494b212c2SPaul Mackerras subf. r5,r0,r5 # dividend.hi %= divisor 2594b212c2SPaul Mackerras beq 3f 2694b212c2SPaul Mackerras1: mr r11,r5 # here dividend.hi != 0 2794b212c2SPaul Mackerras andis. r0,r5,0xc000 2894b212c2SPaul Mackerras bne 2f 2994b212c2SPaul Mackerras cntlzw r0,r5 # we are shifting the dividend right 3094b212c2SPaul Mackerras li r10,-1 # to make it < 2^32, and shifting 3194b212c2SPaul Mackerras srw r10,r10,r0 # the divisor right the same amount, 32acbfd58eSBenjamin Herrenschmidt addc r9,r4,r10 # rounding up (so the estimate cannot 3394b212c2SPaul Mackerras andc r11,r6,r10 # ever be too large, only too small) 3494b212c2SPaul Mackerras andc r9,r9,r10 35acbfd58eSBenjamin Herrenschmidt addze r9,r9 3694b212c2SPaul Mackerras or r11,r5,r11 3794b212c2SPaul Mackerras rotlw r9,r9,r0 3894b212c2SPaul Mackerras rotlw r11,r11,r0 3994b212c2SPaul Mackerras divwu r11,r11,r9 # then we divide the shifted quantities 4094b212c2SPaul Mackerras2: mullw r10,r11,r4 # to get an estimate of the quotient, 4194b212c2SPaul Mackerras mulhwu r9,r11,r4 # multiply the estimate by the divisor, 4294b212c2SPaul Mackerras subfc r6,r10,r6 # take the product from the divisor, 4394b212c2SPaul Mackerras add r8,r8,r11 # and add the estimate to the accumulated 4494b212c2SPaul Mackerras subfe. r5,r9,r5 # quotient 4594b212c2SPaul Mackerras bne 1b 4694b212c2SPaul Mackerras3: cmplw r6,r4 4794b212c2SPaul Mackerras blt 4f 4894b212c2SPaul Mackerras divwu r0,r6,r4 # perform the remaining 32-bit division 4994b212c2SPaul Mackerras mullw r10,r0,r4 # and get the remainder 5094b212c2SPaul Mackerras add r8,r8,r0 5194b212c2SPaul Mackerras subf r6,r10,r6 5294b212c2SPaul Mackerras4: stw r7,0(r3) # return the quotient in *r3 5394b212c2SPaul Mackerras stw r8,4(r3) 5494b212c2SPaul Mackerras mr r3,r6 # return the remainder in r3 5594b212c2SPaul Mackerras blr 56e32a0329STony Breeds 57e32a0329STony Breeds/* 58e32a0329STony Breeds * Extended precision shifts. 59e32a0329STony Breeds * 60e32a0329STony Breeds * Updated to be valid for shift counts from 0 to 63 inclusive. 61e32a0329STony Breeds * -- Gabriel 62e32a0329STony Breeds * 63e32a0329STony Breeds * R3/R4 has 64 bit value 64e32a0329STony Breeds * R5 has shift count 65e32a0329STony Breeds * result in R3/R4 66e32a0329STony Breeds * 67e32a0329STony Breeds * ashrdi3: arithmetic right shift (sign propagation) 68e32a0329STony Breeds * lshrdi3: logical right shift 69e32a0329STony Breeds * ashldi3: left shift 70e32a0329STony Breeds */ 71e32a0329STony Breeds .globl __ashrdi3 72e32a0329STony Breeds__ashrdi3: 73e32a0329STony Breeds subfic r6,r5,32 74e32a0329STony Breeds srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count 75e32a0329STony Breeds addi r7,r5,32 # could be xori, or addi with -32 76e32a0329STony Breeds slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count) 77e32a0329STony Breeds rlwinm r8,r7,0,32 # t3 = (count < 32) ? 32 : 0 78e32a0329STony Breeds sraw r7,r3,r7 # t2 = MSW >> (count-32) 79e32a0329STony Breeds or r4,r4,r6 # LSW |= t1 80e32a0329STony Breeds slw r7,r7,r8 # t2 = (count < 32) ? 0 : t2 81e32a0329STony Breeds sraw r3,r3,r5 # MSW = MSW >> count 82e32a0329STony Breeds or r4,r4,r7 # LSW |= t2 83e32a0329STony Breeds blr 84e32a0329STony Breeds 85e32a0329STony Breeds .globl __ashldi3 86e32a0329STony Breeds__ashldi3: 87e32a0329STony Breeds subfic r6,r5,32 88e32a0329STony Breeds slw r3,r3,r5 # MSW = count > 31 ? 0 : MSW << count 89e32a0329STony Breeds addi r7,r5,32 # could be xori, or addi with -32 90e32a0329STony Breeds srw r6,r4,r6 # t1 = count > 31 ? 0 : LSW >> (32-count) 91e32a0329STony Breeds slw r7,r4,r7 # t2 = count < 32 ? 0 : LSW << (count-32) 92e32a0329STony Breeds or r3,r3,r6 # MSW |= t1 93e32a0329STony Breeds slw r4,r4,r5 # LSW = LSW << count 94e32a0329STony Breeds or r3,r3,r7 # MSW |= t2 95e32a0329STony Breeds blr 96e32a0329STony Breeds 97e32a0329STony Breeds .globl __lshrdi3 98e32a0329STony Breeds__lshrdi3: 99e32a0329STony Breeds subfic r6,r5,32 100e32a0329STony Breeds srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count 101e32a0329STony Breeds addi r7,r5,32 # could be xori, or addi with -32 102e32a0329STony Breeds slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count) 103e32a0329STony Breeds srw r7,r3,r7 # t2 = count < 32 ? 0 : MSW >> (count-32) 104e32a0329STony Breeds or r4,r4,r6 # LSW |= t1 105e32a0329STony Breeds srw r3,r3,r5 # MSW = MSW >> count 106e32a0329STony Breeds or r4,r4,r7 # LSW |= t2 107e32a0329STony Breeds blr 108