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