1/* $OpenBSD: divu.S,v 1.11 2011/04/16 20:52:12 deraadt Exp $ */ 2/* 3 (c) Copyright 1986 HEWLETT-PACKARD COMPANY 4 To anyone who acknowledges that this file is provided "AS IS" 5 without any express or implied warranty: 6 permission to use, copy, modify, and distribute this file 7 for any purpose is hereby granted without fee, provided that 8 the above copyright notice and this notice appears in all 9 copies, and that the name of Hewlett-Packard Company not be 10 used in advertising or publicity pertaining to distribution 11 of the software without specific, written prior permission. 12 Hewlett-Packard Company makes no representations about the 13 suitability of this software for any purpose. 14*/ 15/* @(#)divu.s: Revision: 1.11.88.1 Date: 93/12/07 15:06:01 */ 16 17#include <machine/asm.h> 18#include <machine/frame.h> 19 20;************************************************************************ 21; Implement an integer divide routine for 32-bit operands and 32-bit quotient 22; and remainder with operand values of zero (divisor only) treated specially. 23; 24;**************************************************************************** 25; Definitions 26;**************************************************************************** 27; 28; General registers 29; 30gr0 .reg %r0 ; General register zero 31rem .reg %r3 ; remainder and upper part of dividend 32quo .reg %r4 ; quotient and lower part of dividend 33dvr .reg %r5 ; divisor 34tp .reg %r6 ; temp. reg. 35 36;****************************************************************************** 37 .text 38LEAF_ENTRY(divu) 39 stws,ma rem,4(sp) ; save registers on stack 40 stws,ma quo,4(sp) ; save registers on stack 41 stws,ma dvr,4(sp) ; save registers on stack 42 stws,ma tp,4(sp) ; save registers on stack 43 44 addi 0,arg2,dvr ; get divisor 45 addi 0,arg1,quo ; get lower dividend 46 addi 0,arg0,rem ; get upper dividend 47 48 comib,>,n 0,dvr,hibit ; check for dvr >= 2**31 49 addi -1,gr0,tp ; set V-bit to 1 50 ds 0,tp,0 51 add quo,quo,quo ; shift msb bit into carry 52 ds rem,dvr,rem ; 1st divide step, if carry 53 ; out, msb of quotient = 0 54 addc quo,quo,quo ; shift quo with/into carry 55 ds rem,dvr,rem ; 2nd divide step 56 addc quo,quo,quo ; shift quo with/into carry 57 ds rem,dvr,rem ; 3rd divide step 58 addc quo,quo,quo ; shift quo with/into carry 59 ds rem,dvr,rem ; 4th divide step 60 addc quo,quo,quo ; shift quo with/into carry 61 ds rem,dvr,rem ; 5th divide step 62 addc quo,quo,quo ; shift quo with/into carry 63 ds rem,dvr,rem ; 6th divide step 64 addc quo,quo,quo ; shift quo with/into carry 65 ds rem,dvr,rem ; 7th divide step 66 addc quo,quo,quo ; shift quo with/into carry 67 ds rem,dvr,rem ; 8th divide step 68 addc quo,quo,quo ; shift quo with/into carry 69 ds rem,dvr,rem ; 9th divide step 70 addc quo,quo,quo ; shift quo with/into carry 71 ds rem,dvr,rem ; 10th divide step 72 addc quo,quo,quo ; shift quo with/into carry 73 ds rem,dvr,rem ; 11th divide step 74 addc quo,quo,quo ; shift quo with/into carry 75 ds rem,dvr,rem ; 12th divide step 76 addc quo,quo,quo ; shift quo with/into carry 77 ds rem,dvr,rem ; 13th divide step 78 addc quo,quo,quo ; shift quo with/into carry 79 ds rem,dvr,rem ; 14th divide step 80 addc quo,quo,quo ; shift quo with/into carry 81 ds rem,dvr,rem ; 15th divide step 82 addc quo,quo,quo ; shift quo with/into carry 83 ds rem,dvr,rem ; 16th divide step 84 addc quo,quo,quo ; shift quo with/into carry 85 ds rem,dvr,rem ; 17th divide step 86 addc quo,quo,quo ; shift quo with/into carry 87 ds rem,dvr,rem ; 18th divide step 88 addc quo,quo,quo ; shift quo with/into carry 89 ds rem,dvr,rem ; 19th divide step 90 addc quo,quo,quo ; shift quo with/into carry 91 ds rem,dvr,rem ; 20th divide step 92 addc quo,quo,quo ; shift quo with/into carry 93 ds rem,dvr,rem ; 21st divide step 94 addc quo,quo,quo ; shift quo with/into carry 95 ds rem,dvr,rem ; 22nd divide step 96 addc quo,quo,quo ; shift quo with/into carry 97 ds rem,dvr,rem ; 23rd divide step 98 addc quo,quo,quo ; shift quo with/into carry 99 ds rem,dvr,rem ; 24th divide step 100 addc quo,quo,quo ; shift quo with/into carry 101 ds rem,dvr,rem ; 25th divide step 102 addc quo,quo,quo ; shift quo with/into carry 103 ds rem,dvr,rem ; 26th divide step 104 addc quo,quo,quo ; shift quo with/into carry 105 ds rem,dvr,rem ; 27th divide step 106 addc quo,quo,quo ; shift quo with/into carry 107 ds rem,dvr,rem ; 28th divide step 108 addc quo,quo,quo ; shift quo with/into carry 109 ds rem,dvr,rem ; 29th divide step 110 addc quo,quo,quo ; shift quo with/into carry 111 ds rem,dvr,rem ; 30th divide step 112 addc quo,quo,quo ; shift quo with/into carry 113 ds rem,dvr,rem ; 31st divide step 114 addc quo,quo,quo ; shift quo with/into carry 115 ds rem,dvr,rem ; 32nd divide step, 116 addc quo,quo,quo ; shift last quo bit into quo 117 addb,>=,n rem,0,finish ; branch if pos. rem 118 add,< dvr,0,0 ; if dvr > 0, add dvr 119 add,tr rem,dvr,rem ; for correcting rem. 120 sub rem,dvr,rem ; else subtract dvr 121; 122; end of divide routine 123; 124finish stws rem,0(arg3) ; save remainder in high part 125 ; of result 126 stws quo,4(arg3) ; save quotient in low part 127 ; of result 128 ldws,mb -4(sp),tp ; restore registers 129 ldws,mb -4(sp),dvr ; restore registers 130 ldws,mb -4(sp),quo ; restore registers 131 bv 0(rp) ; return 132 ldws,mb -4(sp),rem ; restore registers 133; 134hibit ldo 32(0),tp ; initialize loop counter 135 add quo,quo,quo ; shift high bit into carry 136loop addc rem,rem,rem ; shift in high bit of dvdl 137 addc,<> 0,0,0 ; if bit shifted out of dvdu, 138 ; want to do subtract 139 comb,<<,n rem,dvr,nosub ; if upper dividend > dvr, 140 sub rem,dvr,rem ; subtract and 141 add,tr dvr,dvr,0 ; set carry 142nosub addi 0,0,0 ; otherwise clear carry 143 addib,> -1,tp,loop ; inc. counter; finished? 144 addc quo,quo,quo ; shift bit of result into dvdl 145 b finish+4 ; finish up 146 stws rem,0(arg3) ; save remainder in high part 147 ; of result 148EXIT(divu) 149 150 .end 151