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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [m68k/] [fpsp040/] [x_operr.S] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
|
2
|       x_operr.sa 3.5 7/1/91
3
|
4
|       fpsp_operr --- FPSP handler for operand error exception
5
|
6
|       See 68040 User's Manual pp. 9-44f
7
|
8
| Note 1: For trap disabled 040 does the following:
9
| If the dest is a fp reg, then an extended precision non_signaling
10
| NAN is stored in the dest reg.  If the dest format is b, w, or l and
11
| the source op is a NAN, then garbage is stored as the result (actually
12
| the upper 32 bits of the mantissa are sent to the integer unit). If
13
| the dest format is integer (b, w, l) and the operr is caused by
14
| integer overflow, or the source op is inf, then the result stored is
15
| garbage.
16
| There are three cases in which operr is incorrectly signaled on the
17
| 040.  This occurs for move_out of format b, w, or l for the largest
18
| negative integer (-2^7 for b, -2^15 for w, -2^31 for l).
19
|
20
|         On opclass = 011 fmove.(b,w,l) that causes a conversion
21
|         overflow -> OPERR, the exponent in wbte (and fpte) is:
22
|               byte    56 - (62 - exp)
23
|               word    48 - (62 - exp)
24
|               long    32 - (62 - exp)
25
|
26
|                       where exp = (true exp) - 1
27
|
28
|  So, wbtemp and fptemp will contain the following on erroneously
29
|         signalled operr:
30
|                       fpts = 1
31
|                       fpte = $4000  (15 bit externally)
32
|               byte    fptm = $ffffffff ffffff80
33
|               word    fptm = $ffffffff ffff8000
34
|               long    fptm = $ffffffff 80000000
35
|
36
| Note 2: For trap enabled 040 does the following:
37
| If the inst is move_out, then same as Note 1.
38
| If the inst is not move_out, the dest is not modified.
39
| The exceptional operand is not defined for integer overflow
40
| during a move_out.
41
|
42
 
43
|               Copyright (C) Motorola, Inc. 1990
44
|                       All Rights Reserved
45
|
46
|       THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
47
|       The copyright notice above does not evidence any
48
|       actual or intended publication of such source code.
49
 
50
X_OPERR:        |idnt    2,1 | Motorola 040 Floating Point Software Package
51
 
52
        |section        8
53
 
54
        .include "fpsp.h"
55
 
56
        |xref   mem_write
57
        |xref   real_operr
58
        |xref   real_inex
59
        |xref   get_fline
60
        |xref   fpsp_done
61
        |xref   reg_dest
62
 
63
        .global fpsp_operr
64
fpsp_operr:
65
|
66
        link            %a6,#-LOCAL_SIZE
67
        fsave           -(%a7)
68
        moveml          %d0-%d1/%a0-%a1,USER_DA(%a6)
69
        fmovemx %fp0-%fp3,USER_FP0(%a6)
70
        fmoveml %fpcr/%fpsr/%fpiar,USER_FPCR(%a6)
71
 
72
|
73
| Check if this is an opclass 3 instruction.
74
|  If so, fall through, else branch to operr_end
75
|
76
        btstb   #TFLAG,T_BYTE(%a6)
77
        beqs    operr_end
78
 
79
|
80
| If the destination size is B,W,or L, the operr must be
81
| handled here.
82
|
83
        movel   CMDREG1B(%a6),%d0
