[BACK]Return to srem_mod.sa CVS log [TXT][DIR] Up to [local] / sys / arch / m68k / fpsp

Annotation of sys/arch/m68k/fpsp/srem_mod.sa, Revision 1.1

1.1     ! nbrk        1: *      $OpenBSD: srem_mod.sa,v 1.2 1996/05/29 21:05:41 niklas Exp $
        !             2: *      $NetBSD: srem_mod.sa,v 1.3 1994/10/26 07:49:58 cgd Exp $
        !             3:
        !             4: *      MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
        !             5: *      M68000 Hi-Performance Microprocessor Division
        !             6: *      M68040 Software Package
        !             7: *
        !             8: *      M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
        !             9: *      All rights reserved.
        !            10: *
        !            11: *      THE SOFTWARE is provided on an "AS IS" basis and without warranty.
        !            12: *      To the maximum extent permitted by applicable law,
        !            13: *      MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
        !            14: *      INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
        !            15: *      PARTICULAR PURPOSE and any warranty against infringement with
        !            16: *      regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
        !            17: *      and any accompanying written materials.
        !            18: *
        !            19: *      To the maximum extent permitted by applicable law,
        !            20: *      IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
        !            21: *      (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
        !            22: *      PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
        !            23: *      OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
        !            24: *      SOFTWARE.  Motorola assumes no responsibility for the maintenance
        !            25: *      and support of the SOFTWARE.
        !            26: *
        !            27: *      You are hereby granted a copyright license to use, modify, and
        !            28: *      distribute the SOFTWARE so long as this entire notice is retained
        !            29: *      without alteration in any modified and/or redistributed versions,
        !            30: *      and that such modified versions are clearly identified as such.
        !            31: *      No licenses are granted by implication, estoppel or otherwise
        !            32: *      under any patents or trademarks of Motorola, Inc.
        !            33:
        !            34: *
        !            35: *      srem_mod.sa 3.1 12/10/90
        !            36: *
        !            37: *      The entry point sMOD computes the floating point MOD of the
        !            38: *      input values X and Y. The entry point sREM computes the floating
        !            39: *      point (IEEE) REM of the input values X and Y.
        !            40: *
        !            41: *      INPUT
        !            42: *      -----
        !            43: *      Double-extended value Y is pointed to by address in register
        !            44: *      A0. Double-extended value X is located in -12(A0). The values
        !            45: *      of X and Y are both nonzero and finite; although either or both
        !            46: *      of them can be denormalized. The special cases of zeros, NaNs,
        !            47: *      and infinities are handled elsewhere.
        !            48: *
        !            49: *      OUTPUT
        !            50: *      ------
        !            51: *      FREM(X,Y) or FMOD(X,Y), depending on entry point.
        !            52: *
        !            53: *       ALGORITHM
        !            54: *       ---------
        !            55: *
        !            56: *       Step 1.  Save and strip signs of X and Y: signX := sign(X),
        !            57: *                signY := sign(Y), X := |X|, Y := |Y|,
        !            58: *                signQ := signX EOR signY. Record whether MOD or REM
        !            59: *                is requested.
        !            60: *
        !            61: *       Step 2.  Set L := expo(X)-expo(Y), k := 0, Q := 0.
        !            62: *                If (L < 0) then
        !            63: *                   R := X, go to Step 4.
        !            64: *                else
        !            65: *                   R := 2^(-L)X, j := L.
        !            66: *                endif
        !            67: *
        !            68: *       Step 3.  Perform MOD(X,Y)
        !            69: *            3.1 If R = Y, go to Step 9.
        !            70: *            3.2 If R > Y, then { R := R - Y, Q := Q + 1}
        !            71: *            3.3 If j = 0, go to Step 4.
        !            72: *            3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to
        !            73: *                Step 3.1.
        !            74: *
        !            75: *       Step 4.  At this point, R = X - QY = MOD(X,Y). Set
        !            76: *                Last_Subtract := false (used in Step 7 below). If
        !            77: *                MOD is requested, go to Step 6.
        !            78: *
        !            79: *       Step 5.  R = MOD(X,Y), but REM(X,Y) is requested.
        !            80: *            5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to
        !            81: *                Step 6.
        !            82: *            5.2 If R > Y/2, then { set Last_Subtract := true,
        !            83: *                Q := Q + 1, Y := signY*Y }. Go to Step 6.
        !            84: *            5.3 This is the tricky case of R = Y/2. If Q is odd,
        !            85: *                then { Q := Q + 1, signX := -signX }.
        !            86: *
        !            87: *       Step 6.  R := signX*R.
        !            88: *
        !            89: *       Step 7.  If Last_Subtract = true, R := R - Y.
        !            90: *
        !            91: *       Step 8.  Return signQ, last 7 bits of Q, and R as required.
        !            92: *
        !            93: *       Step 9.  At this point, R = 2^(-j)*X - Q Y = Y. Thus,
        !            94: *                X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1),
        !            95: *                R := 0. Return signQ, last 7 bits of Q, and R.
        !            96: *
        !            97:
        !            98: SREM_MOD    IDNT    2,1 Motorola 040 Floating Point Software Package
        !            99:
        !           100:        section    8
        !           101:
        !           102:        include fpsp.h
        !           103:
        !           104: Mod_Flag  equ  L_SCR3
        !           105: SignY     equ  FP_SCR3+4
        !           106: SignX     equ  FP_SCR3+8
        !           107: SignQ     equ  FP_SCR3+12
        !           108: Sc_Flag   equ  FP_SCR4
        !           109:
        !           110: Y         equ  FP_SCR1
        !           111: Y_Hi      equ  Y+4
        !           112: Y_Lo      equ  Y+8
        !           113:
        !           114: R         equ  FP_SCR2
        !           115: R_Hi      equ  R+4
        !           116: R_Lo      equ  R+8
        !           117:
        !           118:
        !           119: Scale     DC.L $00010000,$80000000,$00000000,$00000000
        !           120:
        !           121:        xref    t_avoid_unsupp
        !           122:
        !           123:         xdef        smod
        !           124: smod:
        !           125:
        !           126:    Clr.L                Mod_Flag(a6)
        !           127:    BRA.B                Mod_Rem
        !           128:
        !           129:         xdef        srem
        !           130: srem:
        !           131:
        !           132:    Move.L               #1,Mod_Flag(a6)
        !           133:
        !           134: Mod_Rem:
        !           135: *..Save sign of X and Y
        !           136:    MoveM.L              D2-D7,-(A7)     ...save data registers
        !           137:    Move.W               (A0),D3
        !           138:    Move.W               D3,SignY(a6)
        !           139:    AndI.L               #$00007FFF,D3   ...Y := |Y|
        !           140:
        !           141: *
        !           142:    Move.L               4(A0),D4
        !           143:    Move.L               8(A0),D5        ...(D3,D4,D5) is |Y|
        !           144:
        !           145:    Tst.L                D3
        !           146:    BNE.B                Y_Normal
        !           147:
        !           148:    Move.L               #$00003FFE,D3  ...$3FFD + 1
        !           149:    Tst.L                D4
        !           150:    BNE.B                HiY_not0
        !           151:
        !           152: HiY_0:
        !           153:    Move.L               D5,D4
        !           154:    CLR.L                D5
        !           155:    SubI.L               #32,D3
        !           156:    CLR.L                D6
        !           157:    BFFFO                D4{0:32},D6
        !           158:    LSL.L                D6,D4
        !           159:    Sub.L                D6,D3           ...(D3,D4,D5) is normalized
        !           160: *                                       ...with bias $7FFD
        !           161:    BRA.B                Chk_X
        !           162:
        !           163: HiY_not0:
        !           164:    CLR.L                D6
        !           165:    BFFFO                D4{0:32},D6
        !           166:    Sub.L                D6,D3
        !           167:    LSL.L                D6,D4
        !           168:    Move.L               D5,D7           ...a copy of D5
        !           169:    LSL.L                D6,D5
        !           170:    Neg.L                D6
        !           171:    AddI.L               #32,D6
        !           172:    LSR.L                D6,D7
        !           173:    Or.L                 D7,D4           ...(D3,D4,D5) normalized
        !           174: *                                       ...with bias $7FFD
        !           175:    BRA.B                Chk_X
        !           176:
        !           177: Y_Normal:
        !           178:    AddI.L               #$00003FFE,D3   ...(D3,D4,D5) normalized
        !           179: *                                       ...with bias $7FFD
        !           180:
        !           181: Chk_X:
        !           182:    Move.W               -12(A0),D0
        !           183:    Move.W               D0,SignX(a6)
        !           184:    Move.W               SignY(a6),D1
        !           185:    EOr.L                D0,D1
        !           186:    AndI.L               #$00008000,D1
        !           187:    Move.W               D1,SignQ(a6)   ...sign(Q) obtained
        !           188:    AndI.L               #$00007FFF,D0
        !           189:    Move.L               -8(A0),D1
        !           190:    Move.L               -4(A0),D2       ...(D0,D1,D2) is |X|
        !           191:    Tst.L                D0
        !           192:    BNE.B                X_Normal
        !           193:    Move.L               #$00003FFE,D0
        !           194:    Tst.L                D1
        !           195:    BNE.B                HiX_not0
        !           196:
        !           197: HiX_0:
        !           198:    Move.L               D2,D1
        !           199:    CLR.L                D2
        !           200:    SubI.L               #32,D0
        !           201:    CLR.L                D6
        !           202:    BFFFO                D1{0:32},D6
        !           203:    LSL.L                D6,D1
        !           204:    Sub.L                D6,D0           ...(D0,D1,D2) is normalized
        !           205: *                                       ...with bias $7FFD
        !           206:    BRA.B                Init
        !           207:
        !           208: HiX_not0:
        !           209:    CLR.L                D6
        !           210:    BFFFO                D1{0:32},D6
        !           211:    Sub.L                D6,D0
        !           212:    LSL.L                D6,D1
        !           213:    Move.L               D2,D7           ...a copy of D2
        !           214:    LSL.L                D6,D2
        !           215:    Neg.L                D6
        !           216:    AddI.L               #32,D6
        !           217:    LSR.L                D6,D7
        !           218:    Or.L                 D7,D1           ...(D0,D1,D2) normalized
        !           219: *                                       ...with bias $7FFD
        !           220:    BRA.B                Init
        !           221:
        !           222: X_Normal:
        !           223:    AddI.L               #$00003FFE,D0   ...(D0,D1,D2) normalized
        !           224: *                                       ...with bias $7FFD
        !           225:
        !           226: Init:
        !           227: *
        !           228:    Move.L               D3,L_SCR1(a6)   ...save biased expo(Y)
        !           229:    move.l              d0,L_SCR2(a6)   ;save d0
        !           230:    Sub.L                D3,D0           ...L := expo(X)-expo(Y)
        !           231: *   Move.L               D0,L            ...D0 is j
        !           232:    CLR.L                D6              ...D6 := carry <- 0
        !           233:    CLR.L                D3              ...D3 is Q
        !           234:    MoveA.L              #0,A1           ...A1 is k; j+k=L, Q=0
        !           235:
        !           236: *..(Carry,D1,D2) is R
        !           237:    Tst.L                D0
        !           238:    BGE.B                Mod_Loop
        !           239:
        !           240: *..expo(X) < expo(Y). Thus X = mod(X,Y)
        !           241: *
        !           242:    move.l              L_SCR2(a6),d0   ;restore d0
        !           243:    BRA.W                Get_Mod
        !           244:
        !           245: *..At this point  R = 2^(-L)X; Q = 0; k = 0; and  k+j = L
        !           246:
        !           247:
        !           248: Mod_Loop:
        !           249:    Tst.L                D6              ...test carry bit
        !           250:    BGT.B                R_GT_Y
        !           251:
        !           252: *..At this point carry = 0, R = (D1,D2), Y = (D4,D5)
        !           253:    Cmp.L                D4,D1           ...compare hi(R) and hi(Y)
        !           254:    BNE.B                R_NE_Y
        !           255:    Cmp.L                D5,D2           ...compare lo(R) and lo(Y)
        !           256:    BNE.B                R_NE_Y
        !           257:
        !           258: *..At this point, R = Y
        !           259:    BRA.W                Rem_is_0
        !           260:
        !           261: R_NE_Y:
        !           262: *..use the borrow of the previous compare
        !           263:    BCS.B                R_LT_Y          ...borrow is set iff R < Y
        !           264:
        !           265: R_GT_Y:
        !           266: *..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0
        !           267: *..and Y < (D1,D2) < 2Y. Either way, perform R - Y
        !           268:    Sub.L                D5,D2           ...lo(R) - lo(Y)
        !           269:    SubX.L               D4,D1           ...hi(R) - hi(Y)
        !           270:    CLR.L                D6              ...clear carry
        !           271:    AddQ.L               #1,D3           ...Q := Q + 1
        !           272:
        !           273: R_LT_Y:
        !           274: *..At this point, Carry=0, R < Y. R = 2^(k-L)X - QY; k+j = L; j >= 0.
        !           275:    Tst.L                D0              ...see if j = 0.
        !           276:    BEQ.B                PostLoop
        !           277:
        !           278:    Add.L                D3,D3           ...Q := 2Q
        !           279:    Add.L                D2,D2           ...lo(R) = 2lo(R)
        !           280:    AddX.L               D1,D1           ...hi(R) = 2hi(R) + carry
        !           281:    SCS                  D6              ...set Carry if 2(R) overflows
        !           282:    AddQ.L               #1,A1           ...k := k+1
        !           283:    SubQ.L               #1,D0           ...j := j - 1
        !           284: *..At this point, R=(Carry,D1,D2) = 2^(k-L)X - QY, j+k=L, j >= 0, R < 2Y.
        !           285:
        !           286:    BRA.B                Mod_Loop
        !           287:
        !           288: PostLoop:
        !           289: *..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y.
        !           290:
        !           291: *..normalize R.
        !           292:    Move.L               L_SCR1(a6),D0           ...new biased expo of R
        !           293:    Tst.L                D1
        !           294:    BNE.B                HiR_not0
        !           295:
        !           296: HiR_0:
        !           297:    Move.L               D2,D1
        !           298:    CLR.L                D2
        !           299:    SubI.L               #32,D0
        !           300:    CLR.L                D6
        !           301:    BFFFO                D1{0:32},D6
        !           302:    LSL.L                D6,D1
        !           303:    Sub.L                D6,D0           ...(D0,D1,D2) is normalized
        !           304: *                                       ...with bias $7FFD
        !           305:    BRA.B                Get_Mod
        !           306:
        !           307: HiR_not0:
        !           308:    CLR.L                D6
        !           309:    BFFFO                D1{0:32},D6
        !           310:    BMI.B                Get_Mod         ...already normalized
        !           311:    Sub.L                D6,D0
        !           312:    LSL.L                D6,D1
        !           313:    Move.L               D2,D7           ...a copy of D2
        !           314:    LSL.L                D6,D2
        !           315:    Neg.L                D6
        !           316:    AddI.L               #32,D6
        !           317:    LSR.L                D6,D7
        !           318:    Or.L                 D7,D1           ...(D0,D1,D2) normalized
        !           319:
        !           320: *
        !           321: Get_Mod:
        !           322:    CmpI.L              #$000041FE,D0
        !           323:    BGE.B               No_Scale
        !           324: Do_Scale:
        !           325:    Move.W              D0,R(a6)
        !           326:    clr.w               R+2(a6)
        !           327:    Move.L              D1,R_Hi(a6)
        !           328:    Move.L              D2,R_Lo(a6)
        !           329:    Move.L              L_SCR1(a6),D6
        !           330:    Move.W              D6,Y(a6)
        !           331:    clr.w               Y+2(a6)
        !           332:    Move.L              D4,Y_Hi(a6)
        !           333:    Move.L              D5,Y_Lo(a6)
        !           334:    FMove.X             R(a6),fp0               ...no exception
        !           335:    Move.L              #1,Sc_Flag(a6)
        !           336:    BRA.B               ModOrRem
        !           337: No_Scale:
        !           338:    Move.L              D1,R_Hi(a6)
        !           339:    Move.L              D2,R_Lo(a6)
        !           340:    SubI.L              #$3FFE,D0
        !           341:    Move.W              D0,R(a6)
        !           342:    clr.w               R+2(a6)
        !           343:    Move.L              L_SCR1(a6),D6
        !           344:    SubI.L              #$3FFE,D6
        !           345:    Move.L              D6,L_SCR1(a6)
        !           346:    FMove.X             R(a6),fp0
        !           347:    Move.W              D6,Y(a6)
        !           348:    Move.L              D4,Y_Hi(a6)
        !           349:    Move.L              D5,Y_Lo(a6)
        !           350:    Clr.L               Sc_Flag(a6)
        !           351:
        !           352: *
        !           353:
        !           354:
        !           355: ModOrRem:
        !           356:    Move.L               Mod_Flag(a6),D6
        !           357:    BEQ.B                Fix_Sign
        !           358:
        !           359:    Move.L               L_SCR1(a6),D6           ...new biased expo(Y)
        !           360:    SubQ.L               #1,D6           ...biased expo(Y/2)
        !           361:    Cmp.L                D6,D0
        !           362:    BLT.B                Fix_Sign
        !           363:    BGT.B                Last_Sub
        !           364:
        !           365:    Cmp.L                D4,D1
        !           366:    BNE.B                Not_EQ
        !           367:    Cmp.L                D5,D2
        !           368:    BNE.B                Not_EQ
        !           369:    BRA.W                Tie_Case
        !           370:
        !           371: Not_EQ:
        !           372:    BCS.B                Fix_Sign
        !           373:
        !           374: Last_Sub:
        !           375: *
        !           376:    FSub.X              Y(a6),fp0               ...no exceptions
        !           377:    AddQ.L               #1,D3           ...Q := Q + 1
        !           378:
        !           379: *
        !           380:
        !           381: Fix_Sign:
        !           382: *..Get sign of X
        !           383:    Move.W               SignX(a6),D6
        !           384:    BGE.B               Get_Q
        !           385:    FNeg.X              fp0
        !           386:
        !           387: *..Get Q
        !           388: *
        !           389: Get_Q:
        !           390:    clr.l               d6
        !           391:    Move.W               SignQ(a6),D6        ...D6 is sign(Q)
        !           392:    Move.L               #8,D7
        !           393:    LSR.L                D7,D6
        !           394:    AndI.L               #$0000007F,D3   ...7 bits of Q
        !           395:    Or.L                 D6,D3           ...sign and bits of Q
        !           396:    Swap                 D3
        !           397:    FMove.L              fpsr,D6
        !           398:    AndI.L               #$FF00FFFF,D6
        !           399:    Or.L                 D3,D6
        !           400:    FMove.L              D6,fpsr         ...put Q in fpsr
        !           401:
        !           402: *
        !           403: Restore:
        !           404:    MoveM.L              (A7)+,D2-D7
        !           405:    FMove.L              USER_FPCR(a6),fpcr
        !           406:    Move.L               Sc_Flag(a6),D0
        !           407:    BEQ.B                Finish
        !           408:    FMul.X              Scale(pc),fp0   ...may cause underflow
        !           409:    bra                 t_avoid_unsupp  ;check for denorm as a
        !           410: *                                      ;result of the scaling
        !           411:
        !           412: Finish:
        !           413:        fmove.x         fp0,fp0         ;capture exceptions & round
        !           414:        rts
        !           415:
        !           416: Rem_is_0:
        !           417: *..R = 2^(-j)X - Q Y = Y, thus R = 0 and quotient = 2^j (Q+1)
        !           418:    AddQ.L               #1,D3
        !           419:    CmpI.L               #8,D0           ...D0 is j
        !           420:    BGE.B                Q_Big
        !           421:
        !           422:    LSL.L                D0,D3
        !           423:    BRA.B                Set_R_0
        !           424:
        !           425: Q_Big:
        !           426:    CLR.L                D3
        !           427:
        !           428: Set_R_0:
        !           429:    FMove.S             #:00000000,fp0
        !           430:    Clr.L               Sc_Flag(a6)
        !           431:    BRA.W                Fix_Sign
        !           432:
        !           433: Tie_Case:
        !           434: *..Check parity of Q
        !           435:    Move.L               D3,D6
        !           436:    AndI.L               #$00000001,D6
        !           437:    Tst.L                D6
        !           438:    BEq.W                Fix_Sign       ...Q is even
        !           439:
        !           440: *..Q is odd, Q := Q + 1, signX := -signX
        !           441:    AddQ.L               #1,D3
        !           442:    Move.W               SignX(a6),D6
        !           443:    EOrI.L               #$00008000,D6
        !           444:    Move.W               D6,SignX(a6)
        !           445:    BRA.W                Fix_Sign
        !           446:
        !           447:    End

CVSweb