aboutsummaryrefslogtreecommitdiff
path: root/op-i386.c
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2003-05-10 21:35:30 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2003-05-10 21:35:30 +0000
commit2792c4f2afda061645ef122dc179f0d058a43484 (patch)
tree573704b77be3a63baf14da4d93730f31d9e53a70 /op-i386.c
parent447db2139a6f6883183a7a750c5849145fd29899 (diff)
added EIP return to INTO - fixed SHL C flag computation - added LAR/LSL
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@148 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'op-i386.c')
-rw-r--r--op-i386.c71
1 files changed, 66 insertions, 5 deletions
diff --git a/op-i386.c b/op-i386.c
index dac8700357..64cbe708a5 100644
--- a/op-i386.c
+++ b/op-i386.c
@@ -634,6 +634,7 @@ void OPPROTO op_into(void)
int eflags;
eflags = cc_table[CC_OP].compute_all();
if (eflags & CC_O) {
+ EIP = PARAM1;
raise_exception(EXCP04_INTO);
}
FORCE_RET();
@@ -1136,6 +1137,66 @@ void OPPROTO op_addl_A0_seg(void)
A0 += *(unsigned long *)((char *)env + PARAM1);
}
+void helper_lsl(void)
+{
+ unsigned int selector, limit;
+ SegmentDescriptorTable *dt;
+ int index;
+ uint32_t e1, e2;
+ uint8_t *ptr;
+
+ CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z;
+ selector = T0 & 0xffff;
+ if (selector & 0x4)
+ dt = &env->ldt;
+ else
+ dt = &env->gdt;
+ index = selector & ~7;
+ if ((index + 7) > dt->limit)
+ return;
+ ptr = dt->base + index;
+ e1 = ldl(ptr);
+ e2 = ldl(ptr + 4);
+ limit = (e1 & 0xffff) | (e2 & 0x000f0000);
+ if (e2 & (1 << 23))
+ limit = (limit << 12) | 0xfff;
+ T1 = limit;
+ CC_SRC |= CC_Z;
+}
+
+void OPPROTO op_lsl(void)
+{
+ helper_lsl();
+}
+
+void helper_lar(void)
+{
+ unsigned int selector;
+ SegmentDescriptorTable *dt;
+ int index;
+ uint32_t e2;
+ uint8_t *ptr;
+
+ CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z;
+ selector = T0 & 0xffff;
+ if (selector & 0x4)
+ dt = &env->ldt;
+ else
+ dt = &env->gdt;
+ index = selector & ~7;
+ if ((index + 7) > dt->limit)
+ return;
+ ptr = dt->base + index;
+ e2 = ldl(ptr + 4);
+ T1 = e2 & 0x00f0ff00;
+ CC_SRC |= CC_Z;
+}
+
+void OPPROTO op_lar(void)
+{
+ helper_lar();
+}
+
/* flags handling */
/* slow jumps cases (compute x86 flags) */
@@ -1490,13 +1551,13 @@ CCTable cc_table[CC_OP_NB] = {
[CC_OP_DECW] = { compute_all_decw, compute_c_incl },
[CC_OP_DECL] = { compute_all_decl, compute_c_incl },
- [CC_OP_SHLB] = { compute_all_shlb, compute_c_shll },
- [CC_OP_SHLW] = { compute_all_shlw, compute_c_shll },
+ [CC_OP_SHLB] = { compute_all_shlb, compute_c_shlb },
+ [CC_OP_SHLW] = { compute_all_shlw, compute_c_shlw },
[CC_OP_SHLL] = { compute_all_shll, compute_c_shll },
- [CC_OP_SARB] = { compute_all_sarb, compute_c_shll },
- [CC_OP_SARW] = { compute_all_sarw, compute_c_shll },
- [CC_OP_SARL] = { compute_all_sarl, compute_c_shll },
+ [CC_OP_SARB] = { compute_all_sarb, compute_c_sarl },
+ [CC_OP_SARW] = { compute_all_sarw, compute_c_sarl },
+ [CC_OP_SARL] = { compute_all_sarl, compute_c_sarl },
};
/* floating point support. Some of the code for complicated x87