0001
0002 .file "div_Xsig.S"
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include "exception.h"
0032 #include "fpu_emu.h"
0033
0034
0035 #define XsigLL(x) (x)
0036 #define XsigL(x) 4(x)
0037 #define XsigH(x) 8(x)
0038
0039
0040 #ifndef NON_REENTRANT_FPU
0041
0042
0043
0044
0045 #define FPU_accum_3 -4(%ebp)
0046 #define FPU_accum_2 -8(%ebp)
0047 #define FPU_accum_1 -12(%ebp)
0048 #define FPU_accum_0 -16(%ebp)
0049 #define FPU_result_3 -20(%ebp)
0050 #define FPU_result_2 -24(%ebp)
0051 #define FPU_result_1 -28(%ebp)
0052
0053 #else
0054 .data
0055
0056
0057
0058
0059 .align 4,0
0060 FPU_accum_3:
0061 .long 0
0062 FPU_accum_2:
0063 .long 0
0064 FPU_accum_1:
0065 .long 0
0066 FPU_accum_0:
0067 .long 0
0068 FPU_result_3:
0069 .long 0
0070 FPU_result_2:
0071 .long 0
0072 FPU_result_1:
0073 .long 0
0074 #endif
0075
0076
0077 .text
0078 SYM_FUNC_START(div_Xsig)
0079 pushl %ebp
0080 movl %esp,%ebp
0081 #ifndef NON_REENTRANT_FPU
0082 subl $28,%esp
0083 #endif
0084
0085 pushl %esi
0086 pushl %edi
0087 pushl %ebx
0088
0089 movl PARAM1,%esi
0090 movl PARAM2,%ebx
0091
0092 #ifdef PARANOID
0093 testl $0x80000000, XsigH(%ebx)
0094 je L_bugged
0095 #endif
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115 clc
0116 movl XsigH(%esi),%eax
0117 rcrl %eax
0118 movl %eax,FPU_accum_3
0119 movl XsigL(%esi),%eax
0120 rcrl %eax
0121 movl %eax,FPU_accum_2
0122 movl XsigLL(%esi),%eax
0123 rcrl %eax
0124 movl %eax,FPU_accum_1
0125 movl $0,%eax
0126 rcrl %eax
0127 movl %eax,FPU_accum_0
0128
0129 movl FPU_accum_2,%eax
0130 movl FPU_accum_3,%edx
0131
0132
0133
0134
0135
0136
0137 movl XsigH(%ebx),%ecx
0138 addl $1,%ecx
0139 jnc LFirst_div_not_1
0140
0141
0142
0143 mov %edx,%eax
0144 jmp LFirst_div_done
0145
0146 LFirst_div_not_1:
0147 divl %ecx
0148
0149
0150 LFirst_div_done:
0151 movl %eax,FPU_result_3
0152
0153 mull XsigH(%ebx)
0154
0155 subl %eax,FPU_accum_2
0156 sbbl %edx,FPU_accum_3
0157
0158 movl FPU_result_3,%eax
0159 mull XsigL(%ebx)
0160
0161 subl %eax,FPU_accum_1
0162 sbbl %edx,FPU_accum_2
0163 sbbl $0,FPU_accum_3
0164 je LDo_2nd_32_bits
0165
0166 #ifdef PARANOID
0167 jb L_bugged_1
0168 #endif
0169
0170
0171 incl FPU_result_3
0172
0173 movl XsigL(%ebx),%eax
0174 movl XsigH(%ebx),%edx
0175 subl %eax,FPU_accum_1
0176 sbbl %edx,FPU_accum_2
0177
0178 #ifdef PARANOID
0179 sbbl $0,FPU_accum_3
0180 jne L_bugged_1
0181 #endif
0182
0183
0184
0185
0186
0187 LDo_2nd_32_bits:
0188 movl FPU_accum_2,%edx
0189 movl FPU_accum_1,%eax
0190
0191
0192 cmpl XsigH(%ebx),%edx
0193 jb LDo_2nd_div
0194 ja LPrevent_2nd_overflow
0195
0196 cmpl XsigL(%ebx),%eax
0197 jb LDo_2nd_div
0198
0199 LPrevent_2nd_overflow:
0200
0201
0202 subl XsigL(%ebx),%eax
0203 sbbl XsigH(%ebx),%edx
0204 movl %edx,FPU_accum_2
0205 movl %eax,FPU_accum_1
0206
0207 incl FPU_result_3
0208
0209 #ifdef PARANOID
0210 je L_bugged_2
0211 #endif
0212
0213 LDo_2nd_div:
0214 cmpl $0,%ecx
0215 jnz LSecond_div_not_1
0216
0217
0218 mov %edx,%eax
0219 jmp LSecond_div_done
0220
0221 LSecond_div_not_1:
0222 divl %ecx
0223
0224 LSecond_div_done:
0225 movl %eax,FPU_result_2
0226
0227 mull XsigH(%ebx)
0228
0229 subl %eax,FPU_accum_1
0230 sbbl %edx,FPU_accum_2
0231
0232 #ifdef PARANOID
0233 jc L_bugged_2
0234 #endif
0235
0236 movl FPU_result_2,%eax
0237 mull XsigL(%ebx)
0238
0239 subl %eax,FPU_accum_0
0240 sbbl %edx,FPU_accum_1
0241 sbbl $0,FPU_accum_2
0242
0243 #ifdef PARANOID
0244 jc L_bugged_2
0245 #endif
0246
0247 jz LDo_3rd_32_bits
0248
0249 #ifdef PARANOID
0250 cmpl $1,FPU_accum_2
0251 jne L_bugged_2
0252 #endif
0253
0254
0255 movl XsigL(%ebx),%eax
0256 movl XsigH(%ebx),%edx
0257 subl %eax,FPU_accum_0
0258 sbbl %edx,FPU_accum_1
0259 sbbl $0,FPU_accum_2
0260
0261 #ifdef PARANOID
0262 jc L_bugged_2
0263 jne L_bugged_2
0264 #endif
0265
0266 addl $1,FPU_result_2
0267 adcl $0,FPU_result_3
0268
0269 #ifdef PARANOID
0270 jc L_bugged_2
0271 #endif
0272
0273
0274
0275
0276
0277 LDo_3rd_32_bits:
0278
0279
0280
0281
0282 movl FPU_result_3,%eax
0283 mull XsigLL(%ebx)
0284
0285 subl %edx,FPU_accum_1
0286
0287
0288 jnb LTest_over
0289
0290 movl XsigH(%ebx),%edx
0291 addl %edx,FPU_accum_1
0292
0293 subl $1,FPU_result_2
0294 sbbl $0,FPU_result_3
0295
0296
0297 movl FPU_accum_1,%edx
0298 cmpl XsigH(%ebx),%edx
0299 jb LDo_3rd_div
0300
0301 movl XsigH(%ebx),%edx
0302 addl %edx,FPU_accum_1
0303
0304 subl $1,FPU_result_2
0305 sbbl $0,FPU_result_3
0306 jmp LDo_3rd_div
0307
0308 LTest_over:
0309 movl FPU_accum_1,%edx
0310
0311
0312 cmpl XsigH(%ebx),%edx
0313 jb LDo_3rd_div
0314
0315
0316 subl XsigH(%ebx),%edx
0317 movl %edx,FPU_accum_1
0318
0319 addl $1,FPU_result_2
0320 adcl $0,FPU_result_3
0321
0322 LDo_3rd_div:
0323 movl FPU_accum_0,%eax
0324 movl FPU_accum_1,%edx
0325 divl XsigH(%ebx)
0326
0327 movl %eax,FPU_result_1
0328
0329 movl PARAM3,%esi
0330
0331 movl FPU_result_1,%eax
0332 movl %eax,XsigLL(%esi)
0333 movl FPU_result_2,%eax
0334 movl %eax,XsigL(%esi)
0335 movl FPU_result_3,%eax
0336 movl %eax,XsigH(%esi)
0337
0338 L_exit:
0339 popl %ebx
0340 popl %edi
0341 popl %esi
0342
0343 leave
0344 RET
0345
0346
0347 #ifdef PARANOID
0348
0349 L_bugged:
0350 pushl EX_INTERNAL|0x240
0351 call EXCEPTION
0352 pop %ebx
0353 jmp L_exit
0354
0355 L_bugged_1:
0356 pushl EX_INTERNAL|0x241
0357 call EXCEPTION
0358 pop %ebx
0359 jmp L_exit
0360
0361 L_bugged_2:
0362 pushl EX_INTERNAL|0x242
0363 call EXCEPTION
0364 pop %ebx
0365 jmp L_exit
0366 #endif
0367 SYM_FUNC_END(div_Xsig)