/* * 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; }
/* 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); } }
/* * 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; } }
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ GLOBAL VOID SBB IFN3( IU32 *, pop1, /* pntr to dst/lsrc operand */ IU32, op2, /* rsrc operand */ IUM8, op_sz /* 8, 16 or 32-bit */ ) { IU32 result; IU32 carry; IU32 msb; IU32 op1_msb; IU32 op2_msb; IU32 res_msb; msb = SZ2MSB(op_sz); /* Do operation */ result = *pop1 - op2 - GET_CF() & SZ2MASK(op_sz); op1_msb = (*pop1 & msb) != 0; /* Isolate all msb's */ op2_msb = (op2 & msb) != 0; res_msb = (result & msb) != 0; carry = *pop1 ^ op2 ^ result; /* Isolate carries */ /* Determine flags */ /* OF = (op1 == !op2) & (op1 ^ res) ie if operand signs differ and res sign different to original destination set OF. */ SET_OF((op1_msb != op2_msb) & (op1_msb ^ res_msb)); /* Formally:- CF = !op1 & op2 | res & !op1 | res & op2 Equivalently:- CF = OF ^ op1 ^ op2 ^ res */ SET_CF(((carry & msb) != 0) ^ GET_OF()); SET_PF(pf_table[result & BYTE_MASK]); SET_ZF(result == 0); SET_SF((result & msb) != 0); /* SF = MSB */ SET_AF((carry & BIT4_MASK) != 0); /* AF = Bit 4 carry */ *pop1 = result; /* Return answer */ }
/* * 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; }