diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2003-03-16 20:28:50 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2003-03-16 20:28:50 +0000 |
commit | 1a9353d258aba69afd8a389bf5fb705caab12ce0 (patch) | |
tree | 6d82000351db013b87af23a2f554bdd5a5bf6b5a /ops_template.h | |
parent | 6dbad63eef5947c6c8750e44f408138779b6d0bb (diff) |
added loop/xadd/cmpxchg support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@29 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'ops_template.h')
-rw-r--r-- | ops_template.h | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/ops_template.h b/ops_template.h index 745c27d7e5..60bdbe5091 100644 --- a/ops_template.h +++ b/ops_template.h @@ -277,6 +277,61 @@ void OPPROTO glue(op_jle_sub, SUFFIX)(void) FORCE_RET(); } +/* oldies */ + +#if DATA_BITS >= 16 + +void OPPROTO glue(op_loopnz, SUFFIX)(void) +{ + unsigned int tmp; + int eflags; + eflags = cc_table[CC_OP].compute_all(); + tmp = (ECX - 1) & DATA_MASK; + ECX = (ECX & ~DATA_MASK) | tmp; + if (tmp != 0 && !(eflags & CC_Z)) + PC = PARAM1; + else + PC = PARAM2; + FORCE_RET(); +} + +void OPPROTO glue(op_loopz, SUFFIX)(void) +{ + unsigned int tmp; + int eflags; + eflags = cc_table[CC_OP].compute_all(); + tmp = (ECX - 1) & DATA_MASK; + ECX = (ECX & ~DATA_MASK) | tmp; + if (tmp != 0 && (eflags & CC_Z)) + PC = PARAM1; + else + PC = PARAM2; + FORCE_RET(); +} + +void OPPROTO glue(op_loop, SUFFIX)(void) +{ + unsigned int tmp; + tmp = (ECX - 1) & DATA_MASK; + ECX = (ECX & ~DATA_MASK) | tmp; + if (tmp != 0) + PC = PARAM1; + else + PC = PARAM2; + FORCE_RET(); +} + +void OPPROTO glue(op_jecxz, SUFFIX)(void) +{ + if ((DATA_TYPE)ECX == 0) + PC = PARAM1; + else + PC = PARAM2; + FORCE_RET(); +} + +#endif + /* various optimized set cases */ void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void) @@ -599,6 +654,18 @@ void OPPROTO glue(glue(op_sbb, SUFFIX), _T0_T1_cc)(void) CC_OP = CC_OP_SUBB + SHIFT + cf * 3; } +void OPPROTO glue(glue(op_cmpxchg, SUFFIX), _T0_T1_EAX_cc)(void) +{ + CC_SRC = EAX; + CC_DST = EAX - T0; + if ((DATA_TYPE)CC_DST == 0) { + T0 = T1; + } else { + EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK); + } + FORCE_RET(); +} + /* bit operations */ #if DATA_BITS >= 16 |