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