[project @ 1998-06-05 14:37:55 by simonm]
authorsimonm <unknown>
Fri, 5 Jun 1998 14:37:55 +0000 (14:37 +0000)
committersimonm <unknown>
Fri, 5 Jun 1998 14:37:55 +0000 (14:37 +0000)
Initial revision

ghc/rts/gmp/mpn/sparc32/add_n.S [new file with mode: 0644]
ghc/rts/gmp/mpn/sparc32/addmul_1.S [new file with mode: 0644]
ghc/rts/gmp/mpn/sparc32/lshift.S [new file with mode: 0644]
ghc/rts/gmp/mpn/sparc32/mul_1.S [new file with mode: 0644]
ghc/rts/gmp/mpn/sparc32/rshift.S [new file with mode: 0644]
ghc/rts/gmp/mpn/sparc32/sub_n.S [new file with mode: 0644]
ghc/rts/gmp/mpn/sparc32/submul_1.S [new file with mode: 0644]
ghc/rts/gmp/mpn/sparc32/udiv_fp.S [new file with mode: 0644]
ghc/rts/gmp/mpn/sparc32/udiv_nfp.S [new file with mode: 0644]

diff --git a/ghc/rts/gmp/mpn/sparc32/add_n.S b/ghc/rts/gmp/mpn/sparc32/add_n.S
new file mode 100644 (file)
index 0000000..9852c25
--- /dev/null
@@ -0,0 +1,226 @@
+! SPARC __mpn_add_n -- Add two limb vectors of the same length > 0 and store
+! sum in a third limb vector.
+
+! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+#define res_ptr        %o0
+#define s1_ptr %o1
+#define s2_ptr %o2
+#define size   %o3
+
+#include "sysdep.h"
+
+       .text
+       .align  4
+       .global C_SYMBOL_NAME(__mpn_add_n)
+C_SYMBOL_NAME(__mpn_add_n):
+       xor     s2_ptr,res_ptr,%g1
+       andcc   %g1,4,%g0
+       bne     L1                      ! branch if alignment differs
+       nop
+! **  V1a  **
+L0:    andcc   res_ptr,4,%g0           ! res_ptr unaligned? Side effect: cy=0
+       be      L_v1                    ! if no, branch
+       nop
+/* Add least significant limb separately to align res_ptr and s2_ptr */
+       ld      [s1_ptr],%g4
+       add     s1_ptr,4,s1_ptr
+       ld      [s2_ptr],%g2
+       add     s2_ptr,4,s2_ptr
+       add     size,-1,size
+       addcc   %g4,%g2,%o4
+       st      %o4,[res_ptr]
+       add     res_ptr,4,res_ptr
+L_v1:  addx    %g0,%g0,%o4             ! save cy in register
+       cmp     size,2                  ! if size < 2 ...
+       bl      Lend2                   ! ... branch to tail code
+       subcc   %g0,%o4,%g0             ! restore cy
+
+       ld      [s1_ptr+0],%g4
+       addcc   size,-10,size
+       ld      [s1_ptr+4],%g1
+       ldd     [s2_ptr+0],%g2
+       blt     Lfin1
+       subcc   %g0,%o4,%g0             ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+Loop1: addxcc  %g4,%g2,%o4
+       ld      [s1_ptr+8],%g4
+       addxcc  %g1,%g3,%o5
+       ld      [s1_ptr+12],%g1
+       ldd     [s2_ptr+8],%g2
+       std     %o4,[res_ptr+0]
+       addxcc  %g4,%g2,%o4
+       ld      [s1_ptr+16],%g4
+       addxcc  %g1,%g3,%o5
+       ld      [s1_ptr+20],%g1
+       ldd     [s2_ptr+16],%g2
+       std     %o4,[res_ptr+8]
+       addxcc  %g4,%g2,%o4
+       ld      [s1_ptr+24],%g4
+       addxcc  %g1,%g3,%o5
+       ld      [s1_ptr+28],%g1
+       ldd     [s2_ptr+24],%g2
+       std     %o4,[res_ptr+16]
+       addxcc  %g4,%g2,%o4
+       ld      [s1_ptr+32],%g4
+       addxcc  %g1,%g3,%o5
+       ld      [s1_ptr+36],%g1
+       ldd     [s2_ptr+32],%g2
+       std     %o4,[res_ptr+24]
+       addx    %g0,%g0,%o4             ! save cy in register
+       addcc   size,-8,size
+       add     s1_ptr,32,s1_ptr
+       add     s2_ptr,32,s2_ptr
+       add     res_ptr,32,res_ptr
+       bge     Loop1
+       subcc   %g0,%o4,%g0             ! restore cy
+
+Lfin1: addcc   size,8-2,size
+       blt     Lend1
+       subcc   %g0,%o4,%g0             ! restore cy
+/* Add blocks of 2 limbs until less than 2 limbs remain */
+Loope1:        addxcc  %g4,%g2,%o4
+       ld      [s1_ptr+8],%g4
+       addxcc  %g1,%g3,%o5
+       ld      [s1_ptr+12],%g1
+       ldd     [s2_ptr+8],%g2
+       std     %o4,[res_ptr+0]
+       addx    %g0,%g0,%o4             ! save cy in register
+       addcc   size,-2,size
+       add     s1_ptr,8,s1_ptr
+       add     s2_ptr,8,s2_ptr
+       add     res_ptr,8,res_ptr
+       bge     Loope1
+       subcc   %g0,%o4,%g0             ! restore cy
+Lend1: addxcc  %g4,%g2,%o4
+       addxcc  %g1,%g3,%o5
+       std     %o4,[res_ptr+0]
+       addx    %g0,%g0,%o4             ! save cy in register
+
+       andcc   size,1,%g0
+       be      Lret1
+       subcc   %g0,%o4,%g0             ! restore cy
+/* Add last limb */
+       ld      [s1_ptr+8],%g4
+       ld      [s2_ptr+8],%g2
+       addxcc  %g4,%g2,%o4
+       st      %o4,[res_ptr+8]
+
+Lret1: retl
+       addx    %g0,%g0,%o0     ! return carry-out from most sign. limb
+
+L1:    xor     s1_ptr,res_ptr,%g1
+       andcc   %g1,4,%g0
+       bne     L2
+       nop
+! **  V1b  **
+       mov     s2_ptr,%g1
+       mov     s1_ptr,s2_ptr
+       b       L0
+       mov     %g1,s1_ptr
+
+! **  V2  **
+/* If we come here, the alignment of s1_ptr and res_ptr as well as the
+   alignment of s2_ptr and res_ptr differ.  Since there are only two ways
+   things can be aligned (that we care about) we now know that the alignment
+   of s1_ptr and s2_ptr are the same.  */
+
+L2:    cmp     size,1
+       be      Ljone
+       nop
+       andcc   s1_ptr,4,%g0            ! s1_ptr unaligned? Side effect: cy=0
+       be      L_v2                    ! if no, branch
+       nop
+/* Add least significant limb separately to align s1_ptr and s2_ptr */
+       ld      [s1_ptr],%g4
+       add     s1_ptr,4,s1_ptr
+       ld      [s2_ptr],%g2
+       add     s2_ptr,4,s2_ptr
+       add     size,-1,size
+       addcc   %g4,%g2,%o4
+       st      %o4,[res_ptr]
+       add     res_ptr,4,res_ptr
+
+L_v2:  addx    %g0,%g0,%o4             ! save cy in register
+       addcc   size,-8,size
+       blt     Lfin2
+       subcc   %g0,%o4,%g0             ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+Loop2: ldd     [s1_ptr+0],%g2
+       ldd     [s2_ptr+0],%o4
+       addxcc  %g2,%o4,%g2
+       st      %g2,[res_ptr+0]
+       addxcc  %g3,%o5,%g3
+       st      %g3,[res_ptr+4]
+       ldd     [s1_ptr+8],%g2
+       ldd     [s2_ptr+8],%o4
+       addxcc  %g2,%o4,%g2
+       st      %g2,[res_ptr+8]
+       addxcc  %g3,%o5,%g3
+       st      %g3,[res_ptr+12]
+       ldd     [s1_ptr+16],%g2
+       ldd     [s2_ptr+16],%o4
+       addxcc  %g2,%o4,%g2
+       st      %g2,[res_ptr+16]
+       addxcc  %g3,%o5,%g3
+       st      %g3,[res_ptr+20]
+       ldd     [s1_ptr+24],%g2
+       ldd     [s2_ptr+24],%o4
+       addxcc  %g2,%o4,%g2
+       st      %g2,[res_ptr+24]
+       addxcc  %g3,%o5,%g3
+       st      %g3,[res_ptr+28]
+       addx    %g0,%g0,%o4             ! save cy in register
+       addcc   size,-8,size
+       add     s1_ptr,32,s1_ptr
+       add     s2_ptr,32,s2_ptr
+       add     res_ptr,32,res_ptr
+       bge     Loop2
+       subcc   %g0,%o4,%g0             ! restore cy
+
+Lfin2: addcc   size,8-2,size
+       blt     Lend2
+       subcc   %g0,%o4,%g0             ! restore cy
+Loope2:        ldd     [s1_ptr+0],%g2
+       ldd     [s2_ptr+0],%o4
+       addxcc  %g2,%o4,%g2
+       st      %g2,[res_ptr+0]
+       addxcc  %g3,%o5,%g3
+       st      %g3,[res_ptr+4]
+       addx    %g0,%g0,%o4             ! save cy in register
+       addcc   size,-2,size
+       add     s1_ptr,8,s1_ptr
+       add     s2_ptr,8,s2_ptr
+       add     res_ptr,8,res_ptr
+       bge     Loope2
+       subcc   %g0,%o4,%g0             ! restore cy
+Lend2: andcc   size,1,%g0
+       be      Lret2
+       subcc   %g0,%o4,%g0             ! restore cy
+/* Add last limb */
+Ljone: ld      [s1_ptr],%g4
+       ld      [s2_ptr],%g2
+       addxcc  %g4,%g2,%o4
+       st      %o4,[res_ptr]
+
+Lret2: retl
+       addx    %g0,%g0,%o0     ! return carry-out from most sign. limb
diff --git a/ghc/rts/gmp/mpn/sparc32/addmul_1.S b/ghc/rts/gmp/mpn/sparc32/addmul_1.S
new file mode 100644 (file)
index 0000000..375d25d
--- /dev/null
@@ -0,0 +1,147 @@
+! SPARC __mpn_addmul_1 -- Multiply a limb vector with a limb and add
+! the result to a second limb vector.
+
+! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! res_ptr      o0
+! s1_ptr       o1
+! size         o2
+! s2_limb      o3
+
+#include "sysdep.h"
+
+.text
+       .align 4
+       .global C_SYMBOL_NAME(__mpn_addmul_1)
+C_SYMBOL_NAME(__mpn_addmul_1):
+       ! Make S1_PTR and RES_PTR point at the end of their blocks
+       ! and put (- 4 x SIZE) in index/loop counter.
+       sll     %o2,2,%o2
+       add     %o0,%o2,%o4     ! RES_PTR in o4 since o0 is retval
+       add     %o1,%o2,%o1
+       sub     %g0,%o2,%o2
+
+       cmp     %o3,0xfff
+       bgu     Large
+       nop
+
+       ld      [%o1+%o2],%o5
+       mov     0,%o0
+       b       L0
+        add    %o4,-4,%o4
+Loop0:
+       addcc   %o5,%g1,%g1
+       ld      [%o1+%o2],%o5
+       addx    %o0,%g0,%o0
+       st      %g1,[%o4+%o2]
+L0:    wr      %g0,%o3,%y
+       sra     %o5,31,%g2
+       and     %o3,%g2,%g2
+       andcc   %g1,0,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,0,%g1
+       sra     %g1,20,%g4
+       sll     %g1,12,%g1
+       rd      %y,%g3
+       srl     %g3,20,%g3
+       or      %g1,%g3,%g1
+
+       addcc   %g1,%o0,%g1
+       addx    %g2,%g4,%o0     ! add sign-compensation and cy to hi limb
+       addcc   %o2,4,%o2       ! loop counter
+       bne     Loop0
+        ld     [%o4+%o2],%o5
+
+       addcc   %o5,%g1,%g1
+       addx    %o0,%g0,%o0
+       retl
+       st      %g1,[%o4+%o2]
+
+
+Large: ld      [%o1+%o2],%o5
+       mov     0,%o0
+       sra     %o3,31,%g4      ! g4 = mask of ones iff S2_LIMB < 0
+       b       L1
+        add    %o4,-4,%o4
+Loop:
+       addcc   %o5,%g3,%g3
+       ld      [%o1+%o2],%o5
+       addx    %o0,%g0,%o0
+       st      %g3,[%o4+%o2]
+L1:    wr      %g0,%o5,%y
+       and     %o5,%g4,%g2
+       andcc   %g0,%g0,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%g0,%g1
+       rd      %y,%g3
+       addcc   %g3,%o0,%g3
+       addx    %g2,%g1,%o0
+       addcc   %o2,4,%o2
+       bne     Loop
+        ld     [%o4+%o2],%o5
+
+       addcc   %o5,%g3,%g3
+       addx    %o0,%g0,%o0
+       retl
+       st      %g3,[%o4+%o2]
diff --git a/ghc/rts/gmp/mpn/sparc32/lshift.S b/ghc/rts/gmp/mpn/sparc32/lshift.S
new file mode 100644 (file)
index 0000000..4f0595f
--- /dev/null
@@ -0,0 +1,95 @@
+! sparc __mpn_lshift --
+
+! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! res_ptr      %o0
+! src_ptr      %o1
+! size         %o2
+! cnt          %o3
+
+#include "sysdep.h"
+
+       .text
+       .align  4
+       .global C_SYMBOL_NAME(__mpn_lshift)
+C_SYMBOL_NAME(__mpn_lshift):
+       sll     %o2,2,%g1
+       add     %o1,%g1,%o1     ! make %o1 point at end of src
+       ld      [%o1-4],%g2     ! load first limb
+       sub     %g0,%o3,%o5     ! negate shift count
+       add     %o0,%g1,%o0     ! make %o0 point at end of res
+       add     %o2,-1,%o2
+       andcc   %o2,4-1,%g4     ! number of limbs in first loop
+       srl     %g2,%o5,%g1     ! compute function result
+       be      L0              ! if multiple of 4 limbs, skip first loop
+       st      %g1,[%sp+80]
+
+       sub     %o2,%g4,%o2     ! adjust count for main loop
+
+Loop0: ld      [%o1-8],%g3
+       add     %o0,-4,%o0
+       add     %o1,-4,%o1
+       addcc   %g4,-1,%g4
+       sll     %g2,%o3,%o4
+       srl     %g3,%o5,%g1
+       mov     %g3,%g2
+       or      %o4,%g1,%o4
+       bne     Loop0
+        st     %o4,[%o0+0]
+
+L0:    tst     %o2
+       be      Lend
+        nop
+
+Loop:  ld      [%o1-8],%g3
+       add     %o0,-16,%o0
+       addcc   %o2,-4,%o2
+       sll     %g2,%o3,%o4
+       srl     %g3,%o5,%g1
+
+       ld      [%o1-12],%g2
+       sll     %g3,%o3,%g4
+       or      %o4,%g1,%o4
+       st      %o4,[%o0+12]
+       srl     %g2,%o5,%g1
+
+       ld      [%o1-16],%g3
+       sll     %g2,%o3,%o4
+       or      %g4,%g1,%g4
+       st      %g4,[%o0+8]
+       srl     %g3,%o5,%g1
+
+       ld      [%o1-20],%g2
+       sll     %g3,%o3,%g4
+       or      %o4,%g1,%o4
+       st      %o4,[%o0+4]
+       srl     %g2,%o5,%g1
+
+       add     %o1,-16,%o1
+       or      %g4,%g1,%g4
+       bne     Loop
+        st     %g4,[%o0+0]
+
+Lend:  sll     %g2,%o3,%g2
+       st      %g2,[%o0-4]
+       retl
+       ld      [%sp+80],%o0
diff --git a/ghc/rts/gmp/mpn/sparc32/mul_1.S b/ghc/rts/gmp/mpn/sparc32/mul_1.S
new file mode 100644 (file)
index 0000000..142fd8b
--- /dev/null
@@ -0,0 +1,199 @@
+! SPARC __mpn_mul_1 -- Multiply a limb vector with a limb and store
+! the result in a second limb vector.
+
+! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! res_ptr      o0
+! s1_ptr       o1
+! size         o2
+! s2_limb      o3
+
+! ADD CODE FOR SMALL MULTIPLIERS!
+!1:    ld
+!      st
+!
+!2:    ld      ,a
+!      addxcc  a,a,x
+!      st      x,
+!
+!3_unrolled:
+!      ld      ,a
+!      addxcc  a,a,x1          ! 2a + cy
+!      addx    %g0,%g0,x2
+!      addcc   a,x1,x          ! 3a + c
+!      st      x,
+!
+!      ld      ,a
+!      addxcc  a,a,y1
+!      addx    %g0,%g0,y2
+!      addcc   a,y1,x
+!      st      x,
+!
+!4_unrolled:
+!      ld      ,a
+!      srl     a,2,x1          ! 4a
+!      addxcc  y2,x1,x
+!      sll     a,30,x2
+!      st      x,
+!
+!      ld      ,a
+!      srl     a,2,y1
+!      addxcc  x2,y1,y
+!      sll     a,30,y2
+!      st      x,
+!
+!5_unrolled:
+!      ld      ,a
+!      srl     a,2,x1          ! 4a
+!      addxcc  a,x1,x          ! 5a + c
+!      sll     a,30,x2
+!      addx    %g0,x2,x2
+!      st      x,
+!
+!      ld      ,a
+!      srl     a,2,y1
+!      addxcc  a,y1,x
+!      sll     a,30,y2
+!      addx    %g0,y2,y2
+!      st      x,
+!
+!8_unrolled:
+!      ld      ,a
+!      srl     a,3,x1          ! 8a
+!      addxcc  y2,x1,x
+!      sll     a,29,x2
+!      st      x,
+!
+!      ld      ,a
+!      srl     a,3,y1
+!      addxcc  x2,y1,y
+!      sll     a,29,y2
+!      st      x,
+
+#include "sysdep.h"
+
+.text
+       .align 4
+       .global C_SYMBOL_NAME(__mpn_mul_1)
+C_SYMBOL_NAME(__mpn_mul_1):
+       ! Make S1_PTR and RES_PTR point at the end of their blocks
+       ! and put (- 4 x SIZE) in index/loop counter.
+       sll     %o2,2,%o2
+       add     %o0,%o2,%o4     ! RES_PTR in o4 since o0 is retval
+       add     %o1,%o2,%o1
+       sub     %g0,%o2,%o2
+
+       cmp     %o3,0xfff
+       bgu     Large
+       nop
+
+       ld      [%o1+%o2],%o5
+       mov     0,%o0
+       b       L0
+        add    %o4,-4,%o4
+Loop0:
+       st      %g1,[%o4+%o2]
+L0:    wr      %g0,%o3,%y
+       sra     %o5,31,%g2
+       and     %o3,%g2,%g2
+       andcc   %g1,0,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,0,%g1
+       sra     %g1,20,%g4
+       sll     %g1,12,%g1
+       rd      %y,%g3
+       srl     %g3,20,%g3
+       or      %g1,%g3,%g1
+
+       addcc   %g1,%o0,%g1
+       addx    %g2,%g4,%o0     ! add sign-compensation and cy to hi limb
+       addcc   %o2,4,%o2       ! loop counter
+       bne,a   Loop0
+        ld     [%o1+%o2],%o5
+
+       retl
+       st      %g1,[%o4+%o2]
+
+
+Large: ld      [%o1+%o2],%o5
+       mov     0,%o0
+       sra     %o3,31,%g4      ! g4 = mask of ones iff S2_LIMB < 0
+       b       L1
+        add    %o4,-4,%o4
+Loop:
+       st      %g3,[%o4+%o2]
+L1:    wr      %g0,%o5,%y
+       and     %o5,%g4,%g2     ! g2 = S1_LIMB iff S2_LIMB < 0, else 0
+       andcc   %g0,%g0,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%g0,%g1
+       rd      %y,%g3
+       addcc   %g3,%o0,%g3
+       addx    %g2,%g1,%o0     ! add sign-compensation and cy to hi limb
+       addcc   %o2,4,%o2       ! loop counter
+       bne,a   Loop
+        ld     [%o1+%o2],%o5
+
+       retl
+       st      %g3,[%o4+%o2]
diff --git a/ghc/rts/gmp/mpn/sparc32/rshift.S b/ghc/rts/gmp/mpn/sparc32/rshift.S
new file mode 100644 (file)
index 0000000..fea4f3b
--- /dev/null
@@ -0,0 +1,92 @@
+! sparc __mpn_rshift --
+
+! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! res_ptr      %o0
+! src_ptr      %o1
+! size         %o2
+! cnt          %o3
+
+#include "sysdep.h"
+
+       .text
+       .align  4
+       .global C_SYMBOL_NAME(__mpn_rshift)
+C_SYMBOL_NAME(__mpn_rshift):
+       ld      [%o1],%g2       ! load first limb
+       sub     %g0,%o3,%o5     ! negate shift count
+       add     %o2,-1,%o2
+       andcc   %o2,4-1,%g4     ! number of limbs in first loop
+       sll     %g2,%o5,%g1     ! compute function result
+       be      L0              ! if multiple of 4 limbs, skip first loop
+       st      %g1,[%sp+80]
+
+       sub     %o2,%g4,%o2     ! adjust count for main loop
+
+Loop0: ld      [%o1+4],%g3
+       add     %o0,4,%o0
+       add     %o1,4,%o1
+       addcc   %g4,-1,%g4
+       srl     %g2,%o3,%o4
+       sll     %g3,%o5,%g1
+       mov     %g3,%g2
+       or      %o4,%g1,%o4
+       bne     Loop0
+        st     %o4,[%o0-4]
+
+L0:    tst     %o2
+       be      Lend
+        nop
+
+Loop:  ld      [%o1+4],%g3
+       add     %o0,16,%o0
+       addcc   %o2,-4,%o2
+       srl     %g2,%o3,%o4
+       sll     %g3,%o5,%g1
+
+       ld      [%o1+8],%g2
+       srl     %g3,%o3,%g4
+       or      %o4,%g1,%o4
+       st      %o4,[%o0-16]
+       sll     %g2,%o5,%g1
+
+       ld      [%o1+12],%g3
+       srl     %g2,%o3,%o4
+       or      %g4,%g1,%g4
+       st      %g4,[%o0-12]
+       sll     %g3,%o5,%g1
+
+       ld      [%o1+16],%g2
+       srl     %g3,%o3,%g4
+       or      %o4,%g1,%o4
+       st      %o4,[%o0-8]
+       sll     %g2,%o5,%g1
+
+       add     %o1,16,%o1
+       or      %g4,%g1,%g4
+       bne     Loop
+        st     %g4,[%o0-4]
+
+Lend:  srl     %g2,%o3,%g2
+       st      %g2,[%o0-0]
+       retl
+       ld      [%sp+80],%o0
diff --git a/ghc/rts/gmp/mpn/sparc32/sub_n.S b/ghc/rts/gmp/mpn/sparc32/sub_n.S
new file mode 100644 (file)
index 0000000..b7a1195
--- /dev/null
@@ -0,0 +1,311 @@
+! SPARC __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+! store difference in a third limb vector.
+
+! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+#define res_ptr        %o0
+#define s1_ptr %o1
+#define s2_ptr %o2
+#define size   %o3
+
+#include "sysdep.h"
+
+       .text
+       .align  4
+       .global C_SYMBOL_NAME(__mpn_sub_n)
+C_SYMBOL_NAME(__mpn_sub_n):
+       xor     s2_ptr,res_ptr,%g1
+       andcc   %g1,4,%g0
+       bne     L1                      ! branch if alignment differs
+       nop
+! **  V1a  **
+       andcc   res_ptr,4,%g0           ! res_ptr unaligned? Side effect: cy=0
+       be      L_v1                    ! if no, branch
+       nop
+/* Add least significant limb separately to align res_ptr and s2_ptr */
+       ld      [s1_ptr],%g4
+       add     s1_ptr,4,s1_ptr
+       ld      [s2_ptr],%g2
+       add     s2_ptr,4,s2_ptr
+       add     size,-1,size
+       subcc   %g4,%g2,%o4
+       st      %o4,[res_ptr]
+       add     res_ptr,4,res_ptr
+L_v1:  addx    %g0,%g0,%o4             ! save cy in register
+       cmp     size,2                  ! if size < 2 ...
+       bl      Lend2                   ! ... branch to tail code
+       subcc   %g0,%o4,%g0             ! restore cy
+
+       ld      [s1_ptr+0],%g4
+       addcc   size,-10,size
+       ld      [s1_ptr+4],%g1
+       ldd     [s2_ptr+0],%g2
+       blt     Lfin1
+       subcc   %g0,%o4,%g0             ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+Loop1: subxcc  %g4,%g2,%o4
+       ld      [s1_ptr+8],%g4
+       subxcc  %g1,%g3,%o5
+       ld      [s1_ptr+12],%g1
+       ldd     [s2_ptr+8],%g2
+       std     %o4,[res_ptr+0]
+       subxcc  %g4,%g2,%o4
+       ld      [s1_ptr+16],%g4
+       subxcc  %g1,%g3,%o5
+       ld      [s1_ptr+20],%g1
+       ldd     [s2_ptr+16],%g2
+       std     %o4,[res_ptr+8]
+       subxcc  %g4,%g2,%o4
+       ld      [s1_ptr+24],%g4
+       subxcc  %g1,%g3,%o5
+       ld      [s1_ptr+28],%g1
+       ldd     [s2_ptr+24],%g2
+       std     %o4,[res_ptr+16]
+       subxcc  %g4,%g2,%o4
+       ld      [s1_ptr+32],%g4
+       subxcc  %g1,%g3,%o5
+       ld      [s1_ptr+36],%g1
+       ldd     [s2_ptr+32],%g2
+       std     %o4,[res_ptr+24]
+       addx    %g0,%g0,%o4             ! save cy in register
+       addcc   size,-8,size
+       add     s1_ptr,32,s1_ptr
+       add     s2_ptr,32,s2_ptr
+       add     res_ptr,32,res_ptr
+       bge     Loop1
+       subcc   %g0,%o4,%g0             ! restore cy
+
+Lfin1: addcc   size,8-2,size
+       blt     Lend1
+       subcc   %g0,%o4,%g0             ! restore cy
+/* Add blocks of 2 limbs until less than 2 limbs remain */
+Loope1:        subxcc  %g4,%g2,%o4
+       ld      [s1_ptr+8],%g4
+       subxcc  %g1,%g3,%o5
+       ld      [s1_ptr+12],%g1
+       ldd     [s2_ptr+8],%g2
+       std     %o4,[res_ptr+0]
+       addx    %g0,%g0,%o4             ! save cy in register
+       addcc   size,-2,size
+       add     s1_ptr,8,s1_ptr
+       add     s2_ptr,8,s2_ptr
+       add     res_ptr,8,res_ptr
+       bge     Loope1
+       subcc   %g0,%o4,%g0             ! restore cy
+Lend1: subxcc  %g4,%g2,%o4
+       subxcc  %g1,%g3,%o5
+       std     %o4,[res_ptr+0]
+       addx    %g0,%g0,%o4             ! save cy in register
+
+       andcc   size,1,%g0
+       be      Lret1
+       subcc   %g0,%o4,%g0             ! restore cy
+/* Add last limb */
+       ld      [s1_ptr+8],%g4
+       ld      [s2_ptr+8],%g2
+       subxcc  %g4,%g2,%o4
+       st      %o4,[res_ptr+8]
+
+Lret1: retl
+       addx    %g0,%g0,%o0     ! return carry-out from most sign. limb
+
+L1:    xor     s1_ptr,res_ptr,%g1
+       andcc   %g1,4,%g0
+       bne     L2
+       nop
+! **  V1b  **
+       andcc   res_ptr,4,%g0           ! res_ptr unaligned? Side effect: cy=0
+       be      L_v1b                   ! if no, branch
+       nop
+/* Add least significant limb separately to align res_ptr and s1_ptr */
+       ld      [s2_ptr],%g4
+       add     s2_ptr,4,s2_ptr
+       ld      [s1_ptr],%g2
+       add     s1_ptr,4,s1_ptr
+       add     size,-1,size
+       subcc   %g2,%g4,%o4
+       st      %o4,[res_ptr]
+       add     res_ptr,4,res_ptr
+L_v1b: addx    %g0,%g0,%o4             ! save cy in register
+       cmp     size,2                  ! if size < 2 ...
+       bl      Lend2                   ! ... branch to tail code
+       subcc   %g0,%o4,%g0             ! restore cy
+
+       ld      [s2_ptr+0],%g4
+       addcc   size,-10,size
+       ld      [s2_ptr+4],%g1
+       ldd     [s1_ptr+0],%g2
+       blt     Lfin1b
+       subcc   %g0,%o4,%g0             ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+Loop1b:        subxcc  %g2,%g4,%o4
+       ld      [s2_ptr+8],%g4
+       subxcc  %g3,%g1,%o5
+       ld      [s2_ptr+12],%g1
+       ldd     [s1_ptr+8],%g2
+       std     %o4,[res_ptr+0]
+       subxcc  %g2,%g4,%o4
+       ld      [s2_ptr+16],%g4
+       subxcc  %g3,%g1,%o5
+       ld      [s2_ptr+20],%g1
+       ldd     [s1_ptr+16],%g2
+       std     %o4,[res_ptr+8]
+       subxcc  %g2,%g4,%o4
+       ld      [s2_ptr+24],%g4
+       subxcc  %g3,%g1,%o5
+       ld      [s2_ptr+28],%g1
+       ldd     [s1_ptr+24],%g2
+       std     %o4,[res_ptr+16]
+       subxcc  %g2,%g4,%o4
+       ld      [s2_ptr+32],%g4
+       subxcc  %g3,%g1,%o5
+       ld      [s2_ptr+36],%g1
+       ldd     [s1_ptr+32],%g2
+       std     %o4,[res_ptr+24]
+       addx    %g0,%g0,%o4             ! save cy in register
+       addcc   size,-8,size
+       add     s1_ptr,32,s1_ptr
+       add     s2_ptr,32,s2_ptr
+       add     res_ptr,32,res_ptr
+       bge     Loop1b
+       subcc   %g0,%o4,%g0             ! restore cy
+
+Lfin1b:        addcc   size,8-2,size
+       blt     Lend1b
+       subcc   %g0,%o4,%g0             ! restore cy
+/* Add blocks of 2 limbs until less than 2 limbs remain */
+Loope1b:subxcc %g2,%g4,%o4
+       ld      [s2_ptr+8],%g4
+       subxcc  %g3,%g1,%o5
+       ld      [s2_ptr+12],%g1
+       ldd     [s1_ptr+8],%g2
+       std     %o4,[res_ptr+0]
+       addx    %g0,%g0,%o4             ! save cy in register
+       addcc   size,-2,size
+       add     s1_ptr,8,s1_ptr
+       add     s2_ptr,8,s2_ptr
+       add     res_ptr,8,res_ptr
+       bge     Loope1b
+       subcc   %g0,%o4,%g0             ! restore cy
+Lend1b:        subxcc  %g2,%g4,%o4
+       subxcc  %g3,%g1,%o5
+       std     %o4,[res_ptr+0]
+       addx    %g0,%g0,%o4             ! save cy in register
+
+       andcc   size,1,%g0
+       be      Lret1b
+       subcc   %g0,%o4,%g0             ! restore cy
+/* Add last limb */
+       ld      [s2_ptr+8],%g4
+       ld      [s1_ptr+8],%g2
+       subxcc  %g2,%g4,%o4
+       st      %o4,[res_ptr+8]
+
+Lret1b:        retl
+       addx    %g0,%g0,%o0     ! return carry-out from most sign. limb
+
+! **  V2  **
+/* If we come here, the alignment of s1_ptr and res_ptr as well as the
+   alignment of s2_ptr and res_ptr differ.  Since there are only two ways
+   things can be aligned (that we care about) we now know that the alignment
+   of s1_ptr and s2_ptr are the same.  */
+
+L2:    cmp     size,1
+       be      Ljone
+       nop
+       andcc   s1_ptr,4,%g0            ! s1_ptr unaligned? Side effect: cy=0
+       be      L_v2                    ! if no, branch
+       nop
+/* Add least significant limb separately to align s1_ptr and s2_ptr */
+       ld      [s1_ptr],%g4
+       add     s1_ptr,4,s1_ptr
+       ld      [s2_ptr],%g2
+       add     s2_ptr,4,s2_ptr
+       add     size,-1,size
+       subcc   %g4,%g2,%o4
+       st      %o4,[res_ptr]
+       add     res_ptr,4,res_ptr
+
+L_v2:  addx    %g0,%g0,%o4             ! save cy in register
+       addcc   size,-8,size
+       blt     Lfin2
+       subcc   %g0,%o4,%g0             ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+Loop2: ldd     [s1_ptr+0],%g2
+       ldd     [s2_ptr+0],%o4
+       subxcc  %g2,%o4,%g2
+       st      %g2,[res_ptr+0]
+       subxcc  %g3,%o5,%g3
+       st      %g3,[res_ptr+4]
+       ldd     [s1_ptr+8],%g2
+       ldd     [s2_ptr+8],%o4
+       subxcc  %g2,%o4,%g2
+       st      %g2,[res_ptr+8]
+       subxcc  %g3,%o5,%g3
+       st      %g3,[res_ptr+12]
+       ldd     [s1_ptr+16],%g2
+       ldd     [s2_ptr+16],%o4
+       subxcc  %g2,%o4,%g2
+       st      %g2,[res_ptr+16]
+       subxcc  %g3,%o5,%g3
+       st      %g3,[res_ptr+20]
+       ldd     [s1_ptr+24],%g2
+       ldd     [s2_ptr+24],%o4
+       subxcc  %g2,%o4,%g2
+       st      %g2,[res_ptr+24]
+       subxcc  %g3,%o5,%g3
+       st      %g3,[res_ptr+28]
+       addx    %g0,%g0,%o4             ! save cy in register
+       addcc   size,-8,size
+       add     s1_ptr,32,s1_ptr
+       add     s2_ptr,32,s2_ptr
+       add     res_ptr,32,res_ptr
+       bge     Loop2
+       subcc   %g0,%o4,%g0             ! restore cy
+
+Lfin2: addcc   size,8-2,size
+       blt     Lend2
+       subcc   %g0,%o4,%g0             ! restore cy
+Loope2:        ldd     [s1_ptr+0],%g2
+       ldd     [s2_ptr+0],%o4
+       subxcc  %g2,%o4,%g2
+       st      %g2,[res_ptr+0]
+       subxcc  %g3,%o5,%g3
+       st      %g3,[res_ptr+4]
+       addx    %g0,%g0,%o4             ! save cy in register
+       addcc   size,-2,size
+       add     s1_ptr,8,s1_ptr
+       add     s2_ptr,8,s2_ptr
+       add     res_ptr,8,res_ptr
+       bge     Loope2
+       subcc   %g0,%o4,%g0             ! restore cy
+Lend2: andcc   size,1,%g0
+       be      Lret2
+       subcc   %g0,%o4,%g0             ! restore cy
+/* Add last limb */
+Ljone: ld      [s1_ptr],%g4
+       ld      [s2_ptr],%g2
+       subxcc  %g4,%g2,%o4
+       st      %o4,[res_ptr]
+
+Lret2: retl
+       addx    %g0,%g0,%o0     ! return carry-out from most sign. limb
diff --git a/ghc/rts/gmp/mpn/sparc32/submul_1.S b/ghc/rts/gmp/mpn/sparc32/submul_1.S
new file mode 100644 (file)
index 0000000..a8ebd50
--- /dev/null
@@ -0,0 +1,147 @@
+! SPARC __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
+! the result from a second limb vector.
+
+! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! res_ptr      o0
+! s1_ptr       o1
+! size         o2
+! s2_limb      o3
+
+#include "sysdep.h"
+
+.text
+       .align 4
+       .global C_SYMBOL_NAME(__mpn_submul_1)
+C_SYMBOL_NAME(__mpn_submul_1):
+       ! Make S1_PTR and RES_PTR point at the end of their blocks
+       ! and put (- 4 x SIZE) in index/loop counter.
+       sll     %o2,2,%o2
+       add     %o0,%o2,%o4     ! RES_PTR in o4 since o0 is retval
+       add     %o1,%o2,%o1
+       sub     %g0,%o2,%o2
+
+       cmp     %o3,0xfff
+       bgu     Large
+       nop
+
+       ld      [%o1+%o2],%o5
+       mov     0,%o0
+       b       L0
+        add    %o4,-4,%o4
+Loop0:
+       subcc   %o5,%g1,%g1
+       ld      [%o1+%o2],%o5
+       addx    %o0,%g0,%o0
+       st      %g1,[%o4+%o2]
+L0:    wr      %g0,%o3,%y
+       sra     %o5,31,%g2
+       and     %o3,%g2,%g2
+       andcc   %g1,0,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,%o5,%g1
+       mulscc  %g1,0,%g1
+       sra     %g1,20,%g4
+       sll     %g1,12,%g1
+       rd      %y,%g3
+       srl     %g3,20,%g3
+       or      %g1,%g3,%g1
+
+       addcc   %g1,%o0,%g1
+       addx    %g2,%g4,%o0     ! add sign-compensation and cy to hi limb
+       addcc   %o2,4,%o2       ! loop counter
+       bne     Loop0
+        ld     [%o4+%o2],%o5
+
+       subcc   %o5,%g1,%g1
+       addx    %o0,%g0,%o0
+       retl
+       st      %g1,[%o4+%o2]
+
+
+Large: ld      [%o1+%o2],%o5
+       mov     0,%o0
+       sra     %o3,31,%g4      ! g4 = mask of ones iff S2_LIMB < 0
+       b       L1
+        add    %o4,-4,%o4
+Loop:
+       subcc   %o5,%g3,%g3
+       ld      [%o1+%o2],%o5
+       addx    %o0,%g0,%o0
+       st      %g3,[%o4+%o2]
+L1:    wr      %g0,%o5,%y
+       and     %o5,%g4,%g2
+       andcc   %g0,%g0,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%o3,%g1
+       mulscc  %g1,%g0,%g1
+       rd      %y,%g3
+       addcc   %g3,%o0,%g3
+       addx    %g2,%g1,%o0
+       addcc   %o2,4,%o2
+       bne     Loop
+        ld     [%o4+%o2],%o5
+
+       subcc   %o5,%g3,%g3
+       addx    %o0,%g0,%o0
+       retl
+       st      %g3,[%o4+%o2]
diff --git a/ghc/rts/gmp/mpn/sparc32/udiv_fp.S b/ghc/rts/gmp/mpn/sparc32/udiv_fp.S
new file mode 100644 (file)
index 0000000..d11227d
--- /dev/null
@@ -0,0 +1,145 @@
+! SPARC v7 __udiv_qrnnd division support, used from longlong.h.
+! This is for v7 CPUs with a floating-point unit.
+
+! Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! rem_ptr      i0
+! n1           i1
+! n0           i2
+! d            i3
+
+#include "sysdep.h"
+#undef ret     /* Kludge for glibc */
+
+       .text
+       .align  8
+LC0:   .double 0r4294967296
+LC1:   .double 0r2147483648
+
+       .align  4
+       .global C_SYMBOL_NAME(__udiv_qrnnd)
+C_SYMBOL_NAME(__udiv_qrnnd):
+       !#PROLOGUE# 0
+       save    %sp,-104,%sp
+       !#PROLOGUE# 1
+       st      %i1,[%fp-8]
+       ld      [%fp-8],%f10
+       sethi   %hi(LC0),%o7
+       fitod   %f10,%f4
+       ldd     [%o7+%lo(LC0)],%f8
+       cmp     %i1,0
+       bge     L248
+       mov     %i0,%i5
+       faddd   %f4,%f8,%f4
+L248:
+       st      %i2,[%fp-8]
+       ld      [%fp-8],%f10
+       fmuld   %f4,%f8,%f6
+       cmp     %i2,0
+       bge     L249
+       fitod   %f10,%f2
+       faddd   %f2,%f8,%f2
+L249:
+       st      %i3,[%fp-8]
+       faddd   %f6,%f2,%f2
+       ld      [%fp-8],%f10
+       cmp     %i3,0
+       bge     L250
+       fitod   %f10,%f4
+       faddd   %f4,%f8,%f4
+L250:
+       fdivd   %f2,%f4,%f2
+       sethi   %hi(LC1),%o7
+       ldd     [%o7+%lo(LC1)],%f4
+       fcmped  %f2,%f4
+       nop
+       fbge,a  L251
+       fsubd   %f2,%f4,%f2
+       fdtoi   %f2,%f2
+       st      %f2,[%fp-8]
+       b       L252
+       ld      [%fp-8],%i4
+L251:
+       fdtoi   %f2,%f2
+       st      %f2,[%fp-8]
+       ld      [%fp-8],%i4
+       sethi   %hi(-2147483648),%g2
+       xor     %i4,%g2,%i4
+L252:
+       wr      %g0,%i4,%y
+       sra     %i3,31,%g2
+       and     %i4,%g2,%g2
+       andcc   %g0,0,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,%i3,%g1
+       mulscc  %g1,0,%g1
+       add     %g1,%g2,%i0
+       rd      %y,%g3
+       subcc   %i2,%g3,%o7
+       subxcc  %i1,%i0,%g0
+       be      L253
+       cmp     %o7,%i3
+
+       add     %i4,-1,%i0
+       add     %o7,%i3,%o7
+       st      %o7,[%i5]
+       ret
+       restore
+L253:
+       blu     L246
+       mov     %i4,%i0
+       add     %i4,1,%i0
+       sub     %o7,%i3,%o7
+L246:
+       st      %o7,[%i5]
+       ret
+       restore
diff --git a/ghc/rts/gmp/mpn/sparc32/udiv_nfp.S b/ghc/rts/gmp/mpn/sparc32/udiv_nfp.S
new file mode 100644 (file)
index 0000000..118d8a4
--- /dev/null
@@ -0,0 +1,188 @@
+! SPARC v7 __udiv_qrnnd division support, used from longlong.h.
+! This is for v7 CPUs without a floating-point unit.
+
+! Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! rem_ptr      o0
+! n1           o1
+! n0           o2
+! d            o3
+
+#include "sysdep.h"
+
+       .text
+       .align 4
+       .global C_SYMBOL_NAME(__udiv_qrnnd)
+C_SYMBOL_NAME(__udiv_qrnnd):
+       tst     %o3
+       bneg    Largedivisor
+       mov     8,%g1
+
+       b       Lp1
+       addxcc  %o2,%o2,%o2
+
+Lplop: bcc     Ln1
+       addxcc  %o2,%o2,%o2
+Lp1:   addx    %o1,%o1,%o1
+       subcc   %o1,%o3,%o4
+       bcc     Ln2
+       addxcc  %o2,%o2,%o2
+Lp2:   addx    %o1,%o1,%o1
+       subcc   %o1,%o3,%o4
+       bcc     Ln3
+       addxcc  %o2,%o2,%o2
+Lp3:   addx    %o1,%o1,%o1
+       subcc   %o1,%o3,%o4
+       bcc     Ln4
+       addxcc  %o2,%o2,%o2
+Lp4:   addx    %o1,%o1,%o1
+       addcc   %g1,-1,%g1
+       bne     Lplop
+       subcc   %o1,%o3,%o4
+       bcc     Ln5
+       addxcc  %o2,%o2,%o2
+Lp5:   st      %o1,[%o0]
+       retl
+       xnor    %g0,%o2,%o0
+
+Lnlop: bcc     Lp1
+       addxcc  %o2,%o2,%o2
+Ln1:   addx    %o4,%o4,%o4
+       subcc   %o4,%o3,%o1
+       bcc     Lp2
+       addxcc  %o2,%o2,%o2
+Ln2:   addx    %o4,%o4,%o4
+       subcc   %o4,%o3,%o1
+       bcc     Lp3
+       addxcc  %o2,%o2,%o2
+Ln3:   addx    %o4,%o4,%o4
+       subcc   %o4,%o3,%o1
+       bcc     Lp4
+       addxcc  %o2,%o2,%o2
+Ln4:   addx    %o4,%o4,%o4
+       addcc   %g1,-1,%g1
+       bne     Lnlop
+       subcc   %o4,%o3,%o1
+       bcc     Lp5
+       addxcc  %o2,%o2,%o2
+Ln5:   st      %o4,[%o0]
+       retl
+       xnor    %g0,%o2,%o0
+
+Largedivisor:
+       and     %o2,1,%o5       ! %o5 = n0 & 1
+
+       srl     %o2,1,%o2
+       sll     %o1,31,%g2
+       or      %g2,%o2,%o2     ! %o2 = lo(n1n0 >> 1)
+       srl     %o1,1,%o1       ! %o1 = hi(n1n0 >> 1)
+
+       and     %o3,1,%g2
+       srl     %o3,1,%g3       ! %g3 = floor(d / 2)
+       add     %g3,%g2,%g3     ! %g3 = ceil(d / 2)
+
+       b       LLp1
+       addxcc  %o2,%o2,%o2
+
+LLplop:        bcc     LLn1
+       addxcc  %o2,%o2,%o2
+LLp1:  addx    %o1,%o1,%o1
+       subcc   %o1,%g3,%o4
+       bcc     LLn2
+       addxcc  %o2,%o2,%o2
+LLp2:  addx    %o1,%o1,%o1
+       subcc   %o1,%g3,%o4
+       bcc     LLn3
+       addxcc  %o2,%o2,%o2
+LLp3:  addx    %o1,%o1,%o1
+       subcc   %o1,%g3,%o4
+       bcc     LLn4
+       addxcc  %o2,%o2,%o2
+LLp4:  addx    %o1,%o1,%o1
+       addcc   %g1,-1,%g1
+       bne     LLplop
+       subcc   %o1,%g3,%o4
+       bcc     LLn5
+       addxcc  %o2,%o2,%o2
+LLp5:  add     %o1,%o1,%o1     ! << 1
+       tst     %g2
+       bne     Oddp
+       add     %o5,%o1,%o1
+       st      %o1,[%o0]
+       retl
+       xnor    %g0,%o2,%o0
+
+LLnlop:        bcc     LLp1
+       addxcc  %o2,%o2,%o2
+LLn1:  addx    %o4,%o4,%o4
+       subcc   %o4,%g3,%o1
+       bcc     LLp2
+       addxcc  %o2,%o2,%o2
+LLn2:  addx    %o4,%o4,%o4
+       subcc   %o4,%g3,%o1
+       bcc     LLp3
+       addxcc  %o2,%o2,%o2
+LLn3:  addx    %o4,%o4,%o4
+       subcc   %o4,%g3,%o1
+       bcc     LLp4
+       addxcc  %o2,%o2,%o2
+LLn4:  addx    %o4,%o4,%o4
+       addcc   %g1,-1,%g1
+       bne     LLnlop
+       subcc   %o4,%g3,%o1
+       bcc     LLp5
+       addxcc  %o2,%o2,%o2
+LLn5:  add     %o4,%o4,%o4     ! << 1
+       tst     %g2
+       bne     Oddn
+       add     %o5,%o4,%o4
+       st      %o4,[%o0]
+       retl
+       xnor    %g0,%o2,%o0
+
+Oddp:  xnor    %g0,%o2,%o2
+       ! q' in %o2. r' in %o1
+       addcc   %o1,%o2,%o1
+       bcc     LLp6
+       addx    %o2,0,%o2
+       sub     %o1,%o3,%o1
+LLp6:  subcc   %o1,%o3,%g0
+       bcs     LLp7
+       subx    %o2,-1,%o2
+       sub     %o1,%o3,%o1
+LLp7:  st      %o1,[%o0]
+       retl
+       mov     %o2,%o0
+
+Oddn:  xnor    %g0,%o2,%o2
+       ! q' in %o2. r' in %o4
+       addcc   %o4,%o2,%o4
+       bcc     LLn6
+       addx    %o2,0,%o2
+       sub     %o4,%o3,%o4
+LLn6:  subcc   %o4,%o3,%g0
+       bcs     LLn7
+       subx    %o2,-1,%o2
+       sub     %o4,%o3,%o4
+LLn7:  st      %o4,[%o0]
+       retl
+       mov     %o2,%o0