1 2 3/* $OpenBSD: __divlu.S,v 1.1 2007/11/25 18:25:34 deraadt Exp $ */ 4/* $NetBSD: divrem.m4,v 1.5 1996/10/17 04:26:25 cgd Exp $ */ 5 6/* 7 * Copyright (c) 1994, 1995 Carnegie-Mellon University. 8 * All rights reserved. 9 * 10 * Author: Chris G. Demetriou 11 * 12 * Permission to use, copy, modify and distribute this software and 13 * its documentation is hereby granted, provided that both the copyright 14 * notice and this permission notice appear in all copies of the 15 * software, derivative works or modified versions, and any portions 16 * thereof, and that both notices appear in supporting documentation. 17 * 18 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 19 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 20 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 21 * 22 * Carnegie Mellon requests users of this software to return to 23 * 24 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 25 * School of Computer Science 26 * Carnegie Mellon University 27 * Pittsburgh PA 15213-3890 28 * 29 * any improvements or extensions that they make and grant Carnegie the 30 * rights to redistribute these changes. 31 */ 32 33/* 34 * Division and remainder. 35 * 36 * The use of m4 is modeled after the sparc code, but the algorithm is 37 * simple binary long division. 38 * 39 * Note that the loops could probably benefit from unrolling. 40 */ 41 42/* 43 * M4 Parameters 44 * __divlu name of function to generate 45 * div div=div: t10 / t11 -> t12; div=rem: t10 % t11 -> t12 46 * false false=true: signed; false=false: unsigned 47 * 32 total number of bits 48 */ 49 50 51 52 53 54 55 56 57 58 59 60#include <machine/asm.h> 61 62LEAF(__divlu, 0) /* XXX */ 63 lda sp, -64(sp) 64 stq t0, 0(sp) 65 stq t1, 8(sp) 66 stq t2, 16(sp) 67 stq t3, 24(sp) 68 69 stq t10, 40(sp) 70 stq t11, 48(sp) 71 mov zero, t12 /* Initialize result to zero */ 72 73 74 75 /* 76 * Clear the top 32 bits of each operand, as they may 77 * sign extension (if negated above), or random junk. 78 */ 79 zap t10, 0xf0, t10 80 zap t11, 0xf0, t11 81 82 83 /* kill the special cases. */ 84 beq t11, Ldotrap /* division by zero! */ 85 86 cmpult t10, t11, t2 /* t10 < t11? */ 87 /* t12 is already zero, from above. t10 is untouched. */ 88 bne t2, Lret_result 89 90 cmpeq t10, t11, t2 /* t10 == t11? */ 91 cmovne t2, 1, t12 92 cmovne t2, zero, t10 93 bne t2, Lret_result 94 95 /* 96 * Find out how many bits of zeros are at the beginning of the divisor. 97 */ 98LBbits: 99 ldiq t3, 1 /* t1 = 0; t0 = 1<<32-1 */ 100 mov zero, t1 101 sll t3, 32-1, t0 102LBloop: 103 and t11, t0, t2 /* if bit in t11 is set, done. */ 104 bne t2, LAbits 105 addq t1, 1, t1 /* increment t1, bit */ 106 srl t0, 1, t0 107 cmplt t1, 32-1, t2 /* if t1 leaves one bit, done. */ 108 bne t2, LBloop 109 110LAbits: 111 beq t1, Ldodiv /* If t1 = 0, divide now. */ 112 ldiq t3, 1 /* t0 = 1<<32-1 */ 113 sll t3, 32-1, t0 114 115LAloop: 116 and t10, t0, t2 /* if bit in t10 is set, done. */ 117 bne t2, Ldodiv 118 subq t1, 1, t1 /* decrement t1, bit */ 119 srl t0, 1, t0 120 bne t1, LAloop /* If t1 != 0, loop again */ 121 122Ldodiv: 123 sll t11, t1, t11 /* t11 <<= i */ 124 ldiq t3, 1 125 sll t3, t1, t0 126 127Ldivloop: 128 cmpult t10, t11, t2 129 or t12, t0, t3 130 cmoveq t2, t3, t12 131 subq t10, t11, t3 132 cmoveq t2, t3, t10 133 srl t0, 1, t0 134 srl t11, 1, t11 135 beq t10, Lret_result 136 bne t0, Ldivloop 137 138Lret_result: 139 140 141 142 ldq t0, 0(sp) 143 ldq t1, 8(sp) 144 ldq t2, 16(sp) 145 ldq t3, 24(sp) 146 147 ldq t10, 40(sp) 148 ldq t11, 48(sp) 149 lda sp, 64(sp) 150 ret zero, (t9), 1 151 152Ldotrap: 153 ldiq a0, -2 /* This is the signal to SIGFPE! */ 154 call_pal PAL_gentrap 155 156 br zero, Lret_result 157 158END(__divlu) 159