Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 | | | |
e00d82d0 MW |
38 | | For details on the license for this file, please see the |
39 | | file, README, in this same directory. | |
1da177e4 LT |
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 |