Annotation of sys/arch/m68k/fpsp/util.sa, Revision 1.1
1.1 ! nbrk 1: * $OpenBSD: util.sa,v 1.2 1996/05/29 21:05:45 niklas Exp $
! 2: * $NetBSD: util.sa,v 1.3 1994/10/26 07:50:20 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: * util.sa 3.7 7/29/91
! 36: *
! 37: * This file contains routines used by other programs.
! 38: *
! 39: * ovf_res: used by overflow to force the correct
! 40: * result. ovf_r_k, ovf_r_x2, ovf_r_x3 are
! 41: * derivatives of this routine.
! 42: * get_fline: get user's opcode word
! 43: * g_dfmtou: returns the destination format.
! 44: * g_opcls: returns the opclass of the float instruction.
! 45: * g_rndpr: returns the rounding precision.
! 46: * reg_dest: write byte, word, or long data to Dn
! 47: *
! 48:
! 49: UTIL IDNT 2,1 Motorola 040 Floating Point Software Package
! 50:
! 51: section 8
! 52:
! 53: include fpsp.h
! 54:
! 55: xref mem_read
! 56:
! 57: xdef g_dfmtou
! 58: xdef g_opcls
! 59: xdef g_rndpr
! 60: xdef get_fline
! 61: xdef reg_dest
! 62:
! 63: *
! 64: * Final result table for ovf_res. Note that the negative counterparts
! 65: * are unnecessary as ovf_res always returns the sign separately from
! 66: * the exponent.
! 67: * ;+inf
! 68: EXT_PINF dc.l $7fff0000,$00000000,$00000000,$00000000
! 69: * ;largest +ext
! 70: EXT_PLRG dc.l $7ffe0000,$ffffffff,$ffffffff,$00000000
! 71: * ;largest magnitude +sgl in ext
! 72: SGL_PLRG dc.l $407e0000,$ffffff00,$00000000,$00000000
! 73: * ;largest magnitude +dbl in ext
! 74: DBL_PLRG dc.l $43fe0000,$ffffffff,$fffff800,$00000000
! 75: * ;largest -ext
! 76:
! 77: tblovfl:
! 78: dc.l EXT_RN
! 79: dc.l EXT_RZ
! 80: dc.l EXT_RM
! 81: dc.l EXT_RP
! 82: dc.l SGL_RN
! 83: dc.l SGL_RZ
! 84: dc.l SGL_RM
! 85: dc.l SGL_RP
! 86: dc.l DBL_RN
! 87: dc.l DBL_RZ
! 88: dc.l DBL_RM
! 89: dc.l DBL_RP
! 90: dc.l error
! 91: dc.l error
! 92: dc.l error
! 93: dc.l error
! 94:
! 95:
! 96: *
! 97: * ovf_r_k --- overflow result calculation
! 98: *
! 99: * This entry point is used by kernel_ex.
! 100: *
! 101: * This forces the destination precision to be extended
! 102: *
! 103: * Input: operand in ETEMP
! 104: * Output: a result is in ETEMP (internal extended format)
! 105: *
! 106: xdef ovf_r_k
! 107: ovf_r_k:
! 108: lea ETEMP(a6),a0 ;a0 points to source operand
! 109: bclr.b #sign_bit,ETEMP_EX(a6)
! 110: sne ETEMP_SGN(a6) ;convert to internal IEEE format
! 111:
! 112: *
! 113: * ovf_r_x2 --- overflow result calculation
! 114: *
! 115: * This entry point used by x_ovfl. (opclass 0 and 2)
! 116: *
! 117: * Input a0 points to an operand in the internal extended format
! 118: * Output a0 points to the result in the internal extended format
! 119: *
! 120: * This sets the round precision according to the user's FPCR unless the
! 121: * instruction is fsgldiv or fsglmul or fsadd, fdadd, fsub, fdsub, fsmul,
! 122: * fdmul, fsdiv, fddiv, fssqrt, fsmove, fdmove, fsabs, fdabs, fsneg, fdneg.
! 123: * If the instruction is fsgldiv of fsglmul, the rounding precision must be
! 124: * extended. If the instruction is not fsgldiv or fsglmul but a force-
! 125: * precision instruction, the rounding precision is then set to the force
! 126: * precision.
! 127:
! 128: xdef ovf_r_x2
! 129: ovf_r_x2:
! 130: btst.b #E3,E_BYTE(a6) ;check for nu exception
! 131: beq.l ovf_e1_exc ;it is cu exception
! 132: ovf_e3_exc:
! 133: move.w CMDREG3B(a6),d0 ;get the command word
! 134: andi.w #$00000060,d0 ;clear all bits except 6 and 5
! 135: cmpi.l #$00000040,d0
! 136: beq.l ovff_sgl ;force precision is single
! 137: cmpi.l #$00000060,d0
! 138: beq.l ovff_dbl ;force precision is double
! 139: move.w CMDREG3B(a6),d0 ;get the command word again
! 140: andi.l #$7f,d0 ;clear all except operation
! 141: cmpi.l #$33,d0
! 142: beq.l ovf_fsgl ;fsglmul or fsgldiv
! 143: cmpi.l #$30,d0
! 144: beq.l ovf_fsgl
! 145: bra ovf_fpcr ;instruction is none of the above
! 146: * ;use FPCR
! 147: ovf_e1_exc:
! 148: move.w CMDREG1B(a6),d0 ;get command word
! 149: andi.l #$00000044,d0 ;clear all bits except 6 and 2
! 150: cmpi.l #$00000040,d0
! 151: beq.l ovff_sgl ;the instruction is force single
! 152: cmpi.l #$00000044,d0
! 153: beq.l ovff_dbl ;the instruction is force double
! 154: move.w CMDREG1B(a6),d0 ;again get the command word
! 155: andi.l #$0000007f,d0 ;clear all except the op code
! 156: cmpi.l #$00000027,d0
! 157: beq.l ovf_fsgl ;fsglmul
! 158: cmpi.l #$00000024,d0
! 159: beq.l ovf_fsgl ;fsgldiv
! 160: bra ovf_fpcr ;none of the above, use FPCR
! 161: *
! 162: *
! 163: * Inst is either fsgldiv or fsglmul. Force extended precision.
! 164: *
! 165: ovf_fsgl:
! 166: clr.l d0
! 167: bra.b ovf_res
! 168:
! 169: ovff_sgl:
! 170: move.l #$00000001,d0 ;set single
! 171: bra.b ovf_res
! 172: ovff_dbl:
! 173: move.l #$00000002,d0 ;set double
! 174: bra.b ovf_res
! 175: *
! 176: * The precision is in the fpcr.
! 177: *
! 178: ovf_fpcr:
! 179: bfextu FPCR_MODE(a6){0:2},d0 ;set round precision
! 180: bra.b ovf_res
! 181:
! 182: *
! 183: *
! 184: * ovf_r_x3 --- overflow result calculation
! 185: *
! 186: * This entry point used by x_ovfl. (opclass 3 only)
! 187: *
! 188: * Input a0 points to an operand in the internal extended format
! 189: * Output a0 points to the result in the internal extended format
! 190: *
! 191: * This sets the round precision according to the destination size.
! 192: *
! 193: xdef ovf_r_x3
! 194: ovf_r_x3:
! 195: bsr g_dfmtou ;get dest fmt in d0{1:0}
! 196: * ;for fmovout, the destination format
! 197: * ;is the rounding precision
! 198:
! 199: *
! 200: * ovf_res --- overflow result calculation
! 201: *
! 202: * Input:
! 203: * a0 points to operand in internal extended format
! 204: * Output:
! 205: * a0 points to result in internal extended format
! 206: *
! 207: xdef ovf_res
! 208: ovf_res:
! 209: lsl.l #2,d0 ;move round precision to d0{3:2}
! 210: bfextu FPCR_MODE(a6){2:2},d1 ;set round mode
! 211: or.l d1,d0 ;index is fmt:mode in d0{3:0}
! 212: lea.l tblovfl,a1 ;load a1 with table address
! 213: move.l (a1,d0*4),a1 ;use d0 as index to the table
! 214: jmp (a1) ;go to the correct routine
! 215: *
! 216: *case DEST_FMT = EXT
! 217: *
! 218: EXT_RN:
! 219: lea.l EXT_PINF,a1 ;answer is +/- infinity
! 220: bset.b #inf_bit,FPSR_CC(a6)
! 221: bra set_sign ;now go set the sign
! 222: EXT_RZ:
! 223: lea.l EXT_PLRG,a1 ;answer is +/- large number
! 224: bra set_sign ;now go set the sign
! 225: EXT_RM:
! 226: tst.b LOCAL_SGN(a0) ;if negative overflow
! 227: beq.b e_rm_pos
! 228: e_rm_neg:
! 229: lea.l EXT_PINF,a1 ;answer is negative infinity
! 230: or.l #neginf_mask,USER_FPSR(a6)
! 231: bra end_ovfr
! 232: e_rm_pos:
! 233: lea.l EXT_PLRG,a1 ;answer is large positive number
! 234: bra end_ovfr
! 235: EXT_RP:
! 236: tst.b LOCAL_SGN(a0) ;if negative overflow
! 237: beq.b e_rp_pos
! 238: e_rp_neg:
! 239: lea.l EXT_PLRG,a1 ;answer is large negative number
! 240: bset.b #neg_bit,FPSR_CC(a6)
! 241: bra end_ovfr
! 242: e_rp_pos:
! 243: lea.l EXT_PINF,a1 ;answer is positive infinity
! 244: bset.b #inf_bit,FPSR_CC(a6)
! 245: bra end_ovfr
! 246: *
! 247: *case DEST_FMT = DBL
! 248: *
! 249: DBL_RN:
! 250: lea.l EXT_PINF,a1 ;answer is +/- infinity
! 251: bset.b #inf_bit,FPSR_CC(a6)
! 252: bra set_sign
! 253: DBL_RZ:
! 254: lea.l DBL_PLRG,a1 ;answer is +/- large number
! 255: bra set_sign ;now go set the sign
! 256: DBL_RM:
! 257: tst.b LOCAL_SGN(a0) ;if negative overflow
! 258: beq.b d_rm_pos
! 259: d_rm_neg:
! 260: lea.l EXT_PINF,a1 ;answer is negative infinity
! 261: or.l #neginf_mask,USER_FPSR(a6)
! 262: bra end_ovfr ;inf is same for all precisions (ext,dbl,sgl)
! 263: d_rm_pos:
! 264: lea.l DBL_PLRG,a1 ;answer is large positive number
! 265: bra end_ovfr
! 266: DBL_RP:
! 267: tst.b LOCAL_SGN(a0) ;if negative overflow
! 268: beq.b d_rp_pos
! 269: d_rp_neg:
! 270: lea.l DBL_PLRG,a1 ;answer is large negative number
! 271: bset.b #neg_bit,FPSR_CC(a6)
! 272: bra end_ovfr
! 273: d_rp_pos:
! 274: lea.l EXT_PINF,a1 ;answer is positive infinity
! 275: bset.b #inf_bit,FPSR_CC(a6)
! 276: bra end_ovfr
! 277: *
! 278: *case DEST_FMT = SGL
! 279: *
! 280: SGL_RN:
! 281: lea.l EXT_PINF,a1 ;answer is +/- infinity
! 282: bset.b #inf_bit,FPSR_CC(a6)
! 283: bra.b set_sign
! 284: SGL_RZ:
! 285: lea.l SGL_PLRG,a1 ;anwer is +/- large number
! 286: bra.b set_sign
! 287: SGL_RM:
! 288: tst.b LOCAL_SGN(a0) ;if negative overflow
! 289: beq.b s_rm_pos
! 290: s_rm_neg:
! 291: lea.l EXT_PINF,a1 ;answer is negative infinity
! 292: or.l #neginf_mask,USER_FPSR(a6)
! 293: bra.b end_ovfr
! 294: s_rm_pos:
! 295: lea.l SGL_PLRG,a1 ;answer is large positive number
! 296: bra.b end_ovfr
! 297: SGL_RP:
! 298: tst.b LOCAL_SGN(a0) ;if negative overflow
! 299: beq.b s_rp_pos
! 300: s_rp_neg:
! 301: lea.l SGL_PLRG,a1 ;answer is large negative number
! 302: bset.b #neg_bit,FPSR_CC(a6)
! 303: bra.b end_ovfr
! 304: s_rp_pos:
! 305: lea.l EXT_PINF,a1 ;answer is postive infinity
! 306: bset.b #inf_bit,FPSR_CC(a6)
! 307: bra.b end_ovfr
! 308:
! 309: set_sign:
! 310: tst.b LOCAL_SGN(a0) ;if negative overflow
! 311: beq.b end_ovfr
! 312: neg_sign:
! 313: bset.b #neg_bit,FPSR_CC(a6)
! 314:
! 315: end_ovfr:
! 316: move.w LOCAL_EX(a1),LOCAL_EX(a0) ;do not overwrite sign
! 317: move.l LOCAL_HI(a1),LOCAL_HI(a0)
! 318: move.l LOCAL_LO(a1),LOCAL_LO(a0)
! 319: rts
! 320:
! 321:
! 322: *
! 323: * ERROR
! 324: *
! 325: error:
! 326: rts
! 327: *
! 328: * get_fline --- get f-line opcode of interrupted instruction
! 329: *
! 330: * Returns opcode in the low word of d0.
! 331: *
! 332: get_fline:
! 333: move.l USER_FPIAR(a6),a0 ;opcode address
! 334: clr.l -(a7) ;reserve a word on the stack
! 335: lea.l 2(a7),a1 ;point to low word of temporary
! 336: move.l #2,d0 ;count
! 337: bsr.l mem_read
! 338: move.l (a7)+,d0
! 339: rts
! 340: *
! 341: * g_rndpr --- put rounding precision in d0{1:0}
! 342: *
! 343: * valid return codes are:
! 344: * 00 - extended
! 345: * 01 - single
! 346: * 10 - double
! 347: *
! 348: * begin
! 349: * get rounding precision (cmdreg3b{6:5})
! 350: * begin
! 351: * case opclass = 011 (move out)
! 352: * get destination format - this is the also the rounding precision
! 353: *
! 354: * case opclass = 0x0
! 355: * if E3
! 356: * *case RndPr(from cmdreg3b{6:5} = 11 then RND_PREC = DBL
! 357: * *case RndPr(from cmdreg3b{6:5} = 10 then RND_PREC = SGL
! 358: * case RndPr(from cmdreg3b{6:5} = 00 | 01
! 359: * use precision from FPCR{7:6}
! 360: * case 00 then RND_PREC = EXT
! 361: * case 01 then RND_PREC = SGL
! 362: * case 10 then RND_PREC = DBL
! 363: * else E1
! 364: * use precision in FPCR{7:6}
! 365: * case 00 then RND_PREC = EXT
! 366: * case 01 then RND_PREC = SGL
! 367: * case 10 then RND_PREC = DBL
! 368: * end
! 369: *
! 370: g_rndpr:
! 371: bsr.w g_opcls ;get opclass in d0{2:0}
! 372: cmp.w #$0003,d0 ;check for opclass 011
! 373: bne.b op_0x0
! 374:
! 375: *
! 376: * For move out instructions (opclass 011) the destination format
! 377: * is the same as the rounding precision. Pass results from g_dfmtou.
! 378: *
! 379: bsr.w g_dfmtou
! 380: rts
! 381: op_0x0:
! 382: btst.b #E3,E_BYTE(a6)
! 383: beq.l unf_e1_exc ;branch to e1 underflow
! 384: unf_e3_exc:
! 385: move.l CMDREG3B(a6),d0 ;rounding precision in d0{10:9}
! 386: bfextu d0{9:2},d0 ;move the rounding prec bits to d0{1:0}
! 387: cmpi.l #$2,d0
! 388: beq.l unff_sgl ;force precision is single
! 389: cmpi.l #$3,d0 ;force precision is double
! 390: beq.l unff_dbl
! 391: move.w CMDREG3B(a6),d0 ;get the command word again
! 392: andi.l #$7f,d0 ;clear all except operation
! 393: cmpi.l #$33,d0
! 394: beq.l unf_fsgl ;fsglmul or fsgldiv
! 395: cmpi.l #$30,d0
! 396: beq.l unf_fsgl ;fsgldiv or fsglmul
! 397: bra unf_fpcr
! 398: unf_e1_exc:
! 399: move.l CMDREG1B(a6),d0 ;get 32 bits off the stack, 1st 16 bits
! 400: * ;are the command word
! 401: andi.l #$00440000,d0 ;clear all bits except bits 6 and 2
! 402: cmpi.l #$00400000,d0
! 403: beq.l unff_sgl ;force single
! 404: cmpi.l #$00440000,d0 ;force double
! 405: beq.l unff_dbl
! 406: move.l CMDREG1B(a6),d0 ;get the command word again
! 407: andi.l #$007f0000,d0 ;clear all bits except the operation
! 408: cmpi.l #$00270000,d0
! 409: beq.l unf_fsgl ;fsglmul
! 410: cmpi.l #$00240000,d0
! 411: beq.l unf_fsgl ;fsgldiv
! 412: bra unf_fpcr
! 413:
! 414: *
! 415: * Convert to return format. The values from cmdreg3b and the return
! 416: * values are:
! 417: * cmdreg3b return precision
! 418: * -------- ------ ---------
! 419: * 00,01 0 ext
! 420: * 10 1 sgl
! 421: * 11 2 dbl
! 422: * Force single
! 423: *
! 424: unff_sgl:
! 425: move.l #1,d0 ;return 1
! 426: rts
! 427: *
! 428: * Force double
! 429: *
! 430: unff_dbl:
! 431: move.l #2,d0 ;return 2
! 432: rts
! 433: *
! 434: * Force extended
! 435: *
! 436: unf_fsgl:
! 437: clr.l d0
! 438: rts
! 439: *
! 440: * Get rounding precision set in FPCR{7:6}.
! 441: *
! 442: unf_fpcr:
! 443: move.l USER_FPCR(a6),d0 ;rounding precision bits in d0{7:6}
! 444: bfextu d0{24:2},d0 ;move the rounding prec bits to d0{1:0}
! 445: rts
! 446: *
! 447: * g_opcls --- put opclass in d0{2:0}
! 448: *
! 449: g_opcls:
! 450: btst.b #E3,E_BYTE(a6)
! 451: beq.b opc_1b ;if set, go to cmdreg1b
! 452: opc_3b:
! 453: clr.l d0 ;if E3, only opclass 0x0 is possible
! 454: rts
! 455: opc_1b:
! 456: move.l CMDREG1B(a6),d0
! 457: bfextu d0{0:3},d0 ;shift opclass bits d0{31:29} to d0{2:0}
! 458: rts
! 459: *
! 460: * g_dfmtou --- put destination format in d0{1:0}
! 461: *
! 462: * If E1, the format is from cmdreg1b{12:10}
! 463: * If E3, the format is extended.
! 464: *
! 465: * Dest. Fmt.
! 466: * extended 010 -> 00
! 467: * single 001 -> 01
! 468: * double 101 -> 10
! 469: *
! 470: g_dfmtou:
! 471: btst.b #E3,E_BYTE(a6)
! 472: beq.b op011
! 473: clr.l d0 ;if E1, size is always ext
! 474: rts
! 475: op011:
! 476: move.l CMDREG1B(a6),d0
! 477: bfextu d0{3:3},d0 ;dest fmt from cmdreg1b{12:10}
! 478: cmp.b #1,d0 ;check for single
! 479: bne.b not_sgl
! 480: move.l #1,d0
! 481: rts
! 482: not_sgl:
! 483: cmp.b #5,d0 ;check for double
! 484: bne.b not_dbl
! 485: move.l #2,d0
! 486: rts
! 487: not_dbl:
! 488: clr.l d0 ;must be extended
! 489: rts
! 490:
! 491: *
! 492: *
! 493: * Final result table for unf_sub. Note that the negative counterparts
! 494: * are unnecessary as unf_sub always returns the sign separately from
! 495: * the exponent.
! 496: * ;+zero
! 497: EXT_PZRO dc.l $00000000,$00000000,$00000000,$00000000
! 498: * ;+zero
! 499: SGL_PZRO dc.l $3f810000,$00000000,$00000000,$00000000
! 500: * ;+zero
! 501: DBL_PZRO dc.l $3c010000,$00000000,$00000000,$00000000
! 502: * ;smallest +ext denorm
! 503: EXT_PSML dc.l $00000000,$00000000,$00000001,$00000000
! 504: * ;smallest +sgl denorm
! 505: SGL_PSML dc.l $3f810000,$00000100,$00000000,$00000000
! 506: * ;smallest +dbl denorm
! 507: DBL_PSML dc.l $3c010000,$00000000,$00000800,$00000000
! 508: *
! 509: * UNF_SUB --- underflow result calculation
! 510: *
! 511: * Input:
! 512: * d0 contains round precision
! 513: * a0 points to input operand in the internal extended format
! 514: *
! 515: * Output:
! 516: * a0 points to correct internal extended precision result.
! 517: *
! 518:
! 519: tblunf:
! 520: dc.l uEXT_RN
! 521: dc.l uEXT_RZ
! 522: dc.l uEXT_RM
! 523: dc.l uEXT_RP
! 524: dc.l uSGL_RN
! 525: dc.l uSGL_RZ
! 526: dc.l uSGL_RM
! 527: dc.l uSGL_RP
! 528: dc.l uDBL_RN
! 529: dc.l uDBL_RZ
! 530: dc.l uDBL_RM
! 531: dc.l uDBL_RP
! 532: dc.l uDBL_RN
! 533: dc.l uDBL_RZ
! 534: dc.l uDBL_RM
! 535: dc.l uDBL_RP
! 536:
! 537: xdef unf_sub
! 538: unf_sub:
! 539: lsl.l #2,d0 ;move round precision to d0{3:2}
! 540: bfextu FPCR_MODE(a6){2:2},d1 ;set round mode
! 541: or.l d1,d0 ;index is fmt:mode in d0{3:0}
! 542: lea.l tblunf,a1 ;load a1 with table address
! 543: move.l (a1,d0*4),a1 ;use d0 as index to the table
! 544: jmp (a1) ;go to the correct routine
! 545: *
! 546: *case DEST_FMT = EXT
! 547: *
! 548: uEXT_RN:
! 549: lea.l EXT_PZRO,a1 ;answer is +/- zero
! 550: bset.b #z_bit,FPSR_CC(a6)
! 551: bra uset_sign ;now go set the sign
! 552: uEXT_RZ:
! 553: lea.l EXT_PZRO,a1 ;answer is +/- zero
! 554: bset.b #z_bit,FPSR_CC(a6)
! 555: bra uset_sign ;now go set the sign
! 556: uEXT_RM:
! 557: tst.b LOCAL_SGN(a0) ;if negative underflow
! 558: beq.b ue_rm_pos
! 559: ue_rm_neg:
! 560: lea.l EXT_PSML,a1 ;answer is negative smallest denorm
! 561: bset.b #neg_bit,FPSR_CC(a6)
! 562: bra end_unfr
! 563: ue_rm_pos:
! 564: lea.l EXT_PZRO,a1 ;answer is positive zero
! 565: bset.b #z_bit,FPSR_CC(a6)
! 566: bra end_unfr
! 567: uEXT_RP:
! 568: tst.b LOCAL_SGN(a0) ;if negative underflow
! 569: beq.b ue_rp_pos
! 570: ue_rp_neg:
! 571: lea.l EXT_PZRO,a1 ;answer is negative zero
! 572: ori.l #negz_mask,USER_FPSR(a6)
! 573: bra end_unfr
! 574: ue_rp_pos:
! 575: lea.l EXT_PSML,a1 ;answer is positive smallest denorm
! 576: bra end_unfr
! 577: *
! 578: *case DEST_FMT = DBL
! 579: *
! 580: uDBL_RN:
! 581: lea.l DBL_PZRO,a1 ;answer is +/- zero
! 582: bset.b #z_bit,FPSR_CC(a6)
! 583: bra uset_sign
! 584: uDBL_RZ:
! 585: lea.l DBL_PZRO,a1 ;answer is +/- zero
! 586: bset.b #z_bit,FPSR_CC(a6)
! 587: bra uset_sign ;now go set the sign
! 588: uDBL_RM:
! 589: tst.b LOCAL_SGN(a0) ;if negative overflow
! 590: beq.b ud_rm_pos
! 591: ud_rm_neg:
! 592: lea.l DBL_PSML,a1 ;answer is smallest denormalized negative
! 593: bset.b #neg_bit,FPSR_CC(a6)
! 594: bra end_unfr
! 595: ud_rm_pos:
! 596: lea.l DBL_PZRO,a1 ;answer is positive zero
! 597: bset.b #z_bit,FPSR_CC(a6)
! 598: bra end_unfr
! 599: uDBL_RP:
! 600: tst.b LOCAL_SGN(a0) ;if negative overflow
! 601: beq.b ud_rp_pos
! 602: ud_rp_neg:
! 603: lea.l DBL_PZRO,a1 ;answer is negative zero
! 604: ori.l #negz_mask,USER_FPSR(a6)
! 605: bra end_unfr
! 606: ud_rp_pos:
! 607: lea.l DBL_PSML,a1 ;answer is smallest denormalized negative
! 608: bra end_unfr
! 609: *
! 610: *case DEST_FMT = SGL
! 611: *
! 612: uSGL_RN:
! 613: lea.l SGL_PZRO,a1 ;answer is +/- zero
! 614: bset.b #z_bit,FPSR_CC(a6)
! 615: bra.b uset_sign
! 616: uSGL_RZ:
! 617: lea.l SGL_PZRO,a1 ;answer is +/- zero
! 618: bset.b #z_bit,FPSR_CC(a6)
! 619: bra.b uset_sign
! 620: uSGL_RM:
! 621: tst.b LOCAL_SGN(a0) ;if negative overflow
! 622: beq.b us_rm_pos
! 623: us_rm_neg:
! 624: lea.l SGL_PSML,a1 ;answer is smallest denormalized negative
! 625: bset.b #neg_bit,FPSR_CC(a6)
! 626: bra.b end_unfr
! 627: us_rm_pos:
! 628: lea.l SGL_PZRO,a1 ;answer is positive zero
! 629: bset.b #z_bit,FPSR_CC(a6)
! 630: bra.b end_unfr
! 631: uSGL_RP:
! 632: tst.b LOCAL_SGN(a0) ;if negative overflow
! 633: beq.b us_rp_pos
! 634: us_rp_neg:
! 635: lea.l SGL_PZRO,a1 ;answer is negative zero
! 636: ori.l #negz_mask,USER_FPSR(a6)
! 637: bra.b end_unfr
! 638: us_rp_pos:
! 639: lea.l SGL_PSML,a1 ;answer is smallest denormalized positive
! 640: bra.b end_unfr
! 641:
! 642: uset_sign:
! 643: tst.b LOCAL_SGN(a0) ;if negative overflow
! 644: beq.b end_unfr
! 645: uneg_sign:
! 646: bset.b #neg_bit,FPSR_CC(a6)
! 647:
! 648: end_unfr:
! 649: move.w LOCAL_EX(a1),LOCAL_EX(a0) ;be careful not to overwrite sign
! 650: move.l LOCAL_HI(a1),LOCAL_HI(a0)
! 651: move.l LOCAL_LO(a1),LOCAL_LO(a0)
! 652: rts
! 653: *
! 654: * reg_dest --- write byte, word, or long data to Dn
! 655: *
! 656: *
! 657: * Input:
! 658: * L_SCR1: Data
! 659: * d1: data size and dest register number formatted as:
! 660: *
! 661: * 32 5 4 3 2 1 0
! 662: * -----------------------------------------------
! 663: * | 0 | Size | Dest Reg # |
! 664: * -----------------------------------------------
! 665: *
! 666: * Size is:
! 667: * 0 - Byte
! 668: * 1 - Word
! 669: * 2 - Long/Single
! 670: *
! 671: pregdst:
! 672: dc.l byte_d0
! 673: dc.l byte_d1
! 674: dc.l byte_d2
! 675: dc.l byte_d3
! 676: dc.l byte_d4
! 677: dc.l byte_d5
! 678: dc.l byte_d6
! 679: dc.l byte_d7
! 680: dc.l word_d0
! 681: dc.l word_d1
! 682: dc.l word_d2
! 683: dc.l word_d3
! 684: dc.l word_d4
! 685: dc.l word_d5
! 686: dc.l word_d6
! 687: dc.l word_d7
! 688: dc.l long_d0
! 689: dc.l long_d1
! 690: dc.l long_d2
! 691: dc.l long_d3
! 692: dc.l long_d4
! 693: dc.l long_d5
! 694: dc.l long_d6
! 695: dc.l long_d7
! 696:
! 697: reg_dest:
! 698: lea.l pregdst,a0
! 699: move.l (a0,d1*4),a0
! 700: jmp (a0)
! 701:
! 702: byte_d0:
! 703: move.b L_SCR1(a6),USER_D0+3(a6)
! 704: rts
! 705: byte_d1:
! 706: move.b L_SCR1(a6),USER_D1+3(a6)
! 707: rts
! 708: byte_d2:
! 709: move.b L_SCR1(a6),d2
! 710: rts
! 711: byte_d3:
! 712: move.b L_SCR1(a6),d3
! 713: rts
! 714: byte_d4:
! 715: move.b L_SCR1(a6),d4
! 716: rts
! 717: byte_d5:
! 718: move.b L_SCR1(a6),d5
! 719: rts
! 720: byte_d6:
! 721: move.b L_SCR1(a6),d6
! 722: rts
! 723: byte_d7:
! 724: move.b L_SCR1(a6),d7
! 725: rts
! 726: word_d0:
! 727: move.w L_SCR1(a6),USER_D0+2(a6)
! 728: rts
! 729: word_d1:
! 730: move.w L_SCR1(a6),USER_D1+2(a6)
! 731: rts
! 732: word_d2:
! 733: move.w L_SCR1(a6),d2
! 734: rts
! 735: word_d3:
! 736: move.w L_SCR1(a6),d3
! 737: rts
! 738: word_d4:
! 739: move.w L_SCR1(a6),d4
! 740: rts
! 741: word_d5:
! 742: move.w L_SCR1(a6),d5
! 743: rts
! 744: word_d6:
! 745: move.w L_SCR1(a6),d6
! 746: rts
! 747: word_d7:
! 748: move.w L_SCR1(a6),d7
! 749: rts
! 750: long_d0:
! 751: move.l L_SCR1(a6),USER_D0(a6)
! 752: rts
! 753: long_d1:
! 754: move.l L_SCR1(a6),USER_D1(a6)
! 755: rts
! 756: long_d2:
! 757: move.l L_SCR1(a6),d2
! 758: rts
! 759: long_d3:
! 760: move.l L_SCR1(a6),d3
! 761: rts
! 762: long_d4:
! 763: move.l L_SCR1(a6),d4
! 764: rts
! 765: long_d5:
! 766: move.l L_SCR1(a6),d5
! 767: rts
! 768: long_d6:
! 769: move.l L_SCR1(a6),d6
! 770: rts
! 771: long_d7:
! 772: move.l L_SCR1(a6),d7
! 773: rts
! 774: end
CVSweb