0001
0002 .file "reg_u_sub.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 #include "control_w.h"
0034
0035 .text
0036 SYM_FUNC_START(FPU_u_sub)
0037 pushl %ebp
0038 movl %esp,%ebp
0039 pushl %esi
0040 pushl %edi
0041 pushl %ebx
0042
0043 movl PARAM1,%esi
0044 movl PARAM2,%edi
0045
0046 movl PARAM6,%ecx
0047 subl PARAM7,%ecx
0048
0049 #ifdef PARANOID
0050
0051 js L_bugged_1
0052
0053 testl $0x80000000,SIGH(%edi)
0054 je L_bugged_2
0055
0056 testl $0x80000000,SIGH(%esi)
0057 je L_bugged_2
0058 #endif
0059
0060
0061
0062
0063
0064 movl SIGH(%edi),%eax
0065 movl SIGL(%edi),%ebx
0066
0067 movl PARAM3,%edi
0068 movl PARAM6,%edx
0069 movw %dx,EXP(%edi)
0070
0071 xorl %edx,%edx
0072
0073
0074
0075
0076
0077
0078
0079 cmpw $32,%cx
0080 jnc L_more_than_31
0081
0082
0083 shrd %cl,%ebx,%edx
0084 shrd %cl,%eax,%ebx
0085 shr %cl,%eax
0086 jmp L_shift_done
0087
0088 L_more_than_31:
0089 cmpw $64,%cx
0090 jnc L_more_than_63
0091
0092 subb $32,%cl
0093 jz L_exactly_32
0094
0095 shrd %cl,%eax,%edx
0096 shr %cl,%eax
0097 orl %ebx,%ebx
0098 jz L_more_31_no_low
0099
0100 orl $1,%edx
0101
0102 L_more_31_no_low:
0103 movl %eax,%ebx
0104 xorl %eax,%eax
0105 jmp L_shift_done
0106
0107 L_exactly_32:
0108 movl %ebx,%edx
0109 movl %eax,%ebx
0110 xorl %eax,%eax
0111 jmp L_shift_done
0112
0113 L_more_than_63:
0114 cmpw $65,%cx
0115 jnc L_more_than_64
0116
0117
0118 movl %eax,%edx
0119 orl %ebx,%ebx
0120 jz L_more_63_no_low
0121
0122 orl $1,%edx
0123 jmp L_more_63_no_low
0124
0125 L_more_than_64:
0126 jne L_more_than_65
0127
0128
0129
0130 movl %eax,%edx
0131 rcrl %edx
0132 jnc L_shift_65_nc
0133
0134 orl $1,%edx
0135 jmp L_more_63_no_low
0136
0137 L_shift_65_nc:
0138 orl %ebx,%ebx
0139 jz L_more_63_no_low
0140
0141 orl $1,%edx
0142 jmp L_more_63_no_low
0143
0144 L_more_than_65:
0145 movl $1,%edx
0146
0147 L_more_63_no_low:
0148 xorl %ebx,%ebx
0149 xorl %eax,%eax
0150
0151 L_shift_done:
0152 L_subtr:
0153
0154
0155
0156 xorl %ecx,%ecx
0157 subl %edx,%ecx
0158 movl %ecx,%edx
0159 movl SIGL(%esi),%ecx
0160 sbbl %ebx,%ecx
0161 movl %ecx,%ebx
0162 movl SIGH(%esi),%ecx
0163 sbbl %eax,%ecx
0164 movl %ecx,%eax
0165
0166 #ifdef PARANOID
0167
0168 jc L_bugged
0169 #endif
0170
0171
0172
0173
0174 testl $0x80000000,%eax
0175 jnz L_round
0176
0177 orl %eax,%eax
0178 jnz L_shift_1
0179
0180 orl %ebx,%ebx
0181 jnz L_shift_32
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191 cmpl $0x80000000,%edx
0192 jnz L_must_be_zero
0193
0194
0195 subw $64,EXP(%edi)
0196 xchg %edx,%eax
0197 jmp fpu_reg_round
0198
0199 L_must_be_zero:
0200 #ifdef PARANOID
0201 orl %edx,%edx
0202 jnz L_bugged_3
0203 #endif
0204
0205
0206 movw $0,EXP(%edi)
0207 movl $0,SIGL(%edi)
0208 movl $0,SIGH(%edi)
0209 movl TAG_Zero,%eax
0210 jmp L_exit
0211
0212 L_shift_32:
0213 movl %ebx,%eax
0214 movl %edx,%ebx
0215 movl $0,%edx
0216 subw $32,EXP(%edi)
0217
0218
0219 L_shift_1:
0220 bsrl %eax,%ecx
0221 subl $31,%ecx
0222 negl %ecx
0223 shld %cl,%ebx,%eax
0224 shld %cl,%edx,%ebx
0225 shl %cl,%edx
0226 subw %cx,EXP(%edi)
0227
0228 L_round:
0229 jmp fpu_reg_round
0230
0231
0232 #ifdef PARANOID
0233 L_bugged_1:
0234 pushl EX_INTERNAL|0x206
0235 call EXCEPTION
0236 pop %ebx
0237 jmp L_error_exit
0238
0239 L_bugged_2:
0240 pushl EX_INTERNAL|0x209
0241 call EXCEPTION
0242 pop %ebx
0243 jmp L_error_exit
0244
0245 L_bugged_3:
0246 pushl EX_INTERNAL|0x210
0247 call EXCEPTION
0248 pop %ebx
0249 jmp L_error_exit
0250
0251 L_bugged_4:
0252 pushl EX_INTERNAL|0x211
0253 call EXCEPTION
0254 pop %ebx
0255 jmp L_error_exit
0256
0257 L_bugged:
0258 pushl EX_INTERNAL|0x212
0259 call EXCEPTION
0260 pop %ebx
0261 jmp L_error_exit
0262
0263 L_error_exit:
0264 movl $-1,%eax
0265
0266 #endif
0267
0268 L_exit:
0269 popl %ebx
0270 popl %edi
0271 popl %esi
0272 leave
0273 RET
0274 SYM_FUNC_END(FPU_u_sub)