[BACK]Return to sqr_basecase.asm CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / mpn / x86 / pentium4 / sse2

Annotation of OpenXM_contrib/gmp/mpn/x86/pentium4/sse2/sqr_basecase.asm, Revision 1.1.1.1

1.1       ohara       1: dnl  Intel Pentium-4 mpn_sqr_basecase -- square an mpn number.
                      2:
                      3: dnl  Copyright 2001, 2002 Free Software Foundation, Inc.
                      4: dnl
                      5: dnl  This file is part of the GNU MP Library.
                      6: dnl
                      7: dnl  The GNU MP Library is free software; you can redistribute it and/or
                      8: dnl  modify it under the terms of the GNU Lesser General Public License as
                      9: dnl  published by the Free Software Foundation; either version 2.1 of the
                     10: dnl  License, or (at your option) any later version.
                     11: dnl
                     12: dnl  The GNU MP Library is distributed in the hope that it will be useful,
                     13: dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14: dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     15: dnl  Lesser General Public License for more details.
                     16: dnl
                     17: dnl  You should have received a copy of the GNU Lesser General Public
                     18: dnl  License along with the GNU MP Library; see the file COPYING.LIB.  If
                     19: dnl  not, write to the Free Software Foundation, Inc., 59 Temple Place -
                     20: dnl  Suite 330, Boston, MA 02111-1307, USA.
                     21:
                     22: include(`../config.m4')
                     23:
                     24:
                     25: C P4: approx 3.5 cycles per crossproduct, or 7 cycles per triangular
                     26: C     product, at around 30x30 limbs.
                     27:
                     28:
                     29: C void mpn_sqr_basecase (mp_ptr dst, mp_srcptr src, mp_size_t size);
                     30: C
                     31: C The algorithm is basically the same as mpn/generic/sqr_basecase.c, but a
                     32: C lot of function call overheads are avoided, especially when the size is
                     33: C small.
                     34: C
                     35: C On small sizes there's only a small speedup over mpn_mul_basecase,
                     36: C presumably branch mispredictions are a bigger fraction of the work done.
                     37: C It's not clear how to help this.
                     38:
                     39: defframe(PARAM_SIZE,12)
                     40: defframe(PARAM_SRC, 8)
                     41: defframe(PARAM_DST, 4)
                     42:
                     43:        TEXT
                     44:        ALIGN(8)
                     45: PROLOGUE(mpn_sqr_basecase)
                     46: deflit(`FRAME',0)
                     47:
                     48:        movl    PARAM_SIZE, %edx
                     49:        movl    PARAM_SRC, %eax
                     50:        movl    PARAM_DST, %ecx
                     51:
                     52:        cmpl    $2, %edx
                     53:
                     54:        je      L(two_limbs)
                     55:        ja      L(three_or_more)
                     56:
                     57: C -----------------------------------------------------------------------------
                     58: C one limb only
                     59:        C eax   src
                     60:        C ebx
                     61:        C ecx   dst
                     62:        C edx
                     63:
                     64:        movl    (%eax), %eax
                     65:        mull    %eax
                     66:
                     67:        movl    %eax, (%ecx)
                     68:        movl    %edx, 4(%ecx)
                     69:
                     70:        ret
                     71:
                     72: C -----------------------------------------------------------------------------
                     73: L(two_limbs):
                     74:        C eax   src
                     75:        C ebx
                     76:        C ecx   dst
                     77:        C edx   size
                     78:
                     79:        movd    (%eax), %mm1
                     80:        movd    4(%eax), %mm0
                     81:        pmuludq %mm1, %mm0              C src[0]*src[1]
                     82:
                     83:        pmuludq %mm1, %mm1              C src[0]^2
                     84:
                     85:        movd    4(%eax), %mm2
                     86:        pmuludq %mm2, %mm2              C src[1]^2
                     87:
                     88:        movd    %mm1, (%ecx)            C dst[0]
                     89:        psrlq   $32, %mm1
                     90:
                     91:        pcmpeqd %mm3, %mm3
                     92:        psrlq   $32, %mm3               C 0x00000000FFFFFFFF
                     93:        pand    %mm0, %mm3              C low(src[0]*src[1])
                     94:        psrlq   $32, %mm0               C high(src[0]*src[1])
                     95:
                     96:        psllq   $1, %mm3                C 2*low(src[0]*src[1])
                     97:        paddq   %mm3, %mm1              C high(src[0]^2)
                     98:        movd    %mm1, 4(%ecx)           C dst[1]
                     99:
                    100:        pcmpeqd %mm4, %mm4
                    101:        psrlq   $32, %mm4               C 0x00000000FFFFFFFF
                    102:        pand    %mm2, %mm4              C low(src[1]^2)
                    103:        psrlq   $32, %mm2               C high(src[1]^2)
                    104:
                    105:        psllq   $1, %mm0                C 2*high(src[0]*src[1])
                    106:        psrlq   $32, %mm1               C carry
                    107:        paddq   %mm1, %mm0
                    108:        paddq   %mm4, %mm0              C low(src[1]^2)
                    109:        movd    %mm0, 8(%ecx)           C dst[2]
                    110:
                    111:        psrlq   $32, %mm0               C carry
                    112:        paddq   %mm2, %mm0              C high(src[1]^2)
                    113:        movd    %mm0, 12(%ecx)          C dst[3]
                    114:
                    115:        ASSERT(z,`
                    116:        psrlq   $32, %mm0
                    117:        movd    %mm0, %eax
                    118:        orl     %eax, %eax')
                    119:
                    120:        emms
                    121:        ret
                    122:
                    123:
                    124: C -----------------------------------------------------------------------------
                    125: L(three_or_more):
                    126:
                    127:        C eax   src
                    128:        C ebx
                    129:        C ecx   dst
                    130:        C edx   size
                    131:        C esi
                    132:        C edi
                    133:        C ebp
                    134:        C
                    135:        C First multiply src[0]*src[1..size-1] and store at dst[1..size].
                    136:
                    137: defframe(SAVE_ESI,  -4)
                    138: defframe(SAVE_EDI,  -8)
                    139: defframe(SAVE_EBP, -12)
                    140: deflit(STACK_SPACE, 12)
                    141:
                    142:         subl    $STACK_SPACE, %esp     FRAME_subl_esp(STACK_SPACE)
                    143:        pxor    %mm0, %mm0              C initial carry
                    144:        movd    (%eax), %mm7            C multiplier
                    145:
                    146:        movl    %esi, SAVE_ESI
                    147:        movl    %edi, SAVE_EDI
                    148:        movl    %ebp, SAVE_EBP
                    149:
                    150:
                    151:        movl    %eax, %esi
                    152:        movl    %ecx, %edi
                    153:        subl    $1, %edx
                    154:
                    155:        C First multiply src[0]*src[1..size-1] and store at dst[1..size].
                    156: L(mul1):
                    157:        C eax   src, incrementing
                    158:        C ebx
                    159:        C ecx   dst, incrementing
                    160:        C edx   counter, size-1 iterations
                    161:        C esi   src
                    162:        C edi   dst
                    163:        C ebp
                    164:        C
                    165:        C mm0   carry limb
                    166:        C mm7   multiplier
                    167:
                    168:        movd    4(%eax), %mm1
                    169:        addl    $4, %eax
                    170:        pmuludq %mm7, %mm1
                    171:        paddq   %mm1, %mm0
                    172:        movd    %mm0, 4(%ecx)
                    173:        addl    $4, %ecx
                    174:        psrlq   $32, %mm0
                    175:        subl    $1, %edx
                    176:        jnz     L(mul1)
                    177:
                    178:
                    179:        movl    PARAM_SIZE, %ebp
                    180:        subl    $3, %ebp
                    181:        jz      L(corner)
                    182:
                    183:
                    184:        C Add products src[n]*src[n+1..size-1] at dst[2*n-1...], for
                    185:        C n=1..size-2.  The last two products, which are the end corner of
                    186:        C the product triangle, are handled separately to save looping
                    187:        C overhead.
                    188:
                    189: L(outer):
                    190:        C eax
                    191:        C ebx
                    192:        C ecx
                    193:        C edx
                    194:        C esi   src, incrementing
                    195:        C edi   dst, incrementing
                    196:        C ebp   size, decrementing
                    197:        C
                    198:        C mm0   prev carry
                    199:
                    200:        movd    4(%esi), %mm7           C multiplier
                    201:        movd    %mm0, 4(%ecx)           C prev carry
                    202:
                    203:        leal    8(%esi), %eax           C next src
                    204:        addl    $4, %esi
                    205:
                    206:        leal    8(%edi), %ecx           C next dst
                    207:        addl    $8, %edi
                    208:
                    209:        leal    1(%ebp), %edx           C counter
                    210:
                    211:        pxor    %mm0, %mm0              C initial carry limb, clear carry flag
                    212:
                    213: L(inner):
                    214:        C eax   src, incrementing
                    215:        C edx
                    216:        C ecx   dst, incrementing
                    217:        C edx   counter
                    218:        C esi   outer src
                    219:        C edi   outer dst
                    220:        C ebp   outer size
                    221:        C
                    222:        C mm0   carry
                    223:
                    224:        movd    (%eax), %mm1
                    225:        leal    4(%eax), %eax
                    226:        movd    4(%ecx),%mm2
                    227:        pmuludq %mm7, %mm1
                    228:        paddq   %mm2, %mm1
                    229:        paddq   %mm1, %mm0
                    230:        subl    $1, %edx
                    231:        movd    %mm0, 4(%ecx)
                    232:        psrlq   $32, %mm0
                    233:        leal    4(%ecx), %ecx
                    234:        jnz     L(inner)
                    235:
                    236:        subl    $1, %ebp
                    237:        jnz     L(outer)
                    238:
                    239:
                    240: L(corner):
                    241:        C esi   &src[size-3]
                    242:        C edi   &dst[2*size-6]
                    243:        C mm0   carry
                    244:        C
                    245:        C       +-----+-----+--
                    246:        C       | mm0 | dst so far
                    247:        C       +-----+-----+--
                    248:        C +-----+-----+
                    249:        C |     |     |  src[size-2]*src[size-1]
                    250:        C +-----+-----+
                    251:
                    252:        movd    4(%esi), %mm1
                    253:        movd    8(%esi), %mm2
                    254:        pmuludq %mm2, %mm1              C src[size-1]*src[size-2]
                    255:
                    256:        movl    PARAM_SRC, %eax
                    257:        movd    (%eax), %mm2
                    258:        pmuludq %mm2, %mm2              C src[0]^2
                    259:
                    260:        pcmpeqd %mm7, %mm7
                    261:        psrlq   $32, %mm7
                    262:
                    263:        movl    PARAM_DST, %edx
                    264:        movd    4(%edx), %mm3           C dst[1]
                    265:
                    266:        paddq   %mm1, %mm0
                    267:        movd    %mm0, 12(%edi)          C dst[2*size-3]
                    268:
                    269:        psrlq   $32, %mm0
                    270:        movd    %mm0, 16(%edi)          C dst[2*size-2]
                    271:
                    272:        movd    %mm2, (%edx)            C dst[0]
                    273:        psrlq   $32, %mm2
                    274:
                    275:        psllq   $1, %mm3                C 2*dst[1]
                    276:        paddq   %mm3, %mm2
                    277:        movd    %mm2, 4(%edx)
                    278:        psrlq   $32, %mm2
                    279:
                    280:        movl    PARAM_SIZE, %ecx
                    281:        subl    $2, %ecx
                    282:
                    283:        C Now form squares on the diagonal src[0]^2,...,src[size-1]^2, and
                    284:        C add to the triangular parts dst[1..2*size-2] with those left
                    285:        C shifted by 1 bit.
                    286:
                    287: L(diag):
                    288:        C eax   src, incrementing
                    289:        C ebx
                    290:        C ecx   counter, size-2 iterations
                    291:        C edx   dst, incrementing
                    292:        C esi
                    293:        C edi
                    294:        C ebp
                    295:        C
                    296:        C mm2   carry
                    297:        C mm7   0x00000000FFFFFFFF
                    298:
                    299:        movd    4(%eax), %mm0   C src limb
                    300:        addl    $4, %eax
                    301:        pmuludq %mm0, %mm0
                    302:        movq    %mm7, %mm1
                    303:        pand    %mm0, %mm1      C diagonal low
                    304:        psrlq   $32, %mm0       C diagonal high
                    305:
                    306:        movd    8(%edx), %mm3
                    307:        psllq   $1, %mm3        C 2*dst[i]
                    308:        paddq   %mm3, %mm1
                    309:        paddq   %mm1, %mm2
                    310:        movd    %mm2, 8(%edx)
                    311:        psrlq   $32, %mm2
                    312:
                    313:        movd    12(%edx), %mm3
                    314:        psllq   $1, %mm3        C 2*dst[i+1]
                    315:        paddq   %mm3, %mm0
                    316:        paddq   %mm0, %mm2
                    317:        movd    %mm2, 12(%edx)
                    318:        addl    $8, %edx
                    319:        psrlq   $32, %mm2
                    320:
                    321:        subl    $1, %ecx
                    322:        jnz     L(diag)
                    323:
                    324:
                    325:        movd    4(%eax), %mm0   C src[size-1]
                    326:        pmuludq %mm0, %mm0
                    327:        pand    %mm0, %mm7      C diagonal low
                    328:        psrlq   $32, %mm0       C diagonal high
                    329:
                    330:        movd    8(%edx), %mm3   C dst[2*size-2]
                    331:        psllq   $1, %mm3
                    332:        paddq   %mm3, %mm7
                    333:        paddq   %mm7, %mm2
                    334:        movd    %mm2, 8(%edx)
                    335:        psrlq   $32, %mm2
                    336:
                    337:        paddq   %mm0, %mm2
                    338:        movd    %mm2, 12(%edx)  C dst[2*size-1]
                    339:
                    340:        ASSERT(z,`      C no further carry
                    341:        psrlq   $32, %mm2
                    342:        movd    %mm2, %eax
                    343:        orl     %eax, %eax')
                    344:
                    345:
                    346:        movl    SAVE_ESI, %esi
                    347:        movl    SAVE_EDI, %edi
                    348:        movl    SAVE_EBP, %ebp
                    349:        addl    $STACK_SPACE, %esp
                    350:        emms
                    351:        ret
                    352:
                    353: EPILOGUE()

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