/* * cond_doit: whether do (mov or jmp) it? * args * PACK_CC: the current condition codes * cond: conditions (C_YES, C_LE, C_L, C_E, C_NE, C_GE, C_G) * * return * TRUE: do it * FALSE: not do it */ bool_t cond_doit(cc_t cc, cond_t cond) { bool_t doit = FALSE; switch(cond){ case C_YES: doit = TRUE; break; case C_LE: doit = ((GET_SF(cc) ^ GET_OF(cc)) | GET_ZF(cc)); break; case C_L: doit = (GET_SF(cc) ^ GET_OF(cc)); break; case C_E: doit = (GET_ZF(cc)); break; case C_NE: doit = (!GET_ZF(cc)); break; case C_GE: doit = !(GET_SF(cc) ^ GET_OF(cc)); break; case C_G: doit = !(GET_SF(cc) ^ GET_OF(cc)) & !GET_ZF(cc); break; } return doit; }
/* Branch logic */ bool_t take_branch(cc_t cc, jump_t bcond) { bool_t zf = GET_ZF(cc); bool_t sf = GET_SF(cc); bool_t of = GET_OF(cc); bool_t jump = FALSE; switch(bcond) { case J_YES: jump = TRUE; break; case J_LE: jump = (sf^of)|zf; break; case J_L: jump = sf^of; break; case J_E: jump = zf; break; case J_NE: jump = zf^1; break; case J_GE: jump = sf^of^1; break; case J_G: jump = (sf^of^1)&(zf^1); break; default: jump = FALSE; break; } return jump; }
/* Branch logic */ bool_t cond_holds(cc_t cc, cond_t bcond) { bool_t zf = GET_ZF(cc); bool_t sf = GET_SF(cc); bool_t of = GET_OF(cc); bool_t jump = FALSE; switch(bcond) { case C_YES: jump = TRUE; break; case C_LE: jump = (sf^of)|zf; break; case C_L: jump = sf^of; break; case C_E: jump = zf; break; case C_NE: jump = zf^1; break; case C_GE: jump = sf^of^1; break; case C_G: jump = (sf^of^1)&(zf^1); break; default: jump = FALSE; break; } return jump; }
GLOBAL VOID CMPXCHG32 IFN2( IU32 *, pop1, /* pntr to dst/lsrc operand */ IU32, op2 /* rsrc operand */ ) { /* First do comparision and generate flags. */ CMP((IU32)GET_EAX(), *pop1, 32); /* Then swap data as required. */ if ( GET_ZF() ) /* ie iff EAX == op1 */ { *pop1 = op2; } else { SET_EAX(*pop1); } }
/* Provide mechanism for simulator to update condition code display */ void show_cc(cc_t cc) { int code; sprintf(tcl_msg, "setCC %d %d %d", GET_ZF(cc), GET_SF(cc), GET_OF(cc)); code = Tcl_Eval(sim_interp, tcl_msg); if (code != TCL_OK) { fprintf(stderr, "Failed to display condition codes\n"); fprintf(stderr, "Error Message was '%s'\n", sim_interp->result); } }
GLOBAL VOID LOOPNE16 IFN1( IU32, rel_offset ) { SET_CX(GET_CX() - 1); if ( GET_CX() != 0 && !GET_ZF() ) update_relative_ip(rel_offset); }
GLOBAL VOID LOOPE32 IFN1( IU32, rel_offset ) { SET_ECX(GET_ECX() - 1); if ( GET_ECX() != 0 && GET_ZF() ) update_relative_ip(rel_offset); }
/* * cond_doit: whether do (mov or jmp) it? * args * PACK_CC: the current condition codes * cond: conditions (C_YES, C_LE, C_L, C_E, C_NE, C_GE, C_G) * * return * TRUE: do it * FALSE: not do it */ bool_t cond_doit(cc_t cc, cond_t cond) { bool_t doit; bool_t ZF = GET_ZF(cc), SF = GET_SF(cc), OF = GET_OF(cc); switch (cond) { case C_YES: return TRUE; case C_LE: return (SF^OF)|ZF; case C_L: return SF^OF; case C_E: return ZF; case C_NE: return !ZF; case C_GE: return !(SF^OF); case C_G: return !(SF^OF)&!ZF; default: return FALSE; } }
/* * cond_doit: whether do (mov or jmp) it? * args * PACK_CC: the current condition codes * cond: conditions (C_YES, C_LE, C_L, C_E, C_NE, C_GE, C_G) * * return * TRUE: do it * FALSE: not do it */ bool_t cond_doit(cc_t cc, cond_t cond) { bool_t doit = FALSE; bool_t zero = GET_ZF(cc); bool_t sign = GET_SF(cc); bool_t ovf = GET_OF(cc); switch (cond) { case C_YES: doit = TRUE; break; case C_LE: if (((sign^ovf)|zero)&0x1) doit = TRUE; break; case C_L: if ((sign^ovf)&0x1) doit = TRUE; break; case C_E: if ((zero)&0x1) doit = TRUE; break; case C_NE: if ((!zero)&0x1) doit = TRUE; break; case C_GE: if ((~(sign^ovf))&0x1) doit = TRUE; break; case C_G: if (((~(sign^ovf))&(~zero))&0x1) doit = TRUE; break; default: break; } return doit; }