Annotation of sys/arch/m68k/fpsp/util.sa, Revision 1.1.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