[BACK]Return to lshift.asm CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / mpn / x86 / pentium / mmx

Annotation of OpenXM_contrib/gmp/mpn/x86/pentium/mmx/lshift.asm, Revision 1.1.1.1

1.1       maekawa     1: dnl  Intel P5 mpn_lshift -- mpn left shift.
                      2: dnl
                      3: dnl  P5: 1.75 cycles/limb.
                      4:
                      5:
                      6: dnl  Copyright (C) 2000 Free Software Foundation, Inc.
                      7: dnl
                      8: dnl  This file is part of the GNU MP Library.
                      9: dnl
                     10: dnl  The GNU MP Library is free software; you can redistribute it and/or
                     11: dnl  modify it under the terms of the GNU Lesser General Public License as
                     12: dnl  published by the Free Software Foundation; either version 2.1 of the
                     13: dnl  License, or (at your option) any later version.
                     14: dnl
                     15: dnl  The GNU MP Library is distributed in the hope that it will be useful,
                     16: dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     18: dnl  Lesser General Public License for more details.
                     19: dnl
                     20: dnl  You should have received a copy of the GNU Lesser General Public
                     21: dnl  License along with the GNU MP Library; see the file COPYING.LIB.  If
                     22: dnl  not, write to the Free Software Foundation, Inc., 59 Temple Place -
                     23: dnl  Suite 330, Boston, MA 02111-1307, USA.
                     24:
                     25:
                     26: include(`../config.m4')
                     27:
                     28:
                     29: C mp_limb_t mpn_lshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
                     30: C                       unsigned shift);
                     31: C
                     32: C Shift src,size left by shift many bits and store the result in dst,size.
                     33: C Zeros are shifted in at the right.  Return the bits shifted out at the
                     34: C left.
                     35: C
                     36: C The comments in mpn_rshift apply here too.
                     37:
                     38: defframe(PARAM_SHIFT,16)
                     39: defframe(PARAM_SIZE, 12)
                     40: defframe(PARAM_SRC,  8)
                     41: defframe(PARAM_DST,  4)
                     42: deflit(`FRAME',0)
                     43:
                     44: dnl  minimum 5, because the unrolled loop can't handle less
                     45: deflit(UNROLL_THRESHOLD, 5)
                     46:
                     47:        .text
                     48:        ALIGN(8)
                     49:
                     50: PROLOGUE(mpn_lshift)
                     51:
                     52:        pushl   %ebx
                     53:        pushl   %edi
                     54: deflit(`FRAME',8)
                     55:
                     56:        movl    PARAM_SIZE, %eax
                     57:        movl    PARAM_DST, %edx
                     58:
                     59:        movl    PARAM_SRC, %ebx
                     60:        movl    PARAM_SHIFT, %ecx
                     61:
                     62:        cmp     $UNROLL_THRESHOLD, %eax
                     63:        jae     L(unroll)
                     64:
                     65:        movl    -4(%ebx,%eax,4), %edi   C src high limb
                     66:        decl    %eax
                     67:
                     68:        jnz     L(simple)
                     69:
                     70:        shldl(  %cl, %edi, %eax)        C eax was decremented to zero
                     71:
                     72:        shll    %cl, %edi
                     73:
                     74:        movl    %edi, (%edx)            C dst low limb
                     75:        popl    %edi                    C risk of data cache bank clash
                     76:
                     77:        popl    %ebx
                     78:
                     79:        ret
                     80:
                     81:
                     82: C -----------------------------------------------------------------------------
                     83: L(simple):
                     84:        C eax   size-1
                     85:        C ebx   src
                     86:        C ecx   shift
                     87:        C edx   dst
                     88:        C esi
                     89:        C edi
                     90:        C ebp
                     91: deflit(`FRAME',8)
                     92:
                     93:        movd    (%ebx,%eax,4), %mm5     C src high limb
                     94:
                     95:        movd    %ecx, %mm6              C lshift
                     96:        negl    %ecx
                     97:
                     98:        psllq   %mm6, %mm5
                     99:        addl    $32, %ecx
                    100:
                    101:        movd    %ecx, %mm7
                    102:        psrlq   $32, %mm5               C retval
                    103:
                    104:
                    105: L(simple_top):
                    106:        C eax   counter, limbs, negative
                    107:        C ebx   src
                    108:        C ecx
                    109:        C edx   dst
                    110:        C esi
                    111:        C edi
                    112:        C
                    113:        C mm0   scratch
                    114:        C mm5   return value
                    115:        C mm6   shift
                    116:        C mm7   32-shift
                    117:
                    118:        movq    -4(%ebx,%eax,4), %mm0
                    119:        decl    %eax
                    120:
                    121:        psrlq   %mm7, %mm0
                    122:
                    123:        C
                    124:
                    125:        movd    %mm0, 4(%edx,%eax,4)
                    126:        jnz     L(simple_top)
                    127:
                    128:
                    129:        movd    (%ebx), %mm0
                    130:
                    131:        movd    %mm5, %eax
                    132:        psllq   %mm6, %mm0
                    133:
                    134:        popl    %edi
                    135:        popl    %ebx
                    136:
                    137:        movd    %mm0, (%edx)
                    138:
                    139:        emms
                    140:
                    141:        ret
                    142:
                    143:
                    144: C -----------------------------------------------------------------------------
                    145:        ALIGN(8)
                    146: L(unroll):
                    147:        C eax   size
                    148:        C ebx   src
                    149:        C ecx   shift
                    150:        C edx   dst
                    151:        C esi
                    152:        C edi
                    153:        C ebp
                    154: deflit(`FRAME',8)
                    155:
                    156:        movd    -4(%ebx,%eax,4), %mm5   C src high limb
                    157:        leal    (%ebx,%eax,4), %edi
                    158:
                    159:        movd    %ecx, %mm6              C lshift
                    160:        andl    $4, %edi
                    161:
                    162:        psllq   %mm6, %mm5
                    163:        jz      L(start_src_aligned)
                    164:
                    165:
                    166:        C src isn't aligned, process high limb separately (marked xxx) to
                    167:        C make it so.
                    168:        C
                    169:        C  source     -8(ebx,%eax,4)
                    170:        C                  |
                    171:        C  +-------+-------+-------+--
                    172:        C  |               |
                    173:        C  +-------+-------+-------+--
                    174:        C        0mod8   4mod8   0mod8
                    175:        C
                    176:        C  dest
                    177:        C     -4(edx,%eax,4)
                    178:        C          |
                    179:        C  +-------+-------+--
                    180:        C  |  xxx  |       |
                    181:        C  +-------+-------+--
                    182:
                    183:        movq    -8(%ebx,%eax,4), %mm0   C unaligned load
                    184:
                    185:        psllq   %mm6, %mm0
                    186:        decl    %eax
                    187:
                    188:        psrlq   $32, %mm0
                    189:
                    190:        C
                    191:
                    192:        movd    %mm0, (%edx,%eax,4)
                    193: L(start_src_aligned):
                    194:
                    195:        movq    -8(%ebx,%eax,4), %mm1   C src high qword
                    196:        leal    (%edx,%eax,4), %edi
                    197:
                    198:        andl    $4, %edi
                    199:        psrlq   $32, %mm5               C return value
                    200:
                    201:        movq    -16(%ebx,%eax,4), %mm3  C src second highest qword
                    202:        jz      L(start_dst_aligned)
                    203:
                    204:        C dst isn't aligned, subtract 4 to make it so, and pretend the shift
                    205:        C is 32 bits extra.  High limb of dst (marked xxx) handled here
                    206:        C separately.
                    207:        C
                    208:        C  source     -8(ebx,%eax,4)
                    209:        C                  |
                    210:        C  +-------+-------+--
                    211:        C  |      mm1      |
                    212:        C  +-------+-------+--
                    213:        C                0mod8   4mod8
                    214:        C
                    215:        C  dest
                    216:        C     -4(edx,%eax,4)
                    217:        C          |
                    218:        C  +-------+-------+-------+--
                    219:        C  |  xxx  |               |
                    220:        C  +-------+-------+-------+--
                    221:        C        0mod8   4mod8   0mod8
                    222:
                    223:        movq    %mm1, %mm0
                    224:        addl    $32, %ecx               C new shift
                    225:
                    226:        psllq   %mm6, %mm0
                    227:
                    228:        movd    %ecx, %mm6
                    229:        psrlq   $32, %mm0
                    230:
                    231:        C wasted cycle here waiting for %mm0
                    232:
                    233:        movd    %mm0, -4(%edx,%eax,4)
                    234:        subl    $4, %edx
                    235: L(start_dst_aligned):
                    236:
                    237:
                    238:        psllq   %mm6, %mm1
                    239:        negl    %ecx                    C -shift
                    240:
                    241:         addl    $64, %ecx              C 64-shift
                    242:        movq    %mm3, %mm2
                    243:
                    244:         movd    %ecx, %mm7
                    245:        subl    $8, %eax                C size-8
                    246:
                    247:        psrlq   %mm7, %mm3
                    248:
                    249:        por     %mm1, %mm3              C mm3 ready to store
                    250:        jc      L(finish)
                    251:
                    252:
                    253:        C The comments in mpn_rshift apply here too.
                    254:
                    255:        ALIGN(8)
                    256: L(unroll_loop):
                    257:        C eax   counter, limbs
                    258:        C ebx   src
                    259:        C ecx
                    260:        C edx   dst
                    261:        C esi
                    262:        C edi
                    263:        C
                    264:        C mm0
                    265:        C mm1
                    266:        C mm2   src qword from 48(%ebx,%eax,4)
                    267:        C mm3   dst qword ready to store to 56(%edx,%eax,4)
                    268:        C
                    269:        C mm5   return value
                    270:        C mm6   lshift
                    271:        C mm7   rshift
                    272:
                    273:        movq    8(%ebx,%eax,4), %mm0
                    274:        psllq   %mm6, %mm2
                    275:
                    276:        movq    %mm0, %mm1
                    277:        psrlq   %mm7, %mm0
                    278:
                    279:        movq    %mm3, 24(%edx,%eax,4)   C prev
                    280:        por     %mm2, %mm0
                    281:
                    282:        movq    (%ebx,%eax,4), %mm3     C
                    283:        psllq   %mm6, %mm1              C
                    284:
                    285:        movq    %mm0, 16(%edx,%eax,4)
                    286:        movq    %mm3, %mm2              C
                    287:
                    288:        psrlq   %mm7, %mm3              C
                    289:        subl    $4, %eax
                    290:
                    291:        por     %mm1, %mm3              C
                    292:        jnc     L(unroll_loop)
                    293:
                    294:
                    295:
                    296: L(finish):
                    297:        C eax   -4 to -1 representing respectively 0 to 3 limbs remaining
                    298:
                    299:        testb   $2, %al
                    300:
                    301:        jz      L(finish_no_two)
                    302:
                    303:        movq    8(%ebx,%eax,4), %mm0
                    304:        psllq   %mm6, %mm2
                    305:
                    306:        movq    %mm0, %mm1
                    307:        psrlq   %mm7, %mm0
                    308:
                    309:        movq    %mm3, 24(%edx,%eax,4)   C prev
                    310:        por     %mm2, %mm0
                    311:
                    312:        movq    %mm1, %mm2
                    313:        movq    %mm0, %mm3
                    314:
                    315:        subl    $2, %eax
                    316: L(finish_no_two):
                    317:
                    318:
                    319:        C eax   -4 or -3 representing respectively 0 or 1 limbs remaining
                    320:        C
                    321:        C mm2   src prev qword, from 48(%ebx,%eax,4)
                    322:        C mm3   dst qword, for 56(%edx,%eax,4)
                    323:
                    324:        testb   $1, %al
                    325:        movd    %mm5, %eax      C retval
                    326:
                    327:        popl    %edi
                    328:        jz      L(finish_zero)
                    329:
                    330:
                    331:        C One extra src limb, destination was aligned.
                    332:        C
                    333:        C                 source                  ebx
                    334:        C                 --+---------------+-------+
                    335:        C                   |      mm2      |       |
                    336:        C                 --+---------------+-------+
                    337:        C
                    338:        C dest         edx+12           edx+4     edx
                    339:        C --+---------------+---------------+-------+
                    340:        C   |      mm3      |               |       |
                    341:        C --+---------------+---------------+-------+
                    342:        C
                    343:        C mm6 = shift
                    344:        C mm7 = ecx = 64-shift
                    345:
                    346:
                    347:        C One extra src limb, destination was unaligned.
                    348:        C
                    349:        C                 source                  ebx
                    350:        C                 --+---------------+-------+
                    351:        C                   |      mm2      |       |
                    352:        C                 --+---------------+-------+
                    353:        C
                    354:        C         dest         edx+12           edx+4
                    355:        C         --+---------------+---------------+
                    356:        C           |      mm3      |               |
                    357:        C         --+---------------+---------------+
                    358:        C
                    359:        C mm6 = shift+32
                    360:        C mm7 = ecx = 64-(shift+32)
                    361:
                    362:
                    363:        C In both cases there's one extra limb of src to fetch and combine
                    364:        C with mm2 to make a qword at 4(%edx), and in the aligned case
                    365:        C there's an extra limb of dst to be formed from that extra src limb
                    366:        C left shifted.
                    367:
                    368:
                    369:         movd    (%ebx), %mm0
                    370:        psllq   %mm6, %mm2
                    371:
                    372:        movq    %mm3, 12(%edx)
                    373:        psllq   $32, %mm0
                    374:
                    375:         movq    %mm0, %mm1
                    376:         psrlq   %mm7, %mm0
                    377:
                    378:         por     %mm2, %mm0
                    379:         psllq   %mm6, %mm1
                    380:
                    381:        movq    %mm0, 4(%edx)
                    382:        psrlq   $32, %mm1
                    383:
                    384:         andl   $32, %ecx
                    385:        popl    %ebx
                    386:
                    387:        jz      L(finish_one_unaligned)
                    388:
                    389:        movd    %mm1, (%edx)
                    390: L(finish_one_unaligned):
                    391:
                    392:        emms
                    393:
                    394:         ret
                    395:
                    396:
                    397: L(finish_zero):
                    398:
                    399:        C No extra src limbs, destination was aligned.
                    400:        C
                    401:        C                 source          ebx
                    402:        C                 --+---------------+
                    403:        C                   |      mm2      |
                    404:        C                 --+---------------+
                    405:        C
                    406:        C dest          edx+8             edx
                    407:        C --+---------------+---------------+
                    408:        C   |      mm3      |               |
                    409:        C --+---------------+---------------+
                    410:        C
                    411:        C mm6 = shift
                    412:        C mm7 = ecx = 64-shift
                    413:
                    414:
                    415:        C No extra src limbs, destination was unaligned.
                    416:        C
                    417:        C               source            ebx
                    418:        C                 --+---------------+
                    419:        C                   |      mm2      |
                    420:        C                 --+---------------+
                    421:        C
                    422:        C         dest          edx+8   edx+4
                    423:        C         --+---------------+-------+
                    424:        C           |      mm3      |       |
                    425:        C         --+---------------+-------+
                    426:        C
                    427:        C mm6 = shift+32
                    428:        C mm7 = ecx = 64-(shift+32)
                    429:
                    430:
                    431:        C The movd for the unaligned case writes the same data to 4(%edx)
                    432:        C that the movq does for the aligned case.
                    433:
                    434:
                    435:        movq    %mm3, 8(%edx)
                    436:        andl    $32, %ecx
                    437:
                    438:        psllq   %mm6, %mm2
                    439:        jz      L(finish_zero_unaligned)
                    440:
                    441:        movq    %mm2, (%edx)
                    442: L(finish_zero_unaligned):
                    443:
                    444:        psrlq   $32, %mm2
                    445:        popl    %ebx
                    446:
                    447:        movd    %mm5, %eax      C retval
                    448:
                    449:        movd    %mm2, 4(%edx)
                    450:
                    451:        emms
                    452:
                    453:        ret
                    454:
                    455: EPILOGUE()

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