1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 .ident "%Z%%M% %I% %E% SMI" 28 29 .file "%M%" 30 31/ Double long divide routine. 32 33#include <sys/asm_linkage.h> 34 35 ANSI_PRAGMA_WEAK(ldivide,function) 36 37#include "SYS.h" 38 39 .set lop,16 40 .set rop,24 41 .set ans,0 42 43 ENTRY(ldivide) 44 popl %eax 45 xchgl %eax,0(%esp) 46 pushl %eax 47 48 pushl %esi 49 pushl %edi 50 51 movl lop(%esp),%eax 52 movl lop+4(%esp),%edx 53 54/ the following code is only for compatibility with original ldivide code 55 orl %edx,%edx / force numerator positive 56 jns .ldiv1 57 notl %edx 58 negl %eax 59 sbbl $0xffffffff,%edx 60.ldiv1: 61 testl $0x80000000,rop+4(%esp) 62 jz .ldiv2 63 notl rop+4(%esp) / force denominator positive 64 negl rop(%esp) 65 sbbl $0xffffffff,rop+4(%esp) 66.ldiv2: 67/ end of compatibility code 68 69 xorl %esi,%esi / initialize remainder to 0 70 movl %esi,%edi 71 movl $64,%ecx / initialize counter for 64-bits 72.div_mod_loop: 73 shll $1,%edi 74 rcll $1,%esi / remainder * 2 75 shll $1,%eax 76 rcll $1,%edx / numerator * 2 (also quotient) 77 adcl $0,%edi / add in any carry from the shift 78 subl rop(%esp),%edi / subtract denominator from remainder 79 sbbl rop+4(%esp),%esi 80 incl %eax / turn on quotient bit for now 81 jnc .inc_remainder / inc didn't affect carry flag 82/ can't subtract the denominator from the remainder, add it back 83 addl rop(%esp),%edi 84 adcl rop+4(%esp),%esi 85 decl %eax / turn quotient bit off 86.inc_remainder: 87 loop .div_mod_loop 88 89/ at this point, %edx:%eax has the quotient and %edi:%esi has the remainder 90 popl %edi 91 popl %esi 92 movl %eax,%ecx 93 popl %eax 94 movl %ecx,ans(%eax) 95 movl %edx,ans+4(%eax) 96 ret 97 SET_SIZE(ldivide) 98