Revision 6191b059

b/target-i386/helper.c
5240 5240

  
5241 5241
#endif
5242 5242

  
5243
/* bit operations */
5244
target_ulong helper_bsf(target_ulong t0)
5245
{
5246
    int count;
5247
    target_ulong res;
5248

  
5249
    res = t0;
5250
    count = 0;
5251
    while ((res & 1) == 0) {
5252
        count++;
5253
        res >>= 1;
5254
    }
5255
    return count;
5256
}
5257

  
5258
target_ulong helper_bsr(target_ulong t0)
5259
{
5260
    int count;
5261
    target_ulong res, mask;
5262
    
5263
    res = t0;
5264
    count = TARGET_LONG_BITS - 1;
5265
    mask = (target_ulong)1 << (TARGET_LONG_BITS - 1);
5266
    while ((res & mask) == 0) {
5267
        count--;
5268
        res <<= 1;
5269
    }
5270
    return count;
5271
}
5272

  
5273

  
5243 5274
static int compute_all_eflags(void)
5244 5275
{
5245 5276
    return CC_SRC;
b/target-i386/helper.h
187 187
void helper_frstor(target_ulong ptr, int data32);
188 188
void helper_fxsave(target_ulong ptr, int data64);
189 189
void helper_fxrstor(target_ulong ptr, int data64);
190
target_ulong helper_bsf(target_ulong t0);
191
target_ulong helper_bsr(target_ulong t0);
190 192

  
191 193
/* MMX/SSE */
192 194

  
b/target-i386/ops_template.h
200 200
    T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2);
201 201
}
202 202

  
203
/* bit operations */
204
#if DATA_BITS >= 16
205

  
206
void OPPROTO glue(glue(op_bsf, SUFFIX), _T0_cc)(void)
207
{
208
    int count;
209
    target_long res;
210

  
211
    res = T0 & DATA_MASK;
212
    if (res != 0) {
213
        count = 0;
214
        while ((res & 1) == 0) {
215
            count++;
216
            res >>= 1;
217
        }
218
        T1 = count;
219
        CC_DST = 1; /* ZF = 0 */
220
    } else {
221
        CC_DST = 0; /* ZF = 1 */
222
    }
223
    FORCE_RET();
224
}
225

  
226
void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)
227
{
228
    int count;
229
    target_long res;
230

  
231
    res = T0 & DATA_MASK;
232
    if (res != 0) {
233
        count = DATA_BITS - 1;
234
        while ((res & SIGN_MASK) == 0) {
235
            count--;
236
            res <<= 1;
237
        }
238
        T1 = count;
239
        CC_DST = 1; /* ZF = 0 */
240
    } else {
241
        CC_DST = 0; /* ZF = 1 */
242
    }
243
    FORCE_RET();
244
}
245

  
246
#endif
247

  
248 203
/* string operations */
249 204

  
250 205
void OPPROTO glue(op_movl_T0_Dshift, SUFFIX)(void)
b/target-i386/translate.c
498 498
#endif
499 499
};
500 500

  
501
static GenOpFunc *gen_op_bsx_T0_cc[3][2] = {
502
    [0] = {
503
        gen_op_bsfw_T0_cc,
504
        gen_op_bsrw_T0_cc,
505
    },
506
    [1] = {
507
        gen_op_bsfl_T0_cc,
508
        gen_op_bsrl_T0_cc,
509
    },
510
#ifdef TARGET_X86_64
511
    [2] = {
512
        gen_op_bsfq_T0_cc,
513
        gen_op_bsrq_T0_cc,
514
    },
515
#endif
516
};
517

  
518 501
static inline void gen_op_lds_T0_A0(int idx)
519 502
{
520 503
    int mem_index = (idx >> 2) - 1;
......
5837 5820
        break;
5838 5821
    case 0x1bc: /* bsf */
5839 5822
    case 0x1bd: /* bsr */
5840
        ot = dflag + OT_WORD;
5841
        modrm = ldub_code(s->pc++);
5842
        reg = ((modrm >> 3) & 7) | rex_r;
5843
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
5844
        /* NOTE: in order to handle the 0 case, we must load the
5845
           result. It could be optimized with a generated jump */
5846
        gen_op_mov_TN_reg(ot, 1, reg);
5847
        gen_op_bsx_T0_cc[ot - OT_WORD][b & 1]();
5848
        gen_op_mov_reg_T1(ot, reg);
5849
        s->cc_op = CC_OP_LOGICB + ot;
5823
        {
5824
            int label1;
5825
            ot = dflag + OT_WORD;
5826
            modrm = ldub_code(s->pc++);
5827
            reg = ((modrm >> 3) & 7) | rex_r;
5828
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
5829
            gen_extu(ot, cpu_T[0]);
5830
            label1 = gen_new_label();
5831
            tcg_gen_movi_tl(cpu_cc_dst, 0);
5832
            tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[0], tcg_const_tl(0), label1);
5833
            if (b & 1) {
5834
                tcg_gen_helper_1_1(helper_bsr, cpu_T[0], cpu_T[0]);
5835
            } else {
5836
                tcg_gen_helper_1_1(helper_bsf, cpu_T[0], cpu_T[0]);
5837
            }
5838
            gen_op_mov_reg_T0(ot, reg);
5839
            tcg_gen_movi_tl(cpu_cc_dst, 1);
5840
            gen_set_label(label1);
5841
            tcg_gen_discard_tl(cpu_cc_src);
5842
            s->cc_op = CC_OP_LOGICB + ot;
5843
        }
5850 5844
        break;
5851 5845
        /************************/
5852 5846
        /* bcd */

Also available in: Unified diff