OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [m68k/] [fpsp040/] [gen_except.S] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
|
2
|       gen_except.sa 3.7 1/16/92
3
|
4
|       gen_except --- FPSP routine to detect reportable exceptions
5
|
6
|       This routine compares the exception enable byte of the
7
|       user_fpcr on the stack with the exception status byte
8
|       of the user_fpsr.
9
|
10
|       Any routine which may report an exceptions must load
11
|       the stack frame in memory with the exceptional operand(s).
12
|
13
|       Priority for exceptions is:
14
|
15
|       Highest:        bsun
16
|                       snan
17
|                       operr
18
|                       ovfl
19
|                       unfl
20
|                       dz
21
|                       inex2
22
|       Lowest:         inex1
23
|
24
|       Note: The IEEE standard specifies that inex2 is to be
25
|       reported if ovfl occurs and the ovfl enable bit is not
26
|       set but the inex2 enable bit is.
27
|
28
|
29
|               Copyright (C) Motorola, Inc. 1990
30
|                       All Rights Reserved
31
|
32
|       THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
33
|       The copyright notice above does not evidence any
34
|       actual or intended publication of such source code.
35
 
36
GEN_EXCEPT:    |idnt    2,1 | Motorola 040 Floating Point Software Package
37
 
38
        |section 8
39
 
40
        .include "fpsp.h"
41
 
42
        |xref   real_trace
43
        |xref   fpsp_done
44
        |xref   fpsp_fmt_error
45
 
46
exc_tbl:
47
        .long   bsun_exc
48
        .long   commonE1
49
        .long   commonE1
50
        .long   ovfl_unfl
51
        .long   ovfl_unfl
52
        .long   commonE1
53
        .long   commonE3
54
        .long   commonE3
55
        .long   no_match
56
 
57
        .global gen_except
58
gen_except:
59
        cmpib   #IDLE_SIZE-4,1(%a7)     |test for idle frame
60
        beq     do_check                |go handle idle frame
61
        cmpib   #UNIMP_40_SIZE-4,1(%a7) |test for orig unimp frame
62
        beqs    unimp_x                 |go handle unimp frame
63
        cmpib   #UNIMP_41_SIZE-4,1(%a7) |test for rev unimp frame
64
        beqs    unimp_x                 |go handle unimp frame
65
        cmpib   #BUSY_SIZE-4,1(%a7)     |if size <> $60, fmt error
66
        bnel    fpsp_fmt_error
67
        leal    BUSY_SIZE+LOCAL_SIZE(%a7),%a1 |init a1 so fpsp.h
68
|                                       ;equates will work
69
| Fix up the new busy frame with entries from the unimp frame
70
|
71
        movel   ETEMP_EX(%a6),ETEMP_EX(%a1) |copy etemp from unimp
72
        movel   ETEMP_HI(%a6),ETEMP_HI(%a1) |frame to busy frame
73
        movel   ETEMP_LO(%a6),ETEMP_LO(%a1)
74
        movel   CMDREG1B(%a6),CMDREG1B(%a1) |set inst in frame to unimp
75
        movel   CMDREG1B(%a6),%d0               |fix cmd1b to make it
76
        andl    #0x03c30000,%d0         |work for cmd3b
