Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/m68k/fpsp040/x_ovfl.S
10817 views
1
|
2
| x_ovfl.sa 3.5 7/1/91
3
|
4
| fpsp_ovfl --- FPSP handler for overflow exception
5
|
6
| Overflow occurs when a floating-point intermediate result is
7
| too large to be represented in a floating-point data register,
8
| or when storing to memory, the contents of a floating-point
9
| data register are too large to be represented in the
10
| destination format.
11
|
12
| Trap disabled results
13
|
14
| If the instruction is move_out, then garbage is stored in the
15
| destination. If the instruction is not move_out, then the
16
| destination is not affected. For 68881 compatibility, the
17
| following values should be stored at the destination, based
18
| on the current rounding mode:
19
|
20
| RN Infinity with the sign of the intermediate result.
21
| RZ Largest magnitude number, with the sign of the
22
| intermediate result.
23
| RM For pos overflow, the largest pos number. For neg overflow,
24
| -infinity
25
| RP For pos overflow, +infinity. For neg overflow, the largest
26
| neg number
27
|
28
| Trap enabled results
29
| All trap disabled code applies. In addition the exceptional
30
| operand needs to be made available to the users exception handler
31
| with a bias of $6000 subtracted from the exponent.
32
|
33
|
34
35
| Copyright (C) Motorola, Inc. 1990
36
| All Rights Reserved
37
|
38
| For details on the license for this file, please see the
39
| file, README, in this same directory.
40
41
X_OVFL: |idnt 2,1 | Motorola 040 Floating Point Software Package
42
43
|section 8
44
45
#include "fpsp.h"
46
47
|xref ovf_r_x2
48
|xref ovf_r_x3
49
|xref store
50
|xref real_ovfl
51
|xref real_inex
52
|xref fpsp_done
53
|xref g_opcls
54
|xref b1238_fix
55
56
.global fpsp_ovfl
57
fpsp_ovfl:
58
link %a6,#-LOCAL_SIZE
59
fsave -(%a7)
60
moveml %d0-%d1/%a0-%a1,USER_DA(%a6)
61
fmovemx %fp0-%fp3,USER_FP0(%a6)
62
fmoveml %fpcr/%fpsr/%fpiar,USER_FPCR(%a6)
63
64
|
65
| The 040 doesn't set the AINEX bit in the FPSR, the following
66
| line temporarily rectifies this error.
67
|
68
bsetb #ainex_bit,FPSR_AEXCEPT(%a6)
69
|
70
bsrl ovf_adj |denormalize, round & store interm op
71
|
72
| if overflow traps not enabled check for inexact exception
73
|
74
btstb #ovfl_bit,FPCR_ENABLE(%a6)
75
beqs ck_inex
76
|
77
btstb #E3,E_BYTE(%a6)
78
beqs no_e3_1
79
bfextu CMDREG3B(%a6){#6:#3},%d0 |get dest reg no
80
bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit
81
bsrl b1238_fix
82
movel USER_FPSR(%a6),FPSR_SHADOW(%a6)
83
orl #sx_mask,E_BYTE(%a6)
84
no_e3_1:
85
moveml USER_DA(%a6),%d0-%d1/%a0-%a1
86
fmovemx USER_FP0(%a6),%fp0-%fp3
87
fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
88
frestore (%a7)+
89
unlk %a6
90
bral real_ovfl
91
|
92
| It is possible to have either inex2 or inex1 exceptions with the
93
| ovfl. If the inex enable bit is set in the FPCR, and either
94
| inex2 or inex1 occurred, we must clean up and branch to the
95
| real inex handler.
96
|
97
ck_inex:
98
| move.b FPCR_ENABLE(%a6),%d0
99
| and.b FPSR_EXCEPT(%a6),%d0
100
| andi.b #$3,%d0
101
btstb #inex2_bit,FPCR_ENABLE(%a6)
102
beqs ovfl_exit
103
|
104
| Inexact enabled and reported, and we must take an inexact exception.
105
|
106
take_inex:
107
btstb #E3,E_BYTE(%a6)
108
beqs no_e3_2
109
bfextu CMDREG3B(%a6){#6:#3},%d0 |get dest reg no
110
bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit
111
bsrl b1238_fix
112
movel USER_FPSR(%a6),FPSR_SHADOW(%a6)
113
orl #sx_mask,E_BYTE(%a6)
114
no_e3_2:
115
moveb #INEX_VEC,EXC_VEC+1(%a6)
116
moveml USER_DA(%a6),%d0-%d1/%a0-%a1
117
fmovemx USER_FP0(%a6),%fp0-%fp3
118
fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
119
frestore (%a7)+
120
unlk %a6
121
bral real_inex
122
123
ovfl_exit:
124
bclrb #E3,E_BYTE(%a6) |test and clear E3 bit
125
beqs e1_set
126
|
127
| Clear dirty bit on dest resister in the frame before branching
128
| to b1238_fix.
129
|
130
bfextu CMDREG3B(%a6){#6:#3},%d0 |get dest reg no
131
bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit
132
bsrl b1238_fix |test for bug1238 case
133
134
movel USER_FPSR(%a6),FPSR_SHADOW(%a6)
135
orl #sx_mask,E_BYTE(%a6)
136
moveml USER_DA(%a6),%d0-%d1/%a0-%a1
137
fmovemx USER_FP0(%a6),%fp0-%fp3
138
fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
139
frestore (%a7)+
140
unlk %a6
141
bral fpsp_done
142
e1_set:
143
moveml USER_DA(%a6),%d0-%d1/%a0-%a1
144
fmovemx USER_FP0(%a6),%fp0-%fp3
145
fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
146
unlk %a6
147
bral fpsp_done
148
149
|
150
| ovf_adj
151
|
152
ovf_adj:
153
|
154
| Have a0 point to the correct operand.
155
|
156
btstb #E3,E_BYTE(%a6) |test E3 bit
157
beqs ovf_e1
158
159
lea WBTEMP(%a6),%a0
160
bras ovf_com
161
ovf_e1:
162
lea ETEMP(%a6),%a0
163
164
ovf_com:
165
bclrb #sign_bit,LOCAL_EX(%a0)
166
sne LOCAL_SGN(%a0)
167
168
bsrl g_opcls |returns opclass in d0
169
cmpiw #3,%d0 |check for opclass3
170
bnes not_opc011
171
172
|
173
| FPSR_CC is saved and restored because ovf_r_x3 affects it. The
174
| CCs are defined to be 'not affected' for the opclass3 instruction.
175
|
176
moveb FPSR_CC(%a6),L_SCR1(%a6)
177
bsrl ovf_r_x3 |returns a0 pointing to result
178
moveb L_SCR1(%a6),FPSR_CC(%a6)
179
bral store |stores to memory or register
180
181
not_opc011:
182
bsrl ovf_r_x2 |returns a0 pointing to result
183
bral store |stores to memory or register
184
185
|end
186
187