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