77
        bfextu  CMDREG1B(%a6){#13:#1},%d1       |extract bit 2
78
        lsll    #5,%d1
79
        swap    %d1
80
        orl     %d1,%d0                 |put it in the right place
81
        bfextu  CMDREG1B(%a6){#10:#3},%d1       |extract bit 3,4,5
82
        lsll    #2,%d1
83
        swap    %d1
84
        orl     %d1,%d0                 |put them in the right place
85
        movel   %d0,CMDREG3B(%a1)               |in the busy frame
86
|
87
| Or in the FPSR from the emulation with the USER_FPSR on the stack.
88
|
89
        fmovel  %FPSR,%d0
90
        orl     %d0,USER_FPSR(%a6)
91
        movel   USER_FPSR(%a6),FPSR_SHADOW(%a1) |set exc bits
92
        orl     #sx_mask,E_BYTE(%a1)
93
        bra     do_clean
94
 
95
|
96
| Frame is an unimp frame possible resulting from an fmove ,fp0
97
| that caused an exception
98
|
99
| a1 is modified to point into the new frame allowing fpsp equates
100
| to be valid.
101
|
102
unimp_x:
103
        cmpib   #UNIMP_40_SIZE-4,1(%a7) |test for orig unimp frame
104
        bnes    test_rev
105
        leal    UNIMP_40_SIZE+LOCAL_SIZE(%a7),%a1
106
        bras    unimp_con
107
test_rev:
108
        cmpib   #UNIMP_41_SIZE-4,1(%a7) |test for rev unimp frame
109
        bnel    fpsp_fmt_error          |if not $28 or $30
110
        leal    UNIMP_41_SIZE+LOCAL_SIZE(%a7),%a1
111
 
112
unimp_con:
113
|
114
| Fix up the new unimp frame with entries from the old unimp frame
115
|
116
        movel   CMDREG1B(%a6),CMDREG1B(%a1) |set inst in frame to unimp
117
|
118
| Or in the FPSR from the emulation with the USER_FPSR on the stack.
119
|
120
        fmovel  %FPSR,%d0
121
        orl     %d0,USER_FPSR(%a6)
122
        bra     do_clean
123
 
124
|
125
| Frame is idle, so check for exceptions reported through
126
| USER_FPSR and set the unimp frame accordingly.
127
| A7 must be incremented to the point before the
128
| idle fsave vector to the unimp vector.
129
|
130
 
131
do_check:
132
        addl    #4,%a7                  |point A7 back to unimp frame
133
|
134
| Or in the FPSR from the emulation with the USER_FPSR on the stack.
135
|
136
        fmovel  %FPSR,%d0
137
        orl     %d0,USER_FPSR(%a6)
138
|
139
| On a busy frame, we must clear the nmnexc bits.
140
|
141
        cmpib   #BUSY_SIZE-4,1(%a7)     |check frame type
142
        bnes    check_fr                |if busy, clr nmnexc
143
        clrw    NMNEXC(%a6)             |clr nmnexc & nmcexc
144
        btstb   #5,CMDREG1B(%a6)                |test for fmove out
145
        bnes    frame_com
146
        movel   USER_FPSR(%a6),FPSR_SHADOW(%a6) |set exc bits
147
        orl     #sx_mask,E_BYTE(%a6)
148
        bras    frame_com
149
check_fr:
150
        cmpb    #UNIMP_40_SIZE-4,1(%a7)
151
        beqs    frame_com
152
        clrw    NMNEXC(%a6)
153
frame_com:
154
        moveb   FPCR_ENABLE(%a6),%d0    |get fpcr enable byte
155
        andb    FPSR_EXCEPT(%a6),%d0    |and in the fpsr exc byte
156
        bfffo   %d0{#24:#8},%d1         |test for first set bit
157
        leal    exc_tbl,%a0             |load jmp table address
158
        subib   #24,%d1                 |normalize bit offset to 0-8
159
        movel   (%a0,%d1.w*4),%a0               |load routine address based
160
|                                       ;based on first enabled exc
161
        jmp     (%a0)                   |jump to routine
162
|
163
| Bsun is not possible in unimp or unsupp
164
|
165
bsun_exc:
166
        bra     do_clean
167
|
168
| The typical work to be done to the unimp frame to report an
169
| exception is to set the E1/E3 byte and clr the U flag.
170
| commonE1 does this for E1 exceptions, which are snan,
171
| operr, and dz.  commonE3 does this for E3 exceptions, which
172
| are inex2 and inex1, and also clears the E1 exception bit
173
| left over from the unimp exception.
174
|
175
commonE1:
176
        bsetb   #E1,E_BYTE(%a6)         |set E1 flag
177
        bra     commonE                 |go clean and exit
178
 
179
commonE3:
180
        tstb    UFLG_TMP(%a6)           |test flag for unsup/unimp state
181
        bnes    unsE3
182
uniE3:
183
        bsetb   #E3,E_BYTE(%a6)         |set E3 flag
184
        bclrb   #E1,E_BYTE(%a6)         |clr E1 from unimp
185
        bra     commonE
186
 
187
unsE3:
188
        tstb    RES_FLG(%a6)
189
        bnes    unsE3_0
190
unsE3_1:
191
        bsetb   #E3,E_BYTE(%a6)         |set E3 flag
192
unsE3_0:
193
        bclrb   #E1,E_BYTE(%a6)         |clr E1 flag
194
        movel   CMDREG1B(%a6),%d0
195
        andl    #0x03c30000,%d0         |work for cmd3b
196
        bfextu  CMDREG1B(%a6){#13:#1},%d1       |extract bit 2
197
        lsll    #5,%d1
198
        swap    %d1
199
        orl     %d1,%d0                 |put it in the right place
200
        bfextu  CMDREG1B(%a6){#10:#3},%d1       |extract bit 3,4,5
201
        lsll    #2,%d1
202
        swap    %d1
203
        orl     %d1,%d0                 |put them in the right place
204
        movel   %d0,CMDREG3B(%a6)               |in the busy frame
205
 
206
commonE:
207
        bclrb   #UFLAG,T_BYTE(%a6)      |clr U flag from unimp
208
        bra     do_clean                |go clean and exit
209
|
210
| No bits in the enable byte match existing exceptions.  Check for
211
| the case of the ovfl exc without the ovfl enabled, but with
212
| inex2 enabled.
213
|
214
no_match:
215
        btstb   #inex2_bit,FPCR_ENABLE(%a6) |check for ovfl/inex2 case
216
        beqs    no_exc                  |if clear, exit
217
        btstb   #ovfl_bit,FPSR_EXCEPT(%a6) |now check ovfl
218
        beqs    no_exc                  |if clear, exit
219
        bras    ovfl_unfl               |go to unfl_ovfl to determine if
220
|                                       ;it is an unsupp or unimp exc
221
 
222
| No exceptions are to be reported.  If the instruction was
223
| unimplemented, no FPU restore is necessary.  If it was
224
| unsupported, we must perform the restore.
225
no_exc:
226
        tstb    UFLG_TMP(%a6)   |test flag for unsupp/unimp state
227
        beqs    uni_no_exc
228
uns_no_exc:
229
        tstb    RES_FLG(%a6)    |check if frestore is needed
230
        bne     do_clean        |if clear, no frestore needed
231
uni_no_exc:
232
        moveml  USER_DA(%a6),%d0-%d1/%a0-%a1
233
        fmovemx USER_FP0(%a6),%fp0-%fp3
234
        fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
235
        unlk    %a6
236
        bra     finish_up
237
|
238
| Unsupported Data Type Handler:
239
| Ovfl:
240
|   An fmoveout that results in an overflow is reported this way.
241
| Unfl:
242
|   An fmoveout that results in an underflow is reported this way.
243
|
244
| Unimplemented Instruction Handler:
245
| Ovfl:
246
|   Only scosh, setox, ssinh, stwotox, and scale can set overflow in
247
|   this manner.
248
| Unfl:
249
|   Stwotox, setox, and scale can set underflow in this manner.
250
|   Any of the other Library Routines such that f(x)=x in which
251
|   x is an extended denorm can report an underflow exception.
252
|   It is the responsibility of the exception-causing exception
253
|   to make sure that WBTEMP is correct.
254
|
255
|   The exceptional operand is in FP_SCR1.
256
|
257
ovfl_unfl:
258
        tstb    UFLG_TMP(%a6)   |test flag for unsupp/unimp state
259
        beqs    ofuf_con
260
|
261
| The caller was from an unsupported data type trap.  Test if the
262
| caller set CU_ONLY.  If so, the exceptional operand is expected in
263
| FPTEMP, rather than WBTEMP.
264
|
265
        tstb    CU_ONLY(%a6)            |test if inst is cu-only
266
        beq     unsE3
267
|       move.w  #$fe,CU_SAVEPC(%a6)
268
        clrb    CU_SAVEPC(%a6)
269
        bsetb   #E1,E_BYTE(%a6)         |set E1 exception flag
270
        movew   ETEMP_EX(%a6),FPTEMP_EX(%a6)
271
        movel   ETEMP_HI(%a6),FPTEMP_HI(%a6)
272
        movel   ETEMP_LO(%a6),FPTEMP_LO(%a6)
273
        bsetb   #fptemp15_bit,DTAG(%a6) |set fpte15
274
        bclrb   #UFLAG,T_BYTE(%a6)      |clr U flag from unimp
275
        bra     do_clean                |go clean and exit
276
 
277
ofuf_con:
278
        moveb   (%a7),VER_TMP(%a6)      |save version number
279
        cmpib   #BUSY_SIZE-4,1(%a7)     |check for busy frame
280
        beqs    busy_fr                 |if unimp, grow to busy
281
        cmpib   #VER_40,(%a7)           |test for orig unimp frame
282
        bnes    try_41                  |if not, test for rev frame
283
        moveql  #13,%d0                 |need to zero 14 lwords
284
        bras    ofuf_fin
285
try_41:
286
        cmpib   #VER_41,(%a7)           |test for rev unimp frame
287
        bnel    fpsp_fmt_error          |if neither, exit with error
288
        moveql  #11,%d0                 |need to zero 12 lwords
289
 
290
ofuf_fin:
291
        clrl    (%a7)
292
loop1:
293
        clrl    -(%a7)                  |clear and dec a7
294
        dbra    %d0,loop1
295
        moveb   VER_TMP(%a6),(%a7)
296
        moveb   #BUSY_SIZE-4,1(%a7)             |write busy fmt word.
297
busy_fr:
298
        movel   FP_SCR1(%a6),WBTEMP_EX(%a6)     |write
299
        movel   FP_SCR1+4(%a6),WBTEMP_HI(%a6)   |exceptional op to
300
        movel   FP_SCR1+8(%a6),WBTEMP_LO(%a6)   |wbtemp
301
        bsetb   #E3,E_BYTE(%a6)                 |set E3 flag
302
        bclrb   #E1,E_BYTE(%a6)                 |make sure E1 is clear
303
        bclrb   #UFLAG,T_BYTE(%a6)              |clr U flag
304
        movel   USER_FPSR(%a6),FPSR_SHADOW(%a6)
305
        orl     #sx_mask,E_BYTE(%a6)
306
        movel   CMDREG1B(%a6),%d0               |fix cmd1b to make it
307
        andl    #0x03c30000,%d0         |work for cmd3b
308
        bfextu  CMDREG1B(%a6){#13:#1},%d1       |extract bit 2
309
        lsll    #5,%d1
310
        swap    %d1
311
        orl     %d1,%d0                 |put it in the right place
312
        bfextu  CMDREG1B(%a6){#10:#3},%d1       |extract bit 3,4,5
313
        lsll    #2,%d1
314
        swap    %d1
315
        orl     %d1,%d0                 |put them in the right place
316
        movel   %d0,CMDREG3B(%a6)               |in the busy frame
317
 
318
|
319
| Check if the frame to be restored is busy or unimp.
320
|** NOTE *** Bug fix for errata (0d43b #3)
321
| If the frame is unimp, we must create a busy frame to
322
| fix the bug with the nmnexc bits in cases in which they
323
| are set by a previous instruction and not cleared by
324
| the save. The frame will be unimp only if the final
325
| instruction in an emulation routine caused the exception
326
| by doing an fmove ,fp0.  The exception operand, in
327
| internal format, is in fptemp.
328
|
329
do_clean:
330
        cmpib   #UNIMP_40_SIZE-4,1(%a7)
331
        bnes    do_con
332
        moveql  #13,%d0                 |in orig, need to zero 14 lwords
333
        bras    do_build
334
do_con:
335
        cmpib   #UNIMP_41_SIZE-4,1(%a7)
336
        bnes    do_restore              |frame must be busy
337
        moveql  #11,%d0                 |in rev, need to zero 12 lwords
338
 
339
do_build:
340
        moveb   (%a7),VER_TMP(%a6)
341
        clrl    (%a7)
342
loop2:
343
        clrl    -(%a7)                  |clear and dec a7
344
        dbra    %d0,loop2
345
|
346
| Use a1 as pointer into new frame.  a6 is not correct if an unimp or
347
| busy frame was created as the result of an exception on the final
348
| instruction of an emulation routine.
349
|
350
| We need to set the nmcexc bits if the exception is E1. Otherwise,
351
| the exc taken will be inex2.
352
|
353
        leal    BUSY_SIZE+LOCAL_SIZE(%a7),%a1   |init a1 for new frame
354
        moveb   VER_TMP(%a6),(%a7)      |write busy fmt word
355
        moveb   #BUSY_SIZE-4,1(%a7)
356
        movel   FP_SCR1(%a6),WBTEMP_EX(%a1)     |write
357
        movel   FP_SCR1+4(%a6),WBTEMP_HI(%a1)   |exceptional op to
358
        movel   FP_SCR1+8(%a6),WBTEMP_LO(%a1)   |wbtemp
359
|       btst.b  #E1,E_BYTE(%a1)
360
|       beq.b   do_restore
361
        bfextu  USER_FPSR(%a6){#17:#4},%d0      |get snan/operr/ovfl/unfl bits
362
        bfins   %d0,NMCEXC(%a1){#4:#4}  |and insert them in nmcexc
363
        movel   USER_FPSR(%a6),FPSR_SHADOW(%a1) |set exc bits
364
        orl     #sx_mask,E_BYTE(%a1)
365
 
366
do_restore:
367
        moveml  USER_DA(%a6),%d0-%d1/%a0-%a1
368
        fmovemx USER_FP0(%a6),%fp0-%fp3
369
        fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
370
        frestore (%a7)+
371
        tstb    RES_FLG(%a6)    |RES_FLG indicates a "continuation" frame
372
        beq     cont
373
        bsr     bug1384
374
cont:
375
        unlk    %a6
376
|
377
| If trace mode enabled, then go to trace handler.  This handler
378
| cannot have any fp instructions.  If there are fp inst's and an
379
| exception has been restored into the machine then the exception
380
| will occur upon execution of the fp inst.  This is not desirable
381
| in the kernel (supervisor mode).  See MC68040 manual Section 9.3.8.
382
|
383
finish_up:
384
        btstb   #7,(%a7)                |test T1 in SR
385
        bnes    g_trace
386
        btstb   #6,(%a7)                |test T0 in SR
387
        bnes    g_trace
388
        bral    fpsp_done
389
|
390
| Change integer stack to look like trace stack
391
| The address of the instruction that caused the
392
| exception is already in the integer stack (is
393
| the same as the saved friar)
394
|
395
| If the current frame is already a 6-word stack then all
396
| that needs to be done is to change the vector# to TRACE.
397
| If the frame is only a 4-word stack (meaning we got here
398
| on an Unsupported data type exception), then we need to grow
399
| the stack an extra 2 words and get the FPIAR from the FPU.
400
|
401
g_trace:
402
        bftst   EXC_VEC-4(%sp){#0:#4}
403
        bne     g_easy
404
 
405
        subw    #4,%sp          | make room
406
        movel   4(%sp),(%sp)
407
        movel   8(%sp),4(%sp)
408
        subw    #BUSY_SIZE,%sp
409
        fsave   (%sp)
410
        fmovel  %fpiar,BUSY_SIZE+EXC_EA-4(%sp)
411
        frestore (%sp)
412
        addw    #BUSY_SIZE,%sp
413
 
414
g_easy:
415
        movew   #TRACE_VEC,EXC_VEC-4(%a7)
416
        bral    real_trace
417
|
418
|  This is a work-around for hardware bug 1384.
419
|
420
bug1384:
421
        link    %a5,#0
422
        fsave   -(%sp)
423
        cmpib   #0x41,(%sp)     | check for correct frame
424
        beq     frame_41
425
        bgt     nofix           | if more advanced mask, do nada
426
 
427
frame_40:
428
        tstb    1(%sp)          | check to see if idle
429
        bne     notidle
430
idle40:
431
        clrl    (%sp)           | get rid of old fsave frame
432
        movel  %d1,USER_D1(%a6)  | save d1
433
        movew   #8,%d1          | place unimp frame instead
434
loop40: clrl    -(%sp)
435
        dbra    %d1,loop40
436
        movel  USER_D1(%a6),%d1  | restore d1
437
        movel   #0x40280000,-(%sp)
438
        frestore (%sp)+
439
        unlk    %a5
440
        rts
441
 
442
frame_41:
443
        tstb    1(%sp)          | check to see if idle
444
        bne     notidle
445
idle41:
446
        clrl    (%sp)           | get rid of old fsave frame
447
        movel  %d1,USER_D1(%a6)  | save d1
448
        movew   #10,%d1         | place unimp frame instead
449
loop41: clrl    -(%sp)
450
        dbra    %d1,loop41
451
        movel  USER_D1(%a6),%d1  | restore d1
452
        movel   #0x41300000,-(%sp)
453
        frestore (%sp)+
454
        unlk    %a5
455
        rts
456
 
457
notidle:
458
        bclrb   #etemp15_bit,-40(%a5)
459
        frestore (%sp)+
460
        unlk    %a5
461
        rts
462
 
463
nofix:
464
        frestore (%sp)+
465
        unlk    %a5
466
        rts
467
 
468
        |end

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.