Annotation of 43BSDTahoe/usr.lib/libm/national/support.s, revision 1.1.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.