[BACK]Return to sub_n.S CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / mpn / sparc32

Annotation of OpenXM_contrib/gmp/mpn/sparc32/sub_n.S, Revision 1.1

1.1     ! maekawa     1: ! SPARC __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
        !             2: ! store difference in a third limb vector.
        !             3:
        !             4: ! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
        !             5:
        !             6: ! This file is part of the GNU MP Library.
        !             7:
        !             8: ! The GNU MP Library is free software; you can redistribute it and/or modify
        !             9: ! it under the terms of the GNU Library General Public License as published by
        !            10: ! the Free Software Foundation; either version 2 of the License, or (at your
        !            11: ! option) any later version.
        !            12:
        !            13: ! The GNU MP Library is distributed in the hope that it will be useful, but
        !            14: ! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            15: ! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
        !            16: ! License for more details.
        !            17:
        !            18: ! You should have received a copy of the GNU Library General Public License
        !            19: ! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
        !            20: ! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
        !            21: ! MA 02111-1307, USA.
        !            22:
        !            23:
        !            24: ! INPUT PARAMETERS
        !            25: #define res_ptr        %o0
        !            26: #define s1_ptr %o1
        !            27: #define s2_ptr %o2
        !            28: #define size   %o3
        !            29:
        !            30: #include "sysdep.h"
        !            31:
        !            32:        .text
        !            33:        .align  4
        !            34:        .global C_SYMBOL_NAME(__mpn_sub_n)
        !            35: C_SYMBOL_NAME(__mpn_sub_n):
        !            36:        xor     s2_ptr,res_ptr,%g1
        !            37:        andcc   %g1,4,%g0
        !            38:        bne     L1                      ! branch if alignment differs
        !            39:        nop
        !            40: ! **  V1a  **
        !            41:        andcc   res_ptr,4,%g0           ! res_ptr unaligned? Side effect: cy=0
        !            42:        be      L_v1                    ! if no, branch
        !            43:        nop
        !            44: /* Add least significant limb separately to align res_ptr and s2_ptr */
        !            45:        ld      [s1_ptr],%g4
        !            46:        add     s1_ptr,4,s1_ptr
        !            47:        ld      [s2_ptr],%g2
        !            48:        add     s2_ptr,4,s2_ptr
        !            49:        add     size,-1,size
        !            50:        subcc   %g4,%g2,%o4
        !            51:        st      %o4,[res_ptr]
        !            52:        add     res_ptr,4,res_ptr
        !            53: L_v1:  addx    %g0,%g0,%o4             ! save cy in register
        !            54:        cmp     size,2                  ! if size < 2 ...
        !            55:        bl      Lend2                   ! ... branch to tail code
        !            56:        subcc   %g0,%o4,%g0             ! restore cy
        !            57:
        !            58:        ld      [s1_ptr+0],%g4
        !            59:        addcc   size,-10,size
        !            60:        ld      [s1_ptr+4],%g1
        !            61:        ldd     [s2_ptr+0],%g2
        !            62:        blt     Lfin1
        !            63:        subcc   %g0,%o4,%g0             ! restore cy
        !            64: /* Add blocks of 8 limbs until less than 8 limbs remain */
        !            65: Loop1: subxcc  %g4,%g2,%o4
        !            66:        ld      [s1_ptr+8],%g4
        !            67:        subxcc  %g1,%g3,%o5
        !            68:        ld      [s1_ptr+12],%g1
        !            69:        ldd     [s2_ptr+8],%g2
        !            70:        std     %o4,[res_ptr+0]
        !            71:        subxcc  %g4,%g2,%o4
        !            72:        ld      [s1_ptr+16],%g4
        !            73:        subxcc  %g1,%g3,%o5
        !            74:        ld      [s1_ptr+20],%g1
        !            75:        ldd     [s2_ptr+16],%g2
        !            76:        std     %o4,[res_ptr+8]
        !            77:        subxcc  %g4,%g2,%o4
        !            78:        ld      [s1_ptr+24],%g4
        !            79:        subxcc  %g1,%g3,%o5
        !            80:        ld      [s1_ptr+28],%g1
        !            81:        ldd     [s2_ptr+24],%g2
        !            82:        std     %o4,[res_ptr+16]
        !            83:        subxcc  %g4,%g2,%o4
        !            84:        ld      [s1_ptr+32],%g4
        !            85:        subxcc  %g1,%g3,%o5
        !            86:        ld      [s1_ptr+36],%g1
        !            87:        ldd     [s2_ptr+32],%g2
        !            88:        std     %o4,[res_ptr+24]
        !            89:        addx    %g0,%g0,%o4             ! save cy in register
        !            90:        addcc   size,-8,size
        !            91:        add     s1_ptr,32,s1_ptr
        !            92:        add     s2_ptr,32,s2_ptr
        !            93:        add     res_ptr,32,res_ptr
        !            94:        bge     Loop1
        !            95:        subcc   %g0,%o4,%g0             ! restore cy
        !            96:
        !            97: Lfin1: addcc   size,8-2,size
        !            98:        blt     Lend1
        !            99:        subcc   %g0,%o4,%g0             ! restore cy
        !           100: /* Add blocks of 2 limbs until less than 2 limbs remain */
        !           101: Loope1:        subxcc  %g4,%g2,%o4
        !           102:        ld      [s1_ptr+8],%g4
        !           103:        subxcc  %g1,%g3,%o5
        !           104:        ld      [s1_ptr+12],%g1
        !           105:        ldd     [s2_ptr+8],%g2
        !           106:        std     %o4,[res_ptr+0]
        !           107:        addx    %g0,%g0,%o4             ! save cy in register
        !           108:        addcc   size,-2,size
        !           109:        add     s1_ptr,8,s1_ptr
        !           110:        add     s2_ptr,8,s2_ptr
        !           111:        add     res_ptr,8,res_ptr
        !           112:        bge     Loope1
        !           113:        subcc   %g0,%o4,%g0             ! restore cy
        !           114: Lend1: subxcc  %g4,%g2,%o4
        !           115:        subxcc  %g1,%g3,%o5
        !           116:        std     %o4,[res_ptr+0]
        !           117:        addx    %g0,%g0,%o4             ! save cy in register
        !           118:
        !           119:        andcc   size,1,%g0
        !           120:        be      Lret1
        !           121:        subcc   %g0,%o4,%g0             ! restore cy
        !           122: /* Add last limb */
        !           123:        ld      [s1_ptr+8],%g4
        !           124:        ld      [s2_ptr+8],%g2
        !           125:        subxcc  %g4,%g2,%o4
        !           126:        st      %o4,[res_ptr+8]
        !           127:
        !           128: Lret1: retl
        !           129:        addx    %g0,%g0,%o0     ! return carry-out from most sign. limb
        !           130:
        !           131: L1:    xor     s1_ptr,res_ptr,%g1
        !           132:        andcc   %g1,4,%g0
        !           133:        bne     L2
        !           134:        nop
        !           135: ! **  V1b  **
        !           136:        andcc   res_ptr,4,%g0           ! res_ptr unaligned? Side effect: cy=0
        !           137:        be      L_v1b                   ! if no, branch
        !           138:        nop
        !           139: /* Add least significant limb separately to align res_ptr and s1_ptr */
        !           140:        ld      [s2_ptr],%g4
        !           141:        add     s2_ptr,4,s2_ptr
        !           142:        ld      [s1_ptr],%g2
        !           143:        add     s1_ptr,4,s1_ptr
        !           144:        add     size,-1,size
        !           145:        subcc   %g2,%g4,%o4
        !           146:        st      %o4,[res_ptr]
        !           147:        add     res_ptr,4,res_ptr
        !           148: L_v1b: addx    %g0,%g0,%o4             ! save cy in register
        !           149:        cmp     size,2                  ! if size < 2 ...
        !           150:        bl      Lend2                   ! ... branch to tail code
        !           151:        subcc   %g0,%o4,%g0             ! restore cy
        !           152:
        !           153:        ld      [s2_ptr+0],%g4
        !           154:        addcc   size,-10,size
        !           155:        ld      [s2_ptr+4],%g1
        !           156:        ldd     [s1_ptr+0],%g2
        !           157:        blt     Lfin1b
        !           158:        subcc   %g0,%o4,%g0             ! restore cy
        !           159: /* Add blocks of 8 limbs until less than 8 limbs remain */
        !           160: Loop1b:        subxcc  %g2,%g4,%o4
        !           161:        ld      [s2_ptr+8],%g4
        !           162:        subxcc  %g3,%g1,%o5
        !           163:        ld      [s2_ptr+12],%g1
        !           164:        ldd     [s1_ptr+8],%g2
        !           165:        std     %o4,[res_ptr+0]
        !           166:        subxcc  %g2,%g4,%o4
        !           167:        ld      [s2_ptr+16],%g4
        !           168:        subxcc  %g3,%g1,%o5
        !           169:        ld      [s2_ptr+20],%g1
        !           170:        ldd     [s1_ptr+16],%g2
        !           171:        std     %o4,[res_ptr+8]
        !           172:        subxcc  %g2,%g4,%o4
        !           173:        ld      [s2_ptr+24],%g4
        !           174:        subxcc  %g3,%g1,%o5
        !           175:        ld      [s2_ptr+28],%g1
        !           176:        ldd     [s1_ptr+24],%g2
        !           177:        std     %o4,[res_ptr+16]
        !           178:        subxcc  %g2,%g4,%o4
        !           179:        ld      [s2_ptr+32],%g4
        !           180:        subxcc  %g3,%g1,%o5
        !           181:        ld      [s2_ptr+36],%g1
        !           182:        ldd     [s1_ptr+32],%g2
        !           183:        std     %o4,[res_ptr+24]
        !           184:        addx    %g0,%g0,%o4             ! save cy in register
        !           185:        addcc   size,-8,size
        !           186:        add     s1_ptr,32,s1_ptr
        !           187:        add     s2_ptr,32,s2_ptr
        !           188:        add     res_ptr,32,res_ptr
        !           189:        bge     Loop1b
        !           190:        subcc   %g0,%o4,%g0             ! restore cy
        !           191:
        !           192: Lfin1b:        addcc   size,8-2,size
        !           193:        blt     Lend1b
        !           194:        subcc   %g0,%o4,%g0             ! restore cy
        !           195: /* Add blocks of 2 limbs until less than 2 limbs remain */
        !           196: Loope1b:subxcc %g2,%g4,%o4
        !           197:        ld      [s2_ptr+8],%g4
        !           198:        subxcc  %g3,%g1,%o5
        !           199:        ld      [s2_ptr+12],%g1
        !           200:        ldd     [s1_ptr+8],%g2
        !           201:        std     %o4,[res_ptr+0]
        !           202:        addx    %g0,%g0,%o4             ! save cy in register
        !           203:        addcc   size,-2,size
        !           204:        add     s1_ptr,8,s1_ptr
        !           205:        add     s2_ptr,8,s2_ptr
        !           206:        add     res_ptr,8,res_ptr
        !           207:        bge     Loope1b
        !           208:        subcc   %g0,%o4,%g0             ! restore cy
        !           209: Lend1b:        subxcc  %g2,%g4,%o4
        !           210:        subxcc  %g3,%g1,%o5
        !           211:        std     %o4,[res_ptr+0]
        !           212:        addx    %g0,%g0,%o4             ! save cy in register
        !           213:
        !           214:        andcc   size,1,%g0
        !           215:        be      Lret1b
        !           216:        subcc   %g0,%o4,%g0             ! restore cy
        !           217: /* Add last limb */
        !           218:        ld      [s2_ptr+8],%g4
        !           219:        ld      [s1_ptr+8],%g2
        !           220:        subxcc  %g2,%g4,%o4
        !           221:        st      %o4,[res_ptr+8]
        !           222:
        !           223: Lret1b:        retl
        !           224:        addx    %g0,%g0,%o0     ! return carry-out from most sign. limb
        !           225:
        !           226: ! **  V2  **
        !           227: /* If we come here, the alignment of s1_ptr and res_ptr as well as the
        !           228:    alignment of s2_ptr and res_ptr differ.  Since there are only two ways
        !           229:    things can be aligned (that we care about) we now know that the alignment
        !           230:    of s1_ptr and s2_ptr are the same.  */
        !           231:
        !           232: L2:    cmp     size,1
        !           233:        be      Ljone
        !           234:        nop
        !           235:        andcc   s1_ptr,4,%g0            ! s1_ptr unaligned? Side effect: cy=0
        !           236:        be      L_v2                    ! if no, branch
        !           237:        nop
        !           238: /* Add least significant limb separately to align s1_ptr and s2_ptr */
        !           239:        ld      [s1_ptr],%g4
        !           240:        add     s1_ptr,4,s1_ptr
        !           241:        ld      [s2_ptr],%g2
        !           242:        add     s2_ptr,4,s2_ptr
        !           243:        add     size,-1,size
        !           244:        subcc   %g4,%g2,%o4
        !           245:        st      %o4,[res_ptr]
        !           246:        add     res_ptr,4,res_ptr
        !           247:
        !           248: L_v2:  addx    %g0,%g0,%o4             ! save cy in register
        !           249:        addcc   size,-8,size
        !           250:        blt     Lfin2
        !           251:        subcc   %g0,%o4,%g0             ! restore cy
        !           252: /* Add blocks of 8 limbs until less than 8 limbs remain */
        !           253: Loop2: ldd     [s1_ptr+0],%g2
        !           254:        ldd     [s2_ptr+0],%o4
        !           255:        subxcc  %g2,%o4,%g2
        !           256:        st      %g2,[res_ptr+0]
        !           257:        subxcc  %g3,%o5,%g3
        !           258:        st      %g3,[res_ptr+4]
        !           259:        ldd     [s1_ptr+8],%g2
        !           260:        ldd     [s2_ptr+8],%o4
        !           261:        subxcc  %g2,%o4,%g2
        !           262:        st      %g2,[res_ptr+8]
        !           263:        subxcc  %g3,%o5,%g3
        !           264:        st      %g3,[res_ptr+12]
        !           265:        ldd     [s1_ptr+16],%g2
        !           266:        ldd     [s2_ptr+16],%o4
        !           267:        subxcc  %g2,%o4,%g2
        !           268:        st      %g2,[res_ptr+16]
        !           269:        subxcc  %g3,%o5,%g3
        !           270:        st      %g3,[res_ptr+20]
        !           271:        ldd     [s1_ptr+24],%g2
        !           272:        ldd     [s2_ptr+24],%o4
        !           273:        subxcc  %g2,%o4,%g2
        !           274:        st      %g2,[res_ptr+24]
        !           275:        subxcc  %g3,%o5,%g3
        !           276:        st      %g3,[res_ptr+28]
        !           277:        addx    %g0,%g0,%o4             ! save cy in register
        !           278:        addcc   size,-8,size
        !           279:        add     s1_ptr,32,s1_ptr
        !           280:        add     s2_ptr,32,s2_ptr
        !           281:        add     res_ptr,32,res_ptr
        !           282:        bge     Loop2
        !           283:        subcc   %g0,%o4,%g0             ! restore cy
        !           284:
        !           285: Lfin2: addcc   size,8-2,size
        !           286:        blt     Lend2
        !           287:        subcc   %g0,%o4,%g0             ! restore cy
        !           288: Loope2:        ldd     [s1_ptr+0],%g2
        !           289:        ldd     [s2_ptr+0],%o4
        !           290:        subxcc  %g2,%o4,%g2
        !           291:        st      %g2,[res_ptr+0]
        !           292:        subxcc  %g3,%o5,%g3
        !           293:        st      %g3,[res_ptr+4]
        !           294:        addx    %g0,%g0,%o4             ! save cy in register
        !           295:        addcc   size,-2,size
        !           296:        add     s1_ptr,8,s1_ptr
        !           297:        add     s2_ptr,8,s2_ptr
        !           298:        add     res_ptr,8,res_ptr
        !           299:        bge     Loope2
        !           300:        subcc   %g0,%o4,%g0             ! restore cy
        !           301: Lend2: andcc   size,1,%g0
        !           302:        be      Lret2
        !           303:        subcc   %g0,%o4,%g0             ! restore cy
        !           304: /* Add last limb */
        !           305: Ljone: ld      [s1_ptr],%g4
        !           306:        ld      [s2_ptr],%g2
        !           307:        subxcc  %g4,%g2,%o4
        !           308:        st      %o4,[res_ptr]
        !           309:
        !           310: Lret2: retl
        !           311:        addx    %g0,%g0,%o0     ! return carry-out from most sign. limb

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>