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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [m68k/] [fpsp040/] [x_operr.S] - Blame information for rev 3

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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