diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/m68k/fpsp040/x_ovfl.S |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/m68k/fpsp040/x_ovfl.S')
-rw-r--r-- | arch/m68k/fpsp040/x_ovfl.S | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/arch/m68k/fpsp040/x_ovfl.S b/arch/m68k/fpsp040/x_ovfl.S new file mode 100644 index 000000000000..22cb8b42c7b6 --- /dev/null +++ b/arch/m68k/fpsp040/x_ovfl.S | |||
@@ -0,0 +1,186 @@ | |||
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 | ||