On 14/07/2025 5:02 pm, Jan Beulich wrote: > SDM revision 087 points out that apparently as of quite some time ago on > Intel hardware BSF and BSR may alter all arithmetic flags, not just ZF. > Because of the inconsistency (and because documentation doesn't look to
It's probably worth saying errata explicitly. There are a whole bunch of Intel CPUs where the behaviour doesn't match CPUID. > be quite right about PF), best we can do is simply take the flag values > from what the processor produces, just like we do for various other > arithmetic insns. (Note also that AMD and Intel have always been > disagreeing on arithmetic flags other than ZF.) To be both safe (against > further anomalies) and consistent, extend this to {L,T}ZCNT as well. > (Emulating the two insns correctly even when underlying hardware doesn't > support it was perhaps nice, but yielded guest-observable > inconsistencies.) > > Signed-off-by: Jan Beulich <jbeul...@suse.com> Reviewed-by: Andrew Cooper <andrew.coop...@citrix.com> This is one of the more messy parts of x86, and that's saying something. > --- > v2: Use emulate_2op_SrcV_srcmem() also for {L,T}ZCNT. > > --- a/xen/arch/x86/x86_emulate/x86_emulate.c > +++ b/xen/arch/x86/x86_emulate/x86_emulate.c > @@ -5270,62 +5270,26 @@ x86_emulate( > break; > > case X86EMUL_OPC(0x0f, 0xbc): /* bsf or tzcnt */ > - { > - bool zf; > - > - asm ( "bsf %2,%0" ASM_FLAG_OUT(, "; setz %1") > - : "=r" (dst.val), ASM_FLAG_OUT("=@ccz", "=qm") (zf) > - : "rm" (src.val) ); > - _regs.eflags &= ~X86_EFLAGS_ZF; > - if ( (vex.pfx == vex_f3) && vcpu_has_bmi1() ) > - { > - _regs.eflags &= ~X86_EFLAGS_CF; > - if ( zf ) > - { > - _regs.eflags |= X86_EFLAGS_CF; > - dst.val = op_bytes * 8; > - } > - else if ( !dst.val ) > - _regs.eflags |= X86_EFLAGS_ZF; > - } > - else if ( zf ) > + if ( vex.pfx == vex_f3 ) > + emulate_2op_SrcV_srcmem("rep; bsf", src, dst, _regs.eflags); Do we need the ; ? We surely don't on 4.21, but I presume there are bugs in older binutils? (All Clangs back to 3.5 seem happy) ~Andrew