[BACK]Return to impys.S CVS log [TXT][DIR] Up to [local] / sys / arch / hppa / spmath

Annotation of sys/arch/hppa/spmath/impys.S, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: impys.S,v 1.11 2005/01/23 18:01:30 mickey Exp $       */
                      2: /*
                      3:   (c) Copyright 1986 HEWLETT-PACKARD COMPANY
                      4:   To anyone who acknowledges that this file is provided "AS IS"
                      5:   without any express or implied warranty:
                      6:       permission to use, copy, modify, and distribute this file
                      7:   for any purpose is hereby granted without fee, provided that
                      8:   the above copyright notice and this notice appears in all
                      9:   copies, and that the name of Hewlett-Packard Company not be
                     10:   used in advertising or publicity pertaining to distribution
                     11:   of the software without specific, written prior permission.
                     12:   Hewlett-Packard Company makes no representations about the
                     13:   suitability of this software for any purpose.
                     14: */
                     15: /* @(#)impys.s: Revision: 1.11.88.1 Date: 93/12/07 15:06:28 */
                     16:
                     17: #include <machine/asm.h>
                     18: #define _LOCORE
                     19: #include <machine/frame.h>
                     20:
                     21: ;****************************************************************************
                     22: ;
                     23: ;Implement an integer multiply routine for 32-bit operands and 64-bit product
                     24: ;with operand values of zero (multiplicand only) and -2**31 treated specially.
                     25: ;The algorithm uses the absolute value of the multiplier, four bits at a time,
                     26: ;from right to left, to generate partial product.  Execution speed is more
                     27: ;important than program size in this implementation.
                     28: ;
                     29: ;****************************************************************************
                     30: ;
                     31: ; Definitions - General registers
                     32: ;
                     33: gr0    .reg            %r0             ; General register zero
                     34: pu     .reg            %r3             ; upper part of product
                     35: pl     .reg            %r4             ; lower part of product
                     36: op2    .reg            %r4             ; multiplier
                     37: op1    .reg            %r5             ; multiplicand
                     38: cnt    .reg            %r6             ; count in multiply
                     39: brindex        .reg            %r7             ; index into the br. table
                     40: sign   .reg            %r8             ; sign of product
                     41: pc     .reg            %r9             ; carry bit of product, = 00...01
                     42: pm     .reg            %r10            ; value of -1 used in shifting
                     43:
                     44: ;*****************************************************************************
                     45:        .text
                     46:
                     47: LEAF_ENTRY(s_xmpy)
                     48:        stws,ma         pu,4(sp)                ; save registers on stack
                     49:        stws,ma         pl,4(sp)                ; save registers on stack
                     50:        stws,ma         op1,4(sp)               ; save registers on stack
                     51:        stws,ma         cnt,4(sp)               ; save registers on stack
                     52:        stws,ma         brindex,4(sp)           ; save registers on stack
                     53:        stws,ma         sign,4(sp)              ; save registers on stack
                     54:        stws,ma         pc,4(sp)                ; save registers on stack
                     55:        stws,ma         pm,4(sp)                ; save registers on stack
                     56: ;
                     57: ;   Start multiply process
                     58: ;
                     59:        ldws            0(arg1),op2             ; get multiplier
                     60:        ldws            0(arg0),op1             ; get multiplicand
                     61:        addi            -1,gr0,pm               ; initialize pm to 111...1
                     62:        comb,<          op2,gr0,mpyb            ; br. if multiplier < 0
                     63:        xor             op2,op1,sign            ; sign(0) = sign of product
                     64: mpy1   comb,<          op1,gr0,mpya            ; br. if multiplicand < 0
                     65:        addi            0,gr0,pu                ; clear product
                     66:        addib,=         0,op1,fini0             ; op1 = 0, product = 0
                     67: mpy2   addi            1,gr0,pc                ; initialize pc to 00...01
                     68:        movib,tr        8,cnt,mloop             ; set count for mpy loop
                     69:        extru           op2,31,4,brindex        ; 4 bits as index into table
                     70: ;
                     71:        .align          8
                     72: ;
                     73:        b               sh4c                    ; br. if sign overflow
                     74: sh4n   shd             pu,pl,4,pl              ; shift product right 4 bits
                     75:        addib,<=        -1,cnt,mulend           ; reduce count by 1, exit if
                     76:        extru           pu,27,28,pu             ;   <= zero
                     77: ;
                     78: mloop  blr             brindex,gr0             ; br. into table
                     79:                                                ;   entries of 2 words
                     80:        extru           op2,27,4,brindex        ; next 4 bits into index
                     81: ;
                     82: ;
                     83: ;      branch table for the multiplication process with four multiplier bits
                     84: ;
                     85: mtable                                         ; two words per entry
                     86: ;
                     87: ; ---- bits = 0000 ---- shift product 4 bits -------------------------------
                     88: ;
                     89:        b               sh4n+4                  ; just shift partial
                     90:        shd             pu,pl,4,pl              ;   product right 4 bits
                     91: ;
                     92: ;  ----        bits = 0001 ---- add op1, then shift 4 bits
                     93: ;
                     94:        addb,tr         op1,pu,sh4n+4           ; add op1 to product, to shift
                     95:        shd             pu,pl,4,pl              ;   product right 4 bits
                     96: ;
                     97: ;  ----        bits = 0010 ---- add op1, add op1, then shift 4 bits
                     98: ;
                     99:        addb,tr         op1,pu,sh4n             ; add 2*op1, to shift
                    100:        addb,uv         op1,pu,sh4c             ;   product right 4 bits
                    101: ;
                    102: ;  ---- bits = 0011 ---- add op1, add 2*op1, shift 4 bits
                    103: ;
                    104:        addb,tr         op1,pu,sh4n-4           ; add op1 & 2*op1, shift
                    105:        sh1add,nsv      op1,pu,pu                       ;   product right 4 bits
                    106: ;
                    107: ;  ----        bits = 0100 ---- shift 2, add op1, shift 2
                    108: ;
                    109:        b               sh2sa
                    110:        shd             pu,pl,2,pl              ; shift product 2 bits
                    111: ;
                    112: ;  ----        bits = 0101 ---- add op1, shift 2, add op1, and shift 2 again
                    113: ;
                    114:        addb,tr         op1,pu,sh2us            ; add op1 to product
                    115:        shd             pu,pl,2,pl              ; shift 2 bits
                    116: ;
                    117: ;  ----        bits = 0110 ---- add op1, add op1, shift 2, add op1, and shift 2 again
                    118: ;
                    119:        addb,tr         op1,pu,sh2c             ; add 2*op1, to shift 2 bits
                    120:        addb,nuv        op1,pu,sh2us            ; br. if not overflow
                    121: ;
                    122: ;  ----        bits = 0111 ---- subtract op1, shift 3, add op1, and shift 1
                    123: ;
                    124:        b               sh3s
                    125:        sub             pu,op1,pu               ; subtract op1, br. to sh3s
                    126:
                    127: ;
                    128: ;  ----        bits = 1000 ---- shift 3, add op1, shift 1
                    129: ;
                    130:        b               sh3sa
                    131:        shd             pu,pl,3,pl              ; shift product right 3 bits
                    132: ;
                    133: ;  ----        bits = 1001 ---- add op1, shift 3, add op1, shift 1
                    134: ;
                    135:        addb,tr         op1,pu,sh3us            ; add op1, to shift 3, add op1,
                    136:        shd             pu,pl,3,pl              ;   and shift 1
                    137: ;
                    138: ;  ----        bits = 1010 ---- add op1, add op1, shift 3, add op1, shift 1
                    139: ;
                    140:        addb,tr         op1,pu,sh3c             ; add 2*op1, to shift 3 bits
                    141:        addb,nuv        op1,pu,sh3us            ;   br. if no overflow
                    142: ;
                    143: ;  ----        bits = 1011 ---- add -op1, shift 2, add -op1, shift 2, inc. next index
                    144: ;
                    145:        addib,tr        1,brindex,sh2s          ; add 1 to index, subtract op1,
                    146:        sub             pu,op1,pu               ;   shift 2 with minus sign
                    147: ;
                    148: ;  ----        bits = 1100 ---- shift 2, subtract op1, shift 2, increment next index
                    149: ;
                    150:        addib,tr        1,brindex,sh2sb         ; add 1 to index, to shift
                    151:        shd             pu,pl,2,pl              ; shift right 2 bits signed
                    152: ;
                    153: ;  ----        bits = 1101 ---- add op1, shift 2, add -op1, shift 2
                    154: ;
                    155:        addb,tr         op1,pu,sh2ns            ; add op1, to shift 2
                    156:        shd             pu,pl,2,pl              ;   right 2 unsigned, etc.
                    157: ;
                    158: ;  ----        bits = 1110 ---- shift 1 signed, add -op1, shift 3 signed
                    159: ;
                    160:        addib,tr        1,brindex,sh1sa         ; add 1 to index, to shift
                    161:        shd             pu,pl,1,pl              ; shift 1 bit
                    162: ;
                    163: ;  ----        bits = 1111 ---- add -op1, shift 4 signed
                    164: ;
                    165:        addib,tr        1,brindex,sh4s          ; add 1 to index, subtract op1,
                    166:        sub             pu,op1,pu               ;   to shift 4 signed
                    167:
                    168: ;
                    169: ;  ----        bits = 10000 ---- shift 4 signed
                    170: ;
                    171:        addib,tr        1,brindex,sh4s+4        ; add 1 to index
                    172:        shd             pu,pl,4,pl              ; shift 4 signed
                    173: ;
                    174: ;  ---- end of table ---------------------------------------------------------
                    175: ;
                    176: sh4s   shd             pu,pl,4,pl
                    177:        addib,tr        -1,cnt,mloop            ; loop (count > 0 always here)
                    178:        shd             pm,pu,4,pu              ; shift 4, minus signed
                    179: ;
                    180: sh4c   addib,>         -1,cnt,mloop            ; decrement count, loop if > 0
                    181:        shd             pc,pu,4,pu              ; shift 4 with overflow
                    182:        b               signs                   ; end of multiply
                    183:        bb,>=,n         sign,0,fini             ; test sign of procduct
                    184: ;
                    185: mpyb   add,=           op2,op2,gr0             ; if <> 0, back to main sect.
                    186:        b               mpy1
                    187:        sub             0,op2,op2               ; op2 = |multiplier|
                    188:        add,>=          op1,gr0,gr0             ; if op1 < 0, invert sign,
                    189:        xor             pm,sign,sign            ;   for correct result
                    190: ;
                    191: ;      special case for multiplier = -2**31, op1 = signed multiplicand
                    192: ;              or multiplicand = -2**31, op1 = signed multiplier
                    193: ;
                    194:        shd             op1,0,1,pl              ; shift op1 left 31 bits
                    195: mmax   extrs           op1,30,31,pu
                    196:        b               signs                   ; negate product (if needed)
                    197:        bb,>=,n         sign,0,fini             ; test sign of product
                    198: ;
                    199: mpya   add,=           op1,op1,gr0             ; op1 = -2**31, special case
                    200:        b               mpy2
                    201:        sub             0,op1,op1               ; op1 = |multiplicand|
                    202:        add,>=          op2,gr0,gr0             ; if op2 < 0, invert sign,
                    203:        xor             pm,sign,sign            ;   for correct result
                    204:        movb,tr         op2,op1,mmax            ; use op2 as multiplicand
                    205:        shd             op1,0,1,pl              ; shift it left 31 bits
                    206: ;
                    207: sh3c   shd             pu,pl,3,pl              ; shift product 3 bits
                    208:        shd             pc,pu,3,pu              ; shift 3 signed
                    209:        addb,tr         op1,pu,sh1              ; add op1, to shift 1 bit
                    210:        shd             pu,pl,1,pl
                    211: ;
                    212: sh3us  extru           pu,28,29,pu             ; shift 3 unsigned
                    213:        addb,tr         op1,pu,sh1              ; add op1, to shift 1 bit
                    214:        shd             pu,pl,1,pl
                    215: ;
                    216: sh3sa  extrs           pu,28,29,pu             ; shift 3 signed
                    217:        addb,tr         op1,pu,sh1              ; add op1, to shift 1 bit
                    218:        shd             pu,pl,1,pl
                    219: ;
                    220: sh3s   shd             pu,pl,3,pl              ; shift 3 minus signed
                    221:        shd             pm,pu,3,pu
                    222:        addb,tr         op1,pu,sh1              ; add op1, to shift 1 bit
                    223:        shd             pu,pl,1,pl
                    224: ;
                    225: sh1    addib,>         -1,cnt,mloop            ; loop if count > 0
                    226:        extru           pu,30,31,pu
                    227:        b               signs                   ; end of multiply
                    228:        bb,>=,n         sign,0,fini             ; test sign of product
                    229: ;
                    230: sh2ns  addib,tr        1,brindex,sh2sb+4       ; increment index
                    231:        extru           pu,29,30,pu             ; shift unsigned
                    232: ;
                    233: sh2s   shd             pu,pl,2,pl              ; shift with minus sign
                    234:        shd             pm,pu,2,pu              ;
                    235:        sub             pu,op1,pu               ; subtract op1
                    236:        shd             pu,pl,2,pl              ; shift with minus sign
                    237:        addib,tr        -1,cnt,mloop            ; decrement count, loop
                    238:        shd             pm,pu,2,pu              ; shift with minus sign
                    239:                                                ; count never reaches 0 here
                    240: ;
                    241: sh2sb  extrs           pu,29,30,pu             ; shift 2 signed
                    242:        sub             pu,op1,pu               ; subtract op1 from product
                    243:        shd             pu,pl,2,pl              ; shift with minus sign
                    244:        addib,tr        -1,cnt,mloop            ; decrement count, loop
                    245:        shd             pm,pu,2,pu              ; shift with minus sign
                    246:                                                ; count never reaches 0 here
                    247: ;
                    248: sh1sa  extrs           pu,30,31,pu             ;   signed
                    249:        sub             pu,op1,pu               ; subtract op1 from product
                    250:        shd             pu,pl,3,pl              ; shift 3 with minus sign
                    251:        addib,tr        -1,cnt,mloop            ; dec. count, to loop
                    252:        shd             pm,pu,3,pu              ; count never reaches 0 here
                    253: ;
                    254: fini0  movib,tr,n      0,pl,fini               ; product = 0 as op1 = 0
                    255: ;
                    256: sh2us  extru           pu,29,30,pu             ; shift 2 unsigned
                    257:        addb,tr         op1,pu,sh2a             ; add op1
                    258:        shd             pu,pl,2,pl              ; shift 2 bits
                    259: ;
                    260: sh2c   shd             pu,pl,2,pl
                    261:        shd             pc,pu,2,pu              ; shift with carry
                    262:        addb,tr         op1,pu,sh2a             ; add op1 to product
                    263:        shd             pu,pl,2,pl              ; br. to sh2 to shift pu
                    264: ;
                    265: sh2sa  extrs           pu,29,30,pu             ; shift with sign
                    266:        addb,tr         op1,pu,sh2a             ; add op1 to product
                    267:        shd             pu,pl,2,pl              ; br. to sh2 to shift pu
                    268: ;
                    269: sh2a   addib,>         -1,cnt,mloop            ; loop if count > 0
                    270:        extru           pu,29,30,pu
                    271: ;
                    272: mulend bb,>=,n         sign,0,fini             ; test sign of product
                    273: signs  sub             0,pl,pl                 ; negate product if sign
                    274:        subb            0,pu,pu                 ;   is negative
                    275: ;
                    276: ;      finish
                    277: ;
                    278: fini   stws            pu,0(arg2)              ; save high part of result
                    279:        stws            pl,4(arg2)              ; save low part of result
                    280:
                    281:        ldws,mb         -4(sp),pm               ; restore registers
                    282:        ldws,mb         -4(sp),pc               ; restore registers
                    283:        ldws,mb         -4(sp),sign             ; restore registers
                    284:        ldws,mb         -4(sp),brindex          ; restore registers
                    285:        ldws,mb         -4(sp),cnt              ; restore registers
                    286:        ldws,mb         -4(sp),op1              ; restore registers
                    287:        ldws,mb         -4(sp),pl               ; restore registers
                    288:        bv              0(rp)                   ; return
                    289:        ldws,mb         -4(sp),pu               ; restore registers
                    290: EXIT(s_xmpy)
                    291:
                    292:        .end

CVSweb