fn calc_rflags_cpazso(op0: u64, op1: u64, op_size: usize) -> u64 {
    let op_bits = op_size * 8;
    let msb_shift = op_bits - 1;
    // CMP is the same as SUB.
    let result = op0.wrapping_sub(op1);

    // Carry-out vector for SUB.
    let cout = (!op0 & op1) | ((!op0 ^ op1) & result);

    let cf = ((cout >> msb_shift) & 0x1) << CF_SHIFT;

    // PF only needs the least significant byte. XOR its higher 4 bits with its lower 4 bits then
    // use the value directly.
    let pf = ((0x9669 >> ((result ^ (result >> 4)) & 0xf)) & 0x1) << PF_SHIFT;

    // AF cares about the lowest 4 bits (nibble). msb_shift is 3 in this case.
    let af = ((cout >> 3) & 0x1) << AF_SHIFT;

    let zf = if result & (!0u64 >> (63 - msb_shift)) == 0 {
        1
    } else {
        0
    } << ZF_SHIFT;

    let sf = ((result >> msb_shift) & 0x1) << SF_SHIFT;

    // Overflow happens when two operands have the same sign but the result has a different sign.
    let of = ((((op0 ^ op1) & (op0 ^ result)) >> msb_shift) & 0x1) << OF_SHIFT;

    cf | pf | af | zf | sf | of
}
// TODO: Switch to inline asm when that's stable. Executing CMP (or any arthimetic instructions)
// natively and extracting RFLAGS will be much faster and make the code simpler.
Switch to inline asm when that's stable. Executing CMP (or any arthimetic instructions)
natively and extracting RFLAGS will be much faster and make the code simpler.
Switch to inline asm when that ' s stable . Executing CMP ( or any arthimetic instructions ) natively and extracting RFLAGS will be much faster and make the code simpler .
fn calc_rflags_cpazso(op0: u64, op1: u64, op_size: usize) -> u64 {
    let op_bits = op_size * 8;
    let msb_shift = op_bits - 1;
    // CMP is the same as SUB.
    let result = op0.wrapping_sub(op1);
    // Carry-out vector for SUB.
    let cout = (!op0 & op1) | ((!op0 ^ op1) & result);
    let cf = ((cout >> msb_shift) & 0x1) << CF_SHIFT;
    // PF only needs the least significant byte. XOR its higher 4 bits with its lower 4 bits then
    // use the value directly.
    let pf = ((0x9669 >> ((result ^ (result >> 4)) & 0xf)) & 0x1) << PF_SHIFT;
    // AF cares about the lowest 4 bits (nibble). msb_shift is 3 in this case.
    let af = ((cout >> 3) & 0x1) << AF_SHIFT;
    let zf = if result & (!0u64 >> (63 - msb_shift)) == 0 {
        1
    } else {
        0
    } << ZF_SHIFT;
    let sf = ((result >> msb_shift) & 0x1) << SF_SHIFT;
    // Overflow happens when two operands have the same sign but the result has a different sign.
    let of = ((((op0 ^ op1) & (op0 ^ result)) >> msb_shift) & 0x1) << OF_SHIFT;
    cf | pf | af | zf | sf | of
}
fn calc_rflags_cpazso ( op0 : u64 , op1 : u64 , op_size : usize ) -> u64 { let op_bits = op_size * 8 ; let msb_shift = op_bits - 1 ; // CMP is the same as SUB. let result = op0 . wrapping_sub ( op1 ) ; // Carry-out vector for SUB. let cout = ( ! op0 & op1 ) | ( ( ! op0 ^ op1 ) & result ) ; let cf = ( ( cout >> msb_shift ) & 0x1 ) << CF_SHIFT ; // PF only needs the least significant byte. XOR its higher 4 bits with its lower 4 bits then // use the value directly. let pf = ( ( 0x9669 >> ( ( result ^ ( result >> 4 ) ) & 0xf ) ) & 0x1 ) << PF_SHIFT ; // AF cares about the lowest 4 bits (nibble). msb_shift is 3 in this case. let af = ( ( cout >> 3 ) & 0x1 ) << AF_SHIFT ; let zf = if result & ( ! 0u64 >> ( 63 - msb_shift ) ) == 0 { 1 } else { 0 } << ZF_SHIFT ; let sf = ( ( result >> msb_shift ) & 0x1 ) << SF_SHIFT ; // Overflow happens when two operands have the same sign but the result has a different sign. let of = ( ( ( ( op0 ^ op1 ) & ( op0 ^ result ) ) >> msb_shift ) & 0x1 ) << OF_SHIFT ; cf | pf | af | zf | sf | of }
TODO: Switch to inline asm when that's stable.
TODO : Switch to inline asm when that ' s stable .
op0
u64
op1
u64
op_size
usize
op0
u64
op1
u64
op_size
usize