usbfuzz-afl/qemu_mode/qemu/linux-user/main.c
/*
 * Compare the 8-byte contents of the CmpValue SPR with the 8-byte value in
 * memory at the address held in the first source register. If the values are
 * not equal, then no memory operation is performed. If the values are equal,
 * the 8-byte quantity from the second source register is written into memory
 * at the address held in the first source register. In either case, the result
 * of the instruction is the value read from memory. The compare and write to
 * memory are atomic and thus can be used for synchronization purposes. This
 * instruction only operates for addresses aligned to a 8-byte boundary.
 * Unaligned memory access causes an Unaligned Data Reference interrupt.
 *
 * Functional Description (64-bit)
 *       uint64_t memVal = memoryReadDoubleWord (rf[SrcA]);
 *       rf[Dest] = memVal;
 *       if (memVal == SPR[CmpValueSPR])
 *           memoryWriteDoubleWord (rf[SrcA], rf[SrcB]);
 *
 * Functional Description (32-bit)
 *       uint64_t memVal = signExtend32 (memoryReadWord (rf[SrcA]));
 *       rf[Dest] = memVal;
 *       if (memVal == signExtend32 (SPR[CmpValueSPR]))
 *           memoryWriteWord (rf[SrcA], rf[SrcB]);
 *
 *
 * This function also processes exch and exch4 which need not process SPR.
 */
Compare the 8-byte contents of the CmpValue SPR with the 8-byte value in
memory at the address held in the first source register. If the values are
not equal, then no memory operation is performed. If the values are equal,
the 8-byte quantity from the second source register is written into memory
at the address held in the first source register. In either case, the result
of the instruction is the value read from memory. The compare and write to
memory are atomic and thus can be used for synchronization purposes. This
instruction only operates for addresses aligned to a 8-byte boundary.
Unaligned memory access causes an Unaligned Data Reference interrupt.





This function also processes exch and exch4 which need not process SPR.
Compare the 8 - byte contents of the CmpValue SPR with the 8 - byte value in memory at the address held in the first source register . If the values are not equal then no memory operation is performed . If the values are equal the 8 - byte quantity from the second source register is written into memory at the address held in the first source register . In either case the result of the instruction is the value read from memory . The compare and write to memory are atomic and thus can be used for synchronization purposes . This instruction only operates for addresses aligned to a 8 - byte boundary . Unaligned memory access causes an Unaligned Data Reference interrupt . This function also processes exch and exch4 which need not process SPR .
static void do_exch(CPUTLGState *env, bool quad, bool cmp)
{
    target_ulong addr;
    target_long val, sprval;
    start_exclusive();
    addr = env->atomic_srca;
    if (quad ? get_user_s64(val, addr) : get_user_s32(val, addr)) {
        goto sigsegv_maperr;
    }
    if (cmp) {
        if (quad) {
            sprval = env->spregs[TILEGX_SPR_CMPEXCH];
        } else {
            sprval = sextract64(env->spregs[TILEGX_SPR_CMPEXCH], 0, 32);
        }
    }
    if (!cmp || val == sprval) {
        target_long valb = env->atomic_srcb;
        if (quad ? put_user_u64(valb, addr) : put_user_u32(valb, addr)) {
            goto sigsegv_maperr;
        }
    }
    set_regval(env, env->atomic_dstr, val);
    end_exclusive();
    return;
 sigsegv_maperr:
    end_exclusive();
    gen_sigsegv_maperr(env, addr);
}
static void do_exch ( CPUTLGState * env , bool quad , bool cmp ) { target_ulong addr ; target_long val , sprval ; start_exclusive ( ) ; addr = env -> atomic_srca ; if ( quad ? get_user_s64 ( val , addr ) : get_user_s32 ( val , addr ) ) { goto sigsegv_maperr ; } if ( cmp ) { if ( quad ) { sprval = env -> spregs [ TILEGX_SPR_CMPEXCH ] ; } else { sprval = sextract64 ( env -> spregs [ TILEGX_SPR_CMPEXCH ] , 0 , 32 ) ; } } if ( ! cmp || val == sprval ) { target_long valb = env -> atomic_srcb ; if ( quad ? put_user_u64 ( valb , addr ) : put_user_u32 ( valb , addr ) ) { goto sigsegv_maperr ; } } set_regval ( env , env -> atomic_dstr , val ) ; end_exclusive ( ) ; return ; sigsegv_maperr : end_exclusive ( ) ; gen_sigsegv_maperr ( env , addr ) ; }
Compare the 8-byte contents of the CmpValue SPR with the 8-byte value in
 memory at the address held in the first source register.
Compare the 8 - byte contents of the CmpValue SPR with the 8 - byte value in memory at the address held in the first source register .