1/* $NetBSD: divu.S,v 1.1 2002/06/05 01:04:25 fredette Exp $ */ 2 3/* $OpenBSD: divu.S,v 1.5 2001/03/29 03:58:18 mickey Exp $ */ 4 5/* 6 * Copyright 1996 1995 by Open Software Foundation, Inc. 7 * All Rights Reserved 8 * 9 * Permission to use, copy, modify, and distribute this software and 10 * its documentation for any purpose and without fee is hereby granted, 11 * provided that the above copyright notice appears in all copies and 12 * that both the copyright notice and this permission notice appear in 13 * supporting documentation. 14 * 15 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 17 * FOR A PARTICULAR PURPOSE. 18 * 19 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 22 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 23 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 * 25 */ 26/* 27 * pmk1.1 28 */ 29/* 30 * (c) Copyright 1986 HEWLETT-PACKARD COMPANY 31 * 32 * To anyone who acknowledges that this file is provided "AS IS" 33 * without any express or implied warranty: 34 * permission to use, copy, modify, and distribute this file 35 * for any purpose is hereby granted without fee, provided that 36 * the above copyright notice and this notice appears in all 37 * copies, and that the name of Hewlett-Packard Company not be 38 * used in advertising or publicity pertaining to distribution 39 * of the software without specific, written prior permission. 40 * Hewlett-Packard Company makes no representations about the 41 * suitability of this software for any purpose. 42 */ 43 44#include <machine/asm.h> 45 46/************************************************************************** 47 * Implement an integer divide routine for 32-bit operands and 32-bit quotient 48 * and remainder with operand values of zero (divisor only) treated specially. 49 * 50 ***************************************************************************/ 51/* 52 * General registers 53 */ 54gr0 .reg %r0 /* General register zero */ 55rem .reg %r3 /* remainder and upper part of dividend */ 56quo .reg %r4 /* quotient and lower part of dividend */ 57dvr .reg %r5 /* divisor */ 58tp .reg %r6 /* temp. reg. */ 59 60 .text 61 62/*****************************************************************************/ 63ENTRY(divu,16) 64 stws,ma rem,4(sp) ; save registers on stack 65 stws,ma quo,4(sp) ; save registers on stack 66 stws,ma dvr,4(sp) ; save registers on stack 67 stws,ma tp,4(sp) ; save registers on stack 68 69 addi 0,arg2,dvr ; get divisor 70 addi 0,arg1,quo ; get lower dividend 71 addi 0,arg0,rem ; get upper dividend 72 73 comib,>,n 0,dvr,hibit ; check for dvr >= 2**31 74 addi -1,gr0,tp ; set V-bit to 1 75 ds 0,tp,0 76 add quo,quo,quo ; shift msb bit into carry 77 ds rem,dvr,rem ; 1st divide step, if carry 78 ; out, msb of quotient = 0 79 addc quo,quo,quo ; shift quo with/into carry 80 ds rem,dvr,rem ; 2nd divide step 81 addc quo,quo,quo ; shift quo with/into carry 82 ds rem,dvr,rem ; 3rd divide step 83 addc quo,quo,quo ; shift quo with/into carry 84 ds rem,dvr,rem ; 4th divide step 85 addc quo,quo,quo ; shift quo with/into carry 86 ds rem,dvr,rem ; 5th divide step 87 addc quo,quo,quo ; shift quo with/into carry 88 ds rem,dvr,rem ; 6th divide step 89 addc quo,quo,quo ; shift quo with/into carry 90 ds rem,dvr,rem ; 7th divide step 91 addc quo,quo,quo ; shift quo with/into carry 92 ds rem,dvr,rem ; 8th divide step 93 addc quo,quo,quo ; shift quo with/into carry 94 ds rem,dvr,rem ; 9th divide step 95 addc quo,quo,quo ; shift quo with/into carry 96 ds rem,dvr,rem ; 10th divide step 97 addc quo,quo,quo ; shift quo with/into carry 98 ds rem,dvr,rem ; 11th divide step 99 addc quo,quo,quo ; shift quo with/into carry 100 ds rem,dvr,rem ; 12th divide step 101 addc quo,quo,quo ; shift quo with/into carry 102 ds rem,dvr,rem ; 13th divide step 103 addc quo,quo,quo ; shift quo with/into carry 104 ds rem,dvr,rem ; 14th divide step 105 addc quo,quo,quo ; shift quo with/into carry 106 ds rem,dvr,rem ; 15th divide step 107 addc quo,quo,quo ; shift quo with/into carry 108 ds rem,dvr,rem ; 16th divide step 109 addc quo,quo,quo ; shift quo with/into carry 110 ds rem,dvr,rem ; 17th divide step 111 addc quo,quo,quo ; shift quo with/into carry 112 ds rem,dvr,rem ; 18th divide step 113 addc quo,quo,quo ; shift quo with/into carry 114 ds rem,dvr,rem ; 19th divide step 115 addc quo,quo,quo ; shift quo with/into carry 116 ds rem,dvr,rem ; 20th divide step 117 addc quo,quo,quo ; shift quo with/into carry 118 ds rem,dvr,rem ; 21st divide step 119 addc quo,quo,quo ; shift quo with/into carry 120 ds rem,dvr,rem ; 22nd divide step 121 addc quo,quo,quo ; shift quo with/into carry 122 ds rem,dvr,rem ; 23rd divide step 123 addc quo,quo,quo ; shift quo with/into carry 124 ds rem,dvr,rem ; 24th divide step 125 addc quo,quo,quo ; shift quo with/into carry 126 ds rem,dvr,rem ; 25th divide step 127 addc quo,quo,quo ; shift quo with/into carry 128 ds rem,dvr,rem ; 26th divide step 129 addc quo,quo,quo ; shift quo with/into carry 130 ds rem,dvr,rem ; 27th divide step 131 addc quo,quo,quo ; shift quo with/into carry 132 ds rem,dvr,rem ; 28th divide step 133 addc quo,quo,quo ; shift quo with/into carry 134 ds rem,dvr,rem ; 29th divide step 135 addc quo,quo,quo ; shift quo with/into carry 136 ds rem,dvr,rem ; 30th divide step 137 addc quo,quo,quo ; shift quo with/into carry 138 ds rem,dvr,rem ; 31st divide step 139 addc quo,quo,quo ; shift quo with/into carry 140 ds rem,dvr,rem ; 32nd divide step, 141 addc quo,quo,quo ; shift last quo bit into quo 142 addb,>=,n rem,0,finish ; branch if pos. rem 143 add,< dvr,0,0 ; if dvr > 0, add dvr 144 add,tr rem,dvr,rem ; for correcting rem. 145 sub rem,dvr,rem ; else subtract dvr 146; 147; end of divide routine 148; 149finish stws rem,0(arg3) ; save remainder in high part 150 ; of result 151 stws quo,4(arg3) ; save quotient in low part 152 ; of result 153 ldws,mb -4(sp),tp ; restore registers 154 ldws,mb -4(sp),dvr ; restore registers 155 ldws,mb -4(sp),quo ; restore registers 156 bv 0(rp) ; return 157 ldws,mb -4(sp),rem ; restore registers 158; 159hibit ldo 32(0),tp ; initialize loop counter 160 add quo,quo,quo ; shift high bit into carry 161loop addc rem,rem,rem ; shift in high bit of dvdl 162 addc,<> 0,0,0 ; if bit shifted out of dvdu, 163 ; want to do subtract 164 comb,<<,n rem,dvr,nosub ; if upper dividend > dvr, 165 sub rem,dvr,rem ; subtract and 166 add,tr dvr,dvr,0 ; set carry 167nosub addi 0,0,0 ; otherwise clear carry 168 addib,> -1,tp,loop ; inc. counter; finished? 169 addc quo,quo,quo ; shift bit of result into dvdl 170 b finish+4 ; finish up 171 stws rem,0(arg3) ; save remainder in high part 172 ; of result 173 174EXIT(divu) 175 .end 176