84
        bfextu  %d0{#3:#3},%d0  |0=long, 4=word, 6=byte
85
        cmpib   #0,%d0          |determine size; check long
86
        beq     operr_long
87
        cmpib   #4,%d0          |check word
88
        beq     operr_word
89
        cmpib   #6,%d0          |check byte
90
        beq     operr_byte
91
 
92
|
93
| The size is not B,W,or L, so the operr is handled by the
94
| kernel handler.  Set the operr bits and clean up, leaving
95
| only the integer exception frame on the stack, and the
96
| fpu in the original exceptional state.
97
|
98
operr_end:
99
        bsetb           #operr_bit,FPSR_EXCEPT(%a6)
100
        bsetb           #aiop_bit,FPSR_AEXCEPT(%a6)
101
 
102
        moveml          USER_DA(%a6),%d0-%d1/%a0-%a1
103
        fmovemx USER_FP0(%a6),%fp0-%fp3
104
        fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
105
        frestore        (%a7)+
106
        unlk            %a6
107
        bral            real_operr
108
 
109
operr_long:
110
        moveql  #4,%d1          |write size to d1
111
        moveb   STAG(%a6),%d0   |test stag for nan
112
        andib   #0xe0,%d0               |clr all but tag
113
        cmpib   #0x60,%d0               |check for nan
114
        beq     operr_nan
115
        cmpil   #0x80000000,FPTEMP_LO(%a6) |test if ls lword is special
116
        bnes    chklerr         |if not equal, check for incorrect operr
117
        bsr     check_upper     |check if exp and ms mant are special
118
        tstl    %d0
119
        bnes    chklerr         |if d0 is true, check for incorrect operr
120
        movel   #0x80000000,%d0 |store special case result
121
        bsr     operr_store
122
        bra     not_enabled     |clean and exit
123
|
124
|       CHECK FOR INCORRECTLY GENERATED OPERR EXCEPTION HERE
125
|
126
chklerr:
127
        movew   FPTEMP_EX(%a6),%d0
128
        andw    #0x7FFF,%d0     |ignore sign bit
129
        cmpw    #0x3FFE,%d0     |this is the only possible exponent value
130
        bnes    chklerr2
131
fixlong:
132
        movel   FPTEMP_LO(%a6),%d0
133
        bsr     operr_store
134
        bra     not_enabled
135
chklerr2:
136
        movew   FPTEMP_EX(%a6),%d0
137
        andw    #0x7FFF,%d0     |ignore sign bit
138
        cmpw    #0x4000,%d0
139
        bcc     store_max       |exponent out of range
140
 
141
        movel   FPTEMP_LO(%a6),%d0
142
        andl    #0x7FFF0000,%d0 |look for all 1's on bits 30-16
143
        cmpl    #0x7FFF0000,%d0
144
        beqs    fixlong
145
 
146
        tstl    FPTEMP_LO(%a6)
147
        bpls    chklepos
148
        cmpl    #0xFFFFFFFF,FPTEMP_HI(%a6)
149
        beqs    fixlong
150
        bra     store_max
151
chklepos:
152
        tstl    FPTEMP_HI(%a6)
153
        beqs    fixlong
154
        bra     store_max
155
 
156
operr_word:
157
        moveql  #2,%d1          |write size to d1
158
        moveb   STAG(%a6),%d0   |test stag for nan
159
        andib   #0xe0,%d0               |clr all but tag
160
        cmpib   #0x60,%d0               |check for nan
161
        beq     operr_nan
162
        cmpil   #0xffff8000,FPTEMP_LO(%a6) |test if ls lword is special
163
        bnes    chkwerr         |if not equal, check for incorrect operr
164
        bsr     check_upper     |check if exp and ms mant are special
165
        tstl    %d0
166
        bnes    chkwerr         |if d0 is true, check for incorrect operr
167
        movel   #0x80000000,%d0 |store special case result
168
        bsr     operr_store
169
        bra     not_enabled     |clean and exit
170
|
171
|       CHECK FOR INCORRECTLY GENERATED OPERR EXCEPTION HERE
172
|
173
chkwerr:
174
        movew   FPTEMP_EX(%a6),%d0
175
        andw    #0x7FFF,%d0     |ignore sign bit
176
        cmpw    #0x3FFE,%d0     |this is the only possible exponent value
177
        bnes    store_max
178
        movel   FPTEMP_LO(%a6),%d0
179
        swap    %d0
180
        bsr     operr_store
181
        bra     not_enabled
182
 
183
operr_byte:
184
        moveql  #1,%d1          |write size to d1
185
        moveb   STAG(%a6),%d0   |test stag for nan
186
        andib   #0xe0,%d0               |clr all but tag
187
        cmpib   #0x60,%d0               |check for nan
188
        beqs    operr_nan
189
        cmpil   #0xffffff80,FPTEMP_LO(%a6) |test if ls lword is special
190
        bnes    chkberr         |if not equal, check for incorrect operr
191
        bsr     check_upper     |check if exp and ms mant are special
192
        tstl    %d0
193
        bnes    chkberr         |if d0 is true, check for incorrect operr
194
        movel   #0x80000000,%d0 |store special case result
195
        bsr     operr_store
196
        bra     not_enabled     |clean and exit
197
|
198
|       CHECK FOR INCORRECTLY GENERATED OPERR EXCEPTION HERE
199
|
200
chkberr:
201
        movew   FPTEMP_EX(%a6),%d0
202
        andw    #0x7FFF,%d0     |ignore sign bit
203
        cmpw    #0x3FFE,%d0     |this is the only possible exponent value
204
        bnes    store_max
205
        movel   FPTEMP_LO(%a6),%d0
206
        asll    #8,%d0
207
        swap    %d0
208
        bsr     operr_store
209
        bra     not_enabled
210
 
211
|
212
| This operr condition is not of the special case.  Set operr
213
| and aiop and write the portion of the nan to memory for the
214
| given size.
215
|
216
operr_nan:
217
        orl     #opaop_mask,USER_FPSR(%a6) |set operr & aiop
218
 
219
        movel   ETEMP_HI(%a6),%d0       |output will be from upper 32 bits
220
        bsr     operr_store
221
        bra     end_operr
222
|
223
| Store_max loads the max pos or negative for the size, sets
224
| the operr and aiop bits, and clears inex and ainex, incorrectly
225
| set by the 040.
226
|
227
store_max:
228
        orl     #opaop_mask,USER_FPSR(%a6) |set operr & aiop
229
        bclrb   #inex2_bit,FPSR_EXCEPT(%a6)
230
        bclrb   #ainex_bit,FPSR_AEXCEPT(%a6)
231
        fmovel  #0,%FPSR
232
 
233
        tstw    FPTEMP_EX(%a6)  |check sign
234
        blts    load_neg
235
        movel   #0x7fffffff,%d0
236
        bsr     operr_store
237
        bra     end_operr
238
load_neg:
239
        movel   #0x80000000,%d0
240
        bsr     operr_store
241
        bra     end_operr
242
 
243
|
244
| This routine stores the data in d0, for the given size in d1,
245
| to memory or data register as required.  A read of the fline
246
| is required to determine the destination.
247
|
248
operr_store:
249
        movel   %d0,L_SCR1(%a6) |move write data to L_SCR1
250
        movel   %d1,-(%a7)      |save register size
251
        bsrl    get_fline       |fline returned in d0
252
        movel   (%a7)+,%d1
253
        bftst   %d0{#26:#3}             |if mode is zero, dest is Dn
254
        bnes    dest_mem
255
|
256
| Destination is Dn.  Get register number from d0. Data is on
257
| the stack at (a7). D1 has size: 1=byte,2=word,4=long/single
258
|
259
        andil   #7,%d0          |isolate register number
260
        cmpil   #4,%d1
261
        beqs    op_long         |the most frequent case
262
        cmpil   #2,%d1
263
        bnes    op_con
264
        orl     #8,%d0
265
        bras    op_con
266
op_long:
267
        orl     #0x10,%d0
268
op_con:
269
        movel   %d0,%d1         |format size:reg for reg_dest
270
        bral    reg_dest        |call to reg_dest returns to caller
271
|                               ;of operr_store
272
|
273
| Destination is memory.  Get  from integer exception frame
274
| and call mem_write.
275
|
276
dest_mem:
277
        leal    L_SCR1(%a6),%a0 |put ptr to write data in a0
278
        movel   EXC_EA(%a6),%a1 |put user destination address in a1
279
        movel   %d1,%d0         |put size in d0
280
        bsrl    mem_write
281
        rts
282
|
283
| Check the exponent for $c000 and the upper 32 bits of the
284
| mantissa for $ffffffff.  If both are true, return d0 clr
285
| and store the lower n bits of the least lword of FPTEMP
286
| to d0 for write out.  If not, it is a real operr, and set d0.
287
|
288
check_upper:
289
        cmpil   #0xffffffff,FPTEMP_HI(%a6) |check if first byte is all 1's
290
        bnes    true_operr      |if not all 1's then was true operr
291
        cmpiw   #0xc000,FPTEMP_EX(%a6) |check if incorrectly signalled
292
        beqs    not_true_operr  |branch if not true operr
293
        cmpiw   #0xbfff,FPTEMP_EX(%a6) |check if incorrectly signalled
294
        beqs    not_true_operr  |branch if not true operr
295
true_operr:
296
        movel   #1,%d0          |signal real operr
297
        rts
298
not_true_operr:
299
        clrl    %d0             |signal no real operr
300
        rts
301
 
302
|
303
| End_operr tests for operr enabled.  If not, it cleans up the stack
304
| and does an rte.  If enabled, it cleans up the stack and branches
305
| to the kernel operr handler with only the integer exception
306
| frame on the stack and the fpu in the original exceptional state
307
| with correct data written to the destination.
308
|
309
end_operr:
310
        btstb           #operr_bit,FPCR_ENABLE(%a6)
311
        beqs            not_enabled
312
enabled:
313
        moveml          USER_DA(%a6),%d0-%d1/%a0-%a1
314
        fmovemx USER_FP0(%a6),%fp0-%fp3
315
        fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
316
        frestore        (%a7)+
317
        unlk            %a6
318
        bral            real_operr
319
 
320
not_enabled:
321
|
322
| It is possible to have either inex2 or inex1 exceptions with the
323
| operr.  If the inex enable bit is set in the FPCR, and either
324
| inex2 or inex1 occurred, we must clean up and branch to the
325
| real inex handler.
326
|
327
ck_inex:
328
        moveb   FPCR_ENABLE(%a6),%d0
329
        andb    FPSR_EXCEPT(%a6),%d0
330
        andib   #0x3,%d0
331
        beq     operr_exit
332
|
333
| Inexact enabled and reported, and we must take an inexact exception.
334
|
335
take_inex:
336
        moveb           #INEX_VEC,EXC_VEC+1(%a6)
337
        movel           USER_FPSR(%a6),FPSR_SHADOW(%a6)
338
        orl             #sx_mask,E_BYTE(%a6)
339
        moveml          USER_DA(%a6),%d0-%d1/%a0-%a1
340
        fmovemx USER_FP0(%a6),%fp0-%fp3
341
        fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
342
        frestore        (%a7)+
343
        unlk            %a6
344
        bral            real_inex
345
|
346
| Since operr is only an E1 exception, there is no need to frestore
347
| any state back to the fpu.
348
|
349
operr_exit:
350
        moveml          USER_DA(%a6),%d0-%d1/%a0-%a1
351
        fmovemx USER_FP0(%a6),%fp0-%fp3
352
        fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
353
        unlk            %a6
354
        bral            fpsp_done
355
 
356
        |end

powered by: WebSVN 2.1.0

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