import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / arch / m68k / fpsp040 / x_ovfl.S
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 |       THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA 
39 |       The copyright notice above does not evidence any  
40 |       actual or intended publication of such source code.
41
42 X_OVFL: |idnt    2,1 | Motorola 040 Floating Point Software Package
43
44         |section        8
45
46         .include "fpsp.h"
47
48         |xref   ovf_r_x2
49         |xref   ovf_r_x3
50         |xref   store
51         |xref   real_ovfl
52         |xref   real_inex
53         |xref   fpsp_done
54         |xref   g_opcls
55         |xref   b1238_fix
56
57         .global fpsp_ovfl
58 fpsp_ovfl:
59         link            %a6,#-LOCAL_SIZE
60         fsave           -(%a7)
61         moveml          %d0-%d1/%a0-%a1,USER_DA(%a6)
62         fmovemx %fp0-%fp3,USER_FP0(%a6)
63         fmoveml %fpcr/%fpsr/%fpiar,USER_FPCR(%a6)
64
65 |
66 |       The 040 doesn't set the AINEX bit in the FPSR, the following
67 |       line temporarily rectifies this error.
68 |
69         bsetb   #ainex_bit,FPSR_AEXCEPT(%a6)
70 |
71         bsrl    ovf_adj         |denormalize, round & store interm op
72 |
73 |       if overflow traps not enabled check for inexact exception
74 |
75         btstb   #ovfl_bit,FPCR_ENABLE(%a6)
76         beqs    ck_inex 
77 |
78         btstb           #E3,E_BYTE(%a6)
79         beqs            no_e3_1
80         bfextu          CMDREG3B(%a6){#6:#3},%d0        |get dest reg no
81         bclrb           %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit
82         bsrl            b1238_fix
83         movel           USER_FPSR(%a6),FPSR_SHADOW(%a6)
84         orl             #sx_mask,E_BYTE(%a6)
85 no_e3_1:
86         moveml          USER_DA(%a6),%d0-%d1/%a0-%a1
87         fmovemx USER_FP0(%a6),%fp0-%fp3
88         fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
89         frestore        (%a7)+
90         unlk            %a6
91         bral            real_ovfl
92 |
93 | It is possible to have either inex2 or inex1 exceptions with the
94 | ovfl.  If the inex enable bit is set in the FPCR, and either
95 | inex2 or inex1 occurred, we must clean up and branch to the
96 | real inex handler.
97 |
98 ck_inex:
99 |       move.b          FPCR_ENABLE(%a6),%d0
100 |       and.b           FPSR_EXCEPT(%a6),%d0
101 |       andi.b          #$3,%d0
102         btstb           #inex2_bit,FPCR_ENABLE(%a6)
103         beqs            ovfl_exit
104 |
105 | Inexact enabled and reported, and we must take an inexact exception.
106 |
107 take_inex:
108         btstb           #E3,E_BYTE(%a6)
109         beqs            no_e3_2
110         bfextu          CMDREG3B(%a6){#6:#3},%d0        |get dest reg no
111         bclrb           %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit
112         bsrl            b1238_fix
113         movel           USER_FPSR(%a6),FPSR_SHADOW(%a6)
114         orl             #sx_mask,E_BYTE(%a6)
115 no_e3_2:
116         moveb           #INEX_VEC,EXC_VEC+1(%a6)
117         moveml          USER_DA(%a6),%d0-%d1/%a0-%a1
118         fmovemx USER_FP0(%a6),%fp0-%fp3
119         fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
120         frestore        (%a7)+
121         unlk            %a6
122         bral            real_inex
123         
124 ovfl_exit:
125         bclrb   #E3,E_BYTE(%a6) |test and clear E3 bit
126         beqs    e1_set
127 |
128 | Clear dirty bit on dest resister in the frame before branching
129 | to b1238_fix.
130 |
131         bfextu          CMDREG3B(%a6){#6:#3},%d0        |get dest reg no
132         bclrb           %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit
133         bsrl            b1238_fix               |test for bug1238 case
134
135         movel           USER_FPSR(%a6),FPSR_SHADOW(%a6)
136         orl             #sx_mask,E_BYTE(%a6)
137         moveml          USER_DA(%a6),%d0-%d1/%a0-%a1
138         fmovemx USER_FP0(%a6),%fp0-%fp3
139         fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
140         frestore        (%a7)+
141         unlk            %a6
142         bral            fpsp_done
143 e1_set:
144         moveml          USER_DA(%a6),%d0-%d1/%a0-%a1
145         fmovemx USER_FP0(%a6),%fp0-%fp3
146         fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
147         unlk            %a6
148         bral            fpsp_done
149
150 |
151 |       ovf_adj
152 |
153 ovf_adj:
154 |
155 | Have a0 point to the correct operand. 
156 |
157         btstb   #E3,E_BYTE(%a6) |test E3 bit
158         beqs    ovf_e1
159
160         lea     WBTEMP(%a6),%a0
161         bras    ovf_com
162 ovf_e1:
163         lea     ETEMP(%a6),%a0
164
165 ovf_com:
166         bclrb   #sign_bit,LOCAL_EX(%a0)
167         sne     LOCAL_SGN(%a0)
168
169         bsrl    g_opcls         |returns opclass in d0
170         cmpiw   #3,%d0          |check for opclass3
171         bnes    not_opc011
172
173 |
174 | FPSR_CC is saved and restored because ovf_r_x3 affects it. The
175 | CCs are defined to be 'not affected' for the opclass3 instruction.
176 |
177         moveb   FPSR_CC(%a6),L_SCR1(%a6)
178         bsrl    ovf_r_x3        |returns a0 pointing to result
179         moveb   L_SCR1(%a6),FPSR_CC(%a6)
180         bral    store           |stores to memory or register
181         
182 not_opc011:
183         bsrl    ovf_r_x2        |returns a0 pointing to result
184         bral    store           |stores to memory or register
185
186         |end