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