Annotation of 43BSDTahoe/usr.lib/libm/national/support.s, revision 1.1

1.1     ! root        1: ; Copyright (c) 1985 Regents of the University of California.
        !             2: ; All rights reserved.
        !             3: ;
        !             4: ; Redistribution and use in source and binary forms are permitted
        !             5: ; provided that the above copyright notice and this paragraph are
        !             6: ; duplicated in all such forms and that any documentation,
        !             7: ; advertising materials, and other materials related to such
        !             8: ; distribution and use acknowledge that the software was developed
        !             9: ; by the University of California, Berkeley.  The name of the
        !            10: ; University may not be used to endorse or promote products derived
        !            11: ; from this software without specific prior written permission.
        !            12: ; THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            13: ; IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            14: ; WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            15: ;
        !            16: ; All recipients should regard themselves as participants in an ongoing
        !            17: ; research project and hence should feel obligated to report their
        !            18: ; experiences (good or bad) with these elementary function codes, using
        !            19: ; the sendbug(8) program, to the authors.
        !            20: ;
        !            21: ;      @(#)support.s   5.3 (Berkeley) 6/30/88
        !            22: ;
        !            23: 
        !            24: ; IEEE recommended functions
        !            25: ; 
        !            26: ; double copysign(x,y)
        !            27: ; double x,y;
        !            28: ; IEEE 754 recommended function, return x*sign(y)
        !            29: ; Coded by K.C. Ng in National 32k assembler, 11/9/85.
        !            30: ;
        !            31:        .vers   2
        !            32:        .text
        !            33:        .align  2
        !            34:        .globl  _copysign
        !            35: _copysign:
        !            36:        movl    4(sp),f0
        !            37:        movd    8(sp),r0
        !            38:        movd    16(sp),r1
        !            39:        xord    r0,r1
        !            40:        andd    0x80000000,r1
        !            41:        cmpqd   0,r1
        !            42:        beq     end
        !            43:        negl    f0,f0
        !            44: end:   ret     0
        !            45: 
        !            46: ; 
        !            47: ; double logb(x)
        !            48: ; double x;
        !            49: ; IEEE p854 recommended function, return the exponent of x (return float(N) 
        !            50: ; such that 1 <= x*2**-N < 2, even for subnormal number.
        !            51: ; Coded by K.C. Ng in National 32k assembler, 11/9/85.
        !            52: ; Note: subnormal number (if implemented) will be taken care of. 
        !            53: ;
        !            54:        .vers   2
        !            55:        .text
        !            56:        .align  2
        !            57:        .globl  _logb
        !            58: _logb:
        !            59: ;
        !            60: ; extract the exponent of x
        !            61: ; glossaries:  r0 = high part of x
        !            62: ;              r1 = unbias exponent of x
        !            63: ;              r2 = 20 (first exponent bit position)
        !            64: ;
        !            65:        movd    8(sp),r0
        !            66:        movd    20,r2
        !            67:        extd    r2,r0,r1,11     ; extract the exponent of x
        !            68:        cmpqd   0,r1            ; if exponent bits = 0, goto L3
        !            69:        beq     L3
        !            70:        cmpd    0x7ff,r1
        !            71:        beq     L2              ; if exponent bits = 0x7ff, goto L2
        !            72: L1:    subd    1023,r1         ; unbias the exponent
        !            73:        movdl   r1,f0           ; convert the exponent to floating value
        !            74:        ret     0
        !            75: ;
        !            76: ; x is INF or NaN, simply return x
        !            77: ;
        !            78: L2:
        !            79:        movl    4(sp),f0        ; logb(+inf)=+inf, logb(NaN)=NaN
        !            80:        ret     0
        !            81: ;
        !            82: ; x is 0 or subnormal
        !            83: ;
        !            84: L3:
        !            85:        movl    4(sp),f0
        !            86:        cmpl    0f0,f0
        !            87:        beq     L5              ; x is 0 , goto L5 (return -inf)
        !            88: ;
        !            89: ; Now x is subnormal
        !            90: ;
        !            91:        mull    L64,f0          ; scale up f0 with 2**64
        !            92:        movl    f0,tos
        !            93:        movd    tos,r0
        !            94:        movd    tos,r0          ; now r0 = new high part of x
        !            95:        extd    r2,r0,r1,11     ; extract the exponent of x to r1
        !            96:        subd    1087,r1         ; unbias the exponent with correction 
        !            97:        movdl   r1,f0           ; convert the exponent to floating value
        !            98:        ret     0
        !            99: ;
        !           100: ; x is 0, return logb(0)= -INF
        !           101: ;
        !           102: L5:
        !           103:        movl    0f1.0e300,f0
        !           104:        mull    0f-1.0e300,f0   ; multiply two big numbers to get -INF
        !           105:        ret     0
        !           106: ; 
        !           107: ; double rint(x)
        !           108: ; double x;
        !           109: ; ... delivers integer nearest x in direction of prevailing rounding
        !           110: ; ... mode
        !           111: ; Coded by K.C. Ng in National 32k assembler, 11/9/85.
        !           112: ; Note: subnormal number (if implemented) will be taken care of. 
        !           113: ;
        !           114:        .vers   2
        !           115:        .text
        !           116:        .align  2
        !           117:        .globl  _rint
        !           118: _rint:
        !           119: ;
        !           120:        movd    8(sp),r0
        !           121:        movd    20,r2
        !           122:        extd    r2,r0,r1,11     ; extract the exponent of x
        !           123:        cmpd    0x433,r1
        !           124:        ble     itself
        !           125:        movl    L52,f2          ; f2 = L = 2**52
        !           126:        cmpqd   0,r0
        !           127:        ble     L1
        !           128:        negl    f2,f2           ; f2 = s = copysign(L,x)
        !           129: L1:    addl    f2,f0           ; f0 = x + s
        !           130:        subl    f2,f0           ; f0 = f0 - s
        !           131:        ret     0
        !           132: itself:        movl    4(sp),f0
        !           133:        ret     0
        !           134: L52:   .double 0x0,0x43300000  ; L52=2**52
        !           135: ; 
        !           136: ; int finite(x)
        !           137: ; double x;
        !           138: ; IEEE 754 recommended function, return 0 if x is NaN or INF, else 0
        !           139: ; Coded by K.C. Ng in National 32k assembler, 11/9/85.
        !           140: ;
        !           141:        .vers   2
        !           142:        .text
        !           143:        .align  2
        !           144:        .globl  _finite
        !           145: _finite:
        !           146:        movd    4(sp),r1
        !           147:        andd    0x800fffff,r1
        !           148:        cmpd    0x7ff00000,r1
        !           149:        sned    r0              ; r0=0 if exponent(x) = 0x7ff
        !           150:        ret     0
        !           151: ; 
        !           152: ; double scalb(x,N)
        !           153: ; double x; int N;
        !           154: ; IEEE 754 recommended function, return x*2**N by adjusting 
        !           155: ; exponent of x.
        !           156: ; Coded by K.C. Ng in National 32k assembler, 11/9/85. 
        !           157: ; Note: subnormal number (if implemented) will be taken care of 
        !           158: ;
        !           159:        .vers   2
        !           160:        .text
        !           161:        .align  2
        !           162:        .globl  _scalb
        !           163: _scalb:
        !           164: ;
        !           165: ; if x=0 return 0
        !           166: ;
        !           167:        movl    4(sp),f0
        !           168:        cmpl    0f0,f0
        !           169:        beq     end             ; scalb(0,N) is x itself
        !           170: ;
        !           171: ; extract the exponent of x
        !           172: ; glossaries:  r0 = high part of x, 
        !           173: ;              r1 = unbias exponent of x,
        !           174: ;              r2 = 20 (first exponent bit position).
        !           175: ;
        !           176:        movd    8(sp),r0        ; r0 = high part of x
        !           177:        movd    20,r2           ; r2 = 20
        !           178:        extd    r2,r0,r1,11     ; extract the exponent of x in r1
        !           179:        cmpd    0x7ff,r1        
        !           180: ;
        !           181: ; if exponent of x is 0x7ff, then x is NaN or INF; simply return x  
        !           182: ;
        !           183:        beq     end             
        !           184:        cmpqd   0,r1
        !           185: ;
        !           186: ; if exponent of x is zero, then x is subnormal; goto L19
        !           187: ;
        !           188:        beq     L19             
        !           189:        addd    12(sp),r1       ; r1 = (exponent of x) + N
        !           190:        bfs     inof            ; if integer overflows, goto inof
        !           191:        cmpqd   0,r1            ; if new exponent <= 0, goto underflow
        !           192:        bge     underflow
        !           193:        cmpd    2047,r1         ; if new exponent >= 2047 goto overflow
        !           194:        ble     overflow
        !           195:        insd    r2,r1,r0,11     ; insert the new exponent 
        !           196:        movd    r0,tos
        !           197:        movd    8(sp),tos
        !           198:        movl    tos,f0          ; return x*2**N
        !           199: end:   ret     0
        !           200: inof:  bcs     underflow       ; negative int overflow if Carry bit is set
        !           201: overflow:
        !           202:        andd    0x80000000,r0   ; keep the sign of x
        !           203:        ord     0x7fe00000,r0   ; set x to a huge number
        !           204:        movd    r0,tos
        !           205:        movqd   0,tos
        !           206:        movl    tos,f0
        !           207:        mull    0f1.0e300,f0    ; multiply two huge number to get overflow
        !           208:        ret     0
        !           209: underflow:
        !           210:        addd    64,r1           ; add 64 to exonent to see if it is subnormal
        !           211:        cmpqd   0,r1
        !           212:        bge     zero            ; underflow to zero
        !           213:        insd    r2,r1,r0,11     ; insert the new exponent 
        !           214:        movd    r0,tos
        !           215:        movd    8(sp),tos
        !           216:        movl    tos,f0
        !           217:        mull    L30,f0          ; readjust x by multiply it with 2**-64
        !           218:        ret     0
        !           219: zero:  andd    0x80000000,r0   ; keep the sign of x
        !           220:        ord     0x00100000,r0   ; set x to a tiny number
        !           221:        movd    r0,tos
        !           222:        movqd   0,tos
        !           223:        movl    tos,f0
        !           224:        mull    0f1.0e-300,f0   ; underflow to 0  by multipling two tiny nos.
        !           225:        ret     0
        !           226: L19:           ; subnormal number
        !           227:        mull    L32,f0          ; scale up x by 2**64
        !           228:        movl    f0,tos
        !           229:        movd    tos,r0
        !           230:        movd    tos,r0          ; get the high part of new x
        !           231:        extd    r2,r0,r1,11     ; extract the exponent of x in r1
        !           232:        addd    12(sp),r1       ; exponent of x + N
        !           233:        subd    64,r1           ; adjust it by subtracting 64
        !           234:        cmpqd   0,r1
        !           235:        bge     underflow
        !           236:        cmpd    2047,r1
        !           237:        ble     overflow
        !           238:        insd    r2,r1,r0,11     ; insert back the incremented exponent 
        !           239:        movd    r0,tos
        !           240:        movd    8(sp),tos
        !           241:        movl    tos,f0
        !           242: end:   ret     0
        !           243: L30:   .double 0x0,0x3bf00000  ; floating point 2**-64
        !           244: L32:   .double 0x0,0x43f00000  ; floating point 2**64
        !           245: ; 
        !           246: ; double drem(x,y)
        !           247: ; double x,y;
        !           248: ; IEEE double remainder function, return x-n*y, where n=x/y rounded to 
        !           249: ; nearest integer (half way case goes to even). Result exact.
        !           250: ; Coded by K.C. Ng in National 32k assembly, 11/19/85.
        !           251: ;
        !           252:        .vers   2
        !           253:        .text
        !           254:        .align  2
        !           255:        .globl  _drem
        !           256: _drem:
        !           257: ;
        !           258: ; glossaries:  
        !           259: ;              r2 = high part of x
        !           260: ;              r3 = exponent of x
        !           261: ;              r4 = high part of y
        !           262: ;              r5 = exponent of y
        !           263: ;              r6 = sign of x
        !           264: ;              r7 = constant 0x7ff00000
        !           265: ;
        !           266: ;  16(fp) : y
        !           267: ;   8(fp) : x
        !           268: ; -12(fp) : adjustment on y when y is subnormal
        !           269: ; -16(fp) : fsr
        !           270: ; -20(fp) : nx
        !           271: ; -28(fp) : t
        !           272: ; -36(fp) : t1
        !           273: ; -40(fp) : nf
        !           274: ; 
        !           275: ;
        !           276:        enter   [r3,r4,r5,r6,r7],40
        !           277:        movl    f6,tos
        !           278:        movl    f4,tos
        !           279:        movl    0f0,-12(fp)
        !           280:        movd    0,-20(fp)
        !           281:        movd    0,-40(fp)
        !           282:        movd    0x7ff00000,r7   ; initialize r7=0x7ff00000
        !           283:        movd    12(fp),r2       ; r2 = high(x)
        !           284:        movd    r2,r3
        !           285:        andd    r7,r3           ; r3 = xexp
        !           286:        cmpd    r7,r3
        !           287: ; if x is NaN or INF goto L1
        !           288:        beq     L1              
        !           289:        movd    20(fp),r4
        !           290:        bicd    [31],r4         ; r4 = high part of |y|
        !           291:        movd    r4,20(fp)       ; y = |y|
        !           292:        movd    r4,r5
        !           293:        andd    r7,r5           ; r5 = yexp
        !           294:        cmpd    r7,r5
        !           295:        beq     L2              ; if y is NaN or INF goto L2
        !           296:        cmpd    0x04000000,r5   ; 
        !           297:        bgt     L3              ; if y is tiny goto L3
        !           298: ;
        !           299: ; now y != 0 , x is finite
        !           300: ;
        !           301: L10:
        !           302:        movd    r2,r6
        !           303:        andd    0x80000000,r6   ; r6 = sign(x)
        !           304:        bicd    [31],r2         ; x <- |x|
        !           305:        sfsr    r1
        !           306:        movd    r1,-16(fp)      ; save fsr in -16(fp)
        !           307:        bicd    [5],r1
        !           308:        lfsr    r1              ; disable inexact interupt
        !           309:        movd    16(fp),r0       ; r0 = low part of y
        !           310:        movd    r0,r1           ; r1 = r0 = low part of y
        !           311:        andd    0xf8000000,r1   ; mask off the lsb 27 bits of y
        !           312: 
        !           313:        movd    r2,12(fp)       ; update x to |x|
        !           314:        movd    r0,-28(fp)      ; 
        !           315:        movd    r4,-24(fp)      ; t  = y
        !           316:        movd    r4,-32(fp)      ; 
        !           317:        movd    r1,-36(fp)      ; t1 = y with trialing 27 zeros
        !           318:        movd    0x01900000,r1   ; r1 = 25 in exponent field
        !           319: LOOP:
        !           320:        movl    8(fp),f0        ; f0 = x
        !           321:        movl    16(fp),f2       ; f2 = y
        !           322:        cmpl    f0,f2
        !           323:        ble     fnad            ; goto fnad (final adjustment) if x <= y
        !           324:        movd    r4,-32(fp)
        !           325:        movd    r3,r0
        !           326:        subd    r5,r0           ; xexp - yexp
        !           327:        subd    r1,r0           ; r0 = xexp - yexp - m25
        !           328:        cmpqd   0,r0            ; r0 > 0 ?
        !           329:        bge     1f
        !           330:        addd    r4,r0           ; scale up (high) y
        !           331:        movd    r0,-24(fp)      ; scale up t
        !           332:        movl    -28(fp),f2      ; t
        !           333:        movd    r0,-32(fp)      ; scale up t1
        !           334: 1:
        !           335:        movl    -36(fp),f4      ; t1
        !           336:        movl    f0,f6
        !           337:        divl    f2,f6           ; f6 = x/t
        !           338:        floorld f6,r0           ; r0 = [x/t]
        !           339:        movdl   r0,f6           ; f6 = n
        !           340:        subl    f4,f2           ; t = t - t1 (tail of t1)
        !           341:        mull    f6,f4           ; f4 = n*t1     ...exact
        !           342:        subl    f4,f0           ; x = x - n*t1
        !           343:        mull    f6,f2           ; n*(t-t1)      ...exact
        !           344:        subl    f2,f0           ; x = x - n*(t-t1)
        !           345: ; update xexp
        !           346:        movl    f0,8(fp)
        !           347:        movd    12(fp),r3       
        !           348:        andd    r7,r3
        !           349:        jump    LOOP
        !           350: fnad:
        !           351:        cmpqd   0,-20(fp)       ; 0 = nx?
        !           352:        beq     final
        !           353:        mull    -12(fp),8(fp)   ; scale up x the same amount as y
        !           354:        movd    0,-20(fp)
        !           355:        movd    12(fp),r2
        !           356:        movd    r2,r3
        !           357:        andd    r7,r3           ; update exponent of x
        !           358:        jump    LOOP
        !           359: 
        !           360: final:
        !           361:        movl    16(fp),f2       ; f2 = y (f0=x, r0=n)
        !           362:        subd    0x100000,r4     ; high y /2
        !           363:        movd    r4,-24(fp)
        !           364:        movl    -28(fp),f4      ; f4 = y/2
        !           365:        cmpl    f0,f4           ; x > y/2 ?
        !           366:        bgt     1f
        !           367:        bne     2f
        !           368:        andd    1,r0            ; n is odd or even
        !           369:        cmpqd   0,r0
        !           370:        beq     2f
        !           371: 1:
        !           372:        subl    f2,f0           ; x = x - y
        !           373: 2:
        !           374:        cmpqd   0,-40(fp)
        !           375:        beq     3f
        !           376:        divl    -12(fp),f0      ; scale down the answer
        !           377: 3:
        !           378:        movl    f0,tos
        !           379:        xord    r6,tos
        !           380:        movl    tos,f0
        !           381:        movd    -16(fp),r0
        !           382:        lfsr    r0              ; restore the fsr
        !           383: 
        !           384: end:   movl    tos,f4
        !           385:        movl    tos,f6
        !           386:        exit    [r3,r4,r5,r6,r7]
        !           387:        ret     0
        !           388: ;
        !           389: ; y is NaN or INF
        !           390: ;
        !           391: L2:    
        !           392:        movd    16(fp),r0       ; r0 = low part of y
        !           393:        andd    0xfffff,r4      ; r4 = high part of y & 0x000fffff
        !           394:        ord     r4,r0
        !           395:        cmpqd   0,r0
        !           396:        beq     L4
        !           397:        movl    16(fp),f0       ; y is NaN, return y
        !           398:        jump    end
        !           399: L4:    movl    8(fp),f0        ; y is inf, return x
        !           400:        jump    end
        !           401: ;
        !           402: ; exponent of y is less than 64, y may be zero or subnormal
        !           403: ;
        !           404: L3:
        !           405:        movl    16(fp),f0
        !           406:        cmpl    0f0,f0
        !           407:        bne     L5
        !           408:        divl    f0,f0           ; y is 0, return NaN by doing 0/0
        !           409:        jump    end
        !           410: ;
        !           411: ; subnormal y or tiny y
        !           412: ;
        !           413: L5:    
        !           414:        movd    0x04000000,-20(fp)      ; nx = 64 in exponent field
        !           415:        movl    L64,f2
        !           416:        movl    f2,-12(fp)
        !           417:        mull    f2,f0
        !           418:        cmpl    f0,LTINY
        !           419:        bgt     L6
        !           420:        mull    f2,f0
        !           421:        addd    0x04000000,-20(fp)      ; nx = nx + 64 in exponent field
        !           422:        mull    f2,-12(fp)
        !           423: L6:
        !           424:        movd    -20(fp),-40(fp)
        !           425:        movl    f0,16(fp)
        !           426:        movd    20(fp),r4
        !           427:        movd    r4,r5
        !           428:        andd    r7,r5           ; exponent of new y
        !           429:        jump    L10
        !           430: ;
        !           431: ; x is NaN or INF, return x-x
        !           432: ;
        !           433: L1:
        !           434:        movl    8(fp),f0
        !           435:        subl    f0,f0           ; if x is INF, then INF-INF is NaN
        !           436:        ret     0
        !           437: L64:   .double 0x0,0x43f00000  ; L64 = 2**64
        !           438: LTINY: .double 0x0,0x04000000  ; LTINY = 2**-959

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.