Revision 7524c84d target-i386/helper.c
b/target-i386/helper.c | ||
---|---|---|
3139 | 3139 |
CPU86_LDouble dblq, fpsrcop, fptemp; |
3140 | 3140 |
CPU86_LDoubleU fpsrcop1, fptemp1; |
3141 | 3141 |
int expdif; |
3142 |
int q; |
|
3142 |
signed long long int q; |
|
3143 |
|
|
3144 |
if (isinf(ST0) || isnan(ST0) || isnan(ST1) || (ST1 == 0.0)) { |
|
3145 |
ST0 = 0.0 / 0.0; /* NaN */ |
|
3146 |
env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ |
|
3147 |
return; |
|
3148 |
} |
|
3143 | 3149 |
|
3144 | 3150 |
fpsrcop = ST0; |
3145 | 3151 |
fptemp = ST1; |
3146 | 3152 |
fpsrcop1.d = fpsrcop; |
3147 | 3153 |
fptemp1.d = fptemp; |
3148 | 3154 |
expdif = EXPD(fpsrcop1) - EXPD(fptemp1); |
3155 |
|
|
3156 |
if (expdif < 0) { |
|
3157 |
/* optimisation? taken from the AMD docs */ |
|
3158 |
env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ |
|
3159 |
/* ST0 is unchanged */ |
|
3160 |
return; |
|
3161 |
} |
|
3162 |
|
|
3149 | 3163 |
if (expdif < 53) { |
3150 | 3164 |
dblq = fpsrcop / fptemp; |
3151 |
dblq = (dblq < 0.0)? ceil(dblq): floor(dblq); |
|
3152 |
ST0 = fpsrcop - fptemp*dblq; |
|
3153 |
q = (int)dblq; /* cutting off top bits is assumed here */ |
|
3165 |
/* round dblq towards nearest integer */ |
|
3166 |
dblq = rint(dblq); |
|
3167 |
ST0 = fpsrcop - fptemp * dblq; |
|
3168 |
|
|
3169 |
/* convert dblq to q by truncating towards zero */ |
|
3170 |
if (dblq < 0.0) |
|
3171 |
q = (signed long long int)(-dblq); |
|
3172 |
else |
|
3173 |
q = (signed long long int)dblq; |
|
3174 |
|
|
3154 | 3175 |
env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ |
3155 |
/* (C0,C1,C3) <-- (q2,q1,q0) */
|
|
3156 |
env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */
|
|
3157 |
env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */
|
|
3158 |
env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */
|
|
3176 |
/* (C0,C3,C1) <-- (q2,q1,q0) */
|
|
3177 |
env->fpus |= (q & 0x4) << (8 - 2); /* (C0) <-- q2 */
|
|
3178 |
env->fpus |= (q & 0x2) << (14 - 1); /* (C3) <-- q1 */
|
|
3179 |
env->fpus |= (q & 0x1) << (9 - 0); /* (C1) <-- q0 */
|
|
3159 | 3180 |
} else { |
3160 | 3181 |
env->fpus |= 0x400; /* C2 <-- 1 */ |
3161 |
fptemp = pow(2.0, expdif-50);
|
|
3182 |
fptemp = pow(2.0, expdif - 50);
|
|
3162 | 3183 |
fpsrcop = (ST0 / ST1) / fptemp; |
3163 |
/* fpsrcop = integer obtained by rounding to the nearest */
|
|
3164 |
fpsrcop = (fpsrcop-floor(fpsrcop) < ceil(fpsrcop)-fpsrcop)?
|
|
3165 |
floor(fpsrcop): ceil(fpsrcop);
|
|
3184 |
/* fpsrcop = integer obtained by chopping */
|
|
3185 |
fpsrcop = (fpsrcop < 0.0) ?
|
|
3186 |
-(floor(fabs(fpsrcop))) : floor(fpsrcop);
|
|
3166 | 3187 |
ST0 -= (ST1 * fpsrcop * fptemp); |
3167 | 3188 |
} |
3168 | 3189 |
} |
... | ... | |
3172 | 3193 |
CPU86_LDouble dblq, fpsrcop, fptemp; |
3173 | 3194 |
CPU86_LDoubleU fpsrcop1, fptemp1; |
3174 | 3195 |
int expdif; |
3175 |
int q; |
|
3176 |
|
|
3177 |
fpsrcop = ST0; |
|
3178 |
fptemp = ST1; |
|
3196 |
signed long long int q; |
|
3197 |
|
|
3198 |
if (isinf(ST0) || isnan(ST0) || isnan(ST1) || (ST1 == 0.0)) { |
|
3199 |
ST0 = 0.0 / 0.0; /* NaN */ |
|
3200 |
env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ |
|
3201 |
return; |
|
3202 |
} |
|
3203 |
|
|
3204 |
fpsrcop = (CPU86_LDouble)ST0; |
|
3205 |
fptemp = (CPU86_LDouble)ST1; |
|
3179 | 3206 |
fpsrcop1.d = fpsrcop; |
3180 | 3207 |
fptemp1.d = fptemp; |
3181 | 3208 |
expdif = EXPD(fpsrcop1) - EXPD(fptemp1); |
3209 |
|
|
3210 |
if (expdif < 0) { |
|
3211 |
/* optimisation? taken from the AMD docs */ |
|
3212 |
env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ |
|
3213 |
/* ST0 is unchanged */ |
|
3214 |
return; |
|
3215 |
} |
|
3216 |
|
|
3182 | 3217 |
if ( expdif < 53 ) { |
3183 |
dblq = fpsrcop / fptemp; |
|
3184 |
dblq = (dblq < 0.0)? ceil(dblq): floor(dblq); |
|
3185 |
ST0 = fpsrcop - fptemp*dblq; |
|
3186 |
q = (int)dblq; /* cutting off top bits is assumed here */ |
|
3218 |
dblq = fpsrcop/*ST0*/ / fptemp/*ST1*/; |
|
3219 |
/* round dblq towards zero */ |
|
3220 |
dblq = (dblq < 0.0) ? ceil(dblq) : floor(dblq); |
|
3221 |
ST0 = fpsrcop/*ST0*/ - fptemp * dblq; |
|
3222 |
|
|
3223 |
/* convert dblq to q by truncating towards zero */ |
|
3224 |
if (dblq < 0.0) |
|
3225 |
q = (signed long long int)(-dblq); |
|
3226 |
else |
|
3227 |
q = (signed long long int)dblq; |
|
3228 |
|
|
3187 | 3229 |
env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ |
3188 |
/* (C0,C1,C3) <-- (q2,q1,q0) */
|
|
3189 |
env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */
|
|
3190 |
env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */
|
|
3191 |
env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */
|
|
3230 |
/* (C0,C3,C1) <-- (q2,q1,q0) */
|
|
3231 |
env->fpus |= (q & 0x4) << (8 - 2); /* (C0) <-- q2 */
|
|
3232 |
env->fpus |= (q & 0x2) << (14 - 1); /* (C3) <-- q1 */
|
|
3233 |
env->fpus |= (q & 0x1) << (9 - 0); /* (C1) <-- q0 */
|
|
3192 | 3234 |
} else { |
3235 |
int N = 32 + (expdif % 32); /* as per AMD docs */ |
|
3193 | 3236 |
env->fpus |= 0x400; /* C2 <-- 1 */ |
3194 |
fptemp = pow(2.0, expdif-50);
|
|
3237 |
fptemp = pow(2.0, (double)(expdif - N));
|
|
3195 | 3238 |
fpsrcop = (ST0 / ST1) / fptemp; |
3196 | 3239 |
/* fpsrcop = integer obtained by chopping */ |
3197 |
fpsrcop = (fpsrcop < 0.0)? |
|
3198 |
-(floor(fabs(fpsrcop))): floor(fpsrcop);
|
|
3240 |
fpsrcop = (fpsrcop < 0.0) ?
|
|
3241 |
-(floor(fabs(fpsrcop))) : floor(fpsrcop);
|
|
3199 | 3242 |
ST0 -= (ST1 * fpsrcop * fptemp); |
3200 | 3243 |
} |
3201 | 3244 |
} |
Also available in: Unified diff