1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
|
* $OpenBSD: x_unfl.sa,v 1.3 2001/09/20 17:02:30 mpech Exp $
* $NetBSD: x_unfl.sa,v 1.3 1994/10/26 07:50:30 cgd Exp $
* MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
* M68000 Hi-Performance Microprocessor Division
* M68040 Software Package
*
* M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
* All rights reserved.
*
* THE SOFTWARE is provided on an "AS IS" basis and without warranty.
* To the maximum extent permitted by applicable law,
* MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
* INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
* PARTICULAR PURPOSE and any warranty against infringement with
* regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
* and any accompanying written materials.
*
* To the maximum extent permitted by applicable law,
* IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
* (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
* PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
* OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
* SOFTWARE. Motorola assumes no responsibility for the maintenance
* and support of the SOFTWARE.
*
* You are hereby granted a copyright license to use, modify, and
* distribute the SOFTWARE so long as this entire notice is retained
* without alteration in any modified and/or redistributed versions,
* and that such modified versions are clearly identified as such.
* No licenses are granted by implication, estoppel or otherwise
* under any patents or trademarks of Motorola, Inc.
*
* x_unfl.sa 3.4 7/1/91
*
* fpsp_unfl --- FPSP handler for underflow exception
*
* Trap disabled results
* For 881/2 compatibility, sw must denormalize the intermediate
* result, then store the result. Denormalization is accomplished
* by taking the intermediate result (which is always normalized) and
* shifting the mantissa right while incrementing the exponent until
* it is equal to the denormalized exponent for the destination
* format. After denormalizatoin, the result is rounded to the
* destination format.
*
* Trap enabled results
* All trap disabled code applies. In addition the exceptional
* operand needs to made available to the user with a bias of $6000
* added to the exponent.
*
X_UNFL IDNT 2,1 Motorola 040 Floating Point Software Package
section 8
include fpsp.h
xref denorm
xref round
xref store
xref g_rndpr
xref g_opcls
xref g_dfmtou
xref real_unfl
xref real_inex
xref fpsp_done
xref b1238_fix
xdef fpsp_unfl
fpsp_unfl:
link a6,#-LOCAL_SIZE
fsave -(a7)
movem.l d0-d1/a0-a1,USER_DA(a6)
fmovem.x fp0-fp3,USER_FP0(a6)
fmovem.l fpcr/fpsr/fpiar,USER_FPCR(a6)
*
bsr.l unf_res ;denormalize, round & store interm op
*
* If underflow exceptions are not enabled, check for inexact
* exception
*
btst.b #unfl_bit,FPCR_ENABLE(a6)
beq.b ck_inex
btst.b #E3,E_BYTE(a6)
beq.b no_e3_1
*
* Clear dirty bit on dest resister in the frame before branching
* to b1238_fix.
*
bfextu CMDREG3B(a6){6:3},d0 ;get dest reg no
bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit
bsr.l b1238_fix ;test for bug1238 case
move.l USER_FPSR(a6),FPSR_SHADOW(a6)
or.l #sx_mask,E_BYTE(a6)
no_e3_1:
movem.l USER_DA(a6),d0-d1/a0-a1
fmovem.x USER_FP0(a6),fp0-fp3
fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
frestore (a7)+
unlk a6
bra.l real_unfl
*
* It is possible to have either inex2 or inex1 exceptions with the
* unfl. If the inex enable bit is set in the FPCR, and either
* inex2 or inex1 occurred, we must clean up and branch to the
* real inex handler.
*
ck_inex:
move.b FPCR_ENABLE(a6),d0
and.b FPSR_EXCEPT(a6),d0
andi.b #$3,d0
beq.b unfl_done
*
* Inexact enabled and reported, and we must take an inexact exception
*
take_inex:
btst.b #E3,E_BYTE(a6)
beq.b no_e3_2
*
* Clear dirty bit on dest resister in the frame before branching
* to b1238_fix.
*
bfextu CMDREG3B(a6){6:3},d0 ;get dest reg no
bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit
bsr.l b1238_fix ;test for bug1238 case
move.l USER_FPSR(a6),FPSR_SHADOW(a6)
or.l #sx_mask,E_BYTE(a6)
no_e3_2:
move.b #INEX_VEC,EXC_VEC+1(a6)
movem.l USER_DA(a6),d0-d1/a0-a1
fmovem.x USER_FP0(a6),fp0-fp3
fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
frestore (a7)+
unlk a6
bra.l real_inex
unfl_done:
bclr.b #E3,E_BYTE(a6)
beq.b e1_set ;if set then branch
*
* Clear dirty bit on dest resister in the frame before branching
* to b1238_fix.
*
bfextu CMDREG3B(a6){6:3},d0 ;get dest reg no
bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit
bsr.l b1238_fix ;test for bug1238 case
move.l USER_FPSR(a6),FPSR_SHADOW(a6)
or.l #sx_mask,E_BYTE(a6)
movem.l USER_DA(a6),d0-d1/a0-a1
fmovem.x USER_FP0(a6),fp0-fp3
fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
frestore (a7)+
unlk a6
bra.l fpsp_done
e1_set:
movem.l USER_DA(a6),d0-d1/a0-a1
fmovem.x USER_FP0(a6),fp0-fp3
fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
unlk a6
bra.l fpsp_done
*
* unf_res --- underflow result calculation
*
unf_res:
bsr.l g_rndpr ;returns RND_PREC in d0 0=ext,
* ;1=sgl, 2=dbl
* ;we need the RND_PREC in the
* ;upper word for round
clr.w -(a7)
move.w d0,-(a7) ;copy RND_PREC to stack
*
*
* If the exception bit set is E3, the exceptional operand from the
* fpu is in WBTEMP; else it is in FPTEMP.
*
btst.b #E3,E_BYTE(a6)
beq.b unf_E1
unf_E3:
lea WBTEMP(a6),a0 ;a0 now points to operand
*
* Test for fsgldiv and fsglmul. If the inst was one of these, then
* force the precision to extended for the denorm routine. Use
* the user's precision for the round routine.
*
move.w CMDREG3B(a6),d1 ;check for fsgldiv or fsglmul
andi.w #$7f,d1
cmpi.w #$30,d1 ;check for sgldiv
beq.b unf_sgl
cmpi.w #$33,d1 ;check for sglmul
bne.b unf_cont ;if not, use fpcr prec in round
unf_sgl:
clr.l d0
move.w #$1,(a7) ;override g_rndpr precision
* ;force single
bra.b unf_cont
unf_E1:
lea FPTEMP(a6),a0 ;a0 now points to operand
unf_cont:
bclr.b #sign_bit,LOCAL_EX(a0) ;clear sign bit
sne LOCAL_SGN(a0) ;store sign
bsr.l denorm ;returns denorm, a0 points to it
*
* WARNING:
* ;d0 has guard,round sticky bit
* ;make sure that it is not corrupted
* ;before it reaches the round subroutine
* ;also ensure that a0 isn't corrupted
*
* Set up d1 for round subroutine d1 contains the PREC/MODE
* information respectively on upper/lower register halves.
*
bfextu FPCR_MODE(a6){2:2},d1 ;get mode from FPCR
* ;mode in lower d1
add.l (a7)+,d1 ;merge PREC/MODE
*
* WARNING: a0 and d0 are assumed to be intact between the denorm and
* round subroutines. All code between these two subroutines
* must not corrupt a0 and d0.
*
*
* Perform Round
* Input: a0 points to input operand
* d0{31:29} has guard, round, sticky
* d1{01:00} has rounding mode
* d1{17:16} has rounding precision
* Output: a0 points to rounded operand
*
bsr.l round ;returns rounded denorm at (a0)
*
* Differentiate between store to memory vs. store to register
*
unf_store:
bsr.l g_opcls ;returns opclass in d0{2:0}
cmpi.b #$3,d0
bne.b not_opc011
*
* At this point, a store to memory is pending
*
opc011:
bsr.l g_dfmtou
tst.b d0
beq.b ext_opc011 ;If extended, do not subtract
* ;If destination format is sgl/dbl,
tst.b LOCAL_HI(a0) ;If rounded result is normal,don't
* ;subtract
bmi.b ext_opc011
subq.w #1,LOCAL_EX(a0) ;account for denorm bias vs.
* ;normalized bias
* ; normalized denormalized
* ;single $7f $7e
* ;double $3ff $3fe
*
ext_opc011:
bsr.l store ;stores to memory
bra.b unf_done ;finish up
*
* At this point, a store to a float register is pending
*
not_opc011:
bsr.l store ;stores to float register
* ;a0 is not corrupted on a store to a
* ;float register.
*
* Set the condition codes according to result
*
tst.l LOCAL_HI(a0) ;check upper mantissa
bne.b ck_sgn
tst.l LOCAL_LO(a0) ;check lower mantissa
bne.b ck_sgn
bset.b #z_bit,FPSR_CC(a6) ;set condition codes if zero
ck_sgn:
btst.b #sign_bit,LOCAL_EX(a0) ;check the sign bit
beq.b unf_done
bset.b #neg_bit,FPSR_CC(a6)
*
* Finish.
*
unf_done:
btst.b #inex2_bit,FPSR_EXCEPT(a6)
beq.b no_aunfl
bset.b #aunfl_bit,FPSR_AEXCEPT(a6)
no_aunfl:
rts
end
|