Update.
[glibc.git] / sysdeps / alpha / ldiv.S
blob81b48cd5599873988e092e85b4177c8b599c8fce
1 /* Copyright (C) 1996, 1997, 2001 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Richard Henderson <rth@tamu.edu>.
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
20 #include <sysdep.h>
22 #ifdef __linux__
23 # include <asm/gentrap.h>
24 # include <asm/pal.h>
25 #else
26 # include <machine/pal.h>
27 #endif
29         .set noat
31         .align 4
32         .globl ldiv
33         .ent ldiv
34 ldiv:
35         .frame sp, 0, ra
36 #ifdef PROF
37         ldgp    gp, 0(pv)
38         lda     AT, _mcount
39         jsr     AT, (AT), _mcount
40         .prologue 1
41 #else
42         .prologue 0
43 #endif
45 #define divisor   t1
46 #define mask      t2
47 #define quotient  t3
48 #define modulus   t4
49 #define tmp1      t5
50 #define tmp2      t6
51 #define compare   t7
53         /* find correct sign for input to unsigned divide loop. */
54         mov     a1, modulus                     # e0    :
55         mov     a2, divisor                     # .. e1 :
56         negq    a1, tmp1                        # e0    :
57         negq    a2, tmp2                        # .. e1 :
58         mov     zero, quotient                  # e0    :
59         mov     1, mask                         # .. e1 :
60         cmovlt  a1, tmp1, modulus               # e0    :
61         cmovlt  a2, tmp2, divisor               # .. e1 :
62         beq     a2, $divbyzero                  # e1    :
63         unop                                    #       :
65         /* shift divisor left.  */
66 1:      cmpult  divisor, modulus, compare       # e0    :
67         blt     divisor, 2f                     # .. e1 :
68         addq    divisor, divisor, divisor       # e0    :
69         addq    mask, mask, mask                # .. e1 :
70         bne     compare, 1b                     # e1    :
71         unop                                    #       :
73         /* start to go right again. */
74 2:      addq    quotient, mask, tmp2            # e1    :
75         srl     mask, 1, mask                   # .. e0 :
76         cmpule  divisor, modulus, compare       # e0    :
77         subq    modulus, divisor, tmp1          # .. e1 :
78         cmovne  compare, tmp2, quotient         # e1    :
79         srl     divisor, 1, divisor             # .. e0 :
80         cmovne  compare, tmp1, modulus          # e0    :
81         bne     mask, 2b                        # .. e1 :
83         /* find correct sign for result.  */
84         xor     a1, a2, compare                 # e0    :
85         negq    quotient, tmp1                  # .. e1 :
86         negq    modulus, tmp2                   # e0    :
87         cmovlt  compare, tmp1, quotient         # .. e1 :
88         cmovlt  a1, tmp2, modulus               # e1    :
90         /* and store it away in the structure.  */
91 9:      stq     quotient, 0(a0)                 # .. e0 :
92         mov     a0, v0                          # e1    :
93         stq     modulus, 8(a0)                  # .. e0 :
94         ret                                     # e1    :
96 $divbyzero:
97         mov     a0, v0
98         lda     a0, GEN_INTDIV
99         call_pal PAL_gentrap
101         /* if trap returns, return zero.  */
102         stq     zero, 0(v0)
103         stq     zero, 8(v0)
104         ret
106         .end ldiv
108 weak_alias(ldiv, lldiv)
109 weak_alias(ldiv, imaxdiv)