Commit 686f3f266b829b06c7b170db7b4ce97abfbfc517
1 parent
5b1214a4
BSR/BSF undefined behaviour fix
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@809 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
6 additions
and
5 deletions
target-i386/ops_template.h
@@ -513,7 +513,7 @@ void OPPROTO glue(glue(op_bsf, SUFFIX), _T0_cc)(void) | @@ -513,7 +513,7 @@ void OPPROTO glue(glue(op_bsf, SUFFIX), _T0_cc)(void) | ||
513 | count++; | 513 | count++; |
514 | res >>= 1; | 514 | res >>= 1; |
515 | } | 515 | } |
516 | - T0 = count; | 516 | + T1 = count; |
517 | CC_DST = 1; /* ZF = 0 */ | 517 | CC_DST = 1; /* ZF = 0 */ |
518 | } else { | 518 | } else { |
519 | CC_DST = 0; /* ZF = 1 */ | 519 | CC_DST = 0; /* ZF = 1 */ |
@@ -531,7 +531,7 @@ void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void) | @@ -531,7 +531,7 @@ void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void) | ||
531 | count--; | 531 | count--; |
532 | res <<= 1; | 532 | res <<= 1; |
533 | } | 533 | } |
534 | - T0 = count; | 534 | + T1 = count; |
535 | CC_DST = 1; /* ZF = 0 */ | 535 | CC_DST = 1; /* ZF = 0 */ |
536 | } else { | 536 | } else { |
537 | CC_DST = 0; /* ZF = 1 */ | 537 | CC_DST = 0; /* ZF = 1 */ |
target-i386/translate.c
@@ -3708,10 +3708,11 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3708,10 +3708,11 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3708 | modrm = ldub_code(s->pc++); | 3708 | modrm = ldub_code(s->pc++); |
3709 | reg = (modrm >> 3) & 7; | 3709 | reg = (modrm >> 3) & 7; |
3710 | gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); | 3710 | gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); |
3711 | + /* NOTE: in order to handle the 0 case, we must load the | ||
3712 | + result. It could be optimized with a generated jump */ | ||
3713 | + gen_op_mov_TN_reg[ot][1][reg](); | ||
3711 | gen_op_bsx_T0_cc[ot - OT_WORD][b & 1](); | 3714 | gen_op_bsx_T0_cc[ot - OT_WORD][b & 1](); |
3712 | - /* NOTE: we always write back the result. Intel doc says it is | ||
3713 | - undefined if T0 == 0 */ | ||
3714 | - gen_op_mov_reg_T0[ot][reg](); | 3715 | + gen_op_mov_reg_T1[ot][reg](); |
3715 | s->cc_op = CC_OP_LOGICB + ot; | 3716 | s->cc_op = CC_OP_LOGICB + ot; |
3716 | break; | 3717 | break; |
3717 | /************************/ | 3718 | /************************/ |