diff options
author | simonm <unknown> | 1998-06-05 14:37:55 +0000 |
---|---|---|
committer | simonm <unknown> | 1998-06-05 14:37:55 +0000 |
commit | 1e1a38f3aefec3c47536e88a6c4f1e36ea999c2e (patch) | |
tree | dcd6a214376c07ca8dc03b27826b7ad849ca6a17 /ghc/rts/gmp/mpn | |
parent | f89b97fbc6f6c5bbd9342ae20f3c74e11d0d27e3 (diff) | |
download | haskell-1e1a38f3aefec3c47536e88a6c4f1e36ea999c2e.tar.gz |
[project @ 1998-06-05 14:37:55 by simonm]
Initial revision
Diffstat (limited to 'ghc/rts/gmp/mpn')
-rw-r--r-- | ghc/rts/gmp/mpn/sparc32/add_n.S | 226 | ||||
-rw-r--r-- | ghc/rts/gmp/mpn/sparc32/addmul_1.S | 147 | ||||
-rw-r--r-- | ghc/rts/gmp/mpn/sparc32/lshift.S | 95 | ||||
-rw-r--r-- | ghc/rts/gmp/mpn/sparc32/mul_1.S | 199 | ||||
-rw-r--r-- | ghc/rts/gmp/mpn/sparc32/rshift.S | 92 | ||||
-rw-r--r-- | ghc/rts/gmp/mpn/sparc32/sub_n.S | 311 | ||||
-rw-r--r-- | ghc/rts/gmp/mpn/sparc32/submul_1.S | 147 | ||||
-rw-r--r-- | ghc/rts/gmp/mpn/sparc32/udiv_fp.S | 145 | ||||
-rw-r--r-- | ghc/rts/gmp/mpn/sparc32/udiv_nfp.S | 188 |
9 files changed, 1550 insertions, 0 deletions
diff --git a/ghc/rts/gmp/mpn/sparc32/add_n.S b/ghc/rts/gmp/mpn/sparc32/add_n.S new file mode 100644 index 0000000000..9852c256aa --- /dev/null +++ b/ghc/rts/gmp/mpn/sparc32/add_n.S @@ -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 index 0000000000..375d25db6b --- /dev/null +++ b/ghc/rts/gmp/mpn/sparc32/addmul_1.S @@ -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 index 0000000000..4f0595f2fb --- /dev/null +++ b/ghc/rts/gmp/mpn/sparc32/lshift.S @@ -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 index 0000000000..142fd8ba2a --- /dev/null +++ b/ghc/rts/gmp/mpn/sparc32/mul_1.S @@ -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 index 0000000000..fea4f3b926 --- /dev/null +++ b/ghc/rts/gmp/mpn/sparc32/rshift.S @@ -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 index 0000000000..b7a11958e2 --- /dev/null +++ b/ghc/rts/gmp/mpn/sparc32/sub_n.S @@ -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 index 0000000000..a8ebd501a7 --- /dev/null +++ b/ghc/rts/gmp/mpn/sparc32/submul_1.S @@ -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 index 0000000000..d11227dff4 --- /dev/null +++ b/ghc/rts/gmp/mpn/sparc32/udiv_fp.S @@ -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 index 0000000000..118d8a4a26 --- /dev/null +++ b/ghc/rts/gmp/mpn/sparc32/udiv_nfp.S @@ -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 |